diff options
| author | Manoj Palat | 2013-01-24 06:22:43 +0000 |
|---|---|---|
| committer | ssankaran | 2013-01-24 06:22:43 +0000 |
| commit | c0d8ddbb4b72e166c7dc81eb807bc47fd1beaa74 (patch) | |
| tree | fc2ff4fa437e9de4b8e20c013415a6d5be01f048 | |
| parent | 6cea394a74122bc3b2f5fee1a70c7921f0e635d8 (diff) | |
| download | eclipse.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
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; } |
