-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify non-native @JsType support for Java 16 records #7
Open
niloc132
wants to merge
2
commits into
google:master
Choose a base branch
from
niloc132:non-native-records
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't checked what we would see in the AST but I thought they would be observed like they are annotated with a @JSmethod since they are public methods. Isn't that the case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking a look.
There might have been a miscommunication between us on #6, where I proposed that this is the desired behavior - this isn't a limitation of what would be seen in the AST at all, but what I believe to be the idiomatic way to express this sort of object in JS - I deliberately left the isNative=true unsolved, and you replied "I think it generally makes sense though not sure what to do with native types."
Briefly rehashing the logic:
get
/set
makes this simple to express as well, without needing/wanting a "real" method to use as an accessorI argue that the default assumption should be that since the record is explicitly being made available to JS, it should be easy to do in an idiomatic way, rather than making the developer effectively write the full "bean" implementation. If for some reason it is desired to have a component accessor be exported as a no-arg method, that should be considered the exception.
As a compromise between these, I also proposed allowing
@JsProperty
to be put on the components themselves, with the special rules that it would not apply to the field (as the JEP says it must). I would personally argue that it is inconsistent to argue a) we're uncomfortable with JsType having its rules bent, but b) JsProperty can be redefined in this context to mean something non-standard ("doesn't apply to fields, even though it normally would"), and that it would be more idiomatic to just allow@JsMethod
on the components (which will correctly be propagated to the public accessor methods, but not the private final fields).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it.
Property accessor are generally a code size / performance concern for ES5 transpiling. I don't know about performance impact on more recent ES versions. This will also affect potential AutoValue to Record migrations. We need to put more thought on to this.
I guess in short we need to start designing around record types to make this commitment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any additional thoughts on this?
My quick surprise here is that closure-compiler cannot optimize
get
accessor methods into regular methods, nor inline them. That is, according to the closure appspot service,is compiled to
but replace
get foo
withgetFoo
:and we do get better optimized output:
This might not generalize well, but if it does, it surprises me to be so stark.
In contrast, just counting bytes of unoptimized but minified code, while
get foo()
could be rewritten to something likeget a()
, a methodgetFoo()
could be rewritten toa()
- clearly savings there of 4 bytes in the declaration.We seem to make it back quickly in usage: invoking
a.a(1)
(ora(a,1)
if made static) as a setter method is a byte longer thana.a=1
, so anyset
accessor used more than 4 times would break even compared to a setter method.Am I missing something, or does it really boil down to closure not optimizing accessors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it hasn't changed recently, Closure compiler doesn't optimize set/get properties. However J2CL has specific passes in Closure compiler to optimize some of them (can't remember in which cases we fallback though).
re. inlining decisions; Closure compiler heuristic put into account the number of usages when making inlining decision.
re. the design of record JsType in general; unfortunately that will need to wait longer - we will like to come back to it in 1-2 quarters. (Though I'm currently leaning towards preserving the contract by default for migration reasons)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that I made a mistake in the above JS samples, but the outcome is presently the same - trivial property access is never optimized out by closure at this time: