Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 403444 - [1.8][dom ast] CCE when resolving binding for malformed LambdaExpression in JLS4 AST
Summary: [1.8][dom ast] CCE when resolving binding for malformed LambdaExpression in J...
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.3   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: BETA J8   Edit
Assignee: Manoj N Palat CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-03-15 07:46 EDT by Markus Keller CLA
Modified: 2013-03-18 05:55 EDT (History)
2 users (show)

See Also:
srikanth_sankaran: review+


Attachments
Proposed Patch (5.18 KB, patch)
2013-03-18 00:50 EDT, Manoj N Palat CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Keller CLA 2013-03-15 07:46:34 EDT
Inspect example from bug 402665 in ASTView with AST Level 4:

package jsr335;

public class SpecExamples335 {
	public static interface StringToInt {
		int stoi(String s);
	}
	public static interface ReduceInt {
		int reduce(int a, int b);
	}
	
	void foo(StringToInt s) { }
	void bar(ReduceInt r) { }
	
	void bar() {
		foo(s -> s.length());
		foo((s) -> s.length());
		foo((String s) -> s.length());
		
		bar((x, y) -> x+y);
		bar((int x, int y) -> x+y);
	}
}

When I drill down to the argument of "foo(s -> s.length())", I get this exception:

java.lang.ClassCastException: org.eclipse.jdt.internal.compiler.ast.LambdaExpression cannot be cast to org.eclipse.jdt.internal.compiler.ast.Literal
	at org.eclipse.jdt.core.dom.DefaultBindingResolver.resolveExpressionType(DefaultBindingResolver.java:735)
	at org.eclipse.jdt.core.dom.Expression.resolveTypeBinding(Expression.java:113)
	at org.eclipse.jdt.astview.views.ASTViewContentProvider.getNodeChildren(ASTViewContentProvider.java:112)
...
Comment 1 Srikanth Sankaran CLA 2013-03-15 08:36:17 EDT
This is due to partial implementation of the charade outlined in https://bugs.eclipse.org/bugs/show_bug.cgi?id=402673#c2
Comment 2 Srikanth Sankaran CLA 2013-03-15 09:06:12 EDT
(In reply to comment #1)
> This is due to partial implementation of the charade outlined in
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=402673#c2

Note that org.eclipse.jdt.core.dom.BindingResolver.resolveExpressionType(Expression) is
documented as possibly returning null.

So in ASTConverter.recordNodes, if JLS level < 8 and DOM node is NullLiteral
and compiler node is LambdaExpression - don't record anything could be
a strategy.

This completion of the charade is a lot simpler than equipping 70+ places
to be prepared to handle nulls in what is basically a broken scenario.
Comment 3 Srikanth Sankaran CLA 2013-03-15 09:47:02 EDT
We could easily avoid these round trips to JDT/UI if we adopt the usage of
ASTView plugin in our own testing more widely. Jay & Manoj, please make note,
Thanks.
Comment 4 Markus Keller CLA 2013-03-15 10:37:47 EDT
(In reply to comment #3)
I agree with that. However, this particular problem only seems to appear in certain situations, but not everywhere a LambdaExpression is involved. E.g. for the example in bug 402673, it doesn't happen (binding is just null, which is OK). And you have to drill down to the node to actually run into it. But checking a few other examples that are lying around in the runtime workbench never hurts...

I looked for similar cases, but I only found ASTConverter#createFakeEmptyStatement(Statement), where there are no problems with bindings. I support the general approach to convert a LambdaExpression into a malformed NullLiteral.
Comment 5 Manoj N Palat CLA 2013-03-16 19:46:32 EDT
(In reply to comment #2)
> (In reply to comment #1)
> > This is due to partial implementation of the charade outlined in
> > https://bugs.eclipse.org/bugs/show_bug.cgi?id=402673#c2
> 
> Note that
> org.eclipse.jdt.core.dom.BindingResolver.resolveExpressionType(Expression) is
> documented as possibly returning null.
> 
> So in ASTConverter.recordNodes, if JLS level < 8 and DOM node is NullLiteral
> and compiler node is LambdaExpression - don't record anything could be
> a strategy.
> 
> This completion of the charade is a lot simpler than equipping 70+ places
> to be prepared to handle nulls in what is basically a broken scenario.
Comment 6 Manoj N Palat CLA 2013-03-16 19:49:26 EDT
(In reply to comment #5)
> (In reply to comment #2)


> > So in ASTConverter.recordNodes, if JLS level < 8 and DOM node is NullLiteral
> > and compiler node is LambdaExpression - don't record anything could be
> > a strategy.
Srikanth: JLS Level < 8 check - would n't this be redundant as LE to NL conversion will happen only for JLS Level < 8. Can have this as an additional safety measure though.

[pl ignore the earlier comment as this was left out]
Comment 7 Srikanth Sankaran CLA 2013-03-17 00:20:34 EDT
(In reply to comment #6)
> (In reply to comment #5)
> > (In reply to comment #2)
> 
> 
> > > So in ASTConverter.recordNodes, if JLS level < 8 and DOM node is NullLiteral
> > > and compiler node is LambdaExpression - don't record anything could be
> > > a strategy.
> Srikanth: JLS Level < 8 check - would n't this be redundant as LE to NL

Correct, so that check is not needed.
Comment 8 Manoj N Palat CLA 2013-03-18 00:50:25 EDT
Created attachment 228550 [details]
Proposed Patch
Comment 9 Srikanth Sankaran CLA 2013-03-18 05:55:23 EDT
I added a comment in recordNodes and also changed the order of the checks
and released the fix & test here: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=BETA_JAVA8&id=d882c7320957134d2934c77732f10d26c3e6378f

Thanks Manoj.