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

Bug 422468

Summary: [1.8][assist] Code assist issues with type elided lambda parameters
Product: [Eclipse Project] JDT Reporter: Srikanth Sankaran <srikanth_sankaran>
Component: CoreAssignee: Srikanth Sankaran <srikanth_sankaran>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: anchakrk, daniel_megert, jarthana, markus.kell.r, noopur_gupta, shankhba, stephan.herrmann
Version: 4.4Flags: srikanth_sankaran: review? (anchakrk)
Target Milestone: BETA J8   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Bug Depends on:    
Bug Blocks: 402079    
Attachments:
Description Flags
Snap shot of work in progress
none
Patch v0.9
none
Patch v0.99 none

Description Srikanth Sankaran CLA 2013-11-25 07:20:49 EST
BETA_JAVA8:

At present, there are a set of problems in the way type elided lambda parameters
are handled by SelectionEngine/SelectionParser. Similar but different issues 
exist with CompletionEngine/CompletionParser too.

Given:

// --
interface I {
	String foo(String x, Integer y);
}
public class X {
	static void foo(I i) {}
	public static void main(String[] args) {
		foo((x, y) -> x + y);
	}
} 

(1) if you hover on either of x or y in x + y, we claim those are of type
Object - this is blatantly wrong, but happens because the selection parser
builds minimal parse trees in which a good bit of the pertinent contextual
information is lost.

The flattened parse tree for the method looks like:

public static void main(String[] args) {
    (<no type> x, <no type> y) -> <SelectOnName:y>;
}

See that the fact about lambda being a method parameter is completely
lost.

I see this as requiring good amount of work to get correctly. Because
lambda's can occur is deeply nested subexpressions, involving numerous
node types, this is not going to be easy solution to "enhance" the
selection/completion parser

(2) If you hover on the parameter declaration, you get nothing. This is
problematic as users will identify this as a classic situation where the
IDE should help clarify things for them.

(3) The hover on the use actually claims:

 Object y - X.main(String[])

This could perhaps be due to bug 416559 ? 

// --

Discussions welcome on how to go about solving this or alternate strategies.
Comment 1 Srikanth Sankaran CLA 2013-11-25 08:47:16 EST
Well, this is really bad for code completion. Members { methods | fields |
types } will be inaccessible unless we can infer the type and the skeletal
parse tree simply does not help. I think if an enclosing method of a lambda
with type elided parameter must be fully reconstructed for things to work
properly with elided types.
Comment 2 Srikanth Sankaran CLA 2013-11-25 09:29:52 EST
(In reply to Srikanth Sankaran from comment #1)

> I think if an enclosing method of a lambda
> with type elided parameter must be fully reconstructed for things to work
> properly with elided types.

Correction: Not the enclosing method, but the ExpressionStatement containing
the lambda must be fully recovered.

Relevant production from JLS(7):

ExpressionStatement:
    StatementExpression ;

StatementExpression:
    Assignment
    PreIncrementExpression
    PreDecrementExpression
    PostIncrementExpression
    PostDecrementExpression
    MethodInvocation
    ClassInstanceCreationExpression

Assignment:
    LeftHandSide AssignmentOperator AssignmentExpression

AssignmentExpression:
    ConditionalExpression
    Assignment
    LeftHandSide:
    ExpressionName
    FieldAccess
    ArrayAccess

AssignmentOperator: one of
= *= /= %= += -= <<= >>= >>>= &= ^= |=
Comment 3 Srikanth Sankaran CLA 2013-11-25 09:33:26 EST
(In reply to Srikanth Sankaran from comment #2)

> Correction: Not the enclosing method, but the ExpressionStatement containing
> the lambda must be fully recovered.

Current recovery strategy used by SelectionParser and CompletionParser are
woefully inadequate for this task: i.e We cannot add more RecoveredElement
abstractions for every kind of node type that would be involved. The list
of productions from comment#2 are the top level productions. They will pull
in other non terminals which will pull in other non terminals which will pull
in other non terminals ... and so on.

I'll prototype an alternate strategy.
Comment 4 Srikanth Sankaran CLA 2013-11-28 02:29:59 EST
I have a very promising solution that works well for code select. Code complete
is a a lot more trickier.
Comment 5 Srikanth Sankaran CLA 2013-11-28 11:29:03 EST
Via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=BETA_JAVA8&id=227e3d5fec0001fbc06115e3f3e6f09f357952e2, I released full
support for selection inside lambda expressions including type elided
parameter declarations and usages.

Turned out that there is some prior art to such recovery past the selection
point. It didn't lend itself to being extended for lambdas, but was useful to
study to understand the issues.

Anirban, please review.

Shankha, this invalidates your patch yet again, please repost after fixing
merge issues.

It is likely we may get rid of the new RecoveredLambdaExpression abstraction
altogether - I didn't want to prune it over-eagerly till code completion support
is in place.
Comment 7 Srikanth Sankaran CLA 2013-12-03 12:11:33 EST
OK, I got the basics working: 

In this program the line with the System.out.println call was completely
composed by code completion.

Still quite a ways to go with some major challenges.

// --


interface I {
	void foo(Integer x);
}

public class X {
	String xField;
	static void goo(String s) {
		
	}
	static void goo(I i) {
		
	}
	public static void main(String[] args) {
		goo((xyz) -> {
			System.out.println(xyz.toString().concat("Hello").hashCode());
		});
	}
}
Comment 8 Srikanth Sankaran CLA 2013-12-09 09:29:15 EST
Created attachment 238163 [details]
Snap shot of work in progress

Just so if something should happen to my hard disk: here is a snap shot.

Many things work, many still don't, but the foundation is firmly in place.
Comment 9 Srikanth Sankaran CLA 2013-12-11 09:18:30 EST
Created attachment 238252 [details]
Patch v0.9

Down to four failures. 

Quite of bit of clean up is required as there is lot of experimental code left in.

Expect to wrap this up tomorrow.
Comment 10 Srikanth Sankaran CLA 2013-12-12 14:31:04 EST
Created attachment 238301 [details]
Patch v0.99

Tom Cargill is correct ! (http://en.wikipedia.org/wiki/Ninety-ninety_rule) :)

Nearly there. All tests are green and most things work though there are a bunch
of loose ends which I plan to address in follow up bugs.

Just one final round of code review and clean up and I am ready to push this.
Most importantly, the review should look into ascertaining that the algorithm
will terminate ;-)
Comment 11 Srikanth Sankaran CLA 2013-12-13 02:28:10 EST
Fix and tests released here: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=BETA_JAVA8&id=a98d7d87df415161ba75f53acbdbe8d316ea160c.

Follow up tasks have been collected here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=423987

Anirban, please review. Also take up verification of the entire code assist
support to gauge what is still missing.