Community
Participate
Working Groups
3.3 RC7 in bug 99358, we get an anonymous class proposal from code assist for a local class. public class A { public void bar() { class LocalClass { } LocalClass l= new LocalClass(<code assist>) } } When code assist is invoke, we need the IType of 'LocalClass'. We currently use the type signature provided by the anonymous class proposal and use project.findType(). This doesn't work for local types. The anonymous class proposal would also give the binding key of this type. If we had an API to get a Java element from a binding key, we could solve this problem.
Would consider adding a project.findType(bindingKey) to handle all corner situations. This would still be a lookup operation.
Actually, project#findElement(bindingKey) would be more interesting
> Actually, project#findElement(bindingKey) would be more interesting Agree!
Proposed API (Martin can you please comment?): /** * Finds the Java element corresponding to the given binding key. Elements are * looked up using this project's classpath. The first element corresponding to * the given key on this project's classpath is returned. * Returns <code>null</code> if the element is not found. * <p>As Java elements are not resolved, if a binding key contains resolved * information (see {@link IMethod#isResolved()} for example), this information * cannot be used to retrieve the method. Thus the first method with matching * simple parameter types (see {@link IType#findMethods(IMethod)} is returned. * </p> * * @param bindingKey the given binding key * @param owner the owner of the returned element's compilation unit, * or <code>null</code> if the default working copy owner must be * used * @exception JavaModelException if this project does not exist or if an * exception occurs while accessing its corresponding resource * @return the Java element corresponding to the given key, * or <code>null</code> if no such Java element is found * @since 3.4 */ IJavaElement findElement(String bindingKey, WorkingCopyOwner owner) throws JavaModelException;
Looks good! Maybe it would be good to name the elements the can result: IPackageFragment from package bindings, IType from type bindings, IMethod or IInitializers from method, and IField from variable bindings. Will it be possible to get ILocalVariable and IAnnotation elements as well? Would definitely be good to have! (bug not required for bug 99358)
New proposed API: /** * Finds the Java element corresponding to the given binding key. Elements are * looked up using this project's classpath. The first element corresponding to * the given key on this project's classpath is returned. * Returns <code>null</code> if the element is not found. * <p>Possible elements are: * <ul> * <li>{@link IPackageFragment} for a binding key from an * {@link IPackageBinding}</li> * <li>{@link IType} for a binding key from an {@link ITypeBinding}</li> * <li>{@link IMethod} for a binding key from an {@link IMethodBinding}</li> * <li>{@link IField} for a binding key from an {@link IVariableBinding} * representing a {@link IVariableBinding#isField() field}</li> * <li>{@link ITypeParameter} for a binding key from an {@link ITypeBinding} * representing a {@link ITypeBinding#isTypeVariable() type * variable}</li> * <li>{@link IAnnotation} for a binding key from an * {@link IAnnotationBinding}</li> * </ul></p> * <p>As Java elements are not resolved, if a binding key contains resolved * information (see {@link IMethod#isResolved()} for example), this information * cannot be used to retrieve the method. Thus the first method with matching * simple parameter types (see {@link IType#findMethods(IMethod)} is returned. * </p> * * @param bindingKey the given binding key * @param owner the owner of the returned element's compilation unit, * or <code>null</code> if the default working copy owner must be * used * @exception JavaModelException if this project does not exist or if an * exception occurs while accessing its corresponding resource * @return the Java element corresponding to the given key, * or <code>null</code> if no such Java element is found * @since 3.4 */ IJavaElement findElement(String bindingKey, WorkingCopyOwner owner) throws JavaModelException; Note that Initializers in the DOM don't have bindings. So the returned element will never be an IInitializer. Also since ILocalVariable are not part of the Java model (they can only be obtained through special operations like codeSelect(...)), the returned element will not be an ILocalVariable either.
Created attachment 83847 [details] Corresponding implementation and tests
API, implementation and tests released for 3.4M4
* <p>As Java elements are not resolved, if a binding key contains resolved * information (see {@link IMethod#isResolved()} for example), this information * cannot be used to retrieve the method. Thus the first method with matching * simple parameter types (see {@link IType#findMethods(IMethod)} is returned.
(Hit return too fast, sorry.) The previous doc extract makes no sense at all to me. What do you mean?
In the following test case, the binding key for the second foo(Y) is "LX;.foo(Lp2/Y;)V". import p1.Y; public class X { void foo(Y y) { } void foo(p2.Y y) { } } To know that the first foo(Y) is in fact foo(p1.Y) we would need to resolve, which we don't do in the Java model.
Reworded the last paragraph as follows: * <p>Note if two methods correspond to the binding key because they have * the same simple parameter types (e.g. <code>X.foo(p1.Y)</code> and * <code>X.foo(p2.Y)</code>), then the first one is returned.</p>
Verified for 3.4M4 looking at JDT/Core v_829 contents.
After Maxime's feedback, the latest version of this API has been released as: /** * Finds the Java element corresponding to the given binding key if any, * else returns <code>null</code>. Elements are looked up using this * project's classpath. The first element corresponding to * the given key on this project's classpath is returned. * <p>Possible elements are: * <ul> * <li>{@link IPackageFragment} for a binding key from an * {@link IPackageBinding}</li> * <li>{@link IType} for a binding key from an {@link ITypeBinding}</li> * <li>{@link IMethod} for a binding key from an {@link IMethodBinding}</li> * <li>{@link IField} for a binding key from an {@link IVariableBinding} * representing a {@link IVariableBinding#isField() field}</li> * <li>{@link ITypeParameter} for a binding key from an {@link ITypeBinding} * representing a {@link ITypeBinding#isTypeVariable() type * variable}</li> * <li>{@link IAnnotation} for a binding key from an * {@link IAnnotationBinding}</li> * </ul></p> * <p>Note: if two methods correspond to the binding key because their * parameter types' simple names are the same, then the first one is returned. * For example, if a class defines two methods <code>foo(p1.Y, String)</code> * and <code>foo(p2.Y, String)</code>, in both cases the parameter type's * simple names are <code>{"Y", "String"}</code>. Thus * <code>foo(p1.Y, String)</code> is returned.</p> * * @param bindingKey the given binding key * @param owner the owner of the returned element's compilation unit, * or <code>null</code> if the default working copy owner must be * used * @exception JavaModelException if this project does not exist or if an * exception occurs while accessing its corresponding resource * @return the Java element corresponding to the given key, * or <code>null</code> if no such Java element is found * @since 3.4 */ IJavaElement findElement(String bindingKey, WorkingCopyOwner owner) throws JavaModelException;