/******************************************************************************* * Copyright (c) 2000, 2016 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 * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for * Bug 425183 - [1.8][inference] make CaptureBinding18 safe *******************************************************************************/ package org.eclipse.jdt.core.tests.dom; import java.io.IOException; import java.util.List; import junit.framework.Test; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.dom.*; import org.eclipse.jdt.core.BindingKey; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.core.ResolvedBinaryMethod; @SuppressWarnings({"rawtypes"}) public class ASTConverter18Test extends ConverterTestSetup { ICompilationUnit workingCopy; public void setUpSuite() throws Exception { super.setUpSuite(); this.ast = AST.newAST(AST.JLS8); } public ASTConverter18Test(String name) { super(name); } static { // TESTS_NUMBERS = new int[] { 19 }; // TESTS_RANGE = new int[] { 1, -1 }; // TESTS_NAMES = new String[] {"test0001"}; } public static Test suite() { return buildModelTestSuite(ASTConverter18Test.class); } protected void tearDown() throws Exception { super.tearDown(); if (this.workingCopy != null) { this.workingCopy.discardWorkingCopy(); this.workingCopy = null; } } /* * Type Annotations on Variable Arguments */ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391898 public void test0001() throws JavaModelException { String contents = " @java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + " @interface Marker {\n" + " }\n" + "public class X {\n" + " public void foo(int @Marker... args) {\n" + " }\n" + " public void bar(@Marker int @Marker... args) {\n" + " }\n" + "}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true/*resolve*/); ASTNode node = buildAST( contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 1, 0); assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); MethodDeclaration methodDeclaration = (MethodDeclaration) node; List parameters = methodDeclaration.parameters(); assertEquals("wrong size", 1, parameters.size()); SingleVariableDeclaration parameter = (SingleVariableDeclaration) parameters.get(0); List annotations = parameter.varargsAnnotations(); assertEquals("Wrong number of annotations", 1, annotations.size()); ASTNode annotation = (ASTNode) annotations.get(0); checkSourceRange(annotation, "@Marker", contents); node = getASTNode(compilationUnit,1,1); assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); parameters = methodDeclaration.parameters(); assertEquals("Wrong number of parameters", 1, parameters.size()); parameter = (SingleVariableDeclaration) parameters.get(0); annotations = parameter.varargsAnnotations(); assertEquals("Wrong number of annotations", 1, annotations.size()); annotation = (ASTNode) annotations.get(0); checkSourceRange(annotation, "@Marker", contents); } /* * Type Annotations on Variable Argument of ArrayType */ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=413569 public void test413569() throws JavaModelException { String contents = "import java.lang.annotation.*;\n" + "public class X {\n" + " @Target(ElementType.TYPE_USE) static @interface A {}\n" + " @Target(ElementType.TYPE_USE) static @interface B {}\n" + " @Target(ElementType.TYPE_USE) static @interface C { Class<?> value() default Object.class; }\n" + " @Target(ElementType.TYPE_USE) static @interface D { Class<?> d(); }\n" + " void foo(@A int @B()[] @C(int[].class) [] @D(d=String[].class)... arg) {}\n" + "}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true/*resolve*/); ASTNode node = buildAST( contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 0, 4); assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); MethodDeclaration methodDeclaration = (MethodDeclaration) node; List parameters = methodDeclaration.parameters(); assertEquals("wrong size", 1, parameters.size()); SingleVariableDeclaration parameter = (SingleVariableDeclaration) parameters.get(0); ArrayType type = (ArrayType) parameter.getType(); List dimensions = type.dimensions(); assertEquals(2, dimensions.size()); Dimension dimension = (Dimension) dimensions.get(0); List annotations = dimension.annotations(); assertEquals("Wrong number of annotations", 1, annotations.size()); Annotation annotation = (Annotation) annotations.get(0); checkSourceRange(annotation, "@B()", contents); dimension = (Dimension) dimensions.get(1); annotations = dimension.annotations(); assertEquals("Wrong number of annotations", 1, annotations.size()); annotation = (Annotation) annotations.get(0); checkSourceRange(annotation, "@C(int[].class)", contents); annotations = parameter.varargsAnnotations(); assertEquals("Wrong number of annotations", 1, annotations.size()); annotation = (Annotation) annotations.get(0); checkSourceRange(annotation, "@D(d=String[].class)", 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); NameQualifiedType nameQualifiedType = (NameQualifiedType) castExpression.getType(); assertNotNull(nameQualifiedType); assertEquals("java.lang.@Marker String", nameQualifiedType.toString()); List annotations = nameQualifiedType.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 = (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.isNameQualifiedType()); nameQualifiedType = (NameQualifiedType) type; assertNotNull(nameQualifiedType); assertEquals("Outer.@Marker2 Inner", nameQualifiedType.toString()); annotations = nameQualifiedType.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.isNameQualifiedType()); nameQualifiedType = (NameQualifiedType) type; assertNotNull(nameQualifiedType); assertEquals("Outer.Inner.@Marker1 Deeper", nameQualifiedType.toString()); annotations = nameQualifiedType.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.isNameQualifiedType()); nameQualifiedType = (NameQualifiedType) qualifierType; assertEquals("Outer.@Marker1 Inner", nameQualifiedType.toString()); annotations = nameQualifiedType.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"; ArrayType type = (ArrayType) buildAST(contents, this.workingCopy); 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 elementType = type.getElementType(); binding = elementType.resolveBinding(); assertNotNull("No binding", binding); assertEquals("Wrong qualified name", "test0004.Outer<java.lang.Integer>.Inner<java.lang.Double>", binding.getQualifiedName()); assertTrue("Not parameterized", elementType.isParameterizedType()); ParameterizedType parameterizedType = (ParameterizedType) elementType; 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.isNameQualifiedType()); NameQualifiedType nameQualifiedType = (NameQualifiedType) type; assertEquals("Outer.@Marker1 Inner", nameQualifiedType.toString()); List annotations = nameQualifiedType.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 = (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); NameQualifiedType nameQualifiedType = (NameQualifiedType) qualifiedType.getQualifier(); assertEquals("Outer.@Marker1 Inner", nameQualifiedType.toString()); annotations = nameQualifiedType.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()); Type qualifierType = qualifiedType.getQualifier(); assertTrue(qualifierType.isNameQualifiedType()); nameQualifiedType = (NameQualifiedType) qualifierType; assertEquals("Outer.@Marker1 Inner", nameQualifiedType.toString()); annotations = nameQualifiedType.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.isNameQualifiedType()); nameQualifiedType = (NameQualifiedType) type; assertEquals("Outer1.@Marker1 Inner", nameQualifiedType.toString()); annotations = nameQualifiedType.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()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391893 public void test0007() throws JavaModelException { String contents = "public class X {\n" + " public void foo(@Marker @Marker2 X this, @Marker2 @Marker int i){}\n" + "}\n" + "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker {}\n" + "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker2 {}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; node = getASTNode(unit, 0, 0); assertEquals("Not a method Declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); MethodDeclaration method = (MethodDeclaration) node; Type receiver = method.getReceiverType(); assertEquals("Not a simple type", ASTNode.SIMPLE_TYPE, receiver.getNodeType()); assertEquals("Incorrect receiver signature", "@Marker @Marker2 X", ((SimpleType) receiver).toString()); assertEquals("Incorrect annotations on receiver", 2, ((SimpleType) receiver).annotations().size()); assertNull("Incorrect receiver qualfier", method.getReceiverQualifier()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391893 public void test0008() throws JavaModelException { String contents = "public class X {\n" + " class Y {\n" + " public Y(@Marker @Marker2 X X.this, @Marker2 @Marker int i){}\n" + " }\n" + "}\n" + "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker {}\n" + "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker2 {}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; node = getASTNode(unit, 0, 0); assertEquals("Not a type Declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); TypeDeclaration innerType = (TypeDeclaration) node; assertEquals("Incorrect no of methods", 1, innerType.getMethods().length); MethodDeclaration method = innerType.getMethods()[0]; Type receiver = method.getReceiverType(); assertEquals("Not a simple type", ASTNode.SIMPLE_TYPE, receiver.getNodeType()); assertEquals("Incorrect receiver signature", "@Marker @Marker2 X", ((SimpleType) receiver).toString()); assertEquals("Incorrect annotations on receiver", 2, ((SimpleType) receiver).annotations().size()); assertNotNull("Incorrect receiver qualfier", method.getReceiverQualifier()); assertEquals("Incorrect receiver qualfier", "X", method.getReceiverQualifier().getFullyQualifiedName()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391895 public void test0009() throws JavaModelException { String contents = "import java.lang.annotation.ElementType;\n" + "public class X {\n" + " class Y {\n" + " @Annot int @Annot1 [] a @Annot2 @Annot3 [] @Annot3 @Annot2 [] @Annot4 [], b @Annot2 @Annot3 [] @Annot4 [], c [][][];\n" + " public void foo1(@Annot int @Annot1 [] p @Annot2 @Annot3 [] @Annot3 @Annot2 [] @Annot4 @Annot3 []) {}\n" + " public void foo2(@Annot int p [][]) {}\n" + " @Annot String @Annot1 [] foo3() @Annot1 @Annot2 [][] { return null; }\n" + " }\n" + "}\n" + "@java.lang.annotation.Target(value = {ElementType.TYPE_USE})\n" + "@interface Annot {}\n" + "@java.lang.annotation.Target(value = {ElementType.TYPE_USE})\n" + "@interface Annot1 {}\n" + "@java.lang.annotation.Target(value = {ElementType.TYPE_USE})\n" + "@interface Annot2 {}\n" + "@java.lang.annotation.Target(value = {ElementType.TYPE_USE})\n" + "@interface Annot3 {}\n" + "@java.lang.annotation.Target(value = {ElementType.TYPE_USE})\n" + "@interface Annot4 {}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; node = getASTNode(unit, 0, 0); assertEquals("Not a type Declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); TypeDeclaration type = (TypeDeclaration) node; FieldDeclaration field = type.getFields()[0]; List fragments = field.fragments(); assertEquals("Incorrect no of fragments", 3, fragments.size()); VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(0); assertExtraDimensionsEqual("Incorrect extra dimensions", fragment.extraDimensions(), "@Annot2 @Annot3 [] @Annot3 @Annot2 [] @Annot4 []"); fragment = (VariableDeclarationFragment) fragments.get(1); assertExtraDimensionsEqual("Incorrect extra dimensions", fragment.extraDimensions(), "@Annot2 @Annot3 [] @Annot4 []"); fragment = (VariableDeclarationFragment) fragments.get(2); assertExtraDimensionsEqual("Incorrect extra dimensions", fragment.extraDimensions(), "[] [] []"); MethodDeclaration[] methods = type.getMethods(); assertEquals("Incorrect no of methods", 3, methods.length); MethodDeclaration method = methods[0]; List parameters = method.parameters(); assertEquals("Incorrect no of parameters", 1, parameters.size()); assertExtraDimensionsEqual("Incorrect extra dimensions", ((SingleVariableDeclaration) parameters.get(0)).extraDimensions(), "@Annot2 @Annot3 [] @Annot3 @Annot2 [] @Annot4 @Annot3 []"); method = methods[1]; parameters = method.parameters(); assertEquals("Incorrect no of parameters", 1, parameters.size()); assertExtraDimensionsEqual("Incorrect extra dimensions", ((SingleVariableDeclaration) parameters.get(0)).extraDimensions(), "[] []"); method = methods[2]; assertExtraDimensionsEqual("Incorrect extra dimensions", method.extraDimensions(), "@Annot1 @Annot2 [] []"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=399600 public void test0010() throws JavaModelException { String contents = "import java.lang.annotation.ElementType;\n" + "public class X {\n" + " @Marker int foo(@Marker(\"Blah\") int z) @Marker [] @Marker [] {\n" + " return null;\n" + " }\n" + "}\n" + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + "@interface Marker {\n" + " String value() default \"Blah\";\n" + "}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; node = getASTNode(unit, 0, 0); assertEquals("Not a method declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); MethodDeclaration method = (MethodDeclaration) node; assertExtraDimensionsEqual("Incorrect extra dimensions", method.extraDimensions(), "@Marker [] @Marker []"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391894 public void test0011() throws JavaModelException { String contents = "import java.lang.annotation.ElementType;\n" + "public class X {\n" + " public void foo() {\n" + " int @Marker [][][] i = new @Marker2 int @Marker @Marker2 [2] @Marker2 @Marker3 [bar()] @Marker3 @Marker []; \n" + " int @Marker [][][] j = new @Marker int @Marker3 @Marker [2] @Marker @Marker2 [X.bar2(2)] @Marker2 @Marker3 [];\n" + " }\n" + " public int bar() {\n" + " return 2;\n" + " }\n" + " public static int bar2(int k) {\n" + " return k;\n" + " }\n" + "}\n" + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + "@interface Marker {}\n" + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + "@interface Marker2 {}\n" + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + "@interface Marker3 {}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; node = getASTNode(unit, 0, 0); assertEquals("Not a Method Declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); MethodDeclaration method = (MethodDeclaration) node; List list = method.getBody().statements(); assertEquals("Incorrect no of statements", 2, list.size()); VariableDeclarationStatement statement1 = (VariableDeclarationStatement) list.get(0); VariableDeclarationStatement statement2 = (VariableDeclarationStatement) list.get(1); list = statement1.fragments(); assertEquals("Incorrect no of fragments", 1, list.size()); VariableDeclarationFragment fragment = (VariableDeclarationFragment) list.get(0); ArrayCreation creation = (ArrayCreation) fragment.getInitializer(); Type type = creation.getType(); assertEquals("Incorrect type", true, type.isArrayType()); checkSourceRange(type, "@Marker2 int @Marker @Marker2 [2] @Marker2 @Marker3 [bar()] @Marker3 @Marker []", contents.toCharArray()); Dimension dimension = (Dimension) ((ArrayType) type).dimensions().get(2); assertEquals("Incorrect annotations", "@Marker3 @Marker ", convertAnnotationsList(dimension.annotations())); dimension = (Dimension) ((ArrayType) type).dimensions().get(1); assertEquals("Incorrect annotations", "@Marker2 @Marker3 ", convertAnnotationsList(dimension.annotations())); dimension = (Dimension) ((ArrayType) type).dimensions().get(0); assertEquals("Incorrect annotations", "@Marker @Marker2 ", convertAnnotationsList(dimension.annotations())); List dimensions = creation.dimensions(); assertEquals("Incorrect expressions", 2, dimensions.size()); assertEquals("Incorrect expressions", "2", dimensions.get(0).toString()); assertEquals("Incorrect expressions", "bar()", dimensions.get(1).toString()); list = statement2.fragments(); assertEquals("Incorrect no of fragments", 1, list.size()); fragment = (VariableDeclarationFragment) list.get(0); creation = (ArrayCreation) fragment.getInitializer(); checkSourceRange(creation.getType(), "@Marker int @Marker3 @Marker [2] @Marker @Marker2 [X.bar2(2)] @Marker2 @Marker3 []", contents.toCharArray()); type = creation.getType(); assertEquals("Incorrect type", true, type.isArrayType()); dimension = (Dimension) ((ArrayType) type).dimensions().get(2); assertEquals("Incorrect annotations", "@Marker2 @Marker3 ", convertAnnotationsList(dimension.annotations())); dimension = (Dimension) ((ArrayType) type).dimensions().get(1); assertEquals("Incorrect annotations", "@Marker @Marker2 ", convertAnnotationsList(dimension.annotations())); dimension = (Dimension) ((ArrayType) type).dimensions().get(0); assertEquals("Incorrect annotations", "@Marker3 @Marker ", convertAnnotationsList(dimension.annotations())); dimensions = creation.dimensions(); assertEquals("Incorrect expressions", 2, dimensions.size()); assertEquals("Incorrect expressions", "2", dimensions.get(0).toString()); assertEquals("Incorrect expressions", "X.bar2(2)", dimensions.get(1).toString()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391894 public void test0012() throws JavaModelException { String contents = "import java.lang.annotation.ElementType;\n" + "public class X {\n" + " public void foo() {\n" + " int @Marker [][][] i = new @Marker2 int @Marker @Marker2 [] @Marker2 @Marker3 [] @Marker3 @Marker [] {{{1, 2, 3}}}; \n" + " }\n" + "}\n" + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + "@interface Marker {}\n" + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + "@interface Marker2 {}\n" + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + "@interface Marker3 {}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; node = getASTNode(unit, 0, 0); assertEquals("Not a Method Declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); MethodDeclaration method = (MethodDeclaration) node; List list = method.getBody().statements(); assertEquals("Incorrect no of statements", 1, list.size()); VariableDeclarationStatement statement1 = (VariableDeclarationStatement) list.get(0); list = statement1.fragments(); assertEquals("Incorrect no of fragments", 1, list.size()); VariableDeclarationFragment fragment = (VariableDeclarationFragment) list.get(0); ArrayCreation creation = (ArrayCreation) fragment.getInitializer(); Type type = creation.getType(); assertEquals("Incorrect type", true, type.isArrayType()); checkSourceRange(type, "@Marker2 int @Marker @Marker2 [] @Marker2 @Marker3 [] @Marker3 @Marker []", contents.toCharArray()); ArrayInitializer initializer = creation.getInitializer(); checkSourceRange(initializer, "{{{1, 2, 3}}}", contents.toCharArray()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391894 // Force to use JLS4 and confirm malformed flags are set. public void test0021() throws JavaModelException { String contents = "import java.lang.annotation.ElementType;\n" + "public class X {\n" + " public void foo() {\n" + " int @Marker [][][] i = new @Marker2 int @Marker @Marker2 [] @Marker2 @Marker3 [] @Marker3 @Marker [] {{{1, 2, 3}}}; \n" + " }\n" + "}\n" + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + "@interface Marker {}\n" + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + "@interface Marker2 {}\n" + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + "@interface Marker3 {}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); CompilationUnit unit = (CompilationUnit) buildAST(getJLS4(), contents, this.workingCopy, true, true, true); ASTNode node = getASTNode(unit, 0, 0); assertEquals("Not a Method Declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); MethodDeclaration method = (MethodDeclaration) node; List list = method.getBody().statements(); assertEquals("Incorrect no of statements", 1, list.size()); VariableDeclarationStatement statement1 = (VariableDeclarationStatement) list.get(0); list = statement1.fragments(); assertEquals("Incorrect no of fragments", 1, list.size()); VariableDeclarationFragment fragment = (VariableDeclarationFragment) list.get(0); ArrayCreation creation = (ArrayCreation) fragment.getInitializer(); Type type = creation.getType(); assertEquals("Incorrect type", true, type.isArrayType()); assertEquals("Type should be malformed", ASTNode.MALFORMED, (type.getFlags() & ASTNode.MALFORMED)); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=399768 * * @throws JavaModelException */ public void test0013() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test0010/X.java", true/* resolve */); String contents = "package test0010;" + "import java.lang.annotation.Target;\n" + "public class X implements One<@Marker1 Integer, @Marker2 Boolean> {\n" + "}\n" + "class Y implements One<@Marker1 @Marker2 Integer, @Marker2 @Marker1 Double> {\n" + "}\n" + "interface One<T, U> {}\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); // simple types for generic type arguments to parameterized classes TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 0); Type type = (Type)((ParameterizedType) typedeclaration.superInterfaceTypes().get(0)).typeArguments().get(0); assertTrue(type.isSimpleType()); SimpleType simpleType = (SimpleType) type; List annotations = simpleType.annotations(); assertEquals("wrong number of annotations", 1, annotations.size()); assertEquals("@Marker1", annotations.get(0).toString()); assertNotNull("No annotation", type); typedeclaration = (TypeDeclaration) getASTNode(cu, 1); type = (Type)((ParameterizedType) typedeclaration.superInterfaceTypes().get(0)).typeArguments().get(0); assertTrue(type.isSimpleType()); simpleType = (SimpleType) type; annotations = simpleType.annotations(); assertEquals("wrong number of annotations", 2, annotations.size()); assertEquals("@Marker2", annotations.get(1).toString()); assertNotNull("No annotation", type); type = (Type)((ParameterizedType) typedeclaration.superInterfaceTypes().get(0)).typeArguments().get(1); assertTrue(type.isSimpleType()); simpleType = (SimpleType) type; annotations = simpleType.annotations(); assertEquals("wrong number of annotations", 2, annotations.size()); assertEquals("@Marker1", annotations.get(1).toString()); assertNotNull("No annotation", type); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=399768 * * @throws JavaModelException */ public void test0014() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test0011/X.java", true/* resolve */); String contents = "package test0011;" + "import java.lang.annotation.Target;\n" + "public class X {\n" + " public void foo() {\n" + " Y y = new <@Marker2 @Marker1 String> Y(new String(\"Hello\"));\n" + " len = y.<@Marker1 @Marker2 String> bar(new String(\"World\"));\n" + " }\n" + " public int len;\n" + "}\n" + "class Y {\n" + " public <T> Y(T t) {\n" + " len = t instanceof String ? ((String)t).length() : 0;\n" + " }\n" + " public <T> int bar(T t) {\n" + " return t instanceof String ? ((String)t).length() : len;\n" + " }\n" + " private int len;\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); // simple type for generic type arguments in a generic method or constructor invocation MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(cu, 0, 0); List statements = methodDeclaration.getBody().statements(); Statement statement = (Statement)statements.get(0); VariableDeclarationStatement variableDeclarationStatement = (VariableDeclarationStatement) statement; VariableDeclarationFragment variableDeclarationFragment = (VariableDeclarationFragment) variableDeclarationStatement.fragments().get(0); Expression expression = variableDeclarationFragment.getInitializer(); ClassInstanceCreation classInstanceCreation = (ClassInstanceCreation) expression; Type type = (Type) classInstanceCreation.typeArguments().get(0); assertEquals("@Marker2 @Marker1 String", type.toString()); assertTrue(type.isSimpleType()); SimpleType simpleType = (SimpleType) type; List annotations = simpleType.annotations(); assertEquals("wrong number of annotations", 2, annotations.size()); assertEquals("@Marker2", annotations.get(0).toString()); statement = (Statement) statements.get(1); Assignment assignment = (Assignment) ((ExpressionStatement)statement).getExpression(); expression = assignment.getRightHandSide(); MethodInvocation methodInvocation = (MethodInvocation) expression; simpleType = (SimpleType)methodInvocation.typeArguments().get(0); annotations = simpleType.annotations(); assertEquals("wrong number of annotations", 2, annotations.size()); assertEquals("@Marker1", annotations.get(0).toString()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=399768 * * @throws JavaModelException */ public void test0015() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test0012/X.java", true/* resolve */); String contents = "package test0012;" + "import java.lang.annotation.Target;\n" + "import java.io.File;\n" + "public class X <@Marker1 @Marker3 F extends @Marker1 @Marker2 File> {\n" + " public int foo(F f) {\n" + " Y <@Marker2 @Marker3 ? super @Marker1 @Marker2 File> y = new @Marker2 @Marker1 Y<File>();\n" + " Outer o = new @Marker1 @Marker2 Outer();\n" + " Outer.Inner inner = o.new @Marker1 @Marker2 Inner();\n" + " ZZ zz = new <String> @Marker1 @Marker2 ZZ();\n" + " return f.getName().length() + y.hashCode() + inner.hashCode();\n" + " }\n" + "}\n" + "class Y<@Marker3 T> {\n" + " public int bar(T t) {\n" + " return t instanceof @Marker1 @Marker2 File ? t.toString().length() : 0;\n" + " }\n" + "}\n" + "class Outer {\n" + " public class Inner {\n" + " public class Deeper {\n" + " }\n" + " }\n" + "}\n" + "class ZZ {\n" + "public @Marker1 @Marker2 <T> ZZ() {\n" + " T t = null;\n" + " len = t instanceof String ? t.hashCode() : 0;\n" + "}\n" + "public @Marker1 int getint(@Marker2 @Marker1 ZZ this) {return len;}\n" + "public int len;\n" + "}\n" + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker1 {}\n" + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker2 {}\n" + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker3 {}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 0); TypeParameter typeParameter = (TypeParameter) typedeclaration.typeParameters().get(0); // TypeParameter with TYPE_USE and TYPE_PARAMETER annotation combination. assertEquals("@Marker1 @Marker3 F extends @Marker1 @Marker2 File", typeParameter.toString()); assertTrue(typeParameter.modifiers().size() == 2); Annotation annotation = (Annotation)typeParameter.modifiers().get(1); assertEquals("@Marker3", annotation.toString()); IAnnotationBinding abinding = annotation.resolveAnnotationBinding(); assertEquals("@Marker3()", abinding.toString()); // simpletype for type parameter bounds SimpleType simpleType = (SimpleType) typeParameter.typeBounds().get(0); annotation = (Annotation) simpleType.annotations().get(1); assertEquals("@Marker2", annotation.toString()); abinding = annotation.resolveAnnotationBinding(); assertEquals("@Marker2()", abinding.toString()); MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(cu, 0, 0); List statements = methodDeclaration.getBody().statements(); Statement statement = (Statement)statements.get(0); VariableDeclarationStatement variableDeclarationStatement = (VariableDeclarationStatement)statement; Type type = variableDeclarationStatement.getType(); assertTrue(type.isParameterizedType()); type = (Type)((ParameterizedType)type).typeArguments().get(0); assertTrue(type.isWildcardType()); // for constructor invocation results 1/4 VariableDeclarationFragment fragment = (VariableDeclarationFragment) variableDeclarationStatement.fragments().get(0); Expression expression = fragment.getInitializer(); assertEquals("new @Marker2 @Marker1 Y<File>()", expression.toString()); simpleType = (SimpleType) ((ParameterizedType)((ClassInstanceCreation)expression).getType()).getType(); assertEquals("@Marker2 @Marker1 Y", simpleType.toString()); annotation = (Annotation) simpleType.annotations().get(1); assertEquals("@Marker1", annotation.toString()); abinding = annotation.resolveAnnotationBinding(); assertEquals("@Marker1()", abinding.toString()); // for constructor invocation results 2/4 variableDeclarationStatement = (VariableDeclarationStatement) statements.get(1); fragment = (VariableDeclarationFragment) variableDeclarationStatement.fragments().get(0); expression = fragment.getInitializer(); assertEquals("new @Marker1 @Marker2 Outer()", expression.toString()); simpleType = (SimpleType) ((ClassInstanceCreation)expression).getType(); assertEquals("@Marker1 @Marker2 Outer", simpleType.toString()); annotation = (Annotation) simpleType.annotations().get(1); assertEquals("@Marker2", annotation.toString()); abinding = annotation.resolveAnnotationBinding(); assertEquals("@Marker2()", abinding.toString()); // for constructor invocation results 3/4 variableDeclarationStatement = (VariableDeclarationStatement) statements.get(2); fragment = (VariableDeclarationFragment) variableDeclarationStatement.fragments().get(0); expression = fragment.getInitializer(); assertEquals("o.new @Marker1 @Marker2 Inner()", expression.toString()); simpleType = (SimpleType) ((ClassInstanceCreation)expression).getType(); assertEquals("@Marker1 @Marker2 Inner", simpleType.toString()); annotation = (Annotation) simpleType.annotations().get(1); assertEquals("@Marker2", annotation.toString()); abinding = annotation.resolveAnnotationBinding(); assertEquals("@Marker2()", abinding.toString()); // for constructor invocation results 4/4 variableDeclarationStatement = (VariableDeclarationStatement) statements.get(3); fragment = (VariableDeclarationFragment) variableDeclarationStatement.fragments().get(0); expression = fragment.getInitializer(); assertEquals("new <String>@Marker1 @Marker2 ZZ()", expression.toString()); simpleType = (SimpleType) ((ClassInstanceCreation)expression).getType(); assertEquals("@Marker1 @Marker2 ZZ", simpleType.toString()); annotation = (Annotation) simpleType.annotations().get(1); assertEquals("@Marker2", annotation.toString()); abinding = annotation.resolveAnnotationBinding(); assertEquals("@Marker2()", abinding.toString()); // annotations on wildcardtypes with TYPE_USE and TYPE_PARAMETER combination. WildcardType wildCardType = (WildcardType) type; assertEquals("@Marker2 @Marker3 ? super @Marker1 @Marker2 File", wildCardType.toString()); assertTrue(wildCardType.annotations().size() == 2); annotation = (Annotation) wildCardType.annotations().get(1); assertEquals("@Marker3", annotation.toString()); abinding = annotation.resolveAnnotationBinding(); assertEquals("@Marker3()", abinding.toString()); // simpleType for wildcard bounds simpleType = (SimpleType) wildCardType.getBound(); annotation = (Annotation) simpleType.annotations().get(1); assertEquals("@Marker2", annotation.toString()); abinding = annotation.resolveAnnotationBinding(); assertEquals("@Marker2()", abinding.toString()); // class declaration with TYPE_PARAMETER annotation typedeclaration = (TypeDeclaration) getASTNode(cu, 1); typeParameter = (TypeParameter) typedeclaration.typeParameters().get(0); assertEquals("@Marker3 T", typeParameter.toString()); assertTrue(typeParameter.modifiers().size() == 1); annotation = (Annotation)typeParameter.modifiers().get(0); assertEquals("@Marker3", annotation.toString()); abinding = annotation.resolveAnnotationBinding(); assertEquals("@Marker3()", abinding.toString()); // for type tests methodDeclaration = (MethodDeclaration) getASTNode(cu, 1, 0); statements = methodDeclaration.getBody().statements(); statement = (Statement)statements.get(0); ConditionalExpression conditionalExpression = (ConditionalExpression)((ReturnStatement)statement).getExpression(); simpleType = (SimpleType) ((InstanceofExpression)conditionalExpression.getExpression()).getRightOperand(); assertEquals("@Marker1 @Marker2 File", simpleType.toString()); assertTrue(simpleType.annotations().size() == 2); annotation = (Annotation) simpleType.annotations().get(1); assertEquals("@Marker2", annotation.toString()); // type annotation in front of a constructor declaration methodDeclaration = (MethodDeclaration) getASTNode(cu, 3, 0); annotation = (Annotation) methodDeclaration.modifiers().get(2); assertEquals("@Marker2", annotation.toString()); abinding = annotation.resolveAnnotationBinding(); assertEquals("@Marker2()", abinding.toString()); // type annotation on "this" methodDeclaration = (MethodDeclaration) getASTNode(cu, 3, 1); simpleType = (SimpleType) methodDeclaration.getReceiverType(); assertEquals("@Marker2 @Marker1 ZZ", simpleType.toString()); annotation = (Annotation) simpleType.annotations().get(1); assertEquals("@Marker1", annotation.toString()); abinding = annotation.resolveAnnotationBinding(); assertEquals("@Marker1()", abinding.toString()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=399793 * * @throws JavaModelException */ public void test399793a() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test399793/X.java", true/* resolve */); String contents = "package test399793;" + "interface I {\n" + " int foo(int x);\n" + "}\n" + "public class X {\n" + " I i = vlambda -> {return 200;};\n" +"}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 1); FieldDeclaration fieldDeclaration = (FieldDeclaration) typedeclaration.bodyDeclarations().get(0); VariableDeclarationFragment fragment = (VariableDeclarationFragment)fieldDeclaration.fragments().get(0); Expression expression = fragment.getInitializer(); assertTrue(expression instanceof LambdaExpression); LambdaExpression lambdaExpression = (LambdaExpression)expression; assertEquals("vlambda -> {\n return 200;\n}\n", lambdaExpression.toString()); assertTrue(lambdaExpression.parameters().size() == 1); IMethodBinding binding = lambdaExpression.resolveMethodBinding(); assertEquals("public int foo(int) ", binding.toString()); assertEquals("real modifiers", ClassFileConstants.AccPublic, binding.getModifiers()); VariableDeclaration variableDeclaration = (VariableDeclaration) lambdaExpression.parameters().get(0); assertTrue(variableDeclaration instanceof VariableDeclarationFragment); fragment = (VariableDeclarationFragment)variableDeclaration; assertEquals("vlambda", fragment.toString()); IVariableBinding variableBinding = fragment.resolveBinding(); ITypeBinding typeBinding = variableBinding.getType(); assertNotNull("Null Binding for lambda argument", typeBinding); assertEquals("binding of int expected for lambda","int",typeBinding.getName()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=399793 * * @throws JavaModelException */ public void test399793b() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test399793/X.java", true/* resolve */); String contents = "package test399793;" + "interface I {\n" + " int foo(int x);\n" + "}\n" + "public class X {\n" + " I i = vlambda -> 200;\n" +"}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 1); FieldDeclaration fieldDeclaration = (FieldDeclaration) typedeclaration.bodyDeclarations().get(0); VariableDeclarationFragment fragment = (VariableDeclarationFragment)fieldDeclaration.fragments().get(0); Expression expression = fragment.getInitializer(); assertTrue(expression instanceof LambdaExpression); LambdaExpression lambdaExpression = (LambdaExpression)expression; assertEquals("vlambda -> 200", lambdaExpression.toString()); IMethodBinding binding = lambdaExpression.resolveMethodBinding(); assertEquals("public int foo(int) ", binding.toString()); assertEquals("real modifiers", ClassFileConstants.AccPublic, binding.getModifiers()); assertTrue(lambdaExpression.parameters().size() == 1); VariableDeclaration variableDeclaration = (VariableDeclaration) lambdaExpression.parameters().get(0); assertTrue(variableDeclaration instanceof VariableDeclarationFragment); fragment = (VariableDeclarationFragment)variableDeclaration; assertEquals("vlambda", fragment.toString()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=399793 * * @throws JavaModelException */ public void test399793c() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test399793/X.java", true/* resolve */); String contents = "package test399793;" + "interface I {\n" + " Object foo(int [] ia);\n" + "}\n" + "public class X {\n" + " I i = (int [] ia) ->{\n" + " return ia.clone();" + "};\n" +"}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 1); FieldDeclaration fieldDeclaration = (FieldDeclaration) typedeclaration.bodyDeclarations().get(0); VariableDeclarationFragment fragment = (VariableDeclarationFragment)fieldDeclaration.fragments().get(0); Expression expression = fragment.getInitializer(); assertTrue(expression instanceof LambdaExpression); LambdaExpression lambdaExpression = (LambdaExpression)expression; assertEquals("(int[] ia) -> {\n return ia.clone();\n}\n", lambdaExpression.toString()); IMethodBinding binding = lambdaExpression.resolveMethodBinding(); assertEquals("public java.lang.Object foo(int[]) ", binding.toString()); assertEquals("real modifiers", ClassFileConstants.AccPublic, binding.getModifiers()); assertTrue(lambdaExpression.parameters().size() == 1); VariableDeclaration variableDeclaration = (VariableDeclaration) lambdaExpression.parameters().get(0); assertTrue(variableDeclaration instanceof SingleVariableDeclaration); SingleVariableDeclaration singleVariableDeclaration = (SingleVariableDeclaration)variableDeclaration; assertEquals("int[] ia", singleVariableDeclaration.toString()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=399793 * * @throws JavaModelException */ public void test399793d() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test399793/X.java", true/* resolve */); String contents = "package test399793;" + "interface I {\n" + " void doit();\n" + "}\n" + "public class X {\n" + " I i = () -> {\n" + " System.out.println(this);\n" + " I j = () -> {\n" + " System.out.println(this);\n" + " I k = () -> {\n" + " System.out.println(this);\n" + " };\n" + " };\n" + " };\n" + " }\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 1); FieldDeclaration fieldDeclaration = (FieldDeclaration) typedeclaration.bodyDeclarations().get(0); VariableDeclarationFragment fragment = (VariableDeclarationFragment)fieldDeclaration.fragments().get(0); IVariableBinding variableBinding = fragment.resolveBinding(); assertEquals("test399793.I i", variableBinding.toString()); Expression expression = fragment.getInitializer(); assertTrue(expression instanceof LambdaExpression); LambdaExpression lambdaExpression = (LambdaExpression)expression; assertEquals("() -> {\n System.out.println(this);\n I j=() -> {\n System.out.println(this);\n I k=() -> {\n System.out.println(this);\n }\n;\n }\n;\n}\n", lambdaExpression.toString()); IMethodBinding binding = lambdaExpression.resolveMethodBinding(); assertEquals("public void doit() ", binding.toString()); assertEquals("real modifiers", ClassFileConstants.AccPublic, binding.getModifiers()); assertTrue(lambdaExpression.parameters().size() == 0); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=399794 * ReferenceExpression Family Tests * * @throws JavaModelException */ public void test399794() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test399794/X.java", true/* resolve */); String contents = "package test399794;" + "import java.lang.annotation.*;\n " + "interface I {\n" + " Object copy(int [] ia);\n" + "}\n" + "interface J {\n" + " void foo(int x);\n" + "}\n" + "class XX {\n" + " public void foo(int x) {}\n" + "}\n" + "\n" + "class Y {\n" + " static class Z {\n" + " public static void foo(int x) {\n" + " System.out.print(x);\n" + " }\n" + " }\n" + " public void foo(int x) {\n" + " System.out.print(x);\n" + " }\n" + " public <T> void foo(T t){t.hashCode();}\n" + "}\n" + "\n" + "public class X extends XX {\n" + " @SuppressWarnings(\"unused\")\n" + " public void bar(String [] args) {\n" + " Y y = new Y();\n" + " I i = @Marker int []::<String>clone;\n" + " J j = Y.@Marker Z :: foo;\n" + " J j1 = Y.@Marker Z :: <String> foo;\n" + " J jdash = @Marker W<@Marker Integer> :: <String> new ;\n" + " J jj = y :: foo;\n" + " J jx = super :: foo;\n" + " class Z {\n" + " void foo() {\n" + " J jz = X.super :: foo;\n" + " }\n" + " }\n" + " }\n" + " public static void main (String [] args) {}\n" + "}\n" + "class W<T> extends Y {\n" + " public W(T x) {}\n" + "}\n" + "\n" + "@Target (ElementType.TYPE_USE)\n" + "@interface Marker {}"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typeDeclaration = (TypeDeclaration) getASTNode(cu, 4); MethodDeclaration method = typeDeclaration.getMethods()[0]; List statements = method.getBody().statements(); assertTrue(statements.size() == 8); int fCount = 1; // type method reference with primitive type with type arguments VariableDeclarationStatement statement = (VariableDeclarationStatement) statements.get(fCount++); VariableDeclarationFragment fragment = (VariableDeclarationFragment) statement.fragments().get(0); Expression expression = fragment.getInitializer(); assertTrue(expression instanceof TypeMethodReference); TypeMethodReference typeMethodReference = (TypeMethodReference) expression; checkSourceRange(typeMethodReference, "@Marker int []::<String>clone", contents); ITypeBinding typeBinding = typeMethodReference.resolveTypeBinding(); assertNotNull(typeBinding); IMethodBinding methodBinding = typeMethodReference.resolveMethodBinding(); assertNull(methodBinding); Type type = typeMethodReference.getType(); checkSourceRange(type, "@Marker int []", contents); assertTrue(type.isArrayType()); List typeArguments = typeMethodReference.typeArguments(); assertTrue(typeArguments.size() == 1); type = (Type) typeArguments.get(0); checkSourceRange(type, "String", contents); assertTrue(type.isSimpleType()); SimpleName name = typeMethodReference.getName(); checkSourceRange(name, "clone", contents); typeBinding = name.resolveTypeBinding(); assertNotNull(typeBinding); // type method reference with qualified type without type arguments statement = (VariableDeclarationStatement) statements.get(fCount++); fragment = (VariableDeclarationFragment) statement.fragments().get(0); expression = fragment.getInitializer(); assertTrue(expression instanceof TypeMethodReference); typeMethodReference = (TypeMethodReference) expression; checkSourceRange(typeMethodReference, "Y.@Marker Z :: foo", contents); typeBinding = typeMethodReference.resolveTypeBinding(); assertNotNull(typeBinding); methodBinding = typeMethodReference.resolveMethodBinding(); assertNotNull(methodBinding); type = typeMethodReference.getType(); assertTrue(type.isNameQualifiedType()); checkSourceRange(type, "Y.@Marker Z", contents); typeArguments = typeMethodReference.typeArguments(); assertTrue(typeArguments.size() == 0); name = typeMethodReference.getName(); checkSourceRange(name, "foo", contents); typeBinding = name.resolveTypeBinding(); assertNotNull(typeBinding); // type method reference with qualified type with type arguments statement = (VariableDeclarationStatement) statements.get(fCount++); fragment = (VariableDeclarationFragment) statement.fragments().get(0); expression = fragment.getInitializer(); assertTrue(expression instanceof TypeMethodReference); typeMethodReference = (TypeMethodReference) expression; checkSourceRange(typeMethodReference, "Y.@Marker Z :: <String> foo", contents); typeBinding = typeMethodReference.resolveTypeBinding(); assertNotNull(typeBinding); methodBinding = typeMethodReference.resolveMethodBinding(); assertNotNull(methodBinding); type = typeMethodReference.getType(); assertTrue(type.isNameQualifiedType()); checkSourceRange(type, "Y.@Marker Z", contents); typeArguments = typeMethodReference.typeArguments(); assertTrue(typeArguments.size() == 1); type = (Type) typeArguments.get(0); assertTrue(type.isSimpleType()); checkSourceRange(type, "String", contents); name = typeMethodReference.getName(); checkSourceRange(name, "foo", contents); typeBinding = name.resolveTypeBinding(); assertNotNull(typeBinding); // creation method reference statement = (VariableDeclarationStatement) statements.get(fCount++); fragment = (VariableDeclarationFragment) statement.fragments().get(0); expression = fragment.getInitializer(); assertTrue(expression instanceof CreationReference); CreationReference creationReference = (CreationReference) expression; checkSourceRange(creationReference, "@Marker W<@Marker Integer> :: <String> new", contents); typeBinding = creationReference.resolveTypeBinding(); assertNotNull(typeBinding); methodBinding = creationReference.resolveMethodBinding(); assertNotNull(methodBinding); type = creationReference.getType(); checkSourceRange(type, "@Marker W<@Marker Integer>", contents); assertTrue(type instanceof ParameterizedType); assertASTNodeEquals("@Marker W<@Marker Integer>", type); typeArguments = creationReference.typeArguments(); assertTrue(typeArguments.size() == 1); type = (Type) typeArguments.get(0); assertTrue(type.isSimpleType()); checkSourceRange(type, "String", contents); // expression method reference statement = (VariableDeclarationStatement) statements.get(fCount++); fragment = (VariableDeclarationFragment) statement.fragments().get(0); expression = fragment.getInitializer(); assertTrue(expression instanceof ExpressionMethodReference); ExpressionMethodReference expressionMethodReference = (ExpressionMethodReference) expression; checkSourceRange(expressionMethodReference, "y :: foo", contents); typeBinding = expressionMethodReference.resolveTypeBinding(); assertNotNull(typeBinding); methodBinding = expressionMethodReference.resolveMethodBinding(); assertNotNull(methodBinding); Expression lhs = expressionMethodReference.getExpression(); checkSourceRange(lhs, "y", contents); typeArguments = expressionMethodReference.typeArguments(); assertTrue(typeArguments.size() == 0); name = expressionMethodReference.getName(); checkSourceRange(name, "foo", contents); typeBinding = name.resolveTypeBinding(); assertNotNull(typeBinding); // super method reference without qualifier statement = (VariableDeclarationStatement) statements.get(fCount++); fragment = (VariableDeclarationFragment) statement.fragments().get(0); expression = fragment.getInitializer(); assertTrue(expression instanceof SuperMethodReference); SuperMethodReference superMethodReference = (SuperMethodReference) expression; checkSourceRange(superMethodReference, "super :: foo", contents); typeBinding = superMethodReference.resolveTypeBinding(); assertNotNull(typeBinding); methodBinding = superMethodReference.resolveMethodBinding(); assertNotNull(methodBinding); assertNull(superMethodReference.getQualifier()); typeArguments = superMethodReference.typeArguments(); assertTrue(typeArguments.size() == 0); name = superMethodReference.getName(); checkSourceRange(name, "foo", contents); typeBinding = name.resolveTypeBinding(); assertNotNull(typeBinding); // super method reference with qualifier TypeDeclarationStatement typeDeclarationStatement = (TypeDeclarationStatement) statements.get(fCount); typeDeclaration = (TypeDeclaration) typeDeclarationStatement.getDeclaration(); method = typeDeclaration.getMethods()[0]; statements = method.getBody().statements(); assertTrue(statements.size() == 1); statement = (VariableDeclarationStatement) statements.get(0); fragment = (VariableDeclarationFragment) statement.fragments().get(0); expression = fragment.getInitializer(); assertTrue(expression instanceof SuperMethodReference); superMethodReference = (SuperMethodReference) expression; checkSourceRange(superMethodReference, "X.super :: foo", contents); typeBinding = superMethodReference.resolveTypeBinding(); assertNotNull(typeBinding); methodBinding = superMethodReference.resolveMethodBinding(); assertNotNull(methodBinding); name = (SimpleName) superMethodReference.getQualifier(); checkSourceRange(name, "X", contents); typeArguments = superMethodReference.typeArguments(); assertTrue(typeArguments.size() == 0); name = superMethodReference.getName(); checkSourceRange(name, "foo", contents); typeBinding = name.resolveTypeBinding(); assertNotNull(typeBinding); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=399793 * * @throws JavaModelException */ public void test399793e() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test399793/X.java", true/* resolve */); String contents = "package test399793;" + "interface I {\n" + " J foo();\n" + "}\n" + "interface J {\n" + " int foo();\n" + "}\n" + "public class X {\n" + " I I = () -> () -> 10;\n" + "}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 2); FieldDeclaration fieldDeclaration = (FieldDeclaration) typedeclaration.bodyDeclarations().get(0); VariableDeclarationFragment fragment = (VariableDeclarationFragment)fieldDeclaration.fragments().get(0); Expression expression = fragment.getInitializer(); assertTrue(expression instanceof LambdaExpression); LambdaExpression lambdaExpression = (LambdaExpression)expression; assertEquals("() -> () -> 10", lambdaExpression.toString()); IMethodBinding binding = lambdaExpression.resolveMethodBinding(); assertEquals("public test399793.J foo() ", binding.toString()); assertEquals("real modifiers", ClassFileConstants.AccPublic, binding.getModifiers()); assertTrue(lambdaExpression.parameters().size() == 0); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=402665 * * @throws JavaModelException */ public void test402665a() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test402665/X.java", true/* resolve */); String contents = "package test402665;" + "public class X {\n" + " public static interface StringToInt {\n" + " int stoi(String s);\n" + " }\n" + " public static interface ReduceInt {\n" + " int reduce(int a, int b);\n" + " }\n" + " void foo(StringToInt s) { }\n" + " void bar(ReduceInt r) { }\n" + " void bar() {\n" + " foo(s -> s.length());\n" + " foo((s) -> s.length());\n" + " foo((String s) -> s.length()); //SingleVariableDeclaration is OK\n" + " bar((x, y) -> x+y);\n" + " bar((int x, int y) -> x+y); //SingleVariableDeclarations are OK\n" + " }\n" + "}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 0); MethodDeclaration methoddecl = (MethodDeclaration)typedeclaration.bodyDeclarations().get(4); List statements = methoddecl.getBody().statements(); int sCount = 0; ExpressionStatement statement = (ExpressionStatement)statements.get(sCount++); MethodInvocation methodInvocation = (MethodInvocation)statement.getExpression(); LambdaExpression lambdaExpression = (LambdaExpression) methodInvocation.arguments().get(0); VariableDeclarationFragment fragment = (VariableDeclarationFragment)lambdaExpression.parameters().get(0); checkSourceRange(fragment, "s", contents); statement = (ExpressionStatement)statements.get(sCount++); methodInvocation = (MethodInvocation)statement.getExpression(); lambdaExpression = (LambdaExpression) methodInvocation.arguments().get(0); fragment = (VariableDeclarationFragment)lambdaExpression.parameters().get(0); checkSourceRange(fragment, "s", contents); statement = (ExpressionStatement)statements.get(sCount++); methodInvocation = (MethodInvocation)statement.getExpression(); lambdaExpression = (LambdaExpression) methodInvocation.arguments().get(0); SingleVariableDeclaration singleVarDecl = (SingleVariableDeclaration)lambdaExpression.parameters().get(0); checkSourceRange(singleVarDecl, "String s", contents); statement = (ExpressionStatement)statements.get(sCount++); methodInvocation = (MethodInvocation)statement.getExpression(); lambdaExpression = (LambdaExpression) methodInvocation.arguments().get(0); fragment = (VariableDeclarationFragment)lambdaExpression.parameters().get(0); checkSourceRange(fragment, "x", contents); fragment = (VariableDeclarationFragment)lambdaExpression.parameters().get(1); checkSourceRange(fragment, "y", contents); statement = (ExpressionStatement)statements.get(sCount++); methodInvocation = (MethodInvocation)statement.getExpression(); lambdaExpression = (LambdaExpression) methodInvocation.arguments().get(0); singleVarDecl = (SingleVariableDeclaration)lambdaExpression.parameters().get(0); checkSourceRange(singleVarDecl, "int x", contents); singleVarDecl = (SingleVariableDeclaration)lambdaExpression.parameters().get(1); checkSourceRange(singleVarDecl, "int y", contents); } public void testBug403132() throws JavaModelException { String contents = "import java.lang.annotation.*;\n" + "public class X {\n" + " class Y {\n" + " class Z {\n" + " public Z(@A X.@B Y Y.this,String str){\n}" + " public void foo(@A X.@B Y.@C Z this,String str){\n}\n" + " }\n" + " }\n" + "}\n" + "@Target(ElementType.TYPE_USE)\n" + "@interface A {}\n" + "@Target(ElementType.TYPE_USE)\n" + "@interface B {}\n" + "@Target(ElementType.TYPE_USE)\n" + "@interface C {}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; node = getASTNode(unit, 0, 0); TypeDeclaration type = (TypeDeclaration)node; node = (ASTNode) type.bodyDeclarations().get(0); type = (TypeDeclaration) node; node = (ASTNode) type.bodyDeclarations().get(0); assertEquals("Not a method Declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); MethodDeclaration method = (MethodDeclaration) node; Type receiver = method.getReceiverType(); assertEquals("Not a qualified type", ASTNode.QUALIFIED_TYPE, receiver.getNodeType()); assertEquals("Incorrect receiver", "@A X.@B Y", ((QualifiedType) receiver).toString()); assertEquals("Incorrect method signature", "public Z(@A X.@B Y Y.this,String str){\n}\n", method.toString()); method = (MethodDeclaration) type.bodyDeclarations().get(1); receiver = method.getReceiverType(); assertEquals("Incorrect receiver", "@A X.@B Y.@C Z", ((QualifiedType) receiver).toString()); assertEquals("Incorrect method signature", "public void foo(@A X.@B Y.@C Z this,String str){\n}\n", method.toString()); } public void testParameterizedReceiverType() throws JavaModelException { String contents = "import java.lang.annotation.*;\n" + "public class X<T extends Exception> {\n" + " class Y<K, V> {\n" + " class Z {\n" + " public Z(@A X<T>.@B Y<K, V> Y.this, boolean a){ }\n" + " public void foo(@B Y<K, V>.@C Z this, boolean a){ }\n" + " public Z(X<T>.@B Y<K, V> Y.this){ }\n" + " public void foo(Y<K, V>.@C Z this){ }\n" + " }\n" + " }\n" + "}\n" + "@Target(ElementType.TYPE_USE)\n" + "@interface A {}\n" + "@Target(ElementType.TYPE_USE)\n" + "@interface B {}\n" + "@Target(ElementType.TYPE_USE)\n" + "@interface C {}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; node = getASTNode(unit, 0, 0); TypeDeclaration type = (TypeDeclaration)node; node = (ASTNode) type.bodyDeclarations().get(0); type = (TypeDeclaration) node; MethodDeclaration method = (MethodDeclaration) type.bodyDeclarations().get(0); Type receiver = method.getReceiverType(); assertEquals("Not a ParameterizedType", ASTNode.PARAMETERIZED_TYPE, receiver.getNodeType()); checkSourceRange(receiver, "@A X<T>.@B Y<K, V>", contents); assertEquals("Incorrect method signature", "public Z(@A X<T>.@B Y<K,V> Y.this,boolean a){\n}\n", method.toString()); method = (MethodDeclaration) type.bodyDeclarations().get(1); receiver = method.getReceiverType(); assertEquals("Not a QualifiedType", ASTNode.QUALIFIED_TYPE, receiver.getNodeType()); checkSourceRange(receiver, "@B Y<K, V>.@C Z", contents); assertEquals("Incorrect method signature", "public void foo(@B Y<K,V>.@C Z this,boolean a){\n}\n", method.toString()); method = (MethodDeclaration) type.bodyDeclarations().get(2); receiver = method.getReceiverType(); assertEquals("Not a ParameterizedType", ASTNode.PARAMETERIZED_TYPE, receiver.getNodeType()); checkSourceRange(receiver, "X<T>.@B Y<K, V>", contents); assertEquals("Incorrect method signature", "public Z(X<T>.@B Y<K,V> Y.this){\n}\n", method.toString()); method = (MethodDeclaration) type.bodyDeclarations().get(3); receiver = method.getReceiverType(); assertEquals("Not a QualifiedType", ASTNode.QUALIFIED_TYPE, receiver.getNodeType()); checkSourceRange(receiver, "Y<K, V>.@C Z", contents); assertEquals("Incorrect method signature", "public void foo(Y<K,V>.@C Z this){\n}\n", method.toString()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=403410 public void testBug403410() throws JavaModelException { String contents = "import java.lang.annotation.*;\n" + "public class X {\n" + " class Y {\n" + " class Z {\n" + " public Z(final Y Y.this){\n}" + " public void foo(static @A Z this){\n}\n" + " }\n" + " }\n" + "}\n" + "@Target(ElementType.TYPE_USE)\n" + "@interface A {}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", false); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; node = getASTNode(unit, 0, 0); TypeDeclaration type = (TypeDeclaration)node; node = (ASTNode) type.bodyDeclarations().get(0); type = (TypeDeclaration) node; node = (ASTNode) type.bodyDeclarations().get(0); assertEquals("Not a method Declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); MethodDeclaration method = (MethodDeclaration) node; assertEquals("Type should be malformed", ASTNode.MALFORMED, (method.getFlags() & ASTNode.MALFORMED)); method = (MethodDeclaration) type.bodyDeclarations().get(1); assertEquals("Type should be malformed", ASTNode.MALFORMED, (method.getFlags() & ASTNode.MALFORMED)); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=402674 * * @throws JavaModelException */ public void test402674() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test402674/X.java", true/* resolve */); String contents = "package test402674;" + "public class X {\n" + " public static interface StringToInt {\n" + " int stoi(String s);\n" + " }\n" + " public static interface ReduceInt {\n" + " int reduce(int a, int b);\n" + " }\n" + " void foo(StringToInt s) { }\n" + " void bar(ReduceInt r) { }\n" + " void bar() {\n" + " foo(s -> s.length());\n" + " foo((s) -> s.length());\n" + " foo((String s) -> s.length()); //SingleVariableDeclaration is OK\n" + " bar((x, y) -> x+y);\n" + " bar((int x, int y) -> x+y); //SingleVariableDeclarations are OK\n" + " }\n" + "}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 0); MethodDeclaration methoddecl = (MethodDeclaration)typedeclaration.bodyDeclarations().get(4); List statements = methoddecl.getBody().statements(); int sCount = 0; ExpressionStatement statement = (ExpressionStatement)statements.get(sCount++); MethodInvocation methodInvocation = (MethodInvocation)statement.getExpression(); LambdaExpression lambdaExpression = (LambdaExpression) methodInvocation.arguments().get(0); ITypeBinding binding = lambdaExpression.resolveTypeBinding(); assertNotNull(binding); assertEquals("StringToInt", binding.getName()); statement = (ExpressionStatement)statements.get(sCount++); methodInvocation = (MethodInvocation)statement.getExpression(); lambdaExpression = (LambdaExpression) methodInvocation.arguments().get(0); binding = lambdaExpression.resolveTypeBinding(); assertNotNull(binding); assertEquals("StringToInt", binding.getName()); statement = (ExpressionStatement)statements.get(sCount++); methodInvocation = (MethodInvocation)statement.getExpression(); lambdaExpression = (LambdaExpression) methodInvocation.arguments().get(0); binding = lambdaExpression.resolveTypeBinding(); assertNotNull(binding); assertEquals("StringToInt", binding.getName()); statement = (ExpressionStatement)statements.get(sCount++); methodInvocation = (MethodInvocation)statement.getExpression(); lambdaExpression = (LambdaExpression) methodInvocation.arguments().get(0); binding = lambdaExpression.resolveTypeBinding(); assertNotNull(binding); assertEquals("ReduceInt", binding.getName()); statement = (ExpressionStatement)statements.get(sCount++); methodInvocation = (MethodInvocation)statement.getExpression(); lambdaExpression = (LambdaExpression) methodInvocation.arguments().get(0); binding = lambdaExpression.resolveTypeBinding(); assertNotNull(binding); assertEquals("ReduceInt", binding.getName()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=399791 public void testBug399791() throws JavaModelException { String contents = "public interface X {\n" + " static void foo(){}\n" + " public default void foo(int i){}\n" + " native void foo(float f){}\n" + " abstract void foo(long l){}\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", false); ASTNode node = buildAST(contents, this.workingCopy, false); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; TypeDeclaration type = (TypeDeclaration) unit.types().get(0); node = (ASTNode) type.bodyDeclarations().get(0); assertEquals("Not a method Declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); MethodDeclaration method = (MethodDeclaration) node; assertEquals("Method should not be malformed", 0, (method.getFlags() & ASTNode.MALFORMED)); List modifiers = method.modifiers(); assertEquals("Incorrect no of modfiers", 1, modifiers.size()); Modifier modifier = (Modifier) modifiers.get(0); assertSame("Incorrect modifier keyword", Modifier.ModifierKeyword.STATIC_KEYWORD, modifier.getKeyword()); method = (MethodDeclaration) type.bodyDeclarations().get(1); assertEquals("Method should not be malformed", 0, (method.getFlags() & ASTNode.MALFORMED)); modifiers = method.modifiers(); assertEquals("Incorrect no of modfiers", 2, modifiers.size()); modifier = (Modifier) modifiers.get(1); assertSame("Incorrect modifier keyword", Modifier.ModifierKeyword.DEFAULT_KEYWORD, modifier.getKeyword()); assertTrue("Incorrect modifier", modifier.isDefault()); assertEquals("Incorrect AST", "public default void foo(int i){\n}\n", method.toString()); method = (MethodDeclaration) type.bodyDeclarations().get(2); assertEquals("Method should be malformed", ASTNode.MALFORMED, (method.getFlags() & ASTNode.MALFORMED)); method = (MethodDeclaration) type.bodyDeclarations().get(3); assertEquals("Method should be malformed", ASTNode.MALFORMED, (method.getFlags() & ASTNode.MALFORMED)); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=404489 public void testBug404489a() throws JavaModelException { String contents = "package test404489.bug;\n" + "public class X { \n" + " class Y { \n" + " class Z {\n" + " public Z(@A X.@B Y Y.this){}\n" + " }\n" + " }\n" + " Object o=(@A X.@B Y.@Marker Z)null;\n" + " }\n" + "@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_USE) @interface Marker {} \n" + "@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_USE) @interface A {} \n" + "@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_USE) @interface B {} \n"; this.workingCopy = getWorkingCopy("/Converter18/src/test404489/bug/X.java", true/* resolve */); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; TypeDeclaration type = (TypeDeclaration) unit.types().get(0); node = (ASTNode) type.bodyDeclarations().get(0); assertEquals("Not a Type Declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); node = (ASTNode) ((TypeDeclaration)node).bodyDeclarations().get(0); assertEquals("Not a Type Declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); node = (ASTNode) ((TypeDeclaration)node).bodyDeclarations().get(0); assertEquals("Not a method Declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); MethodDeclaration method = (MethodDeclaration) node; assertEquals("Method should not be malformed", 0, (method.getFlags() & ASTNode.MALFORMED)); Type annotatableType = method.getReceiverType(); assertTrue(annotatableType.isQualifiedType()); QualifiedType qualifiedType = (QualifiedType) annotatableType; assertEquals("wrong qualified type", "@A X.@B Y", qualifiedType.toString()); ITypeBinding binding = qualifiedType.resolveBinding(); assertNotNull("No binding", binding); assertEquals("Wrong qualified name", "test404489.bug.X.Y", binding.getQualifiedName()); SimpleType simpleType = (SimpleType) qualifiedType.getQualifier(); assertEquals("incorrect type", "@A X", simpleType.toString()); binding = simpleType.resolveBinding(); assertNotNull("No binding", binding); assertEquals("Wrong qualified name", "test404489.bug.X", binding.getQualifiedName()); List annotations = qualifiedType.annotations(); assertTrue(annotations.size() == 1); MarkerAnnotation marker = (MarkerAnnotation) annotations.get(0); assertEquals("wrong annotation name", "@B", marker.toString()); binding = marker.resolveTypeBinding(); assertNotNull("No binding", binding); assertEquals("Wrong qualified name", "test404489.bug.B", binding.getQualifiedName()); IAnnotationBinding annotationBinding = marker.resolveAnnotationBinding(); assertNotNull(annotationBinding); assertEquals("wrong annotation binding", "B", annotationBinding.getName()); Name name = marker.getTypeName(); assertTrue(name.isSimpleName()); SimpleName simpleName = (SimpleName) name; assertEquals("wrong type name", "B", simpleName.toString()); assertEquals("wrong simple name", "B",simpleName.getIdentifier()); binding = simpleName.resolveTypeBinding(); assertNotNull("No binding", binding); assertEquals("Wrong qualified name", "test404489.bug.B", binding.getQualifiedName()); assertTrue(qualifiedType.getQualifier().isSimpleType()); simpleType = (SimpleType) qualifiedType.getQualifier(); assertEquals("incorrect type", "@A X", simpleType.toString()); binding = simpleType.resolveBinding(); assertNotNull("No binding", binding); assertEquals("Wrong qualified name", "test404489.bug.X", binding.getQualifiedName()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=404489 public void testBug404489b() throws JavaModelException { ICompilationUnit sourceUnit = getCompilationUnit("Converter18" , "src", "test404489.bug", "X.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ ASTNode result = runConversion(this.ast.apiLevel(), sourceUnit, true); char[] source = sourceUnit.getSource().toCharArray(); assertTrue("Not a compilation unit", result.getNodeType() == ASTNode.COMPILATION_UNIT); CompilationUnit compilationUnit = (CompilationUnit) result; assertProblemsSize(compilationUnit, 0); ASTNode node = getASTNode(compilationUnit, 0, 0, 0); TypeDeclaration typeDeclaration = (TypeDeclaration) compilationUnit.types().get(0); node = (ASTNode) typeDeclaration.bodyDeclarations().get(2); assertEquals("Not a method declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); MethodDeclaration methodDecl = (MethodDeclaration) node; Type type = methodDecl.getReturnType2(); assertTrue(type.isNameQualifiedType()); NameQualifiedType nameQualifiedType = (NameQualifiedType) type; checkSourceRange(nameQualifiedType, "test404489.bug.@NonNull IOException", source); ITypeBinding typeBinding = nameQualifiedType.resolveBinding(); assertNotNull("null binding", typeBinding); assertEquals("not a valid binding", "test404489.bug.IOException", typeBinding.getQualifiedName()); // qualifier of the name qualified type Name name = nameQualifiedType.getQualifier(); assertTrue(name.isQualifiedName()); QualifiedName qualifiedName = (QualifiedName) name; checkSourceRange(qualifiedName, "test404489.bug", source); typeBinding = qualifiedName.resolveTypeBinding(); assertNull(typeBinding); IBinding binding = qualifiedName.resolveBinding(); assertTrue("not a package binding", binding.getKind() == IBinding.PACKAGE); assertEquals("wrong package binding", "package test404489.bug", binding.toString()); name = qualifiedName.getQualifier(); assertTrue("wrong name type", name.isSimpleName()); SimpleName simpleName = (SimpleName) name; checkSourceRange(simpleName, "test404489", source); typeBinding = simpleName.resolveTypeBinding(); assertNull(typeBinding); binding = simpleName.resolveBinding(); assertTrue("not a package binding", binding.getKind() == IBinding.PACKAGE); assertEquals("wrong package binding", "package test404489", binding.toString()); simpleName = qualifiedName.getName(); checkSourceRange(simpleName, "bug", source); typeBinding = simpleName.resolveTypeBinding(); assertNull(typeBinding); binding = simpleName.resolveBinding(); assertTrue("not a package binding", binding.getKind() == IBinding.PACKAGE); assertEquals("wrong package binding", "package test404489.bug", binding.toString()); // annotations of name qualified type List annotations = nameQualifiedType.annotations(); assertTrue(annotations.size() == 1); Annotation annotation = (Annotation) annotations.get(0); typeBinding = annotation.resolveTypeBinding(); assertNotNull("null binding", typeBinding); assertEquals("not a valid binding", "test404489.bug.X.NonNull", typeBinding.getQualifiedName()); IAnnotationBinding annotationBinding = annotation.resolveAnnotationBinding(); assertEquals("not a valid annotation binding", "@NonNull()", annotationBinding.toString()); name = annotation.getTypeName(); assertTrue(name.isSimpleName()); simpleName = (SimpleName) name; typeBinding = simpleName.resolveTypeBinding(); checkSourceRange(simpleName, "NonNull", source); assertNotNull(typeBinding); // name of the name qualified type simpleName = nameQualifiedType.getName(); checkSourceRange(simpleName, "IOException", source); typeBinding = simpleName.resolveTypeBinding(); assertNotNull(typeBinding); // parameter SingleVariableDeclaration param = (SingleVariableDeclaration) methodDecl.parameters().get(0); type = param.getType(); assertTrue(type.isNameQualifiedType()); nameQualifiedType = (NameQualifiedType) type; checkSourceRange(nameQualifiedType, "test404489.bug.@NonNull FileNotFoundException", source); typeBinding = nameQualifiedType.resolveBinding(); assertNotNull("null binding", typeBinding); assertEquals("not a valid binding", "test404489.bug.FileNotFoundException", typeBinding.getQualifiedName()); // qualifier of the name qualified type name = nameQualifiedType.getQualifier(); assertTrue(name.isQualifiedName()); qualifiedName = (QualifiedName) name; checkSourceRange(qualifiedName, "test404489.bug", source); typeBinding = qualifiedName.resolveTypeBinding(); assertNull(typeBinding); binding = qualifiedName.resolveBinding(); assertTrue("not a package binding", binding.getKind() == IBinding.PACKAGE); assertEquals("wrong package binding", "package test404489.bug", binding.toString()); name = qualifiedName.getQualifier(); assertTrue("wrong name type", name.isSimpleName()); simpleName = (SimpleName) name; checkSourceRange(simpleName, "test404489", source); typeBinding = simpleName.resolveTypeBinding(); assertNull(typeBinding); binding = simpleName.resolveBinding(); assertTrue("not a package binding", binding.getKind() == IBinding.PACKAGE); assertEquals("wrong package binding", "package test404489", binding.toString()); simpleName = qualifiedName.getName(); checkSourceRange(simpleName, "bug", source); typeBinding = simpleName.resolveTypeBinding(); assertNull(typeBinding); binding = simpleName.resolveBinding(); assertTrue("not a package binding", binding.getKind() == IBinding.PACKAGE); assertEquals("wrong package binding", "package test404489.bug", binding.toString()); // annotations of name qualified type annotations = nameQualifiedType.annotations(); assertTrue(annotations.size() == 1); annotation = (Annotation) annotations.get(0); typeBinding = annotation.resolveTypeBinding(); assertNotNull("null binding", typeBinding); assertEquals("not a valid binding", "test404489.bug.X.NonNull", typeBinding.getQualifiedName()); annotationBinding = annotation.resolveAnnotationBinding(); assertEquals("not a valid annotation binding", "@NonNull()", annotationBinding.toString()); name = annotation.getTypeName(); assertTrue(name.isSimpleName()); simpleName = (SimpleName) name; typeBinding = simpleName.resolveTypeBinding(); checkSourceRange(simpleName, "NonNull", source); assertNotNull(typeBinding); // name of the name qualified type simpleName = nameQualifiedType.getName(); checkSourceRange(simpleName, "FileNotFoundException", source); typeBinding = simpleName.resolveTypeBinding(); assertNotNull(typeBinding); // throws type = (Type) methodDecl.thrownExceptionTypes().get(0); assertTrue(type.isNameQualifiedType()); nameQualifiedType = (NameQualifiedType) type; checkSourceRange(nameQualifiedType, "test404489.bug.@NonNull EOFException", source); typeBinding = nameQualifiedType.resolveBinding(); assertNotNull("null binding", typeBinding); assertEquals("not a valid binding", "test404489.bug.EOFException", typeBinding.getQualifiedName()); // qualifier of the name qualified type name = nameQualifiedType.getQualifier(); assertTrue(name.isQualifiedName()); qualifiedName = (QualifiedName) name; checkSourceRange(qualifiedName, "test404489.bug", source); typeBinding = qualifiedName.resolveTypeBinding(); assertNull(typeBinding); binding = qualifiedName.resolveBinding(); assertTrue("not a package binding", binding.getKind() == IBinding.PACKAGE); assertEquals("wrong package binding", "package test404489.bug", binding.toString()); name = qualifiedName.getQualifier(); assertTrue("wrong name type", name.isSimpleName()); simpleName = (SimpleName) name; checkSourceRange(simpleName, "test404489", source); typeBinding = simpleName.resolveTypeBinding(); assertNull(typeBinding); binding = simpleName.resolveBinding(); assertTrue("not a package binding", binding.getKind() == IBinding.PACKAGE); assertEquals("wrong package binding", "package test404489", binding.toString()); simpleName = qualifiedName.getName(); checkSourceRange(simpleName, "bug", source); typeBinding = simpleName.resolveTypeBinding(); assertNull(typeBinding); binding = simpleName.resolveBinding(); assertTrue("not a package binding", binding.getKind() == IBinding.PACKAGE); assertEquals("wrong package binding", "package test404489.bug", binding.toString()); // annotations of name qualified type annotations = nameQualifiedType.annotations(); assertTrue(annotations.size() == 1); annotation = (Annotation) annotations.get(0); typeBinding = annotation.resolveTypeBinding(); assertNotNull("null binding", typeBinding); assertEquals("not a valid binding", "test404489.bug.X.NonNull", typeBinding.getQualifiedName()); annotationBinding = annotation.resolveAnnotationBinding(); assertEquals("not a valid annotation binding", "@NonNull()", annotationBinding.toString()); name = annotation.getTypeName(); assertTrue(name.isSimpleName()); simpleName = (SimpleName) name; typeBinding = simpleName.resolveTypeBinding(); checkSourceRange(simpleName, "NonNull", source); assertNotNull(typeBinding); // name of the name qualified type simpleName = nameQualifiedType.getName(); checkSourceRange(simpleName, "EOFException", source); typeBinding = simpleName.resolveTypeBinding(); assertNotNull(typeBinding); node = (ASTNode) typeDeclaration.bodyDeclarations().get(3); assertEquals("Not a field declaration", ASTNode.FIELD_DECLARATION, node.getNodeType()); FieldDeclaration field = (FieldDeclaration) node; type = field.getType(); assertTrue(type.isQualifiedType()); QualifiedType qualifiedType = (QualifiedType) type; nameQualifiedType = (NameQualifiedType)qualifiedType.getQualifier(); checkSourceRange(nameQualifiedType, "test404489.bug.@NonNull X", source); typeBinding = nameQualifiedType.resolveBinding(); assertNotNull("null binding", typeBinding); assertEquals("not a valid binding", "test404489.bug.X", typeBinding.getQualifiedName()); name = nameQualifiedType.getName(); assertSame("bindings different for name qualified type and assocated name", typeBinding, name.resolveTypeBinding()); // qualifier of the name qualified type name = nameQualifiedType.getQualifier(); assertTrue(name.isQualifiedName()); qualifiedName = (QualifiedName) name; checkSourceRange(qualifiedName, "test404489.bug", source); typeBinding = qualifiedName.resolveTypeBinding(); assertNull(typeBinding); binding = qualifiedName.resolveBinding(); assertTrue("not a package binding", binding.getKind() == IBinding.PACKAGE); assertEquals("wrong package binding", "package test404489.bug", binding.toString()); name = qualifiedName.getQualifier(); assertTrue("wrong name type", name.isSimpleName()); simpleName = (SimpleName) name; checkSourceRange(simpleName, "test404489", source); typeBinding = simpleName.resolveTypeBinding(); assertNull(typeBinding); binding = simpleName.resolveBinding(); assertTrue("not a package binding", binding.getKind() == IBinding.PACKAGE); assertEquals("wrong package binding", "package test404489", binding.toString()); simpleName = qualifiedName.getName(); checkSourceRange(simpleName, "bug", source); typeBinding = simpleName.resolveTypeBinding(); assertNull(typeBinding); binding = simpleName.resolveBinding(); assertTrue("not a package binding", binding.getKind() == IBinding.PACKAGE); assertEquals("wrong package binding", "package test404489.bug", binding.toString()); // annotations of name qualified type annotations = nameQualifiedType.annotations(); assertTrue(annotations.size() == 1); annotation = (Annotation) annotations.get(0); typeBinding = annotation.resolveTypeBinding(); assertNotNull("null binding", typeBinding); assertEquals("not a valid binding", "test404489.bug.X.NonNull", typeBinding.getQualifiedName()); annotationBinding = annotation.resolveAnnotationBinding(); assertEquals("not a valid annotation binding", "@NonNull()", annotationBinding.toString()); name = annotation.getTypeName(); assertTrue(name.isSimpleName()); simpleName = (SimpleName) name; typeBinding = simpleName.resolveTypeBinding(); checkSourceRange(simpleName, "NonNull", source); assertNotNull(typeBinding); // name of the name qualified type simpleName = nameQualifiedType.getName(); checkSourceRange(simpleName, "X", source); typeBinding = simpleName.resolveTypeBinding(); assertNotNull(typeBinding); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=399792 public void testBug399792() throws JavaModelException { String content = "import java.lang.annotation.ElementType;\n" + "import java.io.Serializable;\n" + "public class X {\n" + " Object o = (@Marker1 @Marker2 Serializable & I & @Marker3 @Marker1 J) () -> {};" + " public Serializable main(Object o) {\n" + " Serializable oo = (Serializable & @Marker3 @Marker1 @Marker2 I & J) o;\n" + " return oo;\n" + " }\n" + "}\n" + "interface I {\n" + " public void foo();\n" + "}\n" + "interface J {\n" + " public void foo();\n" + " public void bar();\n" + "}\n" + "interface K {\n" + " public void foo();\n" + " public void bar();\n" + "}\n" + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + "@interface Marker {}\n" + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + "@interface Marker2 {}\n" + "@java.lang.annotation.Target (ElementType.TYPE_USE)\n" + "@interface Marker3 {}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", false); ASTNode node = buildAST(content, this.workingCopy, false); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; TypeDeclaration type = (TypeDeclaration) unit.types().get(0); node = (ASTNode) type.bodyDeclarations().get(0); assertEquals("Not a field Declaration", ASTNode.FIELD_DECLARATION, node.getNodeType()); FieldDeclaration field = (FieldDeclaration) node; assertEquals("Field should not be malformed", 0, (field.getFlags() & ASTNode.MALFORMED)); List fragments = field.fragments(); assertEquals("Incorrect no of fragments", 1, fragments.size()); VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(0); CastExpression cast = (CastExpression) fragment.getInitializer(); Type castType = cast.getType(); assertEquals("Not an intersection cast type", ASTNode.INTERSECTION_TYPE, castType.getNodeType()); assertTrue("Not an intersection cast type", castType.isIntersectionType()); assertEquals("Type should not be malformed", 0, (castType.getFlags() & ASTNode.MALFORMED)); List intersectionTypes = ((IntersectionType) castType).types(); assertEquals("Incorrect no of types", 3, intersectionTypes.size()); castType = (Type) intersectionTypes.get(0); assertEquals("Incorrect type", ASTNode.SIMPLE_TYPE, castType.getNodeType()); SimpleName name = (SimpleName) ((SimpleType) castType).getName(); assertEquals("Incorrect name", "Serializable", name.getIdentifier()); List annotations = ((SimpleType) castType).annotations(); assertEquals("Incorrect no of annotations", 2, annotations.size()); assertEquals("Incorrect receiver", "@Marker1 @Marker2 Serializable", castType.toString()); castType = (Type) intersectionTypes.get(1); assertEquals("Incorrect type", ASTNode.SIMPLE_TYPE, castType.getNodeType()); name = (SimpleName) ((SimpleType) castType).getName(); assertEquals("Incorrect name", "I", name.getIdentifier()); annotations = ((SimpleType) castType).annotations(); assertEquals("Incorrect no of annotations", 0, annotations.size()); assertEquals("Incorrect receiver", "I", castType.toString()); castType = (Type) intersectionTypes.get(2); assertEquals("Incorrect type", ASTNode.SIMPLE_TYPE, castType.getNodeType()); name = (SimpleName) ((SimpleType) castType).getName(); assertEquals("Incorrect name", "J", name.getIdentifier()); annotations = ((SimpleType) castType).annotations(); assertEquals("Incorrect no of annotations", 2, annotations.size()); assertEquals("Incorrect receiver", "@Marker3 @Marker1 J", castType.toString()); node = (ASTNode) type.bodyDeclarations().get(1); assertEquals("Not a method Declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); MethodDeclaration method = (MethodDeclaration) node; assertEquals("Method should not be malformed", 0, (method.getFlags() & ASTNode.MALFORMED)); List statements = method.getBody().statements(); VariableDeclarationStatement statement = (VariableDeclarationStatement) statements.get(0); fragment = (VariableDeclarationFragment) statement.fragments().get(0); cast = (CastExpression) fragment.getInitializer(); castType = cast.getType(); intersectionTypes = ((IntersectionType) castType).types(); assertEquals("Incorrect no of types", 3, intersectionTypes.size()); castType = (Type) intersectionTypes.get(0); annotations = ((SimpleType) castType).annotations(); assertEquals("Incorrect no of annotations", 0, annotations.size()); assertEquals("Incorrect receiver", "Serializable", castType.toString()); castType = (Type) intersectionTypes.get(1); annotations = ((SimpleType) castType).annotations(); assertEquals("Incorrect no of annotations", 3, annotations.size()); assertEquals("Incorrect receiver", "@Marker3 @Marker1 @Marker2 I", castType.toString()); castType = (Type) intersectionTypes.get(2); annotations = ((SimpleType) castType).annotations(); assertEquals("Incorrect no of annotations", 0, annotations.size()); assertEquals("Incorrect receiver", "J", castType.toString()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=406505 * tests the source range issue that resulted in bad ast node. * * @throws JavaModelException */ public void testBug406505() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test406505/X.java", true/* resolve */); String contents = "package test406505;" + "import java.lang.annotation.Target;\n" + "import java.io.File;\n" + "public class X {\n" + " class Folder<@Marker F extends File> { }\n" + "}\n" + "@Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker {}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 0); typedeclaration = (TypeDeclaration)typedeclaration.bodyDeclarations().get(0); TypeParameter typeParameter = (TypeParameter) typedeclaration.typeParameters().get(0); checkSourceRange(typeParameter, "@Marker F extends File", contents); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=412726 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428526 public void testBug412726() throws JavaModelException { String contents = "public interface X {\n" + " abstract void foo();\n" + "}\n" + "interface Y1 {\n" + "}\n" + "interface Y2 {\n" + " default void foo() {}\n" + "}\n" + "interface Z1 {\n" + " default void foo(){}\n" + " abstract void bar();\n" + "}\n" + "interface Z2 {\n" + " default void foo(){}\n" + " abstract void bar1();\n" + " abstract void bar2();\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy, true); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; /* case 0: vanilla case - interface with one abstract method */ TypeDeclaration type = (TypeDeclaration) unit.types().get(0); ITypeBinding typeBinding = type.resolveBinding(); assertEquals("Incorrect method", typeBinding.getDeclaredMethods()[0], typeBinding.getFunctionalInterfaceMethod()); /* case 1: interface without any method */ type = (TypeDeclaration) unit.types().get(1); typeBinding = type.resolveBinding(); assertNull(typeBinding.getFunctionalInterfaceMethod()); /* case 2: interface with just one default method and without any abstract method */ type = (TypeDeclaration) unit.types().get(2); typeBinding = type.resolveBinding(); assertNull(typeBinding.getFunctionalInterfaceMethod()); /* case 3: interface with just one default method and one abstract method */ type = (TypeDeclaration) unit.types().get(3); typeBinding = type.resolveBinding(); IMethodBinding functionalInterfaceMethod = typeBinding.getFunctionalInterfaceMethod(); assertNotNull(functionalInterfaceMethod); assertEquals("Incorrect method", "public abstract void bar() ", functionalInterfaceMethod.toString()); assertEquals(typeBinding, functionalInterfaceMethod.getDeclaringClass()); /* case 4: interface with just one default method and two abstract methods */ type = (TypeDeclaration) unit.types().get(4); typeBinding = type.resolveBinding(); assertNull(typeBinding.getFunctionalInterfaceMethod()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=417017 * * @throws JavaModelException */ public void test417017a() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test417017/X.java", true/* resolve */); String contents = "package test417017;" + "interface I {\n" + " int foo(int x);\n" + "}\n" + "public class X {\n" + " void fun(int a) {\n" +" I i1 = x1-> x1;\n" +" I i2 = xxx-> {\n" +" i1.foo(a);\n" +" return xxx;\n" +" };\n" +" }\n" +"}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 1); MethodDeclaration methodDeclaration = typedeclaration.getMethods()[0]; VariableDeclarationFragment vdf= (VariableDeclarationFragment) ((VariableDeclarationStatement) methodDeclaration.getBody().statements().get(1)).fragments().get(0); LambdaExpression lambda= (LambdaExpression) vdf.getInitializer(); List parameters = lambda.parameters(); assertTrue("Incorrect Number of parameters", parameters.size() == 1); ITypeBinding[] parameterTypes= lambda.resolveMethodBinding().getParameterTypes(); assertTrue("Incorrect Number of parameter type", parameterTypes.length == 1); assertEquals("Incorrect parameter type", "int", parameterTypes[0].toString()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=417017 * * @throws JavaModelException */ public void test417017b() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test417017/X.java", true/* resolve */); String contents = "package test417017;" + "interface I1 {\n" + " int foo(int a);\n" + "}\n" + "\n" + "interface I2 {\n" + " public default int foo() {\n" + " I1 i1 = (a) -> {\n" + " return a;\n" + " };\n" + " //return 0;\n" + // Error on purpose " }\n" + "}\n" ; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy, false); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 1); MethodDeclaration methodDeclaration = typedeclaration.getMethods()[0]; VariableDeclarationFragment vdf= (VariableDeclarationFragment) ((VariableDeclarationStatement) methodDeclaration.getBody().statements().get(0)).fragments().get(0); LambdaExpression lambda= (LambdaExpression) vdf.getInitializer(); List parameters = lambda.parameters(); assertTrue("Incorrect Number of parameters", parameters.size() == 1); ITypeBinding[] parameterTypes= lambda.resolveMethodBinding().getParameterTypes(); assertTrue("Incorrect Number of parameter type", parameterTypes.length == 1); assertEquals("Incorrect parameter type", "int", parameterTypes[0].toString()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=417017 * * @throws JavaModelException */ public void test417017c() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test417017/X.java", true/* resolve */); String contents = "package test417017;" + "interface I1 {\n" + " int foo(int a);\n" + "}\n" + "\n" + "interface I2 {\n" + " public default int foo() {\n" + " I1 i1 = (float a) -> {\n" + " return a;\n" + " };\n" + " //return 0;\n" + // Error on purpose " }\n" + "}\n" ; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy, false); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 1); MethodDeclaration methodDeclaration = typedeclaration.getMethods()[0]; VariableDeclarationFragment vdf= (VariableDeclarationFragment) ((VariableDeclarationStatement) methodDeclaration.getBody().statements().get(0)).fragments().get(0); LambdaExpression lambda= (LambdaExpression) vdf.getInitializer(); List parameters = lambda.parameters(); assertTrue("Incorrect Number of parameters", parameters.size() == 1); ITypeBinding[] parameterTypes= lambda.resolveMethodBinding().getParameterTypes(); assertTrue("Incorrect Number of parameter type", parameterTypes.length == 1); assertEquals("Incorrect parameter type", "float", parameterTypes[0].toString()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=417017 * * @throws JavaModelException */ public void test417017d() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test399794/X.java", true/* resolve */); String contents = "package test399794;" + "interface I {\n" + " void foo(X x);\n" + "}\n" + "public class X {\n" + " void foo(X x) {\n" + " }\n" + " I i = this::foo;\n" + "}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typeDeclaration = (TypeDeclaration) getASTNode(cu, 1); FieldDeclaration field = typeDeclaration.getFields()[0]; VariableDeclarationFragment fragment = (VariableDeclarationFragment) field.fragments().get(0); Expression expression = fragment.getInitializer(); ExpressionMethodReference methodReference = (ExpressionMethodReference) expression; IMethodBinding methodBinding = methodReference.resolveMethodBinding(); assertNotNull(methodBinding); ITypeBinding [] parameterTypes = methodBinding.getParameterTypes(); assertTrue("Incorrect Number of parameter type", parameterTypes.length == 1); assertEquals("Incorrect parameter type", "X", parameterTypes[0].getName()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=417017 * * @throws JavaModelException */ public void test417017e() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test399794/X.java", true/* resolve */); String contents = "package test399794;" + "interface I {\n" + " int [] foo(int x);\n" + "}\n" + "public class X {\n" + " I i = int []::new;\n" + "}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typeDeclaration = (TypeDeclaration) getASTNode(cu, 1); FieldDeclaration field = typeDeclaration.getFields()[0]; VariableDeclarationFragment fragment = (VariableDeclarationFragment) field.fragments().get(0); Expression expression = fragment.getInitializer(); CreationReference creationReference = (CreationReference) expression; IMethodBinding methodBinding = creationReference.resolveMethodBinding(); assertNull(methodBinding); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=417017 * * @throws JavaModelException */ public void test417017f() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test399794/X.java", true/* resolve */); String contents = "package test399794;" + "interface I {\n" + " void foo(X x);\n" + "}\n" + "public class X {\n" + " private void foo(X x) {\n" + " }\n" + " class Y {\n" + " I i = X.this::foo;\n" + " }\n" + "}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typeDeclaration = (TypeDeclaration) getASTNode(cu, 1); typeDeclaration = typeDeclaration.getTypes()[0]; FieldDeclaration field = typeDeclaration.getFields()[0]; VariableDeclarationFragment fragment = (VariableDeclarationFragment) field.fragments().get(0); Expression expression = fragment.getInitializer(); ExpressionMethodReference reference = (ExpressionMethodReference) expression; IMethodBinding methodBinding = reference.resolveMethodBinding(); assertNotNull(methodBinding); assertEquals("Wrong name", "foo", methodBinding.getName()); ITypeBinding [] parameterTypes = methodBinding.getParameterTypes(); assertTrue("Incorrect Number of parameter type", parameterTypes.length == 1); assertEquals("Incorrect parameter type", "X", parameterTypes[0].getName()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=413942 // also refer https://bugs.eclipse.org/bugs/show_bug.cgi?id=413569 public void testBug413942() throws JavaModelException { String contents = "public class X extends @NonNull(int[].class) Object {\n" + " Object field = new ArrayList< @NonEmpty(0) int @NonNull(value1 = 1) [] @NonEmpty(1) [ ]>() ;\n" + " @Annot int @Annot1 [] a1 @Annot2 @Annot3 @NonNull (value = int[].class, value1 = 0)[/* [] */ ] @Annot3 @Annot2 [] @Annot4 [];\n" + " int[] xxx[];\n" + " int [][] ii = new int[2][3];" + " ArrayList<int[]> [][] yyy; // source ranges already broken in AST.JLS4\n" + " ArrayList<int[][]> [][][][] zzz;\n" + " ArrayList<Float> [][][] zzz2;\n" + " Object a = new ArrayList< @TakeType(int[][].class) int @TakeType(float.class) [] @TakeType(double.class) []>() ;\n" + " Object b = new @NonNull(value1 = Math.PI) ArrayList< >() ; \n" + " Object c = new ArrayList<@NonNull(value1= Math.PI ) Object[]>() ;\n" + "\n" + " int foo(@TakeType(int[].class)int i ) @TakeType(int[].class) [] {\n" + " int[] arr = new int[2];\n" + " for (String tab @TakeType(int[].class) [] = null;; ++i) { break; }\n" + " for (@Deprecated String tab@TakeType(int[].class) [][] = null;; ++i) {}\n" + " }\n" + " int bar(int [] /*@TakeType(int[].class)*/ [] a ) {\n" + " return 0;\n" + " }\n" + "public int var1(int @TakeType(int[].class)... args) { return 0;}\n" + "public int var2(int @Annot ... args) { return 0;}\n" + "}\n" + "\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@Documented\n" + "@interface NonNull {\n" + " Class value() default int.class;\n" + " double value1() default 0;\n" + "}\n" + "\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@Documented\n" + "@interface NonEmpty {\n" + " int value() default 0;\n" + "}\n" + "\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@Documented\n" + "@interface TakeType {\n" + " Class value() default int[].class;\n" + "}\n" + "\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@Documented\n" + "@interface Annot {}\n" + "\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@Documented\n" + "@interface Annot1 {}\n" + "\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@Documented\n" + "@interface Annot2 {}\n" + "\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@Documented\n" + "@interface Annot3 {}\n" + "\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@Documented\n" + "@interface Annot4 {}\n" + "\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy, false); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; TypeDeclaration type = (TypeDeclaration) unit.types().get(0); SimpleType simpleType = (SimpleType) type.getSuperclassType(); checkSourceRange(simpleType, "@NonNull(int[].class) Object", contents); SingleMemberAnnotation singleMemberAnnotation = (SingleMemberAnnotation) simpleType.annotations().get(0); checkSourceRange(singleMemberAnnotation, "@NonNull(int[].class)", contents); TypeLiteral typeLiteral = (TypeLiteral) singleMemberAnnotation.getValue(); checkSourceRange(typeLiteral, "int[].class", contents); ArrayType arrayType = (ArrayType) typeLiteral.getType(); checkSourceRange(arrayType, "int[]", contents); int count = 0; FieldDeclaration field = (FieldDeclaration) type.bodyDeclarations().get(count++); checkSourceRange(field, "Object field = new ArrayList< @NonEmpty(0) int @NonNull(value1 = 1) [] @NonEmpty(1) [ ]>() ;", contents); VariableDeclarationFragment fragment = (VariableDeclarationFragment) field.fragments().get(0); ClassInstanceCreation instance = (ClassInstanceCreation) fragment.getInitializer(); ParameterizedType parameterizedType = (ParameterizedType) instance.getType(); arrayType = (ArrayType) parameterizedType.typeArguments().get(0); checkSourceRange(arrayType, "@NonEmpty(0) int @NonNull(value1 = 1) [] @NonEmpty(1) [ ]", contents); PrimitiveType primitiveType = (PrimitiveType) arrayType.getElementType(); checkSourceRange(primitiveType, "@NonEmpty(0) int", contents); Dimension dimension = (Dimension) arrayType.dimensions().get(0); checkSourceRange(dimension, "@NonNull(value1 = 1) []", contents); dimension = (Dimension) arrayType.dimensions().get(1); checkSourceRange(dimension, "@NonEmpty(1) [ ]", contents); field = (FieldDeclaration) type.bodyDeclarations().get(count++); checkSourceRange(field, "@Annot int @Annot1 [] a1 @Annot2 @Annot3 @NonNull (value = int[].class, value1 = 0)[/* [] */ ] @Annot3 @Annot2 [] @Annot4 [];", contents); arrayType = (ArrayType) field.getType(); checkSourceRange(arrayType, "int @Annot1 []", contents); fragment = (VariableDeclarationFragment) field.fragments().get(0); dimension = (Dimension) fragment.extraDimensions().get(0); checkSourceRange(dimension, "@Annot2 @Annot3 @NonNull (value = int[].class, value1 = 0)[/* [] */ ]", contents); dimension = (Dimension) fragment.extraDimensions().get(1); checkSourceRange(dimension, "@Annot3 @Annot2 []", contents); field = (FieldDeclaration) type.bodyDeclarations().get(count++); checkSourceRange(field, "int[] xxx[];", contents); assertTrue(field.getType().isArrayType()); arrayType = (ArrayType) field.getType(); checkSourceRange(arrayType, "int[]", contents); field = (FieldDeclaration) type.bodyDeclarations().get(count++); checkSourceRange(field, "int [][] ii = new int[2][3];", contents); arrayType = (ArrayType) field.getType(); checkSourceRange(arrayType, "int [][]", contents); fragment = (VariableDeclarationFragment) field.fragments().get(0); ArrayCreation arrayCreation = (ArrayCreation) fragment.getInitializer(); arrayType = arrayCreation.getType(); assertTrue(arrayType.getElementType().isPrimitiveType()); assertTrue(arrayType.getDimensions() == 2); field = (FieldDeclaration) type.bodyDeclarations().get(count++); checkSourceRange(field, "ArrayList<int[]> [][] yyy;", contents); arrayType = (ArrayType) field.getType(); checkSourceRange(arrayType, "ArrayList<int[]> [][]", contents); field = (FieldDeclaration) type.bodyDeclarations().get(count++); checkSourceRange(field, "ArrayList<int[][]> [][][][] zzz;", contents); arrayType = (ArrayType) field.getType(); assertTrue(arrayType.getElementType().isParameterizedType()); assertTrue(arrayType.getDimensions() == 4); field = (FieldDeclaration) type.bodyDeclarations().get(count++); checkSourceRange(field, "ArrayList<Float> [][][] zzz2;", contents); arrayType = (ArrayType) field.getType(); assertTrue(arrayType.getElementType().isParameterizedType()); assertTrue(arrayType.getDimensions() == 3); field = (FieldDeclaration) type.bodyDeclarations().get(count++); checkSourceRange(field, "Object a = new ArrayList< @TakeType(int[][].class) int @TakeType(float.class) [] @TakeType(double.class) []>() ;", contents); fragment = (VariableDeclarationFragment) field.fragments().get(0); ClassInstanceCreation classInstanceCreation = (ClassInstanceCreation) fragment.getInitializer(); parameterizedType = (ParameterizedType) classInstanceCreation.getType(); arrayType = (ArrayType) parameterizedType.typeArguments().get(0); checkSourceRange(arrayType, "@TakeType(int[][].class) int @TakeType(float.class) [] @TakeType(double.class) []", contents); checkSourceRange(arrayType.getElementType(), "@TakeType(int[][].class) int", contents); assertTrue(arrayType.getElementType().isPrimitiveType()); dimension = (Dimension) arrayType.dimensions().get(0); checkSourceRange(dimension, "@TakeType(float.class) []", contents); dimension = (Dimension) arrayType.dimensions().get(1); Annotation annotation = (Annotation) dimension.annotations().get(0); assertTrue(annotation.isSingleMemberAnnotation()); singleMemberAnnotation = (SingleMemberAnnotation) annotation; typeLiteral = (TypeLiteral) singleMemberAnnotation.getValue(); checkSourceRange(typeLiteral, "double.class", contents); field = (FieldDeclaration) type.bodyDeclarations().get(count++); checkSourceRange(field, "Object b = new @NonNull(value1 = Math.PI) ArrayList< >() ;", contents); fragment = (VariableDeclarationFragment) field.fragments().get(0); classInstanceCreation = (ClassInstanceCreation) fragment.getInitializer(); parameterizedType = (ParameterizedType) classInstanceCreation.getType(); checkSourceRange(parameterizedType.getType(), "@NonNull(value1 = Math.PI) ArrayList", contents); field = (FieldDeclaration) type.bodyDeclarations().get(count++); checkSourceRange(field, "Object c = new ArrayList<@NonNull(value1= Math.PI ) Object[]>() ;", contents); fragment = (VariableDeclarationFragment) field.fragments().get(0); classInstanceCreation = (ClassInstanceCreation) fragment.getInitializer(); parameterizedType = (ParameterizedType) classInstanceCreation.getType(); arrayType = (ArrayType) parameterizedType.typeArguments().get(0); assertTrue(arrayType.getDimensions() == 1); MethodDeclaration method = (MethodDeclaration) type.bodyDeclarations().get(count++); dimension = (Dimension) method.extraDimensions().get(0); checkSourceRange(dimension, "@TakeType(int[].class) []", contents); singleMemberAnnotation = (SingleMemberAnnotation) dimension.annotations().get(0); typeLiteral = (TypeLiteral) singleMemberAnnotation.getValue(); arrayType = (ArrayType) typeLiteral.getType(); assertTrue(arrayType.getElementType().isPrimitiveType()); assertTrue(arrayType.getDimensions() == 1); SingleVariableDeclaration singleVariableDeclaration = (SingleVariableDeclaration) method.parameters().get(0); singleMemberAnnotation = (SingleMemberAnnotation) singleVariableDeclaration.modifiers().get(0); checkSourceRange(singleMemberAnnotation, "@TakeType(int[].class)", contents); typeLiteral = (TypeLiteral) singleMemberAnnotation.getValue(); arrayType = (ArrayType) typeLiteral.getType(); assertTrue(arrayType.getElementType().isPrimitiveType()); assertTrue(arrayType.getDimensions() == 1); ForStatement forStatement = (ForStatement) method.getBody().statements().get(1); VariableDeclarationExpression variableDeclarationExpression = (VariableDeclarationExpression) forStatement.initializers().get(0); fragment = (VariableDeclarationFragment) variableDeclarationExpression.fragments().get(0); dimension = (Dimension) fragment.extraDimensions().get(0); checkSourceRange(dimension, "@TakeType(int[].class) []", contents); forStatement = (ForStatement) method.getBody().statements().get(1); variableDeclarationExpression = (VariableDeclarationExpression) forStatement.initializers().get(0); fragment = (VariableDeclarationFragment) variableDeclarationExpression.fragments().get(0); dimension = (Dimension) fragment.extraDimensions().get(0); checkSourceRange(dimension, "@TakeType(int[].class) []", contents); method = (MethodDeclaration) type.bodyDeclarations().get(count++); singleVariableDeclaration = (SingleVariableDeclaration) method.parameters().get(0); // test case active only after bug 417660 is fixed (uncomment) checkSourceRange(singleVariableDeclaration, "int [] /*@TakeType(int[].class)*/ [] a", contents); method = (MethodDeclaration) type.bodyDeclarations().get(count++); singleVariableDeclaration = (SingleVariableDeclaration) method.parameters().get(0); checkSourceRange(singleVariableDeclaration, "int @TakeType(int[].class)... args", contents); singleMemberAnnotation = (SingleMemberAnnotation) singleVariableDeclaration.varargsAnnotations().get(0); typeLiteral = (TypeLiteral) singleMemberAnnotation.getValue(); arrayType = (ArrayType) typeLiteral.getType(); assertTrue(arrayType.getElementType().isPrimitiveType()); assertTrue(arrayType.getDimensions() == 1); method = (MethodDeclaration) type.bodyDeclarations().get(count++); singleVariableDeclaration = (SingleVariableDeclaration) method.parameters().get(0); checkSourceRange(singleVariableDeclaration, "int @Annot ... args", contents); assertTrue(singleVariableDeclaration.varargsAnnotations().size() == 1); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=409586 public void testBug409586() throws JavaModelException { String contents = "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker {\n" + " String value() default \"\";\n" + "}\n" + "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker2 {\n" + " String value() default \"22\";\n" + "}\n" + "public class X {\n" + " public @Marker(\"1\") String foo(int @Marker @Marker2 [] args) {\n" + " return null;\n" + " }\n" + " public @Marker(\"3\") String bar() {\n" + " return null;\n" + " }\n" + " public String @Marker(\"i0\") @Marker2 [] [] @Marker(\"i1\") [] str = null;\n" + " public @Marker String str2 = null;\n" + " public @Marker String str3 = null;\n" + " public String str4 = null;\n" + "}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 2, 0); assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); MethodDeclaration methodDeclaration = (MethodDeclaration) node; IMethodBinding mBinding = methodDeclaration.resolveBinding(); assertNotNull("Should not be null", mBinding); ITypeBinding tBinding1 = mBinding.getReturnType(); assertNotNull("Should not be null", tBinding1); /* public @Marker("1") String foo(int @Marker @Marker2 [] args) */ List params = methodDeclaration.parameters(); assertEquals("Incorrect params", 1, params.size()); SingleVariableDeclaration param = (SingleVariableDeclaration) params.get(0); ArrayType type = (ArrayType) param.getType(); ITypeBinding tBinding = type.resolveBinding(); assertNotNull("Should not be null", tBinding); IAnnotationBinding[] annots = tBinding.getTypeAnnotations(); assertEquals("Incorrect type annotations", 2, annots.length); assertEquals("Incorrect annotation", "@Marker()", annots[0].toString()); assertEquals("Incorrect annotation", "@Marker2()", annots[1].toString()); /* public @Marker("3") String bar()*/ node = getASTNode(compilationUnit, 2, 1); assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); methodDeclaration = (MethodDeclaration) node; mBinding = methodDeclaration.resolveBinding(); assertNotNull("Should not be null", mBinding); ITypeBinding tBinding2 = mBinding.getReturnType(); assertNotNull("Should not be null", tBinding1); assertNotSame("Type bindings should not be same", tBinding1, tBinding2); annots = tBinding1.getTypeAnnotations(); assertEquals("Incorrect type annotations", 1, annots.length); IAnnotationBinding annot = annots[0]; assertEquals("Incorrect annotation", "@Marker(value = 1)", annot.toString()); annots = tBinding2.getTypeAnnotations(); assertEquals("Incorrect type annotations", 1, annots.length); annot = annots[0]; assertEquals("Incorrect annotation", "@Marker(value = 3)", annot.toString()); /* public String @Marker("i0") @Marker2 [] [] @Marker("i1") [] str = null; */ node = getASTNode(compilationUnit, 2, 2); assertTrue("Not a field declaration", node.getNodeType() == ASTNode.FIELD_DECLARATION); FieldDeclaration field = (FieldDeclaration) node; List fragments = field.fragments(); assertEquals("Incorrect no of fragments", 1, fragments.size()); VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(0); IVariableBinding variable = fragment.resolveBinding(); assertNotNull("Should not be null", variable); ITypeBinding tBinding3 = variable.getType(); assertNotNull("Should not be null", tBinding3); annots = tBinding3.getTypeAnnotations(); assertEquals("Incorrect type annotations", 2, annots.length); assertEquals("Incorrect annotation", "@Marker(value = i0)", annots[0].toString()); assertEquals("Incorrect annotation", "@Marker2()", annots[1].toString()); tBinding3 = tBinding3.getComponentType(); annots = tBinding3.getTypeAnnotations(); assertEquals("Incorrect type annotations", 0, annots.length); tBinding3 = tBinding3.getComponentType(); annots = tBinding3.getTypeAnnotations(); assertEquals("Incorrect type annotations", 1, annots.length); assertEquals("Incorrect annotation", "@Marker(value = i1)", annots[0].toString()); /* public @Marker String str2 = null; */ node = getASTNode(compilationUnit, 2, 3); assertTrue("Not a field declaration", node.getNodeType() == ASTNode.FIELD_DECLARATION); field = (FieldDeclaration) node; fragments = field.fragments(); assertEquals("Incorrect no of fragments", 1, fragments.size()); fragment = (VariableDeclarationFragment) fragments.get(0); variable = fragment.resolveBinding(); assertNotNull("Should not be null", variable); tBinding1 = variable.getType(); /* public @Marker String str3 = null; */ node = getASTNode(compilationUnit, 2, 4); assertTrue("Not a field declaration", node.getNodeType() == ASTNode.FIELD_DECLARATION); field = (FieldDeclaration) node; fragments = field.fragments(); assertEquals("Incorrect no of fragments", 1, fragments.size()); fragment = (VariableDeclarationFragment) fragments.get(0); variable = fragment.resolveBinding(); assertNotNull("Should not be null", variable); tBinding2 = variable.getType(); assertSame("Type bindings should be same", tBinding1, tBinding2); assertTrue("Unannotated bindings should be same", tBinding1.isEqualTo(tBinding2)); /* public String str4 = null; */ node = getASTNode(compilationUnit, 2, 5); assertTrue("Not a field declaration", node.getNodeType() == ASTNode.FIELD_DECLARATION); field = (FieldDeclaration) node; fragments = field.fragments(); assertEquals("Incorrect no of fragments", 1, fragments.size()); fragment = (VariableDeclarationFragment) fragments.get(0); variable = fragment.resolveBinding(); assertNotNull("Should not be null", variable); tBinding2 = variable.getType(); assertNotSame("Type bindings should not be same", tBinding1, tBinding2); assertTrue("Unannotated bindings should be same", tBinding1.isEqualTo(tBinding2)); } public void testExtendedDimensions() throws JavaModelException { String contents = "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker {\n" + " String value() default \"\";\n" + "}\n" + "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker2 {\n" + " String value() default \"22\";\n" + "}\n" + "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker3 {\n" + " String value() default \"22\";\n" + "}\n" + "public class X {\n" + " public @Marker(\"1\") String @Marker(\"2\") [] foo(int @Marker @Marker2 [] args @Marker3 []) @Marker3(\"3\") [] {\n" + " return null;\n" + " }\n" + " public String @Marker(\"i0\") @Marker2 [] [] @Marker(\"i1\") [] str @Marker(\"Extended\") [] = null;\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 3, 0); assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); MethodDeclaration methodDeclaration = (MethodDeclaration) node; Type returnType = methodDeclaration.getReturnType2(); ITypeBinding tBinding1 = returnType.resolveBinding(); assertEquals("Unexpected type", tBinding1.toString(), "@Marker((String)\"1\") String @Marker((String)\"2\") []"); assertEquals("Unexpected type", methodDeclaration.resolveBinding().getReturnType().toString(), "@Marker((String)\"1\") String @Marker3((String)\"3\") [] @Marker((String)\"2\") []"); List params = methodDeclaration.parameters(); assertEquals("Incorrect params", 1, params.size()); SingleVariableDeclaration param = (SingleVariableDeclaration) params.get(0); ArrayType type = (ArrayType) param.getType(); ITypeBinding tBinding = type.resolveBinding(); assertEquals("Unexpected type", tBinding.toString(), "int @Marker @Marker2 []"); assertEquals("Unexpected type", param.resolveBinding().getType().toString(), "int @Marker3 [] @Marker @Marker2 []"); // public String @Marker(\"i0\") @Marker2 [] [] @Marker(\"i1\") [] str @Marker(\"Extended\") [] = null; node = getASTNode(compilationUnit, 3, 1); assertTrue("Not a field declaration", node.getNodeType() == ASTNode.FIELD_DECLARATION); FieldDeclaration field = (FieldDeclaration) node; List fragments = field.fragments(); assertEquals("Incorrect no of fragments", 1, fragments.size()); VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(0); assertEquals("Unexpected type", fragment.resolveBinding().getType().toString(), "String @Marker((String)\"Extended\") [] @Marker((String)\"i0\") @Marker2 [] [] @Marker((String)\"i1\") []"); assertEquals("Unexpected type", "String @Marker(\"i0\") @Marker2 [][] @Marker(\"i1\") []", field.getType().toString()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=417669 public void testBug417669() throws JavaModelException { String contents = "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Marker {}\n" + "public class X {\n" + " public static void main(String [] args) {\n" + " W<String> w = (@Marker W<String>) null;\n" + " }\n" + "}\n" + "class W<T> {}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 1, 0); assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); MethodDeclaration method = (MethodDeclaration) node; assertEquals("Method should not be malformed", 0, (method.getFlags() & ASTNode.MALFORMED)); List statements = method.getBody().statements(); VariableDeclarationStatement statement = (VariableDeclarationStatement) statements.get(0); VariableDeclarationFragment fragment = (VariableDeclarationFragment) statement.fragments().get(0); CastExpression cast = (CastExpression) fragment.getInitializer(); ParameterizedType castType = (ParameterizedType) cast.getType(); Type type = castType.getType(); checkSourceRange(castType, "@Marker W<String>", contents); checkSourceRange(type, "@Marker W", contents); } // Bug 414113 - [1.8] Method Binding for default method has abstract modifier instead of default // https://bugs.eclipse.org/bugs/show_bug.cgi?id=414113 public void testBug414113() throws JavaModelException { String contents = "public interface X {\n" + " int i = foo();\n" + " default int foo_default() { return 1;}\n" + " static int foo_static() { return 1;}\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy, false); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; TypeDeclaration type = (TypeDeclaration) unit.types().get(0); MethodDeclaration method = (MethodDeclaration) type.bodyDeclarations().get(1); IMethodBinding binding = method.resolveBinding(); assertTrue("binding is default", (binding.getModifiers() & Modifier.DEFAULT) != 0); method = (MethodDeclaration) type.bodyDeclarations().get(2); binding = method.resolveBinding(); assertTrue("binding is static", (binding.getModifiers() & Modifier.STATIC) != 0); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=420660 */ public void testBug420660() throws JavaModelException { String contents = "package java.lang;\n" + "public class X {\n" + " public void foo(int p, int q) {\n" + " final int finalVar = 1; // not effectively final! \n" + " int effectivelyFinalVar = 2;\n" + " int nonFinalVar = 3;\n" + " nonFinalVar = 4; \n" + " q = 0;\n" + " try (FIS fis = new FIS()) {\n" + " if (q == 0) { throw new IOError(); } else { throw new IllegalStateException(); }\n" + " } catch (IOError | IllegalStateException implicitlyFinalExc) {\n" + " // implicitlyFinalExc is not effectively final! \n" + " } catch (Exception effectivelyFinalExc) { \n" + " }\n" + " }\n" + "}\n" + "class IOError extends Exception {private static final long serialVersionUID = 1L;}\n" + "class IllegalStateException extends Exception {private static final long serialVersionUID = 1L;}\n" + "class FIS implements AutoCloseable {\n public void close() throws Exception {} \n }\n" + "interface AutoCloseable { \n void close() throws Exception; \n}"; this.workingCopy = getWorkingCopy("/Converter18/src/java/lang/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 0); assertEquals("Not a type declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); MethodDeclaration[] methods = ((TypeDeclaration) node).getMethods(); assertEquals("Incorrect no of methods", 1, methods.length); MethodDeclaration method = methods[0]; List params = method.parameters(); assertEquals("Incorrect no of parameters", 2, params.size()); SingleVariableDeclaration variable = (SingleVariableDeclaration) params.get(0); IVariableBinding binding = variable.resolveBinding(); assertTrue("Should be effectively final", binding.isEffectivelyFinal()); variable = (SingleVariableDeclaration) params.get(1); binding = variable.resolveBinding(); assertFalse("Should not be effectively final", binding.isEffectivelyFinal()); List statements = method.getBody().statements(); VariableDeclarationStatement statement = (VariableDeclarationStatement) statements.get(0); List fragments = statement.fragments(); VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(0); binding = fragment.resolveBinding(); assertFalse("Should not be effectively final", binding.isEffectivelyFinal()); statement = (VariableDeclarationStatement) statements.get(1); fragments = statement.fragments(); fragment = (VariableDeclarationFragment) fragments.get(0); binding = fragment.resolveBinding(); assertTrue("Should be effectively final", binding.isEffectivelyFinal()); statement = (VariableDeclarationStatement) statements.get(2); fragments = statement.fragments(); fragment = (VariableDeclarationFragment) fragments.get(0); binding = fragment.resolveBinding(); assertFalse("Should not be effectively final", binding.isEffectivelyFinal()); TryStatement tryStmt = (TryStatement) statements.get(5); List resources = tryStmt.resources(); VariableDeclarationExpression resourceExp = (VariableDeclarationExpression) resources.get(0); fragment = (VariableDeclarationFragment) resourceExp.fragments().get(0); binding = fragment.resolveBinding(); assertFalse("Should not be effectively final", binding.isEffectivelyFinal()); List catches = tryStmt.catchClauses(); CatchClause catchCl = (CatchClause) catches.get(1); variable = catchCl.getException(); binding = variable.resolveBinding(); assertTrue("Should be effectively final", binding.isEffectivelyFinal()); catchCl = (CatchClause) catches.get(0); variable = catchCl.getException(); binding = variable.resolveBinding(); assertFalse("Should not be effectively final", binding.isEffectivelyFinal()); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=420660 */ public void testBug420660a() throws JavaModelException { String contents = "interface I {\nvoid foo();\n}\n" + "interface J {}\n" + "public class X {\n" + " void foo(int [] p) {\n" + " for (int is : p) {\n" + " I j = new I () {\n" + " public void foo() {\n" + " System.out.println(is);\n" + " }\n" + " };\n" + " }\n" + " }\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 2); assertEquals("Not a type declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); MethodDeclaration[] methods = ((TypeDeclaration) node).getMethods(); assertEquals("Incorrect no of methods", 1, methods.length); MethodDeclaration method = methods[0]; List statements = method.getBody().statements(); EnhancedForStatement stmt = (EnhancedForStatement) statements.get(0); SingleVariableDeclaration variable = stmt.getParameter(); IVariableBinding binding = variable.resolveBinding(); assertTrue("Should be effectively final", binding.isEffectivelyFinal()); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=423872 */ public void testBug423872() throws JavaModelException { String contents = "public interface X {\n" + " void foo(Y.Z<?>... events);\n" + "}\n" + "interface Y<T> {\n" + " public static interface Z<T> {}\n" + "}\n"; try { this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 0); assertEquals("Not a type declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); MethodDeclaration[] methods = ((TypeDeclaration) node).getMethods(); assertEquals("Incorrect no of methods", 1, methods.length); MethodDeclaration method = methods[0]; List parameters = method.parameters(); assertTrue(parameters.size() == 1); SingleVariableDeclaration singleVariableDeclaration = (SingleVariableDeclaration) parameters.get(0); checkSourceRange(singleVariableDeclaration, "Y.Z<?>... events", contents); assertTrue(singleVariableDeclaration.isVarargs()); Type type = singleVariableDeclaration.getType(); assertTrue(type.isParameterizedType()); } catch (IllegalArgumentException e) { assertTrue(false); } } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=424138 */ public void testBug424138_001() throws JavaModelException { String contents = "package jsr308.myex;\n" + "\n" + "public class X extends @jsr308.myex.X.Anno Object {\n" + " void foo(@jsr308.myex.X.Anno X this) {}\n" + " Y<@jsr308.myex.X.Anno Object> l;\n" + " int o @jsr308.myex.X.Anno[];\n" + "\n" + " @jsr308.myex.X.Anno X f;\n" + " int @jsr308.myex.X.Anno[] ok;\n" + " @jsr308.myex.X.Anno X g;\n" + " void bar(@jsr308.myex.X.Anno X ok) {\n" + " @jsr308.myex.X.Anno X l;\n" + " }\n" + " @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_USE)\n" + " public @interface Anno {}\n" + "}\n" + "class Y<T> {}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/jsr308/myex/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 0); assertEquals("Not a type declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); TypeDeclaration typeDeclaration = (TypeDeclaration) node; SimpleType simpleType = (SimpleType) typeDeclaration.getSuperclassType(); checkSourceRange(simpleType, "@jsr308.myex.X.Anno Object", contents); Annotation annotation = (Annotation) simpleType.annotations().get(0); checkSourceRange(annotation, "@jsr308.myex.X.Anno", contents); MethodDeclaration[] methods = ((TypeDeclaration) node).getMethods(); assertEquals("Incorrect no of methods", 2, methods.length); MethodDeclaration method = methods[0]; simpleType = (SimpleType) method.getReceiverType(); checkSourceRange(simpleType, "@jsr308.myex.X.Anno X", contents); FieldDeclaration [] fields = typeDeclaration.getFields(); FieldDeclaration f = fields[0]; checkSourceRange(f, "Y<@jsr308.myex.X.Anno Object> l;", contents); Type type = f.getType(); assertTrue(type.isParameterizedType()); ParameterizedType parameterizedType = (ParameterizedType) type; checkSourceRange((ASTNode) parameterizedType.typeArguments().get(0), "@jsr308.myex.X.Anno Object", contents); f = fields[1]; checkSourceRange(f, "int o @jsr308.myex.X.Anno[];", contents); assertTrue(f.getType().isPrimitiveType()); VariableDeclarationFragment fragment = (VariableDeclarationFragment) f.fragments().get(0); checkSourceRange((ASTNode) fragment.extraDimensions().get(0), "@jsr308.myex.X.Anno[]", contents); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=424138 */ public void testBug424138_002() throws JavaModelException { String contents = "package jsr308.myex;\n" + "\n" + "public class X{\n" + " int o2[];\n" + " int o1 @jsr308.myex.X.Anno[];\n" + " int @jsr308.myex.X.Anno[][] o3 @jsr308.myex.X.Anno[][];\n" + " @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_USE)\n" + " public @interface Anno {}\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/jsr308/myex/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 0); assertEquals("Not a type declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); TypeDeclaration typeDeclaration = (TypeDeclaration) node; FieldDeclaration [] fields = typeDeclaration.getFields(); FieldDeclaration f = fields[0]; checkSourceRange(f, "int o2[];", contents); f = fields[1]; checkSourceRange(f, "int o1 @jsr308.myex.X.Anno[];", contents); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=424138 */ public void testBug424138_003() throws JavaModelException { String contents = "package jsr308.myex;\n" + "\n" + "public class X{\n" + " public void foo() {\n" + " for (int i @jsr308.myex.X.Anno[]: new int[10][12]) {\n" + " System.out.println(\"hello\");\n" + " }\n" + " }\n" + " @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_USE)\n" + " public @interface Anno {}\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/jsr308/myex/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 0); assertEquals("Not a type declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); TypeDeclaration typeDeclaration = (TypeDeclaration) node; MethodDeclaration [] methods = typeDeclaration.getMethods(); EnhancedForStatement statement = (EnhancedForStatement) methods[0].getBody().statements().get(0); SingleVariableDeclaration variable = statement.getParameter(); checkSourceRange(variable, "int i @jsr308.myex.X.Anno[]", contents); Dimension dim = (Dimension) variable.extraDimensions().get(0); checkSourceRange(dim, "@jsr308.myex.X.Anno[]", contents); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=423584, [1.8][dom ast] NPE in LambdaExpression#getMethodBinding() for lambda with unresolved type */ public void test423584() throws JavaModelException { String contents = "interface I { }\n" + "public class X {\n" + " static void goo(I i) {\n" + " System.out.println(\"goo(I)\");\n" + " }\n" + " public static void main(String[] args) {\n" + " goo(s -> 0);\n" + " }\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy, false); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 2, "The method goo(I) in the type X is not applicable for the arguments ((<no type> s) -> {})\n" + "The target type of this expression must be a functional interface"); node = getASTNode(compilationUnit, 1); assertEquals("Not a type declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); MethodDeclaration[] methods = ((TypeDeclaration) node).getMethods(); assertEquals("Incorrect no of methods", 2, methods.length); MethodDeclaration method = methods[1]; List statements = method.getBody().statements(); LambdaExpression lambda = (LambdaExpression) ((MethodInvocation) ((ExpressionStatement) statements.get(0)).getExpression()).arguments().get(0); IMethodBinding resolveMethodBinding = lambda.resolveMethodBinding(); assertTrue("Should be null", resolveMethodBinding == null); // no NPE, just a null method binding. } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=418979 */ public void testBug418979_001() throws JavaModelException { String contents = "import java.lang.annotation.*;\n" + "public class X {\n" + " void foo(Y.@A Z<?> events) {}\n" + " void foo(Y.@A ZZ events) {}\n" + " }\n" + "class Y {\n" + " class Z<T> {}\n" + " class ZZ{}\n" + "}\n" + "@Target (ElementType.TYPE_USE)\n" + "@interface A{}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy, false); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 0); assertEquals("Not a type declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); MethodDeclaration[] methods = ((TypeDeclaration) node).getMethods(); assertEquals("Incorrect no of methods", 2, methods.length); MethodDeclaration method = methods[0]; List params = method.parameters(); assertEquals("Incorrect no of parameters", 1, params.size()); SingleVariableDeclaration variable = (SingleVariableDeclaration) params.get(0); Type type = variable.getType(); assertTrue(type.isParameterizedType()); ParameterizedType parameterizedType = (ParameterizedType) type; checkSourceRange(parameterizedType, "Y.@A Z<?>", contents); type = parameterizedType.getType(); assertTrue(type.isNameQualifiedType()); NameQualifiedType nameQualifiedType = (NameQualifiedType) type; checkSourceRange(nameQualifiedType, "Y.@A Z", contents); method = methods[1]; params = method.parameters(); assertEquals("Incorrect no of parameters", 1, params.size()); variable = (SingleVariableDeclaration) params.get(0); type = variable.getType(); assertTrue(type.isNameQualifiedType()); nameQualifiedType = (NameQualifiedType) type; checkSourceRange(nameQualifiedType, "Y.@A ZZ", contents); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=418979 */ public void testBug418979_002() throws JavaModelException { String contents = "package test;\n" + "import java.lang.annotation.*;\n" + "public class X {\n" + " test.@A Outer<C>.@A Inner<C> i;\n" + " }\n" + "class Outer<T> {\n" + " class Inner<S> {}\n" + "}\n" + "class C {}\n" + "@Target (ElementType.TYPE_USE)\n" + "@interface A{}"; this.workingCopy = getWorkingCopy("/Converter18/src/test/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy, false); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; node = getASTNode(compilationUnit, 0); assertEquals("Not a type declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); FieldDeclaration field = ((TypeDeclaration) node).getFields()[0]; checkSourceRange(field, "test.@A Outer<C>.@A Inner<C> i;", contents); ParameterizedType parameterizedType = (ParameterizedType) field.getType(); checkSourceRange(parameterizedType, "test.@A Outer<C>.@A Inner<C>", contents); QualifiedType qualifiedType = (QualifiedType) parameterizedType.getType(); checkSourceRange(qualifiedType, "test.@A Outer<C>.@A Inner", contents); parameterizedType = (ParameterizedType) qualifiedType.getQualifier(); checkSourceRange(parameterizedType, "test.@A Outer<C>", contents); NameQualifiedType nameQualifiedType = (NameQualifiedType) parameterizedType.getType(); checkSourceRange(nameQualifiedType, "test.@A Outer", contents); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=418979 */ public void testBug418979_003() throws JavaModelException { String contents = "package test;\n" + "import java.lang.annotation.*;\n" + "public class X {\n" + " public void foo() {\n" + " new java.util.@A HashMap<>();\n" + " }\n" + " }\n" + "@Target (ElementType.TYPE_USE)\n" + "@interface A{}"; this.workingCopy = getWorkingCopy("/Converter18/src/test/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy, false); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; node = getASTNode(compilationUnit, 0); assertEquals("Not a type declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); MethodDeclaration method = ((TypeDeclaration) node).getMethods()[0]; ExpressionStatement statement = (ExpressionStatement) method.getBody().statements().get(0); ClassInstanceCreation instance = (ClassInstanceCreation) statement.getExpression(); ParameterizedType parameterizedType = (ParameterizedType) instance.getType(); checkSourceRange(parameterizedType, "java.util.@A HashMap<>", contents); NameQualifiedType nameQualifiedType = (NameQualifiedType) parameterizedType.getType(); checkSourceRange(nameQualifiedType, "java.util.@A HashMap", contents); checkSourceRange(nameQualifiedType.getQualifier(), "java.util", contents); checkSourceRange(nameQualifiedType.getName(), "HashMap", contents); checkSourceRange((ASTNode) nameQualifiedType.annotations().get(0), "@A", contents); } /* * [1.8][dom ast] variable binding for LambdaExpression parameter has non-unique key (https://bugs.eclipse.org/bugs/show_bug.cgi?id=416559) */ public void test416559() throws JavaModelException { String contents = "interface I {\n" + " int f (int x);\n" + "}\n" + "\n" + "class X {\n" + " I i1 = (x) -> 1;\n" + " I i2 = (x) -> 1;\n" + "}\n" ; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy, false); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 1); FieldDeclaration[] field = ((TypeDeclaration) node).getFields(); List fragments = field[0].fragments(); VariableDeclarationFragment fragment = (VariableDeclarationFragment)fragments.get(0); Expression expression = fragment.getInitializer(); LambdaExpression lambdaExpression = (LambdaExpression)expression; VariableDeclaration variableDeclaration = (VariableDeclaration) lambdaExpression.parameters().get(0); IVariableBinding variableBinding = variableDeclaration.resolveBinding(); IMethodBinding methodBinding = lambdaExpression.resolveMethodBinding(); String methodKey = ((IBinding) methodBinding).getKey(); String variableKey = ((IBinding) variableBinding).getKey(); assertTrue(variableKey.regionMatches(0, methodKey, 0, methodKey.length())); fragments = field[1].fragments(); fragment = (VariableDeclarationFragment)fragments.get(0); expression = fragment.getInitializer(); lambdaExpression = (LambdaExpression)expression; variableDeclaration = (VariableDeclaration) lambdaExpression.parameters().get(0); variableBinding = variableDeclaration.resolveBinding(); assertNotSame(variableKey.intern(), ((IBinding) variableBinding).getKey().intern()); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=420458 */ public void testBug420458() throws JavaModelException { String contents = "/**\n" + " * Hello\n" + " * @see #foo(Object[][][])\n" + " **/\n" + "public class X {}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/test/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy, false); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; node = getASTNode(compilationUnit, 0); assertEquals("Not a type declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); Javadoc javaDoc = ((TypeDeclaration) node).getJavadoc(); TagElement tagElement = (TagElement) javaDoc.tags().get(1); MethodRef methodRef = (MethodRef) tagElement.fragments().get(0); MethodRefParameter parameter = (MethodRefParameter) methodRef.parameters().get(0); ArrayType arrayType = (ArrayType) parameter.getType(); checkSourceRange(arrayType, "Object[][][]", contents); checkSourceRange(arrayType.getElementType(), "Object", contents); assertTrue(arrayType.getDimensions() == 3); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=420458 */ public void testBug425741() throws JavaModelException { String contents = "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface Annot { String value(); }\n" + "@Annot(\"decl\") public class X {\n" + " @Annot(\"field\") X x = null;\n" + " public void foo(@Annot(\"param\") X i) {\n" + " }\n" + "}"; this.workingCopy = getWorkingCopy("/Converter18/src/test/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy, false); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; node = getASTNode(compilationUnit, 1); assertEquals("Not a type declaration", ASTNode.TYPE_DECLARATION, node.getNodeType()); FieldDeclaration field = ((TypeDeclaration) node).getFields()[0]; List fragments = field.fragments(); ITypeBinding typeBinding = field.getType().resolveBinding(); IAnnotationBinding[] annots = typeBinding.getTypeAnnotations(); assertEquals("Incorrect type annotations", 1, annots.length); assertEquals("Incorrect annotation", "@Annot(value = field)", annots[0].toString()); VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(0); typeBinding = typeBinding.getTypeDeclaration(); annots = typeBinding.getTypeAnnotations(); assertEquals("Incorrect type annotations", 0, annots.length); typeBinding = fragment.resolveBinding().getType().getTypeDeclaration(); annots = typeBinding.getTypeAnnotations(); assertEquals("Incorrect type annotations", 0, annots.length); MethodDeclaration method = ((TypeDeclaration) node).getMethods()[0]; SingleVariableDeclaration param = (SingleVariableDeclaration) method.parameters().get(0); typeBinding = param.getType().resolveBinding(); annots = typeBinding.getTypeAnnotations(); assertEquals("Incorrect type annotations", 1, annots.length); assertEquals("Incorrect annotation", "@Annot(value = param)", annots[0].toString()); typeBinding = typeBinding.getTypeDeclaration(); annots = typeBinding.getTypeAnnotations(); assertEquals("Incorrect type annotations", 0, annots.length); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=416560, [1.8] Incorrect source range for lambda expression's parameter after reconciliation */ public void testBug416560_001() throws JavaModelException { String contents = "import java.lang.annotation.ElementType;\n" + "@Target (ElementType.FIELD)\n" + "public class X{\n" + " public FI fi= /*a*/(int n1, int n2) -> n1 * n2;\n" + "}\n" + "public class X\n" + " public FI fi= /*a*/(int n1, int n2) -> n1 * n2;\n" + "interface FI {\n" + " int foo(int s1, int s2);\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/test/X.java", true/*resolve*/); this.workingCopy.getBuffer().setContents(contents); CompilationUnit compilationUnit = this.workingCopy.reconcile(AST.JLS8, ICompilationUnit.FORCE_PROBLEM_DETECTION, null, null); ASTNode node = getASTNode(compilationUnit, 0); FieldDeclaration[] field = ((TypeDeclaration) node).getFields(); List fragments = field[0].fragments(); VariableDeclarationFragment fragment = (VariableDeclarationFragment)fragments.get(0); Expression expression = fragment.getInitializer(); LambdaExpression lambdaExpression = (LambdaExpression)expression; VariableDeclaration variableDeclaration = (VariableDeclaration) lambdaExpression.parameters().get(0); checkSourceRange(variableDeclaration, "int n1", contents); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=416560, [1.8] Incorrect source range for lambda expression's parameter after reconciliation */ public void testBug416560_002() throws JavaModelException { String contents = "import java.lang.annotation.ElementType;\n" + "@Target (ElementType.FIELD)\n" + "public class X{\n" + " public FI fi= /*a*/(int n1, int n2) -> n1 * n2;\n" + "}\n" + "public class X\n" + " public FI fi= /*a*/(int n1, int n2) -> n1 * n2;\n" + "interface FI {\n" + " int foo(int s1, int s2);\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/test/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy, false); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; node = getASTNode(compilationUnit, 0); FieldDeclaration[] field = ((TypeDeclaration) node).getFields(); List fragments = field[0].fragments(); VariableDeclarationFragment fragment = (VariableDeclarationFragment)fragments.get(0); Expression expression = fragment.getInitializer(); LambdaExpression lambdaExpression = (LambdaExpression)expression; VariableDeclaration variableDeclaration = (VariableDeclaration) lambdaExpression.parameters().get(0); checkSourceRange(variableDeclaration, "int n1", contents); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=416560, [1.8] Incorrect source range for lambda expression's parameter after reconciliation */ public void testBug416560_003() throws JavaModelException { String contents = "public class X{\n" + " void f() {\n" + " //a\n" + " //few\n" + " //comments\n" + " //here\n" + " bar((int x) -> 91);\n" + " }\n" + " int bar(FI f){ return 1;}" + "}\n" + "interface FI {\n" + " int foo(int s1);\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy, true); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; node = getASTNode(compilationUnit, 0); MethodDeclaration[] methods = ((TypeDeclaration) node).getMethods(); MethodDeclaration method = methods[0]; Block block = method.getBody(); List statements = block.statements(); Statement statement = (Statement) statements.get(0); MethodInvocation methodInvocation = (MethodInvocation) ((ExpressionStatement) statement).getExpression(); LambdaExpression lambdaExpression = (LambdaExpression) methodInvocation.arguments().get(0); VariableDeclaration variableDeclaration = (VariableDeclaration) lambdaExpression.parameters().get(0); checkSourceRange(variableDeclaration, "int x", contents); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=425743, [1.8][api] CompilationUnit#findDeclaringNode(IBinding binding) returns null for type inferred lambda parameter */ public void testBug425743() throws JavaModelException { String contents = "public class X{\n" + " FI fi = (x2) -> x2;\n" + "}\n" + "interface FI {\n" + " int foo(int n);\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true/*resolve*/); ASTNode node = buildAST(contents, this.workingCopy, true); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; node = getASTNode(compilationUnit, 0); FieldDeclaration fi = ((TypeDeclaration) node).getFields()[0]; VariableDeclarationFragment vdf = (VariableDeclarationFragment) fi.fragments().get(0); LambdaExpression lambda = (LambdaExpression) vdf.getInitializer(); VariableDeclaration param = (VariableDeclaration) lambda.parameters().get(0); IBinding binding = param.getName().resolveBinding(); ASTNode astNode = compilationUnit.findDeclaringNode(binding); assertNotNull(astNode); assertEquals("Not a variable declaration fragment", ASTNode.VARIABLE_DECLARATION_FRAGMENT, astNode.getNodeType()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=427357 public void testBug427357() throws JavaModelException { String contents = "public class X {\n" + " public static void foo(X this, int i){}\n" + " public void foo(Inner this){}\n" + " I I = new I() {\n" + " public void bar(I this, int i) {}\n" + " };\n" + " static class Inner {\n" + " public Inner(Test2 Test2.this){}\n" + " public Inner(Inner Inner.this, int i){}\n" + " }\n" + "}\n"+ "interface I {}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy, false); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; TypeDeclaration typeDecl = (TypeDeclaration) unit.types().get(0); MethodDeclaration method = (MethodDeclaration) typeDecl.bodyDeclarations().get(0); Type receiver = method.getReceiverType(); assertNotNull("Receiver should not be null", receiver); assertEquals("Incorrect receiver type", "X", receiver.toString()); method = (MethodDeclaration) typeDecl.bodyDeclarations().get(1); receiver = method.getReceiverType(); assertNotNull("Receiver should not be null", receiver); FieldDeclaration field = (FieldDeclaration) typeDecl.bodyDeclarations().get(2); ClassInstanceCreation anonymousInst = (ClassInstanceCreation ) ((VariableDeclarationFragment) field.fragments().get(0)).getInitializer(); AnonymousClassDeclaration anonymousDecl = anonymousInst.getAnonymousClassDeclaration(); method = (MethodDeclaration) anonymousDecl.bodyDeclarations().get(0); receiver = method.getReceiverType(); assertNotNull("Receiver should not be null", receiver); assertEquals("Incorrect receiver type", "I", receiver.toString()); typeDecl = (TypeDeclaration) typeDecl.bodyDeclarations().get(3); method = (MethodDeclaration) typeDecl.bodyDeclarations().get(0); receiver = method.getReceiverType(); assertNotNull("Receiver should not be null", receiver); assertEquals("Incorrect receiver type", "Test2", receiver.toString()); method = (MethodDeclaration) typeDecl.bodyDeclarations().get(1); receiver = method.getReceiverType(); assertNotNull("Receiver should not be null", receiver); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=426459 public void testBug426459() throws JavaModelException { String contents = "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE) @interface A {}\n" + "@Target(ElementType.TYPE_USE) @interface B {}\n" + "@Target(ElementType.TYPE_USE) @interface C {}\n" + "public class X {\n" + " @A int @B [] @C [] @A [] is;\n" + " @C String @A [] @B [] @C [] ss;\n" + " @C String @A [] [] [] [] sss;\n" + "}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 3, 0); assertTrue("Not a field declaration", node.getNodeType() == ASTNode.FIELD_DECLARATION); FieldDeclaration field = (FieldDeclaration) node; Type type = field.getType(); ITypeBinding original = type.resolveBinding(); assertEquals("Incorrect type binding", "@A int @B [] @C [] @A []", original.toString()); ITypeBinding binding = original.createArrayType(1); assertEquals("Incorrect type binding", "@A int [] @B [] @C [] @A []", binding.toString()); int dims = binding.getDimensions(); assertEquals("Incorrect no of dimensions", 4, dims); IAnnotationBinding[] annotations = binding.getTypeAnnotations(); assertEquals("Incorrect no of type annotations", 0, annotations.length); binding = binding.getComponentType(); annotations = binding.getTypeAnnotations(); assertEquals("Incorrect no of type annotations", 1, annotations.length); assertEquals("Incorrect annotation", "@B()", annotations[0].toString()); binding = binding.getComponentType(); annotations = binding.getTypeAnnotations(); assertEquals("Incorrect no of type annotations", 1, annotations.length); assertEquals("Incorrect annotation", "@C()", annotations[0].toString()); binding = binding.getComponentType(); annotations = binding.getTypeAnnotations(); assertEquals("Incorrect no of type annotations", 1, annotations.length); assertEquals("Incorrect annotation", "@A()", annotations[0].toString()); binding = binding.getElementType(); annotations = binding.getTypeAnnotations(); assertEquals("Incorrect no of type annotations", 1, annotations.length); assertEquals("Incorrect annotation", "@A()", annotations[0].toString()); node = getASTNode(compilationUnit, 3, 1); assertTrue("Not a field declaration", node.getNodeType() == ASTNode.FIELD_DECLARATION); field = (FieldDeclaration) node; type = field.getType(); original = type.resolveBinding(); assertEquals("Incorrect type binding", "@C String @A [] @B [] @C []", original.toString()); binding = original.createArrayType(1); assertEquals("Incorrect type binding", "@C String [] @A [] @B [] @C []", binding.toString()); dims = binding.getDimensions(); assertEquals("Incorrect no of dimensions", 4, dims); binding = original.createArrayType(-1); assertEquals("Incorrect type binding", "@C String @B [] @C []", binding.toString()); dims = binding.getDimensions(); assertEquals("Incorrect no of dimensions", 2, dims); binding = original.createArrayType(-2); assertEquals("Incorrect type binding", "@C String @C []", binding.toString()); dims = binding.getDimensions(); assertEquals("Incorrect no of dimensions", 1, dims); node = getASTNode(compilationUnit, 3, 2); assertTrue("Not a field declaration", node.getNodeType() == ASTNode.FIELD_DECLARATION); field = (FieldDeclaration) node; type = field.getType(); original = type.resolveBinding(); assertEquals("Incorrect type binding", "@C String @A [] [] [] []", original.toString()); binding = original.createArrayType(-1); assertEquals("Incorrect type binding", "@C String [] [] []", binding.toString()); dims = binding.getDimensions(); assertEquals("Incorrect no of dimensions", 3, dims); binding = binding.createArrayType(-2); assertEquals("Incorrect type binding", "@C String []", binding.toString()); dims = binding.getDimensions(); assertEquals("Incorrect no of dimensions", 1, dims); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=426459 public void testBug426459a() throws JavaModelException { String contents = "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE) @interface A {}\n" + "@Target(ElementType.TYPE_USE) @interface B {}\n" + "@Target(ElementType.TYPE_USE) @interface C {}\n" + "public class X {\n" + " public void foo() {}\n" + " public @A X.@B Y foo(@C int i){ return null;}\n" + " public @A @B X foo(int i, int j){ return null;}\n" + " public @A X.Y [] @B [] foo(float f){ return null;}\n" + " class Y {}\n" + "}"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); node = getASTNode(compilationUnit, 3, 0); assertEquals("Not a method declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); Type type = ((MethodDeclaration) node).getReturnType2(); ITypeBinding binding = type.resolveBinding(); assertNotNull("Binding should not be null", binding); try { binding = binding.createArrayType(1); binding = null; } catch(IllegalArgumentException iae) { } assertNotNull("IllegalArgumentException should have been thrown", binding); node = getASTNode(compilationUnit, 3, 1); assertEquals("Not a method declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); type = ((MethodDeclaration) node).getReturnType2(); binding = type.resolveBinding(); assertEquals("Incorrect type binding", "@A X.@B Y", binding.toString()); binding = binding.createArrayType(2); assertEquals("Incorrect type binding", "@A X.@B Y [] []", binding.toString()); int dims = binding.getDimensions(); assertEquals("Incorrect no of dimensions", 2, dims); SingleVariableDeclaration param = (SingleVariableDeclaration) ((MethodDeclaration) node).parameters().get(0); type = param.getType(); binding = type.resolveBinding(); assertEquals("Incorrect type binding", "@C int", binding.toString()); binding = binding.createArrayType(2); assertEquals("Incorrect type binding", "@C int [] []", binding.toString()); node = getASTNode(compilationUnit, 3, 2); assertEquals("Not a method declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); type = ((MethodDeclaration) node).getReturnType2(); binding = type.resolveBinding(); assertEquals("Incorrect type binding", "@A @B X", binding.toString()); binding = binding.createArrayType(2); assertEquals("Incorrect type binding", "@A @B X [] []", binding.toString()); dims = binding.getDimensions(); assertEquals("Incorrect no of dimensions", 2, dims); node = getASTNode(compilationUnit, 3, 3); assertEquals("Not a method declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); type = ((MethodDeclaration) node).getReturnType2(); ITypeBinding original = type.resolveBinding(); assertEquals("Incorrect type binding", "@A X.Y [] @B []", original.toString()); binding = original.createArrayType(1); assertEquals("Incorrect type binding", "@A X.Y [] [] @B []", binding.toString()); dims = binding.getDimensions(); assertEquals("Incorrect no of dimensions", 3, dims); binding = original.createArrayType(-1); assertEquals("Incorrect type binding", "@A X.Y @B []", binding.toString()); dims = binding.getDimensions(); assertEquals("Incorrect no of dimensions", 1, dims); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428526, [1.8] API to get the single abstract method in a functional interface public void test428526() throws JavaModelException { String contents = "interface Foo<T, N extends Number> {\n" + " void m(T arg);\n" + " void m(N arg);\n" + "}\n" + "interface Baz extends Foo<Integer, Integer> {}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); TypeDeclaration type = (TypeDeclaration) getASTNode(compilationUnit, 0); assertEquals("Not a Type declaration", ASTNode.TYPE_DECLARATION, type.getNodeType()); ITypeBinding binding = type.resolveBinding(); assertNotNull("Binding should not be null", binding); IMethodBinding functionalInterfaceMethod = binding.getFunctionalInterfaceMethod(); assertNull("Should not be a functional interface", functionalInterfaceMethod); type = (TypeDeclaration) getASTNode(compilationUnit, 1); assertEquals("Not a Type declaration", ASTNode.TYPE_DECLARATION, type.getNodeType()); binding = type.resolveBinding(); assertNotNull("Binding should not be null", binding); functionalInterfaceMethod = binding.getFunctionalInterfaceMethod(); assertNotNull("Should be a functional interface", functionalInterfaceMethod); ITypeBinding declaringClass = functionalInterfaceMethod.getDeclaringClass(); assertEquals("Foo<Integer,Integer>", declaringClass.getName()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428526, [1.8] API to get the single abstract method in a functional interface public void test428526a() throws JavaModelException { String contents = "interface I { X foo(); }\n" + "interface J { Y foo(); }\n" + "interface K extends I, J {}\n" + "class X {}\n" + "class Y extends X {}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); TypeDeclaration type = (TypeDeclaration) getASTNode(compilationUnit, 0); assertEquals("Not a Type declaration", ASTNode.TYPE_DECLARATION, type.getNodeType()); ITypeBinding binding = type.resolveBinding(); assertNotNull("Binding should not be null", binding); IMethodBinding functionalInterfaceMethod = binding.getFunctionalInterfaceMethod(); assertNotNull("Should not be a functional interface", functionalInterfaceMethod); type = (TypeDeclaration) getASTNode(compilationUnit, 1); assertEquals("Not a Type declaration", ASTNode.TYPE_DECLARATION, type.getNodeType()); binding = type.resolveBinding(); assertNotNull("Binding should not be null", binding); functionalInterfaceMethod = binding.getFunctionalInterfaceMethod(); assertNotNull("Should be a functional interface", functionalInterfaceMethod); type = (TypeDeclaration) getASTNode(compilationUnit, 2); assertEquals("Not a Type declaration", ASTNode.TYPE_DECLARATION, type.getNodeType()); binding = type.resolveBinding(); assertNotNull("Binding should not be null", binding); functionalInterfaceMethod = binding.getFunctionalInterfaceMethod(); assertNotNull("Should be a functional interface", functionalInterfaceMethod); ITypeBinding returnType = functionalInterfaceMethod.getReturnType(); assertEquals("Y", returnType.getName()); } // round-trip for binding keys of CaptureBinding18: public void testBug425183a() throws JavaModelException { String contents = "interface Comparator<T> {\n" + " public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() { return null; }\n" + "}\n" + "public class Bug425183a {\n" + " @SuppressWarnings(\"unchecked\")\n" + " <T> void test() {\n" + " Comparator<? super T> comparator = (Comparator<? super T>) Comparator.naturalOrder();\n" + " System.out.println(\"OK\");\n" + " }\n" + " public static void main(String[] args) {\n" + " new Bug425183a().test();\n" + " }\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/Bug425183a.java", true); ASTNode node = buildAST(contents, this.workingCopy); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; assertProblemsSize(compilationUnit, 0); String selection = "naturalOrder"; int start = contents.lastIndexOf(selection); int length = selection.length(); IJavaElement[] elements = this.workingCopy.codeSelect(start, length); assertElementsEqual( "Unexpected elements", "naturalOrder() {key=LBug425183a~Comparator<>;.naturalOrder<T::Ljava/lang/Comparable<-TT;>;>()LComparator<TT;>;%<^{291#0};>} [in Comparator [in [Working copy] Bug425183a.java [in <default> [in src [in Converter18]]]]]", elements, true ); IMethod method = (IMethod)elements[0]; String[] keys = new String[] { method.getKey() }; BindingRequestor requestor = new BindingRequestor(); resolveASTs(new ICompilationUnit[] { this.workingCopy } , keys, requestor, getJavaProject("Converter18"), null); assertBindingsEqual( keys[0], requestor.getBindings(keys)); // assert that KeyToSignature doesn't throw AIOOBE, the result containing '!*' is a workaround for now, see https://bugs.eclipse.org/429264 assertEquals("wrong signature", "<T::Ljava.lang.Comparable<-TT;>;>()LComparator<!*>;", new BindingKey(method.getKey()).toSignature()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=432051 * * @throws JavaModelException */ public void testBug432051() throws JavaModelException { String contents = "public class X {\n" + " * Delete line '/**' above.\n" + " *\n" + " * @param a (for example 'QVector')\n" + " * @param declaringMember the context for resolving (made in)\n" + " * @return if\n" + " */\n" + " void foo() {\n" + " }\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/test432051/X.java", contents, true/*computeProblems*/); IJavaProject javaProject = this.workingCopy.getJavaProject(); class BindingRequestor extends ASTRequestor { ITypeBinding _result = null; public void acceptBinding(String bindingKey, IBinding binding) { if (this._result == null && binding != null && binding.getKind() == IBinding.TYPE) this._result = (ITypeBinding) binding; } } final BindingRequestor requestor = new BindingRequestor(); final ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setResolveBindings(false); parser.setProject(javaProject); try { parser.createASTs(new ICompilationUnit[] {this.workingCopy}, new String[0], requestor, null); } catch (IllegalArgumentException e) { assertTrue("Test Failed", false); } } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=426977 * * @throws JavaModelException */ public void testBug426977() throws JavaModelException { String contents = "package com.test.todo;\r\n"+ "import java.lang.annotation.ElementType;\r\n"+ "import java.lang.annotation.Target;\r\n"+ "public class Test {\r\n"+ " static void m() {}\r\n"+ " new Runnable() {\r\n"+ " public void run(R) {}\r\n"+ " };\r\n"+ "}\r\n"+ "@Target(ElementType.TYPE_USE)\r\n"+ "@interface TU { }"; this.workingCopy = getWorkingCopy("/Converter18/src/com/test/todo/Test.java", true/*computeProblems*/); try { buildAST(AST.JLS8, contents, this.workingCopy, false, true, true); } catch (ClassCastException e) { fail(e.getMessage()); } } //Bug 406805 - [1.8] Parameter names for enum constructor not available // https://bugs.eclipse.org/bugs/show_bug.cgi?id=406805 public void test406805() throws CoreException, IOException { String contents1 = "package test406805;\n" + "public class X {\n" + "}"; createFolder("/Converter18/src/test406805"); createFile("/Converter18/src/test406805/X.java", contents1); this.workingCopy = getWorkingCopy( "/Converter18/src/test406805/X.java", contents1, true ); String jarName = "getParameters.jar"; String srcName = "getParameters_src.zip"; final IJavaProject javaProject = this.workingCopy.getJavaProject(); try { String[] contents = new String[] { "TestEnum.java", "package test406805;\n" + "public enum TestEnum {\n" + " FirstValue(\"Zonk\") {\n" + " @Override\n" + " public String toString() {\n" + " return super.toString();\n" + " }\n" + " },\n" + " SecondValue(\"Bla\");\n" + " String string;\n" + " TestEnum(String string) {\n" + " this.string = string;\n" + " }\n" + "}" }; addLibrary(javaProject, jarName, srcName, contents, JavaCore.VERSION_1_8); ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setIgnoreMethodBodies(true); parser.setProject(javaProject); IType type = javaProject.findType("test406805.TestEnum"); IBinding[] bindings = parser.createBindings(new IJavaElement[] { type }, null); ITypeBinding typeBinding = (ITypeBinding) bindings[0]; IMethodBinding[] methods = typeBinding.getDeclaredMethods(); for (int i = 0, length = methods.length; i < length; i++) { IMethodBinding method = methods[i]; if (method.isConstructor()) { ResolvedBinaryMethod bm = (ResolvedBinaryMethod) method.getJavaElement(); assertTrue(bm.getParameterNames().length == 1); assertEquals(bm.getParameterNames()[0], "string"); assertEquals(bm.getParameterTypes()[0], "Ljava.lang.String;"); } } } finally { removeLibrary(javaProject, jarName, srcName); } } //Bug 406805 - [1.8] Parameter names for enum constructor not available //https://bugs.eclipse.org/bugs/show_bug.cgi?id=406805 //Nested Enum Constructor public void test406805a() throws CoreException, IOException { String contents1 = "package test406805;\n" + "public class X {\n" + "}"; createFolder("/Converter18/src/test406805a"); createFile("/Converter18/src/test406805a/X.java", contents1); this.workingCopy = getWorkingCopy( "/Converter18/src/test406805a/X.java", contents1, true ); String jarName = "getParameters.jar"; String srcName = "getParameters_src.zip"; final IJavaProject javaProject = this.workingCopy.getJavaProject(); try { String[] contents = new String[] { "NestedTestEnum.java", "package test406805a;\n" + "public class NestedTestEnum {\n" + " public enum TestEnum {\n" + " FirstValue(\"Zonk\") {\n" + " @Override\n" + " public String toString() {\n" + " return super.toString();\n" + " }\n" + " },\n" + " SecondValue(\"Bla\");\n" + " String string;\n" + " TestEnum(String string) {\n" + " this.string = string;\n" + " }\n" + "}\n" + "}" }; addLibrary(javaProject, jarName, srcName, contents, JavaCore.VERSION_1_8, null); ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setIgnoreMethodBodies(true); parser.setProject(javaProject); IType type = javaProject.findType("test406805a.NestedTestEnum"); IBinding[] bindings = parser.createBindings(new IJavaElement[] { type }, null); ITypeBinding typeBinding = (ITypeBinding) bindings[0]; typeBinding = typeBinding.getDeclaredTypes()[0]; IMethodBinding[] methods = typeBinding.getDeclaredMethods(); for (int i = 0, length = methods.length; i < length; i++) { IMethodBinding method = methods[i]; if (method.isConstructor()) { ResolvedBinaryMethod bm = (ResolvedBinaryMethod) method.getJavaElement(); assertTrue(bm.getParameterNames().length == 1); } } } finally { removeLibrary(javaProject, jarName, srcName); } } //Bug 406805 - [1.8] Parameter names for enum constructor not available //https://bugs.eclipse.org/bugs/show_bug.cgi?id=406805 //Parameterized enum constructor. public void test406805b() throws CoreException, IOException { String contents1 = "package test406805b;\n" + "public class X {\n" + "}"; createFolder("/Converter18/src/test406805b"); createFile("/Converter18/src/test406805b/X.java", contents1); this.workingCopy = getWorkingCopy( "/Converter18/src/test406805b/X.java", contents1, true ); String jarName = "getParameters.jar"; String srcName = "getParameters_src.zip"; final IJavaProject javaProject = this.workingCopy.getJavaProject(); try { String[] contents = new String[] { "TestEnum.java", "package test406805b;\n" + "interface A<T> {}\n" + "\n" + "class Y {\n" + " static A<String> A1;\n" + "}\n" + "public enum TestEnum implements A<String> {\n" + " FirstValue(Y.A1);\n" + " A<String> xyzabcdef;\n" + " TestEnum(A<String> abcdefghi) {\n" + " this.xyzabcdef = abcdefghi;\n" + " }\n" + " int SecondValue() { return 0;}\n" + "}\n" }; addLibrary(javaProject, jarName, srcName, contents, JavaCore.VERSION_1_8); ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setIgnoreMethodBodies(true); parser.setProject(javaProject); IType type = javaProject.findType("test406805b.TestEnum"); IBinding[] bindings = parser.createBindings(new IJavaElement[] { type }, null); ITypeBinding typeBinding = (ITypeBinding) bindings[0]; IMethodBinding[] methods = typeBinding.getDeclaredMethods(); for (int i = 0, length = methods.length; i < length; i++) { IMethodBinding method = methods[i]; if (method.isConstructor()) { ResolvedBinaryMethod bm = (ResolvedBinaryMethod) method.getJavaElement(); assertTrue(bm.getParameterNames().length == 1); } } } finally { removeLibrary(javaProject, jarName, srcName); } } //Bug 406805 - [1.8] Parameter names for enum constructor not available //https://bugs.eclipse.org/bugs/show_bug.cgi?id=406805 //Testing types and names of parameters. public void test406805d() throws CoreException, IOException { String contents1 = "package test406805;\n" + "public class X {\n" + "}"; createFolder("/Converter18/src/test406805d"); createFile("/Converter18/src/test406805d/X.java", contents1); this.workingCopy = getWorkingCopy( "/Converter18/src/test406805d/X.java", contents1, true ); String jarName = "getParameters.jar"; String srcName = "getParameters_src.zip"; final IJavaProject javaProject = this.workingCopy.getJavaProject(); try { String[] contents = new String[] { "NestedTestEnum.java", "package test406805d;\n" + "public class NestedTestEnum {\n" + " public enum TestEnum {\n" + " FirstValue(\"Zonk\", 1) {\n" + " @Override\n" + " public String toString() {\n" + " return super.toString();\n" + " }\n" + " },\n" + " SecondValue(\"Bla\", 2);\n" + " String string;\n" + " int xyz;\n" + " TestEnum(String string, int xyz) {\n" + " this.string = string;\n" + " this.xyz = xyz;\n" + " }\n" + "}\n" + "}" }; addLibrary(javaProject, jarName, srcName, contents, JavaCore.VERSION_1_8, null); ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setIgnoreMethodBodies(true); parser.setProject(javaProject); IType type = javaProject.findType("test406805d.NestedTestEnum"); IBinding[] bindings = parser.createBindings(new IJavaElement[] { type }, null); ITypeBinding typeBinding = (ITypeBinding) bindings[0]; typeBinding = typeBinding.getDeclaredTypes()[0]; IMethodBinding[] methods = typeBinding.getDeclaredMethods(); for (int i = 0, length = methods.length; i < length; i++) { IMethodBinding method = methods[i]; if (method.isConstructor()) { ResolvedBinaryMethod bm = (ResolvedBinaryMethod) method.getJavaElement(); String[] parameterNames = bm.getParameterNames(); assertTrue(parameterNames.length == 2); assertEquals(parameterNames[0], "string"); assertEquals(parameterNames[1], "xyz"); String[] parameterTypes = bm.getParameterTypes(); assertEquals(parameterTypes[0], "Ljava.lang.String;"); assertEquals(parameterTypes[1], "I"); } } } finally { removeLibrary(javaProject, jarName, srcName); } } //Bug 436347 - Regression: NegativeArraySizeException at org.eclipse.jdt.internal.core.ClassFileInfo.generateMethodInfos //https://bugs.eclipse.org/bugs/show_bug.cgi?id=436347 //Enum constructor with no parameters. public void test436347() throws CoreException, IOException { String contents1 = "package test436347;\n" + "public class X {\n" + "}"; createFolder("/Converter18/src/test436347"); createFile("/Converter18/src/test436347/X.java", contents1); this.workingCopy = getWorkingCopy( "/Converter18/src/test436347/X.java", contents1, true ); String jarName = "getParameters.jar"; String srcName = "getParameters_src.zip"; final IJavaProject javaProject = this.workingCopy.getJavaProject(); try { String[] contents = new String[] { "TestEnum.java", "package test436347;\n" + "public enum TestEnum {\n" + " FirstValue() {\n" + " @Override\n" + " public String toString() {\n" + " return super.toString();\n" + " }\n" + " },\n" + " SecondValue();\n" + " TestEnum() {\n" + " return;\n" + " }\n" + "}" }; addLibrary(javaProject, jarName, srcName, contents, JavaCore.VERSION_1_8); ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setIgnoreMethodBodies(true); parser.setProject(javaProject); IType type = javaProject.findType("test436347.TestEnum"); IBinding[] bindings = parser.createBindings(new IJavaElement[] { type }, null); ITypeBinding typeBinding = (ITypeBinding) bindings[0]; IMethodBinding[] methods = typeBinding.getDeclaredMethods(); for (int i = 0, length = methods.length; i < length; i++) { IMethodBinding method = methods[i]; if (method.isConstructor()) { ResolvedBinaryMethod bm = (ResolvedBinaryMethod) method.getJavaElement(); assertTrue(bm.getParameterNames().length == 0); assertTrue(bm.getParameterTypes().length == 0); } } } finally { removeLibrary(javaProject, jarName, srcName); } } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=433879, org.eclipse.jdt.internal.compiler.lookup.ArrayBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding //@throws ClassCastException without the fix //Array type access in catch block. Test case picked up from the bug. public void testBug433879() throws JavaModelException { String contents = "package Bug433879;\r\n"+ "public class X {\n" + "Class<? extends Exception>[] exceptions;\n" + " void foo() {\n" + " try {\n" + " // some stuff here\n" + " } catch (exceptions[0] e) {\n" + " // some more stuff here\n" + " }\n" + " }\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/Bug433879/X.java", true/*computeProblems*/); try { buildAST(AST.JLS8, contents, this.workingCopy, false, true, true); } catch (ClassCastException e) { fail(e.getMessage()); } } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=433879, org.eclipse.jdt.internal.compiler.lookup.ArrayBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding //@throws ClassCastException without the fix //Simplified version of the test case picked up from the bug report. public void testBug433879a() throws JavaModelException { String contents = "package Bug433879a;\n"+ "public class X {\n" + " void foo() {\n" + " try {\n" + " // some stuff here\n" + " } catch (A[0] e) {\n" + " // some more stuff here\n" + " }\n" + " }\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/Bug433879a/X.java", true/*computeProblems*/); try { buildAST(AST.JLS8, contents, this.workingCopy, false, true, true); } catch (ClassCastException e) { fail(e.getMessage()); } } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=433879, org.eclipse.jdt.internal.compiler.lookup.ArrayBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding //Catch parameters Union Type public void testBug433879b() throws JavaModelException { String contents = "package Bug433879c;\n"+ "public class X {\n" + " void foo() {\n" + " try {\n" + " // some stuff here\n" + " } catch (A[0] | B[0] e) {\n" + " // some more stuff here\n" + " }\n" + " }\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/Bug433879c/X.java", true/*computeProblems*/); try { buildAST(AST.JLS8, contents, this.workingCopy, false, true, true); } catch (ClassCastException e) { fail(e.getMessage()); } } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=433879, org.eclipse.jdt.internal.compiler.lookup.ArrayBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding //@throws ClassCastException without the fix //Catch parameters union type. Multiple Catch handlers. public void testBug433879c() throws JavaModelException { String contents = "package Bug433879d;\n"+ "class E1 extends Exception {private static final long serialVersionUID = 1L;}\n" + "class E2 extends Exception { private static final long serialVersionUID = 1L;}\n" + "\n" + "\n" + "public class X {\n" + " Class<? extends Exception>[] exceptions;\n" + " void foo() {\n" + " try {\n" + " bar();\n" + " } catch (exceptions[0] e) {\n" + " } catch (E1 | E2 eU) {}\n" + " }\n" + " private void bar() throws E1, E2 {}\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/Bug433879d/X.java", true/*computeProblems*/); try { buildAST(AST.JLS8, contents, this.workingCopy, false, true, true); } catch (ClassCastException e) { fail(e.getMessage()); } } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=433879, org.eclipse.jdt.internal.compiler.lookup.ArrayBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding //@throws ClassCastException without the fix //Multiple Catch handlers. public void testBug433879d() throws JavaModelException { String contents = "package Bug433879e;\n"+ "class E1 extends Exception {private static final long serialVersionUID = 1L;}\n" + "class E2 extends Exception { private static final long serialVersionUID = 1L;}\n" + "public class X {\n" + " Class<? extends Exception>[] exceptions;\n" + " Class<? extends Exception>[] exceptions2;\n" + " void foo() {\n" + " try {\n" + " bar();\n" + " } catch (E2 e2) {\n" + " } catch (exceptions[0] e) {\n" + " } catch (E1 e1) {\n" + " } catch (exceptions2[0] e) {\n" + " }\n" + " }\n" + " private void bar() throws E1, E2 {}\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/Bug433879e/X.java", true/*computeProblems*/); try { buildAST(AST.JLS8, contents, this.workingCopy, false, true, true); } catch (ClassCastException e) { fail(e.getMessage()); } } public void testBug432175() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/testBug432175/X.java", true/* resolve */); String contents = "package testBug432175;\n" + "interface Collection <T> {}\n" + "class Collections {\n" + " public static final <T> T emptyList() { return null; }\n" + "}\n" + "public class X {\n" + " public static <T extends Number & Comparable<?>> void method2(Collection<T> coll) {}\n" + "\n" + " public static void main(String[] args) {\n" + " method2(Collections.emptyList());\n" + " }\n" + "}\n" ; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typeDeclaration = (TypeDeclaration) getASTNode(cu, 2); MethodDeclaration [] methods = typeDeclaration.getMethods(); { MethodDeclaration method = methods[1]; ExpressionStatement expressionStatement = (ExpressionStatement) method.getBody().statements().get(0); MethodInvocation methodInvocation = (MethodInvocation) expressionStatement.getExpression(); methodInvocation = (MethodInvocation) methodInvocation.arguments().get(0); ITypeBinding typeBinding = methodInvocation.resolveTypeBinding(); typeBinding = typeBinding.getTypeArguments()[0]; String res = typeBinding.getTypeDeclaration().getName(); this.ast.newSimpleType(this.ast.newName(res)); } } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=435348, [1.8][compiler] NPE in JDT Core during AST creation // NPE without fix public void testBug435348() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/testBug435348/X.java", true/* resolve */); String contents = "package testBug435348;\n" + "class Y {}\n" + "class Z{}\n" + "class X {\n" + " void bar2(@ Z z) {}\n" + " // ^ Illegal @ \n" + " static {\n" + " bar(new Y() {});\n" + " }\n" + "}\n"; buildAST(contents, this.workingCopy, false); } public void testBug432614() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/testBug432614/X.java", true); String contents = "package testBug432614;\n" + "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.Target;\n" + "public class X {\n" + " FI fi1= (@T2 int i) -> {};\n" + "}\n" + "interface FI {\n" + " void foo(@T1 int iii);\n" + "}\n" + "@Target(ElementType.TYPE_USE) @interface T1 {}\n" + "@Target(ElementType.TYPE_USE) @interface T2 {}"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 0); FieldDeclaration fieldDeclaration = (FieldDeclaration) typedeclaration.bodyDeclarations().get(0); VariableDeclarationFragment fragment = (VariableDeclarationFragment)fieldDeclaration.fragments().get(0); Expression expression = fragment.getInitializer(); assertTrue(expression instanceof LambdaExpression); LambdaExpression lambdaExpression = (LambdaExpression)expression; assertEquals("(@T2 int i) -> {\n}\n", lambdaExpression.toString()); assertTrue(lambdaExpression.parameters().size() == 1); IMethodBinding binding = lambdaExpression.resolveMethodBinding(); ITypeBinding[] params = binding.getParameterTypes(); assertEquals("Incorrect no of parameters", 1, params.length); ITypeBinding thatParam = params[0]; assertEquals("Incorrect param", "@T2 int", thatParam.toString()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=447062 * * @throws JavaModelException */ public void testBug447062() throws JavaModelException { String contents = "public class X {\n" + " Runnable foo = () -> {\n" + " \n" + " }\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/test447062/X.java", contents, true/*computeProblems*/); IJavaProject javaProject = this.workingCopy.getJavaProject(); class BindingRequestor extends ASTRequestor { ITypeBinding _result = null; public void acceptBinding(String bindingKey, IBinding binding) { if (this._result == null && binding != null && binding.getKind() == IBinding.TYPE) this._result = (ITypeBinding) binding; } } final BindingRequestor requestor = new BindingRequestor(); final ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setResolveBindings(false); parser.setProject(javaProject); parser.setIgnoreMethodBodies(true); try { parser.createASTs(new ICompilationUnit[] {this.workingCopy}, new String[0], requestor, null); } catch (IllegalArgumentException e) { assertTrue("Test Failed", false); } } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=399793 * * @throws JavaModelException */ public void testBug425601_001() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/testBug425601_001/Outer.java", true/* resolve */); String contents = "package testBug425601_001;\n" + "@Deprecated\n"+ "public class Outer<O> {\n"+ " @Deprecated\n"+ " public class Middle<X> {\n"+ " @Deprecated\n"+ " public class Inner<E> {\n"+ " }\n"+ " }\n"+ " \n"+ " Outer<String> o;\n"+ " Middle<String> m; // Middle should be deprecated - Middle Case one\n"+ " Outer<String>.Middle<String> m2; // Middle should be deprecated - Middle Case Two \n"+ " @SuppressWarnings(\"rawtypes\")"+ " Outer.Middle m3; \n"+ " Middle<String>.Inner<Object> i; // Inner should be deprecated - Inner Case One\n"+ "}\n"+ "class Ref {\n"+ " Outer<String> o;\n"+ " Outer<String>.Middle<String> m;\n"+ " Outer<String>.Middle<String>.Inner<Object> i;\n"+ "}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 0); FieldDeclaration[] fields = typedeclaration.getFields(); ITypeBinding binding = fields[0].getType().resolveBinding(); assertTrue(binding.isDeprecated()); binding = fields[3].getType().resolveBinding(); assertTrue(binding.isDeprecated()); binding = fields[1].getType().resolveBinding(); // Middle Case One assertTrue(binding.isDeprecated()); binding = fields[2].getType().resolveBinding(); // Middle Case Two assertTrue(binding.isDeprecated()); binding = fields[4].getType().resolveBinding(); // Inner Case One assertTrue(binding.isDeprecated()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=399793 * * @throws JavaModelException */ public void testBug425601_002() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/testBug425601_002/Outer.java", true/* resolve */); String contents = "package testBug425601_002;\n" + //"@Deprecated\n"+ "public class Outer<O> {\n"+ " @Deprecated\n"+ " public class Middle<X> {\n"+ " @Deprecated\n"+ " public class Inner<E> {\n"+ " }\n"+ " }\n"+ " \n"+ " Outer<String> o;\n"+ " Middle<String> m; // Middle should be deprecated - Middle Case one\n"+ " Outer<String>.Middle<String> m2; // Middle should be deprecated - Middle Case Two \n"+ " @SuppressWarnings(\"rawtypes\")"+ " Outer.Middle m3; \n"+ " Middle<String>.Inner<Object> i; // Inner should be deprecated - Inner Case One\n"+ "}\n"+ "class Ref {\n"+ " Outer<String> o;\n"+ " Outer<String>.Middle<String> m;\n"+ " Outer<String>.Middle<String>.Inner<Object> i;\n"+ "}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 0); FieldDeclaration[] fields = typedeclaration.getFields(); ITypeBinding binding = fields[0].getType().resolveBinding(); assertTrue(!binding.isDeprecated()); binding = fields[3].getType().resolveBinding(); assertTrue(binding.isDeprecated()); binding = fields[1].getType().resolveBinding(); // Middle Case One assertTrue(binding.isDeprecated()); binding = fields[2].getType().resolveBinding(); // Middle Case Two assertTrue(binding.isDeprecated()); binding = fields[4].getType().resolveBinding(); // Inner Case One assertTrue(binding.isDeprecated()); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=44000 * * @bug Bug 440000 [1.8][dom] MethodReference#resolveMethodBinding() API should return null for CreationReference of an ArrayType * @throws JavaModelException */ public void testBug440000_001() throws JavaModelException { String contents = "interface I<T, R> {\n" + " R apply(T t);\n" + "}\n" + "public class X {\n" + " I<Integer, int[]> m1 = int[]::new;\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", contents, true/*computeProblems*/); CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 1); FieldDeclaration fieldDeclaration = (FieldDeclaration) typedeclaration.bodyDeclarations().get(0); VariableDeclarationFragment fragment = (VariableDeclarationFragment)fieldDeclaration.fragments().get(0); Expression expression = fragment.getInitializer(); assertTrue(expression instanceof CreationReference); CreationReference creationReference = (CreationReference) expression; assertEquals("int[]::new", creationReference.toString()); IMethodBinding binding = creationReference.resolveMethodBinding(); assertNull(binding); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=459344 * * @throws JavaModelException */ public void testBug459344_001() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test459344/X.java", true/* resolve */); String contents = "package test459344;" + "interface I {\n" + " int foo();\n" + "}\n" + "public class X {\n" + " private void foo(Object arg) {\n" + " I i = arg :: hashCode;\n" + " }\n" + "}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typeDeclaration = (TypeDeclaration) getASTNode(cu, 1); MethodDeclaration methodDeclaration = typeDeclaration.getMethods()[0]; VariableDeclarationStatement stmt = (VariableDeclarationStatement) methodDeclaration.getBody().statements().get(0); VariableDeclarationFragment fragment = (VariableDeclarationFragment) stmt.fragments().get(0); ExpressionMethodReference reference = (ExpressionMethodReference) fragment.getInitializer(); IMethodBinding methodBinding = reference.resolveMethodBinding(); assertNotNull(methodBinding); assertEquals("Wrong name", "hashCode", methodBinding.getName()); assertNull("Non-Null",cu.findDeclaringNode(methodBinding)); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=460186 * @bug Bug 460186 IAE in ASTNode.setSourceRange with broken code case 2 * @throws JavaModelException */ public void testBug460186() throws JavaModelException { String contents = "class Foo {\n" + " void foo()\n {" + " foo();[]\n" + " }\n" + "}"; this.workingCopy = getWorkingCopy("/Converter18/src/test460186/NPE.java", contents, false/*computeProblems*/); IJavaProject javaProject = this.workingCopy.getJavaProject(); final ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setResolveBindings(false); parser.setProject(javaProject); parser.setIgnoreMethodBodies(false); ASTRequestor requestor = new ASTRequestor() {}; parser.createASTs(new ICompilationUnit[] {this.workingCopy}, new String[0], requestor, null); // Implicitly check that no exception is thrown by createASTs. } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=443232 * @bug Bug 443232 IAE in ASTNode.setSourceRange with broken code * @throws JavaModelException */ public void testBug443232() throws JavaModelException { String contents = "package test443232;\n" + "public class E21 {\n" + " {private int[] nums;\n" + " void foo() {\n" + " nums\n" + " }\n" + "}"; this.workingCopy = getWorkingCopy("/Converter18/src/test443232/E21.java", contents, false/*computeProblems*/); IJavaProject javaProject = this.workingCopy.getJavaProject(); final ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setResolveBindings(false); parser.setProject(javaProject); parser.setIgnoreMethodBodies(false); ASTRequestor requestor = new ASTRequestor() {}; try { parser.createASTs(new ICompilationUnit[] {this.workingCopy}, new String[0], requestor, null); } catch (IllegalArgumentException e) { assertTrue("Test Failed", false); } } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=429813 * * @throws JavaModelException */ public void test429813() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test429813/Snippet.java", true/* resolve */); String contents = "package test429813;" + "public class Snippet {\n" + " Function<Integer, int[]> m1L = n -> new int[n];\n" + "}" + "interface Function<T, R> {\n" + " public R apply(T t);\n" + "}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 0); FieldDeclaration fieldDeclaration = (FieldDeclaration) typedeclaration.bodyDeclarations().get(0); VariableDeclarationFragment fragment = (VariableDeclarationFragment)fieldDeclaration.fragments().get(0); Expression expression = fragment.getInitializer(); assertTrue(expression instanceof LambdaExpression); LambdaExpression lambdaExpression = (LambdaExpression)expression; IMethodBinding binding = lambdaExpression.resolveMethodBinding(); IJavaElement element = binding.getJavaElement(); assertEquals("Not a method", IJavaElement.METHOD, element.getElementType()); assertFalse("Should not be a synthetic", binding.isSynthetic()); } public void test429813a() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter18/src/test429813/Snippet.java", true/* resolve */); String contents = "package test429813;" + "interface FTest {\n" + " Object foo (int[]... ints);\n" + "};" + "class TestX {" + " FTest fi= ints -> null;\n" + "}\n"; CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy); TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 1); FieldDeclaration fieldDeclaration = (FieldDeclaration) typedeclaration.bodyDeclarations().get(0); VariableDeclarationFragment fragment = (VariableDeclarationFragment)fieldDeclaration.fragments().get(0); Expression expression = fragment.getInitializer(); assertTrue(expression instanceof LambdaExpression); LambdaExpression lambdaExpression = (LambdaExpression)expression; IMethodBinding binding = lambdaExpression.resolveMethodBinding(); assertTrue("Should be a varargs", binding.isVarargs()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=399792 public void testBug470794_001() throws JavaModelException { String content = "public class X {\n" + " Object o = (I & J) () -> {};" + " public K main(Object o) {\n" + " K oo = (I & J & K) o;\n" + " return oo;\n" + " }\n" + "}\n" + "interface I {\n" + " public void foo();\n" + "}\n" + "interface J {\n" + " public void foo();\n" + " public default void bar() {}\n" + "}\n" + "interface K {\n" + " public void foo();\n" + " public void bar();\n" + "}\n"; this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true); ASTNode node = buildAST(content, this.workingCopy, true); assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit unit = (CompilationUnit) node; TypeDeclaration type = (TypeDeclaration) unit.types().get(0); node = (ASTNode) type.bodyDeclarations().get(0); assertEquals("Not a field Declaration", ASTNode.FIELD_DECLARATION, node.getNodeType()); FieldDeclaration field = (FieldDeclaration) node; assertEquals("Field should not be malformed", 0, (field.getFlags() & ASTNode.MALFORMED)); List fragments = field.fragments(); assertEquals("Incorrect no of fragments", 1, fragments.size()); VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(0); CastExpression cast = (CastExpression) fragment.getInitializer(); Type castType = cast.getType(); assertEquals("Not an intersection cast type", ASTNode.INTERSECTION_TYPE, castType.getNodeType()); assertTrue("Not an intersection cast type", castType.isIntersectionType()); assertEquals("Type should not be malformed", 0, (castType.getFlags() & ASTNode.MALFORMED)); ITypeBinding binding = castType.resolveBinding(); assertNotNull("binding is null", binding); assertTrue("Not an intersection type binding", binding.isIntersectionType()); { ITypeBinding [] intersectionBindings = binding.getTypeBounds(); String[] expectedTypes = new String[]{"I", "J"}; assertTrue("Incorrect number of intersection bindings", intersectionBindings.length == expectedTypes.length); for (int i = 0, l = intersectionBindings.length; i < l; ++i) { assertTrue("Unexpected Intersection Type", expectedTypes[i].equals(intersectionBindings[i].getName())); } } node = (ASTNode) type.bodyDeclarations().get(1); assertEquals("Not a method Declaration", ASTNode.METHOD_DECLARATION, node.getNodeType()); MethodDeclaration method = (MethodDeclaration) node; assertEquals("Method should not be malformed", 0, (method.getFlags() & ASTNode.MALFORMED)); List statements = method.getBody().statements(); VariableDeclarationStatement statement = (VariableDeclarationStatement) statements.get(0); fragment = (VariableDeclarationFragment) statement.fragments().get(0); cast = (CastExpression) fragment.getInitializer(); castType = cast.getType(); binding = castType.resolveBinding(); assertNotNull("binding is null", binding); assertTrue("Not an intersection type binding", binding.isIntersectionType()); { ITypeBinding [] intersectionBindings = binding.getTypeBounds(); String[] expectedTypes = new String[]{"I", "J", "K"}; assertTrue("Incorrect number of intersection bindings", intersectionBindings.length == expectedTypes.length); for (int i = 0, l = intersectionBindings.length; i < l; ++i) { assertTrue("Unexpected Intersection Type", expectedTypes[i].equals(intersectionBindings[i].getName())); } } } }