-
-
Notifications
You must be signed in to change notification settings - Fork 353
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 access lookup in lambda for noclasspath mode. #814
Fix access lookup in lambda for noclasspath mode. #814
Conversation
Until now, a token within a lambda (noclasspath mode) is always considered a variable access (in particular a CtLocalVariable), though, it also could refer to a type---a class for instance. This commit adds two features: 1) An improved variable lookup method which ensures that a found variable is visible in current context. Furthermore, the amount of cloned code has been reduced. 2) Check if a given token (SingleNameReference) is a variable or type access and create an appropriate AST node instead of always creating a local variable reference.
The recent commit fixes the anonymous class issue by creating an 'empty' |
I fixed the second test case as well by replacing: int sourceEnd = (int) (positions[qualifiedNameReference.indexOfFirstFieldBinding - 1] >>> 32) - 2; with: int sourceEnd = qualifiedNameReference.sourceEnd(); as described in #813. The following things are missing:
|
Thanks, it looks interesting. However, "enhance" is vague, a PR is either a "bug fix" or a "new feature". What's this one? Could you add the associated test cases? Thanks. |
Working on it.
It is a bug fix. |
ok, I've renamed the PR. |
…iables declared in super classes/interfaces.
The recent commit adds the first lines to search for variables imported statically or declared by super classes/interfaces. Anyhow, the creation of the CtField is still missing since I'm not entirely sure how to properly create one. |
I have added a small test showing that a TypeAccess (Strings in our example) is mapped to a local variable access. Further tests with different variable access types, for instance, field access, statically imported variables and so on are coming soon. However, this simple test should give you an idea of what I'm trying to fix. |
I just added another test with a field access. In current master this test fails to compile the code due to #813. |
Recent commit should properly find variables in super classes/interfaces. I will add some test cases tomorrow. |
Furthermore, fixed the test class FieldAccessInLambda.java.
// try to find the variable on stack beginning with the most recent element | ||
for (final ASTPair astPair : stack) { | ||
// the variable may have been declared directly by one of these elements | ||
final List<U> variables = astPair.element.getElements(new AbstractFilter<U>() { |
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.
Why do you use an AbstractFilter instead of EarlyTerminatingScanner?
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 think there was a reason but let me have a look if an EarlyTerminatingScanner is feasible.
Recent commit uses EarlyTerminatingScanner instead of AbstractFilter making it faster in finding variables. |
…bleAccessNoClasspath`.
I think the PR should be ready now. I will write a summary later depicting what I improved/fixed. |
So, here is the summary:
public class A {
private final String title;
...
public void aMethod(final String title) {
....
}
public void anotherMethod() {
System.out.println(title); // <------
}
} In method
So, I would be appreciated if you could review this commit the next days (and maybe merge it into master) because I we really need the changes for our study we want to conduct the next days :). I know that this pr contains a lot of changes but maybe I could explain why they are necessary. |
public boolean matches(final CtTypeAccess element) { | ||
return element.getAccessedType().getSimpleName().equals("Strings"); | ||
} | ||
}).size(), 1); |
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.
The expected value (1) must be the second parameter of assertEquals
I think this is a very nice PR, thanks a lot. It improves much the noclasspath mode. Since it's a large PR, I wait until tomorrow for merging, to let the other contributors have a look at it. |
Thanks a lot for your hard work on this touchy issue. |
This is a work in progress pull request showing my current work on an enhanced variable lookup for
SingleNameReference
tokens in lambda expressions (noclasspath mode). It took me some time to understandJDTTreeBuilder
and all its helper classes but I think this is going into right direction, though.As you might already have noticed, there are two test cases that fail. The first one is a good example for #813 and can be fixed by using
int sourceEnd = qualifiedNameReference.sourceEnd();
. The second test case fails becausemethodJDT.binding
isnull
for anonymous classes`. Since I'm not sure how to create a type reference to an anonymous class (yet), I was not able to properly handle this case.Furthermore,
getVariableDeclaration
is not finished yet as there might be a variable declared in a super class/interface. This case can be handled by iterating through all super classes/interfaces of aTypeBinding
and checking if the potential variable has been declared in one of them. Unfortunately, I did not managed to create aTypeDeclaration
from aTypeBinding
yet. Maybe you have an idea how to do that.However, in it's current state this pr produces much more precise AST in noclasspath mode as a
SingleNameReference
in a lambda expression is not always mapped to aCtLocalVariableReference
. In addition,getVariableDeclaration
reduces the amount of cloned code and ensures that a variable is visible in current context.