Bug 423123 - [1.8][navigation] Quick Type Hierarchy doesn't show all implementations of functional interface
Summary: [1.8][navigation] Quick Type Hierarchy doesn't show all implementations of fu...
Status: ASSIGNED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Text (show other bugs)
Version: 4.4   Edit
Hardware: All All
: P3 minor with 4 votes (vote)
Target Milestone: ---   Edit
Assignee: JDT-Text-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords: helpwanted
: 527758 549144 (view as bug list)
Depends on: 400905 425134
Blocks: 427110
  Show dependency tree
 
Reported: 2013-12-03 20:33 EST by Markus Keller CLA
Modified: 2022-07-17 04:10 EDT (History)
7 users (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 2013-12-03 20:33:38 EST
Before Java 1.8, the Quick Type Hierarchy could be used to quickly show all implementations of an interface.

Now, a functional interface and its abstract method can also be implemented by lambda expressions and method references, which both don't show up in a type hierarchy.

Always showing all lambda expressions is probably too much, since lambdas are expected to show up more frequently than anonymous classes.

Maybe we could show the lambdas and anonymous classes if there are only a few of them (<=10), and otherwise show a placeholder node "More than 10 lambdas / anonymous classes...", whose action would be to show the implementations in the Search view.

Search engine and type hierarchy currently don't contain lambdas, so we need some help from Core (but I'm not sure yet in what form). See also bug 423122 and bug 400905.
Comment 1 Srikanth Sankaran CLA 2014-02-25 03:35:27 EST
In  bug 400905, I am arranging so that search results will show the lambda
as an implementation of the functional interface. This is not fully
cooked yet - but soon should be

I am leaning towards NOT showing method references as implementations of
the functional interface - Though technically at least from one pov they
are, in another equally justifiable pov, they are just expressions which
manufacture an object that implements the interface. So just as we would
not view a method invocation expression that returns an object that implements
an interface as an implementation of that, we need not view a method
reference as an implementation.
Comment 2 Markus Keller CLA 2014-02-25 09:31:44 EST
(In reply to Srikanth Sankaran from comment #1)
I agree with adding only lambdas to the type hierarchy.

Method references should eventually be found by an ordinary search for references to the method. Filed bug 429012 for a new limitTo flag to find only method references.

(Bug 211748 is already open for adding limitTo information to the search matches, but we still don't have an urgent use case for that).
Comment 3 Srikanth Sankaran CLA 2014-03-14 05:54:18 EDT
Is some one looking at this ? This would be very nice to have for ECNA
demo - if at all possible in that time frame.

Greatly appreciate the progress see in https://bugs.eclipse.org/bugs/show_bug.cgi?id=429498, that would be nice to show case too.
Comment 4 Markus Keller CLA 2014-03-14 06:27:26 EDT
(In reply to Srikanth Sankaran from comment #3)
> Is some one looking at this ? This would be very nice to have for ECNA
> demo - if at all possible in that time frame.

Lambdas are already shown as ordinary implementations of a functional interface. This works in the Type Hierarchy view and in the Quick Hierarchy (on the interface and on the SAM). The proposed filter for huge amounts of lambdas is not implemented, but I didn't find that to be an issue so far.

I'm not sure if we really want method references to show up in the type hierarchy. In contrast to normal method implementations and lambdas, a method reference doesn't have a body, so I consider it more like a reference rather than a real subtype/implementation.

We currently don't have any infrastructure to find method references that are implementations of a given functional interface, so I don't think there's anything more we could do here for GA. Or do have a specific use case in mind that doesn't work right now?
Comment 5 Srikanth Sankaran CLA 2014-03-14 06:49:01 EDT
(In reply to Markus Keller from comment #4)
> (In reply to Srikanth Sankaran from comment #3)

> We currently don't have any infrastructure to find method references that
> are implementations of a given functional interface, so I don't think
> there's anything more we could do here for GA. Or do have a specific use
> case in mind that doesn't work right now?

We are in agreement on the treatment of method references.

If I do CTRL+T on the two places marked below:

import java.io.Serializable;

interface I2 {
	int foo(String s);
}

@FunctionalInterface
interface A2 extends I2 {
	@Override
	default int foo(String s) {
		return -1;
	}

	int bar(java.io.Serializable s);
}
public class X {
	public static void main(String[] args) {
		System.out.println("OK");
	}
	A2 a2 = (x) -> {
		// request quick hierarchy here.
		return x.hashCode();
	};
	
	A2 a = new A2() {
		// request quick type hierarchy here.
		@Override
		public int foo(String s) {
			return 0;
		}

		@Override
		public int bar(Serializable s) {
			return 0;
		}
		
	};
}

I see different treatment: When inside the lambda it is actually showing
the hierarchy of X.
Comment 6 Srikanth Sankaran CLA 2014-03-14 06:51:32 EDT
(In reply to Srikanth Sankaran from comment #5)

> I see different treatment: When inside the lambda it is actually showing
> the hierarchy of X.

If I select A2 and say CTRL+T, it shows the quick type hierarchy alright.
Comment 7 Srikanth Sankaran CLA 2014-03-14 06:54:04 EDT
Let us know if we have a finger in the pie somewhere :)
Comment 8 Markus Keller CLA 2014-03-14 07:59:19 EDT
(In reply to Srikanth Sankaran from comment #5)
That example suffers from bug 430310. This one works:

@FunctionalInterface
interface A2 {
	int bar(java.io.Serializable s);
}
public class X {
	A2 a2 = (x) -> {
		// request quick hierarchy here => opens on X
		return x.hashCode();
	};
}


(In reply to Srikanth Sankaran from comment #7)
> Let us know if we have a finger in the pie somewhere :)

Yes, and you won't like it. The Quick Type Hierarchy first tries to resolve the element at the selection with ITypeRoot#codeSelect(..). If that doesn't return anything, then we fall back to the enclosing scope and ask ITypeRoot#getElementAt(..). But since lambdas are not children of their parents, getElementAt() returns the IField a2, and hence we open the QH on the declaring type X.

To make this work, getElementAt() would have to return the enclosing lambda IMethod. Maybe lambdas need to become full-fledged children of their parent?

After bug 429785 and bug 429814 are fixed, we can work on bug 430039 to at least show the lambda's type hierarchy when the caret is in the "->".
Comment 9 Srikanth Sankaran CLA 2014-03-14 08:19:47 EDT
(In reply to Markus Keller from comment #8)
> (In reply to Srikanth Sankaran from comment #5)
> That example suffers from bug 430310. This one works:

Works as in shows the problem I think you mean - right.

OK, I'll see what we can do.
Comment 10 Markus Keller CLA 2014-03-14 08:47:06 EDT
> To make this work, getElementAt() would have to return the enclosing lambda
> IMethod. Maybe lambdas need to become full-fledged children of their parent?

Just to be clear: it's too late to do this for GA. We have too many places in code that assume they know what kinds of children they can expect.
Comment 11 Markus Keller CLA 2014-03-16 15:17:48 EDT
(In reply to Markus Keller from comment #8)
> To make this work, getElementAt() would have to return the enclosing lambda
> IMethod. Maybe lambdas need to become full-fledged children of their parent?

It's probably better to leave lambdas as second-class elements and solve this problem by adding a new API ITypeRoot#getDeepElementAt(int) or getElementAt2(int), which also returns pseudo-elements like ILocalVariables, ITypeParameters, and lambda IMethods and ITypes.
Comment 12 Noopur Gupta CLA 2016-04-15 09:54:13 EDT
Based on comment #11, this needs a new API from jdt.core.
Comment 13 Noopur Gupta CLA 2017-11-27 04:19:54 EST
*** Bug 527758 has been marked as a duplicate of this bug. ***
Comment 14 Till Brychcy CLA 2018-11-28 10:02:21 EST
Is this bug just about quick hierarchy or about all type hierarchies (it is marked as duplicate of bug 527758).

I think method references should definitely appear in the type hierarchy.

I just lost some time because I could not find the implementations of an interface. Turns out it was only implemented by method references (in following example by Some::new).

interface ISome {}

class Some implements ISome {
	Some(String arg, int otherArg) {}
}

interface ISomeFactory {
	ISome createSome(String arg, int otherArg);
}

class Usage {
	ISomeFactory getDefaultFactory() {
		return Some::new;
	}
}

Neither Type Hierarchy for ISomeFactory nor find implementations for createSome currently helps.
Comment 15 Jan Mothes CLA 2019-03-10 22:52:35 EDT
Agree with previous comment that it should be somehow possible to find all method references that are used to implement a certain interface (use case would just be general navigation & refactoring, lots of situations where it would be useful).

But for me it doesn't need to be shown in the "Type" hierarchy, there could be a separate view/command if it doesn't fit there.
Comment 16 Till Brychcy CLA 2019-07-10 12:26:39 EDT
*** Bug 549144 has been marked as a duplicate of this bug. ***
Comment 17 Eclipse Genie CLA 2022-07-17 04:10:11 EDT
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.

If you have further information on the current state of the bug, please add it. 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.