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
GWT version: 2.10 Browser (with version): Any Operating System: Any
Description
Annotating a method as JsProperty with jsinterop exports disabled (in general or for that member) still emits a Object.defineProperties call, and calls to that method within other GWT code end up being written as a property access rather than a method call.
However, since the property isn't actually being exported, obfuscation still kicks in, but apparently the reference name ends up being different.
A few ways to fix it seem to present themselves:
Don't emit the Object.defineProperties at all when the method (as a property) won't be exported. This will also decrease generated code size.
Always consistently name methods annotated with JsProperty, even if they are not marked for export (but don't treat them as entrypoints, so they aren't truly "exported")
Steps to reproduce
This is easier to reproduce quickly with draft mode, but still possible with a production compile. First, an example with draft mode enabled and no jsinterop exports:
publicclassFoo {
@JsPropertypublicStringgetSomeString() {
// easy to find method in JS outputreturnWindow.prompt("", "");
}
}
To reproduce the bug then, attempt to use that property:
Window.alert(newFoo().getSomeString())
This results in the following alert in the generated JS (note that the property name is not correct for an exported member):
cgguc.alert_0((newceac.Foo).getSomeString);
and this class (with a differently-inconsistent name for the defined member):
demonstrating that this isn't just an issue caused by PRETTY.
To reproduce this with optimized output, we need a bit more indirection - it appears to be sufficient to extra an interface from Foo, and reference that instead:
It might be possible to skip one or more of these steps through a larger, un-inlineable method body, but I didn't explore deeply here. In the original code, there is an interface and a class that implements it, then another subclass that overrides unrelated methods.
This use case came about as part of writing test cases for a GWT based JS library - the library always has the exports enabled, but the unit tests have no need for those. Leaving those exports disabled exposed the issue, and enabling exports on these specific types does work around the issue.
The text was updated successfully, but these errors were encountered:
It is possible that this is related to #9623 - there are a few commonalities here. There is a stale review for that issue, should be tested with this case to see if it resolves both.
GWT version: 2.10
Browser (with version): Any
Operating System: Any
Description
Annotating a method as JsProperty with jsinterop exports disabled (in general or for that member) still emits a
Object.defineProperties
call, and calls to that method within other GWT code end up being written as a property access rather than a method call.However, since the property isn't actually being exported, obfuscation still kicks in, but apparently the reference name ends up being different.
A few ways to fix it seem to present themselves:
Steps to reproduce
This is easier to reproduce quickly with draft mode, but still possible with a production compile. First, an example with draft mode enabled and no jsinterop exports:
To reproduce the bug then, attempt to use that property:
This results in the following alert in the generated JS (note that the property name is not correct for an exported member):
and this class (with a differently-inconsistent name for the defined member):
In OBF, this compiles out to roughly:
and
demonstrating that this isn't just an issue caused by PRETTY.
To reproduce this with optimized output, we need a bit more indirection - it appears to be sufficient to extra an interface from Foo, and reference that instead:
Then introduce a subclass of Foo and instantiate that instead
...And finally create the instance in a way that the compiler can't statically figure out that we always call the same method.
It might be possible to skip one or more of these steps through a larger, un-inlineable method body, but I didn't explore deeply here. In the original code, there is an interface and a class that implements it, then another subclass that overrides unrelated methods.
Prod, OBF output:
Known workarounds
This use case came about as part of writing test cases for a GWT based JS library - the library always has the exports enabled, but the unit tests have no need for those. Leaving those exports disabled exposed the issue, and enabling exports on these specific types does work around the issue.
The text was updated successfully, but these errors were encountered: