Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2013-12-25 21:23:58 +0000
committerStephan Herrmann2013-12-25 21:23:58 +0000
commitc8a7ab78ecfe1bc5f533155d1bcd9817c668625b (patch)
tree883e1d65139bc0458094dd2203295e8efb1a4358
parent7d92c905003ad994c9d0795ed2a253d0f9258b7b (diff)
downloadorg.eclipse.objectteams-c8a7ab78ecfe1bc5f533155d1bcd9817c668625b.tar.gz
org.eclipse.objectteams-c8a7ab78ecfe1bc5f533155d1bcd9817c668625b.tar.xz
org.eclipse.objectteams-c8a7ab78ecfe1bc5f533155d1bcd9817c668625b.zip
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TypeAnnotationSyntaxTest.java188
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java44
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java22
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java128
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java2
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java4918
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java4
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java221
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java53
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java6
-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.java84
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java334
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTypeAnnotationsTest.java101
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java12
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java533
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java385
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java9
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java10
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java17
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java395
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationContext.java11
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationTargetTypeConstants.java69
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java47
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.java16
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MultiCatchExceptionLabel.java24
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/TypeAnnotationCodeStream.java97
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java10
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java56
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java130
-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.java72
-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/AnnotatableType.java2
-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.java241
-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.java61
-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.java307
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LambdaExpression.java6
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodReference.java116
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageQualifiedType.java4
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodReference.java294
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeMethodReference.java304
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java73
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java18
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotation.java75
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotationConstants.java67
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java12
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java471
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExtendedAnnotation.java294
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java17
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties19
55 files changed, 7614 insertions, 3053 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TypeAnnotationSyntaxTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TypeAnnotationSyntaxTest.java
index c1a881ac8..8be878942 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TypeAnnotationSyntaxTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TypeAnnotationSyntaxTest.java
@@ -11,6 +11,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.parser;
@@ -108,19 +110,19 @@ public class TypeAnnotationSyntaxTest extends AbstractSyntaxTreeTest {
}
public boolean visit(MarkerAnnotation annotation, BlockScope scope) {
if (this.enclosingReference != null) {
- storeLocations(annotation, Annotation.getLocations(this.enclosingReference, this.primaryAnnotations, annotation, null));
+ storeLocations(annotation, Annotation.getLocations(this.enclosingReference, this.primaryAnnotations, annotation, null, 0));
}
return false;
}
public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) {
if (this.enclosingReference != null) {
- storeLocations(annotation, Annotation.getLocations(this.enclosingReference, this.primaryAnnotations, annotation, null));
+ storeLocations(annotation, Annotation.getLocations(this.enclosingReference, this.primaryAnnotations, annotation, null, 0));
}
return false;
}
public boolean visit(NormalAnnotation annotation, BlockScope scope) {
if (this.enclosingReference != null) {
- storeLocations(annotation, Annotation.getLocations(this.enclosingReference, this.primaryAnnotations, annotation, null));
+ storeLocations(annotation, Annotation.getLocations(this.enclosingReference, this.primaryAnnotations, annotation, null, 0));
}
return false;
}
@@ -133,14 +135,28 @@ public class TypeAnnotationSyntaxTest extends AbstractSyntaxTreeTest {
this.locations.put(key, null);
return;
}
- StringBuffer buffer = new StringBuffer("{");
- for (int i = 0, max = tab.length; i < max; i++) {
+
+ StringBuffer buffer = new StringBuffer("[");
+ for (int i = 0, max = tab.length; i < max; i += 2) {
if (i > 0) {
- buffer.append(',');
+ buffer.append(", ");
+ }
+ switch (tab[i]) {
+ case 0:
+ buffer.append("ARRAY");
+ break;
+ case 1:
+ buffer.append("INNER_TYPE");
+ break;
+ case 2:
+ buffer.append("WILDCARD");
+ break;
+ case 3:
+ buffer.append("TYPE_ARGUMENT(").append(tab[i+1]).append(')');
+ break;
}
- buffer.append(tab[i]);
}
- buffer.append('}');
+ buffer.append(']');
this.locations.put(key, String.valueOf(buffer));
}
@@ -1656,9 +1672,9 @@ public void test0068() throws IOException {
Map locations = visitor.getLocations();
assertEquals("Wrong size", 4, locations.size());
assertEquals("Wrong location", null, locations.get("@E"));
- assertEquals("Wrong location", "{0}", locations.get("@F"));
- assertEquals("Wrong location", "{1}", locations.get("@G"));
- assertEquals("Wrong location", "{2}", locations.get("@H"));
+ assertEquals("Wrong location", "[ARRAY]", locations.get("@F"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY]", locations.get("@G"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY]", locations.get("@H"));
}
//check locations
public void test0069() throws IOException {
@@ -1678,8 +1694,8 @@ public void test0069() throws IOException {
Map locations = visitor.getLocations();
assertEquals("Wrong size", 3, locations.size());
assertEquals("Wrong location", null, locations.get("@A"));
- assertEquals("Wrong location", "{0}", locations.get("@B"));
- assertEquals("Wrong location", "{1}", locations.get("@H"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0)]", locations.get("@B"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1)]", locations.get("@H"));
}
//check locations
public void test0070() throws IOException {
@@ -1699,11 +1715,11 @@ public void test0070() throws IOException {
Map locations = visitor.getLocations();
assertEquals("Wrong size", 6, locations.size());
assertEquals("Wrong location", null, locations.get("@A"));
- assertEquals("Wrong location", "{0}", locations.get("@B"));
- assertEquals("Wrong location", "{1}", locations.get("@E"));
- assertEquals("Wrong location", "{1,0}", locations.get("@F"));
- assertEquals("Wrong location", "{1,1}", locations.get("@G"));
- assertEquals("Wrong location", "{1,2}", locations.get("@H"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0)]", locations.get("@B"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1)]", locations.get("@E"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1), ARRAY]", locations.get("@F"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1), ARRAY, ARRAY]", locations.get("@G"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1), ARRAY, ARRAY, ARRAY]", locations.get("@H"));
}
//check locations
public void test0071() throws IOException {
@@ -1723,11 +1739,11 @@ public void test0071() throws IOException {
Map locations = visitor.getLocations();
assertEquals("Wrong size", 6, locations.size());
assertEquals("Wrong location", null, locations.get("@A"));
- assertEquals("Wrong location", "{0}", locations.get("@B"));
- assertEquals("Wrong location", "{1}", locations.get("@C"));
- assertEquals("Wrong location", "{1,0,2}", locations.get("@H"));
- assertEquals("Wrong location", "{1,0}", locations.get("@E"));
- assertEquals("Wrong location", "{1,0,1}", locations.get("@G"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0)]", locations.get("@B"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1)]", locations.get("@C"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1), TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]", locations.get("@H"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1), TYPE_ARGUMENT(0)]", locations.get("@E"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1), TYPE_ARGUMENT(0), ARRAY, ARRAY]", locations.get("@G"));
}
//check locations
public void test0072() throws IOException {
@@ -1746,14 +1762,14 @@ public void test0072() throws IOException {
checkParse(CHECK_ALL & ~CHECK_JAVAC_PARSER, source.toCharArray(), null, "test0072", expectedUnitToString, visitor);
Map locations = visitor.getLocations();
assertEquals("Wrong size", 8, locations.size());
- assertEquals("Wrong location", "{0}", locations.get("@I"));
- assertEquals("Wrong location", "{1}", locations.get("@J"));
- assertEquals("Wrong location", "{2}", locations.get("@A"));
- assertEquals("Wrong location", "{2,0}", locations.get("@B"));
- assertEquals("Wrong location", "{2,1}", locations.get("@C"));
- assertEquals("Wrong location", "{2,1,0,2}", locations.get("@H"));
- assertEquals("Wrong location", "{2,1,0}", locations.get("@E"));
- assertEquals("Wrong location", "{2,1,0,1}", locations.get("@G"));
+ assertEquals("Wrong location", "[ARRAY]", locations.get("@I"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY]", locations.get("@J"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY]", locations.get("@A"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(0)]", locations.get("@B"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(1)]", locations.get("@C"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(1), TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]", locations.get("@H"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(1), TYPE_ARGUMENT(0)]", locations.get("@E"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(1), TYPE_ARGUMENT(0), ARRAY, ARRAY]", locations.get("@G"));
}
//check locations
public void test0073() throws IOException {
@@ -1773,13 +1789,13 @@ public void test0073() throws IOException {
Map locations = visitor.getLocations();
assertEquals("Wrong size", 8, locations.size());
assertEquals("Wrong location", null, locations.get("@I"));
- assertEquals("Wrong location", "{1}", locations.get("@J"));
- assertEquals("Wrong location", "{2}", locations.get("@A"));
- assertEquals("Wrong location", "{2,0}", locations.get("@B"));
- assertEquals("Wrong location", "{2,1}", locations.get("@C"));
- assertEquals("Wrong location", "{2,1,0,2}", locations.get("@H"));
- assertEquals("Wrong location", "{2,1,0}", locations.get("@E"));
- assertEquals("Wrong location", "{2,1,0,1}", locations.get("@G"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY]", locations.get("@J"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY]", locations.get("@A"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(0)]", locations.get("@B"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(1)]", locations.get("@C"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(1), TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]", locations.get("@H"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(1), TYPE_ARGUMENT(0)]", locations.get("@E"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(1), TYPE_ARGUMENT(0), ARRAY, ARRAY]", locations.get("@G"));
}
//check locations
public void test0074() throws IOException {
@@ -1799,15 +1815,15 @@ public void test0074() throws IOException {
Map locations = visitor.getLocations();
assertEquals("Wrong size", 10, locations.size());
assertEquals("Wrong location", null, locations.get("@I"));
- assertEquals("Wrong location", "{0}", locations.get("@F"));
- assertEquals("Wrong location", "{1}", locations.get("@J"));
- assertEquals("Wrong location", "{2}", locations.get("@A"));
- assertEquals("Wrong location", "{2,0}", locations.get("@C"));
- assertEquals("Wrong location", "{2,0,0}", locations.get("@E"));
- assertEquals("Wrong location", "{2,0,0,1}", locations.get("@G"));
- assertEquals("Wrong location", "{2,0,0,2}", locations.get("@H"));
- assertEquals("Wrong location", "{2,1,0}", locations.get("@D"));
- assertEquals("Wrong location", "{2,1}", locations.get("@B"));
+ assertEquals("Wrong location", "[ARRAY]", locations.get("@F"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY]", locations.get("@J"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY]", locations.get("@A"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(0)]", locations.get("@C"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(0), TYPE_ARGUMENT(0)]", locations.get("@E"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(0), TYPE_ARGUMENT(0), ARRAY, ARRAY]", locations.get("@G"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(0), TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]", locations.get("@H"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(1), ARRAY]", locations.get("@D"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(1)]", locations.get("@B"));
}
//check locations
public void test0075() throws IOException {
@@ -1826,16 +1842,16 @@ public void test0075() throws IOException {
checkParse(CHECK_ALL & ~CHECK_JAVAC_PARSER, source.toCharArray(), null, "test0075", expectedUnitToString, visitor);
Map locations = visitor.getLocations();
assertEquals("Wrong size", 10, locations.size());
- assertEquals("Wrong location", "{0}", locations.get("@I"));
- assertEquals("Wrong location", "{1}", locations.get("@F"));
- assertEquals("Wrong location", "{2}", locations.get("@J"));
- assertEquals("Wrong location", "{3}", locations.get("@A"));
- assertEquals("Wrong location", "{3,0}", locations.get("@C"));
- assertEquals("Wrong location", "{3,0,0}", locations.get("@E"));
- assertEquals("Wrong location", "{3,0,0,1}", locations.get("@G"));
- assertEquals("Wrong location", "{3,0,0,2}", locations.get("@H"));
- assertEquals("Wrong location", "{3,1}", locations.get("@B"));
- assertEquals("Wrong location", "{3,1,0,0}", locations.get("@D"));
+ assertEquals("Wrong location", "[ARRAY]", locations.get("@I"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY]", locations.get("@F"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY]", locations.get("@J"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, ARRAY]", locations.get("@A"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(0)]", locations.get("@C"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(0), TYPE_ARGUMENT(0)]", locations.get("@E"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(0), TYPE_ARGUMENT(0), ARRAY, ARRAY]", locations.get("@G"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(0), TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]", locations.get("@H"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(1)]", locations.get("@B"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(1), TYPE_ARGUMENT(0), ARRAY]", locations.get("@D"));
}
//check locations
public void test0076() throws IOException {
@@ -1855,9 +1871,9 @@ public void test0076() throws IOException {
Map locations = visitor.getLocations();
assertEquals("Wrong size", 4, locations.size());
assertEquals("Wrong location", null, locations.get("@A"));
- assertEquals("Wrong location", "{0}", locations.get("@B"));
- assertEquals("Wrong location", "{1}", locations.get("@C"));
- assertEquals("Wrong location", "{1,0}", locations.get("@D"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0)]", locations.get("@B"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1)]", locations.get("@C"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1), TYPE_ARGUMENT(0)]", locations.get("@D"));
}
//check locations
public void test0077() throws IOException {
@@ -1877,9 +1893,9 @@ public void test0077() throws IOException {
Map locations = visitor.getLocations();
assertEquals("Wrong size", 4, locations.size());
assertEquals("Wrong location", null, locations.get("@E"));
- assertEquals("Wrong location", "{0}", locations.get("@F"));
- assertEquals("Wrong location", "{1}", locations.get("@G"));
- assertEquals("Wrong location", "{2}", locations.get("@H"));
+ assertEquals("Wrong location", "[ARRAY]", locations.get("@F"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY]", locations.get("@G"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY]", locations.get("@H"));
}
//check locations
public void test0078() throws IOException {
@@ -1899,13 +1915,13 @@ public void test0078() throws IOException {
Map locations = visitor.getLocations();
assertEquals("Wrong size", 8, locations.size());
assertEquals("Wrong location", null, locations.get("@A"));
- assertEquals("Wrong location", "{0}", locations.get("@B"));
- assertEquals("Wrong location", "{0,0,2}", locations.get("@C"));
- assertEquals("Wrong location", "{0,0}", locations.get("@D"));
- assertEquals("Wrong location", "{0,0,0}", locations.get("@E"));
- assertEquals("Wrong location", "{0,0,1}", locations.get("@F"));
- assertEquals("Wrong location", "{1}", locations.get("@G"));
- assertEquals("Wrong location", "{1,0}", locations.get("@H"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0)]", locations.get("@B"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0), TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]", locations.get("@C"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0), TYPE_ARGUMENT(0)]", locations.get("@D"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0), TYPE_ARGUMENT(0), ARRAY]", locations.get("@E"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0), TYPE_ARGUMENT(0), ARRAY, ARRAY]", locations.get("@F"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1)]", locations.get("@G"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1), TYPE_ARGUMENT(0)]", locations.get("@H"));
}
//check locations
public void test0079() throws IOException {
@@ -1925,13 +1941,13 @@ public void test0079() throws IOException {
Map locations = visitor.getLocations();
assertEquals("Wrong size", 8, locations.size());
assertEquals("Wrong location", null, locations.get("@A"));
- assertEquals("Wrong location", "{0}", locations.get("@B"));
- assertEquals("Wrong location", "{0,0,2}", locations.get("@C"));
- assertEquals("Wrong location", "{0,0}", locations.get("@D"));
- assertEquals("Wrong location", "{0,0,0}", locations.get("@E"));
- assertEquals("Wrong location", "{0,0,1}", locations.get("@F"));
- assertEquals("Wrong location", "{1}", locations.get("@G"));
- assertEquals("Wrong location", "{1,0}", locations.get("@H"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0)]", locations.get("@B"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0), TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]", locations.get("@C"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0), TYPE_ARGUMENT(0)]", locations.get("@D"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0), TYPE_ARGUMENT(0), ARRAY]", locations.get("@E"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0), TYPE_ARGUMENT(0), ARRAY, ARRAY]", locations.get("@F"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1)]", locations.get("@G"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1), TYPE_ARGUMENT(0)]", locations.get("@H"));
}
//check locations
public void test0080() throws IOException {
@@ -1951,7 +1967,7 @@ public void test0080() throws IOException {
Map locations = visitor.getLocations();
assertEquals("Wrong size", 2, locations.size());
assertEquals("Wrong location", null, locations.get("@B"));
- assertEquals("Wrong location", "{1}", locations.get("@A"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1), WILDCARD]", locations.get("@A"));
}
//check locations
public void test0081() throws IOException {
@@ -1971,9 +1987,9 @@ public void test0081() throws IOException {
Map locations = visitor.getLocations();
assertEquals("Wrong size", 4, locations.size());
assertEquals("Wrong location", null, locations.get("@E"));
- assertEquals("Wrong location", "{0}", locations.get("@F"));
- assertEquals("Wrong location", "{1}", locations.get("@G"));
- assertEquals("Wrong location", "{2}", locations.get("@H"));
+ assertEquals("Wrong location", "[ARRAY]", locations.get("@F"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY]", locations.get("@G"));
+ assertEquals("Wrong location", "[ARRAY, ARRAY, ARRAY]", locations.get("@H"));
}
//check locations
public void test0082() throws IOException {
@@ -1993,11 +2009,11 @@ public void test0082() throws IOException {
Map locations = visitor.getLocations();
assertEquals("Wrong size", 6, locations.size());
assertEquals("Wrong location", null, locations.get("@A"));
- assertEquals("Wrong location", "{0}", locations.get("@B"));
- assertEquals("Wrong location", "{1}", locations.get("@E"));
- assertEquals("Wrong location", "{1,0}", locations.get("@F"));
- assertEquals("Wrong location", "{1,1}", locations.get("@G"));
- assertEquals("Wrong location", "{1,2}", locations.get("@H"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(0)]", locations.get("@B"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1)]", locations.get("@E"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1), ARRAY]", locations.get("@F"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1), ARRAY, ARRAY]", locations.get("@G"));
+ assertEquals("Wrong location", "[TYPE_ARGUMENT(1), ARRAY, ARRAY, ARRAY]", locations.get("@H"));
}
public void test0083() throws IOException {
String source =
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
index ab9d9612c..2d9ee7fb4 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
@@ -98,27 +98,27 @@ public abstract class AbstractRegressionTest extends AbstractCompilerTest implem
if (IS_JRE_8) { // TODO(stephan) accommodate future versions ...
COMPARATOR_IMPL_JRE8 = // replace '*' with T, '%' with U, $ with S
" public java.util.Comparator<*> reverseOrder() { return null;}\n" +
- " public <% extends *> java.util.Comparator<%> thenComparing(java.util.Comparator<? super *> other) { return null;}\n" +
- " public <$ extends *, % extends java.lang.Comparable<? super %>> java.util.Comparator<$> thenComparing(java.util.function.Function<? super *, ? extends %> keyExtractor) { return null;}\n" +
- " public <$ extends *, %> java.util.Comparator<$> thenComparing(java.util.function.Function<? super *, ? extends %> keyExtractor, java.util.Comparator<? super %> cmp) { return null; }\n" +
- " public <% extends *> java.util.Comparator<%> thenComparing(java.util.function.ToIntFunction<? super *> keyExtractor) { return null;}\n" +
- " public <% extends *> java.util.Comparator<%> thenComparing(java.util.function.ToLongFunction<? super *> keyExtractor) { return null;}\n" +
- " public <% extends *> java.util.Comparator<%> thenComparing(java.util.function.ToDoubleFunction<? super *> keyExtractor) { return null;}\n";
+ " public java.util.Comparator<*> thenComparing(java.util.Comparator<? super *> other) { return null;}\n" +
+ " public <% extends java.lang.Comparable<? super %>> java.util.Comparator<*> thenComparing(java.util.function.Function<? super *, ? extends %> keyExtractor) { return null;}\n" +
+ " public java.util.Comparator<*> thenComparing(java.util.function.ToIntFunction<? super *> keyExtractor) { return null;}\n" +
+ " public java.util.Comparator<*> thenComparing(java.util.function.ToLongFunction<? super *> keyExtractor) { return null;}\n" +
+ " public java.util.Comparator<*> thenComparing(java.util.function.ToDoubleFunction<? super *> keyExtractor) { return null;}\n";
COMPARATOR_RAW_IMPL_JRE8 =
- " public java.util.Comparator reverseOrder() { return null;}\n" +
- " public java.util.Comparator thenComparing(java.util.Comparator other) { return null;}\n" +
- " public java.util.Comparator thenComparing(java.util.function.Function keyExtractor) { return null;}\n" +
- " public java.util.Comparator thenComparing(java.util.function.Function keyExtractor, java.util.Comparator comparator) { return null;}\n" +
- " public java.util.Comparator thenComparing(java.util.function.ToIntFunction keyExtractor) { return null;}\n" +
- " public java.util.Comparator thenComparing(java.util.function.ToLongFunction keyExtractor) { return null;}\n" +
- " public java.util.Comparator thenComparing(java.util.function.ToDoubleFunction keyExtractor) { return null;}\n";
+ " public java.util.Comparator reverseOrder() { return null;}\n" +
+ " public java.util.Comparator thenComparing(java.util.Comparator other) { return null;}\n" +
+ " public java.util.Comparator thenComparing(java.util.function.Function keyExtractor) { return null;}\n" +
+ " public java.util.Comparator thenComparing(java.util.function.ToIntFunction keyExtractor) { return null;}\n" +
+ " public java.util.Comparator thenComparing(java.util.function.ToLongFunction keyExtractor) { return null;}\n" +
+ " public java.util.Comparator thenComparing(java.util.function.ToDoubleFunction keyExtractor) { return null;}\n" ;
COLLECTION_IMPL_JRE8 =
" public boolean removeAll(java.util.function.Predicate<? super *> filter) { return false;}\n" +
+ " public boolean removeIf(java.util.function.Predicate<? super *> filter) { return false;}\n" +
" public java.util.stream.Stream<*> stream() { return null;}\n" +
" public java.util.stream.Stream<*> parallelStream() { return null;}\n" +
" public java.util.Spliterator<*> spliterator() { return null; }\n";
COLLECTION_AND_LIST_IMPL_JRE8 =
" public boolean removeAll(java.util.function.Predicate<? super *> filter) { return false;}\n" +
+ " public boolean removeIf(java.util.function.Predicate<? super *> filter) { return false;}\n" +
" public java.util.stream.Stream<*> stream() { return null;}\n" +
" public java.util.stream.Stream<*> parallelStream() { return null;}\n" +
" public java.util.Spliterator<*> spliterator() { return null; }\n" +
@@ -127,6 +127,7 @@ public abstract class AbstractRegressionTest extends AbstractCompilerTest implem
" public void replaceAll(java.util.function.UnaryOperator<*> operator) {}\n";
COLLECTION_RAW_IMPL_JRE8 =
" public @SuppressWarnings(\"rawtypes\") boolean removeAll(java.util.function.Predicate filter) { return false;}\n" +
+ " public @SuppressWarnings(\"rawtypes\") boolean removeIf(java.util.function.Predicate filter) { return false;}\n" +
" public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream stream() { return null;}\n" +
" public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream parallelStream() { return null;}\n" +
" public @SuppressWarnings(\"rawtypes\") java.util.Spliterator spliterator() { return null; }\n";
@@ -142,6 +143,7 @@ public abstract class AbstractRegressionTest extends AbstractCompilerTest implem
" public @SuppressWarnings(\"rawtypes\") java.util.Spliterator spliterator() { return null; }\n";
COLLECTION_AND_LIST_RAW_IMPL_JRE8 =
" public @SuppressWarnings(\"rawtypes\") boolean removeAll(java.util.function.Predicate filter) { return false;}\n" +
+ " public @SuppressWarnings(\"rawtypes\") boolean removeIf(java.util.function.Predicate filter) { return false;}\n" +
" public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream stream() { return null;}\n" +
" public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream parallelStream() { return null;}\n" +
" public @SuppressWarnings(\"rawtypes\") java.util.Spliterator spliterator() { return null; }\n" +
@@ -149,17 +151,22 @@ public abstract class AbstractRegressionTest extends AbstractCompilerTest implem
" public @SuppressWarnings(\"rawtypes\") void parallelSort(java.util.Comparator comparator) {}\n" +
" public @SuppressWarnings(\"rawtypes\") void replaceAll(java.util.function.UnaryOperator operator) {}\n";
ITERABLE_IMPL_JRE8 = // replace '*' with your concrete type argument
- " public void forEach(java.util.function.Consumer<? super *> block){}\n";
+ " public void forEach(java.util.function.Consumer<? super *> block){}\n" +
+ " public void forEachRemaining(java.util.function.Consumer<? super *> action) {}\n";
ITERABLE_RAW_IMPL_JRE8 =
- " public @SuppressWarnings(\"rawtypes\") void forEach(java.util.function.Consumer action) {}\n";
+ " public @SuppressWarnings(\"rawtypes\") void forEach(java.util.function.Consumer action) {}\n" +
+ " public @SuppressWarnings(\"rawtypes\") void forEachRemaining(java.util.function.Consumer action) {}\n";
ITERATOR_IMPL_JRE8 = // replace '*' with your concrete type argument
- "public void forEach(java.util.function.Consumer<? super *> action) {}\n";
+ "public void forEach(java.util.function.Consumer<? super *> action) {}\n" +
+ "public void forEachRemaining(java.util.function.Consumer<? super *> action) {}\n";
ITERATOR_RAW_IMPL_JRE8 =
- " public void forEach(java.util.function.Consumer block){}\n";
+ " public @SuppressWarnings(\"rawtypes\") void forEach(java.util.function.Consumer block){}\n" +
+ " public @SuppressWarnings(\"rawtypes\") void forEachRemaining(java.util.function.Consumer action) {}\n";
MAP_IMPL_JRE8 = // '*' for 'K', '%' for 'V'
" public boolean remove(Object key, Object value) { return false;}\n" +
+ " public % getOrDefault(Object key, % defaultValue) {return defaultValue;}\n" +
" public void forEach(java.util.function.BiConsumer<? super *, ? super %> block) {}\n" +
- " public void replaceAll(java.util.function.BiFunction<*, %, %> function) {}\n" +
+ " public void replaceAll(java.util.function.BiFunction<? super *, ? super %, ? extends %> function) {}\n" +
" public % putIfAbsent(* key, % value) { return null;}\n" +
" public boolean replace(* key, % oldValue, % newValue) { return false;}\n" +
" public % replace(* key, % value) { return null;}\n" +
@@ -169,6 +176,7 @@ public abstract class AbstractRegressionTest extends AbstractCompilerTest implem
" public % merge(* key, % value, java.util.function.BiFunction<? super %, ? super %, ? extends %> remappingFunction) { return null;}\n";
MAP_RAW_IMPL_JRE8 =
" public boolean remove(Object key, Object value) { return false;}\n" +
+ " public @SuppressWarnings(\"rawtypes\") Object getOrDefault(Object key, Object defaultValue) {return defaultValue;}\n" +
" public @SuppressWarnings(\"rawtypes\") void forEach(java.util.function.BiConsumer block) {}\n" +
" public @SuppressWarnings(\"rawtypes\") void replaceAll(java.util.function.BiFunction function) {}\n" +
" public Object putIfAbsent(Object key, Object value) { return null;}\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
index c33479251..333757963 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
@@ -24937,7 +24937,7 @@ public void test0779() throws Exception {
},
"SUCCESS");
- String constantPoolIdx = IS_JRE_8 ? "70" : "36"; // depends on whether or not stubs for JRE8 default methods are included
+ String constantPoolIdx = IS_JRE_8 ? "73" : "36"; // depends on whether or not stubs for JRE8 default methods are included
String expectedOutput =
" // Method descriptor #31 (I)Ljava/lang/Object;\n" +
" // Stack: 2, Locals: 2\n" +
@@ -25923,27 +25923,27 @@ public void test0809() {
"}\n",
},
"----------\n" +
- "1. WARNING in X.java (at line 22)\n" +
+ "1. WARNING in X.java (at line 23)\n" +
" void f1(Set1 s) {\n" +
" ^^^^\n" +
"Set1 is a raw type. References to generic type Set1<N> should be parameterized\n" +
"----------\n" +
- "2. ERROR in X.java (at line 23)\n" +
+ "2. ERROR in X.java (at line 24)\n" +
" Node n_ = s.iterator().next();\n" +
" ^^^^^^^^^^^^^^^^^^^\n" +
"Type mismatch: cannot convert from Object to Node\n" +
"----------\n" +
- "3. ERROR in X.java (at line 26)\n" +
+ "3. ERROR in X.java (at line 27)\n" +
" for (Node n : s) {\n" +
" ^\n" +
"Type mismatch: cannot convert from element type Object to Node\n" +
"----------\n" +
- "4. WARNING in X.java (at line 36)\n" +
+ "4. WARNING in X.java (at line 37)\n" +
" void f3(Set3 s) {\n" +
" ^^^^\n" +
"Set3 is a raw type. References to generic type Set3<N> should be parameterized\n" +
"----------\n" +
- "5. ERROR in X.java (at line 39)\n" +
+ "5. ERROR in X.java (at line 40)\n" +
" for (Node n : s) {\n" +
" ^\n" +
"Type mismatch: cannot convert from element type Object to Node\n" +
@@ -32588,7 +32588,7 @@ public void test0988() {
" public ISheetViewer getViewer();\n" +
"}", // =================
},
- "----------\n" +
+ "----------\n" +
"1. ERROR in X.java (at line 11)\n" +
" public SheetViewer getViewer() { return null; } \n" +
" ^^^^^^^^^^^\n" +
@@ -48376,12 +48376,6 @@ public void test1403() throws Exception {
"2. ERROR in A.java (at line 3)\n" +
" Class<?> c = A<?>.class; \n" +
" ^^^\n" +
- "Syntax error on token(s), misplaced construct(s)\n" +
- "----------\n" +
- "3. ERROR in A.java (at line 3)\n" +
- " Class<?> c = A<?>.class; \n" +
- " ^^^^^\n" +
- "Syntax error, insert \")\" to complete Expression\n" +
:giro */
" ^\n" +
"Syntax error on token \"?\", invalid typeAnchor\n" +
@@ -49784,7 +49778,7 @@ public void test1444() {
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Unnecessary cast from Iterator to Iterator<String>\n" +
"----------\n" +
- "6. ERROR in X.java (at line 37)\n" +
+ "6. ERROR in X.java (at line 38)\n" +
" Zork z;\n" +
" ^^^^\n" +
"Zork cannot be resolved to a type\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
index d00f07a15..0b00f6203 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
@@ -6534,6 +6534,134 @@ public void test406773() {
compilerOptions /* custom options */
);
}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=406859, [1.8][compiler] Bad hint that method could be declared static
+public void test406859a() {
+ Map compilerOptions = getCompilerOptions();
+ compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBeStatic, CompilerOptions.ERROR);
+ compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " int foo(int i);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " X x = new X();\n" +
+ " I i = x::foo;\n" +
+ " i.foo(3);\n" +
+ " }\n" +
+ " int foo(int x) {\n" +
+ " return x;\n" +
+ " } \n" +
+ "}\n"
+ },
+ "",
+ null /* no extra class libraries */,
+ true /* flush output directory */,
+ compilerOptions /* custom options */
+ );
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=406859, [1.8][compiler] Bad hint that method could be declared static
+public void test406859b() {
+ Map compilerOptions = getCompilerOptions();
+ compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBeStatic, CompilerOptions.ERROR);
+ compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " void doit (Y y);\n" +
+ "}\n" +
+ "\n" +
+ "class Y {\n" +
+ " void foo() {\n" +
+ " return;\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " I i = Y::foo; \n" +
+ " Y y = new Y();\n" +
+ " i.doit(y);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "",
+ null /* no extra class libraries */,
+ true /* flush output directory */,
+ compilerOptions /* custom options */
+ );
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=406859, [1.8][compiler] Bad hint that method could be declared static
+public void test406859c() {
+ Map compilerOptions = getCompilerOptions();
+ compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBeStatic, CompilerOptions.ERROR);
+ compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " void doit ();\n" +
+ "}\n" +
+ "\n" +
+ "class Y {\n" +
+ " void foo() { \n" +
+ " return;\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " I i = new Y()::foo;\n" +
+ " i.doit();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "",
+ null /* no extra class libraries */,
+ true /* flush output directory */,
+ compilerOptions /* custom options */
+ );
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=406859, [1.8][compiler] Bad hint that method could be declared static
+// A case where we can't help but report the wrong hint due to separate compilation.
+public void test406859d() {
+ Map compilerOptions = getCompilerOptions();
+ compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBeStatic, CompilerOptions.ERROR);
+ compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, CompilerOptions.WARNING);
+ this.runNegativeTest(
+ new String[] {
+ "Y.java",
+ "public class Y {\n" +
+ " void foo() {\n" +
+ " return;\n" +
+ " }\n" +
+ "}",
+ "X.java",
+ "interface I {\n" +
+ " void doit ();\n" +
+ "}\n" +
+ "\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " I i = new Y()::foo;\n" +
+ " i.doit();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in Y.java (at line 2)\n" +
+ " void foo() {\n" +
+ " ^^^^^\n" +
+ "The method foo() from the type Y can potentially be declared as static\n" +
+ "----------\n",
+ null /* no extra class libraries */,
+ true /* flush output directory */,
+ compilerOptions /* custom options */
+ );
+}
public static Class testClass() {
return NegativeLambdaExpressionsTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java
index 9e42561fa..d963925b7 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java
@@ -42,7 +42,7 @@ protected Map getCompilerOptions() {
Map compilerOptions = super.getCompilerOptions();
compilerOptions.put(CompilerOptions.OPTION_ShareCommonFinallyBlocks, CompilerOptions.ENABLED);
return compilerOptions;
-};
+}
public void test001() {
this.runConformTest(new String[] {
"p/X.java",
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java
index 0443b26f0..ccb9fde6a 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 IBM Corporation and others.
+ * Copyright (c) 2011, 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
@@ -11,12 +11,15 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
import java.io.File;
-
+import java.util.Map;
import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import junit.framework.Test;
@@ -34,457 +37,208 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
public TypeAnnotationTest(String testName){
super(testName);
}
-// // superclass
-// public void test001() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "Marker.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@interface Marker {}",
-// "X.java",
-// "public class X extends @Marker Object {}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #17 @Marker(\n" +
-// " target type = 0x14 CLASS_EXTENDS_IMPLEMENTS\n" +
-// " type index = -1\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
-// // type parameter
-// public void test002() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "Marker.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "@Target(TYPE_PARAMETER)\n" +
-// "@interface Marker {}",
-// "X.java",
-// "public class X<@Marker T> {}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #21 @Marker(\n" +
-// " target type = 0x22 CLASS_TYPE_PARAMETER\n" +
-// " type parameter index = 0\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
-// // superclass
-// public void test003() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "A.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface A {\n" +
-// " String id() default \"default\";\n" +
-// "}\n",
-// "B.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(CLASS)\n" +
-// "@interface B {\n" +
-// " int value() default -1;\n" +
-// "}",
-// "C.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface C {\n" +
-// " char value() default '-';\n" +
-// "}\n",
-// "Y.java",
-// "class Y {}\n",
-// "X.java",
-// "public class X extends @A(id=\"Hello, World!\") @B @C('(') Y {\n" +
-// "}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeVisibleTypeAnnotations: \n" +
-// " #19 @A(\n" +
-// " #20 id=\"Hello, World!\" (constant type)\n" +
-// " target type = 0x14 CLASS_EXTENDS_IMPLEMENTS\n" +
-// " type index = -1\n" +
-// " )\n" +
-// " #22 @C(\n" +
-// " #23 value=\'(\' (constant type)\n" +
-// " target type = 0x14 CLASS_EXTENDS_IMPLEMENTS\n" +
-// " type index = -1\n" +
-// " )\n" +
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #17 @B(\n" +
-// " target type = 0x14 CLASS_EXTENDS_IMPLEMENTS\n" +
-// " type index = -1\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
-// // super interfaces
-// public void test004() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "A.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface A {\n" +
-// " String id() default \"default\";\n" +
-// "}\n",
-// "B.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(CLASS)\n" +
-// "@interface B {\n" +
-// " int value() default -1;\n" +
-// "}",
-// "C.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface C {\n" +
-// " char value() default '-';\n" +
-// "}\n",
-// "I.java",
-// "interface I {}\n",
-// "J.java",
-// "interface J {}\n",
-// "X.java",
-// "public class X implements @A(id=\"Hello, World!\") I, @B @C('(') J {}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeVisibleTypeAnnotations: \n" +
-// " #23 @A(\n" +
-// " #24 id=\"Hello, World!\" (constant type)\n" +
-// " target type = 0x14 CLASS_EXTENDS_IMPLEMENTS\n" +
-// " type index = 0\n" +
-// " )\n" +
-// " #26 @C(\n" +
-// " #27 value=\'(\' (constant type)\n" +
-// " target type = 0x14 CLASS_EXTENDS_IMPLEMENTS\n" +
-// " type index = 1\n" +
-// " )\n" +
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #21 @B(\n" +
-// " target type = 0x14 CLASS_EXTENDS_IMPLEMENTS\n" +
-// " type index = 1\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
-// // class literal
-// public void test005() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "A.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface A {\n" +
-// " String value() default \"default\";\n" +
-// "}\n",
-// "B.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(CLASS)\n" +
-// "@interface B {\n" +
-// " int value() default -1;\n" +
-// "}",
-// "C.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface C {\n" +
-// " char value() default '-';\n" +
-// "}\n",
-// "I.java",
-// "interface I {}\n",
-// "J.java",
-// "interface J {}\n",
-// "X.java",
-// "public class X {\n" +
-// " public boolean foo(String s) {\n" +
-// " boolean b = (s instanceof @C('_') Object);\n" +
-// " Object o = new @B(3) @A(\"new Object\") Object();\n" +
-// " Class<?> c = @B(4) Object.class;\n" +
-// " Class<?> c2 = @A(\"int class literal\") @B(5) int.class;\n" +
-// " System.out.println(o.toString() + c.toString() + c2.toString());\n" +
-// " return b;\n" +
-// " }\n" +
-// "}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeVisibleTypeAnnotations: \n" +
-// " #73 @C(\n" +
-// " #68 value=\'_\' (constant type)\n" +
-// " target type = 0x2 TYPE_INSTANCEOF\n" +
-// " offset = 1\n" +
-// " )\n" +
-// " #75 @A(\n" +
-// " #68 value=\"new Object\" (constant type)\n" +
-// " target type = 0x4 OBJECT_CREATION\n" +
-// " offset = 5\n" +
-// " )\n" +
-// " #75 @A(\n" +
-// " #68 value=\"int class literal\" (constant type)\n" +
-// " target type = 0x1e CLASS_LITERAL\n" +
-// " offset = 17\n" +
-// " )\n" +
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #67 @B(\n" +
-// " #68 value=(int) 3 (constant type)\n" +
-// " target type = 0x4 OBJECT_CREATION\n" +
-// " offset = 5\n" +
-// " )\n" +
-// " #67 @B(\n" +
-// " #68 value=(int) 4 (constant type)\n" +
-// " target type = 0x1e CLASS_LITERAL\n" +
-// " offset = 13\n" +
-// " )\n" +
-// " #67 @B(\n" +
-// " #68 value=(int) 5 (constant type)\n" +
-// " target type = 0x1e CLASS_LITERAL\n" +
-// " offset = 17\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
-// // class literal generic and array
-// public void test006() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "A.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface A {\n" +
-// " String value() default \"default\";\n" +
-// "}\n",
-// "B.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(CLASS)\n" +
-// "@interface B {\n" +
-// " int value() default -1;\n" +
-// "}",
-// "C.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface C {\n" +
-// " char value() default '-';\n" +
-// "}\n",
-// "I.java",
-// "interface I {}\n",
-// "J.java",
-// "interface J {}\n",
-// "X.java",
-// "public class X {\n" +
-// " public boolean foo(Object o) {\n" +
-// " boolean b = (o instanceof @C('_') Object[]);\n" +
-// " Object o1 = new @B(3) @A(\"new Object\") Object[] {};\n" +
-// " Class<?> c = @B(4) Object[].class;\n" +
-// " Class<?> c2 = @A(\"int class literal\") @B(5) int[].class;\n" +
-// " System.out.println(o1.toString() + c.toString() + c2.toString());\n" +
-// " return b;\n" +
-// " }\n" +
-// "}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeVisibleTypeAnnotations: \n" +
-// " #70 @C(\n" +
-// " #66 value=\'_\' (constant type)\n" +
-// " target type = 0x2 TYPE_INSTANCEOF\n" +
-// " offset = 1\n" +
-// " )\n" +
-// " #72 @A(\n" +
-// " #66 value=\"int class literal\" (constant type)\n" +
-// " target type = 0x1e CLASS_LITERAL\n" +
-// " offset = 14\n" +
-// " )\n" +
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #65 @B(\n" +
-// " #66 value=(int) 4 (constant type)\n" +
-// " target type = 0x1e CLASS_LITERAL\n" +
-// " offset = 10\n" +
-// " )\n" +
-// " #65 @B(\n" +
-// " #66 value=(int) 5 (constant type)\n" +
-// " target type = 0x1e CLASS_LITERAL\n" +
-// " offset = 14\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
-// // parameterized superclass
-// public void test007() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "A.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface A {\n" +
-// " String value() default \"default\";\n" +
-// "}\n",
-// "B.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(CLASS)\n" +
-// "@interface B {\n" +
-// " int value() default -1;\n" +
-// "}",
-// "C.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface C {\n" +
-// " char value() default '-';\n" +
-// "}\n",
-// "Y.java",
-// "class Y<T> {}\n",
-// "X.java",
-// "public class X extends @A(\"Hello, World!\") Y<@B @C('(') String> {\n" +
-// "}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeVisibleTypeAnnotations: \n" +
-// " #21 @A(\n" +
-// " #22 value=\"Hello, World!\" (constant type)\n" +
-// " target type = 0x14 CLASS_EXTENDS_IMPLEMENTS\n" +
-// " type index = -1\n" +
-// " )\n" +
-// " #24 @C(\n" +
-// " #22 value=\'(\' (constant type)\n" +
-// " target type = 0x15 CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY\n" +
-// " type index = -1\n" +
-// " locations = {0}\n" +
-// " )\n" +
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #19 @B(\n" +
-// " target type = 0x15 CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY\n" +
-// " type index = -1\n" +
-// " locations = {0}\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
-// public void test008() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "A.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface A {\n" +
-// " String value() default \"default\";\n" +
-// "}\n",
-// "B.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(CLASS)\n" +
-// "@interface B {\n" +
-// " int value() default -1;\n" +
-// "}",
-// "C.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface C {\n" +
-// " char value() default '-';\n" +
-// "}\n",
-// "I.java",
-// "interface I<T> {}\n",
-// "J.java",
-// "interface J<U,T> {}\n",
-// "X.java",
-// "public class X implements I<@A(\"Hello, World!\") String>, @B J<String, @C('(') Integer> {}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeVisibleTypeAnnotations: \n" +
-// " #25 @A(\n" +
-// " #26 value=\"Hello, World!\" (constant type)\n" +
-// " target type = 0x15 CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY\n" +
-// " type index = 0\n" +
-// " locations = {0}\n" +
-// " )\n" +
-// " #28 @C(\n" +
-// " #26 value=\'(\' (constant type)\n" +
-// " target type = 0x15 CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY\n" +
-// " type index = 1\n" +
-// " locations = {1}\n" +
-// " )\n" +
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #23 @B(\n" +
-// " target type = 0x14 CLASS_EXTENDS_IMPLEMENTS\n" +
-// " type index = 1\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
- // throws
- public void test009() throws Exception {
+
+ // Enables the tests to run individually
+ protected Map getCompilerOptions() {
+ Map defaultOptions = super.getCompilerOptions();
+ defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8);
+ defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8);
+ defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
+ return defaultOptions;
+ }
+
+ private static final String HELPER_CLASS =
+ "import java.lang.annotation.*;\n"+
+ "import java.lang.reflect.*;\n"+
+ "class Helper {\n"+
+ "\n"+
+ // Print type annotations on super types
+ " public static void printTypeAnnotations(Class<?> clazz) {\n"+
+ " System.out.println(\"Annotations on superclass of \"+clazz.getName());\n"+
+ " AnnotatedType superat = clazz.getAnnotatedSuperclass();\n"+
+ " Helper.printAnnos(\" \", superat.getType(),superat.getAnnotations());\n"+
+ " AnnotatedType[] superinterfaces = clazz.getAnnotatedInterfaces();\n"+
+ " if (superinterfaces.length!=0) {\n"+
+ " System.out.println(\"Annotations on superinterfaces of \"+clazz.getName());\n"+
+ " for (int j=0;j<superinterfaces.length;j++) {\n"+
+ " Helper.printAnnos(\" \", superinterfaces[j].getType(),superinterfaces[j].getAnnotations());\n"+
+ " }\n"+
+ " }\n"+
+ " }\n"+
+ // Print type annotations on a type
+ " public static void printTypeAnnotations2(Class<?> clazz) {\n"+
+ " System.out.print(clazz.getName()+\"<\");\n"+
+ " TypeVariable<?>[] tvs = clazz.getTypeParameters();\n"+
+ " for (int t=0;t<tvs.length;t++) {\n"+
+ " TypeVariable<?> tv = tvs[t];\n"+
+ " Annotation[] annos = tv.getAnnotations();\n"+
+ " for (int a=0;a<annos.length;a++) {\n"+
+ " System.out.print(toStringAnno(annos[a])+\" \");\n"+
+ " }\n"+
+ " System.out.print(tv.getName());\n"+
+ " if ((t+1)<tvs.length) System.out.print(\",\");\n"+
+ " }\n"+
+ " System.out.println(\">\");\n"+
+ " }\n"+
+ " public static String toStringAnno(Annotation anno) {\n"+
+ " String s = anno.toString();\n"+
+ " if (s.endsWith(\"()\")) return s.substring(0,s.length()-2); else return s;\n"+
+ " }\n"+
+ " \n"+
+ " public static void printAnnos(String header, Type t, Annotation[] annos) {\n"+
+ " if (annos.length==0) { System.out.println(header+t+\":no annotations\"); return;} \n"+
+ " System.out.print(header+t+\":\");\n"+
+ " for (int i=0;i<annos.length;i++) {\n"+
+ " System.out.print(toStringAnno(annos[i])+\" \");\n"+
+ " }\n"+
+ " System.out.println();\n"+
+ " }\n"+
+ "}\n";
+
+ // http://types.cs.washington.edu/jsr308/specification/java-annotation-design.pdf
+ // type_annotation {
+ // // New fields in JSR 308:
+ // u1 target_type; // the type of the targeted program element, see Section 3.2
+ // union {
+ // type_parameter_target;
+ // supertype_target;
+ // type_parameter_bound_target;
+ // empty_target;
+ // method_formal_parameter_target;
+ // throws_target;
+ // localvar_target;
+ // catch_target;
+ // offset_target;
+ // type_argument_target;
+ // method_reference_target;
+ // } target_info; // identifies the targeted program element, see Section 3.3
+ // type_path target_path; // identifies targeted type in a compound type (array, generic, etc.), see Section 3.4
+ // // Original fields from "annotation" structure:
+ // u2 type_index;
+ // u2 num_element_value_pairs;
+ // {
+ // u2 element_name_index;
+ // element_value value;
+ // } element_value_pairs[num_element_value_pairs];
+ // }
+
+ public void test001_classTypeParameter() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<@Marker T> {}",
+
+ "Marker.java",
+ "import java.lang.annotation.*;\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n"+
+ "@Target(ElementType.TYPE_PARAMETER)\n" +
+ "@interface Marker {}",
+ },
+ "");
+ // javac-b81: 9[0 1 0 0 0 0 13 0 0] (13=Marker annotation)
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #21 @Marker(\n" +
+ " target type = 0x0 CLASS_TYPE_PARAMETER\n" +
+ " type parameter index = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test002_classTypeParameter_reflection() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<@Marker T> {\n"+
+ " public static void main(String[] argv) { Helper.printTypeAnnotations2(X.class);}\n"+
+ "}",
+
+ "Helper.java",HELPER_CLASS,
+ "Marker.java",
+ "import java.lang.annotation.*;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n"+
+ "@Target(TYPE_PARAMETER)\n" +
+ "@interface Marker {}",
+ },
+ "X<@Marker T>");
+ }
+
+ public void test003_classTypeParameter() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<@A1 T1,@A2 @A3 T2> {}",
+
+ "A1.java",
+ "import java.lang.annotation.*;\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n"+
+ "@Target(ElementType.TYPE_PARAMETER)\n" +
+ "@interface A1 {}",
+
+ "A2.java",
+ "import java.lang.annotation.*;\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n"+
+ "@Target(ElementType.TYPE_PARAMETER)\n" +
+ "@interface A2 {}",
+
+ "A3.java",
+ "import java.lang.annotation.*;\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n"+
+ "@Target(ElementType.TYPE_PARAMETER)\n" +
+ "@interface A3 {}",
+
+ },
+ "");
+ // javac-b81: 9[0 1 0 0 0 0 13 0 0] (13=Marker)
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #21 @A1(\n" +
+ " target type = 0x0 CLASS_TYPE_PARAMETER\n" +
+ " type parameter index = 0\n" +
+ " )\n" +
+ " #22 @A2(\n" +
+ " target type = 0x0 CLASS_TYPE_PARAMETER\n" +
+ " type parameter index = 1\n" +
+ " )\n" +
+ " #23 @A3(\n" +
+ " target type = 0x0 CLASS_TYPE_PARAMETER\n" +
+ " type parameter index = 1\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test004_classTypeParameter_reflection() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<@A1 T1,@A2 @A3 T2> {\n"+
+ " public static void main(String[] argv) { Helper.printTypeAnnotations2(X.class); }\n"+
+ "}",
+
+ "Helper.java",HELPER_CLASS,
+ "A1.java",
+ "import java.lang.annotation.*;\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n"+
+ "@Target(ElementType.TYPE_PARAMETER)\n" +
+ "@interface A1 {}",
+ "A2.java",
+ "import java.lang.annotation.*;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n"+
+ "@Target(TYPE_PARAMETER)\n" +
+ "@interface A2 {}",
+ "A3.java",
+ "import java.lang.annotation.*;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n"+
+ "@Target(TYPE_PARAMETER)\n" +
+ "@interface A3 {}",
+ },
+ "X<@A1 T1,@A2 @A3 T2>");
+ }
+
+ public void test005_classTypeParameter() throws Exception {
this.runConformTest(
new String[] {
"A.java",
@@ -492,7 +246,7 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
+ "@Target(TYPE_PARAMETER)\n" +
"@Retention(RUNTIME)\n" +
"@interface A {\n" +
" String value() default \"default\";\n" +
@@ -502,98 +256,31 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
+ "@Target(TYPE_PARAMETER)\n" +
"@Retention(CLASS)\n" +
"@interface B {\n" +
" int value() default -1;\n" +
"}",
- "C.java",
- "import java.lang.annotation.Target;\n" +
- "import static java.lang.annotation.ElementType.*;\n" +
- "import java.lang.annotation.Retention;\n" +
- "import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
- "@Retention(RUNTIME)\n" +
- "@interface C {\n" +
- " char value() default '-';\n" +
- "}\n",
- "E.java",
- "class E extends RuntimeException {\n" +
- " private static final long serialVersionUID = 1L;\n" +
- "}\n",
- "E1.java",
- "class E1 extends RuntimeException {\n" +
- " private static final long serialVersionUID = 1L;\n" +
- "}\n",
- "E2.java",
- "class E2 extends RuntimeException {\n" +
- " private static final long serialVersionUID = 1L;\n" +
- "}\n",
"X.java",
- "public class X {\n" +
- " void foo() throws @A(\"Hello, World!\") E, E1, @B @C('(') E2 {}\n" +
- "}",
+ "public class X<@A @B(3) T> {}",
},
"");
String expectedOutput =
- " RuntimeVisibleTypeAnnotations: \n" +
- " #25 @A(\n" +
- " #26 value=\"Hello, World!\" (constant type)\n" +
- " target type = 0x16 THROWS\n" +
- " throws index = 0\n" +
- " )\n" +
- " #28 @C(\n" +
- " #26 value=\'(\' (constant type)\n" +
- " target type = 0x16 THROWS\n" +
- " throws index = 2\n" +
- " )\n" +
- " RuntimeInvisibleTypeAnnotations: \n" +
- " #23 @B(\n" +
- " target type = 0x16 THROWS\n" +
- " throws index = 2\n" +
- " )\n";
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #25 @A(\n" +
+ " target type = 0x0 CLASS_TYPE_PARAMETER\n" +
+ " type parameter index = 0\n" +
+ " )\n" +
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #21 @B(\n" +
+ " #22 value=(int) 3 (constant type)\n" +
+ " target type = 0x0 CLASS_TYPE_PARAMETER\n" +
+ " type parameter index = 0\n" +
+ " )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
-// // method receiver
-// public void test010() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "A.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface A {\n" +
-// " String value() default \"default\";\n" +
-// "}\n",
-// "B.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(CLASS)\n" +
-// "@interface B {\n" +
-// " int value() default -1;\n" +
-// "}",
-// "X.java",
-// "public class X {\n" +
-// " void foo() @B(3) {}\n" +
-// "}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #16 @B(\n" +
-// " #17 value=(int) 3 (constant type)\n" +
-// " target type = 0x6 METHOD_RECEIVER\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
- // method return type
- public void test011() throws Exception {
+
+ public void test006_classTypeParameter() throws Exception {
this.runConformTest(
new String[] {
"A.java",
@@ -601,7 +288,7 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
+ "@Target(TYPE_PARAMETER)\n" +
"@Retention(RUNTIME)\n" +
"@interface A {\n" +
" String value() default \"default\";\n" +
@@ -611,34 +298,31 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
+ "@Target(TYPE_PARAMETER)\n" +
"@Retention(CLASS)\n" +
"@interface B {\n" +
" int value() default -1;\n" +
"}",
"X.java",
- "public class X {\n" +
- " @B(3) @A(value=\"test\") int foo() {\n" +
- " return 1;\n" +
- " }\n" +
- "}",
+ "public class X<T1,T2,@A @B(3) T3> {}",
},
"");
String expectedOutput =
- " RuntimeVisibleTypeAnnotations: \n" +
- " #21 @A(\n" +
- " #18 value=\"test\" (constant type)\n" +
- " target type = 0xa METHOD_RETURN_TYPE\n" +
- " )\n" +
- " RuntimeInvisibleTypeAnnotations: \n" +
- " #17 @B(\n" +
- " #18 value=(int) 3 (constant type)\n" +
- " target type = 0xa METHOD_RETURN_TYPE\n" +
- " )\n";
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #25 @A(\n" +
+ " target type = 0x0 CLASS_TYPE_PARAMETER\n" +
+ " type parameter index = 2\n" +
+ " )\n" +
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #21 @B(\n" +
+ " #22 value=(int) 3 (constant type)\n" +
+ " target type = 0x0 CLASS_TYPE_PARAMETER\n" +
+ " type parameter index = 2\n" +
+ " )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // field type
- public void test012() throws Exception {
+
+ public void test007_methodTypeParameter() throws Exception {
this.runConformTest(
new String[] {
"A.java",
@@ -646,7 +330,7 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
+ "@Target(TYPE_PARAMETER)\n" +
"@Retention(RUNTIME)\n" +
"@interface A {\n" +
" String value() default \"default\";\n" +
@@ -656,109 +340,33 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
+ "@Target(TYPE_PARAMETER)\n" +
"@Retention(CLASS)\n" +
"@interface B {\n" +
" int value() default -1;\n" +
"}",
"X.java",
"public class X {\n" +
- " @B(3) @A int field;\n" +
+ " <@A @B(3) T> void foo(T t) {}\n" +
"}",
},
"");
String expectedOutput =
" RuntimeVisibleTypeAnnotations: \n" +
- " #12 @A(\n" +
- " target type = 0xe FIELD\n" +
+ " #27 @A(\n" +
+ " target type = 0x1 METHOD_TYPE_PARAMETER\n" +
+ " type parameter index = 0\n" +
" )\n" +
" RuntimeInvisibleTypeAnnotations: \n" +
- " #8 @B(\n" +
- " #9 value=(int) 3 (constant type)\n" +
- " target type = 0xe FIELD\n" +
+ " #23 @B(\n" +
+ " #24 value=(int) 3 (constant type)\n" +
+ " target type = 0x1 METHOD_TYPE_PARAMETER\n" +
+ " type parameter index = 0\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
-// // method parameter
-// public void test013() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "B.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(CLASS)\n" +
-// "@interface B {\n" +
-// " int value() default -1;\n" +
-// "}",
-// "X.java",
-// "public class X {\n" +
-// " int foo(@B(3) String s) {\n" +
-// " return s.length();\n" +
-// " }\n" +
-// "}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #25 @B(\n" +
-// " #26 value=(int) 3 (constant type)\n" +
-// " target type = 0xc METHOD_PARAMETER\n" +
-// " method parameter index = 0\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
-// // method parameter generic or array
-// public void test014() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "A.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface A {\n" +
-// " String value() default \"default\";\n" +
-// "}\n",
-// "B.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(CLASS)\n" +
-// "@interface B {\n" +
-// " int value() default -1;\n" +
-// "}",
-// "X.java",
-// "public class X {\n" +
-// " int foo(String @A [] @B(3) [] s) {\n" +
-// " return s.length;\n" +
-// " }\n" +
-// "}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeVisibleTypeAnnotations: \n" +
-// " #23 @A(\n" +
-// " target type = 0xc METHOD_PARAMETER\n" +
-// " method parameter index = 0\n" +
-// " )\n" +
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #19 @B(\n" +
-// " #20 value=(int) 3 (constant type)\n" +
-// " target type = 0xd METHOD_PARAMETER_GENERIC_OR_ARRAY\n" +
-// " method parameter index = 0\n" +
-// " locations = {0}\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
- // field type generic or array
- public void test015() throws Exception {
+
+ public void test008_methodTypeParameter() throws Exception {
this.runConformTest(
new String[] {
"A.java",
@@ -766,7 +374,7 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
+ "@Target(TYPE_PARAMETER)\n" +
"@Retention(RUNTIME)\n" +
"@interface A {\n" +
" String value() default \"default\";\n" +
@@ -776,75 +384,111 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
+ "@Target(TYPE_PARAMETER)\n" +
"@Retention(CLASS)\n" +
"@interface B {\n" +
" int value() default -1;\n" +
"}",
"X.java",
"public class X {\n" +
- " @A int [] @B(3) [] field;\n" +
+ " <T1, @A @B(3) T2> void foo(T1 t1,T2 t2) {}\n" +
"}",
},
"");
String expectedOutput =
" RuntimeVisibleTypeAnnotations: \n" +
- " #12 @A(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {1}\n" +
+ " #29 @A(\n" +
+ " target type = 0x1 METHOD_TYPE_PARAMETER\n" +
+ " type parameter index = 1\n" +
" )\n" +
" RuntimeInvisibleTypeAnnotations: \n" +
- " #8 @B(\n" +
- " #9 value=(int) 3 (constant type)\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {0}\n" +
+ " #25 @B(\n" +
+ " #26 value=(int) 3 (constant type)\n" +
+ " target type = 0x1 METHOD_TYPE_PARAMETER\n" +
+ " type parameter index = 1\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
-// // class type parameter
-// public void test016() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "A.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_PARAMETER)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface A {\n" +
-// " String value() default \"default\";\n" +
-// "}\n",
-// "B.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_PARAMETER)\n" +
-// "@Retention(CLASS)\n" +
-// "@interface B {\n" +
-// " int value() default -1;\n" +
-// "}",
-// "X.java",
-// "public class X<@A @B(3) T> {}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeVisibleTypeAnnotations: \n" +
-// " #25 @A(\n" +
-// " target type = 0x22 CLASS_TYPE_PARAMETER\n" +
-// " type parameter index = 0\n" +
-// " )\n" +
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #21 @B(\n" +
-// " #22 value=(int) 3 (constant type)\n" +
-// " target type = 0x22 CLASS_TYPE_PARAMETER\n" +
-// " type parameter index = 0\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
- // method type parameter
- public void test017() throws Exception {
+
+ public void test009_classExtends() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "Marker.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@interface Marker {}",
+ "X.java",
+ "public class X extends @Marker Object {}",
+ },
+ "");
+ // javac-b81 annotation contents: len:10[0 1 16 -1 -1 0 0 17 0 0]
+ String expectedOutput =
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #17 @Marker(\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = -1\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test010_classExtends() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "Marker.java",
+ "import java.lang.annotation.*;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n"+
+ "@Target(TYPE_USE)\n" +
+ "@interface Marker {}",
+ "X.java",
+ "public class X extends @Marker Object {}",
+ },
+ "");
+ // Bytes:10[0 1 16 -1 -1 0 0 17 0 0]
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #17 @Marker(\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = -1\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test011_classExtends_reflection() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X extends @Marker Object {public static void main(String[] argv) {Helper.printTypeAnnotations(X.class);}}",
+ "Helper.java",HELPER_CLASS,
+ "Marker.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@interface Marker {}"
+ },
+ "Annotations on superclass of X\n"+
+ " class java.lang.Object:no annotations");
+ }
+
+ public void test012_classExtends_reflection() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X extends @Marker Object {public static void main(String[] argv) {Helper.printTypeAnnotations(X.class);}}",
+ "Helper.java",HELPER_CLASS,
+ "Marker.java",
+ "import java.lang.annotation.*;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n"+
+ "@interface Marker {}"
+ },
+ "Annotations on superclass of X\n"+
+ " class java.lang.Object:@Marker");
+ }
+
+ public void test013_classExtends_interfaces() throws Exception {
this.runConformTest(
new String[] {
"A.java",
@@ -852,152 +496,70 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_PARAMETER)\n" +
+ "@Target(TYPE_USE)\n" +
"@Retention(RUNTIME)\n" +
"@interface A {\n" +
- " String value() default \"default\";\n" +
+ " String id() default \"default\";\n" +
"}\n",
"B.java",
"import java.lang.annotation.Target;\n" +
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_PARAMETER)\n" +
+ "@Target(TYPE_USE)\n" +
"@Retention(CLASS)\n" +
"@interface B {\n" +
" int value() default -1;\n" +
"}",
+ "C.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(RUNTIME)\n" +
+ "@interface C {\n" +
+ " char value() default '-';\n" +
+ "}\n",
+ "I.java",
+ "interface I {}\n",
+ "J.java",
+ "interface J {}\n",
"X.java",
- "public class X {\n" +
- " <@A @B(3) T> void foo(T t) {}\n" +
- "}",
+ "public class X implements @A(id=\"Hello, World!\") I, @B @C('(') J {}",
},
"");
+ // Output from javac b81 lambda
+ // RuntimeVisibleTypeAnnotations
+ // Bytes:28[0 2 16 0 0 0 0 13 0 1 0 14 115 0 15 16 0 1 0 0 16 0 1 0 17 67 0 18]
+ // RuntimeInvisibleTypeAnnotations
+ // Bytes:10[0 1 16 0 1 0 0 20 0 0]
String expectedOutput =
- " RuntimeVisibleTypeAnnotations: \n" +
- " #27 @A(\n" +
- " target type = 0x20 METHOD_TYPE_PARAMETER\n" +
- " type parameter index = 0\n" +
- " )\n" +
- " RuntimeInvisibleTypeAnnotations: \n" +
- " #23 @B(\n" +
- " #24 value=(int) 3 (constant type)\n" +
- " target type = 0x20 METHOD_TYPE_PARAMETER\n" +
- " type parameter index = 0\n" +
- " )\n";
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #23 @A(\n" +
+ " #24 id=\"Hello, World!\" (constant type)\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = 0\n" +
+ " )\n" +
+ " #26 @C(\n" +
+ " #27 value=\'(\' (constant type)\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = 1\n" +
+ " )\n" +
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #21 @B(\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = 1\n" +
+ " )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
-// // class type parameter bound
-// public void test018() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "A.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface A {\n" +
-// " String value() default \"default\";\n" +
-// "}\n",
-// "B.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(CLASS)\n" +
-// "@interface B {\n" +
-// " int value() default -1;\n" +
-// "}",
-// "X.java",
-// "public class X<T extends @A String & @B(3) Cloneable> {}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeVisibleTypeAnnotations: \n" +
-// " #25 @A(\n" +
-// " target type = 0x10 CLASS_TYPE_PARAMETER_BOUND\n" +
-// " type parameter index = 0 type parameter bound index = 0\n" +
-// " )\n" +
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #21 @B(\n" +
-// " #22 value=(int) 3 (constant type)\n" +
-// " target type = 0x10 CLASS_TYPE_PARAMETER_BOUND\n" +
-// " type parameter index = 0 type parameter bound index = 1\n" +
-// " )\n" ;
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
-// // class type parameter bound generic or array
-// public void test019() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "A.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface A {\n" +
-// " String value() default \"default\";\n" +
-// "}\n",
-// "B.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(CLASS)\n" +
-// "@interface B {\n" +
-// " int value() default -1;\n" +
-// "}",
-// "C.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface C {\n" +
-// " char value() default '-';\n" +
-// "}\n",
-// "Y.java",
-// "public class Y<T> {}",
-// "X.java",
-// "public class X<U, T extends Y<@A String @C[][]@B[]> & @B(3) Cloneable> {}",
-// },
-// "");
-// String expectedOutput =
-// " RuntimeVisibleTypeAnnotations: \n" +
-// " #25 @A(\n" +
-// " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY\n" +
-// " type parameter index = 1 type parameter bound index = 0\n" +
-// " locations = {0,2}\n" +
-// " )\n" +
-// " #26 @C(\n" +
-// " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY\n" +
-// " type parameter index = 1 type parameter bound index = 0\n" +
-// " locations = {0}\n" +
-// " )\n" +
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #21 @B(\n" +
-// " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY\n" +
-// " type parameter index = 1 type parameter bound index = 0\n" +
-// " locations = {0,1}\n" +
-// " )\n" +
-// " #21 @B(\n" +
-// " #22 value=(int) 3 (constant type)\n" +
-// " target type = 0x10 CLASS_TYPE_PARAMETER_BOUND\n" +
-// " type parameter index = 1 type parameter bound index = 1\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
- // method type parameter bound
- public void test020() throws Exception {
+
+ public void test014_classExtends_interfaces_reflection() throws Exception {
this.runConformTest(
new String[] {
+ "X.java",
+ "public class X implements @A I {public static void main(String[]argv) {Helper.printTypeAnnotations(X.class);}}",
+ "Helper.java",HELPER_CLASS,
"A.java",
"import java.lang.annotation.Target;\n" +
"import static java.lang.annotation.ElementType.*;\n" +
@@ -1006,7 +568,31 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"@Target(TYPE_USE)\n" +
"@Retention(RUNTIME)\n" +
"@interface A {\n" +
- " String value() default \"default\";\n" +
+ "}\n",
+ "I.java",
+ "interface I {}\n"
+ },
+ "Annotations on superclass of X\n" +
+ " class java.lang.Object:no annotations\n" +
+ "Annotations on superinterfaces of X\n" +
+ " interface I:@A");
+ }
+
+ public void test015_classExtends_interfaces_reflection() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X implements @A(id=\"Hello, World!\") I, @B @C('i') J {public static void main(String[] argv) { Helper.printTypeAnnotations(X.class);}}",
+ "Helper.java",HELPER_CLASS,
+ "A.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(RUNTIME)\n" +
+ "@interface A {\n" +
+ " String id() default \"default\";\n" +
"}\n",
"B.java",
"import java.lang.annotation.Target;\n" +
@@ -1018,30 +604,252 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"@interface B {\n" +
" int value() default -1;\n" +
"}",
- "Z.java",
- "public class Z {}",
+ "C.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(RUNTIME)\n" +
+ "@interface C {\n" +
+ " char value() default '-';\n" +
+ "}\n",
+ "I.java",
+ "interface I {}\n",
+ "J.java",
+ "interface J {}\n",
+ },
+ "Annotations on superclass of X\n" +
+ " class java.lang.Object:no annotations\n" +
+ "Annotations on superinterfaces of X\n" +
+ " interface I:@A(id=Hello, World!) \n" +
+ " interface J:@C(value=i)");
+ }
+
+ public void test016_classExtends() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "B.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(RUNTIME)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ "Y.java",
+ "class Y<T> {}\n",
"X.java",
- "public class X {\n" +
- " <T extends @A Z & @B(3) Cloneable> void foo(T t) {}\n" +
+ "public class X extends Y<@B String> {\n" +
"}",
},
"");
+ // javac-b81: Bytes:12[0 1 16 -1 -1 1 3 0 0 13 0 0] // type path: 1,3,0
String expectedOutput =
- " RuntimeVisibleTypeAnnotations: \n" +
- " #27 @A(\n" +
- " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" +
- " type parameter index = 0 type parameter bound index = 0\n" +
- " )\n" +
- " RuntimeInvisibleTypeAnnotations: \n" +
- " #23 @B(\n" +
- " #24 value=(int) 3 (constant type)\n" +
- " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" +
- " type parameter index = 0 type parameter bound index = 1\n" +
- " )\n";
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #19 @B(\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = -1\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test017_classExtends() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "Marker.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface Marker { }\n",
+ "I.java",
+ "interface I<T> {}\n",
+ "X.java",
+ "public class X implements I<@Marker String> {\n" +
+ "}",
+ },
+ "");
+ // javac-b81: Bytes:12[0 1 16 0 0 1 3 0 0 14 0 0] // type path: 1,3,0
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #21 @Marker(\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = 0\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
+ " )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // class type parameter bound generic or array
- public void test021() throws Exception {
+
+ public void test018_classExtends() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A { }\n",
+
+ "I.java",
+ "interface I<T1,T2> {}\n",
+
+ "X.java",
+ "public class X implements I<Integer, @A String> {}\n"
+ },
+ "");
+ // javac-b81: Bytes:12[0 1 16 0 0 1 3 1 0 14 0 0] // type path: 1,3,1
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #21 @A(\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = 0\n" +
+ " location = [TYPE_ARGUMENT(1)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test019_classExtends() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A { }\n",
+
+ "J.java",
+ "interface J<T> {}\n",
+
+ "I.java",
+ "interface I<T> {}\n",
+
+ "X.java",
+ "public class X implements I<J<@A String>> {}\n"
+ },
+ "");
+ // javac-b81: Bytes:14[0 1 16 0 0 2 3 0 3 0 0 14 0 0] // type path: 2,3,0,3,0
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #21 @A(\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = 0\n" +
+ " location = [TYPE_ARGUMENT(0), TYPE_ARGUMENT(0)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test020_classExtends() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A { }\n",
+
+ "I.java",
+ "interface I<T> {}\n",
+
+ "X.java",
+ "public class X implements I<@A String[]> {}\n"
+ },
+ "");
+ // javac-b81: Bytes:14[0 1 16 0 0 2 3 0 0 0 0 14 0 0] // type path: 2,3,0,0,0
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #21 @A(\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = 0\n" +
+ " location = [TYPE_ARGUMENT(0), ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test021_classExtends() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A { }\n",
+
+ "I.java",
+ "interface I<T> {}\n",
+
+ "X.java",
+ "public class X implements I<String @A[]> {}\n"
+ },
+ "");
+ // javac-b81: Bytes:12[0 1 16 0 0 1 3 0 0 14 0 0] // type path: 1,3,0
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #21 @A(\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = 0\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test022_classExtends() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A { }\n",
+
+ "I.java",
+ "interface I<T> {}\n",
+
+ "X.java",
+ "public class X implements I<String []@A[]> {}\n"
+ },
+ "");
+ // javac-b81: Bytes:14[0 1 16 0 0 2 3 0 0 0 0 14 0 0] // type path: 2,3,0,0,0
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #21 @A(\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = 0\n" +
+ " location = [TYPE_ARGUMENT(0), ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test023_classExtends() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A { }\n",
+
+ "I.java",
+ "interface I<T> {}\n",
+
+ "X.java",
+ "public class X implements I<@A String [][][]> {}\n"
+ },
+ "");
+ // javac-b81: Bytes:10[0 1 16 0 0 0 0 12 0 0] // type path: 4,3,0,0,0,0,0,0,0
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #21 @A(\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = 0\n" +
+ " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+
+ public void test024_classExtends() throws Exception {
this.runConformTest(
new String[] {
"A.java",
@@ -1074,43 +882,60 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"@interface C {\n" +
" char value() default '-';\n" +
"}\n",
- "Z.java",
- "public class Z {}",
- "Y.java",
- "public class Y<T> {}",
+ "I.java",
+ "interface I<T> {}\n",
+ "J.java",
+ "interface J<U,T> {}\n",
"X.java",
- "public class X {\n" +
- " <T extends Y<@A Z @C[][]@B[]> & @B(3) Cloneable> void foo(T t) {}\n" +
- "}",
+ "public class X implements I<@A(\"Hello, World!\") String>, @B J<String, @C('(') Integer> {}",
},
"");
String expectedOutput =
- " RuntimeVisibleTypeAnnotations: \n" +
- " #27 @A(\n" +
- " target type = 0x13 METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY\n" +
- " type parameter index = 0 type parameter bound index = 0\n" +
- " locations = {0,2}\n" +
- " )\n" +
- " #28 @C(\n" +
- " target type = 0x13 METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY\n" +
- " type parameter index = 0 type parameter bound index = 0\n" +
- " locations = {0}\n" +
- " )\n" +
- " RuntimeInvisibleTypeAnnotations: \n" +
- " #23 @B(\n" +
- " target type = 0x13 METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY\n" +
- " type parameter index = 0 type parameter bound index = 0\n" +
- " locations = {0,1}\n" +
- " )\n" +
- " #23 @B(\n" +
- " #24 value=(int) 3 (constant type)\n" +
- " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" +
- " type parameter index = 0 type parameter bound index = 1\n" +
- " )\n";
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #25 @A(\n" +
+ " #26 value=\"Hello, World!\" (constant type)\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = 0\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
+ " )\n" +
+ " #28 @C(\n" +
+ " #26 value=\'(\' (constant type)\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = 1\n" +
+ " location = [TYPE_ARGUMENT(1)]\n" +
+ " )\n" +
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #23 @B(\n" +
+ " target type = 0x10 CLASS_EXTENDS\n" +
+ " type index = 1\n" +
+ " )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // local variable + generic or array
- public void test022() throws Exception {
+
+ public void test025_classTypeParameterBound() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<T extends @A String> {}",
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {}\n"
+ },
+ "");
+ // javac-b81: Bytes:10[0 1 17 0 0 0 0 13 0 0]
+ // [17 0 0] is CLASS_PARAMETER_BOUND type_parameter_index=0 bound_index=0
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #21 @A(\n" +
+ " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 0 type parameter bound index = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test026_classTypeParameterBound() throws Exception {
this.runConformTest(
new String[] {
"A.java",
@@ -1133,62 +958,113 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"@interface B {\n" +
" int value() default -1;\n" +
"}",
+ "X.java",
+ "public class X<T extends @A String & @B(3) Cloneable> {}",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #25 @A(\n" +
+ " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 0 type parameter bound index = 0\n" +
+ " )\n" +
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #21 @B(\n" +
+ " #22 value=(int) 3 (constant type)\n" +
+ " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 0 type parameter bound index = 1\n" +
+ " )\n" ;
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test027_classTypeParameterBound_complex() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
"C.java",
- "import java.lang.annotation.Target;\n" +
- "import static java.lang.annotation.ElementType.*;\n" +
- "import java.lang.annotation.Retention;\n" +
- "import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
- "@Retention(RUNTIME)\n" +
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
"@interface C {\n" +
" char value() default '-';\n" +
"}\n",
+ "Y.java",
+ "public class Y<T> {}",
+ "X.java",
+ "public class X<U, T extends Y<@A String @C[][]@B[]> & @B(3) Cloneable> {}",
+ },
+ "");
+ // javac-b81:
+ // Bytes:28[0 2 17 1 0 1 3 0 0 13 0 0 17 1 0 4 3 0 0 0 0 0 0 0 0 14 0 0]
+ // Bytes:29[0 2 17 1 0 3 3 0 0 0 0 0 0 16 0 0 17 1 1 0 0 16 0 1 0 17 73 0 18]
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #25 @A(\n" +
+ " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 1 type parameter bound index = 0\n" +
+ " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]\n" +
+ " )\n" +
+ " #26 @C(\n" +
+ " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 1 type parameter bound index = 0\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
+ " )\n" +
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #21 @B(\n" +
+ " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 1 type parameter bound index = 0\n" +
+ " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY]\n" +
+ " )\n" +
+ " #21 @B(\n" +
+ " #22 value=(int) 3 (constant type)\n" +
+ " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 1 type parameter bound index = 1\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test028_methodTypeParameterBound() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "Z.java",
+ "public class Z {}",
"X.java",
- "public class X {\n" +
- " String[][] bar() {\n" +
- " return new String[][] {};" +
- " }\n" +
- " void foo(String s) {\n" +
- " @C int i;\n" +
- " @A String [] @B(3)[] tab = bar();\n" +
- " if (tab != null) {\n" +
- " i = 0;\n" +
- " System.out.println(i + tab.length);\n" +
- " } else {\n" +
- " System.out.println(tab.length);\n" +
- " }\n" +
- " i = 4;\n" +
- " System.out.println(-i + tab.length);\n" +
- " }\n" +
+ "public class X {\n" +
+ " <T extends @A Z> void foo(T t) {}\n" +
"}",
},
"");
+ // javac-b81: Bytes:10[0 1 18 0 0 0 0 13 0 0]
String expectedOutput =
" RuntimeVisibleTypeAnnotations: \n" +
- " #49 @C(\n" +
- " target type = 0x8 LOCAL_VARIABLE\n" +
- " local variable entries:\n" +
- " [pc: 11, pc: 24] index: 2\n" +
- " [pc: 34, pc: 46] index: 2\n" +
- " )\n" +
- " #50 @A(\n" +
- " target type = 0x9 LOCAL_VARIABLE_GENERIC_OR_ARRAY\n" +
- " local variable entries:\n" +
- " [pc: 5, pc: 46] index: 3\n" +
- " locations = {1}\n" +
- " )\n" +
- " RuntimeInvisibleTypeAnnotations: \n" +
- " #45 @B(\n" +
- " #46 value=(int) 3 (constant type)\n" +
- " target type = 0x9 LOCAL_VARIABLE_GENERIC_OR_ARRAY\n" +
- " local variable entries:\n" +
- " [pc: 5, pc: 46] index: 3\n" +
- " locations = {0}\n" +
+ " #23 @A(\n" +
+ " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 0 type parameter bound index = 0\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // type argument constructor call
- public void test023() throws Exception {
+
+ public void test029_methodTypeParameterBound() throws Exception {
this.runConformTest(
new String[] {
"A.java",
@@ -1211,35 +1087,186 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"@interface B {\n" +
" int value() default -1;\n" +
"}",
+ "Z.java",
+ "public class Z {}",
"X.java",
- "public class X {\n" +
- " <T> X(T t) {\n" +
- " }\n" +
- " public Object foo() {\n" +
- " X x = new <@A @B(1) String>X(null);\n" +
- " return x;\n" +
- " }\n" +
+ "public class X {\n" +
+ " <T extends @A Z & @B(3) Cloneable> void foo(T t) {}\n" +
"}",
},
"");
String expectedOutput =
" RuntimeVisibleTypeAnnotations: \n" +
- " #31 @A(\n" +
- " target type = 0x18 TYPE_ARGUMENT_CONSTRUCTOR_CALL\n" +
- " offset = 5\n" +
- " type argument index = 0\n" +
+ " #27 @A(\n" +
+ " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 0 type parameter bound index = 0\n" +
" )\n" +
" RuntimeInvisibleTypeAnnotations: \n" +
- " #27 @B(\n" +
- " #28 value=(int) 1 (constant type)\n" +
- " target type = 0x18 TYPE_ARGUMENT_CONSTRUCTOR_CALL\n" +
- " offset = 5\n" +
- " type argument index = 0\n" +
+ " #23 @B(\n" +
+ " #24 value=(int) 3 (constant type)\n" +
+ " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 0 type parameter bound index = 1\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // type argument constructor call generic or array
- public void test024() throws Exception {
+
+ public void test030_methodTypeParameterBound() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ "C.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface C {\n" +
+ " char value() default '-';\n" +
+ "}\n",
+ "Z.java",
+ "public class Z {}",
+ "Y.java",
+ "public class Y<T> {}",
+ "X.java",
+ "public class X {\n" +
+ " <T extends Y<Z [][]@B[]> & Cloneable> void foo(T t) {}\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #23 @B(\n" +
+ " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 0 type parameter bound index = 0\n" +
+ " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test031_methodTypeParameterBound_complex() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ "C.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface C {\n" +
+ " char value() default '-';\n" +
+ "}\n",
+ "Z.java",
+ "public class Z {}",
+ "Y.java",
+ "public class Y<T> {}",
+ "X.java",
+ "public class X {\n" +
+ " <T extends Y<@A Z @C[][]@B[]> & @B(3) Cloneable> void foo(T t) {}\n" +
+ "}",
+ },
+ "");
+ // javac-b81:
+ // Bytes:28[0 2 18 0 0 1 3 0 0 13 0 0 18 0 0 4 3 0 0 0 0 0 0 0 0 14 0 0]
+ // Bytes:29[0 2 18 0 0 3 3 0 0 0 0 0 0 16 0 0 18 0 1 0 0 16 0 1 0 17 73 0 18]
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #27 @A(\n" +
+ " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 0 type parameter bound index = 0\n" +
+ " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]\n" +
+ " )\n" +
+ " #28 @C(\n" +
+ " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 0 type parameter bound index = 0\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
+ " )\n" +
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #23 @B(\n" +
+ " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 0 type parameter bound index = 0\n" +
+ " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY]\n" +
+ " )\n" +
+ " #23 @B(\n" +
+ " #24 value=(int) 3 (constant type)\n" +
+ " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" +
+ " type parameter index = 0 type parameter bound index = 1\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test032_field() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {}\n",
+
+ "X.java",
+ "public class X {\n" +
+ " @A int field;\n" +
+ "}",
+ },
+ "");
+ // javac-b81: Bytes:8[0 1 19 0 0 7 0 0] 19 = 0x13 (FIELD)
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @A(\n" +
+ " target type = 0x13 FIELD\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test033_field() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {}\n",
+
+ "X.java",
+ "public class X {\n" +
+ " java.util.List<@A String> field;\n" +
+ "}",
+ },
+ "");
+ // javac-b81: Bytes:10[0 1 19 1 3 0 0 9 0 0]
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @A(\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test034_field() throws Exception {
this.runConformTest(
new String[] {
"A.java",
@@ -1262,69 +1289,127 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"@interface B {\n" +
" int value() default -1;\n" +
"}",
- "C.java",
- "import java.lang.annotation.Target;\n" +
- "import static java.lang.annotation.ElementType.*;\n" +
- "import java.lang.annotation.Retention;\n" +
- "import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
- "@Retention(RUNTIME)\n" +
- "@interface C {\n" +
- " char value() default '-';\n" +
- "}\n",
"X.java",
"public class X {\n" +
- " <T, U> X(T t, U u) {\n" +
- " }\n" +
- " public Object foo() {\n" +
- " X x = new <@A Integer, @A String @C [] @B(1)[]>X(null, null);\n" +
- " return x;\n" +
- " }\n" +
+ " @B(3) @A int field;\n" +
"}",
},
"");
String expectedOutput =
" RuntimeVisibleTypeAnnotations: \n" +
- " #33 @A(\n" +
- " target type = 0x18 TYPE_ARGUMENT_CONSTRUCTOR_CALL\n" +
- " offset = 6\n" +
- " type argument index = 0\n" +
- " )\n" +
- " #33 @A(\n" +
- " target type = 0x19 TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY\n" +
- " offset = 6\n" +
- " type argument index = 1\n" +
- " locations = {1}\n" +
- " )\n" +
- " #34 @C(\n" +
- " target type = 0x18 TYPE_ARGUMENT_CONSTRUCTOR_CALL\n" +
- " offset = 6\n" +
- " type argument index = 1\n" +
+ " #12 @A(\n" +
+ " target type = 0x13 FIELD\n" +
" )\n" +
" RuntimeInvisibleTypeAnnotations: \n" +
- " #29 @B(\n" +
- " #30 value=(int) 1 (constant type)\n" +
- " target type = 0x19 TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY\n" +
- " offset = 6\n" +
- " type argument index = 1\n" +
- " locations = {0}\n" +
+ " #8 @B(\n" +
+ " #9 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // type argument method call
- public void test025() throws Exception {
+
+ public void test035_field() throws Exception {
this.runConformTest(
new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {}\n",
+
"X.java",
- "public class X {\n" +
- "\n" +
- " static <T, U> T foo(T t, U u) {\n" +
- " return t;\n" +
- " }\n" +
- " public static void main(String[] args) {\n" +
- " System.out.println(X.<@A @B(1) String[], @C('-') X>foo(new String[]{\"SUCCESS\"}, null)[0]);\n" +
- " }\n" +
+ "public class X {\n" +
+ " java.util.Map<String, @A String> field;\n" +
+ "}",
+ },
+ "");
+ // javac-b81: Bytes:10[0 1 19 1 3 1 0 9 0 0]
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @A(\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(1)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test036_field() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {}\n",
+
+ "X.java",
+ "public class X {\n" +
+ " java.util.List<String[][]@A[][]> field;\n" +
+ "}",
+ },
+ "");
+ // javac-b81: Bytes:14[0 1 19 3 3 0 0 0 0 0 0 9 0 0]
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @A(\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test037_field() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " java.util.List<? extends @A Number> field;\n" +
+ "}",
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {}\n",
+ },
+ "");
+ // javac-b81: Bytes:12[0 1 19 2 3 0 2 0 0 9 0 0]
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @A(\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(0), WILDCARD]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test038_field() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class AA { class BB<T> {}}" +
+ "class X {\n" +
+ " AA.@A BB field;\n" +
"}\n",
+
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A { }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @A(\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [INNER_TYPE]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test039_field() throws Exception {
+ this.runConformTest(
+ new String[] {
"A.java",
"import java.lang.annotation.Target;\n" +
"import static java.lang.annotation.ElementType.*;\n" +
@@ -1345,42 +1430,28 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"@interface B {\n" +
" int value() default -1;\n" +
"}",
- "C.java",
- "import java.lang.annotation.Target;\n" +
- "import static java.lang.annotation.ElementType.*;\n" +
- "import java.lang.annotation.Retention;\n" +
- "import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
- "@Retention(RUNTIME)\n" +
- "@interface C {\n" +
- " char value() default '-';\n" +
- "}\n",
+ "X.java",
+ "public class X {\n" +
+ " @A int [] @B(3) [] field;\n" +
+ "}",
},
- "SUCCESS");
+ "");
String expectedOutput =
" RuntimeVisibleTypeAnnotations: \n" +
- " #52 @A(\n" +
- " target type = 0x1a TYPE_ARGUMENT_METHOD_CALL\n" +
- " offset = 13\n" +
- " type argument index = 0\n" +
- " )\n" +
- " #53 @C(\n" +
- " #49 value=\'-\' (constant type)\n" +
- " target type = 0x1a TYPE_ARGUMENT_METHOD_CALL\n" +
- " offset = 13\n" +
- " type argument index = 1\n" +
+ " #12 @A(\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY]\n" +
" )\n" +
" RuntimeInvisibleTypeAnnotations: \n" +
- " #48 @B(\n" +
- " #49 value=(int) 1 (constant type)\n" +
- " target type = 0x1a TYPE_ARGUMENT_METHOD_CALL\n" +
- " offset = 13\n" +
- " type argument index = 0\n" +
+ " #8 @B(\n" +
+ " #9 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY]\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // check locations
- public void test026() throws Exception {
+
+ public void test040_field_complex() throws Exception {
this.runConformTest(
new String[] {
"X.java",
@@ -1478,20 +1549,20 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
" java.lang.String[][][] field;\n" +
" RuntimeVisibleTypeAnnotations: \n" +
" #11 @H(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {2}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY, ARRAY]\n" +
" )\n" +
" #12 @F(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {0}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY]\n" +
" )\n" +
" RuntimeInvisibleTypeAnnotations: \n" +
" #8 @E(\n" +
- " target type = 0xe FIELD\n" +
+ " target type = 0x13 FIELD\n" +
" )\n" +
" #9 @G(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {1}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY]\n" +
" )\n" +
" \n" +
" // Field descriptor #14 Ljava/util/Map;\n" +
@@ -1499,20 +1570,20 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
" java.util.Map field2;\n" +
" RuntimeVisibleTypeAnnotations: \n" +
" #18 @A(\n" +
- " target type = 0xe FIELD\n" +
+ " target type = 0x13 FIELD\n" +
" )\n" +
" #19 @C(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {1}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(1)]\n" +
" )\n" +
" #20 @D(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {1,0}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(1), TYPE_ARGUMENT(0)]\n" +
" )\n" +
" RuntimeInvisibleTypeAnnotations: \n" +
" #17 @B(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {0}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
" )\n" +
" \n" +
" // Field descriptor #14 Ljava/util/Map;\n" +
@@ -1520,38 +1591,38 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
" java.util.Map field3;\n" +
" RuntimeVisibleTypeAnnotations: \n" +
" #18 @A(\n" +
- " target type = 0xe FIELD\n" +
+ " target type = 0x13 FIELD\n" +
" )\n" +
" #11 @H(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {1,2}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(1), ARRAY, ARRAY, ARRAY]\n" +
" )\n" +
" #12 @F(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {1,0}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(1), ARRAY]\n" +
" )\n" +
" RuntimeInvisibleTypeAnnotations: \n" +
" #17 @B(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {0}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
" )\n" +
" #8 @E(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {1}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(1)]\n" +
" )\n" +
" #9 @G(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {1,1}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(1), ARRAY, ARRAY]\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // check locations
- public void test027() throws Exception {
+
+ public void test041_field() throws Exception {
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
- " @H java.lang.String @E[] @F[] @G[] field;\n" +
+ " java.lang.@H String @E[] @F[] @G[] field;\n" +
"}",
"E.java",
"import java.lang.annotation.Target;\n" +
@@ -1598,25 +1669,67 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
String expectedOutput =
" RuntimeVisibleTypeAnnotations: \n" +
" #11 @H(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {2}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY, ARRAY]\n" +
" )\n" +
" #12 @F(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {0}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY]\n" +
" )\n" +
" RuntimeInvisibleTypeAnnotations: \n" +
" #8 @E(\n" +
- " target type = 0xe FIELD\n" +
+ " target type = 0x13 FIELD\n" +
" )\n" +
" #9 @G(\n" +
- " target type = 0xf FIELD_GENERIC_OR_ARRAY\n" +
- " locations = {1}\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY]\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // cast
- public void test028() throws Exception {
+
+ public void test042_methodReturnType() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ "X.java",
+ "public class X {\n" +
+ " @B(3) @A(value=\"test\") int foo() {\n" +
+ " return 1;\n" +
+ " }\n" +
+ "}",
+ },
+ "");
+ // javac-b81:
+ // Bytes:13[0 1 20 0 0 11 0 1 0 12 115 0 13]
+ // Bytes:13[0 1 20 0 0 15 0 1 0 12 73 0 16]
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #21 @A(\n" +
+ " #18 value=\"test\" (constant type)\n" +
+ " target type = 0x14 METHOD_RETURN\n" +
+ " )\n" +
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #17 @B(\n" +
+ " #18 value=(int) 3 (constant type)\n" +
+ " target type = 0x14 METHOD_RETURN\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test043_methodReceiver() throws Exception {
this.runConformTest(
new String[] {
"A.java",
@@ -1639,56 +1752,130 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"@interface B {\n" +
" int value() default -1;\n" +
"}",
- "C.java",
+ "X.java",
+ "public class X {\n" +
+ " void foo(@B(3) X this) {}\n" +
+ "}",
+ },
+ "");
+ // javac-b81: Bytes:13[0 1 21 0 0 10 0 1 0 11 73 0 12]
+ String expectedOutput =
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #16 @B(\n" +
+ " #17 value=(int) 3 (constant type)\n" +
+ " target type = 0x15 METHOD_RECEIVER\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test044_methodReceiver() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<T> {\n" +
+ " void foo(X<@B(3) T> this) {}\n" +
+ "}",
+ "A.java",
"import java.lang.annotation.Target;\n" +
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
"@Target(TYPE_USE)\n" +
"@Retention(RUNTIME)\n" +
- "@interface C {\n" +
- " char value() default '-';\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
"}\n",
- "I.java",
- "interface I {}\n",
- "J.java",
- "interface J {}\n",
+ "B.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ },
+ "");
+ // javac-b81: Bytes:15[0 1 21 1 3 0 0 10 0 1 0 11 73 0 12]
+ String expectedOutput =
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #18 @B(\n" +
+ " #19 value=(int) 3 (constant type)\n" +
+ " target type = 0x15 METHOD_RECEIVER\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+
+ public void test045_methodParameter() throws Exception {
+ this.runConformTest(
+ new String[] {
"X.java",
"public class X {\n" +
- " public void foo(Object o) {\n" +
- " if (o instanceof String[][]) {\n" +
- " String[][] tab = (@C('_') @B(3) String[] @A[]) o;\n" +
- " System.out.println(tab.length);\n" +
- " }\n" +
- " System.out.println(o);\n" +
+ " int foo(@B(3) String s) {\n" +
+ " return s.length();\n" +
" }\n" +
"}",
+
+ "B.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
},
"");
+ // javac-b81: Bytes:14[0 1 22 0 0 0 11 0 1 0 12 73 0 13]
String expectedOutput =
- " RuntimeVisibleTypeAnnotations: \n" +
- " #41 @C(\n" +
- " #38 value=\'_\' (constant type)\n" +
- " target type = 0x1 TYPE_CAST_GENERIC_OR_ARRAY\n" +
- " offset = 8\n" +
- " locations = {1}\n" +
- " )\n" +
- " #43 @A(\n" +
- " target type = 0x1 TYPE_CAST_GENERIC_OR_ARRAY\n" +
- " offset = 8\n" +
- " locations = {0}\n" +
- " )\n" +
" RuntimeInvisibleTypeAnnotations: \n" +
- " #37 @B(\n" +
- " #38 value=(int) 3 (constant type)\n" +
- " target type = 0x1 TYPE_CAST_GENERIC_OR_ARRAY\n" +
- " offset = 8\n" +
- " locations = {1}\n" +
+ " #25 @B(\n" +
+ " #26 value=(int) 3 (constant type)\n" +
+ " target type = 0x16 METHOD_FORMAL_PARAMETER\n" +
+ " method parameter index = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test046_methodParameter() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " int foo(int i, double d, @B(3) String s) {\n" +
+ " return s.length();\n" +
+ " }\n" +
+ "}",
+
+ "B.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ },
+ "");
+ // javac-b81: Bytes:14[0 1 22 1 0 0 11 0 1 0 12 73 0 13]
+ String expectedOutput =
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #29 @B(\n" +
+ " #30 value=(int) 3 (constant type)\n" +
+ " target type = 0x16 METHOD_FORMAL_PARAMETER\n" +
+ " method parameter index = 2\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // qualified allocation expression with type arguments
- public void test029() throws Exception {
+
+ public void test047_methodParameterArray() throws Exception {
this.runConformTest(
new String[] {
"A.java",
@@ -1711,62 +1898,807 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"@interface B {\n" +
" int value() default -1;\n" +
"}",
+ "X.java",
+ "public class X {\n" +
+ " int foo(String @A [] @B(3) [] s) {\n" +
+ " return s.length;\n" +
+ " }\n" +
+ "}",
+ },
+ "");
+ // javac-b81:
+ // Bytes:9[0 1 22 0 0 0 11 0 0]
+ // Bytes:16[0 1 22 0 1 0 0 0 13 0 1 0 14 73 0 15]
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #23 @A(\n" +
+ " target type = 0x16 METHOD_FORMAL_PARAMETER\n" +
+ " method parameter index = 0\n" +
+ " )\n" +
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #19 @B(\n" +
+ " #20 value=(int) 3 (constant type)\n" +
+ " target type = 0x16 METHOD_FORMAL_PARAMETER\n" +
+ " method parameter index = 0\n" +
+ " location = [ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test048_throws() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n"+
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.*;\n"+
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
"C.java",
+ "import java.lang.annotation.*;\n"+
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface C {\n" +
+ " char value() default '-';\n" +
+ "}\n",
+ "E.java",
+ "class E extends RuntimeException {\n" +
+ " private static final long serialVersionUID = 1L;\n" +
+ "}\n",
+ "E1.java",
+ "class E1 extends RuntimeException {\n" +
+ " private static final long serialVersionUID = 1L;\n" +
+ "}\n",
+ "E2.java",
+ "class E2 extends RuntimeException {\n" +
+ " private static final long serialVersionUID = 1L;\n" +
+ "}\n",
+ "X.java",
+ "public class X {\n" +
+ " void foo() throws @A(\"Hello, World!\") E, E1, @B @C('(') E2 {}\n" +
+ "}",
+ },
+ "");
+ // javac-b81:
+ // Bytes:28[0 2 23 0 0 0 0 14 0 1 0 15 115 0 16 23 0 2 0 0 17 0 1 0 15 67 0 18]
+ // Bytes:10[0 1 23 0 2 0 0 20 0 0]
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #25 @A(\n" +
+ " #26 value=\"Hello, World!\" (constant type)\n" +
+ " target type = 0x17 THROWS\n" +
+ " throws index = 0\n" +
+ " )\n" +
+ " #28 @C(\n" +
+ " #26 value=\'(\' (constant type)\n" +
+ " target type = 0x17 THROWS\n" +
+ " throws index = 2\n" +
+ " )\n" +
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #23 @B(\n" +
+ " target type = 0x17 THROWS\n" +
+ " throws index = 2\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+
+ public void test049_codeblocks_localVariable() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.lang.annotation.Target;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " @B int j = 9;\n" +
+ " try {\n" +
+ " System.out.print(\"SUCCESS\" + j);\n" +
+ " } catch(@A Exception e) {\n" +
+ " }\n" +
+ " @B int k = 3;\n" +
+ " System.out.println(k);\n" +
+ " }\n" +
+ "}",
+ "A.java",
"import java.lang.annotation.Target;\n" +
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
"@Target(TYPE_USE)\n" +
"@Retention(RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(CLASS)\n" +
+ "@interface B {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ },
+ "SUCCESS93");
+ String expectedOutput =
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #56 @B(\n" +
+ " target type = 0x40 LOCAL_VARIABLE\n" +
+ " local variable entries:\n" +
+ " [pc: 3, pc: 39] index: 1\n" +
+ " )\n" +
+ " #56 @B(\n" +
+ " target type = 0x40 LOCAL_VARIABLE\n" +
+ " local variable entries:\n" +
+ " [pc: 31, pc: 39] index: 2\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test050_codeblocks_localVariable() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ "C.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
"@interface C {\n" +
" char value() default '-';\n" +
"}\n",
- "D.java",
+ "X.java",
+ "public class X {\n" +
+ " String[][] bar() {\n" +
+ " return new String[][] {};" +
+ " }\n" +
+ " void foo(String s) {\n" +
+ " @C int i;\n" +
+ " @A String [] @B(3)[] tab = bar();\n" +
+ " if (tab != null) {\n" +
+ " i = 0;\n" +
+ " System.out.println(i + tab.length);\n" +
+ " } else {\n" +
+ " System.out.println(tab.length);\n" +
+ " }\n" +
+ " i = 4;\n" +
+ " System.out.println(-i + tab.length);\n" +
+ " }\n" +
+ "}",
+ },
+ "");
+ // javac-b81:
+ // Bytes:34[0 2 64 0 1 0 34 0 12 0 2 0 0 19 0 0 64 0 1 0 5 0 41 0 3 2 0 0 0 0 0 20 0 0]
+ // Bytes:23[0 1 64 0 1 0 5 0 41 0 3 1 0 0 0 22 0 1 0 23 73 0 24]
+ // ECJ data varies a little here as it is splitting the range
+ String expectedOutput =
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #45 @B(\n" +
+ " #46 value=(int) 3 (constant type)\n" +
+ " target type = 0x40 LOCAL_VARIABLE\n" +
+ " local variable entries:\n" +
+ " [pc: 5, pc: 46] index: 3\n" +
+ " location = [ARRAY]\n" +
+ " )\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #49 @C(\n" +
+ " target type = 0x40 LOCAL_VARIABLE\n" +
+ " local variable entries:\n" +
+ " [pc: 11, pc: 24] index: 2\n" +
+ " [pc: 34, pc: 46] index: 2\n" +
+ " )\n" +
+ " #50 @A(\n" +
+ " target type = 0x40 LOCAL_VARIABLE\n" +
+ " local variable entries:\n" +
+ " [pc: 5, pc: 46] index: 3\n" +
+ " location = [ARRAY, ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test051_codeblocks_resourceVariable() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ "X.java",
+ "import java.io.*;\n"+
+ "public class X {\n" +
+ " public static void main(String[] argv) throws Exception {\n"+
+ " try (@A BufferedReader br1 = new BufferedReader(new FileReader(\"a\"));\n"+
+ " @B(99) BufferedReader br2 = new BufferedReader(new FileReader(\"b\"))) {\n"+
+ " System.out.println(br1.readLine()+br2.readLine());\n" +
+ " }\n" +
+ " }\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #81 @B(\n" +
+ " #82 value=(int) 99 (constant type)\n" +
+ " target type = 0x41 RESOURCE_VARIABLE\n" +
+ " local variable entries:\n" +
+ " [pc: 39, pc: 94] index: 4\n" +
+ " )\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #85 @A(\n" +
+ " target type = 0x41 RESOURCE_VARIABLE\n" +
+ " local variable entries:\n" +
+ " [pc: 21, pc: 135] index: 3\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void _test052_codeblocks_exceptionParameter() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.lang.annotation.*;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " Exception test = new Exception() {\n" +
+ " private static final long serialVersionUID = 1L;\n" +
+ " @Override\n" +
+ " public String toString() {\n" +
+ " return \"SUCCESS\";\n" +
+ " }\n" +
+ " };\n" +
+ " try {\n" +
+ " System.out.println(test);\n" +
+ " } catch(@A Exception e) {\n" +
+ " e.printStackTrace();\n" +
+ " }\n" +
+ " }\n" +
+ "}",
+
+ "A.java",
"import java.lang.annotation.Target;\n" +
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
"@Target(TYPE_USE)\n" +
"@Retention(RUNTIME)\n" +
- "@interface D {\n" +
- " char value() default '-';\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
"}\n",
+ },
+ "SUCCESS");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #44 @A(\n" +
+ " target type = 0x42 EXCEPTION_PARAMETER\n" +
+ " exception table index = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void _test053_codeblocks_exceptionParameter() throws Exception {
+ this.runConformTest(
+ new String[] {
"X.java",
+ "import java.lang.annotation.Target;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
"public class X {\n" +
- " class Y {\n" +
- " <T, U> Y(T t, U u) {}\n" +
+ " public static void main(String[] args) {\n" +
+ " @A Exception test = new Exception() {\n" +
+ " private static final long serialVersionUID = 1L;\n" +
+ " @Override\n" +
+ " public String toString() {\n" +
+ " return \"SUCCESS\";\n" +
+ " }\n" +
+ " };\n" +
+ " try {\n" +
+ " System.out.println(test);\n" +
+ " } catch(@A Exception e) {\n" +
+ " e.printStackTrace();\n" +
+ " }\n" +
" }\n" +
+ "}",
+ "A.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ },
+ "SUCCESS");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #44 @A(\n" +
+ " target type = 0x40 LOCAL_VARIABLE\n" +
+ " local variable entries:\n" +
+ " [pc: 8, pc: 24] index: 1\n" +
+ " )\n" +
+ " #44 @A(\n" +
+ " target type = 0x42 EXCEPTION_PARAMETER\n" +
+ " exception table index = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void _test054_codeblocks_exceptionParameter() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.lang.annotation.Target;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "public class X {\n" +
" public static void main(String[] args) {\n" +
- " Y y = new X().new <@D() @A(value = \"hello\") String, @B X> Y(\"SUCCESS\", null);\n" +
- " System.out.println(y);\n" +
+ " try {\n" +
+ " System.out.println(42);\n" +
+ " } catch(@B(1) RuntimeException e) {\n" +
+ " e.printStackTrace();\n" +
+ " } catch(@B(2) Throwable t) {\n" +
+ " t.printStackTrace();\n" +
+ " }\n" +
" }\n" +
"}",
+ "B.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(RUNTIME)\n" +
+ "@interface B {\n" +
+ " int value() default 99;\n" +
+ "}\n",
},
- "");
+ "42");
String expectedOutput =
" RuntimeVisibleTypeAnnotations: \n" +
- " #47 @D(\n" +
- " target type = 0x18 TYPE_ARGUMENT_CONSTRUCTOR_CALL\n" +
- " offset = 19\n" +
- " type argument index = 0\n" +
+ " #44 @B(\n" +
+ " #45 value=(int) 1 (constant type)\n" +
+ " target type = 0x42 EXCEPTION_PARAMETER\n" +
+ " exception table index = 0\n" +
" )\n" +
- " #48 @A(\n" +
- " #49 value=\"hello\" (constant type)\n" +
- " target type = 0x18 TYPE_ARGUMENT_CONSTRUCTOR_CALL\n" +
- " offset = 19\n" +
- " type argument index = 0\n" +
+ " #44 @B(\n" +
+ " #45 value=(int) 2 (constant type)\n" +
+ " target type = 0x42 EXCEPTION_PARAMETER\n" +
+ " exception table index = 1\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void _test055_codeblocks_exceptionParameterMultiCatch() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.lang.annotation.Target;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "class Exc1 extends RuntimeException {" +
+ " private static final long serialVersionUID = 1L;\n" +
+ "}\n"+
+ "class Exc2 extends RuntimeException {" +
+ " private static final long serialVersionUID = 1L;\n" +
+ "}\n"+
+ "class Exc3 extends RuntimeException {" +
+ " private static final long serialVersionUID = 1L;\n" +
+ "}\n"+
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " try {\n" +
+ " System.out.println(42);\n" +
+ // @B(1) is attached to the argument, the others are attached to the type reference in the union type reference
+ // During Parsing the @B(1) is moved from the argument to Exc1
+ " } catch(@B(1) Exc1 | Exc2 | @B(2) Exc3 t) {\n" +
+ " t.printStackTrace();\n" +
+ " }\n" +
+ " }\n" +
+ "}",
+ "B.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(RUNTIME)\n" +
+ "@interface B {\n" +
+ " int value() default 99;\n" +
+ "}\n",
+ },
+ "42");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #45 @B(\n" +
+ " #46 value=(int) 1 (constant type)\n" +
+ " target type = 0x42 EXCEPTION_PARAMETER\n" +
+ " exception table index = 0\n" +
" )\n" +
- " RuntimeInvisibleTypeAnnotations: \n" +
" #45 @B(\n" +
- " target type = 0x18 TYPE_ARGUMENT_CONSTRUCTOR_CALL\n" +
- " offset = 19\n" +
- " type argument index = 1\n" +
+ " #46 value=(int) 2 (constant type)\n" +
+ " target type = 0x42 EXCEPTION_PARAMETER\n" +
+ " exception table index = 2\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test056_codeblocks_instanceof() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public void foo(Object o) {\n" +
+ " if (o instanceof @A String) {\n" +
+ " String tab = (String) o;\n" +
+ " System.out.println(tab);\n" +
+ " }\n" +
+ " System.out.println(o);\n" +
+ " }\n" +
+ "}",
+
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #38 @A(\n" +
+ " target type = 0x43 INSTANCEOF\n" +
+ " offset = 1\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+
+ expectedOutput = " 1 instanceof java.lang.String [16]\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test057_codeblocks_new() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ "C.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface C {\n" +
+ " char value() default '-';\n" +
+ "}\n",
+ "I.java",
+ "interface I {}\n",
+ "J.java",
+ "interface J {}\n",
+ "X.java",
+ "public class X {\n" +
+ " public boolean foo(String s) {\n" +
+ " System.out.println(\"xyz\");\n" +
+ " Object o = new @B(3) Object();\n" +
+ " return true;\n" +
+ " }\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #35 @B(\n" +
+ " #36 value=(int) 3 (constant type)\n" +
+ " target type = 0x44 NEW\n" +
+ " offset = 8\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // local + wildcard
- // qualified allocation expression with type arguments
- public void test030() throws Exception {
+
+ public void test058_codeblocks_new2() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+
+ "X.java",
+ "public class X {\n" +
+ " public void foo() {\n" +
+ " Outer o = new Outer();\n" +
+ " o.new @B(1) Inner();\n" +
+ " }\n" +
+ "}\n" +
+ "class Outer { class Inner {}}\n"
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #30 @B(\n" +
+ " #31 value=(int) 1 (constant type)\n" +
+ " target type = 0x44 NEW\n" +
+ " offset = 8\n" +
+ " location = [INNER_TYPE]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test059_codeblocks_new_newArray() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ "C.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface C {\n" +
+ " char value() default '-';\n" +
+ "}\n",
+ "I.java",
+ "interface I {}\n",
+ "J.java",
+ "interface J {}\n",
+ "X.java",
+ "public class X {\n" +
+ " public boolean foo(String s) {\n" +
+ " System.out.println(\"xyz\");\n" +
+ " Object o = new @A String [1];\n" +
+ " return true;\n" +
+ " }\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #37 @A(\n" +
+ " target type = 0x44 NEW\n" +
+ " offset = 9\n" +
+ " location = [ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test060_codeblocks_new_multiNewArray() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "X.java",
+ "public class X {\n" +
+ " public boolean foo(String s) {\n" +
+ " System.out.println(\"xyz\");\n" +
+ " Object o = new @A String [2][3];\n" +
+ " return true;\n" +
+ " }\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #37 @A(\n" +
+ " target type = 0x44 NEW\n" +
+ " offset = 10\n" +
+ " location = [ARRAY, ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test061_codeblocks_new_newArrayWithInitializer() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ "C.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface C {\n" +
+ " char value() default '-';\n" +
+ "}\n",
+ "I.java",
+ "interface I {}\n",
+ "J.java",
+ "interface J {}\n",
+ "X.java",
+ "public class X {\n" +
+ " public boolean foo(String s) {\n" +
+ " System.out.println(\"xyz\");\n" +
+ " Object o = new @A String []{\"xyz\"};\n" +
+ " return true;\n" +
+ " }\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #37 @A(\n" +
+ " target type = 0x44 NEW\n" +
+ " offset = 9\n" +
+ " location = [ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test062_codeblocks_newArray() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ "C.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface C {\n" +
+ " char value() default '-';\n" +
+ "}\n",
+ "I.java",
+ "interface I {}\n",
+ "J.java",
+ "interface J {}\n",
+ "X.java",
+ "public class X {\n" +
+ " public boolean foo(String s) {\n" +
+ " System.out.println(\"xyz\");\n" +
+ " Object o = new String @A[1];\n" +
+ " return true;\n" +
+ " }\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #37 @A(\n" +
+ " target type = 0x44 NEW\n" +
+ " offset = 9\n" +
+ // no type path expected here
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test062_codeblocks_newArrayWithInitializer() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ "C.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface C {\n" +
+ " char value() default '-';\n" +
+ "}\n",
+ "I.java",
+ "interface I {}\n",
+ "J.java",
+ "interface J {}\n",
+ "X.java",
+ "public class X {\n" +
+ " public boolean foo(String s) {\n" +
+ " System.out.println(\"xyz\");\n" +
+ " Object o = new String @A[] { \"Hello\" };\n" +
+ " return true;\n" +
+ " }\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #39 @A(\n" +
+ " target type = 0x44 NEW\n" +
+ " offset = 9\n" +
+ // no type path expected here
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test063_codeblocks_new_instanceof() throws Exception {
this.runConformTest(
new String[] {
"A.java",
@@ -1799,75 +2731,336 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"@interface C {\n" +
" char value() default '-';\n" +
"}\n",
- "D.java",
+ "I.java",
+ "interface I {}\n",
+ "J.java",
+ "interface J {}\n",
+ "X.java",
+ "public class X {\n" +
+ " public boolean foo(Object o) {\n" +
+ " boolean b = (o instanceof @C('_') Object[]);\n" +
+ " Object o1 = new @B(3) @A(\"new Object\") Object[] {};\n" +
+ " return b;\n" +
+ " }\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #24 @B(\n" +
+ " #25 value=(int) 3 (constant type)\n" +
+ " target type = 0x44 NEW\n" +
+ " offset = 6\n" +
+ " location = [ARRAY]\n" +
+ " )\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #28 @C(\n" +
+ " #25 value=\'_\' (constant type)\n" +
+ " target type = 0x43 INSTANCEOF\n" +
+ " offset = 1\n" +
+ " location = [ARRAY]\n" +
+ " )\n" +
+ " #30 @A(\n" +
+ " #25 value=\"new Object\" (constant type)\n" +
+ " target type = 0x44 NEW\n" +
+ " offset = 6\n" +
+ " location = [ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+
+ public void test064_codeblocks_constructorReference() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.*;\n" +
+ "interface MR { X process(String input); }\n"+
+ "public class X<T> {\n" +
+ " public X(T t) {}\n" +
+ " public static <T> String foo(String bar) { return bar; }\n"+
+ " public void bar() {\n" +
+ " System.out.println(\"abc\");\n" +
+ " MR ref = @A X::new;\n" +
+ " }\n" +
+ "}",
+
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #48 @A(\n" +
+ " target type = 0x45 CONSTRUCTOR_REFERENCE\n" +
+ " offset = 8\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+
+ public void test065_codeblocks_methodReference() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.*;\n" +
+ "interface MR { String process(String input); }\n"+
+ "public class X<T> {\n" +
+ " public static <T> String foo(String bar) { return bar; }\n"+
+ " public void bar() {\n" +
+ " System.out.println(\"abc\");\n" +
+ " MR ref = @A X::foo;\n" +
+ " ref.process(\"abc\");\n" +
+ " }\n" +
+ "}",
+
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #48 @A(\n" +
+ " target type = 0x46 METHOD_REFERENCE\n" +
+ " offset = 8\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test066_codeblocks_methodReference() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface I {\n" +
+ " Object copy(int [] ia);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String [] args) {\n" +
+ " I i = @B(1) int @B(2)[]::<String>clone;\n" +
+ " i.copy(new int[10]); \n" +
+ " }\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #31 @B(\n" +
+ " #32 value=(int) 1 (constant type)\n" +
+ " target type = 0x46 METHOD_REFERENCE\n" +
+ " offset = 0\n" +
+ " location = [ARRAY]\n" +
+ " )\n" +
+ " #31 @B(\n" +
+ " #32 value=(int) 2 (constant type)\n" +
+ " target type = 0x46 METHOD_REFERENCE\n" +
+ " offset = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test067_codeblocks_constructorReferenceTypeArgument() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.*;\n" +
+ "interface MR { X process(String input); }\n" +
+ "public class X<T> {\n" +
+ " public X(T s) {};\n" +
+ " public static <T> String foo(String bar) { return bar; }\n"+
+ " public void bar() {\n" +
+ " System.out.println(\"abc\");\n" +
+ " MR ref = X::<@A String>new;\n" +
+ " ref.process(\"abc\");\n" +
+ " }\n" +
+ "}",
+
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #54 @A(\n" +
+ " target type = 0x4a CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT\n" +
+ " offset = 8\n" +
+ " type argument index = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test068_codeblocks_methodReferenceTypeArgument() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.*;\n" +
+ "interface MR { String process(String input); }\n"+
+ "public class X<T> {\n" +
+ " public static <T> String foo(String bar) { return bar; }\n"+
+ " public void bar() {\n" +
+ " System.out.println(\"abc\");\n" +
+ " MR ref = X::<@A String>foo;\n" +
+ " ref.process(\"abc\");\n" +
+ " }\n" +
+ "}",
+
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #48 @A(\n" +
+ " target type = 0x4b METHOD_REFERENCE_TYPE_ARGUMENT\n" +
+ " offset = 8\n" +
+ " type argument index = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test069_codeblocks_cast() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public void foo(Object o) {\n" +
+ " if (o instanceof String) {\n" +
+ " String tab = (@A String) o;\n" +
+ " System.out.println(tab);\n" +
+ " }\n" +
+ " System.out.println(o);\n" +
+ " }\n" +
+ "}",
+
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+
+ },
+ "");
+ // javac-b81: Bytes:11[0 1 71 0 7 0 0 0 16 0 0]
+ // relevant numbers '71 0 7 0' which mean 0x47 (CAST) at offset 7
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #38 @A(\n" +
+ " target type = 0x47 CAST\n" +
+ " offset = 8\n" +
+ " type argument index = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test070_codeblocks_cast_complex() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(CLASS)\n" +
+ "@interface B {\n" +
+ " int value() default -1;\n" +
+ "}",
+ "C.java",
"import java.lang.annotation.Target;\n" +
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
"@Target(TYPE_USE)\n" +
"@Retention(RUNTIME)\n" +
- "@interface D {\n" +
+ "@interface C {\n" +
" char value() default '-';\n" +
"}\n",
+ "I.java",
+ "interface I {}\n",
+ "J.java",
+ "interface J {}\n",
"X.java",
- "import java.util.Map;\n" +
- "import java.util.HashMap;\n" +
- "@SuppressWarnings({\"unchecked\",\"rawtypes\"})\n" +
"public class X {\n" +
- " Object newMap(Object o) {\n" +
- " Map<@A Object, ? super @C Map<@B String, @D Comparable>> map;\n" +
- " if (o == null) {\n" +
- " map = null;\n" +
- " System.out.println(map);\n" +
- " } else {\n" +
- " System.out.println(\"No map yet\");\n" +
+ " public void foo(Object o) {\n" +
+ " if (o instanceof String[][]) {\n" +
+ " String[][] tab = (@C('_') @B(3) String[] @A[]) o;\n" +
+ " System.out.println(tab.length);\n" +
" }\n" +
- " map = new HashMap();\n" +
- " return map;\n" +
- " } \n" +
+ " System.out.println(o);\n" +
+ " }\n" +
"}",
},
"");
+ // javac-b81:
+ // Bytes:31[0 2 71 0 7 0 1 0 0 0 16 0 0 71 0 7 0 2 0 0 0 0 0 17 0 1 0 18 67 0 19]
+ // Bytes:20[0 1 71 0 7 0 2 0 0 0 0 0 21 0 1 0 18 73 0 22]
String expectedOutput =
- " RuntimeVisibleTypeAnnotations: \n" +
- " #46 @A(\n" +
- " target type = 0x9 LOCAL_VARIABLE_GENERIC_OR_ARRAY\n" +
- " local variable entries:\n" +
- " [pc: 6, pc: 16] index: 2\n" +
- " [pc: 32, pc: 34] index: 2\n" +
- " locations = {0}\n" +
- " )\n" +
- " #47 @C(\n" +
- " target type = 0x1c WILDCARD_BOUND\n" +
- " wildcard location type = 0x9 LOCAL_VARIABLE_GENERIC_OR_ARRAY\n" +
- " local variable entries:\n" +
- " [pc: 6, pc: 16] index: 2\n" +
- " [pc: 32, pc: 34] index: 2\n" +
- " wildcard locations = {1}\n" +
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #37 @B(\n" +
+ " #38 value=(int) 3 (constant type)\n" +
+ " target type = 0x47 CAST\n" +
+ " offset = 8\n" +
+ " type argument index = 0\n" +
+ " location = [ARRAY, ARRAY]\n" +
" )\n" +
- " #48 @D(\n" +
- " target type = 0x1d WILDCARD_BOUND_GENERIC_OR_ARRAY\n" +
- " wildcard location type = 0x9 LOCAL_VARIABLE_GENERIC_OR_ARRAY\n" +
- " local variable entries:\n" +
- " [pc: 6, pc: 16] index: 2\n" +
- " [pc: 32, pc: 34] index: 2\n" +
- " wildcard locations = {1}\n" +
- " locations = {1}\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #41 @C(\n" +
+ " #38 value=\'_\' (constant type)\n" +
+ " target type = 0x47 CAST\n" +
+ " offset = 8\n" +
+ " type argument index = 0\n" +
+ " location = [ARRAY, ARRAY]\n" +
" )\n" +
- " RuntimeInvisibleTypeAnnotations: \n" +
- " #44 @B(\n" +
- " target type = 0x1d WILDCARD_BOUND_GENERIC_OR_ARRAY\n" +
- " wildcard location type = 0x9 LOCAL_VARIABLE_GENERIC_OR_ARRAY\n" +
- " local variable entries:\n" +
- " [pc: 6, pc: 16] index: 2\n" +
- " [pc: 32, pc: 34] index: 2\n" +
- " wildcard locations = {1}\n" +
- " locations = {0}\n" +
+ " #43 @A(\n" +
+ " target type = 0x47 CAST\n" +
+ " offset = 8\n" +
+ " type argument index = 0\n" +
+ " location = [ARRAY]\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // method type parameter bound generic or array
- public void test031() throws Exception {
+
+ public void test071_codeblocks_constructorInvocationTypeArgument() throws Exception {
this.runConformTest(
new String[] {
"A.java",
@@ -1890,65 +3083,202 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"@interface B {\n" +
" int value() default -1;\n" +
"}",
- "C.java",
+ "X.java",
+ "public class X {\n" +
+ " <T> X(T t) {\n" +
+ " }\n" +
+ " public Object foo() {\n" +
+ " X x = new <@A @B(1) String>X(null);\n" +
+ " return x;\n" +
+ " }\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #27 @B(\n" +
+ " #28 value=(int) 1 (constant type)\n" +
+ " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 5\n" +
+ " type argument index = 0\n" +
+ " )\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #31 @A(\n" +
+ " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 5\n" +
+ " type argument index = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test072_codeblocks_constructorInvocationTypeArgument() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "A.java",
+ "import java.lang.annotation.Target;\n" +
+ "import static java.lang.annotation.ElementType.*;\n" +
+ "import java.lang.annotation.Retention;\n" +
+ "import static java.lang.annotation.RetentionPolicy.*;\n" +
+ "@Target(TYPE_USE)\n" +
+ "@Retention(RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+ "B.java",
"import java.lang.annotation.Target;\n" +
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
"@Target(TYPE_USE)\n" +
"@Retention(CLASS)\n" +
- "@interface C {\n" +
+ "@interface B {\n" +
" int value() default -1;\n" +
"}",
- "D.java",
+ "C.java",
"import java.lang.annotation.Target;\n" +
"import static java.lang.annotation.ElementType.*;\n" +
"import java.lang.annotation.Retention;\n" +
"import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_PARAMETER)\n" +
+ "@Target(TYPE_USE)\n" +
"@Retention(RUNTIME)\n" +
- "@interface D {\n" +
- " String value() default \"default\";\n" +
+ "@interface C {\n" +
+ " char value() default '-';\n" +
"}\n",
- "Z.java",
- "public class Z<T> {}",
"X.java",
- "public class X {\n" +
- " <@D U, T extends Z<@A String @C[][]@B[]> & @B(3) Cloneable> void foo(U u, T t) {}\n" +
+ "public class X {\n" +
+ " <T, U> X(T t, U u) {\n" +
+ " }\n" +
+ " public Object foo() {\n" +
+ " X x = new <@A Integer, @A String @C [] @B(1)[]>X(null, null);\n" +
+ " return x;\n" +
+ " }\n" +
"}",
},
"");
String expectedOutput =
- " RuntimeVisibleTypeAnnotations: \n" +
- " #31 @D(\n" +
- " target type = 0x20 METHOD_TYPE_PARAMETER\n" +
- " type parameter index = 0\n" +
- " )\n" +
- " #32 @A(\n" +
- " target type = 0x13 METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY\n" +
- " type parameter index = 1 type parameter bound index = 0\n" +
- " locations = {0,2}\n" +
- " )\n" +
" RuntimeInvisibleTypeAnnotations: \n" +
- " #26 @C(\n" +
- " target type = 0x13 METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY\n" +
- " type parameter index = 1 type parameter bound index = 0\n" +
- " locations = {0}\n" +
+ " #29 @B(\n" +
+ " #30 value=(int) 1 (constant type)\n" +
+ " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 6\n" +
+ " type argument index = 1\n" +
+ " location = [ARRAY]\n" +
" )\n" +
- " #27 @B(\n" +
- " target type = 0x13 METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY\n" +
- " type parameter index = 1 type parameter bound index = 0\n" +
- " locations = {0,1}\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #33 @A(\n" +
+ " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 6\n" +
+ " type argument index = 0\n" +
" )\n" +
- " #27 @B(\n" +
- " #28 value=(int) 3 (constant type)\n" +
- " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" +
- " type parameter index = 1 type parameter bound index = 1\n" +
+ " #33 @A(\n" +
+ " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 6\n" +
+ " type argument index = 1\n" +
+ " location = [ARRAY, ARRAY]\n" +
+ " )\n" +
+ " #34 @C(\n" +
+ " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 6\n" +
+ " type argument index = 1\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+ public void test073_codeblocks_constructorInvocationTypeArgument() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<T1, T2> {\n" +
+ " public void bar() {\n" +
+ " new <String, @A T2>X();\n"+
+ " }\n" +
+ "}",
+
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+
+ },
+ "");
+ // Example bytes:11[0 1 73 0 0 0 0 0 13 0 0] this would be for offset 0
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #19 @A(\n" +
+ " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 3\n" +
+ " type argument index = 1\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test074_codeblocks_constructorInvocationTypeArgument() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<T1,T2> {\n" +
+ " public static void foo(int i) {}\n"+
+ " public void bar() {\n" +
+ " new <java.util.List<@A String>, T2>X();\n"+
+ " }\n" +
+ "}",
+
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+
+ },
+ "");
+ // Example bytes:11[0 1 73 0 0 0 0 0 13 0 0] this would be for offset 0
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #23 @A(\n" +
+ " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 3\n" +
+ " type argument index = 0\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // type argument method call and generic or array
- public void test032() throws Exception {
+
+ public void test075_codeblocks_constructorInvocationTypeArgument() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<T> {\n" +
+ " public void bar() {\n" +
+ " new <@A T>X();\n"+
+ " }\n" +
+ "}",
+
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+
+ },
+ "");
+ // Example bytes:11[0 1 73 0 0 0 0 0 13 0 0] this would be for offset 0
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #19 @A(\n" +
+ " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 3\n" +
+ " type argument index = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test076_codeblocks_methodInvocationTypeArgument() throws Exception {
this.runConformTest(
new String[] {
"X.java",
@@ -1957,8 +3287,8 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
" static <T, U> T foo(T t, U u) {\n" +
" return t;\n" +
" }\n" +
- " public static void bar() {\n" +
- " System.out.println(X.<@A String[] @B(1) [], @C('-') X>foo(new String[][]{{\"SUCCESS\"}}, null)[0]);\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(X.<@A @B(1) String[], @C('-') X>foo(new String[]{\"SUCCESS\"}, null)[0]);\n" +
" }\n" +
"}\n",
"A.java",
@@ -1992,203 +3322,188 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
" char value() default '-';\n" +
"}\n",
},
- "");
+ "SUCCESS");
String expectedOutput =
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #48 @B(\n" +
+ " #49 value=(int) 1 (constant type)\n" +
+ " target type = 0x49 METHOD_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 13\n" +
+ " type argument index = 0\n" +
+ " location = [ARRAY]\n" +
+ " )\n" +
" RuntimeVisibleTypeAnnotations: \n" +
" #52 @A(\n" +
- " target type = 0x1b TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY\n" +
- " offset = 20\n" +
+ " target type = 0x49 METHOD_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 13\n" +
" type argument index = 0\n" +
- " locations = {1}\n" +
+ " location = [ARRAY]\n" +
" )\n" +
" #53 @C(\n" +
" #49 value=\'-\' (constant type)\n" +
- " target type = 0x1a TYPE_ARGUMENT_METHOD_CALL\n" +
- " offset = 20\n" +
+ " target type = 0x49 METHOD_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 13\n" +
" type argument index = 1\n" +
- " )\n" +
- " RuntimeInvisibleTypeAnnotations: \n" +
- " #48 @B(\n" +
- " #49 value=(int) 1 (constant type)\n" +
- " target type = 0x1b TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY\n" +
- " offset = 20\n" +
- " type argument index = 0\n" +
- " locations = {0}\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
-// // superclass
-// public void test033() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "Marker.java",
-// "@interface Marker {}",
-// "X.java",
-// "public class X extends @Marker Object {}",
-// },
-// "");
-// }
- // superclass
- public void test034() throws Exception {
- this.runNegativeTest(
+
+ public void test077_codeblocks_methodInvocationTypeArgument() throws Exception {
+ this.runConformTest(
new String[] {
- "Marker.java",
- "import java.lang.annotation.Target;\n" +
- "import static java.lang.annotation.ElementType.*;\n" +
- "@Target(TYPE_PARAMETER)\n" +
- "@interface Marker {}",
"X.java",
- "public class X extends @Marker Object {}",
- },
- "----------\n" +
- "1. ERROR in X.java (at line 1)\n" +
- " public class X extends @Marker Object {}\n" +
- " ^^^^^^^\n" +
- "The annotation @Marker is disallowed for this location\n" +
- "----------\n");
- }
-// // annotation on catch variable
-// public void test035() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "X.java",
-// "import java.lang.annotation.Target;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "public class X {\n" +
-// " public static void main(String[] args) {\n" +
-// " @A Exception test = new Exception() {\n" +
-// " private static final long serialVersionUID = 1L;\n" +
-// " @Override\n" +
-// " public String toString() {\n" +
-// " return \"SUCCESS\";\n" +
-// " }\n" +
-// " };\n" +
-// " try {\n" +
-// " System.out.println(test);\n" +
-// " } catch(@A Exception e) {\n" +
-// " e.printStackTrace();\n" +
-// " }\n" +
-// " }\n" +
-// "}",
-// "A.java",
-// "import java.lang.annotation.Target;\n" +
-// "import static java.lang.annotation.ElementType.*;\n" +
-// "import java.lang.annotation.Retention;\n" +
-// "import static java.lang.annotation.RetentionPolicy.*;\n" +
-// "@Target(TYPE_USE)\n" +
-// "@Retention(RUNTIME)\n" +
-// "@interface A {\n" +
-// " String value() default \"default\";\n" +
-// "}\n",
-// },
-// "SUCCESS");
-// String expectedOutput =
-// " RuntimeVisibleTypeAnnotations: \n" +
-// " #44 @A(\n" +
-// " target type = 0x8 LOCAL_VARIABLE\n" +
-// " local variable entries:\n" +
-// " [pc: 8, pc: 24] index: 1\n" +
-// " )\n" +
-// " #44 @A(\n" +
-// " target type = 0x8 LOCAL_VARIABLE\n" +
-// " local variable entries:\n" +
-// " [pc: 19, pc: 23] index: 2\n" +
-// " )\n";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
- // annotation on catch variable
- public void test036() throws Exception {
+ "public class X<T1,T2> {\n" +
+ " public static void foo(int i) {}\n"+
+ " public void bar() {\n" +
+ " X.<String, @A T2>foo(42);\n"+
+ " }\n" +
+ "}",
+
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+
+ },
+ "");
+ // Example bytes:11[0 1 73 0 0 0 0 0 13 0 0] this would be for offset 0
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #24 @A(\n" +
+ " target type = 0x49 METHOD_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 2\n" +
+ " type argument index = 1\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test078_codeblocks_methodInvocationTypeArgument() throws Exception {
this.runConformTest(
new String[] {
"X.java",
- "import java.lang.annotation.Target;\n" +
- "import java.lang.annotation.Retention;\n" +
- "import static java.lang.annotation.ElementType.*;\n" +
- "import static java.lang.annotation.RetentionPolicy.*;\n" +
- "public class X {\n" +
- " public static void main(String[] args) {\n" +
- " @B int j = 9;\n" +
- " try {\n" +
- " System.out.print(\"SUCCESS\" + j);\n" +
- " } catch(@A Exception e) {\n" +
- " }\n" +
- " @B int k = 3;\n" +
- " System.out.println(k);\n" +
+ "public class X<T1,T2> {\n" +
+ " public static void foo(int i) {}\n"+
+ " public void bar() {\n" +
+ " X.<java.util.List<@A String>, T2>foo(42);\n"+
" }\n" +
"}",
+
"A.java",
- "import java.lang.annotation.Target;\n" +
- "import static java.lang.annotation.ElementType.*;\n" +
- "import java.lang.annotation.Retention;\n" +
- "import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
- "@Retention(RUNTIME)\n" +
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface A {\n" +
+ " String value() default \"default\";\n" +
+ "}\n",
+
+ },
+ "");
+ // Example bytes:11[0 1 73 0 0 0 0 0 13 0 0] this would be for offset 0
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #24 @A(\n" +
+ " target type = 0x49 METHOD_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 2\n" +
+ " type argument index = 0\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test079_codeblocks_methodInvocationTypeArgument() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<T> {\n" +
+ " public static void foo(int i) {}\n"+
+ " public void bar() {\n" +
+ " X.<@A T>foo(42);\n"+
+ " }\n" +
+ "}",
+
+ "A.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
"@interface A {\n" +
" String value() default \"default\";\n" +
"}\n",
+ },
+ "");
+ // Example bytes:11[0 1 73 0 0 0 0 0 13 0 0] this would be for offset 0
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #24 @A(\n" +
+ " target type = 0x49 METHOD_INVOCATION_TYPE_ARGUMENT\n" +
+ " offset = 2\n" +
+ " type argument index = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+
+ // Annotation should appear twice in this case
+ public void test080_multiuseAnnotations() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " @B(1) int foo() { return 0; }\n" +
+ "}",
"B.java",
- "import java.lang.annotation.Target;\n" +
- "import static java.lang.annotation.ElementType.*;\n" +
- "import java.lang.annotation.Retention;\n" +
- "import static java.lang.annotation.RetentionPolicy.*;\n" +
- "@Target(TYPE_USE)\n" +
- "@Retention(CLASS)\n" +
+ "import java.lang.annotation.*;\n" +
+ "@Target({ElementType.METHOD, ElementType.TYPE_USE})\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
"@interface B {\n" +
- " String value() default \"default\";\n" +
+ " int value() default 99;\n" +
"}\n",
},
- "SUCCESS93");
+ "");
String expectedOutput =
- " RuntimeInvisibleTypeAnnotations: \n" +
- " #56 @B(\n" +
- " target type = 0x8 LOCAL_VARIABLE\n" +
- " local variable entries:\n" +
- " [pc: 3, pc: 39] index: 1\n" +
+ " RuntimeVisibleAnnotations: \n" +
+ " #17 @B(\n" +
+ " #18 value=(int) 1 (constant type)\n" +
" )\n" +
- " #56 @B(\n" +
- " target type = 0x8 LOCAL_VARIABLE\n" +
- " local variable entries:\n" +
- " [pc: 31, pc: 39] index: 2\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #17 @B(\n" +
+ " #18 value=(int) 1 (constant type)\n" +
+ " target type = 0x14 METHOD_RETURN\n" +
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // make sure annotation without target appears twice when set on a method declaration
- public void test037() throws Exception {
+
+ public void test081_multiuseAnnotations() throws Exception {
this.runConformTest(
new String[] {
"X.java",
- "import java.lang.annotation.Target;\r\n" +
- "import static java.lang.annotation.ElementType.*;\r\n" +
- "\r\n" +
- "@Target(METHOD)\r\n" +
- "@interface Annot {\r\n" +
- " int value() default 0;\r\n" +
- "}\r\n" +
- "public class X {\r\n" +
- " @Annot(4)\r\n" +
- " public void foo() {\r\n" +
- " }\r\n" +
+ "import java.lang.annotation.*;\n" +
+ "@Target({ElementType.METHOD, ElementType.TYPE_USE})\n" +
+ "@interface Annot {\n" +
+ " int value() default 0;\n" +
+ "}\n" +
+ "public class X {\n" +
+ " @Annot(4) public String foo() { return \"hello\"; }" +
"}",
},
"");
String expectedOutput =
- " public void foo();\n" +
- " 0 return\n" +
- " Line numbers:\n" +
- " [pc: 0, line: 11]\n" +
- " Local variable table:\n" +
- " [pc: 0, pc: 1] local: this index: 0 type: X\n" +
" RuntimeInvisibleAnnotations: \n" +
- " #16 @Annot(\n" +
- " #17 value=(int) 4 (constant type)\n" +
+ " #17 @Annot(\n" +
+ " #18 value=(int) 4 (constant type)\n" +
" )\n" +
- "}";
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #17 @Annot(\n" +
+ " #18 value=(int) 4 (constant type)\n" +
+ " target type = 0x14 METHOD_RETURN\n" +
+ " )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
- // make sure annotation without target appears twice when set on a method declaration
- public void test038() throws Exception {
+
+ // When not annotated with any TYPE it assumes the Java7 set (i.e. not TYPE_USE/TYPE_PARAMETER)
+ public void test082_multiuseAnnotations() throws Exception {
this.runConformTest(
new String[] {
"X.java",
@@ -2218,75 +3533,856 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
"}";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
-// // make sure annotation without target appears twice when set on a method declaration
-// public void test039() throws Exception {
-// this.runConformTest(
-// new String[] {
-// "X.java",
-// "@interface Annot {\r\n" +
-// " int value() default 0;\r\n" +
-// "}\r\n" +
-// "public class X {\r\n" +
-// " @Annot(4)\r\n" +
-// " public int foo() {\r\n" +
-// " return 0;\r\n" +
-// " }\r\n" +
-// "}",
-// },
-// "");
-// String expectedOutput =
-// " public int foo();\n" +
-// " 0 iconst_0\n" +
-// " 1 ireturn\n" +
-// " Line numbers:\n" +
-// " [pc: 0, line: 7]\n" +
-// " Local variable table:\n" +
-// " [pc: 0, pc: 2] local: this index: 0 type: X\n" +
-// " RuntimeInvisibleAnnotations: \n" +
-// " #17 @Annot(\n" +
-// " #18 value=(int) 4 (constant type)\n" +
-// " )\n" +
-// " RuntimeInvisibleTypeAnnotations: \n" +
-// " #17 @Annot(\n" +
-// " #18 value=(int) 4 (constant type)\n" +
-// " target type = 0xa METHOD_RETURN_TYPE\n" +
-// " )\n" +
-// "}";
-// checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
-// }
- // make sure annotation without target appears twice when set on a method declaration
- public void test040() throws Exception {
- this.runConformTest(
- new String[] {
- "X.java",
- "import java.lang.annotation.Target;\r\n" +
- "import static java.lang.annotation.ElementType.*;\r\n" +
- "\r\n" +
- "@Target(METHOD)\r\n" +
- "@interface Annot {\r\n" +
- " int value() default 0;\r\n" +
- "}\r\n" +
- "public class X {\r\n" +
- " @Annot(4)\r\n" +
- " public int foo() {\r\n" +
- " return 0;\r\n" +
- " }\r\n" +
- "}",
- },
- "");
- String expectedOutput =
- " public int foo();\n" +
- " 0 iconst_0\n" +
- " 1 ireturn\n" +
- " Line numbers:\n" +
- " [pc: 0, line: 11]\n" +
- " Local variable table:\n" +
- " [pc: 0, pc: 2] local: this index: 0 type: X\n" +
- " RuntimeInvisibleAnnotations: \n" +
- " #17 @Annot(\n" +
- " #18 value=(int) 4 (constant type)\n" +
- " )\n" +
- "}";
- checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+
+ public void test100_pqtr() throws Exception { // PQTR (ParameterizedQualifiedTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " java.util.@B(2) List<String> field2;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test100a_pqtr() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " java.util.@B(2) List<String>[] field3;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test100b_pqtr() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " java.util.List<@B(3) String>[] field3;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, TYPE_ARGUMENT(0)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test100c_pqtr() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " java.util.List<String> @B(3)[] field3;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test100d_pqtr() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " java.util.@B(2) List<@B(5) String> @B(3)[]@B(4)[] field;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY]\n" +
+ " )\n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " )\n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 4 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY]\n" +
+ " )\n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 5 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY, TYPE_ARGUMENT(0)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+
+ public void test100e_pqtr() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " java.util.Map.@B(2) Entry<String,String> field;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test100f_pqtr() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "Foo.java",
+ "class Foo {}\n",
+
+ "Levels.java",
+ "package one.two.three;\n" +
+ "class Level1 { static class Level2 { class Level3 { class Level4 { class Level5<T> { } } } } }\n",
+
+ "X.java",
+ "package one.two.three;\n" +
+ "class X {\n" +
+ " one.two.three.Level1.Level2.@B(2) Level3.Level4.@B(3) Level5<String> instance;\n" +
+ "}\n",
+
+ "B.java",
+ "package one.two.three;\n" +
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @one.two.three.B(\n" +
+ " #11 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [INNER_TYPE]\n" +
+ " )\n" +
+ " #10 @one.two.three.B(\n" +
+ " #11 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [INNER_TYPE, INNER_TYPE, INNER_TYPE]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "one" + File.separator + "two" + File.separator + "three" + File.separator + "X.class", "one.two.three.X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test100g_pqtr() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "Foo.java",
+ "class Foo {}\n",
+
+ "Levels.java",
+ "package one.two.three;\n" +
+ "class Level1 { static class Level2 { class Level3 { class Level4 { class Level5<T> { } } } } }\n",
+
+ "X.java",
+ "package one.two.three;\n" +
+ "class X {\n" +
+ " one.two.three.Level1.Level2.@B(2) Level3.Level4.@B(3) Level5<String>[][] instance;\n" +
+ "}\n",
+
+ "B.java",
+ "package one.two.three;\n" +
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @one.two.three.B(\n" +
+ " #11 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY, INNER_TYPE]\n" +
+ " )\n" +
+ " #10 @one.two.three.B(\n" +
+ " #11 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY, INNER_TYPE, INNER_TYPE, INNER_TYPE]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "one" + File.separator + "two" + File.separator + "three" + File.separator + "X.class", "one.two.three.X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test100h_pqtr() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " Level1.Level2.@B(2) Level3.Level4.@B(3) Level5<String>[][] instance;\n" +
+ "}\n",
+
+ "Levels.java",
+ "class Level1 { static class Level2 { class Level3 { class Level4 { class Level5<T> { } } } } }\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY, INNER_TYPE]\n" +
+ " )\n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY, INNER_TYPE, INNER_TYPE, INNER_TYPE]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test100i_pqtr() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " Level1.Level2.Level3.Level4.Level5<@B(1) String>[][] instance;\n" +
+ "}\n",
+
+ "Levels.java",
+ "class Level1 { static class Level2 { class Level3 { class Level4 { class Level5<T> { } } } } }\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 1 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY, INNER_TYPE, INNER_TYPE, INNER_TYPE, TYPE_ARGUMENT(0)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test100j_pqtr() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " Level1.Level2.Level3<@B(1) String>.Level4.Level5<@B(2) String>[][] instance;\n" +
+ "}\n",
+
+ "Levels.java",
+ "class Level1 { static class Level2 { class Level3<Q> { class Level4 { class Level5<T> { } } } } }\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 1 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY, INNER_TYPE, TYPE_ARGUMENT(0)]\n" +
+ " )\n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY, INNER_TYPE, INNER_TYPE, INNER_TYPE, TYPE_ARGUMENT(0)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test100k_pqtr() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " Level1.@B(5) Level2.Level3<@B(1) String>.Level4.Level5<@B(2) String>[][] instance;\n" +
+ "}\n",
+
+ "Levels.java",
+ "class Level1 { static class Level2 { class Level3<Q> { class Level4 { class Level5<T> { } } } } }\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 5 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY]\n" +
+ " )\n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 1 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY, INNER_TYPE, TYPE_ARGUMENT(0)]\n" +
+ " )\n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY, INNER_TYPE, INNER_TYPE, INNER_TYPE, TYPE_ARGUMENT(0)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test101a_qtr() throws Exception { // QTR (QualifiedTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " com.foo.@B(2) List field2;\n" +
+ "}\n",
+
+ "List.java",
+ "package com.foo;\n"+
+ "public class List {}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @B(\n" +
+ " #9 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+
+ public void test101b_qtr() throws Exception { // QTR (QualifiedTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " java.util.Map.@B(2) Entry field;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @B(\n" +
+ " #9 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test101c_qtr() throws Exception { // QTR (QualifiedTypeReference)
+ this.runConformTest(
+ new String[] {
+ "Runner.java",
+ "public class Runner {}\n",
+
+ "B.java",
+ "package one.two.three;\n" +
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+
+ "X.java",
+ "package one.two.three;\n" +
+ "class X {\n" +
+ " one.two.three.Level1.Level2.@B(2) Level3.Level4.@B(3) Level5 instance;\n" +
+ "}\n",
+
+ "Level1.java",
+ "package one.two.three;\n" +
+ "public class Level1 { static class Level2 { class Level3 { class Level4 { class Level5 { } } } } }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @one.two.three.B(\n" +
+ " #9 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [INNER_TYPE]\n" +
+ " )\n" +
+ " #8 @one.two.three.B(\n" +
+ " #9 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [INNER_TYPE, INNER_TYPE, INNER_TYPE]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "one" + File.separator + "two" + File.separator + "three" + File.separator + "X.class", "one.two.three.X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test102a_str() throws Exception { // STR (SingleTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " @B(1) X field;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @B(\n" +
+ " #9 value=(int) 1 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test102b_str() throws Exception { // STR (SingleTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " @B(1) int field;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @B(\n" +
+ " #9 value=(int) 1 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test103a_atr() throws Exception { // ATR (ArrayTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " @B(1) X[] field;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @B(\n" +
+ " #9 value=(int) 1 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test103b_atr() throws Exception { // ATR (ArrayTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " X @B(2)[] field;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @B(\n" +
+ " #9 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test103c_atr() throws Exception { // ATR (ArrayTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " X []@B(3)[] field;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @B(\n" +
+ " #9 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test103d_atr() throws Exception { // ATR (ArrayTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " X []@B(3)[][] field;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @B(\n" +
+ " #9 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test103e_atr() throws Exception { // ATR (ArrayTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ " @B(1) int []@B(3)[][] field;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @B(\n" +
+ " #9 value=(int) 1 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY, ARRAY]\n" +
+ " )\n" +
+ " #8 @B(\n" +
+ " #9 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test104a_pstr() throws Exception { // PSTR (ParameterizedSingleTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X<T1,T2,T3> {\n" +
+ " @B(1) X<@B(2) String, @B(3) Integer, @B(4) Boolean> field;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 1 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " )\n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
+ " )\n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(1)]\n" +
+ " )\n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 4 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(2)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test104b_pstr() throws Exception { // PSTR (ParameterizedSingleTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X<T1> {\n" +
+ " @B(1) X<@B(2) String> @B(3)[] field;\n" +
+ "}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 1 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY]\n" +
+ " )\n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " )\n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, TYPE_ARGUMENT(0)]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test105a_aqtr() throws Exception { // AQTR (ArrayQualifiedTypeReference)
+ this.runConformTest(
+ new String[] {
+ "Y.java",
+ "class Y {}",
+
+ "X.java",
+ "package one.two.three;\n" +
+ "class X<T1> {\n" +
+ " one.two.three.@B(1) List[] field;\n" +
+ "}\n",
+
+ "List.java",
+ "package one.two.three;\n" +
+ "class List {}\n",
+
+ "B.java",
+ "package one.two.three;\n" +
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @one.two.three.B(\n" +
+ " #9 value=(int) 1 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "one" + File.separator + "two" + File.separator + "three" + File.separator +"X.class",
+ "one.two.three.X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test105b_aqtr() throws Exception { // AQTR (ArrayQualifiedTypeReference)
+ this.runConformTest(
+ new String[] {
+ "Y.java",
+ "class Y {}",
+
+ "X.java",
+ "package one.two.three;\n" +
+ "class X<T1> {\n" +
+ " one.two.three.@B(2) List @B(3)[]@B(4)[] field;\n" +
+ "}\n",
+
+ "List.java",
+ "package one.two.three;\n" +
+ "class List {}\n",
+
+ "B.java",
+ "package one.two.three;\n" +
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @one.two.three.B(\n" +
+ " #9 value=(int) 2 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY, ARRAY]\n" +
+ " )\n" +
+ " #8 @one.two.three.B(\n" +
+ " #9 value=(int) 3 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " )\n" +
+ " #8 @one.two.three.B(\n" +
+ " #9 value=(int) 4 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "one" + File.separator + "two" + File.separator + "three" + File.separator +"X.class",
+ "one.two.three.X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test106a_wtr() throws Exception { // WTR (WildcardTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.List;\n" +
+ "class X<T1> {\n" +
+ " List<? extends @B(1) Number> field;\n" +
+ "}\n",
+
+ "List.java",
+ "class List {}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 1 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(0), WILDCARD]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator +"X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test106b_wtr() throws Exception { // WTR (WildcardTypeReference)
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.List;\n" +
+ "class X<T1> {\n" +
+ " List<? extends @B(1) Number[]> field;\n" +
+ "}\n",
+
+ "List.java",
+ "class List {}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B { int value() default -1; }\n",
+ },
+ "");
+ String expectedOutput =
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #10 @B(\n" +
+ " #11 value=(int) 1 (constant type)\n" +
+ " target type = 0x13 FIELD\n" +
+ " location = [TYPE_ARGUMENT(0), WILDCARD, ARRAY]\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
+
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
index 347bbe60e..9a65761a5 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
@@ -2491,7 +2491,7 @@ public class VarargsTest extends AbstractComparableTest {
},
this.complianceLevel < ClassFileConstants.JDK1_7 ?
"----------\n" +
- "1. WARNING in X.java (at line 19)\n" +
+ "1. WARNING in X.java (at line 20)\n" +
" new IteratorChain<Number>(null, null);\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Type safety: A generic array of Collection<? extends Number> is created for a varargs parameter\n" +
@@ -2502,7 +2502,7 @@ public class VarargsTest extends AbstractComparableTest {
" ^^^^^^^^^^^\n" +
"Type safety: Potential heap pollution via varargs parameter collections\n" +
"----------\n" +
- "2. WARNING in X.java (at line 19)\n" +
+ "2. WARNING in X.java (at line 20)\n" +
" new IteratorChain<Number>(null, null);\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Type safety: A generic array of Collection<? extends Number> is created for a varargs parameter\n" +
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 5a3626424..c99f56652 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,227 @@ 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);
+ assertTrue(type.isArrayType());
+ 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);
+ type = creationReference.getType();
+ checkSourceRange(type, "@Marker W<@Marker Integer>", contents);
+ assertTrue(type instanceof ParameterizedType);
+ assertASTNodeEquals("@Marker W<@Marker Integer>", type);
+ 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);
+ Expression 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 4ec77591d..aedf07643 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,16 @@ 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();
+ x1.setType(this.T1);
+ basicMatch(x1);
+ }
+
public void testDoStatement() {
DoStatement x1 = this.ast.newDoStatement();
x1.setExpression(this.E1);
@@ -925,6 +947,17 @@ 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();
+ x1.setExpression(this.E1);
+ x1.setName(this.N1);
+ basicMatch(x1);
+ }
+
public void testExpressionStatement() {
ExpressionStatement x1 = this.ast.newExpressionStatement(this.E1);
basicMatch(x1);
@@ -1157,6 +1190,15 @@ 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();
+ x1.setQualifier(this.N1);
+ x1.setName(this.N2);
+ basicMatch(x1);
+ }
public void testSwitchCase() {
SwitchCase x1 = this.ast.newSwitchCase();
x1.setExpression(this.E1);
@@ -1589,6 +1631,17 @@ 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();
+ x1.setType(this.T1);
+ x1.setName(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 730c9faa1..55ae39b2f 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
@@ -358,7 +358,7 @@ public class ASTStructuralPropertyTest extends org.eclipse.jdt.core.tests.junit.
maxNodeType = 84;
break;
case AST.JLS8:
- maxNodeType = 88;
+ maxNodeType = 92;
break;
default:
fail();
@@ -417,9 +417,9 @@ public class ASTStructuralPropertyTest extends org.eclipse.jdt.core.tests.junit.
}
// {ObjectTeams: adapted for OT specific ASTNodes
/* orig:
- assertEquals("Wrong last known type", 88, hi); // last known one
+ assertEquals("Wrong last known type", 92, hi); // last known one
:giro */
- assertEquals("Wrong last known type", 103, hi); // last known one
+ assertEquals("Wrong last known type", 107, hi); // last known one
// jwl}
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 ee25c3b12..c07b2c14d 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
@@ -8795,6 +8795,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 ff0db3a21..a94cb24b8 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,19 @@ 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();
+ x1.setType(this.T1);
+ TestVisitor v1 = new TestVisitor();
+ this.b.setLength(0);
+ x1.accept(v1);
+ String result = this.b.toString();
+ assertTrue(result.equals("[(eCR"+this.T1S+"eCR)]")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
public void testDoStatement() {
DoStatement x1 = this.ast.newDoStatement();
x1.setExpression(this.E1);
@@ -1476,6 +1521,19 @@ 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();
+ x1.setExpression(this.E1);
+ x1.setName(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 +2067,19 @@ 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();
+ x1.setQualifier(this.N1);
+ x1.setName(this.N2);
+ 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 +2226,19 @@ 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();
+ x1.setType(this.T1);
+ x1.setName(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.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java
index 487ae1af4..d34297e6f 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java
@@ -1060,6 +1060,8 @@ public static Test suite() {
suite.addTest(new CompletionTests("testBug402812c"));
suite.addTest(new CompletionTests("testBug402812d"));
suite.addTest(new CompletionTests("testBug370971"));
+ suite.addTest(new CompletionTests("testBug406468a"));
+ suite.addTest(new CompletionTests("testBug406468b"));
return suite;
}
public CompletionTests(String name) {
@@ -25991,6 +25993,133 @@ public void testBug385858d() throws JavaModelException {
"completion token location={CONSTRUCTOR_START}",
requestor.getContext());
}
+// Bug 402574 - Autocomplete does not recognize all enum constants when constants override methods
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=402574
+public void testBug402574() throws JavaModelException {
+ Map options = COMPLETION_PROJECT.getOptions(true);
+ Object savedOptionCompliance = options.get(CompilerOptions.OPTION_Source);
+ try {
+ options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
+ COMPLETION_PROJECT.setOptions(options);
+ this.workingCopies = new ICompilationUnit[2];
+ this.workingCopies[1] = getWorkingCopy(
+ "/Completion/src/test/ExampleEnumNoAutocomplete.java",
+ "public enum ExampleEnumNoAutocomplete {\n" +
+ " STUFF(\"a\", \"b\") {\n" +
+ " @Override\n" +
+ " public String getProperty1() {\n"+
+ " return super.getProperty1().toUpperCase();\n" +
+ " }\n" +
+ " @Override\n" +
+ " public String getSomething() {\n" +
+ " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
+ " }\n" +
+ " },\n" +
+ " THINGS(\"c\", \"d\") {\n" +
+ " @Override\n" +
+ " public String getProperty1() {\n" +
+ " return super.getProperty2();\n" +
+ " }\n" +
+ " @Override\n" +
+ " public String getProperty2() {\n" +
+ " return super.getProperty1();\n" +
+ " }\n" +
+ " @Override\n" +
+ " public String getSomething() {\n" +
+ " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
+ " }\n" +
+ " },\n" +
+ " MORE_STUFF(\"e\", \"f\") {\n" +
+ " @Override\n" +
+ " public String getProperty1() {\n" +
+ " return getProperty2();\n" +
+ " }\n" +
+ " @Override\n" +
+ " public String getSomething() {\n" +
+ " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
+ " }\n" +
+ " },\n" +
+ " OTHER(\"g\", \"h\") {\n" +
+ " @Override\n" +
+ " public String getSomething() {\n" +
+ " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
+ " }\n" +
+ " },\n" +
+ " STILL_OTHER(\"i\", \"j\") {\n" +
+ " @Override\n" +
+ " public String getSomething() {\n" +
+ " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
+ " }\n" +
+ " },\n" +
+ " IT_MAY_BE_DUE_TO_MIXING_PERHAPS(\"k\", \"l\") {\n" +
+ " @Override\n" +
+ " public String getProperty1() {\n" +
+ " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
+ " }\n" +
+ " @Override\n" +
+ " public String getProperty2() {\n" +
+ " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
+ " }\n" +
+ " @Override\n" +
+ " public String getSomething() {\n" +
+ " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
+ " }\n" +
+ " };\n" +
+ " private final String property1;\n" +
+ " private final String property2;\n" +
+ " ExampleEnumNoAutocomplete(final String property1, final String property2) {\n" +
+ " this.property1 = property1;\n" +
+ " this.property2 = property2;\n" +
+ " }\n" +
+ " public String getProperty1() {\n" +
+ " return property1;\n" +
+ " }\n" +
+ " public String getProperty2() {\n" +
+ " return property2;\n" +
+ " }\n" +
+ " public abstract String getSomething();\n" +
+ " }\n");
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/test/Tester.java",
+ "import java.util.EnumMap;\n" +
+ "import java.util.Map;\n" +
+ "public class Tester {\n" +
+ " public static void main(String[] args) {\n" +
+ " Map<ExampleEnumNoAutocomplete, Map<String, Object>> huh = new EnumMap<ExampleEnumNoAutocomplete, Map<String, Object>>(\n" +
+ " ExampleEnumNoAutocomplete.class);\n" +
+ " huh.put(ExampleEnumNoAutocomplete.STUFF, null);\n" +
+ " ExampleEnumNoAutocomplete. \n" +
+ " }\n" +
+ "}\n");
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, false, false, false, true);
+ requestor.allowAllRequiredProposals();
+ requestor.setRequireExtendedContext(true);
+ requestor.setComputeEnclosingElement(true);
+ NullProgressMonitor monitor = new NullProgressMonitor();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = " ExampleEnumNoAutocomplete.";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner, monitor);
+
+ assertResults(
+ "IT_MAY_BE_DUE_TO_MIXING_PERHAPS[FIELD_REF]{IT_MAY_BE_DUE_TO_MIXING_PERHAPS, Ltest.ExampleEnumNoAutocomplete;, Ltest.ExampleEnumNoAutocomplete;, IT_MAY_BE_DUE_TO_MIXING_PERHAPS, null, 26}\n" +
+ "MORE_STUFF[FIELD_REF]{MORE_STUFF, Ltest.ExampleEnumNoAutocomplete;, Ltest.ExampleEnumNoAutocomplete;, MORE_STUFF, null, 26}\n" +
+ "OTHER[FIELD_REF]{OTHER, Ltest.ExampleEnumNoAutocomplete;, Ltest.ExampleEnumNoAutocomplete;, OTHER, null, 26}\n" +
+ "STILL_OTHER[FIELD_REF]{STILL_OTHER, Ltest.ExampleEnumNoAutocomplete;, Ltest.ExampleEnumNoAutocomplete;, STILL_OTHER, null, 26}\n" +
+ "STUFF[FIELD_REF]{STUFF, Ltest.ExampleEnumNoAutocomplete;, Ltest.ExampleEnumNoAutocomplete;, STUFF, null, 26}\n" +
+ "THINGS[FIELD_REF]{THINGS, Ltest.ExampleEnumNoAutocomplete;, Ltest.ExampleEnumNoAutocomplete;, THINGS, null, 26}\n" +
+ "class[FIELD_REF]{class, null, Ljava.lang.Class<Ltest.ExampleEnumNoAutocomplete;>;, class, null, 26}\n" +
+ "valueOf[METHOD_REF]{valueOf(), Ltest.ExampleEnumNoAutocomplete;, (Ljava.lang.String;)Ltest.ExampleEnumNoAutocomplete;, valueOf, (arg0), 26}\n" +
+ "values[METHOD_REF]{values(), Ltest.ExampleEnumNoAutocomplete;, ()[Ltest.ExampleEnumNoAutocomplete;, values, null, 26}",
+ requestor.getResults());
+ assertEquals(false,
+ requestor.canUseDiamond(0));
+ } finally {
+ // Restore compliance settings.
+ options.put(CompilerOptions.OPTION_Source, savedOptionCompliance);
+ COMPLETION_PROJECT.setOptions(options);
+ }
+}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=402812
//Bug 402812 - [1.8][completion] Code Completion problems with static/default interface methods.
public void testBug402812a() throws Exception {
@@ -26211,103 +26340,27 @@ public void testBug402812d() throws Exception {
COMPLETION_PROJECT.setOptions(completionProjectOptions);
}
}
-// Bug 402574 - Autocomplete does not recognize all enum constants when constants override methods
-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=402574
-public void testBug402574() throws JavaModelException {
+//Bug 370971 - Content Assist autocomplete broken within an array of anonymous classes instances
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=370971
+public void testBug370971() throws JavaModelException {
Map options = COMPLETION_PROJECT.getOptions(true);
Object savedOptionCompliance = options.get(CompilerOptions.OPTION_Source);
try {
options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
COMPLETION_PROJECT.setOptions(options);
- this.workingCopies = new ICompilationUnit[2];
- this.workingCopies[1] = getWorkingCopy(
- "/Completion/src/test/ExampleEnumNoAutocomplete.java",
- "public enum ExampleEnumNoAutocomplete {\n" +
- " STUFF(\"a\", \"b\") {\n" +
- " @Override\n" +
- " public String getProperty1() {\n"+
- " return super.getProperty1().toUpperCase();\n" +
- " }\n" +
- " @Override\n" +
- " public String getSomething() {\n" +
- " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
- " }\n" +
- " },\n" +
- " THINGS(\"c\", \"d\") {\n" +
- " @Override\n" +
- " public String getProperty1() {\n" +
- " return super.getProperty2();\n" +
- " }\n" +
- " @Override\n" +
- " public String getProperty2() {\n" +
- " return super.getProperty1();\n" +
- " }\n" +
- " @Override\n" +
- " public String getSomething() {\n" +
- " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
- " }\n" +
- " },\n" +
- " MORE_STUFF(\"e\", \"f\") {\n" +
- " @Override\n" +
- " public String getProperty1() {\n" +
- " return getProperty2();\n" +
- " }\n" +
- " @Override\n" +
- " public String getSomething() {\n" +
- " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
- " }\n" +
- " },\n" +
- " OTHER(\"g\", \"h\") {\n" +
- " @Override\n" +
- " public String getSomething() {\n" +
- " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
- " }\n" +
- " },\n" +
- " STILL_OTHER(\"i\", \"j\") {\n" +
- " @Override\n" +
- " public String getSomething() {\n" +
- " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
- " }\n" +
- " },\n" +
- " IT_MAY_BE_DUE_TO_MIXING_PERHAPS(\"k\", \"l\") {\n" +
- " @Override\n" +
- " public String getProperty1() {\n" +
- " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
- " }\n" +
- " @Override\n" +
- " public String getProperty2() {\n" +
- " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
- " }\n" +
- " @Override\n" +
- " public String getSomething() {\n" +
- " throw new UnsupportedOperationException(\"What is this, I don't even?!\");\n" +
- " }\n" +
- " };\n" +
- " private final String property1;\n" +
- " private final String property2;\n" +
- " ExampleEnumNoAutocomplete(final String property1, final String property2) {\n" +
- " this.property1 = property1;\n" +
- " this.property2 = property2;\n" +
- " }\n" +
- " public String getProperty1() {\n" +
- " return property1;\n" +
- " }\n" +
- " public String getProperty2() {\n" +
- " return property2;\n" +
- " }\n" +
- " public abstract String getSomething();\n" +
- " }\n");
+ this.workingCopies = new ICompilationUnit[1];
this.workingCopies[0] = getWorkingCopy(
- "/Completion/src/test/Tester.java",
- "import java.util.EnumMap;\n" +
- "import java.util.Map;\n" +
- "public class Tester {\n" +
- " public static void main(String[] args) {\n" +
- " Map<ExampleEnumNoAutocomplete, Map<String, Object>> huh = new EnumMap<ExampleEnumNoAutocomplete, Map<String, Object>>(\n" +
- " ExampleEnumNoAutocomplete.class);\n" +
- " huh.put(ExampleEnumNoAutocomplete.STUFF, null);\n" +
- " ExampleEnumNoAutocomplete. \n" +
- " }\n" +
+ "/Completion/src/test/ExampleEnumNoAutocomplete.java",
+ "public class X {\n" +
+ " private Object[] items = new Object[] {\n" +
+ " new Object() {\n" +
+ " @Override\n" +
+ " public String toString() {\n" +
+ " return super.toS;\n" +
+ " }\n" +
+ " },\n" +
+ " new Object() { }\n" +
+ " } ;\n" +
"}\n");
CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, false, false, false, true);
requestor.allowAllRequiredProposals();
@@ -26315,20 +26368,12 @@ public void testBug402574() throws JavaModelException {
requestor.setComputeEnclosingElement(true);
NullProgressMonitor monitor = new NullProgressMonitor();
String str = this.workingCopies[0].getSource();
- String completeBehind = " ExampleEnumNoAutocomplete.";
+ String completeBehind = "return super.toS";
int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner, monitor);
assertResults(
- "IT_MAY_BE_DUE_TO_MIXING_PERHAPS[FIELD_REF]{IT_MAY_BE_DUE_TO_MIXING_PERHAPS, Ltest.ExampleEnumNoAutocomplete;, Ltest.ExampleEnumNoAutocomplete;, IT_MAY_BE_DUE_TO_MIXING_PERHAPS, null, 26}\n" +
- "MORE_STUFF[FIELD_REF]{MORE_STUFF, Ltest.ExampleEnumNoAutocomplete;, Ltest.ExampleEnumNoAutocomplete;, MORE_STUFF, null, 26}\n" +
- "OTHER[FIELD_REF]{OTHER, Ltest.ExampleEnumNoAutocomplete;, Ltest.ExampleEnumNoAutocomplete;, OTHER, null, 26}\n" +
- "STILL_OTHER[FIELD_REF]{STILL_OTHER, Ltest.ExampleEnumNoAutocomplete;, Ltest.ExampleEnumNoAutocomplete;, STILL_OTHER, null, 26}\n" +
- "STUFF[FIELD_REF]{STUFF, Ltest.ExampleEnumNoAutocomplete;, Ltest.ExampleEnumNoAutocomplete;, STUFF, null, 26}\n" +
- "THINGS[FIELD_REF]{THINGS, Ltest.ExampleEnumNoAutocomplete;, Ltest.ExampleEnumNoAutocomplete;, THINGS, null, 26}\n" +
- "class[FIELD_REF]{class, null, Ljava.lang.Class<Ltest.ExampleEnumNoAutocomplete;>;, class, null, 26}\n" +
- "valueOf[METHOD_REF]{valueOf(), Ltest.ExampleEnumNoAutocomplete;, (Ljava.lang.String;)Ltest.ExampleEnumNoAutocomplete;, valueOf, (arg0), 26}\n" +
- "values[METHOD_REF]{values(), Ltest.ExampleEnumNoAutocomplete;, ()[Ltest.ExampleEnumNoAutocomplete;, values, null, 26}",
+ "toString[METHOD_REF]{toString(), Ljava.lang.Object;, ()Ljava.lang.String;, toString, null, 65}",
requestor.getResults());
assertEquals(false,
requestor.canUseDiamond(0));
@@ -26338,4 +26383,91 @@ public void testBug402574() throws JavaModelException {
COMPLETION_PROJECT.setOptions(options);
}
}
+// Bug 406468 - [1.8][code assist] No completion proposals after the use of a constructor reference
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=406468
+public void testBug406468a() throws JavaModelException {
+ Map options = COMPLETION_PROJECT.getOptions(true);
+ Object savedOptionCompliance = options.get(CompilerOptions.OPTION_Compliance);
+ Object savedOptionSource = options.get(CompilerOptions.OPTION_Source);
+ try {
+ options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8);
+ options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8);
+ COMPLETION_PROJECT.setOptions(options);
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/test/X.java",
+ "interface I {\n" +
+ " X [][][] copy (int x);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " I i = X[][][]::new;\n" +
+ " X[][][] x = i.copy(136);\n" +
+ " System.out.println(x.length);\n" +
+ " \n" +
+ " }\n" +
+ "}\n");
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "System.out.println(x.length);";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults(
+ "I[TYPE_REF]{I, test, Ltest.I;, null, null, 27}\n" +
+ "X[TYPE_REF]{X, test, Ltest.X;, null, null, 27}\n" +
+ "args[LOCAL_VARIABLE_REF]{args, null, [Ljava.lang.String;, args, null, 27}\n" +
+ "i[LOCAL_VARIABLE_REF]{i, null, Ltest.I;, i, null, 27}\n" +
+ "main[METHOD_REF]{main(), Ltest.X;, ([Ljava.lang.String;)V, main, (args), 27}\n" +
+ "x[LOCAL_VARIABLE_REF]{x, null, [[[Ltest.X;, x, null, 27}",
+ requestor.getResults());
+ } finally {
+ // Restore compliance settings.
+ options.put(CompilerOptions.OPTION_Compliance, savedOptionCompliance);
+ options.put(CompilerOptions.OPTION_Source, savedOptionSource);
+ COMPLETION_PROJECT.setOptions(options);
+ }
+}
+public void testBug406468b() throws JavaModelException {
+ Map options = COMPLETION_PROJECT.getOptions(true);
+ Object savedOptionCompliance = options.get(CompilerOptions.OPTION_Compliance);
+ Object savedOptionSource = options.get(CompilerOptions.OPTION_Source);
+ try {
+ options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8);
+ options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8);
+ COMPLETION_PROJECT.setOptions(options);
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/test/X.java",
+ "interface I {\n" +
+ " X<java.lang.String> copy ();\n" +
+ "}\n" +
+ "public class X<S> {\n" +
+ " public static void main(String[] args) {\n" +
+ " I i = X<java.lang.String>::new;\n" +
+ " X x = i.copy();\n" +
+ " System.out.println(x);\n" +
+ " \n" +
+ " }\n" +
+ "}\n");
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "System.out.println(x);";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults(
+ "I[TYPE_REF]{I, test, Ltest.I;, null, null, 27}\n" +
+ "S[TYPE_REF]{S, null, TS;, null, null, 27}\n" +
+ "X<S>[TYPE_REF]{X, test, Ltest.X<TS;>;, null, null, 27}\n" +
+ "args[LOCAL_VARIABLE_REF]{args, null, [Ljava.lang.String;, args, null, 27}\n" +
+ "i[LOCAL_VARIABLE_REF]{i, null, Ltest.I;, i, null, 27}\n" +
+ "main[METHOD_REF]{main(), Ltest.X<TS;>;, ([Ljava.lang.String;)V, main, (args), 27}\n" +
+ "x[LOCAL_VARIABLE_REF]{x, null, Ltest.X;, x, null, 27}",
+ requestor.getResults());
+ } finally {
+ // Restore compliance settings.
+ options.put(CompilerOptions.OPTION_Compliance, savedOptionCompliance);
+ options.put(CompilerOptions.OPTION_Source, savedOptionSource);
+ COMPLETION_PROJECT.setOptions(options);
+ }
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTypeAnnotationsTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTypeAnnotationsTest.java
index 56d7886ba..cea9d59c8 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTypeAnnotationsTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTypeAnnotationsTest.java
@@ -947,7 +947,7 @@ public class ASTRewritingTypeAnnotationsTest extends ASTRewritingTest {
" * @param arg \n" +
" */\n" +
" test406469.bug.@Marker IOException foo(\n" +
- " FileNotFoundException arg)\n" +
+ " test406469.bug.FileNotFoundException arg)\n" +
" throws test406469.bug.@NonNull @Marker EOFException {\n" +
" try {\n" +
" test406469.bug.@NonNull IOError e = new test406469.bug.@Marker IOError();\n" +
@@ -972,4 +972,103 @@ public class ASTRewritingTypeAnnotationsTest extends ASTRewritingTest {
assertEqualString(preview, contentsmodified);
}
+ /**
+ * ASTRewriterTests for QualifiedType
+ * @throws Exception
+ *
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=407364
+ */
+ public void testQualifiedTypeAnnotations() throws Exception {
+ IPackageFragment pack1= this.sourceFolder.createPackageFragment("test407364.bug", false, null);
+ String contents = "package test0002;\n" +
+ "import java.lang.annotation.Target;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " Outer outer = new Outer();\n" +
+ " Outer.@Marker1 Inner first = outer.new Inner();\n" +
+ " Outer.@Marker2 Inner second = outer.new Inner() ;\n" +
+ " Outer.Inner.@Marker1 Deeper deeper = second.new Deeper();\n" +
+ " Outer.Inner.Deeper deeper2 = second.new Deeper();\n" +
+ " }\n" + "}\n" + "class Outer {\n" +
+ " public class Inner {\n" +
+ " public class Deeper {\n" +
+ " }\n" +
+ " }\n" +
+ "}\n" +
+ "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" +
+ "@interface Marker {}\n" +
+ "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" +
+ "@interface Marker1 {}\n" +
+ "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" +
+ "@interface Marker2 {}\n";
+
+ StringBuffer buf = new StringBuffer(contents);
+ ICompilationUnit cu= pack1.createCompilationUnit("X.java", buf.toString(), false, null);
+ CompilationUnit astRoot= createAST(cu, /* resolve */ true, false);
+ ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());
+ AST ast= astRoot.getAST();
+ TypeDeclaration typeDeclaration= findTypeDeclaration(astRoot, "X");
+ MethodDeclaration methodDeclaration= findMethodDeclaration(typeDeclaration, "main");
+ List statements = methodDeclaration.getBody().statements();
+ int sCount = 1;
+
+ { //replace an annotation.
+ VariableDeclarationStatement variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount++);
+ QualifiedType qualifiedType = (QualifiedType) variableDeclarationStatement.getType();
+ MarkerAnnotation markerAnnotation= ast.newMarkerAnnotation();
+ markerAnnotation.setTypeName(ast.newSimpleName("NewMarker"));
+ rewrite.replace((ASTNode) qualifiedType.annotations().get(0), markerAnnotation, null);
+
+ // remove an annotation
+ variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount++);
+ qualifiedType = (QualifiedType) variableDeclarationStatement.getType();
+ rewrite.remove((ASTNode) qualifiedType.annotations().get(0), null);
+
+ // insert an annotation after an existing annotation
+ variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount++);
+ qualifiedType = (QualifiedType) variableDeclarationStatement.getType();
+ markerAnnotation= ast.newMarkerAnnotation();
+ markerAnnotation.setTypeName(ast.newSimpleName("NewMarker"));
+ rewrite.getListRewrite(qualifiedType, QualifiedType.ANNOTATIONS_PROPERTY).insertLast(markerAnnotation, null);
+
+ /* insert an annotation in a type not converted as QualifiedType. This would involve
+ * creation of a QualifiedType from fields of the existing type.
+ */
+ variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount++);
+ SimpleType simpleType = (SimpleType) variableDeclarationStatement.getType();
+ QualifiedName qualifiedName = (QualifiedName) simpleType.getName();
+ SimpleName simpleName = ast.newSimpleName(qualifiedName.getName().getIdentifier());
+ qualifiedName = (QualifiedName) qualifiedName.getQualifier();
+ qualifiedName = ast.newQualifiedName(ast.newName(qualifiedName.getQualifier().toString()), ast.newSimpleName(qualifiedName.getName().toString()));
+ qualifiedType = ast.newQualifiedType(ast.newSimpleType(qualifiedName), simpleName);
+
+ markerAnnotation= ast.newMarkerAnnotation();
+ markerAnnotation.setTypeName(ast.newSimpleName("NewMarker"));
+ rewrite.getListRewrite(qualifiedType, QualifiedType.ANNOTATIONS_PROPERTY).insertLast(markerAnnotation, null);
+ rewrite.replace(variableDeclarationStatement.getType(), qualifiedType, null);
+ }
+ String preview= evaluateRewrite(cu, rewrite);
+ String contentsmodified = "package test0002;\n" +
+ "import java.lang.annotation.Target;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " Outer outer = new Outer();\n" +
+ " Outer.@NewMarker Inner first = outer.new Inner();\n" +
+ " Outer.Inner second = outer.new Inner() ;\n" +
+ " Outer.Inner.@Marker1 @NewMarker Deeper deeper = second.new Deeper();\n" +
+ " Outer. Inner.@NewMarker Deeper deeper2 = second.new Deeper();\n" +
+ " }\n" + "}\n" + "class Outer {\n" +
+ " public class Inner {\n" +
+ " public class Deeper {\n" +
+ " }\n" +
+ " }\n" +
+ "}\n" +
+ "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" +
+ "@interface Marker {}\n" +
+ "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" +
+ "@interface Marker1 {}\n" +
+ "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" +
+ "@interface Marker2 {}\n";
+ assertEqualString(preview, contentsmodified);
+ }
} \ No newline at end of file
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
index bb9a271a1..2e06bda94 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
@@ -196,6 +196,7 @@ public class CompletionParser extends AssistParser {
private boolean storeSourceEnds;
public HashtableOfObjectToInt sourceEnds;
+ private boolean inReferenceExpression;
public CompletionParser(ProblemReporter problemReporter, boolean storeExtraSourceEnds) {
super(problemReporter);
@@ -3902,7 +3903,12 @@ protected void consumeToken(int token) {
break;
}
break;
+ case TokenNameCOLON_COLON:
+ this.inReferenceExpression = true;
+ break;
case TokenNameIdentifier:
+ if (this.inReferenceExpression)
+ break;
if (previous == TokenNameDOT) { // e.g. foo().[fred]()
if (this.invocationType != SUPER_RECEIVER // e.g. not super.[fred]()
//{ObjectTeams: base:
@@ -3931,6 +3937,8 @@ protected void consumeToken(int token) {
}
break;
case TokenNamenew:
+ if (this.inReferenceExpression)
+ break;
pushOnElementStack(K_BETWEEN_NEW_AND_LEFT_BRACKET);
this.qualifier = this.expressionPtr; // NB: even if there is no qualification, set it to the expression ptr so that the number of arguments are correctly computed
if (previous == TokenNameDOT) { // e.g. fred().[new] X()
@@ -4374,6 +4382,10 @@ protected void consumeToken(int token) {
}
}
}
+protected void consumeIdentifierOrNew(boolean newForm) {
+ this.inReferenceExpression = false;
+ super.consumeIdentifierOrNew(newForm);
+}
protected void consumeOnlySynchronized() {
super.consumeOnlySynchronized();
this.hasUnusedModifiers = false;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index ab883e0d0..b1e59181e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -15,6 +15,8 @@
* Technical University Berlin - extended API and implementation
* Jesper S Moller - Contributions for
* Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler;
@@ -28,7 +30,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.Stack;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CharOperation;
@@ -48,15 +49,13 @@ import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
-import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
-import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.Receiver;
import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
-import org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.AnnotationContext;
import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
@@ -64,19 +63,19 @@ import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
import org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel;
+import org.eclipse.jdt.internal.compiler.codegen.MultiCatchExceptionLabel;
import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrame;
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream;
import org.eclipse.jdt.internal.compiler.codegen.TypeAnnotationCodeStream;
-import org.eclipse.jdt.internal.compiler.codegen.VerificationTypeInfo;
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.ExceptionMarker;
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.StackDepthMarker;
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.StackMarker;
+import org.eclipse.jdt.internal.compiler.codegen.VerificationTypeInfo;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.impl.StringConstant;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
@@ -287,75 +286,6 @@ public class ClassFile implements TypeConstants, TypeIds {
LookupEnvironment env = typeBinding.scope.environment();
return env.classFilePool.acquire(typeBinding);
}
-
- /**
- * Return the location for the corresponding annotation inside the type reference, <code>null</code> if none.
- */
- private static int[] getWildcardLocations(TypeReference reference, Wildcard wildcard) {
- class LocationCollector extends ASTVisitor {
- Stack currentIndexes;
- boolean search = true;
- Wildcard currentWildcard;
-
- public LocationCollector(Wildcard currentWildcard) {
- this.currentIndexes = new Stack();
- this.currentWildcard = currentWildcard;
- }
- public boolean visit(ParameterizedSingleTypeReference typeReference, BlockScope scope) {
- if (!this.search) return false;
- TypeReference[] typeReferences = typeReference.typeArguments;
- this.currentIndexes.push(new Integer(0));
- for (int i = 0, max = typeReferences.length; i < max; i++) {
- typeReferences[i].traverse(this, scope);
- if (!this.search) return false;
- this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
- }
- this.currentIndexes.pop();
- return true;
- }
- public boolean visit(ParameterizedQualifiedTypeReference typeReference, BlockScope scope) {
- if (!this.search) return false;
- TypeReference[] typeReferences = typeReference.typeArguments[typeReference.typeArguments.length - 1];
- this.currentIndexes.push(new Integer(0));
- for (int i = 0, max = typeReferences.length; i < max; i++) {
- typeReferences[i].traverse(this, scope);
- if (!this.search) return false;
- this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
- }
- this.currentIndexes.pop();
- return true;
- }
- public boolean visit(Wildcard typeReference, BlockScope scope) {
- if (!this.search) return false;
- if (typeReference.equals(this.currentWildcard)) {
- this.search = false;
- }
- return true;
- }
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer
- .append("search location for ") //$NON-NLS-1$
- .append(this.currentWildcard)
- .append("\ncurrent indexes : ") //$NON-NLS-1$
- .append(this.currentIndexes);
- return String.valueOf(buffer);
- }
- }
- if (reference == null) return null;
- LocationCollector collector = new LocationCollector(wildcard);
- reference.traverse(collector, (BlockScope) null);
- if (collector.currentIndexes.isEmpty()) {
- return null;
- }
- int size = collector.currentIndexes.size();
- int[] result = new int[size];
- for (int i = 0; i < size; i++) {
- result[size - i - 1] = ((Integer) collector.currentIndexes.pop()).intValue();
- }
- return result;
- }
-
/**
* INTERNAL USE-ONLY
* This methods creates a new instance of the receiver.
@@ -374,7 +304,7 @@ public class ClassFile implements TypeConstants, TypeIds {
this.isNestedType = typeBinding.isNestedType();
if (this.targetJDK >= ClassFileConstants.JDK1_6) {
this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE;
- if (this.targetJDK >= ClassFileConstants.JDK1_7) {
+ if (this.targetJDK >= ClassFileConstants.JDK1_8) {
this.produceAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION;
this.codeStream = new TypeAnnotationCodeStream(this);
} else {
@@ -525,6 +455,7 @@ public class ClassFile implements TypeConstants, TypeIds {
}
attributesNumber += generateTypeAnnotationAttributeForTypeDeclaration();
+
// update the number of attributes
if (attributeOffset + 2 >= this.contents.length) {
resizeContents(2);
@@ -579,41 +510,40 @@ public class ClassFile implements TypeConstants, TypeIds {
FieldDeclaration fieldDeclaration = fieldBinding.sourceField();
if (fieldDeclaration != null) {
Annotation[] annotations = fieldDeclaration.annotations;
- List allTypeAnnotationContexts = new ArrayList();
- int invisibleTypeAnnotationsCounter = 0;
- int visibleTypeAnnotationsCounter = 0;
if (annotations != null) {
attributesNumber += generateRuntimeAnnotations(annotations);
- if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
- if ((fieldDeclaration.bits & ASTNode.HasTypeAnnotations) != 0) {
- fieldDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.FIELD, allTypeAnnotationContexts);
- }
- }
}
- TypeReference fieldType = fieldDeclaration.type;
- if (fieldType != null
- && ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0)
- && ((fieldType.bits & ASTNode.HasTypeAnnotations) != 0)) {
- fieldType.getAllAnnotationContexts(AnnotationTargetTypeConstants.FIELD, allTypeAnnotationContexts);
- }
- int size = allTypeAnnotationContexts.size();
- if (size != 0) {
- AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size];
- allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray);
- for (int i = 0, max = allTypeAnnotationContextsArray.length; i < max; i++) {
- AnnotationContext annotationContext = allTypeAnnotationContextsArray[i];
- if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
- invisibleTypeAnnotationsCounter++;
- allTypeAnnotationContexts.add(annotationContext);
- } else {
- visibleTypeAnnotationsCounter++;
- allTypeAnnotationContexts.add(annotationContext);
+
+ if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
+ List allTypeAnnotationContexts = new ArrayList();
+ if (annotations != null && (fieldDeclaration.bits & ASTNode.HasTypeAnnotations) != 0) {
+ fieldDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.FIELD, allTypeAnnotationContexts);
+ }
+ int invisibleTypeAnnotationsCounter = 0;
+ int visibleTypeAnnotationsCounter = 0;
+ TypeReference fieldType = fieldDeclaration.type;
+ if (fieldType != null && ((fieldType.bits & ASTNode.HasTypeAnnotations) != 0)) {
+ fieldType.getAllAnnotationContexts(AnnotationTargetTypeConstants.FIELD, allTypeAnnotationContexts);
+ }
+ int size = allTypeAnnotationContexts.size();
+ if (size != 0) {
+ AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size];
+ allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray);
+ for (int i = 0, max = allTypeAnnotationContextsArray.length; i < max; i++) {
+ AnnotationContext annotationContext = allTypeAnnotationContextsArray[i];
+ if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
+ invisibleTypeAnnotationsCounter++;
+ allTypeAnnotationContexts.add(annotationContext);
+ } else {
+ visibleTypeAnnotationsCounter++;
+ allTypeAnnotationContexts.add(annotationContext);
+ }
}
+ attributesNumber += generateRuntimeTypeAnnotations(
+ allTypeAnnotationContextsArray,
+ visibleTypeAnnotationsCounter,
+ invisibleTypeAnnotationsCounter);
}
- attributesNumber += generateRuntimeTypeAnnotations(
- allTypeAnnotationContextsArray,
- visibleTypeAnnotationsCounter,
- invisibleTypeAnnotationsCounter);
}
}
}
@@ -1523,6 +1453,10 @@ public class ClassFile implements TypeConstants, TypeIds {
max_locals,
false);
}
+
+ if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
+ attributesNumber += generateTypeAnnotationsOnCodeAttribute();
+ }
this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
@@ -1534,6 +1468,62 @@ public class ClassFile implements TypeConstants, TypeIds {
this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
}
+
+ public int generateTypeAnnotationsOnCodeAttribute() {
+ int attributesNumber = 0;
+
+ List allTypeAnnotationContexts = ((TypeAnnotationCodeStream) this.codeStream).allTypeAnnotationContexts;
+ int invisibleTypeAnnotationsCounter = 0;
+ int visibleTypeAnnotationsCounter = 0;
+
+ for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
+ LocalVariableBinding localVariable = this.codeStream.locals[i];
+ if (localVariable.isCatchParameter()) continue;
+ LocalDeclaration declaration = localVariable.declaration;
+ if (declaration == null
+ || (declaration.isArgument() && ((declaration.bits & ASTNode.IsUnionType) == 0))
+ || (localVariable.initializationCount == 0)
+ || ((declaration.bits & ASTNode.HasTypeAnnotations) == 0)) {
+ continue;
+ }
+ int targetType = ((localVariable.tagBits & TagBits.IsResource) == 0) ? AnnotationTargetTypeConstants.LOCAL_VARIABLE : AnnotationTargetTypeConstants.RESOURCE_VARIABLE;
+ declaration.getAllAnnotationContexts(targetType, localVariable, allTypeAnnotationContexts);
+ }
+
+ ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
+ int tableIndex = 0;
+ for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
+ ExceptionLabel exceptionLabel = exceptionLabels[i];
+ if (exceptionLabel instanceof MultiCatchExceptionLabel) {
+ MultiCatchExceptionLabel multiCatchExceptionLabel = (MultiCatchExceptionLabel)exceptionLabel;
+ tableIndex += multiCatchExceptionLabel.getAllAnnotationContexts(tableIndex, allTypeAnnotationContexts);
+ } else {
+ if (exceptionLabel.exceptionTypeReference != null) { // ignore those which cannot be annotated
+ exceptionLabel.exceptionTypeReference.getAllAnnotationContexts(AnnotationTargetTypeConstants.EXCEPTION_PARAMETER, tableIndex, allTypeAnnotationContexts);
+ }
+ tableIndex++;
+ }
+ }
+
+ int size = allTypeAnnotationContexts.size();
+ if (size != 0) {
+ AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size];
+ allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray);
+ for (int j = 0, max2 = allTypeAnnotationContextsArray.length; j < max2; j++) {
+ AnnotationContext annotationContext = allTypeAnnotationContextsArray[j];
+ if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
+ invisibleTypeAnnotationsCounter++;
+ } else {
+ visibleTypeAnnotationsCounter++;
+ }
+ }
+ attributesNumber += generateRuntimeTypeAnnotations(
+ allTypeAnnotationContextsArray,
+ visibleTypeAnnotationsCounter,
+ invisibleTypeAnnotationsCounter);
+ }
+ return attributesNumber;
+ }
/**
* INTERNAL USE-ONLY
@@ -2168,22 +2158,11 @@ public class ClassFile implements TypeConstants, TypeIds {
MethodBinding binding,
int methodAttributeOffset,
int attributesNumber) {
-
+
if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
- List allTypeAnnotationContexts = ((TypeAnnotationCodeStream) this.codeStream).allTypeAnnotationContexts;
+ List allTypeAnnotationContexts = new ArrayList();
int invisibleTypeAnnotationsCounter = 0;
int visibleTypeAnnotationsCounter = 0;
- for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
- LocalVariableBinding localVariable = this.codeStream.locals[i];
- LocalDeclaration declaration = localVariable.declaration;
- if (declaration == null
- || (declaration.isArgument() && ((declaration.bits & ASTNode.IsUnionType) == 0))
- || (localVariable.initializationCount == 0)
- || ((declaration.bits & ASTNode.HasTypeAnnotations) == 0)) {
- continue;
- }
- declaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.LOCAL_VARIABLE, localVariable, allTypeAnnotationContexts);
- }
AbstractMethodDeclaration methodDeclaration = binding.sourceMethod();
if (methodDeclaration != null) {
if ((methodDeclaration.bits & ASTNode.HasTypeAnnotations) != 0) {
@@ -2192,37 +2171,24 @@ public class ClassFile implements TypeConstants, TypeIds {
for (int i = 0, max = arguments.length; i < max; i++) {
Argument argument = arguments[i];
if ((argument.bits & ASTNode.HasTypeAnnotations) != 0) {
- argument.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_PARAMETER, i, allTypeAnnotationContexts);
+ argument.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER, i, allTypeAnnotationContexts);
}
}
}
- Annotation[] annotations = (methodDeclaration.receiver==null?null:methodDeclaration.receiver.annotations);
- if (annotations != null) {
- for (int i = 0, max = annotations.length; i < max; i++) {
- Annotation annotation = annotations[i];
- AnnotationContext annotationContext = null;
- if (annotation.isRuntimeTypeInvisible()) {
- annotationContext = new AnnotationContext(annotation, null, AnnotationTargetTypeConstants.METHOD_RECEIVER, null, AnnotationContext.INVISIBLE, null);
- invisibleTypeAnnotationsCounter++;
- } else if (annotation.isRuntimeTypeVisible()) {
- annotationContext = new AnnotationContext(annotation, null, AnnotationTargetTypeConstants.METHOD_RECEIVER, null, AnnotationContext.VISIBLE, null);
- visibleTypeAnnotationsCounter++;
- }
- if (annotationContext != null) {
- allTypeAnnotationContexts.add(annotationContext);
- }
- }
+ Receiver receiver = methodDeclaration.receiver;
+ if (receiver != null && (receiver.type.bits & ASTNode.HasTypeAnnotations) != 0) {
+ receiver.type.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RECEIVER, allTypeAnnotationContexts);
}
}
Annotation[] annotations = methodDeclaration.annotations;
if (annotations != null && binding.returnType.id != T_void) {
- methodDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN_TYPE, allTypeAnnotationContexts);
+ methodDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts);
}
if (!methodDeclaration.isConstructor() && !methodDeclaration.isClinit() && binding.returnType.id != T_void) {
MethodDeclaration declaration = (MethodDeclaration) methodDeclaration;
TypeReference typeReference = declaration.returnType;
if ((typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
- typeReference.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN_TYPE, allTypeAnnotationContexts);
+ typeReference.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts);
}
}
TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
@@ -2260,21 +2226,24 @@ public class ClassFile implements TypeConstants, TypeIds {
invisibleTypeAnnotationsCounter);
}
}
-
// update the number of attributes
this.contents[methodAttributeOffset++] = (byte) (attributesNumber >> 8);
this.contents[methodAttributeOffset] = (byte) attributesNumber;
}
-
+
private void dumpLocations(int[] locations) {
- if (locations != null) {
+ if (locations == null) {
+ // no type path
+ if (this.contentsOffset + 1 >= this.contents.length) {
+ resizeContents(1);
+ }
+ this.contents[this.contentsOffset++] = (byte) 0;
+ } else {
int length = locations.length;
- int actualSize = 2 + length;
- if (this.contentsOffset + actualSize >= this.contents.length) {
- resizeContents(actualSize);
+ if (this.contentsOffset + length >= this.contents.length) {
+ resizeContents(length + 1);
}
- this.contents[this.contentsOffset++] = (byte) (length >> 8);
- this.contents[this.contentsOffset++] = (byte) length;
+ this.contents[this.contentsOffset++] = (byte) (locations.length / 2);
for (int i = 0; i < length; i++) {
this.contents[this.contentsOffset++] = (byte) locations[i];
}
@@ -2282,22 +2251,67 @@ public class ClassFile implements TypeConstants, TypeIds {
}
private void dumpTargetTypeContents(int targetType, AnnotationContext annotationContext) {
switch(targetType) {
- case AnnotationTargetTypeConstants.THROWS :
- case AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS :
- case AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY :
- case AnnotationTargetTypeConstants.OBJECT_CREATION :
- case AnnotationTargetTypeConstants.OBJECT_CREATION_GENERIC_OR_ARRAY :
- case AnnotationTargetTypeConstants.CLASS_LITERAL :
- case AnnotationTargetTypeConstants.CLASS_LITERAL_GENERIC_OR_ARRAY :
- case AnnotationTargetTypeConstants.TYPE_INSTANCEOF :
- case AnnotationTargetTypeConstants.TYPE_INSTANCEOF_GENERIC_OR_ARRAY :
- case AnnotationTargetTypeConstants.TYPE_CAST :
- case AnnotationTargetTypeConstants.TYPE_CAST_GENERIC_OR_ARRAY :
+ case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
+ case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
+ // parameter index
+ this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+ break;
+
+ case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
+ // type_parameter_index
+ this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+ // bound_index
+ this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
+ break;
+ case AnnotationTargetTypeConstants.FIELD :
+ case AnnotationTargetTypeConstants.METHOD_RECEIVER :
+ case AnnotationTargetTypeConstants.METHOD_RETURN :
+ // target_info is empty_target
+ break;
+ case AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER :
+ // target_info is parameter index
+ this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+ break;
+
+ case AnnotationTargetTypeConstants.INSTANCEOF :
+ case AnnotationTargetTypeConstants.NEW :
+ case AnnotationTargetTypeConstants.EXCEPTION_PARAMETER :
+ case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE :
+ case AnnotationTargetTypeConstants.METHOD_REFERENCE :
+ // bytecode offset for new/instanceof/method_reference
+ // exception table entry index for exception_parameter
+ this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
+ this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+ break;
+ case AnnotationTargetTypeConstants.CAST :
+ // bytecode offset
+ this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
+ this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+ // type_argument_index not set for cast
+ this.contents[this.contentsOffset++] = (byte)0;
+ break;
+
+ case AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
+ case AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
+ case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
+ case AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
+ // bytecode offset
+ this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
+ this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+ // type_argument_index
+ this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
+ break;
+
+ case AnnotationTargetTypeConstants.CLASS_EXTENDS :
+ case AnnotationTargetTypeConstants.THROWS :
+ // For CLASS_EXTENDS - info is supertype index (-1 = superclass)
+ // For THROWS - info is exception table index
this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
this.contents[this.contentsOffset++] = (byte) annotationContext.info;
break;
+
case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
- case AnnotationTargetTypeConstants.LOCAL_VARIABLE_GENERIC_OR_ARRAY :
+ case AnnotationTargetTypeConstants.RESOURCE_VARIABLE :
int localVariableTableOffset = this.contentsOffset;
LocalVariableBinding localVariable = annotationContext.variableBinding;
int actualSize = 0;
@@ -2328,40 +2342,15 @@ public class ClassFile implements TypeConstants, TypeIds {
this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
this.contents[localVariableTableOffset] = (byte) numberOfEntries;
break;
- case AnnotationTargetTypeConstants.METHOD_PARAMETER :
- case AnnotationTargetTypeConstants.METHOD_PARAMETER_GENERIC_OR_ARRAY :
- this.contents[this.contentsOffset++] = (byte) annotationContext.info;
- break;
- // nothing to do
- // case AnnotationTargetTypeConstants.METHOD_RECEIVER :
- // case AnnotationTargetTypeConstants.METHOD_RECEIVER_GENERIC_OR_ARRAY :
- // break;
- // case AnnotationTargetTypeConstants.FIELD :
- // case AnnotationTargetTypeConstants.FIELD_GENERIC_OR_ARRAY :
- // break;
- case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
- case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
- this.contents[this.contentsOffset++] = (byte) annotationContext.info;
- break;
case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
- case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
- case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY :
- case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY :
this.contents[this.contentsOffset++] = (byte) annotationContext.info;
this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
break;
- case AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL :
- case AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY :
- case AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL :
- case AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY :
- // offset
- this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
- this.contents[this.contentsOffset++] = (byte) annotationContext.info;
- // type index
- this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
}
}
+
+
/**
* INTERNAL USE-ONLY
* This methods returns a char[] representing the file name of the receiver
@@ -3762,13 +3751,17 @@ public class ClassFile implements TypeConstants, TypeIds {
}
return attributesNumber;
}
+
/**
* @param annotationContexts the given annotation contexts
* @param visibleTypeAnnotationsNumber the given number of visible type annotations
* @param invisibleTypeAnnotationsNumber the given number of invisible type annotations
* @return the number of attributes created while dumping the annotations in the .class file
*/
- private int generateRuntimeTypeAnnotations(final AnnotationContext[] annotationContexts, int visibleTypeAnnotationsNumber, int invisibleTypeAnnotationsNumber) {
+ private int generateRuntimeTypeAnnotations(
+ final AnnotationContext[] annotationContexts,
+ int visibleTypeAnnotationsNumber,
+ int invisibleTypeAnnotationsNumber) {
int attributesNumber = 0;
final int length = annotationContexts.length;
@@ -4467,175 +4460,52 @@ public class ClassFile implements TypeConstants, TypeIds {
this.contentsOffset = localContentsOffset;
return 1;
}
-
+
private void generateTypeAnnotation(AnnotationContext annotationContext, int currentOffset) {
- int targetType = annotationContext.targetType;
if (annotationContext.wildcard != null) {
- generateWilcardTypeAnnotation(annotationContext, currentOffset);
- return;
- }
- // common part between type annotation and annotation
- generateAnnotation(annotationContext.annotation, currentOffset);
- if (this.contentsOffset == currentOffset) {
- // error occurred while generating the annotation
+ generateWildcardTypeAnnotation(annotationContext, currentOffset);
return;
}
+
+ int targetType = annotationContext.targetType;
+
int[] locations = Annotation.getLocations(
annotationContext.typeReference,
annotationContext.primaryAnnotations,
annotationContext.annotation,
- annotationContext.annotationsOnDimensions);
- if (locations != null) {
- // convert to GENERIC_OR_ARRAY type
- switch(targetType) {
- case AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS :
- targetType = AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
- targetType = AnnotationTargetTypeConstants.LOCAL_VARIABLE_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.METHOD_PARAMETER :
- targetType = AnnotationTargetTypeConstants.METHOD_PARAMETER_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.FIELD :
- targetType = AnnotationTargetTypeConstants.FIELD_GENERIC_OR_ARRAY;
- break;
-// case AnnotationTargetTypeConstants.METHOD_RECEIVER :
-// // should not happen - possible extension
-// targetType = AnnotationTargetTypeConstants.METHOD_RECEIVER_GENERIC_OR_ARRAY;
-// break;
-// case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
-// // should not happen - possible extension
-// targetType = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY;
-// break;
- case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
- // should not happen - possible extension
- targetType = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY;
- break;
-// case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
-// // should not happen - possible extension
-// targetType = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY;
-// break;
- case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
- // should not happen - possible extension
- targetType = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY;
- break;
-// case AnnotationTargetTypeConstants.THROWS :
-// targetType = AnnotationTargetTypeConstants.THROWS_GENERIC_OR_ARRAY;
- case AnnotationTargetTypeConstants.TYPE_INSTANCEOF:
- targetType = AnnotationTargetTypeConstants.TYPE_INSTANCEOF_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.CLASS_LITERAL:
- targetType = AnnotationTargetTypeConstants.CLASS_LITERAL_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.OBJECT_CREATION:
- targetType = AnnotationTargetTypeConstants.OBJECT_CREATION_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.TYPE_CAST:
- targetType = AnnotationTargetTypeConstants.TYPE_CAST_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL :
- targetType = AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL :
- targetType = AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.METHOD_RETURN_TYPE :
- targetType = AnnotationTargetTypeConstants.METHOD_RETURN_TYPE_GENERIC_OR_ARRAY;
- }
- }
- // reserve enough space
+ annotationContext.annotationsOnDimensions,
+ annotationContext.dimensions);
+
if (this.contentsOffset + 5 >= this.contents.length) {
resizeContents(5);
}
this.contents[this.contentsOffset++] = (byte) targetType;
dumpTargetTypeContents(targetType, annotationContext);
dumpLocations(locations);
- }
-
- private void generateWilcardTypeAnnotation(AnnotationContext annotationContext, int currentOffset) {
+
// common part between type annotation and annotation
generateAnnotation(annotationContext.annotation, currentOffset);
- if (this.contentsOffset == currentOffset) {
- // error occurred while generating the annotation
- return;
- }
- int[] wildcardLocations = getWildcardLocations(annotationContext.typeReference, annotationContext.wildcard);
+ }
+
+ private void generateWildcardTypeAnnotation(AnnotationContext annotationContext, int currentOffset) {
int targetType = annotationContext.targetType;
- switch(targetType) {
- case AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS :
- targetType = AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
- targetType = AnnotationTargetTypeConstants.LOCAL_VARIABLE_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.METHOD_PARAMETER :
- targetType = AnnotationTargetTypeConstants.METHOD_PARAMETER_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.FIELD :
- targetType = AnnotationTargetTypeConstants.FIELD_GENERIC_OR_ARRAY;
- break;
-// case AnnotationTargetTypeConstants.METHOD_RECEIVER :
-// // should not happen - possible extension
-// targetType = AnnotationTargetTypeConstants.METHOD_RECEIVER_GENERIC_OR_ARRAY;
-// break;
-// case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
-// // should not happen - possible extension
-// targetType = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY;
-// break;
-// case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
-// // should not happen - possible extension
-// targetType = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY;
-// break;
-// case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
-// // should not happen - possible extension
-// targetType = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY;
-// break;
-// case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
-// // should not happen - possible extension
-// targetType = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY;
-// break;
-// case AnnotationTargetTypeConstants.THROWS :
-// targetType = AnnotationTargetTypeConstants.THROWS_GENERIC_OR_ARRAY;
- case AnnotationTargetTypeConstants.TYPE_INSTANCEOF:
- targetType = AnnotationTargetTypeConstants.TYPE_INSTANCEOF_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.CLASS_LITERAL:
- targetType = AnnotationTargetTypeConstants.CLASS_LITERAL_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.OBJECT_CREATION:
- targetType = AnnotationTargetTypeConstants.OBJECT_CREATION_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.TYPE_CAST:
- targetType = AnnotationTargetTypeConstants.TYPE_CAST_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL :
- targetType = AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL :
- targetType = AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY;
- break;
- case AnnotationTargetTypeConstants.METHOD_RETURN_TYPE :
- targetType = AnnotationTargetTypeConstants.METHOD_RETURN_TYPE_GENERIC_OR_ARRAY;
- }
+
int[] locations = Annotation.getLocations(
- annotationContext.wildcard.bound,
+ annotationContext.typeReference,
null,
annotationContext.annotation,
- null);
+ null,
+ 0);
// reserve enough space
if (this.contentsOffset + 5 >= this.contents.length) {
resizeContents(5);
}
- this.contents[this.contentsOffset++] =
- (byte) (locations != null ?
- AnnotationTargetTypeConstants.WILDCARD_BOUND_GENERIC_OR_ARRAY :
- AnnotationTargetTypeConstants.WILDCARD_BOUND);
this.contents[this.contentsOffset++] = (byte) targetType;
dumpTargetTypeContents(targetType, annotationContext);
- dumpLocations(wildcardLocations);
dumpLocations(locations);
+ generateAnnotation(annotationContext.annotation, currentOffset);
}
+
private int generateTypeAnnotationAttributeForTypeDeclaration() {
TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
if ((typeDeclaration.bits & ASTNode.HasTypeAnnotations) == 0) {
@@ -4647,7 +4517,7 @@ public class ClassFile implements TypeConstants, TypeIds {
TypeReference superclass = typeDeclaration.superclass;
List allTypeAnnotationContexts = new ArrayList();
if (superclass != null && (superclass.bits & ASTNode.HasTypeAnnotations) != 0) {
- superclass.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS, -1, allTypeAnnotationContexts);
+ superclass.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS, -1, allTypeAnnotationContexts);
}
TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
if (superInterfaces != null) {
@@ -4656,7 +4526,7 @@ public class ClassFile implements TypeConstants, TypeIds {
if ((superInterface.bits & ASTNode.HasTypeAnnotations) == 0) {
continue;
}
- superInterface.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS, i, allTypeAnnotationContexts);
+ superInterface.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS, i, allTypeAnnotationContexts);
}
}
TypeParameter[] typeParameters = typeDeclaration.typeParameters;
@@ -4690,6 +4560,9 @@ public class ClassFile implements TypeConstants, TypeIds {
return attributesNumber;
}
+
+
+
private int generateVarargsAttribute() {
int localContentsOffset = this.contentsOffset;
/*
@@ -5148,7 +5021,7 @@ public class ClassFile implements TypeConstants, TypeIds {
this.produceAttributes = options.produceDebugAttributes;
if (this.targetJDK >= ClassFileConstants.JDK1_6) {
this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE;
- if (this.targetJDK >= ClassFileConstants.JDK1_7) {
+ if (this.targetJDK >= ClassFileConstants.JDK1_8) {
this.produceAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION;
}
} else if (this.targetJDK == ClassFileConstants.CLDC_1_1) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
index 64709c909..538c3ee7d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
@@ -17,6 +17,8 @@
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 365662 - [compiler][null] warn on contradictory and redundant null annotations
* bug 331649 - [compiler][null] consider null annotations for fields
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -47,47 +49,44 @@ public abstract class Annotation extends Expression {
final TypeReference reference,
final Annotation[] primaryAnnotation,
final Annotation annotation,
- final Annotation[][] annotationsOnDimensionsOnExpression) {
+ final Annotation[][] annotationsOnDimensionsOnExpression,
+ final int dimensions) {
+
class LocationCollector extends ASTVisitor {
- Stack currentIndexes;
+ Stack typePathEntries;
Annotation currentAnnotation;
boolean search = true;
public LocationCollector(Annotation currentAnnotation) {
- this.currentIndexes = new Stack();
+ this.typePathEntries = new Stack();
this.currentAnnotation = currentAnnotation;
}
- public boolean visit(ArrayTypeReference typeReference, BlockScope scope) {
+
+ public boolean visit(ParameterizedSingleTypeReference typeReference, BlockScope scope) {
if (!this.search) return false;
+
Annotation[][] annotationsOnDimensions = typeReference.annotationsOnDimensions;
if (annotationsOnDimensions != null) {
- // check if the annotation is located on the first dimension
- Annotation[] annotations = annotationsOnDimensions[0];
- if (annotations != null) {
- for (int j = 0, max2 = annotations.length; j < max2; j++) {
- Annotation current = annotations[j];
- if (current == this.currentAnnotation) {
- this.search = false;
- return false;
- }
- }
- }
-
- this.currentIndexes.push(new Integer(0));
- for (int i = 1, max = annotationsOnDimensions.length; i < max; i++) {
- annotations = annotationsOnDimensions[i];
+ for (int i = 0, max = annotationsOnDimensions.length; i < max; i++) {
+ Annotation[] annotations = annotationsOnDimensions[i];
if (annotations != null) {
for (int j = 0, max2 = annotations.length; j < max2; j++) {
Annotation current = annotations[j];
if (current == this.currentAnnotation) {
+ // found it, push any relevant type path entries
+ for (int k = 0; k < i; k++) {
+ this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+ }
this.search = false;
return false;
}
}
}
- this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
+
}
}
+
+ // Example cases handled here: @B(1) List<String>[]
Annotation[][] annotations = typeReference.annotations;
if (annotations == null) {
annotations = new Annotation[][] { primaryAnnotation };
@@ -99,91 +98,99 @@ public abstract class Annotation extends Expression {
for (int j = 0; j < annotationsLength; j++) {
if (current[j] == this.currentAnnotation) {
this.search = false;
+ // Found it, insert any necessary type path elements
+ for (int k = 0; k < typeReference.dimensions; k++) {
+ this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+ }
return false;
}
}
}
- this.currentIndexes.pop();
+
+ // If a type argument is annotated it is necessary jump past the array elements
+ if (typeReference.dimensions != 0) {
+ for (int k = 0, maxk = typeReference.dimensions; k < maxk; k++) {
+ this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+ }
+ }
+ TypeReference[] typeReferences = typeReference.typeArguments;
+ for (int i = 0, max = typeReferences.length; i < max; i++) {
+ this.typePathEntries.add(new int[]{3,i});
+ typeReferences[i].traverse(this, scope);
+ if (!this.search) {
+ return false;
+ } else {
+ this.typePathEntries.pop();
+ }
+ }
+ if (typeReference.dimensions != 0) {
+ for (int k = 0, maxk = typeReference.dimensions; k < maxk; k++) {
+ this.typePathEntries.pop();
+ }
+ }
return true;
}
- public boolean visit(ArrayQualifiedTypeReference typeReference, BlockScope scope) {
+
+ public boolean visit(SingleTypeReference typeReference, BlockScope scope) {
if (!this.search) return false;
- Annotation[][] annotationsOnDimensions = typeReference.annotationsOnDimensions;
- if (annotationsOnDimensions != null) {
- // check if the annotation is located on the first dimension
- Annotation[] annotations = annotationsOnDimensions[0];
- if (annotations != null) {
- for (int j = 0, max2 = annotations.length; j < max2; j++) {
- Annotation current = annotations[j];
- if (current == this.currentAnnotation) {
- this.search = false;
- return false;
- }
- }
- }
- this.currentIndexes.push(new Integer(0));
- for (int i = 1, max = annotationsOnDimensions.length; i < max; i++) {
- annotations = annotationsOnDimensions[i];
- if (annotations != null) {
- for (int j = 0, max2 = annotations.length; j < max2; j++) {
- Annotation current = annotations[j];
- if (current == this.currentAnnotation) {
- this.search = false;
- return false;
- }
- }
- }
- this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
+ // depth allows for the syntax "outerInstance.new @A InnerType();"
+ int depth = 0;
+ if (typeReference.resolvedType instanceof ReferenceBinding) {
+ depth = getInnerDepth((ReferenceBinding)typeReference.resolvedType);
+ }
+
+ if (dimensions != 0) {
+ for (int k = 0; k < dimensions; k++) {
+ this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
}
}
Annotation[][] annotations = typeReference.annotations;
- if (annotations == null) {
- annotations = new Annotation[][] { primaryAnnotation };
- }
- int annotationsLevels = annotations.length;
+ int annotationsLevels = annotations == null ? 0 : annotations.length;
for (int i = 0; i < annotationsLevels; i++) {
Annotation [] current = annotations[i];
int annotationsLength = current == null ? 0 : current.length;
for (int j = 0; j < annotationsLength; j++) {
if (current[j] == this.currentAnnotation) {
+ // Found
this.search = false;
+ if (depth != 0) {
+ for (int k = 0; k<depth; k++) {
+ this.typePathEntries.add(TYPE_PATH_INNER_TYPE);
+ }
+ }
return false;
}
}
}
- this.currentIndexes.pop();
- return true;
+ if (dimensions != 0) {
+ for (int k = 0; k < dimensions; k++) {
+ this.typePathEntries.pop();
+ }
+ }
+ return false;
}
- public boolean visit(ParameterizedSingleTypeReference typeReference, BlockScope scope) {
+
+ public boolean visit(ArrayTypeReference typeReference, BlockScope scope) {
if (!this.search) return false;
+
Annotation[][] annotationsOnDimensions = typeReference.annotationsOnDimensions;
if (annotationsOnDimensions != null) {
- // check if the annotation is located on the first dimension
- Annotation[] annotations = annotationsOnDimensions[0];
- if (annotations != null) {
- for (int j = 0, max2 = annotations.length; j < max2; j++) {
- Annotation current = annotations[j];
- if (current == this.currentAnnotation) {
- this.search = false;
- return false;
- }
- }
- }
-
- this.currentIndexes.push(new Integer(0));
- for (int i = 1, max = annotationsOnDimensions.length; i < max; i++) {
- annotations = annotationsOnDimensions[i];
+ for (int i = 0, max = annotationsOnDimensions.length; i < max; i++) {
+ Annotation[] annotations = annotationsOnDimensions[i];
if (annotations != null) {
for (int j = 0, max2 = annotations.length; j < max2; j++) {
Annotation current = annotations[j];
if (current == this.currentAnnotation) {
+ for (int k = 0; k < i; k++) {
+ this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+ }
this.search = false;
return false;
}
}
}
- this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
+
}
}
Annotation[][] annotations = typeReference.annotations;
@@ -196,50 +203,36 @@ public abstract class Annotation extends Expression {
int annotationsLength = current == null ? 0 : current.length;
for (int j = 0; j < annotationsLength; j++) {
if (current[j] == this.currentAnnotation) {
+ for (int k = 0, maxk=typeReference.dimensions; k < maxk; k++) {
+ this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+ }
this.search = false;
return false;
}
}
}
- TypeReference[] typeReferences = typeReference.typeArguments;
- this.currentIndexes.push(new Integer(0));
- for (int i = 0, max = typeReferences.length; i < max; i++) {
- typeReferences[i].traverse(this, scope);
- if (!this.search) return false;
- this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
- }
- this.currentIndexes.pop();
return true;
}
- public boolean visit(ParameterizedQualifiedTypeReference typeReference, BlockScope scope) {
+
+ public boolean visit(ArrayQualifiedTypeReference typeReference, BlockScope scope) {
if (!this.search) return false;
Annotation[][] annotationsOnDimensions = typeReference.annotationsOnDimensions;
if (annotationsOnDimensions != null) {
- // check if the annotation is located on the first dimension
- Annotation[] annotations = annotationsOnDimensions[0];
- if (annotations != null) {
- for (int j = 0, max2 = annotations.length; j < max2; j++) {
- Annotation current = annotations[j];
- if (current == this.currentAnnotation) {
- this.search = false;
- return false;
- }
- }
- }
-
- this.currentIndexes.push(new Integer(0));
- for (int i = 1, max = annotationsOnDimensions.length; i < max; i++) {
- annotations = annotationsOnDimensions[i];
+ for (int i = 0, max = annotationsOnDimensions.length; i < max; i++) {
+ Annotation[] annotations = annotationsOnDimensions[i];
if (annotations != null) {
for (int j = 0, max2 = annotations.length; j < max2; j++) {
Annotation current = annotations[j];
if (current == this.currentAnnotation) {
this.search = false;
+ // Found it, insert relevant type path elements
+ for (int k = 0, maxk = i; k < maxk; k++) {
+ this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+ }
return false;
}
}
}
- this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
}
}
Annotation[][] annotations = typeReference.annotations;
@@ -253,130 +246,230 @@ public abstract class Annotation extends Expression {
for (int j = 0; j < annotationsLength; j++) {
if (current[j] == this.currentAnnotation) {
this.search = false;
+ for (int k = 0, maxk=typeReference.dimensions; k < maxk; k++) {
+ this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+ }
return false;
}
}
}
- //TODO it is unclear how to manage annotations located in the first type arguments
- TypeReference[] typeReferences = typeReference.typeArguments[typeReference.typeArguments.length - 1];
- this.currentIndexes.push(new Integer(0));
- for (int i = 0, max = typeReferences.length; i < max; i++) {
- typeReferences[i].traverse(this, scope);
- if (!this.search) return false;
- this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
- }
- this.currentIndexes.pop();
return true;
}
- public boolean visit(SingleTypeReference typeReference, BlockScope scope) {
+
+ public boolean visit(ParameterizedQualifiedTypeReference typeReference, BlockScope scope) {
if (!this.search) return false;
- Annotation[][] annotationsOnDimensions = annotationsOnDimensionsOnExpression;
+
+ // Example case handled by this block: java.util.List<String>[]@A[]
+ Annotation[][] annotationsOnDimensions = typeReference.annotationsOnDimensions;
if (annotationsOnDimensions != null) {
- // check if the annotation is located on the first dimension
- Annotation[] annotations = annotationsOnDimensions[0];
- if (annotations != null) {
- for (int j = 0, max2 = annotations.length; j < max2; j++) {
- Annotation current = annotations[j];
- if (current == this.currentAnnotation) {
- this.search = false;
- return false;
- }
- }
- }
-
- this.currentIndexes.push(new Integer(0));
- for (int i = 1, max = annotationsOnDimensions.length; i < max; i++) {
- annotations = annotationsOnDimensions[i];
+ for (int i = 0, max = annotationsOnDimensions.length; i < max; i++) {
+ Annotation[] annotations = annotationsOnDimensions[i];
if (annotations != null) {
for (int j = 0, max2 = annotations.length; j < max2; j++) {
Annotation current = annotations[j];
if (current == this.currentAnnotation) {
this.search = false;
+ // Found it, insert relevant type path elements
+ for (int k = 0, maxk = i; k < maxk; k++) {
+ this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+ }
return false;
}
}
}
- this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
}
}
+
+ boolean[] needsInnerEntryInfo = computeInnerEntryInfo(typeReference);
+
+ // Example cases handled by this block:
+ // java.util.@A List<String>[][], com.demo.@A Outer.@B Inner<String>, java.util.Map.@A Entry<String,String>
Annotation[][] annotations = typeReference.annotations;
- int annotationsLevels = annotations == null ? 0 : annotations.length;
+ if (annotations == null) {
+ annotations = new Annotation[][] { primaryAnnotation };
+ }
+ int annotationsLevels = annotations.length;
for (int i = 0; i < annotationsLevels; i++) {
Annotation [] current = annotations[i];
int annotationsLength = current == null ? 0 : current.length;
for (int j = 0; j < annotationsLength; j++) {
if (current[j] == this.currentAnnotation) {
this.search = false;
+ // Found, insert any relevant type path elements
+ for (int k = 0, maxk = typeReference.dimensions; k < maxk; k++) {
+ this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+ }
+ // Found, insert any relevant type path elements
+ if (needsInnerEntryInfo != null) {
+ for (int k = 0; k <= i; k++) {
+ if (needsInnerEntryInfo[k]) {
+ this.typePathEntries.push(TYPE_PATH_INNER_TYPE);
+ }
+ }
+ }
return false;
}
}
}
- return false;
+
+ // Example cases handled by this block:
+ // java.util.List<@A String>
+ if (typeReference.dimensions != 0) {
+ for (int k = 0, maxk = typeReference.dimensions; k < maxk; k++) {
+ this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+ }
+ }
+ int toPop = 0;
+ for (int i = 0, max = typeReference.typeArguments.length; i < max; i++) {
+ TypeReference[] typeArgumentsForComponent = typeReference.typeArguments[i];
+ if (needsInnerEntryInfo != null && needsInnerEntryInfo[i]) {
+ this.typePathEntries.push(TYPE_PATH_INNER_TYPE);
+ toPop++;
+ }
+ if (typeArgumentsForComponent != null) {
+ for (int j = 0, max2 = typeArgumentsForComponent.length; j < max2; j++) {
+ this.typePathEntries.push(new int[]{3,j});
+ typeArgumentsForComponent[j].traverse(this,scope);
+ if (!this.search) return false;
+ this.typePathEntries.pop();
+ }
+ }
+ }
+ toPop += typeReference.dimensions;
+ for (int k = 0, maxk = toPop; k < maxk; k++) {
+ this.typePathEntries.pop();
+ }
+ return true;
}
+
public boolean visit(Wildcard typeReference, BlockScope scope) {
if (!this.search) return false;
TypeReference bound = typeReference.bound;
+ this.typePathEntries.push(TYPE_PATH_ANNOTATION_ON_WILDCARD_BOUND);
bound.traverse(this, scope);
+ if (!this.search) {
+ return false;
+ }
+ this.typePathEntries.pop();
return true;
}
+
+ private boolean[] computeInnerEntryInfo(QualifiedTypeReference typeReference) {
+ ReferenceBinding resolvedType = (ReferenceBinding)
+ (typeReference.resolvedType instanceof ArrayBinding ? typeReference.resolvedType.leafComponentType() : typeReference.resolvedType);
+ boolean[] needsInnerEntryInfo = null;
+ if (resolvedType != null && resolvedType.isNestedType()) {
+ // Work backwards computing whether a INNER_TYPE entry is required for each level
+ needsInnerEntryInfo = new boolean[typeReference.tokens.length];
+ int counter = needsInnerEntryInfo.length - 1;
+ ReferenceBinding type = resolvedType;//resolvedType.enclosingType();
+ while (type != null) {
+ needsInnerEntryInfo[counter--] = !type.isStatic();
+ type = type.enclosingType();
+ }
+ }
+ return needsInnerEntryInfo;
+ }
+
+ private int getInnerDepth(ReferenceBinding resolvedType) {
+ int depth = 0;
+ ReferenceBinding type = resolvedType;
+ while (type != null) {
+ depth += (type.isStatic())?0:1;
+ type = type.enclosingType();
+ }
+ return depth;
+ }
+
public boolean visit(QualifiedTypeReference typeReference, BlockScope scope) {
if (!this.search) return false;
+ boolean[] needsInnerEntryInfo = computeInnerEntryInfo(typeReference);
+
+ // Example cases handled by this block:
+ // java.util.@A List, com.demo.@A Outer.@B Inner, java.util.Map.@A Entry
Annotation[][] annotations = typeReference.annotations;
- int annotationsLevels = annotations == null ? 0 : annotations.length;
+ if (annotations == null) {
+ annotations = new Annotation[][] { primaryAnnotation };
+ }
+ int annotationsLevels = annotations.length;
for (int i = 0; i < annotationsLevels; i++) {
Annotation [] current = annotations[i];
int annotationsLength = current == null ? 0 : current.length;
for (int j = 0; j < annotationsLength; j++) {
if (current[j] == this.currentAnnotation) {
this.search = false;
+ // Found, insert any relevant type path elements
+ if (needsInnerEntryInfo != null) {
+ for (int k = 0; k <= i; k++) {
+ if (needsInnerEntryInfo[k]) {
+ this.typePathEntries.push(TYPE_PATH_INNER_TYPE);
+ }
+ }
+ }
return false;
}
}
}
return true;
}
+
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer
.append("search location for ") //$NON-NLS-1$
.append(this.currentAnnotation)
- .append("\ncurrent indexes : ") //$NON-NLS-1$
- .append(this.currentIndexes);
+ .append("\ncurrent type_path entries : "); //$NON-NLS-1$
+ for (int i = 0, maxi = this.typePathEntries.size(); i < maxi; i++) {
+ int[] typePathEntry = (int[]) this.typePathEntries.get(i);
+ buffer
+ .append('(')
+ .append(typePathEntry[0])
+ .append(',')
+ .append(typePathEntry[1])
+ .append(')');
+ }
return String.valueOf(buffer);
}
}
if (reference == null) return null;
LocationCollector collector = new LocationCollector(annotation);
reference.traverse(collector, (BlockScope) null);
- if (collector.currentIndexes.isEmpty()) {
+ if (collector.typePathEntries.isEmpty()) {
return null;
}
- int size = collector.currentIndexes.size();
- int[] result = new int[size];
+ int size = collector.typePathEntries.size();
+ int[] result = new int[size*2];
+ int offset=0;
for (int i = 0; i < size; i++) {
- result[size - i - 1] = ((Integer) collector.currentIndexes.pop()).intValue();
+ int[] pathElement = (int[])collector.typePathEntries.get(i);
+ result[offset++] = pathElement[0];
+ result[offset++] = pathElement[1];
}
return result;
}
-
- // jsr 308
- public static class TypeUseBinding extends ReferenceBinding {
- private int kind;
- public TypeUseBinding(int kind) {
- this.tagBits = 0L;
- this.kind = kind;
- }
- public int kind() {
- return this.kind;
- }
- public boolean hasTypeBit(int bit) {
- return false;
- }
+
+ // jsr 308
+ public static class TypeUseBinding extends ReferenceBinding {
+ private int kind;
+ public TypeUseBinding(int kind) {
+ this.tagBits = 0L;
+ this.kind = kind;
+ }
+ public int kind() {
+ return this.kind;
}
+ public boolean hasTypeBit(int bit) {
+ return false;
+ }
+ }
final static MemberValuePair[] NoValuePairs = new MemberValuePair[0];
private static final long TAGBITS_NULLABLE_OR_NONNULL = TagBits.AnnotationNullable|TagBits.AnnotationNonNull;
+ static final int[] TYPE_PATH_ELEMENT_ARRAY = new int[]{0,0};
+ static final int[] TYPE_PATH_INNER_TYPE = new int[]{1,0};
+ static final int[] TYPE_PATH_ANNOTATION_ON_WILDCARD_BOUND = new int[]{2,0};
+
public int declarationSourceEnd;
public Binding recipient;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java
index 41abbac3d..5f9853175 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java
@@ -17,6 +17,9 @@
* bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
* bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
* bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -68,7 +71,7 @@ public class ArrayAllocationExpression extends Expression {
int pc = codeStream.position;
if (this.initializer != null) {
- this.initializer.generateCode(currentScope, codeStream, valueRequired);
+ this.initializer.generateCode(this.type, this.annotationsOnDimensions, currentScope, codeStream, valueRequired);
return;
}
@@ -83,10 +86,10 @@ public class ArrayAllocationExpression extends Expression {
// array allocation
if (explicitDimCount == 1) {
// Mono-dimensional array
- codeStream.newArray((ArrayBinding)this.resolvedType);
+ codeStream.newArray(this.type, this.annotationsOnDimensions, (ArrayBinding)this.resolvedType);
} else {
// Multi-dimensional array
- codeStream.multianewarray(this.resolvedType, explicitDimCount);
+ codeStream.multianewarray(this.type, this.resolvedType, this.dimensions.length, this.annotationsOnDimensions);
}
if (valueRequired) {
codeStream.generateImplicitConversion(this.implicitConversion);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
index 0a4d71b17..d39eeef47 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
@@ -15,6 +15,8 @@
* bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
* bug 370639 - [compiler][resource] restore the default for resource leak warnings
* bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -52,16 +54,20 @@ public class ArrayInitializer extends Expression {
return flowInfo;
}
+ public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+ generateCode(null, null, currentScope, codeStream, valueRequired);
+ }
+
/**
* Code generation for a array initializer
*/
- public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+ public void generateCode(TypeReference typeReference, Annotation[][] annotationsOnDimensions, BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
// Flatten the values and compute the dimensions, by iterating in depth into nested array initializers
int pc = codeStream.position;
int expressionLength = (this.expressions == null) ? 0: this.expressions.length;
codeStream.generateInlinedValue(expressionLength);
- codeStream.newArray(null, this.binding);
+ codeStream.newArray(typeReference, annotationsOnDimensions, this.binding);
if (this.expressions != null) {
// binding is an ArrayType, so I can just deal with the dimension
int elementsTypeID = this.binding.dimensions > 1 ? -1 : this.binding.leafComponentType.id;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
index 4a4a314a2..ee461e693 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
@@ -17,6 +17,8 @@
* Stephan Herrmann - Contribution for
* bug 402028 - [1.8][compiler] null analysis for reference expressions
* bug 404649 - [1.8][compiler] detect illegal reference to indirect or redundant super via I.super.m() syntax
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contribution for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -144,7 +146,8 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
buffer.append(this.resolvedType.constantPoolName());
buffer.append(';');
int invokeDynamicNumber = codeStream.classFile.recordBootstrapMethod(this);
- codeStream.invokeDynamic(invokeDynamicNumber, argumentsSize, 1, LAMBDA, buffer.toString().toCharArray());
+ codeStream.invokeDynamic(invokeDynamicNumber, argumentsSize, 1, LAMBDA, buffer.toString().toCharArray(),
+ this.isConstructorReference(), (this.lhs instanceof TypeReference? (TypeReference) this.lhs : null), this.typeArguments);
codeStream.recordPositionsFrom(pc, this.sourceStart);
}
@@ -399,9 +402,15 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
if (this.binding.isAbstract() && this.lhs.isSuper())
scope.problemReporter().cannotDireclyInvokeAbstractMethod(this, this.binding);
- if (this.binding.isStatic() && this.binding.declaringClass != this.receiverType)
- scope.problemReporter().indirectAccessToStaticMethod(this, this.binding);
-
+ if (this.binding.isStatic()) {
+ if (this.binding.declaringClass != this.receiverType)
+ scope.problemReporter().indirectAccessToStaticMethod(this, this.binding);
+ } else {
+ AbstractMethodDeclaration srcMethod = this.binding.sourceMethod();
+ if (srcMethod != null && srcMethod.isMethod())
+ srcMethod.bits &= ~ASTNode.CanBeStatic;
+ }
+
if (isMethodUseDeprecated(this.binding, scope, true))
scope.problemReporter().deprecatedMethod(this.binding, this);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
index 6c6bc5cf5..07aad10b3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
@@ -27,6 +27,9 @@
* bug 384380 - False positive on a ?? Potential null pointer access ?? after a continue
* Jesper Steen Moller - Contributions for
* bug 404146 - [1.7][compiler] nested try-catch-finally-blocks leads to unrunnable Java byte code
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -524,7 +527,7 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) {
multiCatchExceptionLabel.initialize((UnionTypeReference) argument.type);
exceptionLabel = multiCatchExceptionLabel;
} else {
- exceptionLabel = new ExceptionLabel(codeStream, argument.binding.type);
+ exceptionLabel = new ExceptionLabel(codeStream, argument.binding.type, argument.type);
}
exceptionLabel.placeStart();
exceptionLabels[i] = exceptionLabel;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
index a8ac20a75..32c906102 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
@@ -16,6 +16,8 @@
* Stephan Herrmann - Contribution for
* bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
* bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -54,207 +56,226 @@ import org.eclipse.objectteams.otdt.internal.core.compiler.util.TSuperHelper;
* @version $Id: TypeReference.java 23404 2010-02-03 14:10:22Z stephan $
*/
public abstract class TypeReference extends Expression {
-
public static final TypeReference[] NO_TYPE_ARGUMENTS = new TypeReference[0];
- static class AnnotationCollector extends ASTVisitor {
- List annotationContexts;
- TypeReference typeReference;
- int targetType;
- Annotation[] primaryAnnotations;
- int info = -1;
- int info2 = -1;
- LocalVariableBinding localVariable;
- Annotation[][] annotationsOnDimensions;
- Wildcard currentWildcard;
-
- public AnnotationCollector(
- TypeParameter typeParameter,
- int targetType,
- int typeParameterIndex,
- List annotationContexts) {
- this.annotationContexts = annotationContexts;
- this.typeReference = typeParameter.type;
- this.targetType = targetType;
- this.primaryAnnotations = typeParameter.annotations;
- this.info = typeParameterIndex;
- }
+static class AnnotationCollector extends ASTVisitor {
+ List annotationContexts;
+ TypeReference typeReference;
+ int targetType;
+ Annotation[] primaryAnnotations;
+ int info = -1;
+ int info2 = -1;
+ LocalVariableBinding localVariable;
+ Annotation[][] annotationsOnDimensions;
+ int dimensions;
+ Wildcard currentWildcard;
+
+ public AnnotationCollector(
+ TypeParameter typeParameter,
+ int targetType,
+ int typeParameterIndex,
+ List annotationContexts) {
+ this.annotationContexts = annotationContexts;
+ this.typeReference = typeParameter.type;
+ this.targetType = targetType;
+ this.primaryAnnotations = typeParameter.annotations;
+ this.info = typeParameterIndex;
+ }
- public AnnotationCollector(
- LocalDeclaration localDeclaration,
- int targetType,
- LocalVariableBinding localVariable,
- List annotationContexts) {
- this.annotationContexts = annotationContexts;
- this.typeReference = localDeclaration.type;
- this.targetType = targetType;
- this.primaryAnnotations = localDeclaration.annotations;
- this.localVariable = localVariable;
- }
+ public AnnotationCollector(
+ LocalDeclaration localDeclaration,
+ int targetType,
+ LocalVariableBinding localVariable,
+ List annotationContexts) {
+ this.annotationContexts = annotationContexts;
+ this.typeReference = localDeclaration.type;
+ this.targetType = targetType;
+ this.primaryAnnotations = localDeclaration.annotations;
+ this.localVariable = localVariable;
+ }
- public AnnotationCollector(
- LocalDeclaration localDeclaration,
- int targetType,
- int parameterIndex,
- List annotationContexts) {
- this.annotationContexts = annotationContexts;
- this.typeReference = localDeclaration.type;
- this.targetType = targetType;
- this.primaryAnnotations = localDeclaration.annotations;
- this.info = parameterIndex;
- }
+ public AnnotationCollector(
+ LocalDeclaration localDeclaration,
+ int targetType,
+ int parameterIndex,
+ List annotationContexts) {
+ this.annotationContexts = annotationContexts;
+ this.typeReference = localDeclaration.type;
+ this.targetType = targetType;
+ this.primaryAnnotations = localDeclaration.annotations;
+ this.info = parameterIndex;
+ }
- public AnnotationCollector(
- MethodDeclaration methodDeclaration,
- int targetType,
- List annotationContexts) {
- this.annotationContexts = annotationContexts;
- this.typeReference = methodDeclaration.returnType;
- this.targetType = targetType;
- this.primaryAnnotations = methodDeclaration.annotations;
- }
+ public AnnotationCollector(
+ MethodDeclaration methodDeclaration,
+ int targetType,
+ List annotationContexts) {
+ this.annotationContexts = annotationContexts;
+ this.typeReference = methodDeclaration.returnType;
+ this.targetType = targetType;
+ this.primaryAnnotations = methodDeclaration.annotations;
+ }
- public AnnotationCollector(
- FieldDeclaration fieldDeclaration,
- int targetType,
- List annotationContexts) {
- this.annotationContexts = annotationContexts;
- this.typeReference = fieldDeclaration.type;
- this.targetType = targetType;
- this.primaryAnnotations = fieldDeclaration.annotations;
- }
- public AnnotationCollector(
- TypeReference typeReference,
- int targetType,
- List annotationContexts) {
- this.annotationContexts = annotationContexts;
- this.typeReference = typeReference;
- this.targetType = targetType;
- }
- public AnnotationCollector(
- TypeReference typeReference,
- int targetType,
- int info,
- List annotationContexts) {
- this.annotationContexts = annotationContexts;
- this.typeReference = typeReference;
- this.info = info;
- this.targetType = targetType;
- }
- public AnnotationCollector(
- TypeReference typeReference,
- int targetType,
- int info,
- int typeIndex,
- List annotationContexts) {
- this.annotationContexts = annotationContexts;
- this.typeReference = typeReference;
- this.info = info;
- this.targetType = targetType;
- this.info2 = typeIndex;
- }
- public AnnotationCollector(
- TypeReference typeReference,
- int targetType,
- int info,
- List annotationContexts,
- Annotation[][] annotationsOnDimensions) {
- this.annotationContexts = annotationContexts;
- this.typeReference = typeReference;
- this.info = info;
- this.targetType = targetType;
- this.annotationsOnDimensions = annotationsOnDimensions;
+ public AnnotationCollector(
+ FieldDeclaration fieldDeclaration,
+ int targetType,
+ List annotationContexts) {
+ this.annotationContexts = annotationContexts;
+ this.typeReference = fieldDeclaration.type;
+ this.targetType = targetType;
+ this.primaryAnnotations = fieldDeclaration.annotations;
+ }
+ public AnnotationCollector(
+ TypeReference typeReference,
+ int targetType,
+ List annotationContexts) {
+ this.annotationContexts = annotationContexts;
+ this.typeReference = typeReference;
+ this.targetType = targetType;
+ }
+ public AnnotationCollector(
+ TypeReference typeReference,
+ int targetType,
+ int info,
+ List annotationContexts) {
+ this.annotationContexts = annotationContexts;
+ this.typeReference = typeReference;
+ this.info = info;
+ this.targetType = targetType;
+ }
+ public AnnotationCollector(
+ TypeReference typeReference,
+ int targetType,
+ int info,
+ int typeIndex,
+ List annotationContexts) {
+ this.annotationContexts = annotationContexts;
+ this.typeReference = typeReference;
+ this.info = info;
+ this.targetType = targetType;
+ this.info2 = typeIndex;
+ }
+ public AnnotationCollector(
+ TypeReference typeReference,
+ int targetType,
+ int info,
+ List annotationContexts,
+ Annotation[][] annotationsOnDimensions,
+ int dimensions) {
+ this.annotationContexts = annotationContexts;
+ this.typeReference = typeReference;
+ this.info = info;
+ this.targetType = targetType;
+ this.annotationsOnDimensions = annotationsOnDimensions;
+ // Array references like 'new String[]' manifest as an ArrayAllocationExpression
+ // with a 'type' of String. When the type is not carrying the dimensions count
+ // it is passed in via the dimensions parameter. It is not possible to use
+ // annotationsOnDimensions as it will be null if there are no annotations on any
+ // of the dimensions.
+ this.dimensions = dimensions;
+ }
+
+ private boolean internalVisit(Annotation annotation) {
+ AnnotationContext annotationContext = null;
+ if (annotation.isRuntimeTypeInvisible()) {
+ annotationContext = new AnnotationContext(annotation, this.typeReference, this.targetType, this.primaryAnnotations, AnnotationContext.INVISIBLE, this.annotationsOnDimensions, this.dimensions);
+ } else if (annotation.isRuntimeTypeVisible()) {
+ annotationContext = new AnnotationContext(annotation, this.typeReference, this.targetType, this.primaryAnnotations, AnnotationContext.VISIBLE, this.annotationsOnDimensions, this.dimensions);
}
- private boolean internalVisit(Annotation annotation) {
- AnnotationContext annotationContext = null;
- if (annotation.isRuntimeTypeInvisible()) {
- annotationContext = new AnnotationContext(annotation, this.typeReference, this.targetType, this.primaryAnnotations, AnnotationContext.INVISIBLE, this.annotationsOnDimensions);
- } else if (annotation.isRuntimeTypeVisible()) {
- annotationContext = new AnnotationContext(annotation, this.typeReference, this.targetType, this.primaryAnnotations, AnnotationContext.VISIBLE, this.annotationsOnDimensions);
+ if (annotationContext != null) {
+ annotationContext.wildcard = this.currentWildcard;
+ switch(this.targetType) {
+ case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
+ case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
+ case AnnotationTargetTypeConstants.CLASS_EXTENDS:
+ case AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER :
+ case AnnotationTargetTypeConstants.THROWS :
+ case AnnotationTargetTypeConstants.EXCEPTION_PARAMETER :
+ case AnnotationTargetTypeConstants.INSTANCEOF:
+ case AnnotationTargetTypeConstants.NEW :
+ case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE :
+ case AnnotationTargetTypeConstants.METHOD_REFERENCE :
+ case AnnotationTargetTypeConstants.CAST:
+ annotationContext.info = this.info;
+ break;
+ case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
+ case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
+ annotationContext.info2 = this.info2;
+ annotationContext.info = this.info;
+ break;
+ case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
+ case AnnotationTargetTypeConstants.RESOURCE_VARIABLE :
+ annotationContext.variableBinding = this.localVariable;
+ break;
+ case AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
+ case AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
+ case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
+ case AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
+ annotationContext.info2 = this.info2;
+ annotationContext.info = this.info;
+ break;
+ case AnnotationTargetTypeConstants.FIELD :
+ case AnnotationTargetTypeConstants.METHOD_RETURN :
+ case AnnotationTargetTypeConstants.METHOD_RECEIVER :
+ break;
+
}
- if (annotationContext != null) {
- annotationContext.wildcard = this.currentWildcard;
- switch(this.targetType) {
- case AnnotationTargetTypeConstants.THROWS :
- case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
- case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
- case AnnotationTargetTypeConstants.METHOD_PARAMETER :
- case AnnotationTargetTypeConstants.TYPE_CAST :
- case AnnotationTargetTypeConstants.TYPE_INSTANCEOF :
- case AnnotationTargetTypeConstants.OBJECT_CREATION :
- case AnnotationTargetTypeConstants.CLASS_LITERAL :
- case AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS:
- annotationContext.info = this.info;
- break;
- case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
- case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
- annotationContext.info2 = this.info2;
- annotationContext.info = this.info;
- break;
- case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
- annotationContext.variableBinding = this.localVariable;
- break;
- case AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL :
- case AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL :
- annotationContext.info2 = this.info2;
- annotationContext.info = this.info;
- }
- this.annotationContexts.add(annotationContext);
- }
- return true;
- }
- public boolean visit(MarkerAnnotation annotation, BlockScope scope) {
- return internalVisit(annotation);
+ this.annotationContexts.add(annotationContext);
}
- public boolean visit(NormalAnnotation annotation, BlockScope scope) {
- return internalVisit(annotation);
- }
- public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) {
- return internalVisit(annotation);
- }
- public boolean visit(Wildcard wildcard, BlockScope scope) {
- this.currentWildcard = wildcard;
+ return true;
+ }
+ public boolean visit(MarkerAnnotation annotation, BlockScope scope) {
+ return internalVisit(annotation);
+ }
+ public boolean visit(NormalAnnotation annotation, BlockScope scope) {
+ return internalVisit(annotation);
+ }
+ public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) {
+ return internalVisit(annotation);
+ }
+ public boolean visit(Wildcard wildcard, BlockScope scope) {
+ this.currentWildcard = wildcard;
+ return true;
+ }
+ public boolean visit(Argument argument, BlockScope scope) {
+ if ((argument.bits & ASTNode.IsUnionType) == 0) {
return true;
}
- public boolean visit(Argument argument, BlockScope scope) {
- if ((argument.bits & ASTNode.IsUnionType) == 0) {
+ for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
+ int startPC = this.localVariable.initializationPCs[i << 1];
+ int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
+ if (startPC != endPC) { // only entries for non zero length
return true;
}
- for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
- int startPC = this.localVariable.initializationPCs[i << 1];
- int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
- if (startPC != endPC) { // only entries for non zero length
- return true;
- }
- }
- return false;
}
- public boolean visit(Argument argument, ClassScope scope) {
- if ((argument.bits & ASTNode.IsUnionType) == 0) {
+ return false;
+ }
+ public boolean visit(Argument argument, ClassScope scope) {
+ if ((argument.bits & ASTNode.IsUnionType) == 0) {
+ return true;
+ }
+ for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
+ int startPC = this.localVariable.initializationPCs[i << 1];
+ int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
+ if (startPC != endPC) { // only entries for non zero length
return true;
}
- for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
- int startPC = this.localVariable.initializationPCs[i << 1];
- int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
- if (startPC != endPC) { // only entries for non zero length
- return true;
- }
- }
- return false;
}
- public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) {
- for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
- int startPC = this.localVariable.initializationPCs[i << 1];
- int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
- if (startPC != endPC) { // only entries for non zero length
- return true;
- }
+ return false;
+ }
+ public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) {
+ for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
+ int startPC = this.localVariable.initializationPCs[i << 1];
+ int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
+ if (startPC != endPC) { // only entries for non zero length
+ return true;
}
- return false;
- }
- public void endVisit(Wildcard wildcard, BlockScope scope) {
- this.currentWildcard = null;
}
+ return false;
}
+ public void endVisit(Wildcard wildcard, BlockScope scope) {
+ this.currentWildcard = null;
+ }
+}
//{ObjectTeams: for baseclass decapsulation (implement interface from Expression):
private DecapsulationState baseclassDecapsulation = DecapsulationState.NONE;
@@ -275,7 +296,7 @@ public int deprecationProblemId = IProblem.UsingDeprecatedType;
/*
* Answer a base type reference (can be an array of base type).
*/
-public static final TypeReference baseTypeReference(int baseType, int dim, Annotation[][] dimAnnotations) {
+public static final TypeReference baseTypeReference(int baseType, int dim, Annotation [][] dimAnnotations) {
if (dim == 0) {
switch (baseType) {
@@ -363,12 +384,9 @@ public void getAllAnnotationContexts(int targetType, int info, List allAnnotatio
}
/**
* info can be either a type index (superclass/superinterfaces) or a pc into the bytecode
- * @param targetType
- * @param info
- * @param allAnnotationContexts
*/
-public void getAllAnnotationContexts(int targetType, int info, List allAnnotationContexts, Annotation[][] annotationsOnDimensions) {
- AnnotationCollector collector = new AnnotationCollector(this, targetType, info, allAnnotationContexts, annotationsOnDimensions);
+public void getAllAnnotationContexts(int targetType, int info, List allAnnotationContexts, Annotation[][] annotationsOnDimensions, int dimensions) {
+ AnnotationCollector collector = new AnnotationCollector(this, targetType, info, allAnnotationContexts, annotationsOnDimensions, dimensions);
this.traverse(collector, (BlockScope) null);
if (annotationsOnDimensions != null) {
for (int i = 0, max = annotationsOnDimensions.length; i < max; i++) {
@@ -593,7 +611,6 @@ public boolean isWildcard() {
public boolean isParameterizedTypeReference() {
return false;
}
-
protected void reportDeprecatedType(TypeBinding type, Scope scope, int index) {
scope.problemReporter().deprecatedType(type, this, index);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationContext.java
index 75de873ef..c743d436f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationContext.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 IBM Corporation and others.
+ * Copyright (c) 2012, 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
@@ -11,6 +11,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen;
@@ -32,6 +34,9 @@ public class AnnotationContext {
public LocalVariableBinding variableBinding;
public Annotation[][] annotationsOnDimensions;
public Wildcard wildcard;
+ // annotationsOnDimensions might be null but the dimensions may still be important. In some
+ // cases they are not on the reference.
+ public int dimensions;
public AnnotationContext(
Annotation annotation,
@@ -39,13 +44,15 @@ public class AnnotationContext {
int targetType,
Annotation[] primaryAnnotations,
int visibility,
- Annotation[][] annotationsOnDimensions) {
+ Annotation[][] annotationsOnDimensions,
+ int dimensions) {
this.annotation = annotation;
this.typeReference = typeReference;
this.targetType = targetType;
this.primaryAnnotations = primaryAnnotations;
this.visibility = visibility;
this.annotationsOnDimensions = annotationsOnDimensions;
+ this.dimensions = dimensions;
}
public String toString() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationTargetTypeConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationTargetTypeConstants.java
index ad66617ce..919247a9e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationTargetTypeConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationTargetTypeConstants.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 IBM Corporation and others.
+ * Copyright (c) 2012, 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
@@ -11,44 +11,39 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen;
public interface AnnotationTargetTypeConstants {
- int METHOD_RECEIVER = 0x06;
- int METHOD_RECEIVER_GENERIC_OR_ARRAY = 0x07;
- int METHOD_RETURN_TYPE = 0x0A;
- int METHOD_RETURN_TYPE_GENERIC_OR_ARRAY = 0x0B;
- int METHOD_PARAMETER = 0x0C;
- int METHOD_PARAMETER_GENERIC_OR_ARRAY = 0x0D;
- int FIELD = 0x0E;
- int FIELD_GENERIC_OR_ARRAY = 0x0F;
- int CLASS_TYPE_PARAMETER_BOUND = 0x10;
- int CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY = 0x11;
- int METHOD_TYPE_PARAMETER_BOUND = 0x12;
- int METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY = 0x13;
- int CLASS_EXTENDS_IMPLEMENTS = 0x14;
- int CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY = 0x15;
- int THROWS = 0x16;
- int THROWS_GENERIC_OR_ARRAY = 0x17;
- int WILDCARD_BOUND = 0x1C;
- int WILDCARD_BOUND_GENERIC_OR_ARRAY = 0x1D;
- int METHOD_TYPE_PARAMETER = 0x20;
- int METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY = 0x21;
- int CLASS_TYPE_PARAMETER = 0x22;
- int CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY = 0x23;
- int TYPE_CAST = 0x00;
- int TYPE_CAST_GENERIC_OR_ARRAY = 0x01;
- int TYPE_INSTANCEOF = 0x02;
- int TYPE_INSTANCEOF_GENERIC_OR_ARRAY = 0x03;
- int OBJECT_CREATION = 0x04;
- int OBJECT_CREATION_GENERIC_OR_ARRAY = 0x05;
- int LOCAL_VARIABLE = 0x08;
- int LOCAL_VARIABLE_GENERIC_OR_ARRAY = 0x09;
- int TYPE_ARGUMENT_CONSTRUCTOR_CALL = 0x18;
- int TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY = 0x19;
- int TYPE_ARGUMENT_METHOD_CALL = 0x1A;
- int TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY = 0x1B;
- int CLASS_LITERAL = 0x1E;
- int CLASS_LITERAL_GENERIC_OR_ARRAY = 0x1F;
+
+ // Targets for type parameter declarations
+ int CLASS_TYPE_PARAMETER = 0x00;
+ int METHOD_TYPE_PARAMETER = 0x01;
+
+ // Targets that may be externally visible in classes and members
+ int CLASS_EXTENDS = 0x10;
+ int CLASS_TYPE_PARAMETER_BOUND = 0x11;
+ int METHOD_TYPE_PARAMETER_BOUND = 0x12;
+ int FIELD = 0x13;
+ int METHOD_RETURN = 0x14;
+ int METHOD_RECEIVER = 0x15;
+ int METHOD_FORMAL_PARAMETER = 0x16;
+ int THROWS = 0x17;
+
+ // Targets for type uses that occur only within code blocks
+ int LOCAL_VARIABLE = 0x40;
+ int RESOURCE_VARIABLE = 0x41;
+ int EXCEPTION_PARAMETER = 0x42;
+ int INSTANCEOF = 0x43;
+ int NEW = 0x44;
+ int CONSTRUCTOR_REFERENCE = 0x45;
+ int METHOD_REFERENCE = 0x46;
+ int CAST = 0x47;
+ int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
+ int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
+ int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
+ int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
+
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index 48f2e7a4b..6558a942e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -22,6 +22,8 @@
* bug 391376 - [1.8] check interaction of default methods with bridge methods and generics
* Jesper S Moller - Contributions for
* Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen;
@@ -692,9 +694,11 @@ public void checkcast(int baseId) {
writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName));
}
}
+
public void checkcast(TypeBinding typeBinding) {
this.checkcast(null, typeBinding);
}
+
public void checkcast(TypeReference typeReference, TypeBinding typeBinding) {
/* We use a slightly sub-optimal generation for intersection casts by resorting to a runtime cast for every intersecting type, but in
reality this should not matter. In its intended use form such as (I & Serializable) () -> {}, no cast is emitted at all
@@ -710,6 +714,7 @@ public void checkcast(TypeReference typeReference, TypeBinding typeBinding) {
writeUnsignedShort(this.constantPool.literalIndexForType(types[i]));
}
}
+
public void d2f() {
this.countLabels = 0;
this.stackDepth--;
@@ -1774,13 +1779,11 @@ public void generateBoxingConversion(int unboxedTypeID) {
}
}
}
-public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
- this.generateClassLiteralAccessForType(null, accessedType, syntheticFieldBinding);
-}
+
/**
* Macro for building a class descriptor object
*/
-public void generateClassLiteralAccessForType(TypeReference typeReference, TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
+public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
if (accessedType.isBaseType() && accessedType != TypeBinding.NULL) {
getTYPE(accessedType.id);
return;
@@ -2570,7 +2573,7 @@ public void generateSyntheticBodyForFactoryMethod(SyntheticMethodBinding methodB
public void generateSyntheticBodyForEnumValueOf(SyntheticMethodBinding methodBinding) {
initializeMaxLocals(methodBinding);
final ReferenceBinding declaringClass = methodBinding.declaringClass;
- generateClassLiteralAccessForType(null, declaringClass, null);
+ generateClassLiteralAccessForType(declaringClass, null);
aload_0();
invokeJavaLangEnumvalueOf(declaringClass);
this.checkcast(declaringClass);
@@ -4052,11 +4055,17 @@ public boolean inlineForwardReferencesFromLabelsTargeting(BranchLabel targetLabe
}
return (chaining & (L_OPTIMIZABLE|L_CANNOT_OPTIMIZE)) == L_OPTIMIZABLE; // check was some standards, and no case/recursive
}
+
+/**
+ * We didn't call it instanceof because there is a conflict with the
+ * instanceof keyword
+ */
public void instance_of(TypeBinding typeBinding) {
this.instance_of(null, typeBinding);
}
+
/**
- * We didn't call it instanceof because there is a conflit with the
+ * We didn't call it instanceof because there is a conflict with the
* instanceof keyword
*/
public void instance_of(TypeReference typeReference, TypeBinding typeBinding) {
@@ -4102,7 +4111,12 @@ protected void invoke(byte opcode, int receiverAndArgsSize, int returnTypeSize,
this.stackMax = this.stackDepth;
}
}
+
public void invokeDynamic(int bootStrapIndex, int argsSize, int returnTypeSize, char[] selector, char[] signature) {
+ this.invokeDynamic(bootStrapIndex, argsSize, returnTypeSize, selector, signature, false, null, null);
+}
+
+public void invokeDynamic(int bootStrapIndex, int argsSize, int returnTypeSize, char[] selector, char[] signature, boolean isConstructorReference, TypeReference lhsTypeReference, TypeReference [] typeArguments) {
if (this.classFileOffset + 4 >= this.bCodeStream.length) {
resizeByteArray();
}
@@ -4117,6 +4131,11 @@ public void invokeDynamic(int bootStrapIndex, int argsSize, int returnTypeSize,
this.stackMax = this.stackDepth;
}
}
+
+public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declaringClass) {
+ this.invoke(opcode, methodBinding, declaringClass, null);
+}
+
public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declaringClass, TypeReference[] typeArguments) {
if (declaringClass == null) declaringClass = methodBinding.declaringClass;
if ((declaringClass.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
@@ -4163,7 +4182,7 @@ public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declari
default:
receiverAndArgsSize++;
break;
- }
+ }
}
}
}
@@ -4265,10 +4284,6 @@ public void invokeGetTeam(ReferenceBinding roleIfc) {
}
// SH}
-public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declaringClass) {
- this.invoke(opcode, methodBinding, declaringClass, null);
-}
-
protected void invokeAccessibleObjectSetAccessible() {
// invokevirtual: java.lang.reflect.AccessibleObject.setAccessible(Z)V;
invoke(
@@ -5907,9 +5922,11 @@ public void monitorexit() {
this.position++;
this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_monitorexit;
}
+
public void multianewarray(TypeBinding typeBinding, int dimensions) {
this.multianewarray(null, typeBinding, dimensions, null);
}
+
public void multianewarray(
TypeReference typeReference,
TypeBinding typeBinding,
@@ -5930,9 +5947,11 @@ public void multianewarray(
// SH}
this.bCodeStream[this.classFileOffset++] = (byte) dimensions;
}
+// We didn't call it new, because there is a conflit with the new keyword
public void new_(TypeBinding typeBinding) {
this.new_(null, typeBinding);
}
+
// We didn't call it new, because there is a conflit with the new keyword
public void new_(TypeReference typeReference, TypeBinding typeBinding) {
this.countLabels = 0;
@@ -5961,10 +5980,16 @@ public void newarray(int array_Type) {
this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_newarray;
this.bCodeStream[this.classFileOffset++] = (byte) array_Type;
}
+
public void newArray(ArrayBinding arrayBinding) {
this.newArray(null, arrayBinding);
}
+
public void newArray(TypeReference typeReference, ArrayBinding arrayBinding) {
+ this.newArray(null, null, arrayBinding);
+}
+
+public void newArray(TypeReference typeReference, Annotation[][] annotationsOnDimensions, ArrayBinding arrayBinding) {
TypeBinding component = arrayBinding.elementsType();
switch (component.id) {
case TypeIds.T_int :
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.java
index 7c2639725..e6e619d1f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.java
@@ -1,16 +1,23 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
* Contributors:
* IBM Corporation - initial API and implementation
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen;
import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
public class ExceptionLabel extends Label {
@@ -18,6 +25,13 @@ public class ExceptionLabel extends Label {
public int ranges[] = {POS_NOT_SET,POS_NOT_SET};
private int count = 0; // incremented each time placeStart or placeEnd is called
public TypeBinding exceptionType;
+ public TypeReference exceptionTypeReference;
+
+public ExceptionLabel(CodeStream codeStream, TypeBinding exceptionType, TypeReference exceptionTypeReference) {
+ super(codeStream);
+ this.exceptionType = exceptionType;
+ this.exceptionTypeReference = exceptionTypeReference;
+}
public ExceptionLabel(CodeStream codeStream, TypeBinding exceptionType) {
super(codeStream);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MultiCatchExceptionLabel.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MultiCatchExceptionLabel.java
index 2d0fc549e..21fc79f2b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MultiCatchExceptionLabel.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MultiCatchExceptionLabel.java
@@ -1,15 +1,23 @@
/*******************************************************************************
- * Copyright (c) 2011 IBM Corporation and others.
+ * Copyright (c) 2011, 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
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen;
+import java.util.List;
+
import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
@@ -27,7 +35,7 @@ public class MultiCatchExceptionLabel extends ExceptionLabel {
int length = typeReferences.length;
this.exceptionLabels = new ExceptionLabel[length];
for (int i = 0; i < length; i++) {
- this.exceptionLabels[i] = new ExceptionLabel(this.codeStream, typeReferences[i].resolvedType);
+ this.exceptionLabels[i] = new ExceptionLabel(this.codeStream, typeReferences[i].resolvedType, typeReferences[i]);
}
}
public void place() {
@@ -52,4 +60,16 @@ public class MultiCatchExceptionLabel extends ExceptionLabel {
}
return temp;
}
+
+ public int getAllAnnotationContexts(int tableIndex, List allTypeAnnotationContexts) {
+ int localCount = 0;
+ for (int i = 0, max = this.exceptionLabels.length; i < max; i++) {
+ ExceptionLabel exceptionLabel = this.exceptionLabels[i];
+ if (exceptionLabel.exceptionTypeReference != null) { // ignore those which cannot be annotated
+ exceptionLabel.exceptionTypeReference.getAllAnnotationContexts(AnnotationTargetTypeConstants.EXCEPTION_PARAMETER, tableIndex + localCount, allTypeAnnotationContexts);
+ }
+ tableIndex++;
+ }
+ return localCount;
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/TypeAnnotationCodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/TypeAnnotationCodeStream.java
index aab6d3a31..e1fb841c2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/TypeAnnotationCodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/TypeAnnotationCodeStream.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 IBM Corporation and others.
+ * Copyright (c) 2012, 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
@@ -11,6 +11,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen;
@@ -23,7 +25,6 @@ import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
@@ -35,82 +36,104 @@ public class TypeAnnotationCodeStream extends StackMapFrameCodeStream {
this.generateAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION;
this.allTypeAnnotationContexts = new ArrayList();
}
- private void addAnnotationContext(TypeReference typeReference, int info, int targetType, Annotation[][] annotationsOnDimensions) {
-// if (this.allTypeAnnotationContexts == null) {
-// this.allTypeAnnotationContexts = new ArrayList();
-// }
- typeReference.getAllAnnotationContexts(targetType, info, this.allTypeAnnotationContexts, annotationsOnDimensions);
+
+ private void addAnnotationContext(TypeReference typeReference, int info, int targetType, Annotation[][] annotationsOnDimensions, int dimensions) {
+ typeReference.getAllAnnotationContexts(targetType, info, this.allTypeAnnotationContexts, annotationsOnDimensions, dimensions);
}
+
private void addAnnotationContext(TypeReference typeReference, int info, int targetType) {
-// if (this.allTypeAnnotationContexts == null) {
-// this.allTypeAnnotationContexts = new ArrayList();
-// }
typeReference.getAllAnnotationContexts(targetType, info, this.allTypeAnnotationContexts);
}
+
private void addAnnotationContext(TypeReference typeReference, int info, int typeIndex, int targetType) {
-// if (this.allTypeAnnotationContexts == null) {
-// this.allTypeAnnotationContexts = new ArrayList();
-// }
typeReference.getAllAnnotationContexts(targetType, info, typeIndex, this.allTypeAnnotationContexts);
}
+
public void instance_of(TypeReference typeReference, TypeBinding typeBinding) {
if (typeReference != null && (typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
- addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.TYPE_INSTANCEOF);
+ addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.INSTANCEOF);
}
super.instance_of(typeReference, typeBinding);
}
+
public void multianewarray(
TypeReference typeReference,
TypeBinding typeBinding,
int dimensions,
Annotation [][] annotationsOnDimensions) {
if (typeReference != null && (typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
- addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.OBJECT_CREATION, annotationsOnDimensions);
+ addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.NEW, annotationsOnDimensions, dimensions);
}
super.multianewarray(typeReference, typeBinding, dimensions, annotationsOnDimensions);
}
+
public void new_(TypeReference typeReference, TypeBinding typeBinding) {
if (typeReference != null && (typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
- addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.OBJECT_CREATION);
+ addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.NEW);
}
super.new_(typeReference, typeBinding);
}
- public void newArray(TypeReference typeReference, ArrayBinding arrayBinding) {
- if (typeReference != null && (typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
- addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.OBJECT_CREATION);
- }
- super.newArray(typeReference, arrayBinding);
- }
- public void generateClassLiteralAccessForType(TypeReference typeReference, TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
+
+ public void newArray(TypeReference typeReference, Annotation[][] annotationsOnDimensions, ArrayBinding arrayBinding) {
if (typeReference != null && (typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
- addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.CLASS_LITERAL);
+ addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.NEW, annotationsOnDimensions, 1);
}
- super.generateClassLiteralAccessForType(typeReference, accessedType, syntheticFieldBinding);
+ super.newArray(typeReference, annotationsOnDimensions, arrayBinding);
}
+
public void checkcast(TypeReference typeReference, TypeBinding typeBinding) {
if (typeReference != null && (typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
- addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.TYPE_CAST);
+ addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.CAST);
}
super.checkcast(typeReference, typeBinding);
}
- public void reset(ClassFile givenClassFile) {
- super.reset(givenClassFile);
- this.allTypeAnnotationContexts = new ArrayList();
- }
- public void init(ClassFile targetClassFile) {
- super.init(targetClassFile);
- this.allTypeAnnotationContexts = new ArrayList();
- }
+
public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declaringClass, TypeReference[] typeArguments) {
if (typeArguments != null) {
int targetType = methodBinding.isConstructor()
- ? AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL
- : AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL;
+ ? AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+ : AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT;
for (int i = 0, max = typeArguments.length; i < max; i++) {
TypeReference typeArgument = typeArguments[i];
- addAnnotationContext(typeArgument, this.position, i, targetType);
+ if ((typeArgument.bits & ASTNode.HasTypeAnnotations) != 0) { // TODO can check this at a higher level?
+ addAnnotationContext(typeArgument, this.position, i, targetType);
+ }
}
}
super.invoke(opcode, methodBinding, declaringClass, typeArguments);
}
+
+ public void invokeDynamic(int bootStrapIndex, int argsSize, int returnTypeSize, char[] selector, char[] signature,
+ boolean isConstructorReference, TypeReference lhsTypeReference, TypeReference [] typeArguments) {
+ if (lhsTypeReference != null && (lhsTypeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
+ if (isConstructorReference) {
+ addAnnotationContext(lhsTypeReference, this.position, 0, AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE);
+ } else {
+ addAnnotationContext(lhsTypeReference, this.position, 0, AnnotationTargetTypeConstants.METHOD_REFERENCE);
+ }
+ }
+ if (typeArguments != null) {
+ int targetType =
+ isConstructorReference
+ ? AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+ : AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT;
+ for (int i = 0, max = typeArguments.length; i < max; i++) {
+ TypeReference typeArgument = typeArguments[i];
+ if ((typeArgument.bits & ASTNode.HasTypeAnnotations) != 0) {
+ addAnnotationContext(typeArgument, this.position, i, targetType);
+ }
+ }
+ }
+ super.invokeDynamic(bootStrapIndex, argsSize, returnTypeSize, selector, signature, isConstructorReference, lhsTypeReference, typeArguments);
+ }
+
+ public void reset(ClassFile givenClassFile) {
+ super.reset(givenClassFile);
+ this.allTypeAnnotationContexts = new ArrayList();
+ }
+
+ public void init(ClassFile targetClassFile) {
+ super.init(targetClassFile);
+ this.allTypeAnnotationContexts = new ArrayList();
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
index 6b822c45f..97db2c9d7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
@@ -37,7 +37,6 @@ import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
import org.eclipse.jdt.internal.compiler.util.Util;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.AnchorListAttribute;
-import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleBridgeMethodBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.TeamModel;
@@ -1703,14 +1702,7 @@ public AbstractMethodDeclaration sourceMethod() {
return null;
}
-//{ObjectTeams: more robust this way!?!
-/* orig:
- AbstractMethodDeclaration[] methods = sourceType.scope.referenceContext.methods;
- :giro */
- if (sourceType.model.getState() == ITranslationStates.STATE_FINAL)
- return null; // no source available any more
- AbstractMethodDeclaration[] methods = sourceType.model.getAst().methods;
-// SH}
+ AbstractMethodDeclaration[] methods = sourceType.scope != null ? sourceType.scope.referenceContext.methods : null;
if (methods != null) {
for (int i = methods.length; --i >= 0;)
if (this == methods[i].binding)
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 a23a7dd9f..276a9b7a3 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
@@ -1441,6 +1441,19 @@ public final class AST {
// km(merge) }
/**
+ * Creates an unparented creation reference node owned by this AST.
+ * By default, the type is unspecified (but legal), and there are no type arguments.
+ *
+ * @return a new unparented creation 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() {
+ CreationReference result = new CreationReference(this);
+ 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.
@@ -1508,6 +1521,20 @@ public final class AST {
}
/**
+ * Creates an unparented expression method reference node owned by this AST.
+ * By default, the expression and method name are unspecified (but legal),
+ * and there are no type arguments.
+ *
+ * @return a new unparented expression method 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() {
+ ExpressionMethodReference result = new ExpressionMethodReference(this);
+ return result;
+ }
+
+ /**
* Creates a new unparented expression statement node owned by this AST,
* for the given expression.
* <p>
@@ -2424,7 +2451,7 @@ public final class AST {
/**
* Creates an unparented "super" method invocation expression node owned by
- * this AST. By default, the name of the method is unspecified (but legal)
+ * this AST. By default, the name of the method is unspecified (but legal),
* there is no qualifier, no type arguments, and the list of arguments is empty.
*
* @return a new unparented "super" method invocation
@@ -2436,6 +2463,19 @@ public final class AST {
}
/**
+ * Creates and returns a new unparented super method reference node owned by
+ * this AST. By default, the name of the method is unspecified (but legal),
+ * and there is no qualifier and no type arguments.
+ *
+ * @return a new unparented super method reference node
+ * @since 3.9 BETA_JAVA8
+ */
+ public SuperMethodReference newSuperMethodReference() {
+ SuperMethodReference result = new SuperMethodReference(this);
+ return result;
+ }
+
+ /**
* Creates a new unparented switch case statement node owned by
* this AST. By default, the expression is unspecified, but legal.
*
@@ -2643,6 +2683,20 @@ public final class AST {
}
/**
+ * Creates an unparented type method reference node owned by this AST.
+ * By default, the type and method name are unspecified (but legal),
+ * and there are no type arguments.
+ *
+ * @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() {
+ TypeMethodReference result = new TypeMethodReference(this);
+ 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 fda33cd2f..d10a185f9 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
@@ -53,11 +53,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;
@@ -1955,6 +1957,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);
+ }
//{ObjectTeams: more expressions:
if (expression instanceof org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseCallMessageSend)
{
@@ -2448,13 +2453,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) {
@@ -2813,6 +2812,79 @@ 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() == -1 && name.getIdentifier().equals("<init>")) { // check for "new" //$NON-NLS-1$
+ retrieveInitAndSetPositions(start, reference.sourceEnd, name);
+ Type type = null;
+ if (lhs instanceof TypeReference) {
+ type = convertType((TypeReference) lhs);
+ } else if (lhs instanceof NameReference) {
+ Name typeName = convert((NameReference) lhs);
+ SimpleType simpleType = new SimpleType(this.ast);
+ simpleType.setName(typeName);
+ if (this.resolveBindings) {
+ recordNodes(simpleType, lhs);
+ }
+ simpleType.setSourceRange(lhs.sourceStart, lhs.sourceEnd - lhs.sourceStart + 1);
+ type = simpleType;
+ }
+ CreationReference creationReference = new CreationReference(this.ast);
+ creationReference.setType(type);
+ 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);
@@ -4274,6 +4346,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
*/
@@ -4564,8 +4651,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);
@@ -4924,7 +5011,7 @@ class ASTConverter {
}
/**
- * This method is used to retrieve the start and end position of a name.
+ * This method is used to retrieve the start and end position of a name or primitive type token.
*
* @return int[] a single dimensional array, with two elements, for the start and end positions of the name respectively
*/
@@ -5100,6 +5187,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 939a76827..23ca2f33c 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
@@ -703,6 +703,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.getType(), o.getType())
+ && 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)) {
@@ -835,6 +860,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)) {
@@ -2028,6 +2079,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)) {
@@ -2320,6 +2397,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 c206fd6b3..5b264d788 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
@@ -869,6 +869,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;
+
//{ObjectTeams: required OT specific node type constants added
/**
@@ -876,93 +908,93 @@ public abstract class ASTNode {
* <code>MethodSpec</code>.
* @see MethodSpec
*/
- public static final int METHOD_SPEC = 89;
+ public static final int METHOD_SPEC = 93;
/**
* Node type constant indicating a node of type
* <code>CallinMappingDeclaration</code>.
* @see CallinMappingDeclaration
*/
- public static final int CALLIN_MAPPING_DECLARATION = 90;
+ public static final int CALLIN_MAPPING_DECLARATION = 94;
/**
* Node type constant indicating a node of type
* <code>CalloutMappingDeclaration</code>.
* @see CalloutMappingDeclaration
*/
- public static final int CALLOUT_MAPPING_DECLARATION = 91;
+ public static final int CALLOUT_MAPPING_DECLARATION = 95;
/**
* Node type constant indicating a node of type
* <code>LiftingType</code>.
* @see LiftingType
*/
- public static final int LIFTING_TYPE = 92;
+ public static final int LIFTING_TYPE = 96;
/**
* Node type constant indicating a node of type
* <code>WithinStatement</code>.
* @see WithinStatement
*/
- public static final int WITHIN_STATEMENT = 93;
+ public static final int WITHIN_STATEMENT = 97;
/**
* Node type constant indicating a node of type
* <code>BaseConstructorMessageSend</code>.
* @see BaseConstructorInvocation
*/
- public static final int BASE_CONSTRUCTOR_INVOCATION = 94;
+ public static final int BASE_CONSTRUCTOR_INVOCATION = 98;
/**
* Node type constant indicating a node of type
* <code>ParameterMapping</code>.
* @see ParameterMapping
*/
- public static final int PARAMETER_MAPPING = 95;
+ public static final int PARAMETER_MAPPING = 99;
/**
* Node type constant indicating a node of type
* <code>BaseCallMessageSend</code>.
* @see BaseCallMessageSend
*/
- public static final int BASE_CALL_MESSAGE_SEND = 96;
+ public static final int BASE_CALL_MESSAGE_SEND = 100;
/**
* Node type constant indicating a node of type
* <code>FieldAccessSpec</code>.
* @see FieldAccessSpec
*/
- public static final int FIELD_ACCESS_SPEC = 97;
+ public static final int FIELD_ACCESS_SPEC = 101;
/**
* Node type constant indicating a node of type
* <code>RoleTypeDelaration</code>.
* @see RoleTypeDeclaration
*/
- public static final int ROLE_TYPE_DECLARATION = 98;
+ public static final int ROLE_TYPE_DECLARATION = 102;
/**
* Node type constant indicating a node of type
* <code>TSuperMessageSend</code>.
* @see TSuperMessageSend
*/
- public static final int TSUPER_MESSAGE_SEND = 99;
+ public static final int TSUPER_MESSAGE_SEND = 103;
/**
* Node type constant indicating a node of type
* <code>TSuperCallMessageSend</code>.
* @see TSuperMessageSend
*/
- public static final int TSUPER_CONSTRUCTOR_INVOCATION = 100;
+ public static final int TSUPER_CONSTRUCTOR_INVOCATION = 104;
- public static final int TYPE_ANCHOR = 101;
+ public static final int TYPE_ANCHOR = 105;
- public static final int PRECEDENCE_DECLARATION = 102;
+ public static final int PRECEDENCE_DECLARATION = 106;
- public static final int GUARD_PREDICATE_DECLARATION = 103;
+ public static final int GUARD_PREDICATE_DECLARATION = 107;
/** @since 1.3.1 */
- public static final int METHOD_BINDING_OPERATOR = 104;
+ public static final int METHOD_BINDING_OPERATOR = 108;
//gbr}
/**
@@ -1019,6 +1051,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 :
@@ -1031,6 +1065,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:
@@ -1119,6 +1155,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 :
@@ -1139,6 +1177,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 2272844b7..bb229f5ce 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
@@ -521,6 +521,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>
*
@@ -603,6 +620,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>
*
@@ -1369,6 +1403,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;
@@ -1549,6 +1600,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) {
@@ -2182,6 +2251,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
@@ -2245,6 +2327,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
@@ -2780,6 +2875,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
@@ -2913,6 +3021,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/AnnotatableType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotatableType.java
index c62d5104c..8b2c16dbe 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotatableType.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotatableType.java
@@ -17,7 +17,7 @@ package org.eclipse.jdt.core.dom;
import java.util.List;
/**
- * Type node for an annotatable type (added in JLS8 API).
+ * Abstract base class of AST nodes that represent an annotatable type (added in JLS8 API).
* <p>
* Introduced in JLS8, type references that can be annotated are represented by
* AnnotatableType. For the list of types extending AnnotatableType, see {@link Type}.</p>
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 19ffcc045..585dcda3b 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
@@ -589,6 +589,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 000000000..13602f0dd
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CreationReference.java
@@ -0,0 +1,241 @@
+/*******************************************************************************
+ * 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:
+ * Type <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 "type" structural property of this node type (child type: {@link Type}).
+ */
+ public static final ChildPropertyDescriptor TYPE_PROPERTY =
+ new ChildPropertyDescriptor(CreationReference.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(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(3);
+ createPropertyList(CreationReference.class, propertyList);
+ addProperty(TYPE_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 type; lazily initialized; defaults to an unspecified type.
+ */
+ private Type type = 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 == 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 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.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);
+ }
+ visitor.endVisit(this);
+ }
+
+ /**
+ * Returns the type of this creation reference expression.
+ *
+ * @return the type node
+ */
+ public Type getType() {
+ if (this.type == null) {
+ // lazy init must be thread-safe for readers
+ synchronized (this) {
+ if (this.type == null) {
+ preLazyInit();
+ this.type = new SimpleType(this.ast);
+ postLazyInit(this.type, TYPE_PROPERTY);
+ }
+ }
+ }
+ return this.type;
+ }
+
+ /**
+ * Sets the type of this creation reference expression.
+ *
+ * @param type the new type node
+ * @exception IllegalArgumentException if:
+ * <ul>
+ * <li>the node belongs to a different AST</li>
+ * <li>the node already has a parent</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 creation reference expression.
+ *
+ * @return the live list of type arguments
+ * (element type: {@link Type})
+ */
+ public List typeArguments() {
+ return this.typeArguments;
+ }
+
+ /* (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.type == null ? 0 : getType().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 029f3ccd0..c8bffe5a7 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 7f53c4331..bb707a632 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
@@ -156,12 +156,12 @@ class DefaultBindingResolver extends BindingResolver {
* Toggle controlling whether DOM bindings should be created when missing internal compiler bindings..
*/
boolean isRecoveringBindings;
-
+
/**
* Set to <code>true</code> if initialized from a java project
*/
boolean fromJavaProject;
-
+
/**
* Constructor for DefaultBindingResolver.
*/
@@ -743,6 +743,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 :
@@ -918,15 +922,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);
@@ -938,15 +942,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);
@@ -969,6 +973,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) {
@@ -1289,6 +1313,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();
//{ObjectTeams: Resolve bindings for OT-specific elements
} else if (node instanceof MethodSpec) {
if (node instanceof FieldAccessSpec) {
@@ -1307,7 +1336,6 @@ class DefaultBindingResolver extends BindingResolver {
return getTypeBinding(liftingTypeRef.resolvedType);
// SH}
}
-
return null;
}
@@ -1577,6 +1605,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);
}
//{ObjectTeams: Resolve bindings for OT-specific elements
else if (node instanceof MethodSpec)
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 6fd76fa9c..a5b6dabb3 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 000000000..b98eba8e8
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionMethodReference.java
@@ -0,0 +1,307 @@
+/*******************************************************************************
+ * 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; lazily initialized; defaults to an unspecified,
+ * legal expression.
+ */
+ 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() {
+ 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 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/LambdaExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LambdaExpression.java
index fd541a51e..35fa5b522 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LambdaExpression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LambdaExpression.java
@@ -18,7 +18,7 @@ import java.util.ArrayList;
import java.util.List;
/**
- * Lambda expression AST node type.
+ * Lambda expression AST node type (added in JLS8 API).
* <pre>
* LambdaExpression:
* Identifier <b>-></b> Body
@@ -130,7 +130,7 @@ public class LambdaExpression extends Expression {
/* (omit javadoc for this method)
* Method declared on ASTNode.
*/
- List internalStructuralPropertiesForType(int apiLevel) {
+ final List internalStructuralPropertiesForType(int apiLevel) {
return propertyDescriptors(apiLevel);
}
@@ -180,7 +180,7 @@ public class LambdaExpression extends Expression {
/* (omit javadoc for this method)
* Method declared on ASTNode.
*/
- int getNodeType0() {
+ final int getNodeType0() {
return LAMBDA_EXPRESSION;
}
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 000000000..b7cfe3042
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodReference.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * 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).
+ *
+ * <pre>
+ * MethodReference:
+ * CreationReference
+ * ExpressionMethodReference
+ * SuperMethodReference
+ * TypeMethodReference
+ * </pre>
+ * <p>
+ * A method reference that is represented by a simple or qualified name,
+ * followed by <code>::</code>, followed by a simple name can be represented
+ * as {@link ExpressionMethodReference} or as {@link TypeMethodReference}.
+ * The ASTParser currently prefers the first form.
+ * </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/PackageQualifiedType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageQualifiedType.java
index 7a9cabe79..b3154b430 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageQualifiedType.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageQualifiedType.java
@@ -162,11 +162,11 @@ public class PackageQualifiedType extends AnnotatableType {
return super.internalGetSetChildProperty(property, get, child);
}
- int getNodeType0() {
+ final int getNodeType0() {
return PACKAGE_QUALIFIED_TYPE;
}
- boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+ final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
// dispatch to correct overloaded match method
return matcher.match(this, other);
}
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 000000000..0dfbc2e2e
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodReference.java
@@ -0,0 +1,294 @@
+/*******************************************************************************
+ * 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;
+ }
+
+ /* (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 == 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 000000000..1cebbe493
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeMethodReference.java
@@ -0,0 +1,304 @@
+/*******************************************************************************
+ * 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; lazily initialized; defaults to an unspecified type.
+ */
+ 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.setType((Type) ASTNode.copySubtree(target, getType()));
+ 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, 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() {
+ if (this.type == null) {
+ // lazy init must be thread-safe for readers
+ synchronized (this) {
+ if (this.type == null) {
+ preLazyInit();
+ this.type = new SimpleType(this.ast);
+ postLazyInit(this.type, TYPE_PROPERTY);
+ }
+ }
+ }
+ return this.type;
+ }
+
+ /**
+ * Sets the type of this type method reference expression.
+ *
+ * @param type the new type node
+ * @exception IllegalArgumentException if:
+ * <ul>
+ * <li>the node belongs to a different AST</li>
+ * <li>the node already has a parent</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 expression.
+ *
+ * @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.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 7de4a7e3f..3a1f4b5a3 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
@@ -204,6 +204,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());
@@ -580,6 +601,18 @@ public class NaiveASTFlattener extends ASTVisitor {
}
/*
+ * @see ASTVisitor#visit(CreationReference)
+ *
+ * @since 3.9 BETA_JAVA8
+ */
+ public boolean visit(CreationReference node) {
+ node.getType().accept(this);
+ visitReferenceTypeArguments(node.typeArguments());
+ this.buffer.append("new");//$NON-NLS-1$
+ return false;
+ }
+
+ /*
* @see ASTVisitor#visit(DoStatement)
*/
public boolean visit(DoStatement node) {
@@ -691,6 +724,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) {
@@ -1493,6 +1538,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) {
@@ -1749,6 +1810,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
*/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
index 3072772d6..0542c2f06 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
@@ -4007,9 +4007,12 @@ public final class ASTRewriteAnalyzer extends ASTVisitor {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
- rewriteRequiredNode(node, PackageQualifiedType.QUALIFIER_PROPERTY);
- if (node.getAST().apiLevel() >= AST.JLS8) {
- rewriteTypeAnnotations(node, PackageQualifiedType.ANNOTATIONS_PROPERTY, node.getStartPosition());
+ int pos = rewriteRequiredNode(node, PackageQualifiedType.QUALIFIER_PROPERTY);
+ try {
+ pos = getScanner().getTokenEndOffset(TerminalTokens.TokenNameDOT, pos);
+ rewriteTypeAnnotations(node, PackageQualifiedType.ANNOTATIONS_PROPERTY, pos);
+ } catch (CoreException e) {
+ handleException(e);
}
rewriteRequiredNode(node, PackageQualifiedType.NAME_PROPERTY);
return false;
@@ -4042,9 +4045,14 @@ public final class ASTRewriteAnalyzer extends ASTVisitor {
if (!hasChildrenChanges(node)) {
return doVisitUnchangedChildren(node);
}
- rewriteRequiredNode(node, QualifiedType.QUALIFIER_PROPERTY);
+ int pos = rewriteRequiredNode(node, QualifiedType.QUALIFIER_PROPERTY);
if (node.getAST().apiLevel() >= AST.JLS8) {
- rewriteTypeAnnotations(node, QualifiedType.ANNOTATIONS_PROPERTY, node.getStartPosition());
+ try {
+ pos = getScanner().getTokenEndOffset(TerminalTokens.TokenNameDOT, pos);
+ rewriteTypeAnnotations(node, QualifiedType.ANNOTATIONS_PROPERTY, pos);
+ } catch (CoreException e) {
+ handleException(e);
+ }
}
rewriteRequiredNode(node, QualifiedType.NAME_PROPERTY);
return false;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotation.java
index a143b4cc6..d6eb7df14 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotation.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 IBM Corporation and others.
+ * Copyright (c) 2012, 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
@@ -11,16 +11,18 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.core.util;
/**
* Description of an extended annotation structure as described in the JVM specifications
- * (added in JavaSE-1.7).
+ * (added in JavaSE-1.8).
*
* This interface may be implemented by clients.
*
- * @since 3.9
+ * @since 3.9 BETA_JAVA8
*/
public interface IExtendedAnnotation extends IAnnotation {
/**
@@ -40,18 +42,18 @@ public interface IExtendedAnnotation extends IAnnotation {
* <th>offset description</th>
* </tr>
* <tr>
- * <td>0x00, 0x02, 0x04, 0x1E</td>
- * <td>The offset within the bytecodes of the containing method of the <code>checkcast</code>
- * bytecode emitted for a typecast, the <code>instanceof</code> bytecode for the type tests,
- * the <code>new</code> bytecode emitted for the object creation expression, the <code>ldc(_w)</code>
- * bytecode emitted for class literal, or the <code>getstatic</code> bytecode emitted for primitive
- * class literals.</td>
+ * <td>0x43 (INSTANCE_OF), 0x44 (NEW), 0x45 (CONSTRUCTOR_REFERENCE), 0x46 (METHOD_REFERENCE)</td>
+ * <td>The offset within the bytecodes of the <code>instanceof</code> bytecode for INSTANCE_OF,
+ * the <code>new</code> bytecode for NEW and the implementing instruction for either a
+ * CONSTRUCTOR_REFERENCE or METHOD_REFERENCE.</td>
* </tr>
* <tr>
- * <td>0x18, 0x1A</td>
- * <td>The offset within the bytecodes of the containing method of the <code>new</code>
- * bytecode emitted for a constructor call, or the <code>invoke{interface|special|static|virtual}</code>
- * bytecode emitted for a method invocation.</td>
+ * <td>0x47 (CAST), 0x48 (CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT), 0x49 (METHOD_INVOCATION_TYPE_ARGUMENT),
+ * 0x4A (CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT), 0x4B (METHOD_REFERENCE_TYPE_ARGUMENT)</td>
+ * <td>The offset within the bytecodes of the <code>new</code> bytecode for constructor call, or the
+ * relevant bytecode for method invocation or method reference. For CAST the offset may
+ * point to the <code>checkcast</code> or another instruction as it is possible the cast
+ * may have been discarded by the compiler if it were a no-op.</td>
* </tr>
* </table>
*
@@ -61,6 +63,13 @@ public interface IExtendedAnnotation extends IAnnotation {
int getOffset();
/**
+ * Answer back the exception table index when the target_type is EXCEPTION_PARAMETER.
+ *
+ * @return the exception table index
+ */
+ int getExceptionTableIndex();
+
+ /**
* Answer back the local variable reference info table length of this entry as specified in
* the JVM specifications.
*
@@ -92,20 +101,20 @@ public interface IExtendedAnnotation extends IAnnotation {
int getParameterIndex();
/**
- * Answer back the method type parameter index.
+ * Answer back the index of the type parameter of the class or method
*
* <p>The index is 0-based.</p>
*
- * @return the method type parameter index
+ * @return the index of the type parameter of the class or method
*/
int getTypeParameterIndex();
/**
- * Answer back the method type parameter bound index.
+ * Answer back the index of the bound of the type parameter of the method or class
*
* <p>The index is 0-based.</p>
*
- * @return the method type parameter bound index
+ * @return the index of the bound of the type parameter of the method or class
*/
int getTypeParameterBoundIndex();
@@ -120,45 +129,33 @@ public interface IExtendedAnnotation extends IAnnotation {
* <th>offset description</th>
* </tr>
* <tr>
- * <td>0x18, 0x1A</td>
- * <td>the type argument index in the expression</td>
- * </tr>
- * <tr>
- * <td>0x14</td>
- * <td>the index of the type in the clause: <code>-1 (255)</code> is used if the annotation is on
+ * <td>0x10 (CLASS_EXTENDS)</td>
+ * <td>the index of the type in the clause: <code>-1 (65535)</code> is used if the annotation is on
* the superclass type, and the value <code>i</code> is used if the annotation is on the <code>i</code>th
* superinterface type (counting from zero).</td>
* </tr>
* <tr>
- * <td>0x16</td>
+ * <td>0x17 (THROWS)</td>
* <td>the index of the exception type in the clause: the value <code>i</code> denotes an annotation of the
* <code>i</code>th exception type (counting from zero).</td>
* </tr>
+ * <tr>
+ * <td>0x47 (CAST), 0x48 (CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT), 0x49 (METHOD_INVOCATION_TYPE_ARGUMENT),
+ * 0x4A (CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT), 0x4B (METHOD_REFERENCE_TYPE_ARGUMENT)</td>
+ * <td>the type argument index in the expression</td>
+ * </tr>
* </table>
* @return the index in the given different situations
*/
int getAnnotationTypeIndex();
/**
- * Answer back the target type of the location of the wildcard as described in the JVM specifications.
- *
- * @return the target type of the location of the wildcard
- */
- int getWildcardLocationType();
-
- /**
- * Answer back the locations of the wildcard type as described in the JVM specifications.
- *
- * @return the locations of the wildcard type
- */
- int[] getWildcardLocations();
-
- /**
* Answer back the locations of the annotated type as described in the JVM specifications.
*
* <p>This is used for parameterized and array types.</p>
*
* @return the locations of the annotated type
*/
- int[] getLocations();
+ int[][] getTypePath();
+
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotationConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotationConstants.java
index 15d26470d..c849076fd 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotationConstants.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotationConstants.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 IBM Corporation and others.
+ * Copyright (c) 2012, 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
@@ -11,6 +11,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.core.util;
@@ -18,47 +20,42 @@ import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
/**
* Description of an extended annotation target types constants as described in the JVM specifications
- * (added in JavaSE-1.7).
+ * (added in JavaSE-1.8).
*
- * @since 3.9
+ * @since 3.9 BETA_JAVA8
* @noimplement This interface is not intended to be implemented by clients.
* @noextend This interface is not intended to be extended by clients.
*/
public interface IExtendedAnnotationConstants {
- int METHOD_RECEIVER = AnnotationTargetTypeConstants.METHOD_RECEIVER;
- int METHOD_RECEIVER_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.METHOD_RECEIVER_GENERIC_OR_ARRAY;
- int METHOD_RETURN_TYPE = AnnotationTargetTypeConstants.METHOD_RETURN_TYPE;
- int METHOD_RETURN_TYPE_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.METHOD_RETURN_TYPE_GENERIC_OR_ARRAY;
- int METHOD_PARAMETER = AnnotationTargetTypeConstants.METHOD_PARAMETER;
- int METHOD_PARAMETER_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.METHOD_PARAMETER_GENERIC_OR_ARRAY;
- int FIELD = AnnotationTargetTypeConstants.FIELD;
- int FIELD_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.FIELD_GENERIC_OR_ARRAY;
+
+ int CLASS_TYPE_PARAMETER = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER;
+ int METHOD_TYPE_PARAMETER = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER;
+
+ int CLASS_EXTENDS = AnnotationTargetTypeConstants.CLASS_EXTENDS;
int CLASS_TYPE_PARAMETER_BOUND = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND;
- int CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY;
int METHOD_TYPE_PARAMETER_BOUND = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND;
- int METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY;
- int CLASS_EXTENDS_IMPLEMENTS = AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS;
- int CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY;
+ int FIELD = AnnotationTargetTypeConstants.FIELD;
+ int METHOD_RETURN = AnnotationTargetTypeConstants.METHOD_RETURN;
+ int METHOD_RECEIVER = AnnotationTargetTypeConstants.METHOD_RECEIVER;
+ int METHOD_FORMAL_PARAMETER = AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER;
int THROWS = AnnotationTargetTypeConstants.THROWS;
- int THROWS_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.THROWS_GENERIC_OR_ARRAY;
- int WILDCARD_BOUND = AnnotationTargetTypeConstants.WILDCARD_BOUND;
- int WILDCARD_BOUND_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.WILDCARD_BOUND_GENERIC_OR_ARRAY;
- int METHOD_TYPE_PARAMETER = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER;
- int METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY;
- int CLASS_TYPE_PARAMETER = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER;
- int CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY;
- int TYPE_CAST = AnnotationTargetTypeConstants.TYPE_CAST;
- int TYPE_CAST_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.TYPE_CAST_GENERIC_OR_ARRAY;
- int TYPE_INSTANCEOF = AnnotationTargetTypeConstants.TYPE_INSTANCEOF;
- int TYPE_INSTANCEOF_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.TYPE_INSTANCEOF_GENERIC_OR_ARRAY;
- int OBJECT_CREATION = AnnotationTargetTypeConstants.OBJECT_CREATION;
- int OBJECT_CREATION_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.OBJECT_CREATION_GENERIC_OR_ARRAY;
+
int LOCAL_VARIABLE = AnnotationTargetTypeConstants.LOCAL_VARIABLE;
- int LOCAL_VARIABLE_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.LOCAL_VARIABLE_GENERIC_OR_ARRAY;
- int TYPE_ARGUMENT_CONSTRUCTOR_CALL = AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL;
- int TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY;
- int TYPE_ARGUMENT_METHOD_CALL = AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL;
- int TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY;
- int CLASS_LITERAL = AnnotationTargetTypeConstants.CLASS_LITERAL;
- int CLASS_LITERAL_GENERIC_OR_ARRAY = AnnotationTargetTypeConstants.CLASS_LITERAL_GENERIC_OR_ARRAY;
+ int RESOURCE_VARIABLE = AnnotationTargetTypeConstants.RESOURCE_VARIABLE;
+ int EXCEPTION_PARAMETER = AnnotationTargetTypeConstants.EXCEPTION_PARAMETER;
+ int INSTANCEOF = AnnotationTargetTypeConstants.INSTANCEOF;
+ int NEW = AnnotationTargetTypeConstants.NEW;
+ int CONSTRUCTOR_REFERENCE = AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE;
+ int METHOD_REFERENCE = AnnotationTargetTypeConstants.METHOD_REFERENCE;
+ int CAST = AnnotationTargetTypeConstants.CAST;
+ int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
+ int METHOD_INVOCATION_TYPE_ARGUMENT = AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT;
+ int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT;
+ int METHOD_REFERENCE_TYPE_ARGUMENT = AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT;
+
+ // Type path entry kinds
+ int TYPE_PATH_DEEPER_IN_ARRAY = 0;
+ int TYPE_PATH_DEEPER_IN_INNER_TYPE = 1;
+ int TYPE_PATH_ANNOTATION_ON_WILDCARD_BOUND = 2;
+ int TYPE_PATH_TYPE_ARGUMENT_INDEX = 3;
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java
index a281ab0df..43393752f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java
@@ -1,12 +1,18 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
* Contributors:
* IBM Corporation - initial API and implementation
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.core.util;
@@ -86,6 +92,10 @@ public class CodeAttribute extends ClassFileAttribute implements ICodeAttribute
this.attributes[attributesIndex++] = new StackMapTableAttribute(classFileBytes, constantPool, offset + readOffset);
} else if (equals(attributeName, IAttributeNamesConstants.STACK_MAP)) {
this.attributes[attributesIndex++] = new StackMapAttribute(classFileBytes, constantPool, offset + readOffset);
+ } else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS)) {
+ this.attributes[attributesIndex++] = new RuntimeVisibleTypeAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
+ } else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS)) {
+ this.attributes[attributesIndex++] = new RuntimeInvisibleTypeAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
} else {
this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, constantPool, offset + readOffset);
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
index 32f5c01fb..c7960b433 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
@@ -8,9 +8,11 @@
* 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
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.core.util;
@@ -262,7 +264,7 @@ public class Disassembler extends ClassFileBytesDisassembler {
writeNewLine(buffer, lineSeparator, tabNumber + 1);
buffer.append(Messages.disassembler_annotationentryend);
}
-
+
private void disassemble(IExtendedAnnotation extendedAnnotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
writeNewLine(buffer, lineSeparator, tabNumber + 1);
final int typeIndex = extendedAnnotation.getTypeIndex();
@@ -285,102 +287,30 @@ public class Disassembler extends ClassFileBytesDisassembler {
}));
switch(targetType) {
case IExtendedAnnotationConstants.METHOD_RECEIVER :
- case IExtendedAnnotationConstants.METHOD_RETURN_TYPE :
+ case IExtendedAnnotationConstants.METHOD_RETURN:
case IExtendedAnnotationConstants.FIELD :
break;
default:
writeNewLine(buffer, lineSeparator, tabNumber + 2);
- }
-
- switch(targetType) {
- case IExtendedAnnotationConstants.WILDCARD_BOUND :
- int wildcardLocationType = extendedAnnotation.getWildcardLocationType();
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_wildcardlocationtype, new String[] {
- Integer.toString(wildcardLocationType),
- getTargetType(wildcardLocationType),
- }));
- writeNewLine(buffer, lineSeparator, tabNumber + 3);
- disassembleTargetTypeContents(true, wildcardLocationType, extendedAnnotation, buffer, lineSeparator, tabNumber + 3, mode);
- break;
- case IExtendedAnnotationConstants.WILDCARD_BOUND_GENERIC_OR_ARRAY :
- wildcardLocationType = extendedAnnotation.getWildcardLocationType();
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_wildcardlocationtype, new String[] {
- Integer.toString(wildcardLocationType),
- getTargetType(wildcardLocationType),
- }));
- writeNewLine(buffer, lineSeparator, tabNumber + 3);
- disassembleTargetTypeContents(true, wildcardLocationType, extendedAnnotation, buffer, lineSeparator, tabNumber + 3, mode);
- writeNewLine(buffer, lineSeparator, tabNumber + 2);
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_locations, new String[] {
- toString(extendedAnnotation.getLocations()),
- }));
- break;
- default:
disassembleTargetTypeContents(false, targetType, extendedAnnotation, buffer, lineSeparator, tabNumber, mode);
}
+ disassembleTypePathContents(targetType, extendedAnnotation, buffer, lineSeparator, tabNumber, mode);
writeNewLine(buffer, lineSeparator, tabNumber + 1);
buffer.append(Messages.disassembler_extendedannotationentryend);
}
+ private void disassembleTypePathContents(int targetType, IExtendedAnnotation extendedAnnotation,StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+ int[][] typepath = extendedAnnotation.getTypePath();
+ if (typepath.length != 0) {
+ writeNewLine(buffer, lineSeparator, tabNumber + 2);
+ buffer.append(
+ Messages.bind(Messages.disassembler_extendedannotation_typepath, new String[] {
+ toTypePathString(typepath),
+ }));
+ }
+ }
private void disassembleTargetTypeContents(boolean insideWildcard, int targetType, IExtendedAnnotation extendedAnnotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
switch(targetType) {
- case IExtendedAnnotationConstants.CLASS_EXTENDS_IMPLEMENTS :
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_classextendsimplements, new String[] {
- Integer.toString(extendedAnnotation.getAnnotationTypeIndex()),
- }));
- break;
- case IExtendedAnnotationConstants.CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY :
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_classextendsimplements, new String[] {
- Integer.toString(extendedAnnotation.getAnnotationTypeIndex()),
- }));
- writeNewLine(buffer, lineSeparator, tabNumber + 2);
- if (insideWildcard) {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_wildcardlocations, new String[] {
- toString(extendedAnnotation.getWildcardLocations()),
- }));
- } else {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_locations, new String[] {
- toString(extendedAnnotation.getLocations()),
- }));
- }
- break;
- case IExtendedAnnotationConstants.TYPE_CAST :
- case IExtendedAnnotationConstants.TYPE_INSTANCEOF :
- case IExtendedAnnotationConstants.OBJECT_CREATION :
- case IExtendedAnnotationConstants.CLASS_LITERAL :
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_offset, new String[] {
- Integer.toString(extendedAnnotation.getOffset()),
- }));
- break;
- case IExtendedAnnotationConstants.TYPE_CAST_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.TYPE_INSTANCEOF_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.OBJECT_CREATION_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.CLASS_LITERAL_GENERIC_OR_ARRAY :
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_offset, new String[] {
- Integer.toString(extendedAnnotation.getOffset()),
- }));
- writeNewLine(buffer, lineSeparator, tabNumber + 2);
- if (insideWildcard) {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_wildcardlocations, new String[] {
- toString(extendedAnnotation.getWildcardLocations()),
- }));
- } else {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_locations, new String[] {
- toString(extendedAnnotation.getLocations()),
- }));
- }
- break;
case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER :
case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER :
buffer.append(
@@ -388,54 +318,40 @@ public class Disassembler extends ClassFileBytesDisassembler {
Integer.toString(extendedAnnotation.getTypeParameterIndex()),
}));
break;
- case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY :
+ case IExtendedAnnotationConstants.CLASS_EXTENDS :
buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_type_parameter, new String[] {
- Integer.toString(extendedAnnotation.getTypeParameterIndex()),
- }));
- writeNewLine(buffer, lineSeparator, tabNumber + 2);
- if (insideWildcard) {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_wildcardlocations, new String[] {
- toString(extendedAnnotation.getWildcardLocations()),
- }));
- } else {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_locations, new String[] {
- toString(extendedAnnotation.getLocations()),
- }));
- }
+ Messages.bind(Messages.disassembler_extendedannotation_classextendsimplements, new String[] {
+ Integer.toString(extendedAnnotation.getAnnotationTypeIndex()),
+ }));
break;
- case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_BOUND :
+
case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER_BOUND :
+ case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_BOUND :
buffer.append(
Messages.bind(Messages.disassembler_extendedannotation_type_parameter_with_bound, new String[] {
Integer.toString(extendedAnnotation.getTypeParameterIndex()),
Integer.toString(extendedAnnotation.getTypeParameterBoundIndex()),
}));
+ break;
+ case IExtendedAnnotationConstants.FIELD :
+ case IExtendedAnnotationConstants.METHOD_RETURN :
+ case IExtendedAnnotationConstants.METHOD_RECEIVER :
break;
- case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY :
+ case IExtendedAnnotationConstants.METHOD_FORMAL_PARAMETER :
buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_type_parameter_with_bound, new String[] {
- Integer.toString(extendedAnnotation.getTypeParameterIndex()),
- Integer.toString(extendedAnnotation.getTypeParameterBoundIndex()),
+ Messages.bind(Messages.disassembler_extendedannotation_method_parameter, new String[] {
+ Integer.toString(extendedAnnotation.getParameterIndex()),
}));
- writeNewLine(buffer, lineSeparator, tabNumber + 2);
- if (insideWildcard) {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_wildcardlocations, new String[] {
- toString(extendedAnnotation.getWildcardLocations()),
- }));
- } else {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_locations, new String[] {
- toString(extendedAnnotation.getLocations()),
- }));
- }
break;
+ case IExtendedAnnotationConstants.THROWS :
+ buffer.append(
+ Messages.bind(Messages.disassembler_extendedannotation_throws, new String[] {
+ Integer.toString(extendedAnnotation.getAnnotationTypeIndex()),
+ }));
+ break;
+
case IExtendedAnnotationConstants.LOCAL_VARIABLE :
+ case IExtendedAnnotationConstants.RESOURCE_VARIABLE :
buffer.append(Messages.disassembler_localvariabletargetheader);
writeNewLine(buffer, lineSeparator, tabNumber + 3);
int localVariableTableSize = extendedAnnotation.getLocalVariableRefenceInfoLength();
@@ -456,92 +372,27 @@ public class Disassembler extends ClassFileBytesDisassembler {
}));
}
break;
- case IExtendedAnnotationConstants.LOCAL_VARIABLE_GENERIC_OR_ARRAY :
- buffer.append(Messages.disassembler_localvariabletargetheader);
- writeNewLine(buffer, lineSeparator, tabNumber + 3);
- localVariableTableSize = extendedAnnotation.getLocalVariableRefenceInfoLength();
- localVariableTable = extendedAnnotation.getLocalVariableTable();
- for (int i = 0; i < localVariableTableSize; i++) {
- if (i != 0) {
- writeNewLine(buffer, lineSeparator, tabNumber + 3);
- }
- ILocalVariableReferenceInfo info = localVariableTable[i];
- int index= info.getIndex();
- int startPC = info.getStartPC();
- int length = info.getLength();
- buffer.append(Messages.bind(Messages.classfileformat_localvariablereferenceinfoentry,
- new String[] {
- Integer.toString(startPC),
- Integer.toString(startPC + length),
- Integer.toString(index),
- }));
- }
- writeNewLine(buffer, lineSeparator, tabNumber + 2);
- if (insideWildcard) {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_wildcardlocations, new String[] {
- toString(extendedAnnotation.getWildcardLocations()),
- }));
- } else {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_locations, new String[] {
- toString(extendedAnnotation.getLocations()),
- }));
- }
- break;
- case IExtendedAnnotationConstants.METHOD_PARAMETER :
+ case IExtendedAnnotationConstants.EXCEPTION_PARAMETER :
buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_method_parameter, new String[] {
- Integer.toString(extendedAnnotation.getTypeParameterIndex()),
+ Messages.bind(Messages.disassembler_extendedannotation_exception_table_index, new String[] {
+ Integer.toString(extendedAnnotation.getExceptionTableIndex()),
}));
break;
- case IExtendedAnnotationConstants.METHOD_PARAMETER_GENERIC_OR_ARRAY :
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_method_parameter, new String[] {
- Integer.toString(extendedAnnotation.getTypeParameterIndex()),
- }));
- writeNewLine(buffer, lineSeparator, tabNumber + 2);
- if (insideWildcard) {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_wildcardlocations, new String[] {
- toString(extendedAnnotation.getWildcardLocations()),
- }));
- } else {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_locations, new String[] {
- toString(extendedAnnotation.getLocations()),
- }));
- }
- break;
- case IExtendedAnnotationConstants.METHOD_RECEIVER_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.METHOD_RETURN_TYPE_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.FIELD_GENERIC_OR_ARRAY :
- if (insideWildcard) {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_wildcardlocations, new String[] {
- toString(extendedAnnotation.getWildcardLocations()),
- }));
- } else {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_locations, new String[] {
- toString(extendedAnnotation.getLocations()),
- }));
- }
- break;
- case IExtendedAnnotationConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL :
- case IExtendedAnnotationConstants.TYPE_ARGUMENT_METHOD_CALL :
+
+ case IExtendedAnnotationConstants.INSTANCEOF :
+ case IExtendedAnnotationConstants.NEW :
+ case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE :
+ case IExtendedAnnotationConstants.METHOD_REFERENCE :
buffer.append(
Messages.bind(Messages.disassembler_extendedannotation_offset, new String[] {
Integer.toString(extendedAnnotation.getOffset()),
}));
- writeNewLine(buffer, lineSeparator, tabNumber + 2);
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_type_argument, new String[] {
- Integer.toString(extendedAnnotation.getAnnotationTypeIndex()),
- }));
break;
- case IExtendedAnnotationConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY :
+ case IExtendedAnnotationConstants.CAST :
+ case IExtendedAnnotationConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
+ case IExtendedAnnotationConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
+ case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
+ case IExtendedAnnotationConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
buffer.append(
Messages.bind(Messages.disassembler_extendedannotation_offset, new String[] {
Integer.toString(extendedAnnotation.getOffset()),
@@ -551,124 +402,63 @@ public class Disassembler extends ClassFileBytesDisassembler {
Messages.bind(Messages.disassembler_extendedannotation_type_argument, new String[] {
Integer.toString(extendedAnnotation.getAnnotationTypeIndex()),
}));
- writeNewLine(buffer, lineSeparator, tabNumber + 2);
- if (insideWildcard) {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_wildcardlocations, new String[] {
- toString(extendedAnnotation.getWildcardLocations()),
- }));
- } else {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_locations, new String[] {
- toString(extendedAnnotation.getLocations()),
- }));
- }
- break;
- case IExtendedAnnotationConstants.THROWS :
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_throws, new String[] {
- Integer.toString(extendedAnnotation.getAnnotationTypeIndex()),
- }));
- break;
- case IExtendedAnnotationConstants.THROWS_GENERIC_OR_ARRAY :
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_throws, new String[] {
- Integer.toString(extendedAnnotation.getAnnotationTypeIndex()),
- }));
- writeNewLine(buffer, lineSeparator, tabNumber + 2);
- if (insideWildcard) {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_wildcardlocations, new String[] {
- toString(extendedAnnotation.getWildcardLocations()),
- }));
- } else {
- buffer.append(
- Messages.bind(Messages.disassembler_extendedannotation_locations, new String[] {
- toString(extendedAnnotation.getLocations()),
- }));
- }
break;
}
}
private String getTargetType(int targetType) {
switch(targetType) {
- case IExtendedAnnotationConstants.CLASS_EXTENDS_IMPLEMENTS :
- return "CLASS_EXTENDS_IMPLEMENTS"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY :
- return "CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.TYPE_CAST :
- return "TYPE_CAST"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.TYPE_INSTANCEOF :
- return "TYPE_INSTANCEOF"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.OBJECT_CREATION :
- return "OBJECT_CREATION"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.CLASS_LITERAL :
- return "CLASS_LITERAL"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.TYPE_CAST_GENERIC_OR_ARRAY :
- return "TYPE_CAST_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.TYPE_INSTANCEOF_GENERIC_OR_ARRAY :
- return "TYPE_INSTANCEOF_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.OBJECT_CREATION_GENERIC_OR_ARRAY :
- return "OBJECT_CREATION_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.CLASS_LITERAL_GENERIC_OR_ARRAY :
- return "CLASS_LITERAL_GENERIC_OR_ARRAY"; //$NON-NLS-1$
case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER :
return "CLASS_TYPE_PARAMETER"; //$NON-NLS-1$
case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER :
return "METHOD_TYPE_PARAMETER"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY :
- return "CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY :
- return "METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_BOUND :
- return "METHOD_TYPE_PARAMETER_BOUND"; //$NON-NLS-1$
+
+ case IExtendedAnnotationConstants.CLASS_EXTENDS :
+ return "CLASS_EXTENDS"; //$NON-NLS-1$
case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER_BOUND :
return "CLASS_TYPE_PARAMETER_BOUND"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY :
- return "METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY :
- return "CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.LOCAL_VARIABLE :
- return "LOCAL_VARIABLE"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.LOCAL_VARIABLE_GENERIC_OR_ARRAY :
- return "LOCAL_VARIABLE_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.METHOD_PARAMETER :
- return "METHOD_PARAMETER"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.METHOD_PARAMETER_GENERIC_OR_ARRAY :
- return "METHOD_PARAMETER_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.METHOD_RECEIVER_GENERIC_OR_ARRAY :
- return "METHOD_RECEIVER_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.METHOD_RETURN_TYPE_GENERIC_OR_ARRAY :
- return "METHOD_RETURN_TYPE_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.METHOD_RECEIVER :
- return "METHOD_RECEIVER"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.METHOD_RETURN_TYPE :
- return "METHOD_RETURN_TYPE"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_BOUND :
+ return "METHOD_TYPE_PARAMETER_BOUND"; //$NON-NLS-1$
case IExtendedAnnotationConstants.FIELD :
return "FIELD"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.FIELD_GENERIC_OR_ARRAY :
- return "FIELD_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL :
- return "TYPE_ARGUMENT_CONSTRUCTOR_CALL"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.TYPE_ARGUMENT_METHOD_CALL :
- return "TYPE_ARGUMENT_METHOD_CALL"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY :
- return "TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY :
- return "TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.METHOD_RETURN :
+ return "METHOD_RETURN"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.METHOD_RECEIVER :
+ return "METHOD_RECEIVER"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.METHOD_FORMAL_PARAMETER :
+ return "METHOD_FORMAL_PARAMETER"; //$NON-NLS-1$
case IExtendedAnnotationConstants.THROWS :
return "THROWS"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.THROWS_GENERIC_OR_ARRAY :
- return "THROWS_GENERIC_OR_ARRAY"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.WILDCARD_BOUND :
- return "WILDCARD_BOUND"; //$NON-NLS-1$
- case IExtendedAnnotationConstants.WILDCARD_BOUND_GENERIC_OR_ARRAY :
- return "WILDCARD_BOUND_GENERIC_OR_ARRAY"; //$NON-NLS-1$
+
+ case IExtendedAnnotationConstants.LOCAL_VARIABLE :
+ return "LOCAL_VARIABLE"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.RESOURCE_VARIABLE :
+ return "RESOURCE_VARIABLE"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.EXCEPTION_PARAMETER :
+ return "EXCEPTION_PARAMETER"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.INSTANCEOF :
+ return "INSTANCEOF"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.NEW :
+ return "NEW"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE :
+ return "CONSTRUCTOR_REFERENCE"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.METHOD_REFERENCE :
+ return "METHOD_REFERENCE"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.CAST :
+ return "CAST"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
+ return "CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
+ return "METHOD_INVOCATION_TYPE_ARGUMENT"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
+ return "CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT"; //$NON-NLS-1$
+ case IExtendedAnnotationConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
+ return "METHOD_REFERENCE_TYPE_ARGUMENT"; //$NON-NLS-1$
default:
return "UNKNOWN"; //$NON-NLS-1$
}
}
+
private void disassemble(IAnnotationComponent annotationComponent, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
writeNewLine(buffer, lineSeparator, tabNumber + 1);
buffer.append(
@@ -1128,7 +918,7 @@ public class Disassembler extends ClassFileBytesDisassembler {
}
if (runtimeInvisibleTypeAnnotationsAttribute != null) {
disassemble((IRuntimeInvisibleTypeAnnotationsAttribute) runtimeInvisibleTypeAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
- }
+ }
}
}
@@ -1222,7 +1012,9 @@ public class Disassembler extends ClassFileBytesDisassembler {
IInnerClassesAttribute innerClassesAttribute = classFileReader.getInnerClassesAttribute();
IClassFileAttribute runtimeVisibleAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS);
IClassFileAttribute runtimeInvisibleAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS);
-
+ IClassFileAttribute runtimeVisibleTypeAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
+ IClassFileAttribute runtimeInvisibleTypeAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
+
IClassFileAttribute bootstrapMethods = Util.getAttribute(classFileReader, IAttributeNamesConstants.BOOTSTRAP_METHODS);
if (checkMode(mode, DETAILED)) {
@@ -1369,6 +1161,12 @@ public class Disassembler extends ClassFileBytesDisassembler {
if (runtimeInvisibleAnnotationsAttribute != null) {
disassemble((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, 0, mode);
}
+ if (runtimeVisibleTypeAnnotationsAttribute != null) {
+ disassemble((IRuntimeVisibleTypeAnnotationsAttribute) runtimeVisibleTypeAnnotationsAttribute, buffer, lineSeparator, 0, mode);
+ }
+ if (runtimeInvisibleTypeAnnotationsAttribute != null) {
+ disassemble((IRuntimeInvisibleTypeAnnotationsAttribute) runtimeInvisibleTypeAnnotationsAttribute, buffer, lineSeparator, 0, mode);
+ }
if (length != 0) {
for (int i = 0; i < length; i++) {
IClassFileAttribute attribute = attributes[i];
@@ -1378,6 +1176,8 @@ public class Disassembler extends ClassFileBytesDisassembler {
&& attribute != enclosingMethodAttribute
&& attribute != runtimeInvisibleAnnotationsAttribute
&& attribute != runtimeVisibleAnnotationsAttribute
+ && attribute != runtimeInvisibleTypeAnnotationsAttribute
+ && attribute != runtimeVisibleTypeAnnotationsAttribute
&& !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.DEPRECATED)
&& !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.SYNTHETIC)
&& attribute != bootstrapMethods) {
@@ -1602,6 +1402,10 @@ public class Disassembler extends ClassFileBytesDisassembler {
if (numberOfEntries != 0) {
disassemble(stackMapAttribute, buffer, lineSeparator, tabNumber, mode);
}
+ } else if (CharOperation.equals(attribute.getAttributeName(),IAttributeNamesConstants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS)) {
+ disassemble((IRuntimeVisibleTypeAnnotationsAttribute) attribute, buffer, lineSeparator, tabNumber, mode);
+ } else if (CharOperation.equals(attribute.getAttributeName(),IAttributeNamesConstants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS)) {
+ disassemble((IRuntimeInvisibleTypeAnnotationsAttribute) attribute, buffer, lineSeparator, tabNumber, mode);
} else if (attribute != lineNumberAttribute
&& attribute != localVariableAttribute
&& attribute != localVariableTypeAttribute) {
@@ -2113,7 +1917,7 @@ public class Disassembler extends ClassFileBytesDisassembler {
}
if (runtimeInvisibleTypeAnnotationsAttribute != null) {
disassemble((IRuntimeInvisibleTypeAnnotationsAttribute) runtimeInvisibleTypeAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
- }
+ }
}
}
@@ -2247,16 +2051,7 @@ public class Disassembler extends ClassFileBytesDisassembler {
disassemble(i, parameterAnnotations[i], buffer, lineSeparator, tabNumber + 1, mode);
}
}
-
- private void disassemble(IRuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
- writeNewLine(buffer, lineSeparator, tabNumber + 1);
- buffer.append(Messages.disassembler_runtimevisibleannotationsattributeheader);
- IAnnotation[] annotations = runtimeVisibleAnnotationsAttribute.getAnnotations();
- for (int i = 0, max = annotations.length; i < max; i++) {
- disassemble(annotations[i], buffer, lineSeparator, tabNumber + 1, mode);
- }
- }
-
+
private void disassemble(IRuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
writeNewLine(buffer, lineSeparator, tabNumber + 1);
buffer.append(Messages.disassembler_runtimeinvisibletypeannotationsattributeheader);
@@ -2265,13 +2060,13 @@ public class Disassembler extends ClassFileBytesDisassembler {
disassemble(extendedAnnotations[i], buffer, lineSeparator, tabNumber + 1, mode);
}
}
-
- private void disassemble(IRuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+
+ private void disassemble(IRuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
writeNewLine(buffer, lineSeparator, tabNumber + 1);
- buffer.append(Messages.disassembler_runtimevisibletypeannotationsattributeheader);
- IExtendedAnnotation[] extendedAnnotations = runtimeVisibleTypeAnnotationsAttribute.getExtendedAnnotations();
- for (int i = 0, max = extendedAnnotations.length; i < max; i++) {
- disassemble(extendedAnnotations[i], buffer, lineSeparator, tabNumber + 1, mode);
+ buffer.append(Messages.disassembler_runtimevisibleannotationsattributeheader);
+ IAnnotation[] annotations = runtimeVisibleAnnotationsAttribute.getAnnotations();
+ for (int i = 0, max = annotations.length; i < max; i++) {
+ disassemble(annotations[i], buffer, lineSeparator, tabNumber + 1, mode);
}
}
@@ -2283,6 +2078,15 @@ public class Disassembler extends ClassFileBytesDisassembler {
disassemble(i, parameterAnnotations[i], buffer, lineSeparator, tabNumber + 1, mode);
}
}
+
+ private void disassemble(IRuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+ writeNewLine(buffer, lineSeparator, tabNumber + 1);
+ buffer.append(Messages.disassembler_runtimevisibletypeannotationsattributeheader);
+ IExtendedAnnotation[] extendedAnnotations = runtimeVisibleTypeAnnotationsAttribute.getExtendedAnnotations();
+ for (int i = 0, max = extendedAnnotations.length; i < max; i++) {
+ disassemble(extendedAnnotations[i], buffer, lineSeparator, tabNumber + 1, mode);
+ }
+ }
private String disassemble(IVerificationTypeInfo[] infos, int mode) {
StringBuffer buffer = new StringBuffer();
@@ -2718,16 +2522,37 @@ public class Disassembler extends ClassFileBytesDisassembler {
dumpTab(tabNumber, buffer);
}
- private String toString(int[] tab) {
+ private String toTypePathString(int[][] typepath) {
StringBuffer buffer = new StringBuffer();
- buffer.append('{');
- for (int i = 0, max = tab.length; i < max; i++) {
+ buffer.append('[');
+ for (int i = 0, max = typepath.length; i < max; i++) {
+ int[] typepathElement = typepath[i];
if (i > 0) {
- buffer.append(',');
+ buffer.append(',').append(' ');
+ }
+ switch (typepathElement[0]) {
+ case IExtendedAnnotationConstants.TYPE_PATH_DEEPER_IN_ARRAY:
+ buffer.append(Messages.disassembler_extendedannotation_typepath_array);
+ break;
+ case IExtendedAnnotationConstants.TYPE_PATH_DEEPER_IN_INNER_TYPE:
+ buffer.append(Messages.disassembler_extendedannotation_typepath_innertype);
+ break;
+ case IExtendedAnnotationConstants.TYPE_PATH_ANNOTATION_ON_WILDCARD_BOUND:
+ buffer.append(Messages.disassembler_extendedannotation_typepath_wildcard);
+ break;
+ case IExtendedAnnotationConstants.TYPE_PATH_TYPE_ARGUMENT_INDEX:
+ buffer.append(
+ Messages.bind(Messages.disassembler_extendedannotation_typepath_typeargument,
+ new String[] {
+ Integer.toString(typepathElement[1])
+ }));
+ break;
+ default:
+ throw new IllegalStateException("Unrecognized type_path_kind: "+typepathElement[0]); //$NON-NLS-1$
}
- buffer.append(tab[i]);
}
- buffer.append('}');
- return String.valueOf(buffer);
+ buffer.append(']');
+ return String.valueOf(buffer);
}
+
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExtendedAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExtendedAnnotation.java
index aa429774f..902b32967 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExtendedAnnotation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExtendedAnnotation.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 IBM Corporation and others.
+ * Copyright (c) 2012, 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
@@ -11,6 +11,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.core.util;
@@ -23,30 +25,58 @@ import org.eclipse.jdt.core.util.IExtendedAnnotation;
import org.eclipse.jdt.core.util.IExtendedAnnotationConstants;
import org.eclipse.jdt.core.util.ILocalVariableReferenceInfo;
+/* http://types.cs.washington.edu/jsr308/specification/java-annotation-design.pdf
+ type_annotation {
+ // New fields in JSR 308:
+ u1 target_type; // the type of the targeted program element, see Section 3.2
+ union {
+ type_parameter_target;
+ supertype_target;
+ type_parameter_bound_target;
+ empty_target;
+ method_formal_parameter_target;
+ throws_target;
+ localvar_target;
+ catch_target;
+ offset_target;
+ type_argument_target;
+ method_reference_target;
+ } target_info; // identifies the targeted program element, see Section 3.3
+ type_path target_path; // identifies targeted type in a compound type (array, generic, etc.), see Section 3.4
+ // Original fields from "annotation" structure:
+ u2 type_index;
+ u2 num_element_value_pairs;
+ {
+ u2 element_name_index;
+ element_value value;
+ } element_value_pairs[num_element_value_pairs];
+*/
/**
- * Default implementation of IAnnotation
+ * @since 3.9 BETA_JAVA8
*/
public class ExtendedAnnotation extends ClassFileStruct implements IExtendedAnnotation {
private static final IAnnotationComponent[] NO_ENTRIES = new IAnnotationComponent[0];
+ private final static int[][] NO_TYPEPATH = new int[0][0];
+
+ private int targetType;
+ private int annotationTypeIndex;
+ private int[][] typePath;
private int typeIndex;
private char[] typeName;
private int componentsNumber;
private IAnnotationComponent[] components;
private int readOffset;
- private int targetType;
- private int annotationTypeIndex;
private int offset;
private int typeParameterIndex;
private int typeParameterBoundIndex;
private int parameterIndex;
- private int wildcardLocationType;
+ private int exceptionTableIndex;
private ILocalVariableReferenceInfo[] localVariableTable;
- private int[] locations;
- private int[] wildcardLocations;
+
/**
- * Constructor for Annotation.
+ * Constructor for ExtendedAnnotation, builds an annotation from the supplied bytestream.
*
* @param classFileBytes
* @param constantPool
@@ -58,8 +88,32 @@ public class ExtendedAnnotation extends ClassFileStruct implements IExtendedAnno
IConstantPool constantPool,
int offset) throws ClassFormatException {
- int index = u2At(classFileBytes, 0, offset);
+ // Read target_type
+ int index = u1At(classFileBytes,0,offset);
+ this.targetType = index;
+ this.readOffset = 1;
+
+ readTargetInfo(index, classFileBytes, constantPool, offset);
+
+ // Read type_path
+ index = u1At(classFileBytes, this.readOffset, offset);
+ this.readOffset++;
+ int typePathEntryCount = index;
+ if (typePathEntryCount == 0) {
+ this.typePath = NO_TYPEPATH;
+ } else {
+ this.typePath = new int[typePathEntryCount][];
+ for (int i = 0; i < typePathEntryCount; i++) {
+ int[] typePathEntry = (this.typePath[i] = new int[2]);
+ typePathEntry[0] = u1At(classFileBytes, this.readOffset++, offset);
+ typePathEntry[1] = u1At(classFileBytes, this.readOffset++, offset);
+ }
+ }
+
+ // Read annotation
+ index = u2At(classFileBytes, this.readOffset, offset);
this.typeIndex = index;
+ this.readOffset+=2;
if (index != 0) {
IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
@@ -69,9 +123,9 @@ public class ExtendedAnnotation extends ClassFileStruct implements IExtendedAnno
} else {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
- final int length = u2At(classFileBytes, 2, offset);
+ final int length = u2At(classFileBytes, this.readOffset, offset);
this.componentsNumber = length;
- this.readOffset = 4;
+ this.readOffset+=2;
if (length != 0) {
this.components = new IAnnotationComponent[length];
for (int i = 0; i < length; i++) {
@@ -82,122 +136,55 @@ public class ExtendedAnnotation extends ClassFileStruct implements IExtendedAnno
} else {
this.components = NO_ENTRIES;
}
- index = u1At(classFileBytes, this.readOffset, offset);
- this.readOffset++;
- this.targetType = index;
- switch(index) {
- case IExtendedAnnotationConstants.WILDCARD_BOUND :
- this.wildcardLocationType = u1At(classFileBytes, this.readOffset, offset);
- this.readOffset++;
- internalDecoding(this.wildcardLocationType, classFileBytes, constantPool, offset);
- // copy the location back into the wildcard location
- int size = this.locations.length;
- System.arraycopy(this.locations, 0, (this.wildcardLocations = new int[size]), 0, size);
- this.locations = null;
- break;
- case IExtendedAnnotationConstants.WILDCARD_BOUND_GENERIC_OR_ARRAY :
- this.wildcardLocationType = u1At(classFileBytes, this.readOffset, offset);
- this.readOffset++;
- internalDecoding(this.wildcardLocationType, classFileBytes, constantPool, offset);
- size = this.locations.length;
- System.arraycopy(this.locations, 0, (this.wildcardLocations = new int[size]), 0, size);
- int locationLength = u2At(classFileBytes, this.readOffset, offset);
- this.readOffset += 2;
- this.locations = new int[locationLength];
- for (int i = 0; i < locationLength; i++) {
- this.locations[i] = u1At(classFileBytes, this.readOffset, offset);
- this.readOffset++;
- }
- break;
- default:
- internalDecoding(index, classFileBytes, constantPool, offset);
- }
if (this.annotationTypeIndex == 0xFFFF) {
this.annotationTypeIndex = -1;
}
}
- private void internalDecoding(
+ private void readTargetInfo(
int localTargetType,
byte[] classFileBytes,
IConstantPool constantPool,
int localOffset) throws ClassFormatException {
switch(localTargetType) {
- case IExtendedAnnotationConstants.CLASS_EXTENDS_IMPLEMENTS :
- this.annotationTypeIndex = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset+=2;
- break;
- case IExtendedAnnotationConstants.CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY :
- this.annotationTypeIndex = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset+=2;
- int locationLength = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset += 2;
- this.locations = new int[locationLength];
- for (int i = 0; i < locationLength; i++) {
- this.locations[i] = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
- }
- break;
- case IExtendedAnnotationConstants.TYPE_CAST :
- case IExtendedAnnotationConstants.TYPE_INSTANCEOF :
- case IExtendedAnnotationConstants.OBJECT_CREATION :
- case IExtendedAnnotationConstants.CLASS_LITERAL :
- this.offset = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset += 2;
- break;
- case IExtendedAnnotationConstants.TYPE_CAST_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.TYPE_INSTANCEOF_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.OBJECT_CREATION_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.CLASS_LITERAL_GENERIC_OR_ARRAY :
- this.offset = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset += 2;
- locationLength = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset += 2;
- this.locations = new int[locationLength];
- for (int i = 0; i < locationLength; i++) {
- this.locations[i] = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
- }
- break;
case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER :
case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER :
this.typeParameterIndex = u1At(classFileBytes, this.readOffset, localOffset);
this.readOffset++;
break;
- case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY :
- this.typeParameterIndex = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
- locationLength = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset += 2;
- this.locations = new int[locationLength];
- for (int i = 0; i < locationLength; i++) {
- this.locations[i] = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
- }
+
+ case IExtendedAnnotationConstants.CLASS_EXTENDS :
+ this.annotationTypeIndex = u2At(classFileBytes, this.readOffset, localOffset);
+ this.readOffset+=2;
break;
- case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_BOUND :
+
case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER_BOUND :
+ case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_BOUND :
this.typeParameterIndex = u1At(classFileBytes, this.readOffset, localOffset);
this.readOffset++;
this.typeParameterBoundIndex = u1At(classFileBytes, this.readOffset, localOffset);
this.readOffset++;
break;
- case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY :
- this.typeParameterIndex = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
- this.typeParameterBoundIndex = u1At(classFileBytes, this.readOffset, localOffset);
+
+ case IExtendedAnnotationConstants.FIELD :
+ case IExtendedAnnotationConstants.METHOD_RETURN :
+ case IExtendedAnnotationConstants.METHOD_RECEIVER :
+ // nothing to do, target_info is empty_target
+ break;
+
+ case IExtendedAnnotationConstants.METHOD_FORMAL_PARAMETER :
+ this.parameterIndex = u1At(classFileBytes, this.readOffset, localOffset);
this.readOffset++;
- locationLength = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset += 2;
- this.locations = new int[locationLength];
- for (int i = 0; i < locationLength; i++) {
- this.locations[i] = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
- }
break;
+
+ case IExtendedAnnotationConstants.THROWS :
+ this.annotationTypeIndex = u2At(classFileBytes, this.readOffset, localOffset);
+ this.readOffset+=2;
+ break;
+
+
case IExtendedAnnotationConstants.LOCAL_VARIABLE :
+ case IExtendedAnnotationConstants.RESOURCE_VARIABLE :
int tableLength = u2At(classFileBytes, this.readOffset, localOffset);
this.readOffset += 2;
this.localVariableTable = new LocalVariableReferenceInfo[tableLength];
@@ -206,83 +193,34 @@ public class ExtendedAnnotation extends ClassFileStruct implements IExtendedAnno
this.readOffset += 6;
}
break;
- case IExtendedAnnotationConstants.LOCAL_VARIABLE_GENERIC_OR_ARRAY :
- tableLength = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset += 2;
- this.localVariableTable = new LocalVariableReferenceInfo[tableLength];
- for (int i = 0; i < tableLength; i++) {
- this.localVariableTable[i] = new LocalVariableReferenceInfo(classFileBytes, constantPool, this.readOffset + localOffset);
- this.readOffset += 6;
- }
- locationLength = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset += 2;
- this.locations = new int[locationLength];
- for (int i = 0; i < locationLength; i++) {
- this.locations[i] = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
- }
- break;
- case IExtendedAnnotationConstants.METHOD_PARAMETER :
- this.parameterIndex = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
- break;
- case IExtendedAnnotationConstants.METHOD_PARAMETER_GENERIC_OR_ARRAY :
- this.parameterIndex = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
- locationLength = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset += 2;
- this.locations = new int[locationLength];
- for (int i = 0; i < locationLength; i++) {
- this.locations[i] = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
- }
- break;
- case IExtendedAnnotationConstants.METHOD_RECEIVER_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.METHOD_RETURN_TYPE_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.FIELD_GENERIC_OR_ARRAY :
- locationLength = u2At(classFileBytes, this.readOffset, localOffset);
+
+ case IExtendedAnnotationConstants.EXCEPTION_PARAMETER :
+ this.exceptionTableIndex = u2At(classFileBytes, this.readOffset, localOffset);
this.readOffset += 2;
- this.locations = new int[locationLength];
- for (int i = 0; i < locationLength; i++) {
- this.locations[i] = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
- }
break;
- case IExtendedAnnotationConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL :
- case IExtendedAnnotationConstants.TYPE_ARGUMENT_METHOD_CALL :
+
+ case IExtendedAnnotationConstants.NEW :
+ case IExtendedAnnotationConstants.INSTANCEOF :
+ case IExtendedAnnotationConstants.METHOD_REFERENCE :
+ case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE :
this.offset = u2At(classFileBytes, this.readOffset, localOffset);
this.readOffset += 2;
- this.annotationTypeIndex = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
+ break;
+
+ case IExtendedAnnotationConstants.CAST :
+ this.offset = u2At(classFileBytes, this.readOffset, localOffset);
+ this.readOffset += 3; // skipping the 3rd byte which will be 0 for CAST
break;
- case IExtendedAnnotationConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY :
- case IExtendedAnnotationConstants.TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY :
+
+ case IExtendedAnnotationConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
+ case IExtendedAnnotationConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
+ case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
+ case IExtendedAnnotationConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
this.offset = u2At(classFileBytes, this.readOffset, localOffset);
this.readOffset += 2;
+ // read type_argument_index
this.annotationTypeIndex = u1At(classFileBytes, this.readOffset, localOffset);
this.readOffset++;
- locationLength = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset += 2;
- this.locations = new int[locationLength];
- for (int i = 0; i < locationLength; i++) {
- this.locations[i] = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
- }
- break;
- case IExtendedAnnotationConstants.THROWS :
- this.annotationTypeIndex = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset+=2;
- break;
- case IExtendedAnnotationConstants.THROWS_GENERIC_OR_ARRAY :
- this.annotationTypeIndex = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset+=2;
- locationLength = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset += 2;
- this.locations = new int[locationLength];
- for (int i = 0; i < locationLength; i++) {
- this.locations[i] = u1At(classFileBytes, this.readOffset, localOffset);
- this.readOffset++;
- }
break;
}
}
@@ -319,6 +257,10 @@ public class ExtendedAnnotation extends ClassFileStruct implements IExtendedAnno
public int getTargetType() {
return this.targetType;
}
+
+ public int getExceptionTableIndex() {
+ return this.exceptionTableIndex;
+ }
public int getOffset() {
return this.offset;
@@ -344,16 +286,8 @@ public class ExtendedAnnotation extends ClassFileStruct implements IExtendedAnno
return this.typeParameterBoundIndex;
}
- public int getWildcardLocationType() {
- return this.wildcardLocationType;
- }
-
- public int[] getWildcardLocations() {
- return this.wildcardLocations;
- }
-
- public int[] getLocations() {
- return this.locations;
+ public int[][] getTypePath() {
+ return this.typePath;
}
public int getAnnotationTypeIndex() {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
index 1edfa5f1d..2de336260 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,9 +8,11 @@
* 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
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
package org.eclipse.jdt.internal.core.util;
@@ -304,7 +306,7 @@ public final class Messages extends NLS {
public static String disassembler_runtimevisibletypeannotationsattributeheader;
public static String disassembler_runtimeinvisibletypeannotationsattributeheader;
public static String disassembler_extendedannotation_classextendsimplements;
- public static String disassembler_extendedannotation_locations;
+ public static String disassembler_extendedannotation_typepath;
public static String disassembler_extendedannotation_method_parameter;
public static String disassembler_extendedannotation_offset;
public static String disassembler_extendedannotation_throws;
@@ -314,8 +316,12 @@ public final class Messages extends NLS {
public static String disassembler_extendedannotation_wildcardlocationtype;
public static String disassembler_extendedannotation_targetType;
public static String disassembler_extendedannotation_wildcardlocations;
+ public static String disassembler_extendedannotation_exception_table_index;
+ public static String disassembler_extendedannotation_typepath_array;
+ public static String disassembler_extendedannotation_typepath_wildcard;
+ public static String disassembler_extendedannotation_typepath_typeargument;
+ public static String disassembler_extendedannotation_typepath_innertype;
public static String disassembler_localvariabletargetheader;
- public static String classfileformat_localvariablereferenceinfoentry;
public static String disassembler_runtimevisibleannotationsattributeheader;
public static String disassembler_runtimeinvisibleannotationsattributeheader;
@@ -331,6 +337,9 @@ public final class Messages extends NLS {
public static String classfileformat_superflagisnotset;
public static String classfileformat_superflagisset;
public static String classfileformat_clinitname;
+ // jsr308
+ public static String classfileformat_localvariablereferenceinfoentry;
+
public static String classformat_classformatexception;
public static String classformat_anewarray;
public static String classformat_checkcast;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
index 748f5c1b3..30fad38c9 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2000, 2011 IBM Corporation and others.
+# Copyright (c) 2000, 2013 IBM Corporation and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
@@ -8,9 +8,11 @@
# 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
+# Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+# Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
###############################################################################
### JavaModel messages.
@@ -323,12 +325,13 @@ disassembler_annotationarrayvaluestart = [
disassembler_annotationarrayvalueend = ]
disassembler_annotationentrystart = #{0} @{1}(
disassembler_annotationentryend = )
-# jsr308
+# jsr308 (next two)
disassembler_extendedannotationentrystart=#{0} @{1}(
disassembler_extendedannotationentryend= )
disassembler_annotationcomponent = #{0} {1}=
disassembler_runtimevisibleannotationsattributeheader= RuntimeVisibleAnnotations:\
disassembler_runtimeinvisibleannotationsattributeheader= RuntimeInvisibleAnnotations:\
+# jsr308 (next two)
disassembler_runtimevisibletypeannotationsattributeheader= RuntimeVisibleTypeAnnotations:\
disassembler_runtimeinvisibletypeannotationsattributeheader= RuntimeInvisibleTypeAnnotations:\
disassembler_runtimevisibleparameterannotationsattributeheader= RuntimeVisibleParameterAnnotations:\
@@ -356,11 +359,10 @@ disassembler_method_type_ref_newinvokespecial = newinvokespecial ({0})
disassembler_frame_full_frame=[pc: {0}, full, stack: {4}, locals: {2}]
disassembler_frame_same_frame=[pc: {0}, same]
disassembler_frame_same_locals_1_stack_item=[pc: {0}, same_locals_1_stack_item, stack: {1}]
-
-# jsr 308
+# jsr308
disassembler_extendedannotation_targetType=target type = 0x{0} {1}
disassembler_extendedannotation_classextendsimplements=type index = {0}
-disassembler_extendedannotation_locations=locations = {0}
+disassembler_extendedannotation_typepath=location = {0}
disassembler_extendedannotation_method_parameter=method parameter index = {0}
disassembler_extendedannotation_offset=offset = {0}
disassembler_extendedannotation_throws=throws index = {0}
@@ -369,7 +371,12 @@ disassembler_extendedannotation_type_parameter=type parameter index = {0}
disassembler_extendedannotation_type_parameter_with_bound=type parameter index = {0} type parameter bound index = {1}
disassembler_extendedannotation_wildcardlocationtype=wildcard location type = 0x{0} {1}
disassembler_extendedannotation_wildcardlocations=wildcard locations = {0}
+disassembler_extendedannotation_exception_table_index=exception table index = {0}
disassembler_localvariabletargetheader=local variable entries:
+disassembler_extendedannotation_typepath_array=ARRAY
+disassembler_extendedannotation_typepath_innertype=INNER_TYPE
+disassembler_extendedannotation_typepath_wildcard=WILDCARD
+disassembler_extendedannotation_typepath_typeargument=TYPE_ARGUMENT({0})
### classfileformat decoding
classfileformat_versiondetails =\ (version {0} : {1}.{2}, {3})

Back to the top