Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManoj Palat2013-06-10 18:10:09 +0000
committerMarkus Keller2013-06-10 18:10:09 +0000
commit80351fb8a54757084b1b27c49cb8b0584bf78834 (patch)
treec6c187441d3917e4f751f121782319ba63e0c4f8
parent26e96a017b590b444a246c8fba814dc78fd85b77 (diff)
downloadeclipse.jdt.core-80351fb8a54757084b1b27c49cb8b0584bf78834.tar.gz
eclipse.jdt.core-80351fb8a54757084b1b27c49cb8b0584bf78834.tar.xz
eclipse.jdt.core-80351fb8a54757084b1b27c49cb8b0584bf78834.zip
Bug 399794: [1.8][dom ast] Add a new node type for the compiler node ReferenceExpression
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java218
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java47
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java4
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java4
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java78
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java61
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java121
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java103
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java40
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java122
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java22
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CreationReference.java261
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java27
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java56
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java5
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionMethodReference.java296
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodReference.java111
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodReference.java291
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeMethodReference.java311
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java73
20 files changed, 2227 insertions, 24 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
index 5a36264243..bd45f05508 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
@@ -1662,6 +1662,224 @@ public class ASTConverter18Test extends ConverterTestSetup {
}
/**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=399794
+ * ReferenceExpression Family Tests
+ *
+ * @throws JavaModelException
+ */
+ public void test399794() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/test399794/X.java",
+ true/* resolve */);
+ String contents = "package test399794;" +
+ "import java.lang.annotation.*;\n " +
+ "interface I {\n" +
+ " Object copy(int [] ia);\n" +
+ "}\n" +
+ "interface J {\n" +
+ " void foo(int x);\n" +
+ "}\n" +
+ "class XX {\n" +
+ " public void foo(int x) {}\n" +
+ "}\n" +
+ "\n" +
+ "class Y {\n" +
+ " static class Z {\n" +
+ " public static void foo(int x) {\n" +
+ " System.out.print(x);\n" +
+ " }\n" +
+ " }\n" +
+ " public void foo(int x) {\n" +
+ " System.out.print(x);\n" +
+ " }\n" +
+ " public <T> void foo(T t){t.hashCode();}\n" +
+ "}\n" +
+ "\n" +
+ "public class X extends XX {\n" +
+ " @SuppressWarnings(\"unused\")\n" +
+ " public void bar(String [] args) {\n" +
+ " Y y = new Y();\n" +
+ " I i = @Marker int []::<String>clone;\n" +
+ " J j = Y.@Marker Z :: foo;\n" +
+ " J j1 = Y.@Marker Z :: <String> foo;\n" +
+ " J jdash = @Marker W<@Marker Integer> :: <String> new ;\n" +
+ " J jj = y :: foo;\n" +
+ " J jx = super :: foo;\n" +
+ " class Z {\n" +
+ " void foo() {\n" +
+ " J jz = X.super :: foo;\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main (String [] args) {}\n" +
+ "}\n" +
+ "class W<T> extends Y {\n" +
+ " public W(T x) {}\n" +
+ "}\n" +
+ "\n" +
+ "@Target (ElementType.TYPE_USE)\n" +
+ "@interface Marker {}";
+
+ CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy);
+ TypeDeclaration typeDeclaration = (TypeDeclaration) getASTNode(cu, 4);
+ MethodDeclaration method = typeDeclaration.getMethods()[0];
+ List statements = method.getBody().statements();
+ assertTrue(statements.size() == 8);
+ int fCount = 1;
+
+ // type method reference with primitive type with type arguments
+ VariableDeclarationStatement statement = (VariableDeclarationStatement) statements.get(fCount++);
+ VariableDeclarationFragment fragment = (VariableDeclarationFragment) statement.fragments().get(0);
+ Expression expression = fragment.getInitializer();
+ assertTrue(expression instanceof TypeMethodReference);
+ TypeMethodReference typeMethodReference = (TypeMethodReference) expression;
+ checkSourceRange(typeMethodReference, "@Marker int []::<String>clone", contents);
+ ITypeBinding typeBinding = typeMethodReference.resolveTypeBinding();
+ assertNotNull(typeBinding);
+ IMethodBinding methodBinding = typeMethodReference.resolveMethodBinding();
+ assertNotNull(methodBinding);
+ Type type = typeMethodReference.getType();
+ checkSourceRange(type, "@Marker int []", contents);
+ List typeArguments = typeMethodReference.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ checkSourceRange(type, "String", contents);
+ assertTrue(type.isSimpleType());
+ SimpleName name = typeMethodReference.getName();
+ checkSourceRange(name, "clone", contents);
+ typeBinding = name.resolveTypeBinding();
+ assertNotNull(typeBinding);
+
+ // type method reference with qualified type without type arguments
+ statement = (VariableDeclarationStatement) statements.get(fCount++);
+ fragment = (VariableDeclarationFragment) statement.fragments().get(0);
+ expression = fragment.getInitializer();
+ assertTrue(expression instanceof TypeMethodReference);
+ typeMethodReference = (TypeMethodReference) expression;
+ checkSourceRange(typeMethodReference, "Y.@Marker Z :: foo", contents);
+ typeBinding = typeMethodReference.resolveTypeBinding();
+ assertNotNull(typeBinding);
+ methodBinding = typeMethodReference.resolveMethodBinding();
+ assertNotNull(methodBinding);
+ type = typeMethodReference.getType();
+ assertTrue(type.isQualifiedType());
+ checkSourceRange(type, "Y.@Marker Z", contents);
+ typeArguments = typeMethodReference.typeArguments();
+ assertTrue(typeArguments.size() == 0);
+ name = typeMethodReference.getName();
+ checkSourceRange(name, "foo", contents);
+ typeBinding = name.resolveTypeBinding();
+ assertNotNull(typeBinding);
+
+ // type method reference with qualified type with type arguments
+ statement = (VariableDeclarationStatement) statements.get(fCount++);
+ fragment = (VariableDeclarationFragment) statement.fragments().get(0);
+ expression = fragment.getInitializer();
+ assertTrue(expression instanceof TypeMethodReference);
+ typeMethodReference = (TypeMethodReference) expression;
+ checkSourceRange(typeMethodReference, "Y.@Marker Z :: <String> foo", contents);
+ typeBinding = typeMethodReference.resolveTypeBinding();
+ assertNotNull(typeBinding);
+ methodBinding = typeMethodReference.resolveMethodBinding();
+ assertNotNull(methodBinding);
+ type = typeMethodReference.getType();
+ assertTrue(type.isQualifiedType());
+ checkSourceRange(type, "Y.@Marker Z", contents);
+ typeArguments = typeMethodReference.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertTrue(type.isSimpleType());
+ checkSourceRange(type, "String", contents);
+ name = typeMethodReference.getName();
+ checkSourceRange(name, "foo", contents);
+ typeBinding = name.resolveTypeBinding();
+ assertNotNull(typeBinding);
+
+ // creation method reference
+ statement = (VariableDeclarationStatement) statements.get(fCount++);
+ fragment = (VariableDeclarationFragment) statement.fragments().get(0);
+ expression = fragment.getInitializer();
+ assertTrue(expression instanceof CreationReference);
+ CreationReference creationReference = (CreationReference) expression;
+ checkSourceRange(creationReference, "@Marker W<@Marker Integer> :: <String> new ", contents);
+ typeBinding = creationReference.resolveTypeBinding();
+ assertNotNull(typeBinding);
+ methodBinding = creationReference.resolveMethodBinding();
+ assertNotNull(methodBinding);
+ Expression lhs = creationReference.getExpression();
+ checkSourceRange(lhs, "@Marker W<@Marker Integer> ", contents);
+ typeArguments = creationReference.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertTrue(type.isSimpleType());
+ checkSourceRange(type, "String", contents);
+
+ // expression method reference
+ statement = (VariableDeclarationStatement) statements.get(fCount++);
+ fragment = (VariableDeclarationFragment) statement.fragments().get(0);
+ expression = fragment.getInitializer();
+ assertTrue(expression instanceof ExpressionMethodReference);
+ ExpressionMethodReference expressionMethodReference = (ExpressionMethodReference) expression;
+ checkSourceRange(expressionMethodReference, "y :: foo", contents);
+ typeBinding = expressionMethodReference.resolveTypeBinding();
+ assertNotNull(typeBinding);
+ methodBinding = expressionMethodReference.resolveMethodBinding();
+ assertNotNull(methodBinding);
+ lhs = expressionMethodReference.getExpression();
+ checkSourceRange(lhs, "y", contents);
+ typeArguments = expressionMethodReference.typeArguments();
+ assertTrue(typeArguments.size() == 0);
+ name = expressionMethodReference.getName();
+ checkSourceRange(name, "foo", contents);
+ typeBinding = name.resolveTypeBinding();
+ assertNotNull(typeBinding);
+
+ // super method reference without qualifier
+ statement = (VariableDeclarationStatement) statements.get(fCount++);
+ fragment = (VariableDeclarationFragment) statement.fragments().get(0);
+ expression = fragment.getInitializer();
+ assertTrue(expression instanceof SuperMethodReference);
+ SuperMethodReference superMethodReference = (SuperMethodReference) expression;
+ checkSourceRange(superMethodReference, "super :: foo", contents);
+ typeBinding = superMethodReference.resolveTypeBinding();
+ assertNotNull(typeBinding);
+ methodBinding = superMethodReference.resolveMethodBinding();
+ assertNotNull(methodBinding);
+ assertNull(superMethodReference.getQualifier());
+ typeArguments = superMethodReference.typeArguments();
+ assertTrue(typeArguments.size() == 0);
+ name = superMethodReference.getName();
+ checkSourceRange(name, "foo", contents);
+ typeBinding = name.resolveTypeBinding();
+ assertNotNull(typeBinding);
+
+ // super method reference with qualifier
+ TypeDeclarationStatement typeDeclarationStatement = (TypeDeclarationStatement) statements.get(fCount);
+ typeDeclaration = (TypeDeclaration) typeDeclarationStatement.getDeclaration();
+ method = typeDeclaration.getMethods()[0];
+ statements = method.getBody().statements();
+ assertTrue(statements.size() == 1);
+ statement = (VariableDeclarationStatement) statements.get(0);
+ fragment = (VariableDeclarationFragment) statement.fragments().get(0);
+ expression = fragment.getInitializer();
+ assertTrue(expression instanceof SuperMethodReference);
+ superMethodReference = (SuperMethodReference) expression;
+ checkSourceRange(superMethodReference, "X.super :: foo", contents);
+ typeBinding = superMethodReference.resolveTypeBinding();
+ assertNotNull(typeBinding);
+ methodBinding = superMethodReference.resolveMethodBinding();
+ assertNotNull(methodBinding);
+ name = (SimpleName) superMethodReference.getQualifier();
+ checkSourceRange(name, "X", contents);
+ typeArguments = superMethodReference.typeArguments();
+ assertTrue(typeArguments.size() == 0);
+ name = superMethodReference.getName();
+ checkSourceRange(name, "foo", contents);
+ typeBinding = name.resolveTypeBinding();
+ assertNotNull(typeBinding);
+
+ }
+
+ /**
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=399793
*
* @throws JavaModelException
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java
index 4ec77591d4..65f2f544f6 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java
@@ -504,6 +504,9 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T
public boolean match(SuperMethodInvocation node, Object other) {
return standardBody(node, other, this.superMatch ? super.match(node, other) : false);
}
+ public boolean match(SuperMethodReference node, Object other) {
+ return standardBody(node, other, this.superMatch ? super.match(node, other) : false);
+ }
public boolean match(SwitchCase node, Object other) {
return standardBody(node, other, this.superMatch ? super.match(node, other) : false);
}
@@ -564,6 +567,15 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T
public boolean match(LambdaExpression node, Object other) {
return standardBody(node, other, this.superMatch ? super.match(node, other) : false);
}
+ public boolean match(CreationReference node, Object other) {
+ return standardBody(node, other, this.superMatch ? super.match(node, other) : false);
+ }
+ public boolean match(ExpressionMethodReference node, Object other) {
+ return standardBody(node, other, this.superMatch ? super.match(node, other) : false);
+ }
+ public boolean match(TypeMethodReference node, Object other) {
+ return standardBody(node, other, this.superMatch ? super.match(node, other) : false);
+ }
public boolean match(IntersectionType node, Object other) {
return standardBody(node, other, this.superMatch ? super.match(node, other) : false);
}
@@ -870,6 +882,15 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T
x1.setLabel(this.N1);
basicMatch(x1);
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=399794
+ public void testCreationReference() {
+ if (this.ast.apiLevel() < AST.JLS8) {
+ return;
+ }
+ CreationReference x1 = this.ast.newCreationReference(this.E1);
+ basicMatch(x1);
+ }
+
public void testDoStatement() {
DoStatement x1 = this.ast.newDoStatement();
x1.setExpression(this.E1);
@@ -925,6 +946,15 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T
x1.bodyDeclarations().add(this.FD2);
basicMatch(x1);
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=399794
+ public void testExpressionMethodReference() {
+ if (this.ast.apiLevel() < AST.JLS8) {
+ return;
+ }
+ ExpressionMethodReference x1 = this.ast.newExpressionMethodReference(this.E1, this.N1);
+ basicMatch(x1);
+ }
+
public void testExpressionStatement() {
ExpressionStatement x1 = this.ast.newExpressionStatement(this.E1);
basicMatch(x1);
@@ -1157,6 +1187,14 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T
x1.arguments().add(this.E2);
basicMatch(x1);
}
+ public void testSuperMethodReference() {
+ if (this.ast.apiLevel() < AST.JLS8) {
+ return;
+ }
+ SuperMethodReference x1 = this.ast.newSuperMethodReference(this.N2);
+ x1.setQualifier(this.N1);
+ basicMatch(x1);
+ }
public void testSwitchCase() {
SwitchCase x1 = this.ast.newSwitchCase();
x1.setExpression(this.E1);
@@ -1589,6 +1627,15 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T
basicMatch(x1);
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=399794
+ public void testTypeMethodReference() {
+ if (this.ast.apiLevel() < AST.JLS8) {
+ return;
+ }
+ TypeMethodReference x1 = this.ast.newTypeMethodReference(this.T1, this.N1);
+ basicMatch(x1);
+ }
+
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=399793
public void testLambdaExpressions1() {
if (this.ast.apiLevel() < AST.JLS8) {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java
index c236a0b2d5..2bf4b8720c 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java
@@ -328,7 +328,7 @@ public class ASTStructuralPropertyTest extends org.eclipse.jdt.core.tests.junit.
maxNodeType = 84;
break;
case AST.JLS8:
- maxNodeType = 88;
+ maxNodeType = 92;
break;
default:
fail();
@@ -372,7 +372,7 @@ public class ASTStructuralPropertyTest extends org.eclipse.jdt.core.tests.junit.
// oops - guess that's not valid
}
}
- assertEquals("Wrong last known type", 88, hi); // last known one
+ assertEquals("Wrong last known type", 92, hi); // last known one
assertEquals("Wrong number of distinct types", hi, classes.size()); // all classes are distinct
}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java
index 52c8dd2924..6eb30a992b 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java
@@ -8785,6 +8785,10 @@ public class ASTTest extends org.eclipse.jdt.core.tests.junit.extension.TestCase
ASTNode.LAMBDA_EXPRESSION,
ASTNode.INTERSECTION_TYPE,
ASTNode.PACKAGE_QUALIFIED_TYPE,
+ ASTNode.CREATION_REFERENCE,
+ ASTNode.EXPRESSION_METHOD_REFERENCE,
+ ASTNode.SUPER_METHOD_REFERENCE,
+ ASTNode.TYPE_METHOD_REFERENCE
};
// assert that nodeType values are correct:
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java
index ff0db3a211..4961c091a3 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java
@@ -712,6 +712,22 @@ public class ASTVisitorTest extends org.eclipse.jdt.core.tests.junit.extension.T
ASTVisitorTest.this.b.append("*/)"); //$NON-NLS-1$
}
+ public boolean visit(CreationReference node) {
+ ASTVisitorTest.this.b.append("(eCR"); //$NON-NLS-1$
+ return isVisitingChildren();
+ }
+ public void endVisit(CreationReference node) {
+ ASTVisitorTest.this.b.append("eCR)"); //$NON-NLS-1$
+ }
+
+ public boolean visit(ExpressionMethodReference node) {
+ ASTVisitorTest.this.b.append("(eEMR"); //$NON-NLS-1$
+ return isVisitingChildren();
+ }
+ public void endVisit(ExpressionMethodReference node) {
+ ASTVisitorTest.this.b.append("eEMR)"); //$NON-NLS-1$
+ }
+
public boolean visit(LineComment node) {
ASTVisitorTest.this.b.append("(//"); //$NON-NLS-1$
return isVisitingChildren();
@@ -892,6 +908,14 @@ public class ASTVisitorTest extends org.eclipse.jdt.core.tests.junit.extension.T
ASTVisitorTest.this.b.append("eSM)"); //$NON-NLS-1$
}
+ public boolean visit(SuperMethodReference node) {
+ ASTVisitorTest.this.b.append("(eSMR"); //$NON-NLS-1$
+ return isVisitingChildren();
+ }
+ public void endVisit(SuperMethodReference node) {
+ ASTVisitorTest.this.b.append("eSMR)"); //$NON-NLS-1$
+ }
+
public boolean visit(SwitchCase node) {
ASTVisitorTest.this.b.append("(sSC"); //$NON-NLS-1$
return isVisitingChildren();
@@ -964,6 +988,14 @@ public class ASTVisitorTest extends org.eclipse.jdt.core.tests.junit.extension.T
ASTVisitorTest.this.b.append("eTL)"); //$NON-NLS-1$
}
+ public boolean visit(TypeMethodReference node) {
+ ASTVisitorTest.this.b.append("(eTMR"); //$NON-NLS-1$
+ return isVisitingChildren();
+ }
+ public void endVisit(TypeMethodReference node) {
+ ASTVisitorTest.this.b.append("eTMR)"); //$NON-NLS-1$
+ }
+
public boolean visit(TypeParameter node) {
ASTVisitorTest.this.b.append("(tTP"); //$NON-NLS-1$
return isVisitingChildren();
@@ -1416,6 +1448,18 @@ public class ASTVisitorTest extends org.eclipse.jdt.core.tests.junit.extension.T
String result = this.b.toString();
assertTrue(result.equals("[(sCN"+this.N1S+"sCN)]")); //$NON-NLS-1$ //$NON-NLS-2$
}
+
+ public void testCreationReference() {
+ if (this.ast.apiLevel() < AST.JLS8)
+ return;
+ CreationReference x1 = this.ast.newCreationReference(this.E1);
+ TestVisitor v1 = new TestVisitor();
+ this.b.setLength(0);
+ x1.accept(v1);
+ String result = this.b.toString();
+ assertTrue(result.equals("[(eCR"+this.E1S+"eCR)]")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
public void testDoStatement() {
DoStatement x1 = this.ast.newDoStatement();
x1.setExpression(this.E1);
@@ -1476,6 +1520,17 @@ public class ASTVisitorTest extends org.eclipse.jdt.core.tests.junit.extension.T
String result = this.b.toString();
assertTrue(result.equals("[(ED"+this.JD1S+this.MOD1S+this.MOD2S+this.N1S+this.T1S+this.T2S+this.EC1S+this.EC2S+this.FD1S+this.FD2S+"ED)]")); //$NON-NLS-1$ //$NON-NLS-2$
}
+ public void testExpressionMethodReference() {
+ if (this.ast.apiLevel() < AST.JLS8)
+ return;
+ ExpressionMethodReference x1 = this.ast.newExpressionMethodReference(this.E1, this.N1);
+ TestVisitor v1 = new TestVisitor();
+ this.b.setLength(0);
+ x1.accept(v1);
+ String result = this.b.toString();
+ assertTrue(result.equals("[(eEMR"+this.E1S+this.N1S+"eEMR)]")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
public void testExpressionStatement() {
ExpressionStatement x1 = this.ast.newExpressionStatement(this.E1);
TestVisitor v1 = new TestVisitor();
@@ -2009,6 +2064,18 @@ public class ASTVisitorTest extends org.eclipse.jdt.core.tests.junit.extension.T
assertTrue(result.equals("[(eSM"+this.N1S+this.PT1S+this.N2S+this.E1S+this.E2S+"eSM)]")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
+ public void testSuperMethodReference() {
+ if (this.ast.apiLevel() < AST.JLS8) {
+ return;
+ }
+ SuperMethodReference x1 = this.ast.newSuperMethodReference(this.N2);
+ x1.setQualifier(this.N1);
+ TestVisitor v1 = new TestVisitor();
+ this.b.setLength(0);
+ x1.accept(v1);
+ String result = this.b.toString();
+ assertTrue(result.equals("[(eSMR"+this.N1S+this.N2S+"eSMR)]")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
public void testSwitchCase() {
SwitchCase x1 = this.ast.newSwitchCase();
x1.setExpression(this.E1);
@@ -2155,6 +2222,17 @@ public class ASTVisitorTest extends org.eclipse.jdt.core.tests.junit.extension.T
String result = this.b.toString();
assertTrue(result.equals("[(eTL"+this.T1S+"eTL)]")); //$NON-NLS-1$ //$NON-NLS-2$
}
+ public void testTypeMethodReference() {
+ if (this.ast.apiLevel() < AST.JLS8)
+ return;
+ TypeMethodReference x1 = this.ast.newTypeMethodReference(this.T1, this.N1);
+ TestVisitor v1 = new TestVisitor();
+ this.b.setLength(0);
+ x1.accept(v1);
+ String result = this.b.toString();
+ assertTrue(result.equals("[(eTMR"+this.T1S+this.N1S+"eTMR)]")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
/** @deprecated using deprecated code */
public void testSingleVariableDeclaration() {
SingleVariableDeclaration x1 = this.ast.newSingleVariableDeclaration();
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
index 660201e952..86ae7910d2 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
@@ -1346,6 +1346,20 @@ public final class AST {
}
/**
+ * Creates an unparented creation reference node owned by this AST.
+ *
+ * @param expression expression for the left hand side of CreationReference
+ * @return a new unparented reference expression node
+ * @exception UnsupportedOperationException if this operation is used in a JLS2, JLS3 or JLS4 AST
+ * @since 3.9 BETA_JAVA8
+ */
+ public CreationReference newCreationReference(Expression expression) {
+ CreationReference result = new CreationReference(this);
+ result.setExpression(expression);
+ return result;
+ }
+
+ /**
* Creates a new unparented do statement node owned by this AST.
* By default, the expression is unspecified (but legal), and
* the body statement is an empty block.
@@ -1413,6 +1427,22 @@ public final class AST {
}
/**
+ * Creates an unparented expression method reference node owned by this AST.
+ *
+ * @param expression expression for the left hand side of ExpressionMethodReference
+ * @param name name of the method in the ExpressionMethodReference
+ * @return a new unparented reference expression node
+ * @exception UnsupportedOperationException if this operation is used in a JLS2, JLS3 or JLS4 AST
+ * @since 3.9 BETA_JAVA8
+ */
+ public ExpressionMethodReference newExpressionMethodReference(Expression expression, SimpleName name) {
+ ExpressionMethodReference result = new ExpressionMethodReference(this);
+ result.setExpression(expression);
+ result.setName(name);
+ return result;
+ }
+
+ /**
* Creates a new unparented expression statement node owned by this AST,
* for the given expression.
* <p>
@@ -2244,6 +2274,21 @@ public final class AST {
}
/**
+ * Creates and returns a new unparented super method reference node
+ * owned by this AST. By default, the expression and field are both
+ * unspecified, but legal, names.
+ *
+ * @param name name of the method referenced
+ * @return a new unparented super method reference node
+ * @since 3.9 BETA_JAVA8
+ */
+ public SuperMethodReference newSuperMethodReference(SimpleName name) {
+ SuperMethodReference result = new SuperMethodReference(this);
+ result.setName(name);
+ return result;
+ }
+
+ /**
* Creates a new unparented switch case statement node owned by
* this AST. By default, the expression is unspecified, but legal.
*
@@ -2424,6 +2469,22 @@ public final class AST {
}
/**
+ * Creates an unparented Type method reference node owned by this AST.
+ *
+ * @param type type for the left hand side of TypeMethodReference
+ * @param name name of the method in the TypeMethodReference
+ * @return a new unparented type method reference node
+ * @exception UnsupportedOperationException if this operation is used in a JLS2, JLS3 or JLS4 AST
+ * @since 3.9 BETA_JAVA8
+ */
+ public TypeMethodReference newTypeMethodReference(Type type, SimpleName name) {
+ TypeMethodReference result = new TypeMethodReference(this);
+ result.setType(type);
+ result.setName(name);
+ return result;
+ }
+
+ /**
* Creates and returns a new unparented type parameter type node with an
* unspecified type variable name and an empty list of type bounds.
*
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
index 2e48221b89..e59773bfe9 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
@@ -46,11 +46,13 @@ import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Receiver;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation;
+import org.eclipse.jdt.internal.compiler.ast.SuperReference;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
@@ -1761,6 +1763,9 @@ class ASTConverter {
if (expression instanceof org.eclipse.jdt.internal.compiler.ast.LambdaExpression) {
return convert((org.eclipse.jdt.internal.compiler.ast.LambdaExpression) expression);
}
+ if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) {
+ return convert((org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) expression);
+ }
return null;
}
@@ -2180,13 +2185,7 @@ class ASTConverter {
public Expression convert(org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambda) {
if (this.ast.apiLevel < AST.JLS8) {
- if (this.referenceContext != null) {
- this.referenceContext.setFlags(this.referenceContext.getFlags() | ASTNode.MALFORMED);
- }
- NullLiteral nullLiteral = new NullLiteral(this.ast);
- nullLiteral.setFlags(nullLiteral.getFlags() | ASTNode.MALFORMED);
- nullLiteral.setSourceRange(lambda.sourceStart, lambda.sourceEnd - lambda.sourceStart + 1);
- return nullLiteral;
+ return createFakeNullLiteral(lambda);
}
final LambdaExpression lambdaExpression = new LambdaExpression(this.ast);
if (this.resolveBindings) {
@@ -2534,6 +2533,72 @@ class ASTConverter {
return null; // cannot be reached
}
+ public Expression convert(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression reference) {
+ if (this.ast.apiLevel < AST.JLS8) {
+ return createFakeNullLiteral(reference);
+ }
+ Expression result = null;
+ org.eclipse.jdt.internal.compiler.ast.Expression lhs = reference.lhs;
+ org.eclipse.jdt.internal.compiler.ast.TypeReference[] arguments = reference.typeArguments;
+ int start = arguments != null && arguments.length > 0 ? arguments[arguments.length - 1].sourceEnd + 1 : reference.lhs.sourceEnd + 1;
+ final SimpleName name = new SimpleName(this.ast);
+ retrieveIdentifierAndSetPositions(start, reference.sourceEnd, name);
+ name.internalSetIdentifier(new String(reference.selector));
+ if (this.resolveBindings) {
+ recordNodes(name, reference);
+ }
+ List typeArguments = null;
+ if (name.getStartPosition() < start) {// check for new
+ retrieveInitAndSetPositions(start, reference.sourceEnd, name);
+ if (!name.getIdentifier().equals("<init>")) { //$NON-NLS-1$
+ NullLiteral nullLiteral = new NullLiteral(this.ast);
+ nullLiteral.setFlags(nullLiteral.getFlags() | ASTNode.MALFORMED);
+ result = nullLiteral;
+ } else {
+ CreationReference creationReference = new CreationReference(this.ast);
+ creationReference.setExpression(convert(lhs));
+ typeArguments = creationReference.typeArguments();
+ result = creationReference;
+ }
+ } else if (lhs instanceof TypeReference) {
+ TypeMethodReference typeMethodReference = new TypeMethodReference(this.ast);
+ typeMethodReference.setType(convertType((TypeReference) lhs));
+ typeMethodReference.setName(name);
+ typeArguments = typeMethodReference.typeArguments();
+ result = typeMethodReference;
+ } else if (lhs instanceof SuperReference) {
+ SuperMethodReference superMethodReference = new SuperMethodReference(this.ast);
+ superMethodReference.setName(name);
+ typeArguments = superMethodReference.typeArguments();
+ result = superMethodReference;
+ } else if (lhs instanceof QualifiedSuperReference) {
+ SuperMethodReference superMethodReference = new SuperMethodReference(this.ast);
+ superMethodReference.setQualifier(convert((QualifiedSuperReference)lhs));
+ superMethodReference.setName(name);
+ typeArguments = superMethodReference.typeArguments();
+ result = superMethodReference;
+ } else {
+ ExpressionMethodReference expressionMethodReference = new ExpressionMethodReference(this.ast);
+ expressionMethodReference.setExpression(convert(lhs));
+ typeArguments = expressionMethodReference.typeArguments();
+ expressionMethodReference.setName(name);
+ result = expressionMethodReference;
+ }
+ if (typeArguments != null && arguments != null) {
+ int argumentsLength = arguments.length;
+ for (int i = 0; i < argumentsLength; i++) {
+ org.eclipse.jdt.internal.compiler.ast.TypeReference argument = arguments[i];
+ typeArguments.add(convertType(argument));
+ }
+ }
+ if (this.resolveBindings) {
+ recordNodes(result, reference);
+ }
+ int sourceStart = reference.sourceStart;
+ result.setSourceRange(sourceStart, reference.sourceEnd - sourceStart + 1);
+ return result;
+ }
+
public ReturnStatement convert(org.eclipse.jdt.internal.compiler.ast.ReturnStatement statement) {
final ReturnStatement returnStatement = new ReturnStatement(this.ast);
returnStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
@@ -3893,6 +3958,21 @@ class ASTConverter {
emptyStatement.setSourceRange(start, end - start + 1);
return emptyStatement;
}
+
+ /**
+ * Warning: Callers of this method must ensure that the fake literal node is not recorded in
+ * {@link #recordNodes(ASTNode, org.eclipse.jdt.internal.compiler.ast.ASTNode)}, see bug 403444!
+ */
+ protected Expression createFakeNullLiteral(org.eclipse.jdt.internal.compiler.ast.FunctionalExpression expression) {
+ if (this.referenceContext != null) {
+ this.referenceContext.setFlags(this.referenceContext.getFlags() | ASTNode.MALFORMED);
+ }
+ NullLiteral nullLiteral = new NullLiteral(this.ast);
+ nullLiteral.setFlags(nullLiteral.getFlags() | ASTNode.MALFORMED);
+ nullLiteral.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+ return nullLiteral;
+ }
+
/**
* @return a new modifier
*/
@@ -4183,8 +4263,8 @@ class ASTConverter {
}
protected void recordNodes(ASTNode node, org.eclipse.jdt.internal.compiler.ast.ASTNode oldASTNode) {
- // Do not record the fake literal node created in lieu of LambdaExpressions at JLS levels < 8, as it would lead to CCE down the road.
- if (oldASTNode instanceof org.eclipse.jdt.internal.compiler.ast.LambdaExpression && node instanceof NullLiteral) {
+ // Do not record the fake literal node created in lieu of functional expressions at JLS levels < 8, as it would lead to CCE down the road.
+ if (oldASTNode instanceof org.eclipse.jdt.internal.compiler.ast.FunctionalExpression && node instanceof NullLiteral) {
return;
}
this.ast.getBindingResolver().store(node, oldASTNode);
@@ -4716,6 +4796,29 @@ class ASTConverter {
}
/**
+ * retrieves the start and and of new and set the positions of the name
+ * @param start position to start search
+ * @param end position to end search
+ * @param name object where these positions will be updated.
+ */
+ protected void retrieveInitAndSetPositions(int start, int end, Name name) {
+ this.scanner.resetTo(start, end);
+ int token;
+ try {
+ while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+ if (token == TerminalTokens.TokenNamenew) {
+ int startName = this.scanner.startPosition;
+ int endName = this.scanner.currentPosition;
+ name.setSourceRange(startName, endName - startName);
+ return;
+ }
+ }
+ } catch(InvalidInputException e) {
+ // ignore
+ }
+ }
+
+ /**
* This method is used to retrieve position before the next comma or semi-colon.
* @param initializerEnd the given initializer end exclusive
* @return int the position found.
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
index 76ad87be2b..39c601e6f9 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
@@ -700,6 +700,31 @@ public class ASTMatcher {
* @return <code>true</code> if the subtree matches, or
* <code>false</code> if they do not match or the other object has a
* different node type or is <code>null</code>
+ * @since 3.9 BETA_JAVA8
+ */
+ public boolean match(CreationReference node, Object other) {
+ if (!(other instanceof CreationReference)) {
+ return false;
+ }
+ CreationReference o = (CreationReference) other;
+ return (
+ safeSubtreeMatch(node.getExpression(), o.getExpression())
+ && safeSubtreeListMatch(node.typeArguments(), o.typeArguments()));
+ }
+
+ /**
+ * Returns whether the given node and the other object match.
+ * <p>
+ * The default implementation provided by this class tests whether the
+ * other object is a node of the same type with structurally isomorphic
+ * child subtrees. Subclasses may override this method as needed.
+ * </p>
+ *
+ * @param node the node
+ * @param other the other object, or <code>null</code>
+ * @return <code>true</code> if the subtree matches, or
+ * <code>false</code> if they do not match or the other object has a
+ * different node type or is <code>null</code>
*/
public boolean match(DoStatement node, Object other) {
if (!(other instanceof DoStatement)) {
@@ -832,6 +857,32 @@ public class ASTMatcher {
* @return <code>true</code> if the subtree matches, or
* <code>false</code> if they do not match or the other object has a
* different node type or is <code>null</code>
+ * @since 3.9 BETA_JAVA8
+ */
+ public boolean match(ExpressionMethodReference node, Object other) {
+ if (!(other instanceof ExpressionMethodReference)) {
+ return false;
+ }
+ ExpressionMethodReference o = (ExpressionMethodReference) other;
+ return (
+ safeSubtreeMatch(node.getExpression(), o.getExpression())
+ && safeSubtreeListMatch(node.typeArguments(), o.typeArguments())
+ && safeSubtreeMatch(node.getName(), o.getName()));
+ }
+
+ /**
+ * Returns whether the given node and the other object match.
+ * <p>
+ * The default implementation provided by this class tests whether the
+ * other object is a node of the same type with structurally isomorphic
+ * child subtrees. Subclasses may override this method as needed.
+ * </p>
+ *
+ * @param node the node
+ * @param other the other object, or <code>null</code>
+ * @return <code>true</code> if the subtree matches, or
+ * <code>false</code> if they do not match or the other object has a
+ * different node type or is <code>null</code>
*/
public boolean match(ExpressionStatement node, Object other) {
if (!(other instanceof ExpressionStatement)) {
@@ -2022,6 +2073,32 @@ public class ASTMatcher {
* @return <code>true</code> if the subtree matches, or
* <code>false</code> if they do not match or the other object has a
* different node type or is <code>null</code>
+ *
+ * @since 3.9 BETA_JAVA8
+ */
+ public boolean match(SuperMethodReference node, Object other) {
+ if (!(other instanceof SuperMethodReference)) {
+ return false;
+ }
+ SuperMethodReference o = (SuperMethodReference) other;
+ return (safeSubtreeMatch(node.getQualifier(), o.getQualifier())
+ && safeSubtreeListMatch(node.typeArguments(), o.typeArguments())
+ && safeSubtreeMatch(node.getName(), o.getName()));
+ }
+
+ /**
+ * Returns whether the given node and the other object match.
+ * <p>
+ * The default implementation provided by this class tests whether the
+ * other object is a node of the same type with structurally isomorphic
+ * child subtrees. Subclasses may override this method as needed.
+ * </p>
+ *
+ * @param node the node
+ * @param other the other object, or <code>null</code>
+ * @return <code>true</code> if the subtree matches, or
+ * <code>false</code> if they do not match or the other object has a
+ * different node type or is <code>null</code>
*/
public boolean match(SwitchCase node, Object other) {
if (!(other instanceof SwitchCase)) {
@@ -2306,6 +2383,32 @@ public class ASTMatcher {
* @return <code>true</code> if the subtree matches, or
* <code>false</code> if they do not match or the other object has a
* different node type or is <code>null</code>
+ * @since 3.9 BETA_JAVA8
+ */
+ public boolean match(TypeMethodReference node, Object other) {
+ if (!(other instanceof TypeMethodReference)) {
+ return false;
+ }
+ TypeMethodReference o = (TypeMethodReference) other;
+ return (
+ safeSubtreeMatch(node.getType(), o.getType())
+ && safeSubtreeListMatch(node.typeArguments(), o.typeArguments())
+ && safeSubtreeMatch(node.getName(), o.getName()));
+ }
+
+ /**
+ * Returns whether the given node and the other object match.
+ * <p>
+ * The default implementation provided by this class tests whether the
+ * other object is a node of the same type with structurally isomorphic
+ * child subtrees. Subclasses may override this method as needed.
+ * </p>
+ *
+ * @param node the node
+ * @param other the other object, or <code>null</code>
+ * @return <code>true</code> if the subtree matches, or
+ * <code>false</code> if they do not match or the other object has a
+ * different node type or is <code>null</code>
* @since 3.1
*/
public boolean match(TypeParameter node, Object other) {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
index 6bba4f50fe..5885d339e1 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
@@ -868,6 +868,38 @@ public abstract class ASTNode {
public static final int PACKAGE_QUALIFIED_TYPE = 88;
/**
+ * Node type constant indicating a node of type
+ * <code>CreationReference</code>.
+ * @see CreationReference
+ * @since 3.9 BETA_JAV8
+ */
+ public static final int CREATION_REFERENCE = 89;
+
+ /**
+ * Node type constant indicating a node of type
+ * <code>ExpressionMethodReference</code>.
+ * @see ExpressionMethodReference
+ * @since 3.9 BETA_JAV8
+ */
+ public static final int EXPRESSION_METHOD_REFERENCE = 90;
+
+ /**
+ * Node type constant indicating a node of type
+ * <code>SuperMethhodReference</code>.
+ * @see SuperMethodReference
+ * @since 3.9 BETA_JAV8
+ */
+ public static final int SUPER_METHOD_REFERENCE = 91;
+
+ /**
+ * Node type constant indicating a node of type
+ * <code>TypeMethodReference</code>.
+ * @see TypeMethodReference
+ * @since 3.9 BETA_JAV8
+ */
+ public static final int TYPE_METHOD_REFERENCE = 92;
+
+ /**
* Returns the node class for the corresponding node type.
*
* @param nodeType AST node type
@@ -921,6 +953,8 @@ public abstract class ASTNode {
return ConstructorInvocation.class;
case CONTINUE_STATEMENT :
return ContinueStatement.class;
+ case CREATION_REFERENCE :
+ return CreationReference.class;
case UNION_TYPE :
return UnionType.class;
case DO_STATEMENT :
@@ -933,6 +967,8 @@ public abstract class ASTNode {
return EnumConstantDeclaration.class;
case ENUM_DECLARATION :
return EnumDeclaration.class;
+ case EXPRESSION_METHOD_REFERENCE :
+ return ExpressionMethodReference.class;
case EXPRESSION_STATEMENT :
return ExpressionStatement.class;
case EXTRA_DIMENSION:
@@ -1021,6 +1057,8 @@ public abstract class ASTNode {
return SuperFieldAccess.class;
case SUPER_METHOD_INVOCATION :
return SuperMethodInvocation.class;
+ case SUPER_METHOD_REFERENCE :
+ return SuperMethodReference.class;
case SWITCH_CASE:
return SwitchCase.class;
case SWITCH_STATEMENT :
@@ -1041,6 +1079,8 @@ public abstract class ASTNode {
return TypeDeclaration.class;
case TYPE_DECLARATION_STATEMENT :
return TypeDeclarationStatement.class;
+ case TYPE_METHOD_REFERENCE :
+ return TypeMethodReference.class;
case TYPE_LITERAL :
return TypeLiteral.class;
case TYPE_PARAMETER :
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
index 681e325d6a..b4ffbaf425 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
@@ -535,6 +535,23 @@ public abstract class ASTVisitor {
* Visits the given type-specific AST node.
* <p>
* The default implementation does nothing and return true.
+ * Subclasses may re-implement.
+ * </p>
+ *
+ * @param node the node to visit
+ * @return <code>true</code> if the children of this node should be
+ * visited, and <code>false</code> if the children of this node should
+ * be skipped
+ * @since 3.9 BETA_JAVA8
+ */
+ public boolean visit(CreationReference node) {
+ return true;
+ }
+
+ /**
+ * Visits the given type-specific AST node.
+ * <p>
+ * The default implementation does nothing and return true.
* Subclasses may reimplement.
* </p>
*
@@ -618,6 +635,23 @@ public abstract class ASTVisitor {
* Visits the given type-specific AST node.
* <p>
* The default implementation does nothing and return true.
+ * Subclasses may re-implement.
+ * </p>
+ *
+ * @param node the node to visit
+ * @return <code>true</code> if the children of this node should be
+ * visited, and <code>false</code> if the children of this node should
+ * be skipped
+ * @since 3.9 BETA_JAVA8
+ */
+ public boolean visit(ExpressionMethodReference node) {
+ return true;
+ }
+
+ /**
+ * Visits the given type-specific AST node.
+ * <p>
+ * The default implementation does nothing and return true.
* Subclasses may reimplement.
* </p>
*
@@ -1367,6 +1401,23 @@ public abstract class ASTVisitor {
* @return <code>true</code> if the children of this node should be
* visited, and <code>false</code> if the children of this node should
* be skipped
+ * @since 3.9 BETA_JAVA8
+ */
+ public boolean visit(SuperMethodReference node) {
+ return true;
+ }
+
+ /**
+ * Visits the given type-specific AST node.
+ * <p>
+ * The default implementation does nothing and return true.
+ * Subclasses may reimplement.
+ * </p>
+ *
+ * @param node the node to visit
+ * @return <code>true</code> if the children of this node should be
+ * visited, and <code>false</code> if the children of this node should
+ * be skipped
*/
public boolean visit(SwitchCase node) {
return true;
@@ -1547,6 +1598,24 @@ public abstract class ASTVisitor {
* @return <code>true</code> if the children of this node should be
* visited, and <code>false</code> if the children of this node should
* be skipped
+ *
+ * @since 3.9 BETA_JAVA8
+ */
+ public boolean visit(TypeMethodReference node) {
+ return true;
+ }
+
+ /**
+ * Visits the given type-specific AST node.
+ * <p>
+ * The default implementation does nothing and return true.
+ * Subclasses may reimplement.
+ * </p>
+ *
+ * @param node the node to visit
+ * @return <code>true</code> if the children of this node should be
+ * visited, and <code>false</code> if the children of this node should
+ * be skipped
* @since 3.1
*/
public boolean visit(TypeParameter node) {
@@ -1918,6 +1987,19 @@ public abstract class ASTVisitor {
* </p>
*
* @param node the node to visit
+ * @since 3.9 BETA_JAVA8
+ */
+ public void endVisit(CreationReference node) {
+ // default implementation: do nothing
+ }
+
+ /**
+ * End of visit the given type-specific AST node.
+ * <p>
+ * The default implementation does nothing. Subclasses may reimplement.
+ * </p>
+ *
+ * @param node the node to visit
*/
public void endVisit(DoStatement node) {
// default implementation: do nothing
@@ -1981,6 +2063,19 @@ public abstract class ASTVisitor {
* </p>
*
* @param node the node to visit
+ * @since 3.9 BETA_JAVA8
+ */
+ public void endVisit(ExpressionMethodReference node) {
+ // default implementation: do nothing
+ }
+
+ /**
+ * End of visit the given type-specific AST node.
+ * <p>
+ * The default implementation does nothing. Subclasses may reimplement.
+ * </p>
+ *
+ * @param node the node to visit
*/
public void endVisit(ExpressionStatement node) {
// default implementation: do nothing
@@ -2516,6 +2611,19 @@ public abstract class ASTVisitor {
* </p>
*
* @param node the node to visit
+ * @since 3.9 BETA_JAVA8
+ */
+ public void endVisit(SuperMethodReference node) {
+ // default implementation: do nothing
+ }
+
+ /**
+ * End of visit the given type-specific AST node.
+ * <p>
+ * The default implementation does nothing. Subclasses may reimplement.
+ * </p>
+ *
+ * @param node the node to visit
*/
public void endVisit(SwitchCase node) {
// default implementation: do nothing
@@ -2649,6 +2757,20 @@ public abstract class ASTVisitor {
* </p>
*
* @param node the node to visit
+ *
+ * @since 3.9 BETA_JAVA8
+ */
+ public void endVisit(TypeMethodReference node) {
+ // default implementation: do nothing
+ }
+
+ /**
+ * End of visit the given type-specific AST node.
+ * <p>
+ * The default implementation does nothing. Subclasses may reimplement.
+ * </p>
+ *
+ * @param node the node to visit
* @since 3.1
*/
public void endVisit(TypeParameter node) {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java
index 71274a3789..de79a4cffd 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java
@@ -581,6 +581,28 @@ class BindingResolver {
}
/**
+ * Resolves the given method reference and returns the binding for it.
+ * <p>
+ * The implementation of <code>MethodReference.resolveMethodBinding</code>
+ * forwards to this method. How the method resolves is often a function of
+ * the context in which the method reference node is embedded as well as
+ * the method reference subtree itself.
+ * </p>
+ * <p>
+ * The default implementation of this method returns <code>null</code>.
+ * Subclasses may reimplement.
+ * </p>
+ *
+ * @param methodReference the method reference of interest
+ * @return the binding for the given method reference, or
+ * <code>null</code> if no binding is available
+ * @since 3.9 BETA_JAVA8
+ */
+ IMethodBinding resolveMethod(MethodReference methodReference) {
+ return null;
+ }
+
+ /**
* Resolves the given Lambda Expression and returns the binding for it.
* <p>
* The implementation of <code>LambdaExpression.resolveMethodBinding</code>
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CreationReference.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CreationReference.java
new file mode 100644
index 0000000000..548afe7351
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CreationReference.java
@@ -0,0 +1,261 @@
+/*******************************************************************************
+ * Copyright (c) 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.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Creation reference expression AST node type (added in JLS8 API).
+ *
+ * <pre>
+ * CreationReference:
+ * Expression <b>::</b>
+ * [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ * <b>new</b>
+ * </pre>
+ *
+ * @since 3.9 BETA_JAVA8
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class CreationReference extends MethodReference {
+
+ /**
+ * The "expression" structural property of this node type (child type: {@link Expression}).
+ */
+ public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+ new ChildPropertyDescriptor(CreationReference.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+ /**
+ * The "typeArguments" structural property of this node type (element type: {@link Type})
+ */
+ public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+ internalTypeArgumentsFactory(CreationReference.class);
+
+ /**
+ * A list of property descriptors (element type:
+ * {@link StructuralPropertyDescriptor}),
+ * or null if uninitialized.
+ */
+ private static final List PROPERTY_DESCRIPTORS_8_0;
+
+ static {
+ List propertyList = new ArrayList(4);
+ createPropertyList(CreationReference.class, propertyList);
+ addProperty(EXPRESSION_PROPERTY, propertyList);
+ addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
+ PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+ }
+
+ /**
+ * Returns a list of structural property descriptors for this node type.
+ * Clients must not modify the result.
+ *
+ * @param apiLevel the API level; one of the AST.JLS* constants
+ * @return a list of property descriptors (element type:
+ * {@link StructuralPropertyDescriptor})
+ */
+ public static List propertyDescriptors(int apiLevel) {
+ return PROPERTY_DESCRIPTORS_8_0;
+ }
+
+ /**
+ * The expression; lazily initialized; defaults to an unspecified,
+ * legal expression (a simple name).
+ */
+ private Expression expression = null;
+
+ /**
+ * Creates a new AST node for an CreationReference declaration owned
+ * by the given AST.
+ * <p>
+ * N.B. This constructor is package-private; all subclasses must be
+ * declared in the same package; clients are unable to declare
+ * additional subclasses.
+ * </p>
+ *
+ * @param ast the AST that is to own this node
+ */
+ CreationReference(AST ast) {
+ super(ast);
+ unsupportedIn2_3_4();
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on MethodReference.
+ */
+ final ChildListPropertyDescriptor internalTypeArgumentsProperty() {
+ return TYPE_ARGUMENTS_PROPERTY;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final List internalStructuralPropertiesForType(int apiLevel) {
+ return propertyDescriptors(apiLevel);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+ if (property == EXPRESSION_PROPERTY) {
+ if (get) {
+ return getExpression();
+ } else {
+ setExpression((Expression) child);
+ return null;
+ }
+ }
+ // allow default implementation to flag the error
+ return super.internalGetSetChildProperty(property, get, child);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+ if (property == TYPE_ARGUMENTS_PROPERTY) {
+ return typeArguments();
+ }
+ // allow default implementation to flag the error
+ return super.internalGetChildListProperty(property);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final int getNodeType0() {
+ return CREATION_REFERENCE;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ ASTNode clone0(AST target) {
+ CreationReference result = new CreationReference(target);
+ result.setSourceRange(getStartPosition(), getLength());
+ result.setExpression(
+ (Expression) ASTNode.copySubtree(target, getExpression()));
+ result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
+ return result;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+ // dispatch to correct overloaded match method
+ return matcher.match(this, other);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ void accept0(ASTVisitor visitor) {
+ boolean visitChildren = visitor.visit(this);
+ if (visitChildren) {
+ // visit children in normal left to right reading order
+ acceptChild(visitor, getExpression());
+ acceptChildren(visitor, this.typeArguments);
+ }
+ visitor.endVisit(this);
+ }
+
+ /**
+ * Returns the expression of this Creation Reference expression, or
+ * <code>null</code> if there is none.
+ *
+ * @return the expression node, or <code>null</code> if there is none
+ */
+ public Expression getExpression() {
+ if (this.expression == null) {
+ // lazy init must be thread-safe for readers
+ synchronized (this) {
+ if (this.expression == null) {
+ preLazyInit();
+ this.expression = new SimpleName(this.ast);
+ postLazyInit(this.expression, EXPRESSION_PROPERTY);
+ }
+ }
+ }
+ return this.expression;
+ }
+
+ /**
+ * Sets the expression of this Creation Reference.
+ *
+ * @param expression the expression node, or <code>null</code> if
+ * there is none
+ * @exception IllegalArgumentException if:
+ * <ul>
+ * <li>the node belongs to a different AST</li>
+ * <li>the node already has a parent</li>
+ * <li>a cycle in would be created</li>
+ * </ul>
+ */
+ public void setExpression(Expression expression) {
+ if (expression == null) {
+ throw new IllegalArgumentException();
+ }
+ ASTNode oldChild = this.expression;
+ preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+ this.expression = expression;
+ postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+ }
+
+ /**
+ * Returns the live ordered list of type arguments of this Creation Reference.
+ *
+ * @return the live list of type arguments
+ * (element type: {@link Type})
+ */
+ public List typeArguments() {
+ return this.typeArguments;
+ }
+
+ /**
+ * Resolves and returns the binding for the method reference by this
+ * expression.
+ * <p>
+ * Note that bindings are generally unavailable unless requested when the
+ * AST is being built.
+ * </p>
+ *
+ * @return the method binding, or <code>null</code> if the binding cannot
+ * be resolved
+ */
+ public IMethodBinding resolveMethodBinding() {
+ return this.ast.getBindingResolver().resolveMethod(this);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ int memSize() {
+ // treat Code as free
+ return BASE_NODE_SIZE + 2 * 4;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ int treeSize() {
+ return
+ memSize()
+ + (this.expression == null ? 0 : getExpression().treeSize())
+ + (this.typeArguments == null ? 0 : this.typeArguments.listSize());
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java
index 029f3ccd0f..c8bffe5a7e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java
@@ -92,6 +92,9 @@ class DefaultASTVisitor extends ASTVisitor {
public void endVisit(ContinueStatement node) {
endVisitNode(node);
}
+ public void endVisit(CreationReference node) {
+ endVisitNode(node);
+ }
public void endVisit(DoStatement node) {
endVisitNode(node);
}
@@ -107,6 +110,9 @@ class DefaultASTVisitor extends ASTVisitor {
public void endVisit(EnumDeclaration node) {
endVisitNode(node);
}
+ public void endVisit(ExpressionMethodReference node) {
+ endVisitNode(node);
+ }
public void endVisit(ExpressionStatement node) {
endVisitNode(node);
}
@@ -239,7 +245,9 @@ class DefaultASTVisitor extends ASTVisitor {
public void endVisit(SuperMethodInvocation node) {
endVisitNode(node);
}
-
+ public void endVisit(SuperMethodReference node) {
+ endVisitNode(node);
+ }
public void endVisit(SwitchCase node) {
endVisitNode(node);
}
@@ -274,6 +282,9 @@ class DefaultASTVisitor extends ASTVisitor {
public void endVisit(TypeLiteral node) {
endVisitNode(node);
}
+ public void endVisit(TypeMethodReference node) {
+ endVisitNode(node);
+ }
public void endVisit(TypeParameter node) {
endVisitNode(node);
}
@@ -363,6 +374,9 @@ class DefaultASTVisitor extends ASTVisitor {
public boolean visit(ContinueStatement node) {
return visitNode(node);
}
+ public boolean visit(CreationReference node) {
+ return visitNode(node);
+ }
public boolean visit(DoStatement node) {
return visitNode(node);
}
@@ -378,6 +392,9 @@ class DefaultASTVisitor extends ASTVisitor {
public boolean visit(EnumDeclaration node) {
return visitNode(node);
}
+ public boolean visit(ExpressionMethodReference node) {
+ return visitNode(node);
+ }
public boolean visit(ExpressionStatement node) {
return visitNode(node);
}
@@ -520,6 +537,10 @@ class DefaultASTVisitor extends ASTVisitor {
return visitNode(node);
}
+ public boolean visit(SuperMethodReference node) {
+ return visitNode(node);
+ }
+
public boolean visit(SwitchCase node) {
return visitNode(node);
}
@@ -564,6 +585,10 @@ class DefaultASTVisitor extends ASTVisitor {
return visitNode(node);
}
+ public boolean visit(TypeMethodReference node) {
+ return visitNode(node);
+ }
+
public boolean visit(TypeParameter node) {
return visitNode(node);
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
index 49f5856f1c..4f266a1cb0 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
@@ -709,6 +709,10 @@ class DefaultBindingResolver extends BindingResolver {
case ASTNode.INFIX_EXPRESSION :
case ASTNode.INSTANCEOF_EXPRESSION :
case ASTNode.LAMBDA_EXPRESSION:
+ case ASTNode.CREATION_REFERENCE:
+ case ASTNode.EXPRESSION_METHOD_REFERENCE:
+ case ASTNode.TYPE_METHOD_REFERENCE:
+ case ASTNode.SUPER_METHOD_REFERENCE :
case ASTNode.FIELD_ACCESS :
case ASTNode.SUPER_FIELD_ACCESS :
case ASTNode.ARRAY_ACCESS :
@@ -875,15 +879,15 @@ class DefaultBindingResolver extends BindingResolver {
/*
* Method declared on BindingResolver.
*/
- synchronized IMethodBinding resolveMethod(MethodDeclaration method) {
- Object oldNode = this.newAstToOldAst.get(method);
- if (oldNode instanceof AbstractMethodDeclaration) {
- AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) oldNode;
- IMethodBinding methodBinding = getMethodBinding(methodDeclaration.binding);
+ synchronized IMethodBinding resolveMethod(LambdaExpression lambda) {
+ Object oldNode = this.newAstToOldAst.get(lambda);
+ if (oldNode instanceof org.eclipse.jdt.internal.compiler.ast.LambdaExpression) {
+ org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambdaExpression = (org.eclipse.jdt.internal.compiler.ast.LambdaExpression) oldNode;
+ IMethodBinding methodBinding = getMethodBinding(lambdaExpression.binding);
if (methodBinding == null) {
return null;
}
- this.bindingsToAstNodes.put(methodBinding, method);
+ this.bindingsToAstNodes.put(methodBinding, lambda);
String key = methodBinding.getKey();
if (key != null) {
this.bindingTables.bindingKeysToBindings.put(key, methodBinding);
@@ -895,15 +899,15 @@ class DefaultBindingResolver extends BindingResolver {
/*
* Method declared on BindingResolver.
*/
- synchronized IMethodBinding resolveMethod(LambdaExpression lambda) {
- Object oldNode = this.newAstToOldAst.get(lambda);
- if (oldNode instanceof org.eclipse.jdt.internal.compiler.ast.LambdaExpression) {
- org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambdaExpression = (org.eclipse.jdt.internal.compiler.ast.LambdaExpression) oldNode;
- IMethodBinding methodBinding = getMethodBinding(lambdaExpression.binding);
+ synchronized IMethodBinding resolveMethod(MethodDeclaration method) {
+ Object oldNode = this.newAstToOldAst.get(method);
+ if (oldNode instanceof AbstractMethodDeclaration) {
+ AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) oldNode;
+ IMethodBinding methodBinding = getMethodBinding(methodDeclaration.binding);
if (methodBinding == null) {
return null;
}
- this.bindingsToAstNodes.put(methodBinding, lambda);
+ this.bindingsToAstNodes.put(methodBinding, method);
String key = methodBinding.getKey();
if (key != null) {
this.bindingTables.bindingKeysToBindings.put(key, methodBinding);
@@ -926,6 +930,26 @@ class DefaultBindingResolver extends BindingResolver {
/*
* Method declared on BindingResolver.
*/
+ synchronized IMethodBinding resolveMethod(MethodReference methodReference) {
+ Object oldNode = this.newAstToOldAst.get(methodReference);
+ if (oldNode instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) {
+ org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression = (org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) oldNode;
+ IMethodBinding methodBinding = getMethodBinding(referenceExpression.binding);
+ if (methodBinding == null) {
+ return null;
+ }
+ this.bindingsToAstNodes.put(methodBinding, methodReference);
+ String key = methodBinding.getKey();
+ if (key != null) {
+ this.bindingTables.bindingKeysToBindings.put(key, methodBinding);
+ }
+ return methodBinding;
+ }
+ return null;
+ }
+ /*
+ * Method declared on BindingResolver.
+ */
synchronized IMethodBinding resolveMethod(SuperMethodInvocation method) {
Object oldNode = this.newAstToOldAst.get(method);
if (oldNode instanceof MessageSend) {
@@ -1140,6 +1164,11 @@ class DefaultBindingResolver extends BindingResolver {
IMethodBinding method = getMethodBinding(memberValuePair.binding);
if (method == null) return null;
return method.getReturnType();
+ } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) {
+ org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression = (org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) node;
+ IMethodBinding method = getMethodBinding(referenceExpression.binding);
+ if (method == null) return null;
+ return method.getReturnType();
}
return null;
}
@@ -1400,6 +1429,9 @@ class DefaultBindingResolver extends BindingResolver {
} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.MemberValuePair) {
org.eclipse.jdt.internal.compiler.ast.MemberValuePair memberValuePair = (org.eclipse.jdt.internal.compiler.ast.MemberValuePair) node;
return getMethodBinding(memberValuePair.binding);
+ } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) {
+ org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression = (org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) node;
+ return getMethodBinding(referenceExpression.binding);
}
return null;
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
index 6fd76fa9cc..a5b6dabb37 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
@@ -31,11 +31,14 @@ package org.eclipse.jdt.core.dom;
* {@link CharacterLiteral},
* {@link ClassInstanceCreation},
* {@link ConditionalExpression},
+ * {@link CreationReference},
+ * {@link ExpressionMethodReference},
* {@link FieldAccess},
* {@link InfixExpression},
* {@link InstanceofExpression},
* {@link LambdaExpression},
* {@link MethodInvocation},
+ * {@link MethodReference},
* {@link Name},
* {@link NullLiteral},
* {@link NumberLiteral},
@@ -45,8 +48,10 @@ package org.eclipse.jdt.core.dom;
* {@link StringLiteral},
* {@link SuperFieldAccess},
* {@link SuperMethodInvocation},
+ * {@link SuperMethodReference},
* {@link ThisExpression},
* {@link TypeLiteral},
+ * {@link TypeMethodReference},
* {@link VariableDeclarationExpression}
* </pre>
* </p>
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionMethodReference.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionMethodReference.java
new file mode 100644
index 0000000000..b1f39588fe
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionMethodReference.java
@@ -0,0 +1,296 @@
+/*******************************************************************************
+ * Copyright (c) 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.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Expression method reference AST node type (added in JLS8 API).
+ * <pre>
+ * ExpressionMethodReference:
+ * Expression <b>::</b>
+ * [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ * Identifier
+ * </pre>
+ *
+ * @since 3.9 BETA_JAVA8
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ExpressionMethodReference extends MethodReference {
+
+ /**
+ * The "expression" structural property of this node type (child type: {@link Expression}).
+ */
+ public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+ new ChildPropertyDescriptor(ExpressionMethodReference.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+ /**
+ * The "typeArguments" structural property of this node type (element type: {@link Type})
+ */
+ public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+ internalTypeArgumentsFactory(ExpressionMethodReference.class);
+
+ /**
+ * The "name" structural property of this node type (child type: {@link SimpleName}.
+ */
+ public static final ChildPropertyDescriptor NAME_PROPERTY =
+ new ChildPropertyDescriptor(ExpressionMethodReference.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+ /**
+ * A list of property descriptors (element type:
+ * {@link StructuralPropertyDescriptor}),
+ * or null if uninitialized.
+ */
+ private static final List PROPERTY_DESCRIPTORS_8_0;
+
+ static {
+ List propertyList = new ArrayList(4);
+ createPropertyList(ExpressionMethodReference.class, propertyList);
+ addProperty(EXPRESSION_PROPERTY, propertyList);
+ addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
+ addProperty(NAME_PROPERTY, propertyList);
+ PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+ }
+
+ /**
+ * Returns a list of structural property descriptors for this node type.
+ * Clients must not modify the result.
+ *
+ * @param apiLevel the API level; one of the AST.JLS* constants
+ * @return a list of property descriptors (element type:
+ * {@link StructuralPropertyDescriptor})
+ */
+ public static List propertyDescriptors(int apiLevel) {
+ return PROPERTY_DESCRIPTORS_8_0;
+ }
+
+ /**
+ * The expression; defaults to null.
+ */
+ private Expression expression = null;
+
+ /**
+ * The method name; lazily initialized; defaults to an unspecified,
+ * legal Java method name.
+ */
+ private SimpleName methodName = null;
+
+ /**
+ * Creates a new AST node for an ExpressionMethodReference declaration owned
+ * by the given AST.
+ * <p>
+ * N.B. This constructor is package-private; all subclasses must be
+ * declared in the same package; clients are unable to declare
+ * additional subclasses.
+ * </p>
+ *
+ * @param ast the AST that is to own this node
+ */
+ ExpressionMethodReference(AST ast) {
+ super(ast);
+ unsupportedIn2_3_4();
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on MethodReference.
+ */
+ final ChildListPropertyDescriptor internalTypeArgumentsProperty() {
+ return TYPE_ARGUMENTS_PROPERTY;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final List internalStructuralPropertiesForType(int apiLevel) {
+ return propertyDescriptors(apiLevel);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+ if (property == NAME_PROPERTY) {
+ if (get) {
+ return getName();
+ } else {
+ setName((SimpleName) child);
+ return null;
+ }
+ }
+ if (property == EXPRESSION_PROPERTY) {
+ if (get) {
+ return getExpression();
+ } else {
+ setExpression((Expression) child);
+ return null;
+ }
+ }
+ // allow default implementation to flag the error
+ return super.internalGetSetChildProperty(property, get, child);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+ if (property == TYPE_ARGUMENTS_PROPERTY) {
+ return typeArguments();
+ }
+ // allow default implementation to flag the error
+ return super.internalGetChildListProperty(property);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final int getNodeType0() {
+ return EXPRESSION_METHOD_REFERENCE;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ ASTNode clone0(AST target) {
+ ExpressionMethodReference result = new ExpressionMethodReference(target);
+ result.setSourceRange(getStartPosition(), getLength());
+ result.setExpression(
+ (Expression) ASTNode.copySubtree(target, getExpression()));
+ result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
+ result.setName((SimpleName) getName().clone(target));
+ return result;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+ // dispatch to correct overloaded match method
+ return matcher.match(this, other);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ void accept0(ASTVisitor visitor) {
+ boolean visitChildren = visitor.visit(this);
+ if (visitChildren) {
+ // visit children in normal left to right reading order
+ acceptChild(visitor, getExpression());
+ acceptChildren(visitor, this.typeArguments);
+ acceptChild(visitor, getName());
+ }
+ visitor.endVisit(this);
+ }
+
+ /**
+ * Returns the expression of this expression method reference expression
+ *
+ * @return the expression node
+ */
+ public Expression getExpression() {
+ return this.expression;
+ }
+
+ /**
+ * Sets the expression of this expression method reference.
+ *
+ * @param expression the expression node
+ * @exception IllegalArgumentException if:
+ * <ul>
+ * <li>the node belongs to a different AST</li>
+ * <li>the node already has a parent</li>
+ * <li>a cycle in would be created</li>
+ * </ul>
+ */
+ public void setExpression(Expression expression) {
+ if (expression == null) {
+ throw new IllegalArgumentException();
+ }
+ ASTNode oldChild = this.expression;
+ preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+ this.expression = expression;
+ postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+ }
+
+ /**
+ * Returns the live ordered list of type arguments of this expression method reference
+ *
+ * @return the live list of type arguments
+ * (element type: {@link Type})
+ */
+ public List typeArguments() {
+ return this.typeArguments;
+ }
+
+ /**
+ * Returns the name of the method referenced in this expression.
+ *
+ * @return the method name node
+ */
+ public SimpleName getName() {
+ if (this.methodName == null) {
+ // lazy init must be thread-safe for readers
+ synchronized (this) {
+ if (this.methodName == null) {
+ preLazyInit();
+ this.methodName = new SimpleName(this.ast);
+ postLazyInit(this.methodName, NAME_PROPERTY);
+ }
+ }
+ }
+ return this.methodName;
+ }
+
+ /**
+ * Sets the name of the method referenced in this expression to the
+ * given name.
+ *
+ * @param name the new method name
+ * @exception IllegalArgumentException if:
+ * <ul>
+ * <li>the node belongs to a different AST</li>
+ * <li>the node already has a parent</li>
+ * </ul>
+ */
+ public void setName(SimpleName name) {
+ if (name == null) {
+ throw new IllegalArgumentException();
+ }
+ ASTNode oldChild = this.methodName;
+ preReplaceChild(oldChild, name, NAME_PROPERTY);
+ this.methodName = name;
+ postReplaceChild(oldChild, name, NAME_PROPERTY);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ int memSize() {
+ // treat Code as free
+ return BASE_NODE_SIZE + 3 * 4;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ int treeSize() {
+ return
+ memSize()
+ + (this.expression == null ? 0 : getExpression().treeSize())
+ + (this.typeArguments == null ? 0 : this.typeArguments.listSize())
+ + (this.methodName == null ? 0 : getName().treeSize());
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodReference.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodReference.java
new file mode 100644
index 0000000000..2cf929e307
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodReference.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 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.dom;
+
+import java.util.List;
+
+/**
+ * Abstract base class of all AST node types that represent a method reference
+ * expression (added in JLS8 API).
+ * <p>
+ * <pre>
+ * MethodReference:
+ * CreationReference
+ * ExpressionMethodReference
+ * SuperMethodReference
+ * TypeMethodReference
+ * </pre>
+ * </p>
+ *
+ * @see CreationReference
+ * @see ExpressionMethodReference
+ * @see SuperMethodReference
+ * @see TypeMethodReference
+ * @since 3.9 BETA_JAVA8
+ */
+public abstract class MethodReference extends Expression {
+
+ /**
+ * The type arguments (element type: {@link Type}).
+ * Defaults to an empty list (see constructor).
+ */
+ ASTNode.NodeList typeArguments;
+
+ /**
+ * Creates and returns a structural property descriptor for the "typeArguments"
+ * property declared on the given concrete node type (element type: {@link Type}).
+ *
+ * @return the property descriptor
+ */
+ static final ChildListPropertyDescriptor internalTypeArgumentsFactory(Class nodeClass) {
+ return new ChildListPropertyDescriptor(nodeClass, "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the structural property descriptor for the "typeArguments" property
+ * of this node (element type: {@link Type}).
+ *
+ * @return the property descriptor
+ */
+ abstract ChildListPropertyDescriptor internalTypeArgumentsProperty();
+
+ /**
+ * Returns the structural property descriptor for the "typeArguments" property
+ * of this node (element type: {@link Type}).
+ *
+ * @return the property descriptor
+ */
+ public final ChildListPropertyDescriptor getTypeArgumentsProperty() {
+ return internalTypeArgumentsProperty();
+ }
+
+ /**
+ * Creates a new AST node for a method reference owned by the given AST.
+ * <p>
+ * N.B. This constructor is package-private.
+ * </p>
+ *
+ * @param ast the AST that is to own this node
+ */
+ MethodReference(AST ast) {
+ super(ast);
+ this.typeArguments = new ASTNode.NodeList(getTypeArgumentsProperty());
+ }
+
+ /**
+ * Returns the live ordered list of type arguments of this method reference.
+ *
+ * @return the live list of type arguments
+ * (element type: {@link Type})
+ */
+ public List typeArguments() {
+ return this.typeArguments;
+ }
+
+ /**
+ * Resolves and returns the binding for the method referenced by this
+ * method reference expression.
+ * <p>
+ * Note that bindings are generally unavailable unless requested when the
+ * AST is being built.
+ * </p>
+ *
+ * @return the method binding, or <code>null</code> if the binding cannot
+ * be resolved
+ */
+ public IMethodBinding resolveMethodBinding() {
+ return this.ast.getBindingResolver().resolveMethod(this);
+ }
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodReference.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodReference.java
new file mode 100644
index 0000000000..9725848472
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodReference.java
@@ -0,0 +1,291 @@
+/*******************************************************************************
+ * Copyright (c) 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.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Super method reference AST node type (added in JLS8 API).
+ *
+ * <pre>
+ * SuperMethodReference:
+ * [ ClassName <b>.</b> ] <b>super</b> <b>::</b>
+ * [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ * Identifier
+ * </pre>
+ *
+ * @since 3.9 BETA_JAVA8
+ * @noinstantiate This class is not intended to be instantiated by clients
+ */
+public class SuperMethodReference extends MethodReference {
+
+ /**
+ * The "qualifier" structural property of this node type (child type: {@link Name}).
+ */
+ public static final ChildPropertyDescriptor QUALIFIER_PROPERTY =
+ new ChildPropertyDescriptor(SuperMethodReference.class, "qualifier", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+ /**
+ * The "typeArguments" structural property of this node type (element type: {@link Type})
+ */
+ public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+ internalTypeArgumentsFactory(SuperMethodReference.class);
+
+ /**
+ * The "name" structural property of this node type (child type: {@link SimpleName}).
+ */
+ public static final ChildPropertyDescriptor NAME_PROPERTY =
+ new ChildPropertyDescriptor(SuperMethodReference.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+ /**
+ * A list of property descriptors (element type:
+ * {@link StructuralPropertyDescriptor}),
+ * or null if uninitialized.
+ */
+ private static final List PROPERTY_DESCRIPTORS_8_0;
+
+ static {
+ List propertyList = new ArrayList(4);
+ createPropertyList(SuperMethodReference.class, propertyList);
+ addProperty(QUALIFIER_PROPERTY, propertyList);
+ addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
+ addProperty(NAME_PROPERTY, propertyList);
+ PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+ }
+
+ /**
+ * Returns a list of structural property descriptors for this node type.
+ * Clients must not modify the result.
+ *
+ * @param apiLevel the API level; one of the
+ * <code>AST.JLS*</code> constants
+ * @return a list of property descriptors (element type:
+ * {@link StructuralPropertyDescriptor})
+ */
+ public static List propertyDescriptors(int apiLevel) {
+ return PROPERTY_DESCRIPTORS_8_0;
+ }
+
+ /**
+ * The optional qualifier; <code>null</code> for none; defaults to none.
+ */
+ private Name optionalQualifier = null;
+
+ /**
+ * The method name; lazily initialized; defaults to a unspecified,
+ * legal Java method name.
+ */
+ private SimpleName methodName = null;
+ /**
+ * Creates a new AST node for a super method reference owned
+ * by the given AST. By default, there is no qualifier.
+ * <p>
+ * N.B. This constructor is package-private; all subclasses must be
+ * declared in the same package; clients are unable to declare
+ * additional subclasses.
+ * </p>
+ *
+ * @param ast the AST that is to own this node
+ */
+ SuperMethodReference(AST ast) {
+ super(ast);
+ unsupportedIn2_3_4();
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on MethodReference.
+ */
+ final ChildListPropertyDescriptor internalTypeArgumentsProperty() {
+ return TYPE_ARGUMENTS_PROPERTY;
+ }
+
+ final List internalStructuralPropertiesForType(int apiLevel) {
+ return propertyDescriptors(apiLevel);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+ if (property == QUALIFIER_PROPERTY) {
+ if (get) {
+ return getQualifier();
+ } else {
+ setQualifier((Name) child);
+ return null;
+ }
+ }
+ if (property == NAME_PROPERTY) {
+ if (get) {
+ return getName();
+ } else {
+ setName((SimpleName) child);
+ return null;
+ }
+ }
+ // allow default implementation to flag the error
+ return super.internalGetSetChildProperty(property, get, child);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+ if (property == TYPE_ARGUMENTS_PROPERTY) {
+ return typeArguments();
+ }
+ // allow default implementation to flag the error
+ return super.internalGetChildListProperty(property);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final int getNodeType0() {
+ return SUPER_METHOD_REFERENCE;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ ASTNode clone0(AST target) {
+ SuperMethodReference result = new SuperMethodReference(target);
+ result.setSourceRange(getStartPosition(), getLength());
+ result.setName((SimpleName) getName().clone(target));
+ result.setQualifier((Name) ASTNode.copySubtree(target, getQualifier()));
+ result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
+ return result;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+ // dispatch to correct overloaded match method
+ return matcher.match(this, other);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ void accept0(ASTVisitor visitor) {
+ boolean visitChildren = visitor.visit(this);
+ if (visitChildren) {
+ // visit children in normal left to right reading order
+ acceptChild(visitor, getQualifier());
+ acceptChildren(visitor, this.typeArguments);
+ acceptChild(visitor, getName());
+ }
+ visitor.endVisit(this);
+ }
+
+ /**
+ * Returns the qualifier of this "super" method reference, or
+ * <code>null</code> if there is none.
+ *
+ * @return the qualifier name node, or <code>null</code> if there is none
+ */
+ public Name getQualifier() {
+ return this.optionalQualifier;
+ }
+
+ /**
+ * Sets the qualifier of this "super" method reference expression.
+ *
+ * @param name the qualifier name node, or <code>null</code> if
+ * there is none
+ * @exception IllegalArgumentException if:
+ * <ul>
+ * <li>the node belongs to a different AST</li>
+ * <li>the node already has a parent</li>
+ * </ul>
+ */
+ public void setQualifier(Name name) {
+ ASTNode oldChild = this.optionalQualifier;
+ preReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+ this.optionalQualifier = name;
+ postReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+ }
+
+ /**
+ * Returns the live ordered list of type arguments of this super method reference.
+ *
+ * @return the live list of type arguments
+ * (element type: {@link Type})
+ */
+ public List typeArguments() {
+ return this.typeArguments;
+ }
+
+ /**
+ * Returns the name of the method referenced in this expression.
+ *
+ * @return the method name node
+ */
+ public SimpleName getName() {
+ if (this.methodName == null) {
+ // lazy init must be thread-safe for readers
+ synchronized (this) {
+ if (this.methodName == null) {
+ preLazyInit();
+ this.methodName = new SimpleName(this.ast);
+ postLazyInit(this.methodName, NAME_PROPERTY);
+ }
+ }
+ }
+ return this.methodName;
+ }
+
+ /**
+ * Sets the name of the method referenced in this expression to the
+ * given name.
+ *
+ * @param name the new method name
+ * @exception IllegalArgumentException if:
+ * <ul>
+ * <li>the node belongs to a different AST</li>
+ * <li>the node already has a parent</li>
+ * </ul>
+ */
+ public void setName(SimpleName name) {
+ if (name == null) {
+ throw new IllegalArgumentException();
+ }
+ ASTNode oldChild = this.methodName;
+ preReplaceChild(oldChild, name, NAME_PROPERTY);
+ this.methodName = name;
+ postReplaceChild(oldChild, name, NAME_PROPERTY);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ int memSize() {
+ // treat Code as free
+ return BASE_NODE_SIZE + 3 * 4;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ int treeSize() {
+ return
+ memSize()
+ + (this.optionalQualifier == null ? 0 : getQualifier().treeSize())
+ + (this.typeArguments == null ? 0 : this.typeArguments.listSize())
+ + (this.methodName == null ? 0 : getName().treeSize());
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeMethodReference.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeMethodReference.java
new file mode 100644
index 0000000000..25158e528d
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeMethodReference.java
@@ -0,0 +1,311 @@
+/*******************************************************************************
+ * Copyright (c) 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.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type method reference expression AST node type (added in JLS8 API).
+ * <pre>
+ * TypeMethodReference:
+ * Type <b>::</b>
+ * [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ * Identifier
+ * </pre>
+ *
+ * @since 3.9 BETA_JAVA8
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class TypeMethodReference extends MethodReference {
+
+ /**
+ * The "type" structural property of this node type (child type: {@link Type}).
+ */
+ public static final ChildPropertyDescriptor TYPE_PROPERTY =
+ new ChildPropertyDescriptor(TypeMethodReference.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+ /**
+ * The "typeArguments" structural property of this node type (element type: {@link Type})
+ */
+ public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+ internalTypeArgumentsFactory(TypeMethodReference.class);
+
+ /**
+ * The "name" structural property of this node type (child type: {@link SimpleName}.
+ */
+ public static final ChildPropertyDescriptor NAME_PROPERTY =
+ new ChildPropertyDescriptor(TypeMethodReference.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+ /**
+ * A list of property descriptors (element type:
+ * {@link StructuralPropertyDescriptor}),
+ * or null if uninitialized.
+ */
+ private static final List PROPERTY_DESCRIPTORS_8_0;
+
+ static {
+ List propertyList = new ArrayList(4);
+ createPropertyList(TypeMethodReference.class, propertyList);
+ addProperty(TYPE_PROPERTY, propertyList);
+ addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
+ addProperty(NAME_PROPERTY, propertyList);
+ PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+ }
+
+ /**
+ * Returns a list of structural property descriptors for this node type.
+ * Clients must not modify the result.
+ *
+ * @param apiLevel the API level; one of the AST.JLS* constants
+ * @return a list of property descriptors (element type:
+ * {@link StructuralPropertyDescriptor})
+ */
+ public static List propertyDescriptors(int apiLevel) {
+ return PROPERTY_DESCRIPTORS_8_0;
+ }
+
+ /**
+ * The type; defaults to null.
+ */
+ private Type type = null;
+
+ /**
+ * The method name; lazily initialized; defaults to an unspecified,
+ * legal Java method name.
+ */
+ private SimpleName methodName = null;
+
+ /**
+ * Creates a new AST node for an TypeMethodReference declaration owned
+ * by the given AST.
+ * <p>
+ * N.B. This constructor is package-private; all subclasses must be
+ * declared in the same package; clients are unable to declare
+ * additional subclasses.
+ * </p>
+ *
+ * @param ast the AST that is to own this node
+ */
+ TypeMethodReference(AST ast) {
+ super(ast);
+ unsupportedIn2_3_4();
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on MethodReference.
+ */
+ final ChildListPropertyDescriptor internalTypeArgumentsProperty() {
+ return TYPE_ARGUMENTS_PROPERTY;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final List internalStructuralPropertiesForType(int apiLevel) {
+ return propertyDescriptors(apiLevel);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+ if (property == NAME_PROPERTY) {
+ if (get) {
+ return getName();
+ } else {
+ setName((SimpleName) child);
+ return null;
+ }
+ }
+ if (property == TYPE_PROPERTY) {
+ if (get) {
+ return getType();
+ } else {
+ setType((Type) child);
+ return null;
+ }
+ }
+ // allow default implementation to flag the error
+ return super.internalGetSetChildProperty(property, get, child);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+ if (property == TYPE_ARGUMENTS_PROPERTY) {
+ return typeArguments();
+ }
+ // allow default implementation to flag the error
+ return super.internalGetChildListProperty(property);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final int getNodeType0() {
+ return TYPE_METHOD_REFERENCE;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ ASTNode clone0(AST target) {
+ TypeMethodReference result = new TypeMethodReference(target);
+ result.setSourceRange(getStartPosition(), getLength());
+ result.setName((SimpleName) getName().clone(target));
+ result.setType(
+ (Type) ASTNode.copySubtree(target, getType()));
+ result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
+ return result;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+ // dispatch to correct overloaded match method
+ return matcher.match(this, other);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ void accept0(ASTVisitor visitor) {
+ boolean visitChildren = visitor.visit(this);
+ if (visitChildren) {
+ // visit children in normal left to right reading order
+ acceptChild(visitor, getType());
+ acceptChildren(visitor, this.typeArguments);
+ acceptChild(visitor, getName());
+ }
+ visitor.endVisit(this);
+ }
+
+ /**
+ * Returns the type of this type method reference expression
+ *
+ * @return the type node
+ */
+ public Type getType() {
+ return this.type;
+ }
+
+ /**
+ * Sets the type of this type method reference.
+ *
+ * @param type type of this method reference
+ * @exception IllegalArgumentException if:
+ * <ul>
+ * <li>the node belongs to a different AST</li>
+ * <li>the node already has a parent</li>
+ * <li>a cycle in would be created</li>
+ * </ul>
+ */
+ public void setType(Type type) {
+ if (type == null) {
+ throw new IllegalArgumentException();
+ }
+ ASTNode oldChild = this.type;
+ preReplaceChild(oldChild, type, TYPE_PROPERTY);
+ this.type = type;
+ postReplaceChild(oldChild, type, TYPE_PROPERTY);
+ }
+
+ /**
+ * Returns the live ordered list of type arguments of this type method reference
+ *
+ * @return the live list of type arguments
+ * (element type: {@link Type})
+ */
+ public List typeArguments() {
+ return this.typeArguments;
+ }
+
+ /**
+ * Returns the name of the method referenced in this expression.
+ *
+ * @return the method name node
+ */
+ public SimpleName getName() {
+ if (this.methodName == null) {
+ // lazy init must be thread-safe for readers
+ synchronized (this) {
+ if (this.methodName == null) {
+ preLazyInit();
+ this.methodName = new SimpleName(this.ast);
+ postLazyInit(this.methodName, NAME_PROPERTY);
+ }
+ }
+ }
+ return this.methodName;
+ }
+
+ /**
+ * Sets the name of the method referenced in this expression to the
+ * given name.
+ *
+ * @param name the new method name
+ * @exception IllegalArgumentException if:
+ * <ul>
+ * <li>the node belongs to a different AST</li>
+ * <li>the node already has a parent</li>
+ * </ul>
+ */
+ public void setName(SimpleName name) {
+ if (name == null) {
+ throw new IllegalArgumentException();
+ }
+ ASTNode oldChild = this.methodName;
+ preReplaceChild(oldChild, name, NAME_PROPERTY);
+ this.methodName = name;
+ postReplaceChild(oldChild, name, NAME_PROPERTY);
+ }
+
+ /**
+ * Resolves and returns the binding for the method referenced by this
+ * expression.
+ * <p>
+ * Note that bindings are generally unavailable unless requested when the
+ * AST is being built.
+ * </p>
+ *
+ * @return the method binding, or <code>null</code> if the binding cannot
+ * be resolved
+ */
+ public IMethodBinding resolveMethodBinding() {
+ return this.ast.getBindingResolver().resolveMethod(this);
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ int memSize() {
+ // treat Code as free
+ return BASE_NODE_SIZE + 3 * 4;
+ }
+
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
+ int treeSize() {
+ return
+ memSize()
+ + (this.type == null ? 0 : getType().treeSize())
+ + (this.typeArguments == null ? 0 : this.typeArguments.listSize())
+ + (this.methodName == null ? 0 : getName().treeSize());
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
index ecd82da382..cf0563c941 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
@@ -202,6 +202,27 @@ public class NaiveASTFlattener extends ASTVisitor {
}
}
+ /**
+ * reference node helper function that is common to all
+ * the difference reference nodes.
+ *
+ * @param typeArguments list of type arguments
+ */
+ private void visitReferenceTypeArguments(List typeArguments) {
+ this.buffer.append("::");//$NON-NLS-1$
+ if (!typeArguments.isEmpty()) {
+ this.buffer.append('<');
+ for (Iterator it = typeArguments.iterator(); it.hasNext(); ) {
+ Type t = (Type) it.next();
+ t.accept(this);
+ if (it.hasNext()) {
+ this.buffer.append(',');
+ }
+ }
+ this.buffer.append('>');
+ }
+ }
+
private void visitTypeAnnotations(AnnotatableType node) {
if (node.getAST().apiLevel() >= AST.JLS8) {
visitAnnotationsList(node.annotations());
@@ -578,6 +599,18 @@ public class NaiveASTFlattener extends ASTVisitor {
}
/*
+ * @see ASTVisitor#visit(CreationReference)
+ *
+ * @since 3.9 BETA_JAVA8
+ */
+ public boolean visit(CreationReference node) {
+ node.getExpression().accept(this);
+ visitReferenceTypeArguments(node.typeArguments());
+ this.buffer.append("new");//$NON-NLS-1$
+ return false;
+ }
+
+ /*
* @see ASTVisitor#visit(DoStatement)
*/
public boolean visit(DoStatement node) {
@@ -689,6 +722,18 @@ public class NaiveASTFlattener extends ASTVisitor {
}
/*
+ * @see ASTVisitor#visit(ExpressionMethodReference)
+ *
+ * @since 3.9 BETA_JAVA8
+ */
+ public boolean visit(ExpressionMethodReference node) {
+ node.getExpression().accept(this);
+ visitReferenceTypeArguments(node.typeArguments());
+ node.getName().accept(this);
+ return false;
+ }
+
+ /*
* @see ASTVisitor#visit(ExpressionStatement)
*/
public boolean visit(ExpressionStatement node) {
@@ -1479,6 +1524,22 @@ public class NaiveASTFlattener extends ASTVisitor {
}
/*
+ * @see ASTVisitor#visit(SuperMethodReference)
+ *
+ * @since 3.9 BETA_JAVA8
+ */
+ public boolean visit(SuperMethodReference node) {
+ if (node.getQualifier() != null) {
+ node.getQualifier().accept(this);
+ this.buffer.append('.');
+ }
+ this.buffer.append("super");//$NON-NLS-1$
+ visitReferenceTypeArguments(node.typeArguments());
+ node.getName().accept(this);
+ return false;
+ }
+
+ /*
* @see ASTVisitor#visit(SwitchCase)
*/
public boolean visit(SwitchCase node) {
@@ -1735,6 +1796,18 @@ public class NaiveASTFlattener extends ASTVisitor {
}
/*
+ * @see ASTVisitor#visit(TypeMethodReference)
+ *
+ * @since 3.9 BETA_JAVA8
+ */
+ public boolean visit(TypeMethodReference node) {
+ node.getType().accept(this);
+ visitReferenceTypeArguments(node.typeArguments());
+ node.getName().accept(this);
+ return false;
+ }
+
+ /*
* @see ASTVisitor#visit(TypeParameter)
* @since 3.1
*/

Back to the top