Bug 192670 - [api] need api to get from binding key to a IJavaElement
Summary: [api] need api to get from binding key to a IJavaElement
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P2 enhancement (vote)
Target Milestone: 3.4 M4   Edit
Assignee: Jerome Lanneluc CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 99358
  Show dependency tree
 
Reported: 2007-06-14 09:33 EDT by Martin Aeschlimann CLA
Modified: 2007-12-13 07:06 EST (History)
3 users (show)

See Also:


Attachments
Corresponding implementation and tests (20.85 KB, patch)
2007-11-27 04:07 EST, Jerome Lanneluc CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Aeschlimann CLA 2007-06-14 09:33:46 EDT
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.
Comment 1 Philipe Mulet CLA 2007-08-31 12:46:43 EDT
Would consider adding a project.findType(bindingKey) to handle all corner situations. This would still be a lookup operation.
Comment 2 Philipe Mulet CLA 2007-08-31 12:49:34 EDT
Actually, project#findElement(bindingKey) would be more interesting
Comment 3 Martin Aeschlimann CLA 2007-09-03 04:51:34 EDT
> Actually, project#findElement(bindingKey) would be more interesting
Agree!
Comment 4 Jerome Lanneluc CLA 2007-11-26 07:23:27 EST
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;
Comment 5 Martin Aeschlimann CLA 2007-11-26 08:26:23 EST
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)
Comment 6 Jerome Lanneluc CLA 2007-11-26 12:05:14 EST
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.
Comment 7 Jerome Lanneluc CLA 2007-11-27 04:07:24 EST
Created attachment 83847 [details]
Corresponding implementation and tests
Comment 8 Jerome Lanneluc CLA 2007-11-27 04:48:30 EST
API, implementation and tests released for 3.4M4
Comment 9 Maxime Daniel CLA 2007-12-11 07:27:28 EST
 * <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.
Comment 10 Maxime Daniel CLA 2007-12-11 07:28:25 EST
(Hit return too fast, sorry.)

The previous doc extract makes no sense at all to me. What do you mean?
Comment 11 Jerome Lanneluc CLA 2007-12-11 07:40:20 EST
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.
Comment 12 Jerome Lanneluc CLA 2007-12-12 06:42:06 EST
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>
Comment 13 Frederic Fusier CLA 2007-12-13 04:24:14 EST
Verified for 3.4M4 looking at JDT/Core v_829 contents.
Comment 14 Jerome Lanneluc CLA 2007-12-13 07:06:13 EST
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;