You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is a problem when multiple methods are marked with @JsNative.
For example:
class C extends JavaScriptObject {
protected new() {
}
@JsNative
def int a() '''
this.a();
'''
@JsNative
def int b() '''
this.b();
'''
}
results in
public class C extends JavaScriptObject {
protected C() {
}
@JsNative
public final native int a() {
C#a()
}
@JsNative
public final native int b() /*-{
this.b();
}-*/;
}
Note that the marker code is not replaced in case of method a().
The cause of the problem is that JsNativeProcessor.doGenerateCode() is using MutableFileSystemSupport.setContents() during code generation to modify the generated sources. setContents()'s javadoc states: Clients should not rely on invocation timing.
Possible solutions:
Using an AbstractClassProcessor instead of the current AbstractMethodProcessor to replace all methods of a compilation unit in one turn.
Creating a synchronous and locking file system API.
The latter can be emulated in a quick and dirty way by modifying JsNativeProcessor.doGenerateCode() to this:
override doGenerateCode(MethodDeclaration annotatedMethod, extension CodeGenerationContext context) {
val path = annotatedMethod.declaringType.getTargetPath(context)
val contents = path.contents.toString
val markerStart = contents.indexOf(getUniqueMarkerCode(annotatedMethod))
val startIndex = contents.substring(0, markerStart).lastIndexOf('{')
val endIndex = contents.substring(markerStart).indexOf('}') + markerStart
val jsCode = annotatedMethod.body.toString.trimTripleQuotes
val newContents = contents.substring(0, startIndex) + "/*-{" + jsCode + "}-*/;" +
contents.substring(endIndex + 1)
path.contents = newContents
do {
Thread.sleep(100);
} while (path.contents.toString != newContents)
}
Note the last few lines that contain the hack by waiting for the file system operation to finish :)
(This works because the annotated methods of a class are processed by the same processor instance on one thread.)
With this ugly modification the generated code is correct:
public class C extends JavaScriptObject {
protected C() {
}
@JsNative
public final native int a() /*-{
this.a();
}-*/;
@JsNative
public final native int b() /*-{
this.b();
}-*/;
}
The text was updated successfully, but these errors were encountered:
import de.itemis.xtend.auto.gwt.JsNative;
@SuppressWarnings("all")
public class C {
protected C() {
}
@JsNative
public final native void a() {
C#a()
}
@JsNative
public final native void b() {
C#b()
}
}
It seems that the file system works differently in case of unit tests...
There is a problem when multiple methods are marked with
@JsNative.
For example:
results in
Note that the marker code is not replaced in case of method
a()
.The cause of the problem is that
JsNativeProcessor.doGenerateCode()
is usingMutableFileSystemSupport.setContents()
during code generation to modify the generated sources.setContents()
's javadoc states: Clients should not rely on invocation timing.Possible solutions:
AbstractClassProcessor
instead of the currentAbstractMethodProcessor
to replace all methods of a compilation unit in one turn.The latter can be emulated in a quick and dirty way by modifying
JsNativeProcessor.doGenerateCode()
to this:Note the last few lines that contain the hack by waiting for the file system operation to finish :)
(This works because the annotated methods of a class are processed by the same processor instance on one thread.)
With this ugly modification the generated code is correct:
The text was updated successfully, but these errors were encountered: