jsweet icon indicating copy to clipboard operation
jsweet copied to clipboard

Non deterministic behavior in Transpiler PrinterAdapter

Open iffyio opened this issue 4 years ago • 0 comments

Hi!

I have a usecase that involves accounting for untyped access in a source file. I figured extending the transpiler by overriding PrinterAdapter might work but it seems JSweetTranspiler has troubles reporting substitutions in some cases, at least the def.js.Object package.

As a repro, here is an adapter that wishes to substitute Class and MethodInvocation access.

...
public boolean substituteNewClass(NewClassElement newClass) {
	System.out.println("CLASS " + newClass);
	return super.substituteNewClass(newClass);
}
public boolean substituteMethodInvocation(MethodInvocationElement invocation) {
	System.out.println("METHOD " + invocation);
	return super.substituteMethodInvocation(invocation);
}

The following code works as expected, we get notified of a new class:

Object obj = new def.js.Object();
// CLASS new def.js.Object()

But nothing gets reported for the following:

Object obj = new def.js.Object(){{}};
// empty

Object obj = new def.js.Object(){{
	$set("x", 1);
}};
// also empty ( expected 'CLASS ...' and 'METHOD ...' )

The next is somewhat stranger, adding a $get throws an exception but combining $get with an arbitrary method invocation not only does not throw, it causes the transpiler to report the expected substitutions.

def.js.Object obj = new def.js.Object(){{
	$set("x", 1);
	$get("v");
}};

// ERROR output:55 - invalid initializer statement; only field assignments are allowed at ...


def.js.Object obj = new def.js.Object(){{
	$set("x", 1);
	$get("v");
	hasOwnProperty("b");
}};


// METHOD $set("x", 1)
// METHOD $get("v")
// METHOD hasOwnProperty("b")

Have I missed something here? e.g if it's some special behavior for instance initializers? The observed behavior doesn't seem deterministic.

iffyio avatar Oct 05 '19 12:10 iffyio