Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 236207 Details for
Bug 408230
[1.8][hovering] NPE on hovering over a type inferred parameter in lambda expression
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
patch for the fix accommodating the review comments
Bug408230--another.patch (text/plain), 49.19 KB, created by
ANIRBAN CHAKRABORTY
on 2013-10-08 07:00:56 EDT
(
hide
)
Description:
patch for the fix accommodating the review comments
Filename:
MIME Type:
Creator:
ANIRBAN CHAKRABORTY
Created:
2013-10-08 07:00:56 EDT
Size:
49.19 KB
patch
obsolete
>diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java >index 942f889..d0f1993 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java >@@ -1,11 +1,15 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2012 IBM Corporation and others. >+ * Copyright (c) 2000, 2013 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at > * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * This is an implementation of an early-draft specification developed under the Java >+ * Community Process (JCP) and is made available for testing and evaluation purposes >+ * only. The code is not compatible with any specification of the JCP. > * > * Contributors: > * IBM Corporation - initial API and implementation > *******************************************************************************/ > package org.eclipse.jdt.core.tests.model; >@@ -832,6 +836,358 @@ > } > finally { > deleteProject("Test342393"); > } > } >+// Bug 408230 - [1.8][hovering] NPE on hovering over a type inferred parameter in lambda expression >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=408230 >+public void testBug408230a() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " FI i1 = (a, barg) -> a+barg;\n" + >+ "}\n" + >+ "interface FI { int f1(int a, int b); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "barg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} >+public void testBug408230b() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " void foo() {\n" + >+ " FI i2 = (a, barg) -> { return a+barg; };\n" + >+ " }\n" + >+ "}\n" + >+ "interface FI { int f1(int a, int b); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "barg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} >+public void testBug408230c() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " void foo() {\n" + >+ " FI i2 = (a, barg) -> { int x = 2; while (x < 2) { x++; } return a+barg; };\n" + >+ " }\n" + >+ "}\n" + >+ "interface FI { int f1(int a, int b); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "barg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} >+public void testBug408230d() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " FI i1 = (barg) -> ++barg;\n" + >+ "}\n" + >+ "interface FI { int f1(int b); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "barg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} >+public void testBug408230e() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " FI i1 = (aarg) -> { return aarg++;};\n" + >+ "}\n" + >+ "interface FI { int f1(int a); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "aarg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} >+public void testBug408230f() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " FI i1 = (aarg) -> { int x = aarg; return aarg++;};\n" + >+ "}\n" + >+ "interface FI { int f1(int a); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "aarg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} >+public void testBug408230g() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " public void boo(FI fi) {}\n" + >+ " void foo() {\n" + >+ " boo((aarg) -> aarg++);\n" + >+ " }\n" + >+ "}\n" + >+ "interface FI { int f1(int a); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "aarg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} >+public void testBug408230h() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " public void boo(FI fi) {}\n" + >+ " void foo() {\n" + >+ " boo((aarg) -> {int b = 10; return aarg++;});\n" + >+ " }\n" + >+ "}\n" + >+ "interface FI { int f1(int a); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "aarg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} >+public void testBug408230i() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " public void boo(FI fi) {}\n" + >+ " void foo() {\n" + >+ " boo((aarg, x) -> x + aarg++);\n" + >+ " }\n" + >+ "}\n" + >+ "interface FI { int f1(int a, int b); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "aarg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} >+public void testBug408230j() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " public void boo(FI fi) {}\n" + >+ " void foo() {\n" + >+ " boo((aarg, x) -> {int b = 10; return x + aarg++;});\n" + >+ " }\n" + >+ "}\n" + >+ "interface FI { int f1(int a, int b); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "aarg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} >+public void testBug408230k() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " public void boo(int x, int y, FI fi) {}\n" + >+ " void foo() {\n" + >+ " boo(2, 4, (aarg) -> aarg++);\n" + >+ " }\n" + >+ "}\n" + >+ "interface FI { int f1(int a); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "aarg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} >+public void testBug408230l() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " public void boo(int x, FI fi) {}\n" + >+ " void foo() {\n" + >+ " boo(2, (aarg) -> {int b = 10; return aarg++;});\n" + >+ " }\n" + >+ "}\n" + >+ "interface FI { int f1(int a); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "aarg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} >+public void testBug408230m() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " public void boo(int x, int y, FI fi) {}\n" + >+ " void foo() {\n" + >+ " boo(2, 5+6, (aarg, x) -> x + aarg++);\n" + >+ " }\n" + >+ "}\n" + >+ "interface FI { int f1(int a, int b); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "aarg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} >+public void testBug408230n() throws CoreException { >+ try { >+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8"); >+ String source = "package p;\n" + >+ "public class X {\n" + >+ " public void boo(int x, FI fi) {}\n" + >+ " void foo() {\n" + >+ " boo(2, (aarg, x) -> {int b = 10; return x + aarg++;});\n" + >+ " }\n" + >+ "}\n" + >+ "interface FI { int f1(int a, int b); }\n"; >+ createFolder("/P/src/p"); >+ createFile( >+ "/P/src/p/X.java", >+ source >+ ); >+ waitForAutoBuild(); >+ >+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); >+ String selectString = "aarg"; >+ IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); >+ assertEquals(1, variable.length); >+ } finally { >+ deleteProject("P"); >+ } >+} > } >diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java >index 99fc088..1ec8b65 100644 >--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java >+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java >@@ -1095,11 +1095,11 @@ > int instanceOfIndex = lastIndexOfElement(K_BETWEEN_INSTANCEOF_AND_RPAREN); > index = blockIndex != -1 && instanceOfIndex < blockIndex ? blockIndex : instanceOfIndex; > } > while (index >= 0) { > // Try to find an enclosing if statement even if one is not found immediately preceding the completion node. >- if (index != -1 && this.elementInfoStack[index] == IF && this.elementObjectInfoStack[index] != null) { >+ if (index != -1 && this.elementInfoStack[index] == IF && this.elementObjectInfoStack[index] != null && !(this.elementObjectInfoStack[index] instanceof Integer)) { > Expression condition = (Expression)this.elementObjectInfoStack[index]; > > // If currentElement is a RecoveredLocalVariable then it can be contained in the if statement > if (this.currentElement instanceof RecoveredLocalVariable && > this.currentElement.parent instanceof RecoveredBlock) { >diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java >index 5093451..7463933 100644 >--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java >+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java >@@ -17,10 +17,11 @@ > /* > * Parser extension for code assist task > * > */ > >+import org.eclipse.jdt.internal.codeassist.select.SelectionOnSingleNameReference; > import org.eclipse.jdt.internal.compiler.ast.*; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.lookup.Binding; > import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; > import org.eclipse.jdt.internal.compiler.parser.Parser; >@@ -70,10 +71,11 @@ > protected static final int K_TYPE_DELIMITER = ASSIST_PARSER + 2; // whether we are inside a type declaration > protected static final int K_METHOD_DELIMITER = ASSIST_PARSER + 3; // whether we are inside a method declaration > protected static final int K_FIELD_INITIALIZER_DELIMITER = ASSIST_PARSER + 4; // whether we are inside a field initializer > protected static final int K_ATTRIBUTE_VALUE_DELIMITER = ASSIST_PARSER + 5; // whether we are inside a annotation attribute valuer > protected static final int K_ENUM_CONSTANT_DELIMITER = ASSIST_PARSER + 6; // whether we are inside a field initializer >+ protected static final int K_INSIDE_LAMBDA_EXPRESSION = ASSIST_PARSER + 7; // whether we are inside a field initializer > > // selector constants > protected static final int THIS_CONSTRUCTOR = -1; > protected static final int SUPER_CONSTRUCTOR = -2; > >@@ -191,11 +193,28 @@ > block.sourceStart = lastStart = -this.blockStarts[j]; > element = element.add(block, 1); > } > blockIndex = j+1; // shift the index to the new block > } >- if (node instanceof LocalDeclaration){ >+ if (node instanceof Argument && ((Argument)node).hasElidedType()){ >+ Argument local = (Argument) node; >+ if (local.declarationSourceEnd == 0){ >+ element = element.add(local, 0); >+ if (local.initialization == null){ >+ this.lastCheckPoint = local.sourceEnd + 1; >+ } else { >+ this.lastCheckPoint = local.initialization.sourceEnd + 1; >+ } >+ } else { >+ element = element.add(local, 0); >+ this.lastCheckPoint = local.declarationSourceEnd + 1; >+ } >+ while (i <= this.astPtr && this.astStack[i+1] instanceof Argument && ((Argument)this.astStack[i+1]).hasElidedType()) { >+ i++; >+ } >+ continue; >+ } else if (node instanceof LocalDeclaration){ > LocalDeclaration local = (LocalDeclaration) node; > if (local.declarationSourceEnd == 0){ > element = element.add(local, 0); > if (local.initialization == null){ > this.lastCheckPoint = local.sourceEnd + 1; >@@ -769,17 +788,17 @@ > switch (token) { > case TokenNameLPAREN : > this.bracketDepth++; > switch (this.previousToken) { > case TokenNameIdentifier: >- this.pushOnElementStack(K_SELECTOR, this.identifierPtr); >+ this.pushOnElementStack(K_SELECTOR, this.identifierPtr, new Integer(this.expressionPtr)); > break; > case TokenNamethis: // explicit constructor invocation, e.g. this(1, 2) >- this.pushOnElementStack(K_SELECTOR, THIS_CONSTRUCTOR); >+ this.pushOnElementStack(K_SELECTOR, THIS_CONSTRUCTOR, new Integer(this.expressionPtr)); > break; > case TokenNamesuper: // explicit constructor invocation, e.g. super(1, 2) >- this.pushOnElementStack(K_SELECTOR, SUPER_CONSTRUCTOR); >+ this.pushOnElementStack(K_SELECTOR, SUPER_CONSTRUCTOR, new Integer(this.expressionPtr)); > break; > case TokenNameGREATER: // explicit constructor invocation, e.g. Fred<X>[(]1, 2) > case TokenNameRIGHT_SHIFT: // or fred<X<X>>[(]1, 2) > case TokenNameUNSIGNED_RIGHT_SHIFT: //or Fred<X<X<X>>>[(]1, 2) > if(this.identifierPtr > -1) { >@@ -814,10 +833,12 @@ > } > } > this.previousToken = token; > if (token == TokenNameIdentifier) { > this.previousIdentifierPtr = this.identifierPtr; >+ } else if (token == TokenNameBeginLambda) { >+ pushOnElementStack(K_INSIDE_LAMBDA_EXPRESSION, this.expressionPtr); > } > } > protected void consumeTypeImportOnDemandDeclarationName() { > // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*' > /* push an ImportRef build from the last name >@@ -1736,10 +1757,14 @@ > return null; > } > protected Object topKnownElementObjectInfo(int owner) { > return topKnownElementObjectInfo(owner, 0); > } >+protected void consumeLambdaExpression() { >+ super.consumeLambdaExpression(); >+ popUntilElement(K_INSIDE_LAMBDA_EXPRESSION); >+} > /** > * If the given ast node is inside an explicit constructor call > * then wrap it with a fake constructor call. > * Returns the wrapped completion node or the completion node itself. > */ >@@ -1759,6 +1784,83 @@ > return call; > } else { > return ast; > } > } >+public MessageSend collectLambdaExpressionInformationFromParserWithoutDisturbingStacks () { >+ if(this.expressionPtr >= 0 && this.expressionStack[this.expressionPtr] instanceof SelectionOnSingleNameReference) { >+ int argumentsRoof = this.elementInfoStack[lastIndexOfElement(K_INSIDE_LAMBDA_EXPRESSION)]; >+ if (topKnownElementKind(ASSIST_PARSER) == K_SELECTOR || topKnownElementKind(ASSIST_PARSER, 1) == K_SELECTOR || topKnownElementKind(ASSIST_PARSER, 2) == K_SELECTOR) { >+ int argumentsFloor = ((Integer)this.elementObjectInfoStack[lastIndexOfElement(K_SELECTOR)]).intValue(); >+ MessageSend sentMessage = new MessageSend(); >+ sentMessage.selector = this.identifierStack[this.identifierPtr]; >+ if (this.expressionPtr > argumentsFloor && argumentsFloor <= argumentsRoof) { >+ int noOfSeenArguments = argumentsRoof - argumentsFloor; >+ if (noOfSeenArguments > 0) { >+ System.arraycopy(this.expressionStack, argumentsFloor + 1, sentMessage.arguments = new Expression[noOfSeenArguments], 0, noOfSeenArguments); >+ } >+ this.expressionPtr = argumentsFloor; >+ } >+ return sentMessage; >+ } >+ } >+ return null; >+} >+public LambdaExpression collectLambdaExpressionInformation () { >+ ASTNode arg; >+ if(this.expressionPtr >= 0 && this.expressionStack[this.expressionPtr] instanceof SelectionOnSingleNameReference) { >+ Argument [] arguments = ASTNode.NO_ARGUMENTS; >+ if (this.astPtr >= 0 && this.astStack[this.astPtr] instanceof Argument) { >+ arguments = new Argument[this.astLengthStack[this.astLengthPtr]]; >+ int k; >+ for (int i = k = this.astPtr + 1 - this.astLengthStack[this.astLengthPtr], j = this.astPtr; i <= j && (arg = this.astStack[i]) instanceof Argument; i++) { >+ arguments[i - k] = (Argument)arg; >+ } >+ >+ } >+ LambdaExpression lExp; >+ int argumentsRoof = this.elementInfoStack[lastIndexOfElement(K_INSIDE_LAMBDA_EXPRESSION)]; >+ popElement(K_INSIDE_LAMBDA_EXPRESSION); >+ lExp = new LambdaExpression(this.compilationUnit.compilationResult, arguments, this.expressionStack[this.expressionPtr--]); >+ this.expressionLengthPtr--; >+ if (topKnownElementKind(ASSIST_PARSER) == K_SELECTOR) { >+ int argumentsFloor = ((Integer)this.elementObjectInfoStack[lastIndexOfElement(K_SELECTOR)]).intValue(); >+ lExp.sentMessage = new MessageSend(); >+ lExp.sentMessage.selector = this.identifierStack[this.identifierPtr]; >+ if (this.expressionPtr > argumentsFloor && argumentsFloor <= argumentsRoof) { >+ int noOfSeenArguments = argumentsRoof - argumentsFloor; >+ if (noOfSeenArguments > 0) { >+ System.arraycopy(this.expressionStack, argumentsFloor + 1, lExp.sentMessage.arguments = new Expression[noOfSeenArguments], 0, noOfSeenArguments); >+ } >+ this.expressionPtr = argumentsFloor; >+ this.expressionLengthPtr--; >+ } >+ } >+ return lExp; >+ } >+ return null; >+} >+public Argument [] getLambdaArgumentsOnwards (Argument arg) { >+ boolean started = false; >+ ASTNode [] nodeStack = this.astStack; >+ Argument [] lArgs = null; >+ for (int i = 0, j = this.astPtr; i <= j; i++) { >+ if (started) { >+ if( nodeStack[i] instanceof Argument && ((Argument)nodeStack[i]).hasElidedType()) { >+ if (lArgs == null) { >+ lArgs = new Argument[1]; >+ } else { >+ int len = lArgs.length; >+ System.arraycopy(lArgs, 0, lArgs = new Argument[len + 1], 0, len); >+ } >+ lArgs[lArgs.length - 1] = (Argument)nodeStack[i]; >+ } else { >+ return lArgs; >+ } >+ } >+ if (nodeStack[i] == arg) { >+ started = true; >+ } >+ } >+ return lArgs; >+} > } >diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java >index 2fe1a7e..b808be7 100644 >--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java >+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java >@@ -25,11 +25,10 @@ > */ > > import org.eclipse.jdt.internal.compiler.*; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.env.*; >- > import org.eclipse.jdt.core.compiler.CharOperation; > import org.eclipse.jdt.internal.codeassist.impl.*; > import org.eclipse.jdt.internal.compiler.ast.*; > import org.eclipse.jdt.internal.compiler.lookup.BlockScope; > import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; >@@ -142,10 +141,13 @@ > cast.sourceStart = castType.sourceStart; > cast.sourceEnd= expression.sourceEnd; > parentNode = cast; > this.assistNodeParent = parentNode; > } >+ break nextElement; >+ case K_INSIDE_LAMBDA_EXPRESSION : >+ this.assistNodeParent = parentNode = collectLambdaExpressionInformation(); > break nextElement; > } > } > if(parentNode != null) { > this.currentElement = this.currentElement.add((Statement)parentNode, 0); >@@ -1434,10 +1436,16 @@ > this action is also performed when shifting token after recovery > got activated once. > */ > recoveryTokenCheck(); > } >+protected void consumeTypeElidedLambdaParameter(boolean parenthesized) { >+ if (this.astPtr > -1 && this.astStack[this.astPtr] instanceof LocalDeclaration) { >+ this.astStack[this.astPtr].bits |= ASTNode.IsInitializedByLamdaExpression; >+ } >+ super.consumeTypeElidedLambdaParameter(parenthesized); >+} > > public String toString() { > String s = Util.EMPTY_STRING; > s = s + "elementKindStack : int[] = {"; //$NON-NLS-1$ > for (int i = 0; i <= this.elementPtr; i++) { >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java >index 5c47287..aacec27 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java >@@ -69,11 +69,11 @@ > public final static int Bit3 = 0x4; // return type (operator) | name reference kind (name ref) | implicit this (this ref) | is argument(local) > public final static int Bit4 = 0x8; // return type (operator) | first assignment to local (name ref,local decl) | undocumented empty block (block, type and method decl) > public final static int Bit5 = 0x10; // value for return (expression) | has all method bodies (unit) | supertype ref (type ref) | resolved (field decl) > public final static int Bit6 = 0x20; // depth (name ref, msg) | ignore need cast check (cast expression) | error in signature (method declaration/ initializer) | is recovered (annotation reference) > public final static int Bit7 = 0x40; // depth (name ref, msg) | operator (operator) | need runtime checkcast (cast expression) | label used (labelStatement) | needFreeReturn (AbstractMethodDeclaration) >- public final static int Bit8 = 0x80; // depth (name ref, msg) | operator (operator) | unsafe cast (cast expression) | is default constructor (constructor declaration) | isElseStatementUnreachable (if statement) >+ public final static int Bit8 = 0x80; // depth (name ref, msg) | operator (operator) | unsafe cast (cast expression) | is default constructor (constructor declaration) | isElseStatementUnreachable (if statement) | IsInitializedByLambdaExpression (local declaration) > public final static int Bit9 = 0x100; // depth (name ref, msg) | operator (operator) | is local type (type decl) | isThenStatementUnreachable (if statement) | can be static > public final static int Bit10= 0x200; // depth (name ref, msg) | operator (operator) | is anonymous type (type decl) > public final static int Bit11 = 0x400; // depth (name ref, msg) | operator (operator) | is member type (type decl) > public final static int Bit12 = 0x800; // depth (name ref, msg) | operator (operator) | has abstract methods (type decl) > public final static int Bit13 = 0x1000; // depth (name ref, msg) | is secondary type (type decl) >@@ -154,10 +154,11 @@ > public static final int IsTypeElided = Bit2; // type elided lambda argument. > public static final int IsArgument = Bit3; > public static final int IsLocalDeclarationReachable = Bit31; > public static final int IsForeachElementVariable = Bit5; > public static final int ShadowsOuterLocal = Bit22; >+ public static final int IsInitializedByLamdaExpression = Bit8; > > // for name refs or local decls > public static final int FirstAssignmentToLocal = Bit4; > > // for msg or field references >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java >index ffe9add..e4d7726 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java >@@ -34,10 +34,11 @@ > import org.eclipse.jdt.internal.compiler.flow.FlowContext; > import org.eclipse.jdt.internal.compiler.flow.FlowInfo; > import org.eclipse.jdt.internal.compiler.impl.Constant; > import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; > import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding; >+import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding; > import org.eclipse.jdt.internal.compiler.lookup.Binding; > import org.eclipse.jdt.internal.compiler.lookup.BlockScope; > import org.eclipse.jdt.internal.compiler.lookup.ClassScope; > import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; > import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; >@@ -77,10 +78,11 @@ > private LambdaExpression original = this; > private SyntheticArgumentBinding[] outerLocalVariables = NO_SYNTHETIC_ARGUMENTS; > private int outerLocalVariablesSlotSize = 0; > public boolean shouldCaptureInstance = false; > private static final SyntheticArgumentBinding [] NO_SYNTHETIC_ARGUMENTS = new SyntheticArgumentBinding[0]; >+ public MessageSend sentMessage = null; > > public LambdaExpression(CompilationResult compilationResult, Argument [] arguments, Statement body) { > super(compilationResult); > this.arguments = arguments != null ? arguments : ASTNode.NO_ARGUMENTS; > this.body = body; >@@ -128,11 +130,59 @@ > currentScope.problemReporter().lambdaExpressionCannotImplementGenericMethod(this, sam); > return false; > } > return super.kosherDescriptor(currentScope, sam, shouldChatter); > } >- >+ >+ private void handleSelectionNode (BlockScope blockScope) { >+ final int smallQSize = 10; >+ MessageSend msgSend = this.sentMessage; >+ ReferenceBinding [] typeArray = new ReferenceBinding[smallQSize]; >+ int typeArrayIndx = 0, typeArrayMax = 0; >+ typeArray[0] = this.scope.classScope().enclosingReceiverType(); >+ do { >+ if (!typeArray[typeArrayIndx].compoundName.equals(JAVA_LANG_OBJECT)) { >+ MethodBinding [] methods = typeArray[typeArrayIndx].methods(); >+ for (int i = 0, j = methods.length, noOfArgsSeen = msgSend.arguments == null ? 0 : msgSend.arguments.length; i < j; i++) { >+ TypeBinding [] params = null; >+ if (methods[i].selector.equals(msgSend.selector) && (params = methods[i].parameters) != null && params.length > noOfArgsSeen && (this.descriptor = params[noOfArgsSeen].getSingleAbstractMethod(blockScope)) != null) { >+ this.expectedType = this.resolvedType = params[noOfArgsSeen]; >+ i = j; >+ } >+ } >+ if (this.descriptor == null) { >+ ReferenceBinding sc = null; >+ ReferenceBinding [] si = null; >+ if (typeArray[typeArrayIndx] instanceof SourceTypeBinding) { >+ sc = ((SourceTypeBinding)typeArray[typeArrayIndx]).superclass(); >+ si = ((SourceTypeBinding)typeArray[typeArrayIndx]).superInterfaces(); >+ } else if (typeArray[typeArrayIndx] instanceof BinaryTypeBinding) { >+ sc = ((BinaryTypeBinding)typeArray[typeArrayIndx]).superclass(); >+ si = ((BinaryTypeBinding)typeArray[typeArrayIndx]).superInterfaces(); >+ } >+ int additionalLength = (si == null ? 0 : si.length) + (sc == null ? 0 : 1); >+ if (typeArrayMax + 1 + additionalLength > typeArray.length) { >+ System.arraycopy(typeArray, typeArrayIndx + 1, >+ typeArrayMax - typeArrayIndx + 1 + additionalLength <= typeArray.length ? >+ typeArray : (typeArray = new ReferenceBinding[typeArrayMax - typeArrayIndx + (additionalLength > smallQSize ? additionalLength : smallQSize)]), >+ 0, typeArrayMax - typeArrayIndx); >+ typeArrayMax -= (typeArrayIndx + 1); >+ typeArrayIndx = -1; >+ } >+ if (sc != null){ >+ typeArray[++typeArrayMax] = sc; >+ } >+ if (si != null && si.length > 0) { >+ System.arraycopy(si, 0, typeArray, ++typeArrayMax, si.length); >+ typeArrayMax += si.length - 1; >+ } >+ } >+ typeArrayIndx++; >+ } >+ } while (this.descriptor == null && typeArrayIndx <= typeArrayMax); >+ } >+ > /* This code is arranged so that we can continue with as much analysis as possible while avoiding > * mine fields that would result in a slew of spurious messages. This method is a merger of: > * @see org.eclipse.jdt.internal.compiler.lookup.MethodScope.createMethod(AbstractMethodDeclaration) > * @see org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.resolveTypesFor(MethodBinding) > * @see org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.resolve(ClassScope) >@@ -156,12 +206,16 @@ > final boolean haveDescriptor = this.descriptor != null; > > if (haveDescriptor && this.descriptor.typeVariables != Binding.NO_TYPE_VARIABLES) // already complained in kosher* > return null; > >- if (!haveDescriptor && argumentsTypeElided) >- return null; // FUBAR, bail out... >+ if (!haveDescriptor && argumentsTypeElided) { >+ if (this.sentMessage == null) { >+ return null; // FUBAR, bail out... >+ } >+ handleSelectionNode(blockScope); >+ } > > this.binding = new MethodBinding(ClassFileConstants.AccPrivate | ClassFileConstants.AccSynthetic | ExtraCompilerModifiers.AccUnresolved, > TypeConstants.ANONYMOUS_METHOD, // will be fixed up later. > haveDescriptor ? this.descriptor.returnType : null, > Binding.NO_PARAMETERS, // for now. >@@ -194,11 +248,11 @@ > buggyArguments = true; > } > } > > TypeBinding parameterType; >- final TypeBinding expectedParameterType = haveDescriptor && i < this.descriptor.parameters.length ? this.descriptor.parameters[i] : null; >+ final TypeBinding expectedParameterType = this.descriptor != null && i < this.descriptor.parameters.length ? this.descriptor.parameters[i] : null; > parameterType = argumentsTypeElided ? expectedParameterType : argument.type.resolveType(this.scope, true /* check bounds*/); > if (parameterType == null) { > buggyArguments = true; > } else if (parameterType == TypeBinding.VOID) { > this.scope.problemReporter().argumentTypeCannotBeVoid(this, argument); >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java >index 1d74fe8..9bcc04b 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java >@@ -1,26 +1,32 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2013 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at > * http://www.eclipse.org/legal/epl-v10.html > * >+ * This is an implementation of an early-draft specification developed under the Java >+ * Community Process (JCP) and is made available for testing and evaluation purposes >+ * only. The code is not compatible with any specification of the JCP. >+ * > * Contributors: > * IBM Corporation - initial API and implementation > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.parser; > > import java.util.HashSet; > import java.util.Set; > > import org.eclipse.jdt.core.compiler.*; >+import org.eclipse.jdt.internal.codeassist.impl.AssistParser; > import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; > import org.eclipse.jdt.internal.compiler.ast.Argument; > import org.eclipse.jdt.internal.compiler.ast.ASTNode; > import org.eclipse.jdt.internal.compiler.ast.Block; > import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; >+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression; > import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; > import org.eclipse.jdt.internal.compiler.ast.Statement; > import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; >@@ -29,11 +35,11 @@ > > public Block blockDeclaration; > public RecoveredStatement[] statements; > public int statementCount; > public boolean preserveContent = false; >- public RecoveredLocalVariable pendingArgument; >+ public RecoveredLocalVariable [] pendingArguments = null; > > int pendingModifiers; > int pendingModifersSourceStart = -1; > RecoveredAnnotation[] pendingAnnotations; > int pendingAnnotationCount; >@@ -54,10 +60,21 @@ > return this; // ignore this element > } > } > return super.add(methodDeclaration, bracketBalanceValue); > } >+public void addPendingArgument(RecoveredLocalVariable pendingArg) { >+ if (this.pendingArguments == null) { >+ RecoveredLocalVariable recoveredLocalVariable [] = {pendingArg}; >+ this.pendingArguments = recoveredLocalVariable; >+ } >+ else { >+ int length = this.pendingArguments.length; >+ System.arraycopy(this.pendingArguments, 0, this.pendingArguments = new RecoveredLocalVariable[length+1], 0, length); >+ this.pendingArguments[length] = pendingArg; >+ } >+} > /* > * Record a nested block declaration > */ > public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalanceValue) { > resetPendingModifiers(); >@@ -70,13 +87,15 @@ > } > > RecoveredBlock element = new RecoveredBlock(nestedBlockDeclaration, this, bracketBalanceValue); > > // if we have a pending Argument, promote it into the new block >- if (this.pendingArgument != null){ >- element.attach(this.pendingArgument); >- this.pendingArgument = null; >+ if (this.pendingArguments != null) { >+ for (int indx = 0; indx < this.pendingArguments.length; indx++) { >+ element.attach(this.pendingArguments[indx]); >+ } >+ this.pendingArguments = null; > } > if(parser().statementRecoveryActivated) { > addBlockStatement(element); > } > attach(element); >@@ -129,11 +148,23 @@ > this.pendingModifersSourceStart); > } > resetPendingModifiers(); > > if (localDeclaration instanceof Argument){ >- this.pendingArgument = element; >+ if (((Argument)localDeclaration).hasElidedType()) { >+ RecoveredLambdaExpression rLexp = new RecoveredLambdaExpression(new Block(0), this, bracketBalanceValue); >+ Parser currParser = parser(); >+ if (currParser instanceof AssistParser) { >+ AssistParser aParser = (AssistParser)currParser; >+ rLexp.sentMessage = aParser.collectLambdaExpressionInformationFromParserWithoutDisturbingStacks(); >+ rLexp.insertLambdaArgument((Argument)localDeclaration); >+ rLexp.insertLambdaArgument(aParser.getLambdaArgumentsOnwards((Argument)localDeclaration)); >+ } >+ attach(rLexp); >+ return rLexp; >+ } >+ addPendingArgument(element); > return this; > } > > attach(element); > if (localDeclaration.declarationSourceEnd == 0) return element; >@@ -277,11 +308,14 @@ > return result.toString(); > } > /* > * Rebuild a block from the nested structure which is in scope > */ >-public Block updatedBlock(int depth, Set knownTypes){ >+public Block updatedBlock(int depth, Set knownTypes) { >+ return updatedBlock(depth, knownTypes, false); >+} >+public Block updatedBlock(int depth, Set knownTypes, boolean lambdaExpressionExpected) { > > // if block was not marked to be preserved or empty, then ignore it > if (!this.preserveContent || this.statementCount == 0) return null; > > Statement[] updatedStatements = new Statement[this.statementCount]; >@@ -323,13 +357,20 @@ > > int lastEnd = this.blockDeclaration.sourceStart; > > // only collect the non-null updated statements > for (int i = 0; i < this.statementCount; i++){ >- Statement updatedStatement = this.statements[i].updatedStatement(depth, knownTypes); >+ boolean lambdaExprInit = i > 0 && lambdaExpressionInitializable(this.statements[i-1]); >+ Statement updatedStatement = this.statements[i].updatedStatement(depth, knownTypes, lambdaExprInit); > if (updatedStatement != null){ >- updatedStatements[updatedCount++] = updatedStatement; >+ LambdaExpression lambdaExpr = getLambdaExpression(updatedStatement); >+ if (lambdaExprInit && lambdaExpr != null) { >+ ((LocalDeclaration)updatedStatements[updatedCount-1]).initialization = lambdaExpr; >+ } >+ else { >+ updatedStatements[updatedCount++] = updatedStatement; >+ } > > if (updatedStatement instanceof LocalDeclaration) { > LocalDeclaration localDeclaration = (LocalDeclaration) updatedStatement; > if(localDeclaration.declarationSourceEnd > lastEnd) { > lastEnd = localDeclaration.declarationSourceEnd; >@@ -351,11 +392,18 @@ > // resize statement collection if necessary > if (updatedCount != this.statementCount){ > this.blockDeclaration.statements = new Statement[updatedCount]; > System.arraycopy(updatedStatements, 0, this.blockDeclaration.statements, 0, updatedCount); > } else { >- this.blockDeclaration.statements = updatedStatements; >+ LambdaExpression lambda = null; >+ if (lambdaExpressionExpected && !(updatedStatements[0] instanceof LambdaExpression) && (lambda = canGetLambdaExpression(updatedStatements, updatedCount)) != null) { >+ Statement [] stmt = {lambda}; >+ this.blockDeclaration.statements = stmt; >+ } >+ else { >+ this.blockDeclaration.statements = updatedStatements; >+ } > } > > if (this.blockDeclaration.sourceEnd == 0) { > if(lastEnd < bodyEndValue) { > this.blockDeclaration.sourceEnd = bodyEndValue; >@@ -364,17 +412,47 @@ > } > } > > return this.blockDeclaration; > } >+public LambdaExpression getLambdaExpression (Statement stmnt) { >+ if (stmnt instanceof LambdaExpression) { >+ return (LambdaExpression)stmnt; >+ } >+ else if (stmnt instanceof Block && ((Block)stmnt).statements[0] instanceof LambdaExpression) { >+ return (LambdaExpression)((Block)stmnt).statements[0]; >+ } >+ return null; >+} >+public LambdaExpression canGetLambdaExpression (Statement [] statementsArray, int count) { >+ for (int indx = 0; indx < count - 1; indx++) { >+ if (!(statementsArray[indx] instanceof Argument)) { >+ return null; >+ } >+ } >+ Argument [] arguments = new Argument [count-1]; >+ System.arraycopy(statementsArray, 0, arguments, 0, count-1); >+ return new LambdaExpression(parser().compilationUnit.compilationResult, arguments, statementsArray[count-1]); >+} > /* > * Rebuild a statement from the nested structure which is in scope > */ > public Statement updatedStatement(int depth, Set knownTypes){ > > return updatedBlock(depth, knownTypes); > } >+public Statement updatedStatement(int depth, Set knownTypes, boolean lambdaExpressionExpected) { >+ >+ return lambdaExpressionExpected ? updatedBlock(depth, knownTypes, true) : updatedStatement(depth, knownTypes); >+} >+boolean lambdaExpressionInitializable(RecoveredStatement stmnt) { >+ if (stmnt instanceof RecoveredLocalVariable) { >+ RecoveredLocalVariable recLocVar = (RecoveredLocalVariable) stmnt; >+ return recLocVar.localDeclaration != null && (recLocVar.localDeclaration.bits & ASTNode.IsInitializedByLamdaExpression) != 0; >+ } >+ return false; >+} > /* > * A closing brace got consumed, might have closed the current element, > * in which case both the currentElement is exited > */ > public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLambdaExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLambdaExpression.java >new file mode 100644 >index 0000000..a72c51f >--- /dev/null >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLambdaExpression.java >@@ -0,0 +1,82 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2013 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * This is an implementation of an early-draft specification developed under the Java >+ * Community Process (JCP) and is made available for testing and evaluation purposes >+ * only. The code is not compatible with any specification of the JCP. >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.compiler.parser; >+ >+import java.util.Set; >+ >+import org.eclipse.jdt.internal.compiler.ast.Argument; >+import org.eclipse.jdt.internal.compiler.ast.Block; >+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression; >+import org.eclipse.jdt.internal.compiler.ast.MessageSend; >+import org.eclipse.jdt.internal.compiler.ast.Statement; >+ >+public class RecoveredLambdaExpression extends RecoveredBlock { >+ >+ public Argument [] lambdaArguments = null; >+ public MessageSend sentMessage = null; >+ >+ public RecoveredLambdaExpression(Block block, RecoveredElement parent, int bracketBalance) { >+ super(block, parent, bracketBalance); >+ } >+ >+ public void insertLambdaArgument (Argument arg) { >+ if (this.lambdaArguments == null) { >+ (this.lambdaArguments = new Argument[1])[0] = arg; >+ } else { >+ int len; >+ System.arraycopy(this.lambdaArguments, 0, this.lambdaArguments = new Argument[(len = this.lambdaArguments.length) + 1], 0, len); >+ this.lambdaArguments[len] = arg; >+ } >+ } >+ >+ public void insertLambdaArgument (Argument [] args) { >+ if (args != null) { >+ if (this.lambdaArguments == null) { >+ this.lambdaArguments = args; >+ } else { >+ int len = this.lambdaArguments.length; >+ System.arraycopy(this.lambdaArguments, 0, this.lambdaArguments = new Argument[len + args.length], 0, len); >+ System.arraycopy(args, 0, this.lambdaArguments, len, args.length); >+ } >+ } >+ } >+ >+ public Statement updatedStatement(int depth, Set knownTypes, boolean lambdaExpressionExpected) { >+ return updatedBlock(depth, knownTypes, true); >+ } >+ >+ public LambdaExpression canGetLambdaExpression (Statement [] statementsArray, int count) { >+ if (statementsArray.length == 1 && this.lambdaArguments != null) { >+ LambdaExpression lExp = new LambdaExpression(parser().compilationUnit.compilationResult, this.lambdaArguments, statementsArray[0]); >+ lExp.sentMessage = this.sentMessage; >+ return lExp; >+ } >+ return super.canGetLambdaExpression(statementsArray, count); >+ } >+ >+ public String toString(int tab) { >+ StringBuffer result = new StringBuffer(tabString(tab)); >+ result.append("Recovered Lambda Expression:\n"); //$NON-NLS-1$ >+ this.blockDeclaration.print(tab + 1, result); >+ if (this.statements != null) { >+ for (int i = 0; i < this.statementCount; i++) { >+ result.append("\n"); //$NON-NLS-1$ >+ result.append(this.statements[i].toString(tab + 1)); >+ } >+ } >+ return result.toString(); >+ } >+ >+} >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java >index 5d3f653..540c2e2 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java >@@ -1,12 +1,16 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2013 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at > * http://www.eclipse.org/legal/epl-v10.html > * >+ * This is an implementation of an early-draft specification developed under the Java >+ * Community Process (JCP) and is made available for testing and evaluation purposes >+ * only. The code is not compatible with any specification of the JCP. >+ * > * Contributors: > * IBM Corporation - initial API and implementation > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.parser; > >@@ -42,10 +46,13 @@ > return tabString(tab) + "Recovered statement:\n" + this.statement.print(tab + 1, new StringBuffer(10)); //$NON-NLS-1$ > } > public Statement updatedStatement(int depth, Set knownTypes){ > return this.statement; > } >+public Statement updatedStatement(int depth, Set knownTypes, boolean lambdaExpressionExpected) { >+ return updatedStatement(depth, knownTypes); >+} > public void updateParseTree(){ > updatedStatement(0, new HashSet()); > } > /* > * Update the declarationSourceEnd of the corresponding parse node >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java >index 7accbff..1ab6fa7 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java >@@ -1,12 +1,16 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2013 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at > * http://www.eclipse.org/legal/epl-v10.html > * >+ * This is an implementation of an early-draft specification developed under the Java >+ * Community Process (JCP) and is made available for testing and evaluation purposes >+ * only. The code is not compatible with any specification of the JCP. >+ * > * Contributors: > * IBM Corporation - initial API and implementation > *******************************************************************************/ > package org.eclipse.jdt.internal.core; > >@@ -449,11 +453,11 @@ > new String(local.name), > local.declarationSourceStart, > local.declarationSourceEnd, > local.sourceStart, > local.sourceEnd, >- Util.typeSignature(local.type), >+ local.type == null ? Signature.createTypeSignature(local.binding.type.readableName(), false) : Util.typeSignature(local.type), > local.annotations, > local.modifiers, > local.getKind() == AbstractVariableDeclaration.PARAMETER); > } > if (localVar != null) {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
anchakrk
:
review?
Actions:
View
|
Diff
Attachments on
bug 408230
:
233920
| 236207