Skip to content
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

Fix interception of return statements in closures #100

Merged

Conversation

dwnusbaum
Copy link
Member

@dwnusbaum dwnusbaum commented Dec 8, 2022

Fixes #99

The code related to intercepting implicit Groovy casts in method return values in 5202432 caused two related bugs for closure expressions with explicit return statements:

  1. Closures that are not inside of a method (e.g. they are defined using @Field) and have explicit return statements cause an NPE during compilation
  2. For Closures that are inside of a method and have explicit return statements, the sandbox transforms the return statement and inserts a checked cast to the return type of the surrounding method, which is incorrect
  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests - that demonstrates feature works or fixes the issue

@@ -498,10 +498,13 @@ private Expression innerTransform(Expression exp) {
}
boolean old = visitingClosureBody;
visitingClosureBody = true;
ClassNode oldMethodReturnType = methodReturnType;
methodReturnType = ClassHelper.OBJECT_TYPE;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The declared type of the generated method is always Object.class, see here and here.

Comment on lines +1109 to +1113
"@groovy.transform.Field\n" +
"private static final field = [\n" +
" key: { x -> return x == 123 }\n" +
"]\n" +
"field.key(123)\n",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script used to throw an NPE during compilation in the sandbox.

Comment on lines +1119 to +1127
"File method() {\n" +
" def field = [\n" +
" key: { x -> return x }\n" +
" ]\n" +
" result = field.key(['secret.key'])\n" +
" null\n" +
"}\n" +
"method()\n" +
"result",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script used to return an instance of File (and intercept the File constructor call) in the sandbox.

Copy link
Member

@daniel-beck daniel-beck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable. Tests make sense to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BUG! exception in phase 'canonicalization': NPE in SandboxTransformer
2 participants