Community
Participate
Working Groups
2 things - not sure if they're bugs <source> package p; class A { private void a(){ int i= 0; int y= i+1; } } </source> calling resolveBinding on SimpleName 'i' (from VariableDeclaration) returns null calling resolveBinding on the VariableDeclaration returns (correctly) VariableBinding is it ok that i have to go up 1 level here to get any useful information? one more thing: getKey() returns null - the only way i can access any useful info on the binging is getVariableId() is that the expected bahavior?
Ask Dirk. He explicitly said that he doesn't need to resolve bindings on name if they are part of a declaration. I can add this, but I'd like a consistent view from you guys about what you want.
The geyKey() method returns null for all local variables. Look at the specification of getKey() on IBinding. If you want the first problem to be solved, let me know, but I won't remove it once done.
Olivier, Dirk did not consult that with me (before i dig into details i cannot know what exactly i will need and i started that new-ast conversion just recently) i will first try without it and see how much code i have to add to work around it the getKey() returning null - i did have a look at the javaDoc on IBinding before (just wanted to confirm the bad news). i guess i will have to live with this null (the spec says 'may be null' - so i can just assume it's always null <g>) anyway, can i uniquely identify a temp by getVariableId() together with MethodDeclaration::resolveBinding().getKey() ? (same question asked on the mailing list - sorry for duplication)
Maybe I misunderstood what Dirk wanted. I am not saying you are wrong. It is simple for me to add this resolution of name inside local declaration. For the getVariableId() question, I guess that if the two locals are at the same place (same block and same positions compare to other locals), then this value should be equals for both.
I think in order to be consistent we should always be able to resolve a binding for a name even if this name is part of a declaration.
Regarding returning null for simple names when used inside a declaration. The motivation for this one was that we need to distinguish if a name is a reference to something or if it is simple a string inside a declaration. For refactoring we need this information and in the old AST it was easy since there are two different nodes: a reference node and a char[] (which is not really a node). Returning null from resolveBinding turned out to be a bad mechanism to do this since a name also returns null if the binding can't be resolved. Olivier, can you propose some mechanism to do provide that information. Regarding returning null from getKey. I will look into this one and will open a spearate PR for it.
Would it be enough for you to use the findDeclaringNode() on the compilation unit. If this returns null, it means that the resolved binding is created in a declaration. You could test the class of the parent as well. So let me know if you want me to add the name resolution for name inside declaration or if I leave it as is.
I would like to see a more explicit support to distinguish names that reference a Java element from names used inside a declaration. The old AST used char[] for declarations and Reference (and subclasses) for references. My proposals are: - we introduce a ReferenceNode to make that difference clear, or - we add a method isDeclaration() to SimpleName.
I'd favour a solution that did not introduce new node types. SimpleName.isDeclaration() would return true iff the nodes was used in the declaration position of its parent node. This would include name of TypeDeclaration name of MethodDeclaration name of VariableDeclarationFragment name of SingleVariableDeclaration name of QualifiedName in name of PackageDeclaration name of PackageDeclaration How does this sound? Are there others?
Will you add an API for settings this flags? I am asking this, because during the conversion I know that a name is used in a declaration. Once the conversion is done, it is much more painful to retrieve this information.
Having the additional method isDeclaration would solve the problem that we have to distinguish between references and declarations. If we add this API then Name.resolveBinding should return a valid value even if the name is used inside a declaration. But please DON'T change the behaviour of Name.resolveBinding for the M5 build since some of out code relies on the fact that the method return null for declarations.
Then we should defer this change post M5. API and changes in ASTConverter should be done post M5.
The API isDeclaration() has been added for SimpleName post build 0411. You can ask me for an update of JDT/Core if you want to update your code checking for null returned by resolveBinding(). I will update the ASTConverter to return a valid binding for such simple names as soon as your code has been updated. So please annotate this PR when you're done.
Can I update the AST/DOM code? I'd like to reintroduce a valid binding for names even if they are in a declaration.
I'd like to get rid of the current implementation which returns null for names inside declarations. Could you please confirm that you are not relying on this anymore?
Adapted flow analyzer to new API
The name inside declarations will return a valid binding when using resolveBinding() in the next integration build.
Fixed and released in HEAD.
I notice that SimpleName.resolveBinding() still returns null for names in variable declarations using the latest integration build (I200208270833). Has this fix not made it's way out to us mortals yet or is there something else going on? Thanks IWorkspace ws = testcasesPlugin.getWorkspace(); IWorkspaceRoot root = ws.getRoot(); IProject project = root.getProjects()[0]; IJavaProject jp = JavaCore.create(project); CompilationUnit cu = AST.parseCompilationUnit( "public class Class {void theMethod() {int local;for (int i = 0; i < 5; ++i) {} } }".toCharArray(), "Class", jp); cu.accept(new ASTVisitor() { public boolean visit(SimpleName node) { IBinding binding = node.resolveBinding(); if (null == binding) { System.out.println("Null binding for SimpleName " + node.getIdentifier ()); } return true; } }); Output: Null binding for SimpleName local Null binding for SimpleName i
I am investigating what could be wrong.
Released in 2.1 stream only for now.
Verified.
Regression tests added (test0364, test0365)