Community
Participate
Working Groups
I20050818-0800 'Override method' content assist does not use parameter names from the overridden method: import java.util.ArrayList; import java.util.List; import java.util.Set; public class A { List<Object> linearize(Set<Object> set) { return new ArrayList<Object>(set); } } class B extends A { //ContentAssist here, override linearize(..) } In the example, content assist inserts: @Override List<Object> linearize(Set<Object> arg0) { // TODO Auto-generated method stub return super.linearize(arg0); } Expected: uses 'set' instead of 'arg0'. A breakpoint in StubUtility2#suggestArgumentNames(..) reveals that IMethodBinding#getJavaElement() returns null. This may be be a consequence of the way the ASTParser is set up in OverrideCompletionProposal#updateReplacementString(). If I change it to ... parser.setSource(fCompilationUnit); ..., then it works in this case (but may invalidate the fix for bug 93249).
Tobias, can you please investigate. This same happens under 3.1.0 and we should try to fix this for 3.1.1. This again reminds me that we are missing some test cases here. When fixing this can you please start adding a test case for this bug.
The same happens for 1.4 source.
We set up the parser like this: final ASTParser parser= ASTParser.newParser(AST.JLS3); parser.setResolveBindings(true); parser.setSource(buffer.get().toCharArray()); parser.setUnitName(fCompilationUnit.getElementName()); parser.setProject(fCompilationUnit.getJavaProject()); To determine the argument names of the method, we use IMethodBinding#getMethodDeclaration on the method binding of the super implementation, call getJavaElement() and then IMethod#getParameterNames(). Because getJavaElement() returns null in this scenario, we are not able to compute the argument names. I do not see why getJavaElement() fails with the above setup. Moving to JDT core for comments
It is not possible to guess the IJavaElement with only the Java project and the compilation unit name. We would need the path, but unfortunately there is no API to set the path on ASTParser. I would suggest to use the full path (i.e. "/P/A.java") as the unit name in this case. Reading the spec for ASTParser#setUnitName(String), this is okay.
Jerome, locking at the code in ASTParser I doubt that this will work. BasicCompilationUnit require a CU name and a package name. When we add the full path to the CU name then the ASTParser should at least check for this and use the prefix as the package name. The relevant code is in ASTParser line 768. Jerome, can you please comment on this. Tobias, can you please give Jeromes suggestion a try.
Jerome, and an additional note: given the example from the description we are trying to get the Java element for the binding representing List<Object> linearize(Set<Object> set) in class A, NOT in class B. We build the AST for class B. So I understand that we can't get Java elements for elements declared in B but why not for A. There shouldn't be any difference where we created the AST for B using a char[] or a compilation unit.
(In reply to comment #5) > Jerome, locking at the code in ASTParser I doubt that this will work. > BasicCompilationUnit require a CU name and a package name. When we add the full > path to the CU name then the ASTParser should at least check for this and use > the prefix as the package name. The relevant code is in ASTParser line 768. > > Jerome, can you please comment on this. > Actually BasicCompilationUnit optinally requires a package name. ASTParser currently passes null as the package name. The other argument needed by BasicCompilationUnit is a file name, even if a unit name is acceptable in cases where the source is also passed in. So passing in a full path as the file name should allow the IJavaElement to be found.
(In reply to comment #6) > Jerome, and an additional note: given the example from the description we are > trying to get the Java element for the binding representing List<Object> > linearize(Set<Object> set) in class A, NOT in class B. We build the AST for > class B. So I understand that we can't get Java elements for elements declared > in B but why not for A. There shouldn't be any difference where we created the > AST for B using a char[] or a compilation unit. Not sure I understand this. In this particalar case, the binding of class A is asked for its Java element. We fail to return it because we don't have enough information to where A resides. If you asked for the IJavaElement to the binding of class B, we would fail the same way.
(In reply to comment #6) Dirk: It depends on how you set up the test. If both declarations for A and B are in one CU, then it fails because the AST of A is the same as the AST for B. If B is in a separate CU, then the argument names are correctly copied from A.
Setting up the ASTParser using parser.setUnitName(fCompilationUnit.getResource().getFullPath().toString()); seems to work.
Sorry for the confusion but I misinterpreted the PR. Here is my new understanding: - the problem only happens if both classes A and B are in the same buffer. It works if both types reside in separate CUs/buffers - setting the full path works however it seems not to be the way how the setUnitName API is supposed to be used. Given this I now opt for the following: - not critical anymore for 3.1.1 since having the two types in one buffer isn't common - we decide on whether we want to use setUnitName in 3.2 with the full path or if we want to add new API. Comments ?
(In reply to comment #11) > - we decide on whether we want to use setUnitName in 3.2 with the full path > or if we want to add new API. > I would opt to keep this API as this is exactly its purpose ("This is used [...] to locate the compilation unit"). Maybe the name of the API was not carefully chosen, but I think it is still okay. If we agree to keep it, I will enter a bug to clarify the spec and say that a full path can also be passed in.
I agree that this bug is not severe enough to deserve a 3.1.1 fix. Jerome: Couldn't the ASTParser fetch the package from the given source, such that getJavaElement() works correctly? The bindings already know in which package they live, so I guess it should be possible to use that information for creating java elements as well. Otherwise, the javadoc should explicitly mention the lost functionality when no full path is passed.
(In reply to comment #13) > Jerome: Couldn't the ASTParser fetch the package from the given source, such > that getJavaElement() works correctly? The bindings already know in which > package they live, so I guess it should be possible to use that information > for creating java elements as well. > Unfortunately the binding doesn't know the package fragment root this package belongs to. This is necessary to recreate the IJavaElement. > Otherwise, the javadoc should explicitly mention the lost functionality when > no full path is passed. Agreed
Opened bug 107901 to clarify the Javadoc of setUnitName. Tobias please fix in the 3.2 time frame.
Fixed > 20050825
verifying...
verified correct parameter names are chosen both from within the same CU and a separate CU.