Bug 321276 - JDT Core APIs don't recognize InnerClass constructor inside .class files
Summary: JDT Core APIs don't recognize InnerClass constructor inside .class files
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.6   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: 3.7 M2   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 322880 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-07-29 19:26 EDT by Prashant Deva CLA
Modified: 2010-09-14 06:19 EDT (History)
3 users (show)

See Also:


Attachments
Proposed fix (2.79 KB, patch)
2010-09-02 12:34 EDT, Olivier Thomann CLA
no flags Details | Diff
Proposed fix + regression test (8.29 KB, patch)
2010-09-03 10:00 EDT, Olivier Thomann CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Prashant Deva CLA 2010-07-29 19:26:42 EDT
This is a fully reproducible bug.

1. Reference some jar in your project. 
2. Attach its source.
3. Browse to an Inner class. 
4. Place your cursor inside the innner class constructor.

Now if the following code snippet is run, it returns null if the file is a .class file, however it returns an IMethod if the same is inside a .java file.


 
	private IMember getMethodAtCursor()
	{
		IJavaElement element = getSelectedJavaElement();
		if (element != null)
		{
			try
			{
				if (element instanceof ICompilationUnit)
				{
					element = ((ICompilationUnit) element).getElementAt(currentSelection.getOffset());
				} else if (element instanceof IClassFile)
				{
                                        //NOTE: this line will set element to null

					element = ((IClassFile) element).getElementAt(currentSelection.getOffset());
				}

				if (element instanceof IMethod || element instanceof IInitializer)
					return (IMember) element;
			} catch (JavaModelException e)
			{
				return null;
			}
		}

		return null;
	}
Comment 1 Prashant Deva CLA 2010-07-30 18:40:54 EDT
An even easier way to reproduce this bug is to open a .class file (with source of course), and open the outline view.
When you place your cursor inside the constructor of the inner class, the outline view doesnt sync and highlight the method inside the view, however it does so for every other method in the inner class.

My personal gut feeling says that its cause the inner class constructors take a hidden parameter to the 'this' pointer of the outerclass and that is messing with the signature that the text editor is passing which does not include the hidden parameter.
Comment 2 Stephan Herrmann CLA 2010-07-30 19:39:10 EDT
At a quick check I couldn't reproduce. Using Eclipse 3.6.0 I opened class
HashMap from the JRE and navigated to some of its inner classes like Entry.
In this scenario everything works as expected.

So you probably have either a different Eclipse version or a different inner
class.
Comment 3 Prashant Deva CLA 2010-07-30 19:42:36 EDT
could be some compiler specific thing in the class file.
try using a 1.5 compiled class file.
Comment 4 Stephan Herrmann CLA 2010-07-30 20:09:27 EDT
If it's fully reproducible on your machine we need to know what
exact Eclipse version you have and which example classes from
which jar you used.
Could you please provide these details? Thanks.
Comment 5 Prashant Deva CLA 2010-07-30 20:35:13 EDT
i am using eclipse 3.6.0.

did you try reproducing on 1.5 compiled class?
Comment 6 Olivier Thomann CLA 2010-07-30 23:06:55 EDT
(In reply to comment #5)
> i am using eclipse 3.6.0.
> did you try reproducing on 1.5 compiled class?
Prashant, please attach a test case that is showing the problem.
Thanks.
Comment 7 Prashant Deva CLA 2010-07-30 23:33:10 EDT
here ya go -

1. download berkeley db je 4.103
2. reference it and attach the src in eclipse.
3. navigate to the constructor of Store.InternalPrimaryIndex

you can see the problem manifest itself there.
Comment 8 Stephan Herrmann CLA 2010-07-31 18:40:49 EDT
(In reply to comment #7)
> here ya go -
> 
> 1. download berkeley db je 4.103
> 2. reference it and attach the src in eclipse.
> 3. navigate to the constructor of Store.InternalPrimaryIndex
> 
> you can see the problem manifest itself there.

OK, that get's us going. Here's a minimal test class:

public class Container {
    private class Inner<S> {
        Inner(String st/*, Class<S> s*/) {
            super();
        }
    }
}

- export as jar in the file system, 
- import into other project as external jar and attach source. 
Using the class as above everything works fine, however, when uncommenting 
the second ctor arg (and repeating the jar-steps) the outline indeed no longer
synchronizes with the editor, likely indicating a missing java element.
Comment 9 Olivier Thomann CLA 2010-08-01 10:27:58 EDT
Thanks for the test case. I'll investigate.
Comment 10 Olivier Thomann CLA 2010-09-02 12:32:41 EDT
*** Bug 322880 has been marked as a duplicate of this bug. ***
Comment 11 Olivier Thomann CLA 2010-09-02 12:33:20 EDT
The problem occurs only when the constructor has a generic signature. I believe the problem comes from the fact that the generic signature doesn't contain the enclosing instance.
Comment 12 Olivier Thomann CLA 2010-09-02 12:34:52 EDT
Created attachment 178060 [details]
Proposed fix

Stephan, could you please test it with your test case ?
Thanks.
I still need to add a regression test for it.
Comment 13 Olivier Thomann CLA 2010-09-03 10:00:11 EDT
Created attachment 178149 [details]
Proposed fix + regression test

Same patch with a regression test.
Comment 14 Olivier Thomann CLA 2010-09-03 11:24:07 EDT
Released for 3.7M2.
Regression test added in:
org.eclipse.jdt.core.tests.model.AttachSourceTests#testConstructorAccess
Comment 15 Stephan Herrmann CLA 2010-09-04 08:09:24 EDT
(In reply to comment #12)
> Created an attachment (id=178060) [details]
> Proposed fix
> 
> Stephan, could you please test it with your test case ?
> Thanks.
> I still need to add a regression test for it.

Sorry for the delay (I was away from the internet for some days).

I just picked up build N20100903-2000 and tried the scenarios from comment 8
and everything works as desired. Good job :)

Obviously the missing JavaElement was indeed the issue and your test
and fix are sufficient.
Comment 16 Dani Megert CLA 2010-09-14 06:19:59 EDT
Verified in I20100914-0100.