Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 484396

Summary: Eclipse fails to find implementations of interface methods inherited from another class
Product: [Eclipse Project] JDT Reporter: Samrat Dhillon <samrat.dhillon>
Component: CoreAssignee: JDT-Core-Inbox <jdt-core-inbox>
Status: CLOSED WONTFIX QA Contact:
Severity: major    
Priority: P3 CC: samrat.dhillon, stephan.herrmann
Version: 4.6   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard: stalebug

Description Samrat Dhillon CLA 2015-12-15 09:07:51 EST
Use the below snipped to reproduce this problem

public interface Foo {
	
	void bar();

}


public  class AbstractFoo {
	public void bar(){
		
	}
}

public class FooImpl extends AbstractFoo implements Foo{

}


public class TestImpl {
	Foo foo;
	public void test(){
//Do ctrl+mouse hover and click open implementations. 
//Eclipse will not be able to find implementation inherited from AsbtractFoo
		foo.bar();
	}

}

Here eclipse correctly determines that FooImpl implements the interface method by extending AbstractFoo and does not gives any compilation error. However when do you do a ctrl+mouse hover to find the implementations of this interface method, it is not able to find it in the AbstractFoo. 

Marking this as major (although I am inclined to mark it as critical) as you would expect this simple functionality to be working in any java IDE.
Comment 1 Stephan Herrmann CLA 2015-12-15 09:12:55 EST
I'd argue that this is correct behavior, because AbstractFoo.bar() does *not* implement Foo.bar() - AbstractFoo would need to implement Foo for this. Only FooImpl.bar() implements Foo.bar(), but that method doesn't "exist".

We would have to invent a new element like "PhantomMethod" to represent "AbstractFoo.bar() as seen from FooImpl".
Comment 2 Stephan Herrmann CLA 2015-12-15 09:15:30 EST
(In reply to Samrat Dhillon from comment #0)
> ... expect this simple functionality to be working in any java IDE.

very few things are simple when implementing tools for Java :)
Comment 3 Samrat Dhillon CLA 2015-12-15 09:24:52 EST
(In reply to Stephan Herrmann from comment #1)
> I'd argue that this is correct behavior, because AbstractFoo.bar() does
> *not* implement Foo.bar() - AbstractFoo would need to implement Foo for
> this. Only FooImpl.bar() implements Foo.bar(), but that method doesn't
> "exist".
> 
> We would have to invent a new element like "PhantomMethod" to represent
> "AbstractFoo.bar() as seen from FooImpl".

IMHO I would disagree. Java compiler is not giving any compilation error that FooImpl does not implements the method bar(). If the compiler behaviour is according to JLS then the IDE should also behave the same way.
Comment 4 Samrat Dhillon CLA 2015-12-15 09:32:53 EST
(In reply to Stephan Herrmann from comment #2)
> (In reply to Samrat Dhillon from comment #0)
> > ... expect this simple functionality to be working in any java IDE.
> 
> very few things are simple when implementing tools for Java :)

Yes Sir :). But other IDE's like IntelliJ do not have these issues and you tend to have similar expectations in eclipse as well. I would want to keep using eclipse but these issues are not very encouraging :).
Comment 5 Stephan Herrmann CLA 2015-12-15 09:48:13 EST
(In reply to Samrat Dhillon from comment #3)
> (In reply to Stephan Herrmann from comment #1)
> > I'd argue that this is correct behavior, because AbstractFoo.bar() does
> > *not* implement Foo.bar() - AbstractFoo would need to implement Foo for
> > this. Only FooImpl.bar() implements Foo.bar(), but that method doesn't
> > "exist".
> > 
> > We would have to invent a new element like "PhantomMethod" to represent
> > "AbstractFoo.bar() as seen from FooImpl".
> 
> IMHO I would disagree. Java compiler is not giving any compilation error
> that FooImpl does not implements the method bar(). If the compiler behaviour
> is according to JLS then the IDE should also behave the same way.

I don't think you understood my reasoning. I'm not saying that the program has an error. Let me put it this way: the method you want to jump to does not have any source code, hence we cannot offer such functionality. Jumping to AbstractFoo.bar() would be wrong.

See, e.g., the following expectation / invariant:

When I navigate from an interface method to one of its implementations, it is always possible to navigate back by searching for declarations of the given method (in Eclipse using Ctrl-t, e.g.). Do you agree?

Looking at AbstractFoo.bar() this method does not have any declaration in a super type, because AbstractFoo has no super type (aside from j.l.Object), so AbstractFoo.bar() cannot be the implementation of any supertype method.

If we'd show an implementation of Foo.bar() we'd need to jump to FooImpl, but where in that class would we highlight method bar()??

The real trouble with Java is that people have different expectations regarding examples that look simple at first but at a closer look prove to be far from it.
Comment 6 Eclipse Genie CLA 2020-01-27 14:48:45 EST
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug.

If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.
Comment 7 Stephan Herrmann CLA 2020-01-27 15:37:44 EST
Just to close a loop: there *is* a view that correctly shows the relationship:

1. Open Typehierarchy on FooImpl
2. select "Show the Supertype Hierarchy" 
3. select interface Foo
4. in the details pane select method bar()
5. in the toolbar above the details select "Lock View and Show Members in Hierarchy".

Other than that Foo.bar() and AbstractFoo.bar() are not connected (and FooImpl.bar() does not exist).