Bug 460921 - [1.8] Content assist does not work in lambda with typed parameters
Summary: [1.8] Content assist does not work in lambda with typed parameters
Status: ASSIGNED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.5   Edit
Hardware: All All
: P3 normal with 4 votes (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug bulk move
Keywords: helpwanted
: 529723 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-02-26 06:51 EST by Noopur Gupta CLA
Modified: 2022-07-13 16:34 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 Noopur Gupta CLA 2015-02-26 06:51:39 EST
package p1;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

class C {
	List<String> names = Arrays.asList("Bob", "Dave", "Charlie", "Alice");
	
	{
		Collections.sort(names, (String a, String b) -> {
			sys
			return a.compareToIgnoreCase(b);
		});
		
		Collections.sort(names, (a, b) -> {
			sys
			return a.compareToIgnoreCase(b);
		});
	}
}

---------------------------------------------------

In the above example, press Ctrl+space after "sys". No proposals are shown at the first location where lambda has typed parameters. It works at the second location.

This used to work fine in Eclipse Luna 4.4(I20140606-1215).
Comment 1 Manoj N Palat CLA 2015-03-05 03:46:15 EST
Ref bug 437444 comment 171 commit
http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=f357f309273e0bfe8345ff708d18fa83c6a34931

This commit caused this issue to appear.
Comment 2 Manoj N Palat CLA 2015-03-05 22:05:28 EST
(In reply to Manoj Palat from comment #1)
> Ref bug 437444 comment 171 commit
> http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/
> ?id=f357f309273e0bfe8345ff708d18fa83c6a34931
> 
> This commit caused this issue to appear.

Note:
Specifically, the following part in LE.resolveType(BScope)
if (groundType != expectedSAMType) { //$IDENTITY-COMPARISON$
						if (!groundType.isCompatibleWith(expectedSAMType, this.scope)) { // the ground has shifted, are we still on firm grounds ? 
							blockScope.problemReporter().typeMismatchError(groundType, this.expectedType, this, null); // report deliberately against block scope so as not to blame the lambda.
	return this.resolvedType = null;
}
Comment 3 Sasikanth Bharadwaj CLA 2015-03-06 01:42:34 EST
The reason is CopyFailureException - copy fails because there are syntax errors in the code and recovery does not occur during copy. I remember there is another bug for this.
Comment 4 Bradley Odell CLA 2016-07-10 01:43:12 EDT
This bug still exists in Eclipse version 4.6 (Neon). I was about to report a new bug for it but this looks to be the same bug.

Also, this bug was reported last year. Why hasn't it been fixed yet?

Anyway, I found some information that may help.

The bug only happens when:
 * The lambda expression is being passed as a parameter to another function.
 * There are generics involved.

Take for example this piece of code.
Content Assist does not work on the 'someStringValue' variable.
The only way to get it to show the correct content assist is to add 'String' between the angle brackets of the EclipseBugClass to explicitly specify the generics type.

#################
# Start of Code #
#################

import java.util.function.Consumer;

public class EclipseBugClass<E> {
    
    public static void main(String[] args) {
        //new EclipseBugClass<>((String someStringValue) -> {
        new EclipseBugClass<String>((String someStringValue) -> {
            
        });
    }
    
    public EclipseBugClass(Consumer<E> consumer) {}
    
}

#################
#  End of Code  #
#################
Comment 5 Stephan Herrmann CLA 2016-07-10 07:03:11 EDT
Possibly a duplicate of bug 493705 (which has a proposed patch in gerrit).
Comment 6 Stephan Herrmann CLA 2018-01-06 09:10:38 EST
Retesting at today's HEAD I still see the CopyFailureException (despite bug 493705  being fixed).

Obviously, the incomplete Lambda has a syntax error thus letting re-parsing fail.
I just wonder, how the first round of parsing managed to create the Lambda in the first place.
Comment 7 Stephan Herrmann CLA 2018-01-06 09:35:28 EST
parseLambdaExpression explicitly sets haltOnSyntaxError=true; which was last edited via bug 401769. I wonder if this could be the key to the problem?
Comment 8 Stephan Herrmann CLA 2018-01-06 10:35:16 EST
After some experiments, I don't see much room for improvement in LE.copy()->Parser.parseLambdaExpression(), because likely the overall result will still just be a failed inference (even if we apply lots of tweaks to the parser to actually return the LE with errors, see that parseExpressions() always returns null when ERROR_ACTION was seen).

I believe the root problem is, that after inference failure we'll never really resolve the lambda body and thus never trigger CompletionNodeFound. In the case of comment 0 I saw 'false' returned from 
  groundType.isCompatibleWith(expectedSAMType, this.scope)


As a quick experiment, inserting resolving of the body right before the 'return' succeeds to bring at least some completion proposals. For templates this would be good enough, not sure if Java proposals needing resolved types will work well.

So, one question would be: can the compiler 'know' when it works on behalf of completion so that it can perform more resolving even after type errors?
Comment 10 Stephan Herrmann CLA 2018-08-26 09:15:48 EDT
Re-assessment after recent improvements in this area (e.g., bug 473654):

Using this variant:

//---
import java.util.function.Consumer;

public class EclipseBugClass<E> {
    
    public static void main(String[] args) {
        new EclipseBugClass<>((String someStringValue) -> {
            |
        });
    }
    
    public EclipseBugClass(Consumer<E> consumer) {}
    
}
//---

At | completion works, proposing things like 'args' and 'someStringValue'.

After inserting someStringValue plus a dot completion is silent.

At this point we see this recovered AST for the lambda:

(String someStringValue) -> {
  <CompleteOnName:someStringValue.>;
}

While it looks weird to see the dot as part of the name, this is only an artifact of the corresponding printExpression() implementation.

Result is still: CopyFailureException.

To be continued in 4.10.
Comment 11 Stephan Herrmann CLA 2019-02-05 15:47:27 EST
I'm stepping down from assignee to qa contact.
Comment 12 Manoj N Palat CLA 2019-08-27 02:07:22 EDT
Bulk move out of 4.13
Comment 13 Stephan Herrmann CLA 2020-04-17 15:31:48 EDT
*** Bug 529723 has been marked as a duplicate of this bug. ***
Comment 14 Eclipse Genie CLA 2022-07-13 16:34:36 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.