Community
Participate
Working Groups
I20040514 The binding of the simple name "Test" in the following statement "new Test();" is a ITypeBinding. Since the name refers to a constructor the binding should be a IMethodBinding.
I disagree. An allocation expression is formed by a type reference which itself points at a type binding. The allocation itself is carrying the constructor binding.
I disagree as well. When I think about a user then new Test() references the constructor not the type. So why do you think that getting the type is superior over getting the method binding. If I get the method binding I can reach the declaring type but not vice versa.
This is not critical for 3.0, but we need a more "intuitive" handling here. Refactoring as lots for work arounds to deal with the problem that search for types finds constuctor references and that in AST constructor references have type bindings.
The theory is that ClassInstanceCreation#resolveConstructorBinding() should answer the constructor you want. The child type reference is correctly answering a type binding. Isn't it what you are observing ?
new Test() is a class instance creation. it has resolveTypeBinding() => ITypeBinding it has resolveConstructorBinding() => IMethodBinding The name of this class instance creation should return a method binding. It also has a resolveTypeBinding() method that woule return an ITypeBinding. Let me check this.
The name itself denotes a type, it should be associated to a type binding. Occurrences of the same name in the same context would all reference to the same type binding. The constructor is referred to from the invocation expression which carries arguments, and thus denotes a specific constructor.
In this case, the name inside a class instance creation is a type reference and as a type reference it resolves to a type binding. We don't intent to change this. A visitor of the DOM/AST can easily get the constructor binding in this case using the class instance creation. I open bug 62650 to check inconsistencies in the DOM/AST binding resolution. A method ref inside Javadoc should also resolves to a type binding and not a method binding. We would change this that late in the cycle.
The problem is that we visit all SimpleNames in an AST. In the case outlined, the SimpleName Test in new Test() refers to an ITypeBinding, although in my opinion the name Test refers to the constructor. Letting the name refer to the constructor makes it easy to reach the type binding, but the other way doesn't work. We can work around this by handling ClassInstanceCreations special and don't visit the name but all the other children by hand. This is error prone since when JDT/Core adds new children to a ClassInstanceCreation we will not visit them. For normal method calls the name refers to a method binding as well. So I don't fully understand why this should be different for contructors.
Olivier, why is "new Test()" a type reference. It clearly reference a constructor.
I didn't say that new Test() is a type reference. It is a constructor reference and this is why you have a method resolveConstructorBinding() on ClassInstanceCreation. The Test name inside new Test IS a type reference and this is why this name resolves to a type binding. You should not visit just the names. We provide a visitor for each type of node. So it is not difficult to handle different types of nodes. In this case, the resolveConstructorBinding() on the Class instance creation node should return the binding you want.
Re: comment #8, the case for method reference names (aka selector) being bound to the method binding is a bug, and we have a PR for it which we will look into post 3.0. The method ref node itself should be the only node bound to the method binding. Similarily, in explicit constructor calls "super(), this()", there is no name you can attach the constructor binding either. These must be found through the constructor call itself.
Regarding visiting names: it is elegant and gives you a polymorphic way to handles names which belong to the same element. So I don't see why client's life must be hard and we have to handle all cases special. But to understand things correctly: class A { public A() { <== name refers to IMethodBinding } public void foo() { <== name refers to IMethodBinding new A(); <== name refers to ITypeBinding foo() <== name referes to IMethodBinding } public void A(String s) { <== name A refers to IMethodBinding A(s); <== name A refers to IMethodBinding } } I still don't see why the constructor must be an exception here. Regarding comment #11: if you change this it will very likely break most of our refactorings and mark occurrences code.
We will keep this behavior for 3.0, but it is clearly inconsistent. We will cleanup our implementation later. Each different reference has a specific node, if you don't want to consider them, but rely on some name to be bound (when unspecified), then you are just asking for trouble. A message send is bound to a method binding, a selector shouldn't be bound to anything; the selector doesn't have a receiver nor arguments; these belongs to the message send which naturally carries the target method binding then.
*** Bug 71574 has been marked as a duplicate of this bug. ***
As of now 'LATER' and 'REMIND' resolutions are no longer supported. Please reopen this bug if it is still valid for you.