Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManoj Palat2013-01-24 06:22:43 +0000
committerssankaran2013-01-24 06:22:43 +0000
commitc0d8ddbb4b72e166c7dc81eb807bc47fd1beaa74 (patch)
treefc2ff4fa437e9de4b8e20c013415a6d5be01f048
parent6cea394a74122bc3b2f5fee1a70c7921f0e635d8 (diff)
downloadeclipse.jdt.core-c0d8ddbb4b72e166c7dc81eb807bc47fd1beaa74.tar.gz
eclipse.jdt.core-c0d8ddbb4b72e166c7dc81eb807bc47fd1beaa74.tar.xz
eclipse.jdt.core-c0d8ddbb4b72e166c7dc81eb807bc47fd1beaa74.zip
Fixed Bug 395886 - [1.8][DOM/AST] Withdraw annotations property from
Name nodes
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java864
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java29
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java263
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java17
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java13
5 files changed, 1080 insertions, 106 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
index 791077ce4b..6d7ec1c6d7 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
@@ -18,6 +18,7 @@ import java.util.List;
import junit.framework.Test;
+import org.eclipse.jdt.core.dom.*;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
@@ -98,4 +99,867 @@ public class ASTConverter18Test extends ConverterTestSetup {
annotation = (ASTNode) annotations.get(0);
checkSourceRange(annotation, "@Marker", contents);
}
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886 tests annotations on
+ * QTR in multiple scenarios of occurrence.
+ *
+ * @throws JavaModelException
+ */
+ public void test0002() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/test0002/X.java",
+ true/* resolve */);
+ 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"
+ + " Object myObject = new Object();\n"
+ + " String myString;\n"
+ + " myString = (java.lang.@Marker String) myObject;\n"
+ + " Outer.Inner first = outer.new Inner();\n"
+ + " Outer. @Marker2 Inner second = outer.new Inner() ;\n"
+ + " Outer.Inner. @Marker1 Deeper deeper = second.new Deeper();\n"
+ + " Outer.@Marker1 Inner.@Marker2 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";
+ CompilationUnit cu = (CompilationUnit) buildAST(contents,
+ this.workingCopy);
+ MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(cu, 0, 0);
+ List statements = methodDeclaration.getBody().statements();
+ int sCount = 3;
+
+ // case 1 - annotation just before the last field
+ ExpressionStatement expressionStatement = (ExpressionStatement) statements.get(sCount++);
+ Assignment assignment = (Assignment) expressionStatement.getExpression();
+ assertNotNull(assignment);
+ CastExpression castExpression = (CastExpression) assignment.getRightHandSide();
+ assertNotNull(castExpression);
+ SimpleType simpleType = (SimpleType) castExpression.getType();
+ assertNotNull(simpleType);
+ assertEquals("java.lang.@Marker String", simpleType.toString());
+ List annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ assertEquals("@Marker", annotations.get(0).toString());
+
+ // case 2 - QualifiedType without annotations.
+ VariableDeclarationStatement variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount++);
+ Type type = variableDeclarationStatement.getType();
+ assertTrue(type.isSimpleType());
+ simpleType = (SimpleType) type;
+ assertEquals("Outer.Inner", simpleType.toString());
+ annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 0);
+
+ // case 3 - Qaulified Type with outer without annotations and inner with
+ // annotations.
+ variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount++);
+ type = variableDeclarationStatement.getType();
+ assertTrue(type.isSimpleType());
+ simpleType = (SimpleType) type;
+ assertNotNull(simpleType);
+ assertEquals("Outer.@Marker2 Inner", simpleType.toString());
+ annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ assertEquals("@Marker2", annotations.get(0).toString());
+
+ // case 4 - Multiple levels with annotations at the last only.
+ variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount++);
+ type = variableDeclarationStatement.getType();
+ assertTrue(type.isSimpleType());
+ simpleType = (SimpleType) type;
+ assertNotNull(simpleType);
+ assertEquals("Outer.Inner.@Marker1 Deeper", simpleType.toString());
+ annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ assertEquals("@Marker1", annotations.get(0).toString());
+
+ // case 5 - Multiple annotations
+ variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount++);
+ type = variableDeclarationStatement.getType();
+ assertTrue(type.isQualifiedType());
+ QualifiedType qualifiedType = (QualifiedType) type;
+ assertNotNull(qualifiedType);
+ assertEquals("Outer.@Marker1 Inner.@Marker2 Deeper", qualifiedType.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 1);
+ assertEquals("@Marker2", annotations.get(0).toString());
+ SimpleName simpleName = qualifiedType.getName();
+ assertEquals("Deeper", simpleName.toString());
+ Type qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isSimpleType());
+ simpleType = (SimpleType) qualifierType;
+ assertEquals("Outer.@Marker1 Inner", simpleType.toString());
+ annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ assertEquals("@Marker1", annotations.get(0).toString());
+ }
+
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886 tests the
+ * representation of type annotations on a possible JAVA 7 and 8 place.
+ *
+ * @throws JavaModelException
+ */
+ public void test0003() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/test0003/X.java",
+ true/* resolve */);
+ String contents = "package test0003;\n"
+ + "import java.lang.annotation.Target;\n"
+ + "public class X {\n"
+ + " public static void main(String[] args) {\n"
+ + " @Marker Outer.Inner first[] = new Outer.Inner[1];\n"
+ + " }\n" + "}\n" + "class Outer {\n"
+ + " public class Inner {\n" + " }\n" + "}\n"
+ + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n"
+ + "@interface Marker {}\n";
+ CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy);
+ MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(cu, 0, 0);
+ List statements = methodDeclaration.getBody().statements();
+ int sCount = 0;
+
+ // Current design expects annotation only at the JAVA 7 place if it is
+ // expected at JAVA 8.
+ VariableDeclarationStatement variableDeclarationStatement = (VariableDeclarationStatement) statements.get(sCount);
+ List modifiers = variableDeclarationStatement.modifiers();
+ assertTrue(modifiers.size() == 1);
+ Annotation annotation = (Annotation) modifiers.get(0);
+ assertEquals("@Marker", annotation.toString());
+ Type type = variableDeclarationStatement.getType();
+ assertTrue(type.isSimpleType());
+ SimpleType simpleType = (SimpleType) type;
+ assertEquals("Outer.Inner", simpleType.toString());
+ List annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 0);
+ }
+
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886 tests QTR with
+ * annotations
+ *
+ * @throws JavaModelException
+ */
+ public void test0004() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/test0004/X.java",
+ true/* resolve */);
+ String contents = "package test0004;"
+ + "import java.lang.annotation.Target;\n"
+ + "public class X implements One</*start*/@Marker1 Outer<Integer>. @Marker2 Inner<Double>[]/*end*/> {\n"
+ + "}\n" + "interface One<T> {}\n" + "class Outer<T> {\n"
+ + " public class Inner<S> {}\n" + "}\n"
+ + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n"
+ + "@interface Marker1 {}\n"
+ + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n"
+ + "@interface Marker2 {}\n";
+ CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy);
+ TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 0);
+ ArrayType type = (ArrayType) ((ParameterizedType) typedeclaration.superInterfaceTypes().get(0)).typeArguments().get(0);
+ assertNotNull("No annotation", type);
+ ITypeBinding binding = type.resolveBinding();
+ assertNotNull("No binding", binding);
+ assertEquals("Wrong qualified name", "test0004.Outer<java.lang.Integer>.Inner<java.lang.Double>[]", binding.getQualifiedName());
+ Type componentType = type.getComponentType();
+ binding = componentType.resolveBinding();
+ assertNotNull("No binding", binding);
+ assertEquals("Wrong qualified name",
+ "test0004.Outer<java.lang.Integer>.Inner<java.lang.Double>", binding.getQualifiedName());
+ assertTrue("Not parameterized", componentType.isParameterizedType());
+ ParameterizedType parameterizedType = (ParameterizedType) componentType;
+ Type type2 = parameterizedType.getType();
+ assertTrue("Not qualified", type2.isQualifiedType());
+ QualifiedType qualifiedType = (QualifiedType) type2;
+ binding = qualifiedType.resolveBinding();
+ assertNotNull("No binding", binding);
+ assertEquals("Wrong qualified name","test0004.Outer<java.lang.Integer>.Inner<java.lang.Double>", binding.getQualifiedName());
+ Type qualifier = qualifiedType.getQualifier();
+ assertTrue("Not parameterized", qualifier.isParameterizedType());
+ binding = qualifier.resolveBinding();
+ assertNotNull("No binding", binding);
+ assertEquals("Wrong qualified name", "test0004.Outer<java.lang.Integer>", binding.getQualifiedName());
+ parameterizedType = (ParameterizedType) qualifier;
+ type2 = parameterizedType.getType();
+ assertTrue("Not simple type", type2.isSimpleType());
+ binding = type2.resolveBinding();
+ assertNotNull("No binding", binding);
+ assertEquals("Wrong qualified name","test0004.Outer<java.lang.Integer>", binding.getQualifiedName());
+ }
+
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886 tests QTR with
+ * annotations
+ *
+ * @throws JavaModelException
+ */
+ public void test0005() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/test0005/X.java",
+ true/* resolve */);
+ String contents = "package test0005;"
+ + "import java.lang.annotation.Target;\n"
+ + "public class X implements One< Outer.Inner > {\n"
+ + "}\n"
+ + "class Y implements One< Outer. @Marker1 Inner > {\n"
+ + "}\n"
+ + "class Z implements One< @Marker1 Outer.Inner > {\n"
+ + "}\n"
+ + "class W implements One< @Marker1 Outer. @Marker2 Inner > {\n"
+ + "}\n" + "interface One<T> {}\n" + "class Outer {\n"
+ + " public class Inner {}\n" + "}\n"
+ + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n"
+ + "@interface Marker1 {}\n"
+ + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n"
+ + "@interface Marker2 {}\n";
+ CompilationUnit cu = (CompilationUnit) buildAST(contents,
+ this.workingCopy);
+ int tCount = 0;
+
+ // case 1 - no annotations Outer.Inner
+ TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ ParameterizedType parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ List typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ Type type = (Type) typeArguments.get(0);
+ assertTrue(type.isSimpleType());
+ assertEquals("Outer.Inner", type.toString());
+
+ // case 2 - QTR with one annotation Outer.@Marker1 Inner
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration
+ .superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ type = (Type) typeArguments.get(0);
+ assertTrue(type.isSimpleType());
+ SimpleType simpleType = (SimpleType) type;
+ assertEquals("Outer.@Marker1 Inner", simpleType.toString());
+ List annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ Annotation annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker1", annotation.toString());
+
+ // case 3 - QTR with one annotation at the beginning @Marker1
+ // Outer.Inner
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ type = (Type) typeArguments.get(0);
+ assertTrue(type.isQualifiedType());
+ assertEquals("@Marker1 Outer.Inner", type.toString());
+ QualifiedType qualifiedType = (QualifiedType) type;
+ assertEquals("Inner", qualifiedType.getName().toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 0);
+ Type qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isSimpleType());
+ simpleType = (SimpleType) qualifierType;
+ assertEquals("@Marker1 Outer", simpleType.toString());
+ annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker1", annotation.toString());
+
+ // case 4 - QTR with annotations at both the types @Marker1
+ // Outer.@Marker2 Inner
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ type = (Type) typeArguments.get(0);
+ assertTrue(type.isQualifiedType());
+ assertEquals("@Marker1 Outer.@Marker2 Inner", type.toString());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("Inner", qualifiedType.getName().toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker2", annotation.toString());
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isSimpleType());
+ simpleType = (SimpleType) qualifierType;
+ assertEquals("@Marker1 Outer", simpleType.toString());
+ annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker1", annotation.toString());
+
+ }
+
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886 tests PQTR with
+ * annotations part
+ *
+ * @throws JavaModelException
+ */
+ public void test0006() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/test0006/X.java",
+ true);
+ String contents = "package test0006;"
+ + "import java.lang.annotation.Target;\n"
+ + "public class X implements One<Outer. Inner.Deeper<Double>> {\n"
+ + "}\n"
+ + "class X1 implements One<Outer. @Marker1 Inner.Deeper<Double>> {\n"
+ + "}\n"
+ + "class X2 implements One<Outer. @Marker1 Inner.@Marker2 Deeper<Double>> {\n"
+ + "}\n"
+ + "class X3 implements One<@Marker1 Outer. @Marker2 Inner. Deeper<Double>> {\n"
+ + "}\n"
+ + "class Y implements One<Outer1. Inner<Integer>. Deeper<Double>> {\n"
+ + "}\n"
+ + "class Y1 implements One<Outer1. Inner<Integer>. @Marker1 Deeper<Double>> {\n"
+ + "}\n"
+ + "class Y2 implements One<Outer1. @Marker1 Inner<Integer>. Deeper<Double>> {\n"
+ + "}\n"
+ + "class Y3 implements One<@Marker1 Outer1. Inner<Integer>. Deeper<Double>> {\n"
+ + "}\n"
+ + "class Y4 implements One<@Marker1 Outer1. @Marker2 Inner<Integer>. Deeper<Double>> {\n"
+ + "}\n"
+ + "class Z implements One<Outer2<Integer>.Inner.Deeper<Double>> {\n"
+ + "}\n"
+ + "class Z1 implements One<@Marker1 Outer2<Integer>.Inner.Deeper<Double>> {\n"
+ + "}\n"
+ + "class Z2 implements One<Outer2<Integer>. @Marker1 Inner.@Marker2 Deeper<Double>> {\n"
+ + "}\n"
+ + "class W implements One<Outer3<Double>. @Marker1 @Marker2 Inner<Integer, Character>. Deeper<Double>> {\n"
+ + "}\n" + "interface One<T> {}\n" + "class Outer {\n"
+ + " public class Inner {\n"
+ + " public class Deeper<S> {\n" + " }\n" + " }\n"
+ + "}\n" + "class Outer1 {\n" + " public class Inner<T> {\n"
+ + " public class Deeper<S> {\n" + " }\n" + " }\n"
+ + "}\n" + "class Outer2 <T> {\n" + " public class Inner {\n"
+ + " public class Deeper<S> {}\n" + " }\n" + "}\n"
+ + "class Outer3 <T> {\n" + " public class Inner<K, V> {\n"
+ + " public class Deeper<S> {}\n" + " }\n" + "}\n"
+ + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n"
+ + "@interface Marker1 {}\n"
+ + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n"
+ + "@interface Marker2 {}\n";
+ CompilationUnit cu = (CompilationUnit) buildAST(contents,
+ this.workingCopy);
+ int tCount = 0;
+
+ // case 1: vanilla case without annotations and with single typeArgument
+ // Outer.Inner.Deeper<Double>
+ TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ ParameterizedType parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ List typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ parametrizedType = (ParameterizedType) typeArguments.get(0);
+ assertEquals("Outer.Inner.Deeper<Double>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ Type type = (Type) typeArguments.get(0);
+ assertEquals("Double", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isSimpleType());
+ SimpleType simpleType = (SimpleType) type;
+ assertEquals("Outer.Inner.Deeper", simpleType.toString());
+ Name name = simpleType.getName();
+ assertTrue(name.isQualifiedName());
+ QualifiedName qualifiedName = (QualifiedName) name;
+ assertEquals("Outer.Inner.Deeper", qualifiedName.toString());
+
+ // case 2 - One annotation after the first class
+ // Outer. @Marker1 Inner.Deeper<Double>
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ parametrizedType = (ParameterizedType) typeArguments.get(0);
+ assertEquals("Outer.@Marker1 Inner.Deeper<Double>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Double", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ QualifiedType qualifiedType = (QualifiedType) type;
+ assertEquals("Outer.@Marker1 Inner.Deeper", qualifiedType.toString());
+ name = qualifiedType.getName();
+ assertEquals("Deeper", name.toString());
+ List annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 0);
+ Type qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isSimpleType());
+ simpleType = (SimpleType) qualifierType;
+ assertEquals("Outer.@Marker1 Inner", simpleType.toString());
+ annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ Annotation annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker1", annotation.toString());
+
+ // case 3 - Inner types annotated with outer not annotated with last
+ // type arg
+ // Outer. @Marker1 Inner.@Marker2 Deeper<Double>
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ parametrizedType = (ParameterizedType) typeArguments.get(0);
+ assertEquals("Outer.@Marker1 Inner.@Marker2 Deeper<Double>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Double", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("Outer.@Marker1 Inner.@Marker2 Deeper", qualifiedType.toString());
+ name = qualifiedType.getName();
+ assertEquals("Deeper", name.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker2", annotation.toString());
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isSimpleType());
+ simpleType = (SimpleType) qualifierType;
+ assertEquals("Outer.@Marker1 Inner", simpleType.toString());
+ annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker1", annotation.toString());
+
+ // case 4 - one annotation on the outermost, one in middle and one
+ // typearg in innermost
+ // @Marker1 Outer. @Marker2 Inner. Deeper<Double>
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration
+ .superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ parametrizedType = (ParameterizedType) typeArguments.get(0);
+ assertEquals("@Marker1 Outer.@Marker2 Inner.Deeper<Double>", parametrizedType.toString());
+ ITypeBinding typeBinding = parametrizedType.resolveBinding();
+ assertNotNull("Binding non-null", typeBinding);
+ assertEquals("wrong qualified name", "test0006.Outer.Inner.Deeper<java.lang.Double>", typeBinding.getQualifiedName());
+ assertTrue("Not a Parameterized Type", typeBinding.isParameterizedType());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Double", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("@Marker1 Outer.@Marker2 Inner.Deeper", qualifiedType.toString());
+ name = qualifiedType.getName();
+ assertEquals("Deeper", name.toString());
+ annotations = qualifiedType.annotations();
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isQualifiedType());
+ qualifiedType = (QualifiedType) qualifierType;
+ assertEquals("@Marker1 Outer.@Marker2 Inner", qualifierType.toString());
+ typeBinding = qualifiedType.resolveBinding();
+ assertNotNull("Binding non-null", typeBinding);
+ typeBinding = qualifiedType.resolveBinding();
+ assertEquals("wrong qualified name", "test0006.Outer.Inner", typeBinding.getQualifiedName());
+ assertTrue(qualifierType.isAnnotatable());
+ AnnotatableType annotatableType = (AnnotatableType) qualifierType;
+ annotations = annotatableType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker2", annotation.toString());
+ name = qualifiedType.getName();
+ assertEquals("Inner", name.toString());
+ type = qualifiedType.getQualifier();
+ assertTrue(type.isSimpleType());
+ simpleType = (SimpleType) type;
+ assertEquals("@Marker1 Outer", simpleType.toString());
+ annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker1", annotation.toString());
+
+ // case 5 - without annotations, but with typeargs at second and third
+ // types
+ // Outer1. Inner<Integer>. Deeper<Double>
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ parametrizedType = (ParameterizedType) typeArguments.get(0);
+ assertEquals("Outer1.Inner<Integer>.Deeper<Double>",parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Double", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("Outer1.Inner<Integer>.Deeper", qualifiedType.toString());
+ name = qualifiedType.getName();
+ assertEquals("Deeper", name.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 0);
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isParameterizedType());
+ parametrizedType = (ParameterizedType) qualifierType;
+ assertEquals("Outer1.Inner<Integer>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Integer", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isSimpleType());
+ simpleType = (SimpleType) type;
+ name = simpleType.getName();
+ assertTrue(name.isQualifiedName());
+ qualifiedName = (QualifiedName) name;
+ assertEquals("Outer1.Inner", qualifiedName.toString());
+
+ // case 6 - Annot in between two PQRT with outermost neither annotated
+ // nor having typeargs
+ // Outer1. Inner<Integer>. @Marker1 Deeper<Double>
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ parametrizedType = (ParameterizedType) typeArguments.get(0);
+ assertEquals("Outer1.Inner<Integer>.@Marker1 Deeper<Double>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Double", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("Outer1.Inner<Integer>.@Marker1 Deeper", qualifiedType.toString());
+ name = qualifiedType.getName();
+ assertEquals("Deeper", name.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker1", annotation.toString());
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isParameterizedType());
+ parametrizedType = (ParameterizedType) qualifierType;
+ assertEquals("Outer1.Inner<Integer>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Integer", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isSimpleType());
+ simpleType = (SimpleType) type;
+ name = simpleType.getName();
+ assertTrue(name.isQualifiedName());
+ qualifiedName = (QualifiedName) name;
+ assertEquals("Outer1.Inner", qualifiedName.toString());
+
+ // case 7 - Outermost still empty (no annotations, no type args),
+ // followed by annotation, and then typeargs
+ // Outer1. @Marker1 Inner<Integer>. Deeper<Double>
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ parametrizedType = (ParameterizedType) typeArguments.get(0);
+ assertEquals("Outer1.@Marker1 Inner<Integer>.Deeper<Double>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Double", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("Outer1.@Marker1 Inner<Integer>.Deeper", qualifiedType.toString());
+ name = qualifiedType.getName();
+ assertEquals("Deeper", name.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 0);
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isParameterizedType());
+ parametrizedType = (ParameterizedType) qualifierType;
+ assertEquals("Outer1.@Marker1 Inner<Integer>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Integer", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isSimpleType());
+ simpleType = (SimpleType) type;
+ assertEquals("Outer1.@Marker1 Inner", simpleType.toString());
+ annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker1", annotation.toString());
+
+ // case 8 - Similar to above, but with the major difference of
+ // annotation shifted to outermost.
+ // @Marker1 Outer1. Inner<Integer>. Deeper<Double>
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ parametrizedType = (ParameterizedType) typeArguments.get(0);
+ assertEquals("@Marker1 Outer1.Inner<Integer>.Deeper<Double>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Double", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("@Marker1 Outer1.Inner<Integer>.Deeper", qualifiedType.toString());
+ name = qualifiedType.getName();
+ assertEquals("Deeper", name.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 0);
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isParameterizedType());
+ parametrizedType = (ParameterizedType) qualifierType;
+ assertEquals("@Marker1 Outer1.Inner<Integer>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Integer", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("@Marker1 Outer1.Inner", qualifiedType.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 0);
+ name = qualifiedType.getName();
+ assertTrue(name.isSimpleName());
+ assertEquals("Inner", name.toString());
+ type = qualifiedType.getQualifier();
+ assertTrue(type.isSimpleType());
+ simpleType = (SimpleType) type;
+ annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker1", annotation.toString());
+ name = simpleType.getName();
+ assertTrue(name.isSimpleName());
+ assertEquals("Outer1", name.toString());
+
+ // case 9: scenario of the above case plus another annotation at
+ // mid-level.
+ // @Marker1 Outer1.@Marker2 Inner<Integer>. Deeper<Double>
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ parametrizedType = (ParameterizedType) typeArguments.get(0);
+ assertEquals("@Marker1 Outer1.@Marker2 Inner<Integer>.Deeper<Double>",parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Double", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("@Marker1 Outer1.@Marker2 Inner<Integer>.Deeper", qualifiedType.toString());
+ name = qualifiedType.getName();
+ assertEquals("Deeper", name.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 0);
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isParameterizedType());
+ parametrizedType = (ParameterizedType) qualifierType;
+ assertEquals("@Marker1 Outer1.@Marker2 Inner<Integer>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Integer", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("@Marker1 Outer1.@Marker2 Inner", qualifiedType.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker2", annotation.toString());
+ name = qualifiedType.getName();
+ assertTrue(name.isSimpleName());
+ assertEquals("Inner", name.toString());
+ type = qualifiedType.getQualifier();
+ assertTrue(type.isSimpleType());
+ simpleType = (SimpleType) type;
+ annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker1", annotation.toString());
+ name = simpleType.getName();
+ assertTrue(name.isSimpleName());
+ assertEquals("Outer1", name.toString());
+
+ // case 10 - PQRT with two type args but without annotations
+ // Outer2<Integer>.Inner.Deeper<Double>
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ parametrizedType = (ParameterizedType) typeArguments.get(0);
+ assertEquals("Outer2<Integer>.Inner.Deeper<Double>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Double", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("Outer2<Integer>.Inner.Deeper", qualifiedType.toString());
+ ITypeBinding binding = qualifiedType.resolveBinding();
+ name = qualifiedType.getName();
+ assertEquals("Deeper", name.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 0);
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isQualifiedType());
+ qualifiedType = (QualifiedType) qualifierType;
+ binding = qualifiedType.resolveBinding();
+ assertEquals("Outer2<Integer>.Inner", qualifiedType.toString());
+ assertEquals("wrong qualified binding", "test0006.Outer2<java.lang.Integer>.Inner", binding.getQualifiedName());
+ name = qualifiedType.getName();
+ assertEquals("Inner", name.toString());
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isParameterizedType());
+ parametrizedType = (ParameterizedType) qualifierType;
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Integer", type.toString());
+ type = parametrizedType.getType();
+ assertEquals("Outer2", type.toString());
+
+ // case 11 - annotation at outermost in addition to scenario in case 10.
+ // @Marker1 Outer2<Integer>.Inner.Deeper<Double>
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ parametrizedType = (ParameterizedType) typeArguments.get(0);
+ assertEquals("@Marker1 Outer2<Integer>.Inner.Deeper<Double>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Double", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("@Marker1 Outer2<Integer>.Inner.Deeper", qualifiedType.toString());
+ name = qualifiedType.getName();
+ assertEquals("Deeper", name.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 0);
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isQualifiedType());
+ qualifiedType = (QualifiedType) qualifierType;
+ assertEquals("@Marker1 Outer2<Integer>.Inner", qualifiedType.toString());
+ name = qualifiedType.getName();
+ assertEquals("Inner", name.toString());
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isParameterizedType());
+ parametrizedType = (ParameterizedType) qualifierType;
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Integer", type.toString());
+ type = parametrizedType.getType();
+ assertEquals("@Marker1 Outer2", type.toString());
+ assertTrue(type.isSimpleType());
+ simpleType = (SimpleType) type;
+ annotations = simpleType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker1", annotation.toString());
+
+ // case 12 - No annotations at outermost, but outermost has
+ // typeAnnotations.
+ // Outer2<Integer>. @Marker1 Inner.@Marker2 Deeper<Double>
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ parametrizedType = (ParameterizedType) typeArguments.get(0);
+ assertEquals("Outer2<Integer>.@Marker1 Inner.@Marker2 Deeper<Double>", parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Double", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("Outer2<Integer>.@Marker1 Inner.@Marker2 Deeper",qualifiedType.toString());
+ name = qualifiedType.getName();
+ assertEquals("Deeper", name.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker2", annotation.toString());
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isQualifiedType());
+ qualifiedType = (QualifiedType) qualifierType;
+ assertEquals("Outer2<Integer>.@Marker1 Inner", qualifiedType.toString());
+ name = qualifiedType.getName();
+ assertEquals("Inner", name.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 1);
+ annotation = (Annotation) annotations.get(0);
+ assertEquals("@Marker1", annotation.toString());
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isParameterizedType());
+ parametrizedType = (ParameterizedType) qualifierType;
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Integer", type.toString());
+ type = parametrizedType.getType();
+ assertEquals("Outer2", type.toString());
+ assertTrue(type.isSimpleType());
+
+ // case 13 - a list of annotations and multiple typeArgument element
+ // lists.
+ // Outer3<Double>. @Marker1 @Marker2 Inner<Integer, Character>.
+ // Deeper<Double>
+ typedeclaration = (TypeDeclaration) getASTNode(cu, tCount++);
+ parametrizedType = (ParameterizedType) typedeclaration.superInterfaceTypes().get(0);
+ typeArguments = parametrizedType.typeArguments();
+ assertEquals(1, typeArguments.size());
+ parametrizedType = (ParameterizedType) typeArguments.get(0);
+ assertEquals("Outer3<Double>.@Marker1 @Marker2 Inner<Integer,Character>.Deeper<Double>",parametrizedType.toString());
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ type = (Type) typeArguments.get(0);
+ assertEquals("Double", type.toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("Outer3<Double>.@Marker1 @Marker2 Inner<Integer,Character>.Deeper", qualifiedType.toString());
+ name = qualifiedType.getName();
+ assertEquals("Deeper", name.toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 0);
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isParameterizedType());
+ parametrizedType = (ParameterizedType) qualifierType;
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 2);
+ assertEquals("Integer", typeArguments.get(0).toString());
+ assertEquals("Character", typeArguments.get(1).toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isQualifiedType());
+ qualifiedType = (QualifiedType) type;
+ assertEquals("Inner", qualifiedType.getName().toString());
+ annotations = qualifiedType.annotations();
+ assertTrue(annotations.size() == 2);
+ assertEquals("@Marker1", annotations.get(0).toString());
+ assertEquals("@Marker2", annotations.get(1).toString());
+ qualifierType = qualifiedType.getQualifier();
+ assertTrue(qualifierType.isParameterizedType());
+ parametrizedType = (ParameterizedType) qualifierType;
+ typeArguments = parametrizedType.typeArguments();
+ assertTrue(typeArguments.size() == 1);
+ assertEquals("Double", typeArguments.get(0).toString());
+ type = parametrizedType.getType();
+ assertTrue(type.isSimpleType());
+ simpleType = (SimpleType) type;
+ assertEquals("Outer3", simpleType.toString());
+ }
}
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 ad0c6b0692..cf39f0da39 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
@@ -1347,4 +1347,33 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T
x1.varargsAnnotations().add(this.ANO1);
basicMatch(x1);
}
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886
+ public void testQualifiedTypeAnnotation() {
+ if (this.ast.apiLevel() < AST.JLS8) {
+ return;
+ }
+ QualifiedType x1 = this.ast.newQualifiedType(this.T1, this.N1);
+ x1.annotations().add(this.ANO1);
+ x1 = this.ast.newQualifiedType(x1, this.N2);
+ x1.annotations().add(this.ANO2);
+ basicMatch(x1);
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=395886
+ public void testParameterizedQualifiedTypeAnnotation() {
+ if (this.ast.apiLevel() < AST.JLS8) {
+ return;
+ }
+ QualifiedType qualifiedType = this.ast.newQualifiedType(this.T1, this.N1);
+ qualifiedType.annotations().add(this.ANO1);
+ ParameterizedType x1 = this.ast.newParameterizedType(qualifiedType);
+ x1.typeArguments().add(this.ast.newSimpleType(this.ast.newSimpleName("SN1")));
+ qualifiedType = this.ast.newQualifiedType(x1, this.N2);
+ x1 = this.ast.newParameterizedType(qualifiedType);
+ SimpleType simpleType = this.ast.newSimpleType(this.ast.newSimpleName("SN2"));
+ simpleType.annotations().add(this.ANO2);
+ x1.typeArguments().add(simpleType);
+ basicMatch(x1);
+ }
}
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 ab91ac8cce..656fbd826f 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
@@ -3264,6 +3264,10 @@ class ASTConverter {
ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference = (ParameterizedQualifiedTypeReference) typeReference;
char[][] tokens = parameterizedQualifiedTypeReference.tokens;
TypeReference[][] typeArguments = parameterizedQualifiedTypeReference.typeArguments;
+ org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations = parameterizedQualifiedTypeReference.annotations;
+ TypeReference[] arguments = null;
+ int lenth = tokens.length;
+ int firstTypeIndex = lenth - 1;
long[] positions = parameterizedQualifiedTypeReference.sourcePositions;
sourceStart = (int)(positions[0]>>>32);
switch(this.ast.apiLevel) {
@@ -3281,124 +3285,185 @@ class ASTConverter {
}
break;
default :
- if (typeArguments != null) {
- int numberOfEnclosingType = 0;
- int startingIndex = 0;
- int endingIndex = 0;
- for (int i = 0, max = typeArguments.length; i < max; i++) {
- if (typeArguments[i] != null) {
- numberOfEnclosingType++;
- } else if (numberOfEnclosingType == 0) {
- endingIndex++;
- }
+ for (int i = 0; i < lenth; ++i) {
+ if (typeArguments != null && typeArguments[i] != null) {
+ firstTypeIndex = i;
+ break;
}
- Name name = null;
- if (endingIndex - startingIndex == 0) {
- final SimpleName simpleName = new SimpleName(this.ast);
- simpleName.internalSetIdentifier(new String(tokens[startingIndex]));
- recordPendingNameScopeResolution(simpleName);
- int start = (int)(positions[startingIndex]>>>32);
- int end = (int) positions[startingIndex];
- simpleName.setSourceRange(start, end - start + 1);
- simpleName.index = 1;
- name = simpleName;
- if (this.resolveBindings) {
- recordNodes(simpleName, typeReference);
- }
- } else {
- name = this.setQualifiedNameNameAndSourceRanges(tokens, positions, endingIndex, typeReference);
+ if (typeAnnotations != null && typeAnnotations[i] != null) {
+ firstTypeIndex = i;
+ break;
}
- SimpleType simpleType = new SimpleType(this.ast);
- simpleType.setName(name);
- int start = (int)(positions[startingIndex]>>>32);
- int end = (int) positions[endingIndex];
- simpleType.setSourceRange(start, end - start + 1);
- if (endingIndex == 0 && typeReference.annotations != null && (annotations = typeReference.annotations[0]) != null) {
- annotateType(simpleType, annotations);
+ }
+
+ Name name = null;
+ if (firstTypeIndex == 0) {
+ final SimpleName simpleName = new SimpleName(this.ast);
+ simpleName.setIdentifier(new String(tokens[0]));
+ recordPendingNameScopeResolution(simpleName);
+ int start = (int) (positions[0] >>> 32);
+ int end = (int) positions[0];
+ simpleName.setSourceRange(start, end - start + 1);
+ simpleName.index = 1;
+ name = simpleName;
+ if (this.resolveBindings) {
+ recordNodes(simpleName, typeReference);
}
+ } else {
+ name = this.setQualifiedNameNameAndSourceRanges(tokens, positions, firstTypeIndex, typeReference);
+ }
+
+ SimpleType simpleType = new SimpleType(this.ast);
+ simpleType.setName(name);
+ int start = (int)(positions[0] >>> 32);
+ int end = (int)positions[firstTypeIndex];
+ simpleType.setSourceRange(start, end - start + 1);
+ if (typeAnnotations != null && (annotations = typeAnnotations[firstTypeIndex]) != null) {
+ annotateType(simpleType, annotations);
+ }
+ if (this.resolveBindings) {
+ recordNodes(simpleType, typeReference);
+ }
+ Type currentType = simpleType;
+ int indexOfEnclosingType = 1;
+ if (typeArguments != null && (arguments = typeArguments[firstTypeIndex]) != null) {
+ int arglen = arguments.length;
ParameterizedType parameterizedType = new ParameterizedType(this.ast);
- parameterizedType.setType(simpleType);
+ parameterizedType.index = indexOfEnclosingType;
+ parameterizedType.setType(currentType);
if (this.resolveBindings) {
- recordNodes(simpleType, typeReference);
recordNodes(parameterizedType, typeReference);
}
- start = simpleType.getStartPosition();
- end = start + simpleType.getLength() - 1;
- for (int i = 0, max = typeArguments[endingIndex].length; i < max; i++) {
- final Type type2 = convertType(typeArguments[endingIndex][i]);
+ Type type2 = null;
+ for (int i = 0; i < arglen; ++i ) {
+ type2 = convertType(arguments[i]);
parameterizedType.typeArguments().add(type2);
- end = type2.getStartPosition() + type2.getLength() - 1;
}
- int indexOfEnclosingType = 1;
- parameterizedType.index = indexOfEnclosingType;
+ end = type2 != null ? type2.getStartPosition() + type2.getLength() - 1 : end;
end = retrieveClosingAngleBracketPosition(end + 1);
- length = end + 1;
parameterizedType.setSourceRange(start, end - start + 1);
- startingIndex = endingIndex + 1;
- Type currentType = parameterizedType;
- while(startingIndex < typeArguments.length) {
- SimpleName simpleName = new SimpleName(this.ast);
- simpleName.internalSetIdentifier(new String(tokens[startingIndex]));
- simpleName.index = startingIndex + 1;
- start = (int)(positions[startingIndex]>>>32);
- end = (int) positions[startingIndex];
- simpleName.setSourceRange(start, end - start + 1);
- recordPendingNameScopeResolution(simpleName);
- QualifiedType qualifiedType = new QualifiedType(this.ast);
- qualifiedType.setQualifier(currentType);
- qualifiedType.setName(simpleName);
- if (typeReference.annotations != null && (annotations = typeReference.annotations[startingIndex]) != null) {
- annotateType(qualifiedType, annotations);
- }
+ currentType = parameterizedType;
+ }
+
+ for (int i = firstTypeIndex + 1; i < lenth; ++i) {
+ SimpleName simpleName = new SimpleName(this.ast);
+ simpleName.setIdentifier(new String(tokens[i]));
+ simpleName.index = i + 1;
+ start = (int) (positions[i] >>> 32);
+ end = (int) positions[i];
+ simpleName.setSourceRange(start, end - start + 1);
+ recordPendingNameScopeResolution(simpleName);
+ QualifiedType qualifiedType = new QualifiedType(this.ast);
+ qualifiedType.setQualifier(currentType);
+ qualifiedType.setName(simpleName);
+ if (typeAnnotations != null && (annotations = typeAnnotations[i]) != null) {
+ annotateType(qualifiedType, annotations);
+ }
+ if (this.resolveBindings) {
+ recordNodes(simpleName, typeReference);
+ recordNodes(qualifiedType, typeReference);
+ }
+ start = currentType.getStartPosition();
+ end = simpleName.getStartPosition() + simpleName.getLength() - 1;
+ qualifiedType.setSourceRange(start, end - start + 1);
+ currentType = qualifiedType;
+ indexOfEnclosingType++;
+
+ if (typeArguments != null && (arguments = typeArguments[i]) != null) {
+ int arglen = arguments.length;
+ qualifiedType.index = indexOfEnclosingType;
+ ParameterizedType parameterizedType = new ParameterizedType(this.ast);
+ parameterizedType.index = indexOfEnclosingType;
+ parameterizedType.setType(currentType);
if (this.resolveBindings) {
- recordNodes(simpleName, typeReference);
- recordNodes(qualifiedType, typeReference);
+ recordNodes(parameterizedType, typeReference);
}
- start = currentType.getStartPosition();
- end = simpleName.getStartPosition() + simpleName.getLength() - 1;
- qualifiedType.setSourceRange(start, end - start + 1);
- indexOfEnclosingType++;
- if (typeArguments[startingIndex] != null) {
- qualifiedType.index = indexOfEnclosingType;
- ParameterizedType parameterizedType2 = new ParameterizedType(this.ast);
- parameterizedType2.setType(qualifiedType);
- parameterizedType2.index = indexOfEnclosingType;
- if (this.resolveBindings) {
- recordNodes(parameterizedType2, typeReference);
- }
- for (int i = 0, max = typeArguments[startingIndex].length; i < max; i++) {
- final Type type2 = convertType(typeArguments[startingIndex][i]);
- parameterizedType2.typeArguments().add(type2);
- end = type2.getStartPosition() + type2.getLength() - 1;
- }
- end = retrieveClosingAngleBracketPosition(end + 1);
- length = end + 1;
- parameterizedType2.setSourceRange(start, end - start + 1);
- currentType = parameterizedType2;
- } else {
- currentType = qualifiedType;
- qualifiedType.index = indexOfEnclosingType;
+ Type type2 = null;
+ for (int j = 0; j < arglen; ++j ) {
+ type2 = convertType(arguments[j]);
+ parameterizedType.typeArguments().add(type2);
}
- startingIndex++;
- }
- if (this.resolveBindings) {
- this.recordNodes(currentType, typeReference);
+ end = type2 != null ? type2.getStartPosition() + type2.getLength() - 1 : end;
+ end = retrieveClosingAngleBracketPosition(end + 1);
+ parameterizedType.setSourceRange(start, end - start + 1);
+ currentType = parameterizedType;
+ } else {
+ qualifiedType.index = indexOfEnclosingType;
}
- type = currentType;
- length -= sourceStart;
}
+ type = currentType;
}
- } else if (typeReference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) {
- char[][] name = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).getTypeName();
- int nameLength = name.length;
+ } else if (typeReference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) {
+ QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) typeReference;
long[] positions = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).sourcePositions;
+ org.eclipse.jdt.internal.compiler.ast.Annotation [][] typeAnnotations = typeReference.annotations;
+ char [][] tokens = qualifiedTypeReference.tokens;
+ int lenth = tokens.length;
+ int firstTypeIndex = lenth - 1;
+
+ if (typeAnnotations != null) {
+ for (int i = 0; i < lenth; ++i) {
+ if (typeAnnotations[i] != null) {
+ firstTypeIndex = i;
+ break;
+ }
+ }
+ }
sourceStart = (int)(positions[0]>>>32);
- length = (int)(positions[nameLength - 1] & 0xFFFFFFFF) - sourceStart + 1;
- final Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference);
- final SimpleType simpleType = new SimpleType(this.ast);
- simpleType.setName(qualifiedName);
- type = simpleType;
- type.setSourceRange(sourceStart, length);
+ Name name = null;
+ if (firstTypeIndex == 0) {
+ final SimpleName simpleName = new SimpleName(this.ast);
+ simpleName.internalSetIdentifier(new String(tokens[0]));
+ recordPendingNameScopeResolution(simpleName);
+ int start = (int) (positions[0] >>> 32);
+ int end = (int) positions[0];
+ simpleName.setSourceRange(start, end);
+ simpleName.index = 1;
+ name = simpleName;
+ if (this.resolveBindings) {
+ recordNodes(simpleName, typeReference);
+ }
+ } else {
+ name = setQualifiedNameNameAndSourceRanges(tokens, positions, firstTypeIndex, typeReference);
+ }
+ SimpleType simpleType = new SimpleType(this.ast);
+ simpleType.setName(name);
+ int start = (int)(positions[0] >>> 32);
+ int end = (int)positions[firstTypeIndex];
+ simpleType.setSourceRange(start, end - start + 1);
+ if (typeAnnotations != null && (annotations = typeAnnotations[firstTypeIndex]) != null) {
+ annotateType(simpleType, annotations);
+ }
+ if (this.resolveBindings) {
+ recordNodes(simpleType, typeReference);
+ }
+ Type currentType = simpleType;
+
+ for (int i = firstTypeIndex + 1; i < lenth; ++i) {
+ SimpleName simpleName = new SimpleName(this.ast);
+ simpleName.internalSetIdentifier(new String(tokens[i]));
+ simpleName.index = i + 1;
+ start = (int) (positions[i] >>> 32);
+ end = (int) positions[i];
+ simpleName.setSourceRange(start, end - start +1);
+ recordPendingNameScopeResolution(simpleName);
+ QualifiedType qualifiedType = new QualifiedType(this.ast);
+ qualifiedType.setQualifier(currentType);
+ qualifiedType.setName(simpleName);
+ if (typeAnnotations != null && (annotations = typeAnnotations[i]) != null) {
+ annotateType(qualifiedType, annotations);
+ }
+ if (this.resolveBindings) {
+ recordNodes(simpleName, typeReference);
+ recordNodes(qualifiedType, typeReference);
+ }
+ start = currentType.getStartPosition();
+ end = simpleName.getStartPosition() + simpleName.getLength() - 1;
+ qualifiedType.setSourceRange(start, end - start + 1);
+ currentType = qualifiedType;
+ qualifiedType.index = 1;
+ }
+ type = currentType;
} else {
TypeReference[] typeReferences = ((org.eclipse.jdt.internal.compiler.ast.UnionTypeReference) typeReference).typeReferences;
switch(this.ast.apiLevel) {
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 18a231a676..77d48d49db 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
@@ -1,10 +1,14 @@
/*******************************************************************************
- * 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
* Stephan Herrmann - Contribution for Bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding
@@ -285,11 +289,14 @@ class DefaultBindingResolver extends BindingResolver {
this.bindingTables.compilerBindingsToASTBindings.put(packageBinding, binding);
return binding;
}
- private int getTypeArguments(ParameterizedQualifiedTypeReference typeReference) {
+ private int getTypeCount(ParameterizedQualifiedTypeReference typeReference) {
TypeReference[][] typeArguments = typeReference.typeArguments;
int value = 0;
- for (int i = 0, max = typeArguments.length; i < max; i++) {
- if ((typeArguments[i] != null) || (value != 0)) {
+ org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations = typeReference.annotations;
+ int length = typeReference.tokens.length;
+ for (int i = 0; i < length; ++i) {
+ if (value != 0 || (typeArguments != null && typeArguments[i] != null) ||
+ (typeAnnotations != null && typeAnnotations[i] != null )) {
value++;
}
}
@@ -1551,7 +1558,7 @@ class DefaultBindingResolver extends BindingResolver {
} else {
index = 1;
}
- final int numberOfTypeArgumentsNotNull = getTypeArguments(typeReference);
+ final int numberOfTypeArgumentsNotNull = getTypeCount(typeReference);
if (index != numberOfTypeArgumentsNotNull) {
int i = numberOfTypeArgumentsNotNull;
while (i != index) {
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 0c44eef602..d29903b68e 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
@@ -1299,8 +1299,17 @@ public class NaiveASTFlattener extends ASTVisitor {
* @see ASTVisitor#visit(SimpleType)
*/
public boolean visit(SimpleType node) {
- visitTypeAnnotations(node);
- node.getName().accept(this);
+ Name name = node.getName();
+ if (name.isQualifiedName()) {
+ QualifiedName qualifiedName = (QualifiedName) name;
+ qualifiedName.getQualifier().accept(this);
+ this.buffer.append(".");//$NON-NLS-1$
+ visitTypeAnnotations(node);
+ qualifiedName.getName().accept(this);
+ } else {
+ visitTypeAnnotations(node);
+ node.getName().accept(this);
+ }
return false;
}

Back to the top