-
Notifications
You must be signed in to change notification settings - Fork 30
Drop Quotable type #685
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
Drop Quotable type #685
Conversation
|
👋 Welcome back mcimadamore! A progress list of the required criteria for merging this PR into |
|
@mcimadamore This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be: You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been no new commits pushed to the ➡️ To integrate this PR with the above commit message to the |
|
There's some future work in this area, not addressed in this PR:
This is a fussier model, but one that makes sure that reflectability of a lambda expression is always controlled by the client. |
| public <R> R runWithAttributedMethod(Env<AttrContext> env, JCMethodDecl tree, Function<JCBlock, R> attributedAction) { | ||
| JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile); | ||
| try { | ||
| annotate.queueScanTreeAndTypeAnnotate(tree.body, env, tree.sym); |
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.
Some adjustments were needed to make sure the type annotations were initialized correctly up to this point. I verified with our annotation processor in crExamples and everything still works.
| } | ||
|
|
||
| class BodyScanner extends TreeScanner { | ||
| class BodyScanner extends TreeScannerPrev { |
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: BodyScanner also defines a currentNode field to keep track of the node being visited. Unfortunately, this field is also used outside the scanning process -- e.g. before (at construction) and after (to finish up things). This means it is currently very hard to merge this field with TreeScannerPrev.currentNode. Maybe this is something we can look again in a separate PR.
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.
Ok, NVM, I think I found a good way to consolidate the code and get rid of that field.
| * reflection API (see jdk.internal.java.lang.reflect.code). | ||
| */ | ||
| public class ReflectMethods extends TreeTranslator { | ||
| public class ReflectMethods extends TreeScannerPrev { |
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've dropped the TreeTranslator supertype here, as it seems to me ReflectMethods doesn't need it; the only thing ReflectMethod does is generating models for quotable methods and lambdas. The models are stored in appropriate AST nodes, but we don't need to alter the structure of the AST (at least for now).
| } | ||
|
|
||
| // @@@: Only used for quoted lambda, not quotable ones. Remove? | ||
| ListBuffer<JCExpression> quotedCapturedArgs(DiagnosticPosition pos, BodyScanner bodyScanner) { |
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.
This was dead code
| * This is required to make sure that LambdaToMethod doesn't end up emitting the | ||
| * code for capturing the bound method reference receiver twice. | ||
| */ | ||
| JCExpression copyReferenceWithReceiverVar(JCMemberReference ref, JCVariableDecl recvDecl) { |
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.
This was used, but I think it was added long ago, before we cleaned up the compiler pipeline as part of flexible constructor bodies.
|
|
||
| CoreOp.FuncOp scanMethod() { | ||
| scan(body); | ||
| scan(body, currentNode); |
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.
These scan methods are tricky. When scanning a quotable method, currentNode points to the method decl (a JCMethodDecl node)., and body points at the method body (a JCBlock node).
But when scanning quotable lambdas, both currentNode and body point at a JCLambda. Hence the different "previous node" forced on the TreeScannerPrev::scan.
Webrevs
|
Fix all samples Fix HAT code
|
Note: while I have updated HAT code, I have not tested that it builds/works correctly. |
Actually, I was able to build -- but not to test as I do not have opencl setup here. |
PaulSandoz
left a comment
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.
This looks good (one minor comment about possibly redundant code check in the code reflection tester).
In a subsequent PR we can rename @CodeReflection to @Reflect and replace use of the term Quotable with Reflectable (we need to keep Quoted, its a more general concept and i cannot think of a better name right now.)
| checkModel(field, found, ir); | ||
| } else if (Quotable.class.isAssignableFrom(field.getType())) { | ||
| Quotable quotable = (Quotable) field.get(null); | ||
| } else { |
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.
Do we need the above check if (field.getType().equals(Quoted.class)) ...?
|
@mcimadamore this pull request can not be integrated into git checkout quotable_anno
git fetch https://git.openjdk.org/babylon.git code-reflection
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge code-reflection"
git push |
|
I am balking on following up and requiring use-site and declaration-site alignment: I worry the current verbosity is so unpalatable it will reduce folks willingness to experiment. We will somehow need to get there eventually with some new concise language feature(s). |
|
/integrate |
|
Going to push as commit 577c89e. |
|
@mcimadamore Pushed as commit 577c89e. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
The
Quotabletype is a marker interface that is used to mark lambda expressions and method reference for which javac should produce a code model (we call them quotable lambdas), as in:Since the lambda metafactory, nor
Op::opQuotableonly rely on this type in a superficial way, this PR simplifies the programming model by removingQuotableand use the@CodeReflectionannotation (now turned into a type annotation) to mark quotable lambdas, as in:Supporting this is relatively straightforward. The most complex part is, perhaps, to make sure that (a) the type annotation we care about is visible in the AST (javac is very lazy when it comes to fill in information on type annotations) and (b) make sure we don't end up using type annotations that appear in positions other than a cast. The latter point is important; if we have this:
we don't want the lambda to magically become quotable simply because the target method parameter has been annotated.
There's also other cases like:
If
@CodeReflectionis a type annotation, the above lambda has a target@CodeReflection Runnableand is also treated as a quotable lambda. What we want here instead is for@CodeReflectionto just act as a regular declaration annotation on the method.To address these issues, I've augmented both
ReflectMethodsand its associatedBodyScannerto keep track of the prviously visited node. This is done by having both classes extend a new simple scannerTreeScannerPrev, which "remembers" the node visited before the current one.Thanks to this, when we see a lambda we can see if the previous node was a cast, and if such a cast contained any type-annotated type. If so, we will treat the lambda as a quotable lambda.
This implementation tactic guarantees that type annotations will only be consulted when needed.
Progress
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/babylon.git pull/685/head:pull/685$ git checkout pull/685Update a local copy of the PR:
$ git checkout pull/685$ git pull https://git.openjdk.org/babylon.git pull/685/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 685View PR using the GUI difftool:
$ git pr show -t 685Using diff file
Download this PR as a diff file:
https://git.openjdk.org/babylon/pull/685.diff
Using Webrev
Link to Webrev Comment