ANTLR4 - How to change source code and get it back? - antlr4

I'd like to rewrite some of the code.
Then, I'd like to get the rewritten code back.
First, I'd like to replace string literals:
local var = "%%var%%"
// to
local var = "SOMETHING"
Second, I'd like to erase the function name and brackets:
function sayHello (a)
local var = "%%var%%"
print("Hello")
end
//to
function (a)
local var = "%%var%%"
print("Hello")
end
What's the suggested way to do so?
My target's JavaScript (specifically antlr4ts), however an answer in any language is welcome.

Use TokenStreamRewriter
const stream = CharStreams.fromString(code);
const lexer = new LuaLexer(stream);
const commonTokenStream = new CommonTokenStream(lexer);
const rewriter = new TokenStreamRewriter(commonTokenStream);
const parser = new LuaParser(commonTokenStream);
const tree = parser.chunk();
class MyVisitor extends AbstractParseTreeVisitor<any>
implements LuaVisitor<any> {
constructor() {
super();
}
visitString(ctx: StringContext) {
rewriter.replace(ctx.start.tokenIndex, ctx.stop?.tokenIndex!, "SOME REPLACEMENT");
}
}
console.log("rewriter", rewriter.getText());

Related

How to insert node by xpath in nodejs, typescript?

I'm trying to make some code to insert node into generic config by xpath.
Usually I'm writing .Net applications but now I need to write tool on nodejs, type script
I don't get it how write it right
How to make cast of **childNodes[0]** so I can call **appendChild**?
import {DOMParser as dom} from "xmldom";
import * as xpath from "xpath";
export default class FileJob extends BaseJob {
async execute(settings: JobSettings) {
this.poke('C:\\Temp\\LocalCache\\Config.xml','/Root','<DB-Connection id="development" database="development"/>');
}
private poke(path:fs.PathLike,pathToNode:string, node : string)
{
const file = fs.readFileSync(path,'utf-8');
var doc = new dom().parseFromString(file);
var tempDoc = new dom().parseFromString(node);
var importedNode = doc.importNode(tempDoc.documentElement, true);
var childNodes = xpath.select(pathToNode, doc);
if (childNodes[0]!==undefined)
{
//What to do here?
//Property 'appendChild' does not exist on type 'SelectedValue'.
//Property 'appendChild' does not exist on type 'string'.
childNodes[0].appendChild(importedNode);
fs.writeFileSync(path,doc.toString());
}
}
}
I was stupid and young.
Here is what was necessary.
import {DOMParser as dom} from "xmldom";
import * as xpath from "xpath";
export default class FileJob extends BaseJob {
async execute(settings: JobSettings) {
this.poke('C:\\Temp\\LocalCache\\Config.xml','/Root','<DB-Connection id="development" database="development"/>');
}
private poke(path:fs.PathLike,pathToNode:string, node : string)
{
const file = fs.readFileSync(path,'utf-8');
var doc = new dom().parseFromString(file);
var tempDoc = new dom().parseFromString(node);
var importedNode = doc.importNode(tempDoc.documentElement, true);
var childNodes = xpath.select(pathToNode, doc);
if (childNodes[0]!==undefined)
{
let currentNode = childNodes[0] as Node;
currentNode.appendChild(importedNode);
fs.writeFileSync(path,doc.toString());
}
}
}

How to export (save) data in OpenFL (Haxe) via XML(?)

In AS3 I could write the following:
fileReference = new FileReference();
var xmlStage:XML = new XML(<STAGE/>);
var xmlObjects:XML = new XML(<OBJECTS/>);
var j:uint;
var scene:SomeScene = ((origin_ as SecurityButton).origin as SomeScene);
var object:SomeObject;
for (j = 0; j < scene.objectArray.length; ++j) {
object = scene.objectArray[j];
if (1 == object.saveToXML){
var item:String = "obj";
var o:XML = new XML(<{item}/>);
o.#x = scene.objectArray[j].x;
o.#y = scene.objectArray[j].y;
o.#n = scene.objectArray[j].name;
o.#g = scene.objectArray[j].band;
o.#f = scene.objectArray[j].frame;
o.#w = scene.objectArray[j].width;
o.#h = scene.objectArray[j].height;
o.#s = scene.objectArray[j].sprite;
o.#b = scene.objectArray[j].bodyType;
xmlObjects.appendChild(o);
//System.disposeXML(o);
}
}
xmlStage.appendChild(xmlObjects);
fileReference.save(xmlStage, "XML.xml");
//System.disposeXML(xmlObjects);
//System.disposeXML(xmlStage);
//fileReference = null;
Is there an equivalent way to do this in Haxe? (Target of interest: HTML5)
If not, what are my options?
(The exported results of this code in AS3 are shown in this link below)
https://pastebin.com/raw/5twiJ01B
You can use the Xml class to create xml (see example: https://try.haxe.org/#68cfF )
class Test {
static function main() {
var root = Xml.createElement('root');
var child = Xml.createElement('my-element');
child.set('attribute1', 'value1'); //add your own object's values
child.set('attribute2', 'value2'); //may be add a few more children
root.addChild(child);
//this could be a file write, or POST'ed to http, or socket
trace(root.toString()); // <root><my-element attribute1="value1" attribute2="value2"/></root>
}
}
The root.toString() in that example could be instead serialized to a file File, or indeed any other kind of output (like POSTing via http to somewhere).
You could use FileReference for flash target, and sys.io and File for supported targets:
var output = sys.io.File.write(path, true);
output.writeString(data);
output.flush();
output.close();

What is the PostFileWithRequest equivalent in ServiceStack's 'New API'?

I want to post some request values alongside the multipart-formdata file contents. In the old API you could use PostFileWithRequest:
[Test]
public void Can_POST_upload_file_using_ServiceClient_with_request()
{
IServiceClient client = new JsonServiceClient(ListeningOn);
var uploadFile = new FileInfo("~/TestExistingDir/upload.html".MapProjectPath());
var request = new FileUpload{CustomerId = 123, CustomerName = "Foo"};
var response = client.PostFileWithRequest<FileUploadResponse>(ListeningOn + "/fileuploads", uploadFile, request);
var expectedContents = new StreamReader(uploadFile.OpenRead()).ReadToEnd();
Assert.That(response.FileName, Is.EqualTo(uploadFile.Name));
Assert.That(response.ContentLength, Is.EqualTo(uploadFile.Length));
Assert.That(response.Contents, Is.EqualTo(expectedContents));
Assert.That(response.CustomerName, Is.EqualTo("Foo"));
Assert.That(response.CustomerId, Is.EqualTo(123));
}
I can't find any such method in the new API, nor any overrides on client.Post() which suggest that this is still possible. Does anyone know if this is a feature that was dropped?
Update
As #Mythz points out, the feature wasn't dropped. I had made the mistake of not casting the client:
private IRestClient CreateRestClient()
{
return new JsonServiceClient(WebServiceHostUrl);
}
[Test]
public void Can_WebRequest_POST_upload_binary_file_to_save_new_file()
{
var restClient = (JsonServiceClient)CreateRestClient(); // this cast was missing
var fileToUpload = new FileInfo(#"D:/test/test.avi");
var beforeHash = this.Hash(fileToUpload);
var response = restClient.PostFileWithRequest<FilesResponse>("files/UploadedFiles/", fileToUpload, new TestRequest() { Echo = "Test"});
var uploadedFile = new FileInfo(FilesRootDir + "UploadedFiles/test.avi");
var afterHash = this.Hash(uploadedFile);
Assert.That(beforeHas, Is.EqualTo(afterHash));
}
private string Hash(FileInfo file)
{
using (var md5 = MD5.Create())
{
using (var stream = file.OpenRead())
{
var bytes = md5.ComputeHash(stream);
return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower();
}
}
}
None of the old API was removed from the C# Service Clients, only new API's were added.
The way you process an uploaded file inside a service also hasn't changed.

Static variable change does not take effect, nodeJS

I'm writing a little nodeJS based email server. I have a Request object, and in it there's one static variable that stores all the users and is defined like so:
Request.publicMemory = new Object();
Request.publicMemory.users = new Object();
Request.prototype.getPublicMemory = function() {
return (Request.publicMemory);
};
I store User objects in it:
function User(params) {
this.mails = new Array();
this.sent = new Array();
var details = new Object();
details.username = params.username;
details.password = params.password
return;
}
As you can see there's also a static function that returns it.
Now, I can add uesrs and that change is actually made, but when I change anything in Request.publicMemory.usesrs[someuser] the change is always local to the function, and does not take effect in other places. Here's an example of how I do it:
function addMail(request) {
var users = request.getPublicMemory().users;
var to = request.parameters['to'];
users[to].mails.push(mail);
}
I've never used a static variable in nodeJS before, and I'm quite new to it so this might be silly, but I still can't solve it. Any ideas?
Thanks!

Writing a javascript library

I want to write a JS library and handle it like this:
var c1 = Module.Class();
c1.init();
var c1 = Module.Class();
c2.init();
And of course, c1 and c2 can not share the same variables.
I think I know how to do this with objects, it would be:
var Module = {
Class = {
init = function(){
...
}
}
}
But the problem is I can't have multiple instances of Class if I write in this way.
So I'm trying to achieve the same with function, but I don't think I'm doing it right.
(function() {
var Module;
window.Module = Module = {};
function Class( i ) {
//How can "this" refer to Class instead of Module?
this.initial = i;
}
Class.prototype.execute = function() {
...
}
//Public
Module.Class = Class;
})();
I don't have a clue if it's even possible, but I accept suggestions of other way to create this module.
I don't know if it's relevant also, but I'm using jQuery inside this library.
Usage:
var c1 = Module.Class("c");
var c2 = Module.Class("a");
var n = c1.initial(); // equals 'c'
c1.initial("s");
n = c1.initial(); // equals 's'
Module Code:
(function(window) {
var Module = window.Module = {};
var Class = Module.Class = function(initial)
{
return new Module.Class.fn.init(initial);
};
Class.fn = Class.prototype = {
init: function(initial) {
this._initial = initial;
},
initial: function(v){
if (v !== undefined) {
this._initial = v;
return this;
}
return this._initial;
}
};
Class.fn.init.prototype = Class.fn;
})(window || this);
This is using the JavaScript "Module" Design Pattern; which is the same design pattern used by JavaScript libraries such as jQuery.
Here's a nice tutorial on the "Module" pattern:
JavaScript Module Pattern: In-Depth

Resources