Bug 107590 - [source action] 'Override method' content assist does not use parameter names from overridden method
Summary: [source action] 'Override method' content assist does not use parameter names...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P2 normal (vote)
Target Milestone: 3.2 M2   Edit
Assignee: Tobias Widmer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-08-22 09:00 EDT by Markus Keller CLA
Modified: 2005-09-20 06:35 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Keller CLA 2005-08-22 09:00:10 EDT
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).
Comment 1 Dirk Baeumer CLA 2005-08-22 11:10:04 EDT
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.
Comment 2 Dirk Baeumer CLA 2005-08-22 11:11:22 EDT
The same happens for 1.4 source.
Comment 3 Tobias Widmer CLA 2005-08-22 11:42:52 EDT
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
Comment 4 Jerome Lanneluc CLA 2005-08-23 12:11:53 EDT
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.
Comment 5 Dirk Baeumer CLA 2005-08-24 06:45:06 EDT
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.
Comment 6 Dirk Baeumer CLA 2005-08-24 06:52:09 EDT
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.
Comment 7 Jerome Lanneluc CLA 2005-08-24 06:53:30 EDT
(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.
Comment 8 Jerome Lanneluc CLA 2005-08-24 06:56:54 EDT
(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.
Comment 9 Markus Keller CLA 2005-08-24 07:01:01 EDT
(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.
Comment 10 Tobias Widmer CLA 2005-08-24 08:10:34 EDT
Setting up the ASTParser using

parser.setUnitName(fCompilationUnit.getResource().getFullPath().toString());

seems to work.
Comment 11 Dirk Baeumer CLA 2005-08-24 08:34:28 EDT
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 ?
Comment 12 Jerome Lanneluc CLA 2005-08-24 08:47:07 EDT
(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.
Comment 13 Markus Keller CLA 2005-08-24 09:05:16 EDT
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.
Comment 14 Jerome Lanneluc CLA 2005-08-24 09:08:29 EDT
(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
Comment 15 Dirk Baeumer CLA 2005-08-24 13:52:33 EDT
Opened bug 107901 to clarify the Javadoc of setUnitName.

Tobias please fix in the 3.2 time frame.
Comment 16 Tobias Widmer CLA 2005-08-25 04:26:06 EDT
Fixed > 20050825
Comment 17 Tom Hofmann CLA 2005-09-20 06:31:37 EDT
verifying...
Comment 18 Tom Hofmann CLA 2005-09-20 06:35:55 EDT
verified correct parameter names are chosen both from within the same CU and a
separate CU.