/******************************************************************************* * Copyright (c) 2004, 2015 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 - Contributions for * Bug 463330 - [dom] DOMFinder doesn't find the VariableBinding corresponding to a method argument * Bug 464463 - [dom] DOMFinder doesn't find an ITypeParameter * Bug 464615 - [dom] ASTParser.createBindings() ignores parameterization of a method invocation * Bug 466279 - [hovering] IAE on hover when annotation-based null analysis is enabled *******************************************************************************/ package org.eclipse.jdt.core.tests.dom; import java.io.File; import java.io.IOException; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.*; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.dom.*; import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.core.tests.model.AbstractJavaSearchTests; import org.eclipse.jdt.core.tests.util.Util; import junit.framework.Test; /* * Test the bridge between the DOM AST and the Java model. */ public class ASTModelBridgeTests extends AbstractASTTests { ICompilationUnit workingCopy; /** * Internal synonym for deprecated constant AST.JSL3 * to alleviate deprecation warnings. * @deprecated */ /*package*/ static final int JLS3_INTERNAL = AST.JLS3; protected void checkSourceRange(int start, int length, String expectedContents, String source) { assertTrue("length == 0", length != 0); //$NON-NLS-1$ //$NON-NLS-2$ assertTrue("start == -1", start != -1); //$NON-NLS-1$ String actualContentsString = source.substring(start, start + length); assertSourceEquals("Unexpected source", Util.convertToIndependantLineDelimiter(expectedContents), Util.convertToIndependantLineDelimiter(actualContentsString)); } public ASTModelBridgeTests(String name) { super(name); } public static Test suite() { return buildModelTestSuite(ASTModelBridgeTests.class); } // Use this static initializer to specify subset for tests // All specified tests which do not belong to the class are skipped... static { // TESTS_PREFIX = "testBug86380"; // TESTS_NAMES = new String[] { "testLocalVariable7" }; // TESTS_NUMBERS = new int[] { 83230 }; // TESTS_RANGE = new int[] { 83304, -1 }; } private void assertFindElement(String key, String expectedElement) throws JavaModelException { IJavaElement element = getJavaProject("P").findElement(key, this.workingCopy.getOwner()); assertElementEquals( "Unexpected found element", expectedElement, element ); } /* * Removes the marker comments "*start*" and "*end*" from the given contents, * builds an AST from the resulting source, and returns the AST node that was delimited * by "*start*" and "*end*". */ private ASTNode buildAST(String contents) throws JavaModelException { return buildAST(contents, this.workingCopy); } /* * Removes the marker comments "*start*" and "*end*" from the given contents, * builds an AST from the resulting source, gets the binding from the AST node that was delimited * by "*start*" and "*end*", and returns the binding key. */ private String buildBindingKey(String contents) throws JavaModelException { ASTNode node = buildAST(contents); if (node == null) return null; IBinding binding = resolveBinding(node); if (binding == null) return null; return binding.getKey(); } private IBinding[] createBindings(String contents, IJavaElement element) throws JavaModelException { this.workingCopy.getBuffer().setContents(contents); this.workingCopy.makeConsistent(null); ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setProject(getJavaProject("P")); IJavaElement[] elements = new IJavaElement[] {element}; return parser.createBindings(elements, null); } private IBinding[] createBinaryBindings(String contents, IJavaElement element) throws CoreException { createClassFile("/P/lib", "A.class", contents); ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setProject(getJavaProject("P")); IJavaElement[] elements = new IJavaElement[] {element}; return parser.createBindings(elements, null); } public void setUpSuite() throws Exception { super.setUpSuite(); setUpJavaProject(); } private void setUpJavaProject() throws CoreException, IOException, JavaModelException { IJavaProject project = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB,JCL15_SRC", "/P/lib"}, "bin", "1.5"); project.setOption(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.IGNORE); project.setOption(JavaCore.COMPILER_PB_UNUSED_PRIVATE_MEMBER, JavaCore.IGNORE); project.setOption(JavaCore.COMPILER_PB_FIELD_HIDING, JavaCore.IGNORE); project.setOption(JavaCore.COMPILER_PB_LOCAL_VARIABLE_HIDING, JavaCore.IGNORE); project.setOption(JavaCore.COMPILER_PB_TYPE_PARAMETER_HIDING, JavaCore.IGNORE); project.setOption(JavaCore.COMPILER_PB_RAW_TYPE_REFERENCE, JavaCore.IGNORE); addLibrary( project, "lib.jar", "libsrc.zip", new String[] { "p/Y.java", "package p;\n" + "public class Y<T> {\n" + " public Y(T t) {\n" + " }\n" + "}", "p/Z.java", "package p;\n" + "public class Z {\n" + " /*start*/class Member {\n" + " }/*end*/\n" + " void foo() {\n" + " new Member() {};\n" + " }\n" + "}", "p/W.java", "package p;\n" + "public class W {\n" + " class Member {\n" + " /*start*/Member(String s) {\n" + " }/*end*/\n" + " }\n" + "}", "p/ABC.java", "package p;\n" + "public class ABC {\n" + "}", "Z.java", "public class Z {\n" + " /*start*/class Member {\n" + " }/*end*/\n" + " void foo() {\n" + " new Member() {};\n" + " }\n" + "}", "p/Q.java", "package p;\n" + "/*start*/@MyAnnot/*end*/\n" + "public class Q {\n" + "}\n" + "@interface MyAnnot {\n" + "}", }, "1.5"); setUpWorkingCopy(); } private void setUpWorkingCopy() throws JavaModelException { if (this.workingCopy != null) this.workingCopy.discardWorkingCopy(); IProblemRequestor problemRequestor = new IProblemRequestor() { public void acceptProblem(IProblem problem) {} public void beginReporting() {} public void endReporting() {} public boolean isActive() { return true; } }; this.workingCopy = getCompilationUnit("/P/src/X.java").getWorkingCopy( newWorkingCopyOwner(problemRequestor), null/*no progress*/); } public void tearDownSuite() throws Exception { tearDownJavaProject(); super.tearDownSuite(); } private void tearDownJavaProject() throws JavaModelException, CoreException { if (this.workingCopy != null) this.workingCopy.discardWorkingCopy(); deleteProject("P"); } /* * Ensures that the IJavaElement of an IBinding representing an annotation is correct. */ public void testAnnotation1() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " /*start*/@MyAnnot/*end*/\n" + " void foo() {\n" + " }\n" + "}\n" + "@interface MyAnnot {\n" + "}" ); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "@MyAnnot [in foo() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing an annotation is correct. */ public void testAnnotation2() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " /*start*/@MyAnnot/*end*/\n" + " int field;\n" + "}\n" + "@interface MyAnnot {\n" + "}" ); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "@MyAnnot [in field [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing an annotation is correct. */ public void testAnnotation3() throws JavaModelException { ASTNode node = buildAST( "/*start*/@MyAnnot/*end*/\n" + "public class X {\n" + "}\n" + "@interface MyAnnot {\n" + "}" ); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "@MyAnnot [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing an annotation is correct. */ public void testAnnotation4() throws JavaModelException { ICompilationUnit myAnnot = null; ICompilationUnit packageInfo = null; try { WorkingCopyOwner owner = this.workingCopy.getOwner(); myAnnot = getCompilationUnit("/P/src/pkg/MyAnnot.java").getWorkingCopy(owner, null); myAnnot.getBuffer().setContents( "package pkg;\n" + "public @interface MyAnnot {\n" + "}" ); myAnnot.makeConsistent(null); packageInfo = getCompilationUnit("/P/src/pkg/package-info.java").getWorkingCopy(owner, null); ASTNode node = buildAST( "/*start*/@MyAnnot/*end*/\n" + "package pkg;", packageInfo ); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "@MyAnnot [in package pkg [in [Working copy] package-info.java [in pkg [in src [in P]]]]]", element ); } finally { if (myAnnot != null) myAnnot.discardWorkingCopy(); if (packageInfo != null) packageInfo.discardWorkingCopy(); } } /* * Ensures that the IJavaElement of an IBinding representing an annotation is correct. */ public void testAnnotation5() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " void foo() {\n" + " /*start*/@MyAnnot/*end*/\n" + " int var1 = 2;\n" + " }\n" + "}\n" + "@interface MyAnnot {\n" + "}" ); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "@MyAnnot [in var1 [in foo() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing an annotation on an annotation type is correct. * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=249844 ) */ public void testAnnotation6() throws JavaModelException { ASTNode node = buildAST( "/*start*/@MyAnnot/*end*/\n" + "public @interface X {\n" + "}\n" + "@interface MyAnnot {\n" + "}" ); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "@MyAnnot [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing an annotation on an enum type is correct. * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=249844 ) */ public void testAnnotation7() throws JavaModelException { ASTNode node = buildAST( "/*start*/@MyAnnot/*end*/\n" + "public enum X {\n" + "}\n" + "@interface MyAnnot {\n" + "}" ); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "@MyAnnot [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing an annotation of a binary member type is correct. */ public void testAnnotation8() throws Exception { IClassFile classFile = getClassFile("P", "/P/lib.jar", "p", "Q.class"); ASTNode node = buildAST(classFile); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "@p.MyAnnot [in Q [in Q.class [in p [in lib.jar [in P]]]]]", element ); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=328969 public void testAnnotation9() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + "/*start*/@MyAnnot/*end*/ void foo() throws MissingException {}\n" + "}\n" + "@interface MyAnnot {\n" + "}", this.workingCopy, false, true, false ); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); assertNull("Got a java element", binding.getJavaElement()); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=328969 public void testAnnotation10() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + "/*start*/@MyAnnot/*end*/ MissingType foo;\n" + "}\n" + "@interface MyAnnot {\n" + "}", this.workingCopy, false, true, false ); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); assertNull("Got a java element", binding.getJavaElement()); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=328969 public void testAnnotation11() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + "/*start*/@MyAnnot/*end*/ void foo() throws MissingException {}\n" + "}\n" + "@interface MyAnnot {\n" + "}", this.workingCopy, false, true, true ); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "@MyAnnot [in foo() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]]", element ); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=328969 public void testAnnotation12() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + "/*start*/@MyAnnot/*end*/ MissingType foo;\n" + "}\n" + "@interface MyAnnot {\n" + "}", this.workingCopy, false, true, true ); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "@MyAnnot [in foo [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]]", element ); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=328969 public void testAnnotation13() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " void bar() {\n" + " /*start*/@MyAnnot/*end*/ MissingType foo;\n" + " }\n" + "}\n" + "@interface MyAnnot {\n" + "}", this.workingCopy, false, true, false ); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); assertNull("Got a java element", binding.getJavaElement()); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=328969 public void testAnnotation14() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " void bar() {\n" + " /*start*/@MyAnnot/*end*/ MissingType foo;\n" + " }\n" + "}\n" + "@interface MyAnnot {\n" + "}", this.workingCopy, false, true, true ); IBinding binding = ((Annotation) node).resolveAnnotationBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "@MyAnnot [in foo [in bar() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]]]", element ); } /* * Ensures that the correct IBindings can be retrieved from an AST * (parameter annotation) */ public void testAnnotation15() throws Exception { createFolder("/P/src/lib"); createFile("/P/src/lib/NonNull.java", "package lib;\n" + "import java.lang.annotation.*;\n" + "@Target(ElementType.PARAMETER)\n" + "public @interface NonNull{}\n"); createFile("/P/src/lib/Foo.java", "package lib;\n" + "public class Foo {\n" + " public <T> void bug1(@NonNull T x) { return; }\n" + " public static <T> void bug2(@NonNull String x) { return; }\n" + "}\n"); String barSource = "import lib.Foo;\n" + "public class Bar {\n" + " void m() { new Foo().bug1(\"x\"); Foo.bug2(\"x\"); }\n" + "}\n"; this.workingCopies = new ICompilationUnit[2]; this.workingCopies[1] = getWorkingCopy("/P/src/Bar.java", barSource, this.wcOwner); ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setProject(getJavaProject("P")); parser.setSource(this.workingCopies[1]); parser.setResolveBindings(true); ASTNode send = NodeFinder.perform(parser.createAST(null), barSource.indexOf("bug1"), 0).getParent(); IBinding[] bindings = new IBinding[] { ((MethodInvocation) send).resolveMethodBinding() }; assertBindingsEqual( "Llib/Foo;.bug1<T:Ljava/lang/Object;>(TT;)V%<Ljava/lang/String;>", bindings); IMethodBinding method = (IMethodBinding) bindings[0]; assertBindingsEqual( "@Llib/NonNull;", method.getParameterAnnotations(0)); } /* * Ensures that the IJavaElement of an IBinding representing an anonymous type is correct. */ public void testAnonymousType() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " Object foo() {\n" + " return new Object() /*start*/{\n" + " }/*end*/;\n" + " }\n" + "}" ); IBinding binding = ((AnonymousClassDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "<anonymous #1> [in foo() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]]", element ); } public void testAnonymousType2() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " public void foo() {\n" + " new Y(0/*c*/) /*start*/{\n" + " Object field;\n" + " }/*end*/;\n" + " }\n" + "}\n" + "class Y {\n" + " Y(int i) {\n" + " }\n" + "}" ); IBinding binding = ((AnonymousClassDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "<anonymous #1> [in foo() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing an array type is correct. */ public void testArrayType1() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " /*start*/Object[]/*end*/ field;\n" + "}" ); IBinding binding = ((ArrayType) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "Object [in Object.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing an array type of base type null. * (regression test for bug 100142 CCE when calling ITypeBinding#getJavaElement() on char[][] */ public void testArrayType2() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " /*start*/char[][]/*end*/ field;\n" + "}" ); IBinding binding = ((ArrayType) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "<null>", element ); } /* * Ensures that the IJavaElement of an IBinding representing a method coming from a class file is correct. * (regression test for bug 91445 IMethodBinding.getJavaElement() returns an "unopen" IMethod) */ public void testBinaryMethod() throws JavaModelException { IClassFile classFile = getClassFile("P", getExternalJCLPathString("1.5"), "java.lang", "Enum.class"); String source = classFile.getSource(); MarkerInfo markerInfo = new MarkerInfo(source); markerInfo.astStarts = new int[] {source.indexOf("protected Enum")}; markerInfo.astEnds = new int[] {source.indexOf('}', markerInfo.astStarts[0]) + 1}; ASTNode node = buildAST(markerInfo, classFile); IBinding binding = ((MethodDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "Enum(java.lang.String, int) [in Enum [in Enum.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a constructor of a binary member type is correct. * (regression test for bug 119249 codeResolve, search, etc. don't work on constructor of binary inner class) */ public void testBinaryMemberTypeConstructor() throws JavaModelException { IClassFile classFile = getClassFile("P", "/P/lib.jar", "p", "W$Member.class"); ASTNode node = buildAST(classFile); IBinding binding = ((MethodDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "Member(p.W, java.lang.String) [in Member [in W$Member.class [in p [in lib.jar [in P]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a type coming from a class file is correct. */ public void testBinaryType() throws JavaModelException { IClassFile classFile = getClassFile("P", getExternalJCLPathString("1.5"), "java.lang", "String.class"); String source = classFile.getSource(); MarkerInfo markerInfo = new MarkerInfo(source); markerInfo.astStarts = new int[] {source.indexOf("public")}; markerInfo.astEnds = new int[] {source.lastIndexOf('}') + 1}; ASTNode node = buildAST(markerInfo, classFile); IBinding binding = ((TypeDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "String [in String.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a type coming from a class file is correct * after searching for references to this type. * (regression test for bug 136016 [refactoring] CCE during Use Supertype refactoring) */ public void testBinaryType2() throws CoreException { IClassFile classFile = getClassFile("P", "lib.jar", "p", "ABC.class"); // class with no references // ensure classfile is open classFile.open(null); //search for references to p.ABC after adding references in exactly 1 file try { createFile( "/P/src/Test.java", "import p.ABC;\n" + "public class Test extends ABC {\n" + "}" ); IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] {getPackageFragmentRoot("/P/src")}); search(classFile.getType(), IJavaSearchConstants.REFERENCES, scope, new AbstractJavaSearchTests.JavaSearchResultCollector()); } finally { deleteFile("/P/src/Test.java"); } String source = classFile.getSource(); MarkerInfo markerInfo = new MarkerInfo(source); markerInfo.astStarts = new int[] {source.indexOf("public")}; markerInfo.astEnds = new int[] {source.lastIndexOf('}') + 1}; ASTNode node = buildAST(markerInfo, classFile); IBinding binding = ((TypeDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "ABC [in ABC.class [in p [in lib.jar [in P]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a type in a jar is correct after deleting the first project * referencing it. */ public void testBinaryType3() throws CoreException, IOException { // force String to be put in the jar cache buildAST( "public class X {\n" + " /*start*/String/*end*/ field;\n" + "}" ); try { tearDownJavaProject(); createJavaProject("P1", new String[] {""}, new String[] {"JCL15_LIB"}, "", "1.5"); createFile( "/P1/X.java", "public class X {\n" + " /*start*/String/*end*/ field;\n" + "}" ); ASTNode node = buildAST(getCompilationUnit("/P1/X.java")); IBinding binding = ((Type) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "String [in String.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]", element ); } finally { deleteProject("P1"); setUpJavaProject(); } } /* * Ensures that the IJavaElement for a binary member type coming from an anoumous class file is correct. * (regression test for bug 100636 [model] Can't find overriden methods of protected nonstatic inner class.) */ public void testBinaryMemberTypeFromAnonymousClassFile1() throws JavaModelException { IClassFile classFile = getClassFile("P", "/P/lib.jar", "p", "Z$1.class"); ASTNode node = buildAST(classFile); IBinding binding = ((TypeDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "Member [in Z$Member.class [in p [in lib.jar [in P]]]]", element ); } /* * Ensures that the IJavaElement for a binary member type coming from an anoumous class file is correct. * (regression test for bug 100636 [model] Can't find overriden methods of protected nonstatic inner class.) */ public void testBinaryMemberTypeFromAnonymousClassFile2() throws JavaModelException { IClassFile classFile = getClassFile("P", "/P/lib.jar", "", "Z$1.class"); ASTNode node = buildAST(classFile); IBinding binding = ((TypeDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "Member [in Z$Member.class [in <default> [in lib.jar [in P]]]]", element ); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (test several kinds of elements) */ public void testCreateBindings01() throws JavaModelException { ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setResolveBindings(true); parser.setProject(getJavaProject("P")); WorkingCopyOwner owner = new WorkingCopyOwner() {}; this.workingCopies = new ICompilationUnit[3]; this.workingCopies[0] = getWorkingCopy( "/P/src/X.java", "public class X {\n" + " public void foo(int i, String s) {\n" + " }\n" + "}", owner ); this.workingCopies[1] = getWorkingCopy( "/P/src/Y.java", "public class Y extends X {\n" + " void bar() {\n" + " new Y() {};\n" + " }\n" + "}", owner ); this.workingCopies[2] = getWorkingCopy( "/P/src/I.java", "public interface I {\n" + " int BAR;\n" + "}", owner ); IType typeX = this.workingCopies[0].getType("X"); IJavaElement[] elements = new IJavaElement[] { typeX, getClassFile("P", getExternalJCLPathString("1.5"), "java.lang", "Object.class").getType(), typeX.getMethod("foo", new String[] {"I", "QString;"}), this.workingCopies[2].getType("I").getField("BAR"), this.workingCopies[1].getType("Y").getMethod("bar", new String[0]).getType("", 1) }; IBinding[] bindings = parser.createBindings(elements, null); assertBindingsEqual( "LX;\n" + "Ljava/lang/Object;\n" + "LX;.foo(ILjava/lang/String;)V\n" + "LI;.BAR)I\n" + "LY$50;", bindings); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=297757 */ public void testCreateBindings23() throws JavaModelException { ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setProject(getJavaProject("P")); WorkingCopyOwner owner = new WorkingCopyOwner() {}; this.workingCopies = new ICompilationUnit[3]; this.workingCopies[0] = getWorkingCopy( "/P/src/p/IScriptRunnable.java", "package p;\n" + "public interface IScriptRunnable<V, E extends Exception> {\n" + " public V run(Object cx, Object scope) throws E;\n" + "}", owner ); this.workingCopies[1] = getWorkingCopy( "/P/src/p/Environment.java", "package p;\n" + "public interface Environment {\n" + " public <V, E extends Exception> V execute(IScriptRunnable<V, E> code) throws E;\n" + "}", owner ); this.workingCopies[2] = getWorkingCopy( "/P/src/X.java", "import p.*;\n" + "public class X {\n" + " p.Environment env;\n" + " private void test() {\n" + " env.execute(new IScriptRunnable<Object, RuntimeException>() {\n" + " public Object run(Object cx, Object scope) throws RuntimeException {\n" + " return null;\n" + " }\n" + " });\n" + " }\n" + "}", owner ); IJavaElement[] elements = new IJavaElement[] { this.workingCopies[0].getType("IScriptRunnable"), this.workingCopies[1].getType("Environment"), this.workingCopies[2].getType("X").getMethod("test", new String[0]).getType("", 1) }; IBinding[] bindings = parser.createBindings(elements, null); assertBindingsEqual( "Lp/IScriptRunnable<TV;TE;>;\n" + "Lp/Environment;\n" + "LX$90;", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (top level type) */ public void testCreateBindings02() throws JavaModelException { IBinding[] bindings = createBindings( "public class X {\n" + "}", this.workingCopy.getType("X") ); assertBindingsEqual( "LX;", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (member type) */ public void testCreateBindings03() throws JavaModelException { IBinding[] bindings = createBindings( "public class X {\n" + " public class Member {\n" + " }\n" + "}", this.workingCopy.getType("X").getType("Member") ); assertBindingsEqual( "LX$Member;", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (anonymous type) */ public void testCreateBindings04() throws JavaModelException { IBinding[] bindings = createBindings( "public class X {\n" + " void foo() {\n" + " new X() {\n" + " };\n" + " }\n" + "}", this.workingCopy.getType("X").getMethod("foo", new String[0]).getType("", 1) ); assertBindingsEqual( "LX$40;", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (local type) */ public void testCreateBindings05() throws JavaModelException { IBinding[] bindings = createBindings( "public class X {\n" + " void foo() {\n" + " class Y {\n" + " }\n" + " }\n" + "}", this.workingCopy.getType("X").getMethod("foo", new String[0]).getType("Y", 1) ); assertBindingsEqual( "LX$42$Y;", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (field) */ public void testCreateBindings06() throws JavaModelException { IBinding[] bindings = createBindings( "public class X {\n" + " int field;\n" + "}", this.workingCopy.getType("X").getField("field") ); assertBindingsEqual( "LX;.field)I", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (method) */ public void testCreateBindings07() throws JavaModelException { IBinding[] bindings = createBindings( "public class X {\n" + " void foo() {}\n" + "}", this.workingCopy.getType("X").getMethod("foo", new String[0]) ); assertBindingsEqual( "LX;.foo()V", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (annotation declaration) */ public void testCreateBindings08() throws JavaModelException { IBinding[] bindings = createBindings( "@interface X {\n" + "}", this.workingCopy.getType("X") ); assertBindingsEqual( "LX;", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (enum declaration) */ public void testCreateBindings09() throws JavaModelException { IBinding[] bindings = createBindings( "public enum X {\n" + "}", this.workingCopy.getType("X") ); assertBindingsEqual( "LX;", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (annotation member declaration) */ public void testCreateBindings10() throws JavaModelException { IBinding[] bindings = createBindings( "@interface X {\n" + " int foo();\n" + "}", this.workingCopy.getType("X").getMethod("foo", new String[0]) ); assertBindingsEqual( "LX;.foo()I", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (enum constant) */ public void testCreateBindings11() throws JavaModelException { IBinding[] bindings = createBindings( "public enum X {\n" + " FOO;\n" + "}", this.workingCopy.getType("X").getField("FOO") ); assertBindingsEqual( "LX;.FOO)LX;", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (import) */ public void testCreateBindings12() throws JavaModelException { IBinding[] bindings = createBindings( "import java.io.*;\n" + "public class X implements Serializable {\n" + " static final long serialVersionUID = 0;\n" + "}", this.workingCopy.getImport("java.io.*") ); assertBindingsEqual( "java/io", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (import) */ public void testCreateBindings13() throws JavaModelException { IBinding[] bindings = createBindings( "import java.io.Serializable;\n" + "public class X implements Serializable {\n" + " static final long serialVersionUID = 0;\n" + "}", this.workingCopy.getImport("java.io.Serializable") ); assertBindingsEqual( "Ljava/io/Serializable;", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (type parameter) */ public void testCreateBindings14() throws JavaModelException { IBinding[] bindings = createBindings( "public class X<T> {\n" + "}", this.workingCopy.getType("X").getTypeParameter("T") ); assertBindingsEqual( "LX;:TT;", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (type parameter with bound) */ public void testCreateBindings14a() throws JavaModelException { IBinding[] bindings = createBindings( "public class X<T extends java.lang.Number> {\n" + "}", this.workingCopy.getType("X").getTypeParameter("T") ); assertBindingsEqual( "LX;:TT;", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (type parameter with parameterized bound) */ public void testCreateBindings14b() throws JavaModelException { IBinding[] bindings = createBindings( "public class X<T extends java.util.List<String>> {\n" + "}", this.workingCopy.getType("X").getTypeParameter("T") ); assertBindingsEqual( "LX;:TT;", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (binary type) */ public void testCreateBindings15() throws CoreException { IBinding[] bindings = createBinaryBindings( "public class A {\n" + "}", getClassFile("/P/lib/A.class").getType() ); assertBindingsEqual( "LA;", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (binary field) */ public void testCreateBindings16() throws CoreException { IBinding[] bindings = createBinaryBindings( "public class A {\n" + " int field;\n" + "}", getClassFile("/P/lib/A.class").getType().getField("field") ); assertBindingsEqual( "LA;.field)I", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (binary method) */ public void testCreateBindings17() throws CoreException { IBinding[] bindings = createBinaryBindings( "public class A {\n" + " int foo(String s, boolean b) {\n" + " return -1;\n" + " }\n" + "}", getClassFile("/P/lib/A.class").getType().getMethod("foo", new String[] {"Ljava.lang.String;", "Z"}) ); assertBindingsEqual( "LA;.foo(Ljava/lang/String;Z)I", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (binary method) * (regression test for bug 122650 ASTParser.createBindings(IJavaElement[]) returns wrong element) */ public void testCreateBindings18() throws CoreException { IBinding[] bindings = createBinaryBindings( "public class A {\n" + " <E> void foo(E e) {\n" + " }\n" + "}", getClassFile("/P/lib/A.class").getType().getMethod("foo", new String[] {"TE;"}) ); assertBindingsEqual( "LA;.foo<E:Ljava/lang/Object;>(TE;)V", bindings); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=160637 */ public void testCreateBindings19() throws CoreException { IBinding[] bindings = createBinaryBindings( "public class A {\n" + " String foo(String s) {\n" + " return null;\n" + " }\n" + "}", getClassFile("/P/lib/A.class").getType().getMethod("foo", new String[] {"Ljava.lang.String;"}) ); assertBindingsEqual( "LA;.foo(Ljava/lang/String;)Ljava/lang/String;", bindings); } /* * Ensures that the correct IBinding is created for an IField starting with a 'L' * (regression test for 205860 ASTParser.createBindings() returns [null]) */ public void testCreateBindings20() throws CoreException { IField field = getClassFile("/P/lib/A.class").getType().getField("LINE"); IBinding[] bindings = createBinaryBindings( "public class A {\n" + " static int LINE = 0;\n" + "}", field ); assertBindingsEqual( "LA;.LINE)I", bindings); } /* * Ensures that the correct IBinding is created for an IField starting with a 'T' * (regression test for 205860 ASTParser.createBindings() returns [null]) */ public void testCreateBindings21() throws CoreException { IField field = getClassFile("/P/lib/A.class").getType().getField("THREE"); IBinding[] bindings = createBinaryBindings( "public class A {\n" + " static int THREE = 0;\n" + "}", field ); assertBindingsEqual( "LA;.THREE)I", bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (annotation) */ public void testCreateBindings22() throws JavaModelException { IBinding[] bindings = createBindings( "@MyAnnot\n" + "public class X {\n" + "}\n" + "@interface MyAnnot {\n" + "}", this.workingCopy.getType("X").getAnnotation("MyAnnot") ); assertBindingsEqual( "LX;@LX~MyAnnot;", bindings); } /* * Ensures that the correct IBinding is created for package-info.class's IType */ public void testCreateBindings24() throws CoreException { createClassFile( "/P/lib", "pack/package-info.class", "@Deprecated\n" + "package pack;"); IJavaProject javaProject = getJavaProject("P"); IPackageFragment pack = javaProject.findPackageFragment(new Path("/P/lib/pack")); IType type = pack.getClassFile("package-info.class").getType(); ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setProject(javaProject); IJavaElement[] elements = new IJavaElement[] {type}; IBinding[] bindings = parser.createBindings(elements, null); assertBindingsEqual( "Lpack/package-info;", bindings); IAnnotationBinding[] annotations = ((ITypeBinding) bindings[0]).getAnnotations(); assertBindingsEqual( "@Ljava/lang/Deprecated;", annotations); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (method arguments) */ public void testCreateBindings25() throws JavaModelException { this.workingCopy.getBuffer().setContents( "public class X {\n" + " void foo(String str, int i) {}\n" + "}"); this.workingCopy.makeConsistent(null); IMethod method = this.workingCopy.getType("X").getMethod("foo", new String[]{"QString;", "I"}); ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setProject(getJavaProject("P")); IBinding[] bindings = parser.createBindings(method.getParameters(), null); assertBindingsEqual( "LX;.foo(Ljava/lang/String;I)V#str#0#0\n" + // occurrence 0, rank 0 "LX;.foo(Ljava/lang/String;I)V#i#0#1", // occurrence 0, rank 1 bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (binary method arguments) */ public void testCreateBindings26() throws CoreException { createClassFile("/P/lib", "A.class", "public class A {\n" + " void foo(String str, int i) {}\n" + "}"); IMethod method = getClassFile("/P/lib/A.class").getType().getMethod("foo", new String[] {"Ljava.lang.String;", "I"}); ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setProject(getJavaProject("P")); IBinding[] bindings = parser.createBindings(method.getParameters(), null); assertBindingsEqual( "LA;.foo(Ljava/lang/String;I)V#str#0#0\n" + // occurrence 0, rank 0 "LA;.foo(Ljava/lang/String;I)V#i#0#1", // occurrence 0, rank 1 bindings); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (invocation of a generic method - binary) */ public void testCreateBinding27() throws Exception { createClassFile("/P/lib", "p/A.class", "package p;\n" + "public class A {\n" + " public static <T> T foo(T[] arg) { return arg[0]; }\n" + "}"); this.workingCopies = new ICompilationUnit[1]; String xSource = "public class X {\n" + " public String test(String[] args) {\n" + " return p.A.foo(args);\n" + " }\n" + "}"; this.workingCopies[0] = getWorkingCopy( "/P/src/X.java", xSource, this.wcOwner ); IJavaElement elem= this.workingCopies[0].codeSelect(xSource.indexOf("foo"), 0)[0]; ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setProject(getJavaProject("P")); IBinding[] bindings = parser.createBindings(new IJavaElement[]{ elem }, null); assertBindingsEqual( "Lp/A;.foo<T:Ljava/lang/Object;>([TT;)TT;%<Ljava/lang/String;>", bindings); IMethodBinding method = (IMethodBinding) bindings[0]; assertBindingsEqual( "[Ljava/lang/String;", method.getParameterTypes()); assertBindingsEqual( "Ljava/lang/String;", new IBinding[] {method.getReturnType()}); } /* * Ensures that the correct IBindings are created for a given set of IJavaElement * (method parameter - binary) */ public void testCreateBinding28() throws Exception { IJavaProject javaProject = getJavaProject("P"); String codeGenOption = javaProject.getOption(JavaCore.COMPILER_LOCAL_VARIABLE_ATTR, true); try { javaProject.setOption(JavaCore.COMPILER_LOCAL_VARIABLE_ATTR, JavaCore.DISABLED); createClassFile("/P/lib", "p/A.class", "package p;\n" + "public class A {\n" + " public static <T> T foo(int i, boolean f) { return null; }\n" + "}"); IType typeA = javaProject.findType("p.A"); IJavaElement[] elems= typeA.getMethod("foo", new String[]{"I", "Z"}).getParameters(); ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setProject(javaProject); IBinding[] bindings = parser.createBindings(elems, null); assertBindingsEqual( "Lp/A;.foo<T:Ljava/lang/Object;>(IZ)TT;#arg0#0#0\n" + "Lp/A;.foo<T:Ljava/lang/Object;>(IZ)TT;#arg1#0#1", bindings); IVariableBinding param1 = (IVariableBinding) bindings[0]; IVariableBinding param2 = (IVariableBinding) bindings[1]; assertBindingsEqual( "I\n" + "Z", new IBinding[] { param1.getType(), param2.getType()}); } finally { javaProject.setOption(JavaCore.COMPILER_LOCAL_VARIABLE_ATTR, codeGenOption); } } /* * Ensures that the IJavaElement of an IBinding representing a field is correct. */ public void testField1() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " Object /*start*/field/*end*/;\n" + "}" ); IBinding binding = ((VariableDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "field [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a field is correct. */ public void testField2() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " Object foo() {\n" + " return new Object() {\n" + " Object /*start*/field/*end*/;\n" + " };\n" + " }\n" + "}" ); IBinding binding = ((VariableDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "field [in <anonymous #1> [in foo() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]]]", element ); } /* * Ensures that an IType can be found using its binding key. */ public void testFindElement01() throws JavaModelException { String bindingKey = buildBindingKey( "/*start*/public class X {\n" + "}/*end*/" ); assertFindElement( bindingKey, "X [in [Working copy] X.java [in <default> [in src [in P]]]]" ); } /* * Ensures that an IMethod can be found using its binding key. */ public void testFindElement02() throws JavaModelException { String bindingKey = buildBindingKey( "public class X {\n" + " /*start*/void foo() {\n" + " }/*end*/\n" + "}" ); assertFindElement( bindingKey, "foo() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]" ); } /* * Ensures that an IField can be found using its binding key. */ public void testFindElement03() throws JavaModelException { String bindingKey = buildBindingKey( "public class X {\n" + " int /*start*/field/*end*/;\n" + "}" ); assertFindElement( bindingKey, "field [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]" ); } /* * Ensures that a member IType can be found using its binding key. */ public void testFindElement04() throws JavaModelException { String bindingKey = buildBindingKey( "public class X {\n" + " /*start*/class Member {\n" + " }/*end*/\n" + "}" ); assertFindElement( bindingKey, "Member [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]" ); } /* * Ensures that a local IType can be found using its binding key. */ public void testFindElement05() throws JavaModelException { String bindingKey = buildBindingKey( "public class X {\n" + " void foo() {\n" + " /*start*/class Local {\n" + " }/*end*/\n" + " }\n" + "}" ); assertFindElement( bindingKey, "Local [in foo() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]]" ); } /* * Ensures that an anonymous IType can be found using its binding key. */ public void testFindElement06() throws JavaModelException { String bindingKey = buildBindingKey( "public class X {\n" + " void foo() {\n" + " new X() /*start*/{\n" + " }/*end*/;\n" + " }\n" + "}" ); assertFindElement( bindingKey, "<anonymous #1> [in foo() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]]" ); } /* * Ensures that a secondary IType can be found using its binding key. */ public void testFindElement07() throws JavaModelException { String bindingKey = buildBindingKey( "public class X {\n" + "}\n" + "/*start*/class Secondary {\n" + "}/*end*/" ); assertFindElement( bindingKey, "Secondary [in [Working copy] X.java [in <default> [in src [in P]]]]" ); } /* * Ensures that an IAnnotation can be found using its binding key. */ public void testFindElement08() throws JavaModelException { String bindingKey = buildBindingKey( "/*start*/@MyAnnot/*end*/\n" + "public class X {\n" + "}\n" + "@interface MyAnnot {\n" + "}" ); assertFindElement( bindingKey, "@MyAnnot [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]" ); } /* * Ensures that an IPackageFragment can be found using its binding key. */ public void testFindElement09() throws JavaModelException { String bindingKey = buildBindingKey( "public class X {\n" + " /*start*/java.lang/*end*/.String field;\n" + "}" ); assertFindElement( bindingKey, "java.lang [in "+ getExternalJCLPathString("1.5") + "]" ); } /* * Ensures that an ITypeParameter can be found using its binding key. */ public void testFindElement10() throws JavaModelException { String bindingKey = buildBindingKey( "public class X</*start*/T/*end*/> {\n" + "}" ); assertFindElement( bindingKey, "<T> [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]" ); } /* * Ensures that a binary top level IType can be found using its binding key. */ public void testFindElement11() throws JavaModelException { String bindingKey = getClassFile("/P/lib.jar/p/Y.class").getType().getKey(); assertFindElement( bindingKey, "Y [in Y.class [in p [in lib.jar [in P]]]]" ); } /* * Ensures that a binary member IType can be found using its binding key. */ public void testFindElement12() throws JavaModelException { String bindingKey = getClassFile("/P/lib.jar/p/Z$Member.class").getType().getKey(); assertFindElement( bindingKey, "Member [in Z$Member.class [in p [in lib.jar [in P]]]]" ); } /* * Ensures that a binary anonymous IType can be found using its binding key. */ public void testFindElement13() throws JavaModelException { String bindingKey = getClassFile("/P/lib.jar/p/Z$1.class").getType().getKey(); assertFindElement( bindingKey, "Z$1.class [in p [in lib.jar [in P]]]" ); } /* * Ensures that the IJavaElement of an IBinding representing a local type is correct. */ public void testLocalType() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " void foo() {\n" + " /*start*/class Y {\n" + " }/*end*/\n" + " }\n" + "}" ); IBinding binding = ((TypeDeclarationStatement) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "Y [in foo() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a local type * and coming from a binding key resolution is correct. */ public void testLocalType2() throws CoreException { String filePath = "/P/src/Z.java"; try { String contents = "public class Z {\n" + " void foo() {\n" + " /*start*/class Local {\n" + " }/*end*/\n" + " }\n" + "}"; createFile(filePath, contents); // Get the binding key ASTNode node = buildAST(contents, getCompilationUnit(filePath)); IBinding binding = ((TypeDeclarationStatement) node).resolveBinding(); String bindingKey = binding.getKey(); // Resolve the binding key BindingRequestor requestor = new BindingRequestor(); String[] bindingKeys = new String[] {bindingKey}; resolveASTs( new ICompilationUnit[] {}, bindingKeys, requestor, getJavaProject("P"), this.workingCopy.getOwner() ); IBinding[] bindings = requestor.getBindings(bindingKeys); // Ensure the Java element is correct IJavaElement element = bindings[0].getJavaElement(); assertElementExists( "Unexpected Java element", "Local [in foo() [in Z [in Z.java [in <default> [in src [in P]]]]]]", element ); } finally { deleteFile(filePath); } } /* * Ensures that the IJavaElement of an IBinding representing a local variable is correct. * (regression test for bug 79610 IVariableBinding#getJavaElement() returns null for local variables) */ public void testLocalVariable1() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " void foo() {\n" + " int /*start*/local/*end*/;\n" + " }\n" + "}" ); IBinding binding = ((VariableDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); IJavaElement expected = getLocalVariable(this.workingCopy, "local", "local"); assertEquals( "Unexpected Java element", expected, element ); } /* * Ensures that the IJavaElement of an IBinding representing a local variable is correct. * (regression test for bug 79610 IVariableBinding#getJavaElement() returns null for local variables) */ public void testLocalVariable2() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " void foo() {\n" + " Object first, /*start*/second/*end*/, third;\n" + " }\n" + "}" ); IBinding binding = ((VariableDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); IJavaElement expected = getLocalVariable(this.workingCopy, "second", "second"); assertEquals( "Unexpected Java element", expected, element ); } /* * Ensures that the IJavaElement of an IBinding representing a local variable is correct. * (regression test for bug 80021 [1.5] CCE in VariableBinding.getJavaElement()) */ public void testLocalVariable3() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " void foo(/*start*/int arg/*end*/) {\n" + " }\n" + "}" ); IBinding binding = ((VariableDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); IJavaElement expected = getLocalVariable(this.workingCopy, "arg", "arg"); assertEquals( "Unexpected Java element", expected, element ); } /* * Ensures that the IJavaElement of an IBinding representing a local variable in an anonymous type * in a discarded working copy is null. * (regression test for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=212096 ) */ public void testLocalVariable4() throws JavaModelException { try { ASTNode node = buildAST( "public class X {\n" + " void foo() {\n" + " new Object() {\n" + " void bar() {\n" + " int /*start*/local/*end*/;\n" + " }\n" + " };\n" + " }\n" + "}" ); IBinding binding = ((VariableDeclaration) node).resolveBinding(); this.workingCopy.discardWorkingCopy(); IJavaElement element = binding.getJavaElement(); assertEquals( "Unexpected Java element", null, element ); } finally { setUpWorkingCopy(); } } /* * Ensures that the IJavaElement of an IBinding representing a local variable in an initializer is correct. * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=217287 ) */ public void testLocalVariable5() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " {\n" + " int /*start*/local/*end*/;\n" + " }\n" + "}" ); IBinding binding = ((VariableDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); IJavaElement expected = getLocalVariable(this.workingCopy, "local", "local"); assertEquals( "Unexpected Java element", expected, element ); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=48420 */ public void testLocalVariable6() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " {\n" + " int local;\n" + " }\n" + " public void foo() {\n" + " int i = 0;\n" + " }\n" + " public static void foo(final int n) {\n" + " int i;\n" + " }\n" + " public X(final int j) {\n" + " int i;\n" + " }\n" + "}" ); node.accept(new ASTVisitor() { public boolean visit(VariableDeclarationFragment fragment) { final IVariableBinding binding = fragment.resolveBinding(); final IJavaElement javaElement = binding.getJavaElement(); assertNotNull("No java element", javaElement); final int type = javaElement.getElementType(); assertEquals("Wrong type", IJavaElement.LOCAL_VARIABLE, type); ILocalVariable variable = (ILocalVariable) javaElement; final ITypeRoot typeRoot = variable.getTypeRoot(); assertNotNull("Not type root", typeRoot); assertTrue("Invalid", typeRoot.exists()); assertNotNull("No declaring element", variable.getDeclaringMember()); int flags = variable.getFlags(); assertFalse("wrong modifier for " + variable.getElementName(), Flags.isFinal(flags)); assertFalse("wrong value for isParameter" + variable.getElementName(), variable.isParameter()); return true; } public boolean visit(SingleVariableDeclaration variableDeclaration) { final IVariableBinding binding = variableDeclaration.resolveBinding(); final IJavaElement javaElement = binding.getJavaElement(); assertNotNull("No java element", javaElement); final int type = javaElement.getElementType(); assertEquals("Wrong type", IJavaElement.LOCAL_VARIABLE, type); ILocalVariable variable = (ILocalVariable) javaElement; final ITypeRoot typeRoot = variable.getTypeRoot(); assertNotNull("Not type root", typeRoot); assertTrue("Invalid", typeRoot.exists()); assertNotNull("No declaring element", variable.getDeclaringMember()); int flags = variable.getFlags(); assertTrue("wrong modifier for " + variable.getElementName(), Flags.isFinal(flags)); assertTrue("wrong value for isParameter" + variable.getElementName(), variable.isParameter()); return true; } }); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=368646 */ public void testLocalVariable7() throws JavaModelException { final String source = "public class X {\n" + " public void m(String strX) {\n" + " String strB = strX;\n" + " }\n" + "}"; ASTNode node = buildAST(source); final boolean[] checked = new boolean[1]; node.accept(new ASTVisitor() { public boolean visit(VariableDeclarationFragment fragment) { final IVariableBinding binding = fragment.resolveBinding(); final IJavaElement javaElement = binding.getJavaElement(); assertNotNull("No java element", javaElement); final int type = javaElement.getElementType(); assertEquals("Wrong type", IJavaElement.LOCAL_VARIABLE, type); ILocalVariable variable = (ILocalVariable) javaElement; ISourceRange range = variable.getNameRange(); checkSourceRange(range.getOffset(), range.getLength(), "strB", source); try { range = variable.getSourceRange(); checkSourceRange(range.getOffset(), range.getLength(), "String strB = strX;", source); } catch(JavaModelException e) { assertTrue("failed to retrieve the source range", false); } checked[0] = true; return true; } }); assertTrue("Not checked", checked[0]); } /* * Ensures that the IJavaElement of an IBinding representing a member type is correct. */ public void testMemberType() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " /*start*/class Y {\n" + " }/*end*/\n" + "}" ); IBinding binding = ((TypeDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementEquals( "Unexpected Java element", "Y [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); assertTrue("Element should exist", element.exists()); } /* * Ensures that the IJavaElement of an IBinding representing a method is correct. */ public void testMethod01() throws JavaModelException { ASTNode node = buildAST( "public class X<K, V> {\n" + " /*start*/void foo(int i, Object o, java.lang.String s, Class[] c, X<K, V> x) {\n" + " }/*end*/\n" + "}" ); IBinding binding = ((MethodDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "foo(int, Object, java.lang.String, Class[], X<K,V>) [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a method is correct. */ public void testMethod02() throws JavaModelException { ASTNode node = buildAST( "public class X<K, V> {\n" + " /*start*/void foo() {\n" + " }/*end*/\n" + "}" ); IBinding binding = ((MethodDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "foo() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a method is correct. * (regression test for bug 78757 MethodBinding.getJavaElement() returns null) */ public void testMethod03() throws JavaModelException { ICompilationUnit otherWorkingCopy = null; try { otherWorkingCopy = getWorkingCopy( "/P/src/Y.java", "public class Y {\n" + " void foo(int i, String[] args, java.lang.Class clazz) {}\n" + "}", this.workingCopy.getOwner() ); ASTNode node = buildAST( "public class X {\n" + " void bar() {\n" + " Y y = new Y();\n" + " /*start*/y.foo(1, new String[0], getClass())/*end*/;\n" + " }\n" + "}" ); IBinding binding = ((MethodInvocation) node).resolveMethodBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "foo(int, String[], java.lang.Class) [in Y [in [Working copy] Y.java [in <default> [in src [in P]]]]]", element ); } finally { if (otherWorkingCopy != null) otherWorkingCopy.discardWorkingCopy(); } } /* * Ensures that the IJavaElement of an IBinding representing a method is correct. * (regression test for bug 81258 IMethodBinding#getJavaElement() is null with inferred method parameterization) */ public void testMethod04() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " void foo() {\n" + " /*start*/bar(new B<Object>())/*end*/;\n" + " }\n" + " <T extends Object> void bar(A<? extends T> arg) {\n" + " }\n" + "}\n" + "class A<T> {\n" + "}\n" + "class B<T> extends A<T> { \n" + "}" ); IBinding binding = ((MethodInvocation) node).resolveMethodBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "bar(A<? extends T>) [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a parameterized method is correct. * (regression test for bug 82382 IMethodBinding#getJavaElement() for method m(T t) in parameterized type Gen<T> is null) */ public void testMethod05() throws JavaModelException { ASTNode node = buildAST( "public class X<T> {\n" + " void m(T t) { }\n" + "}\n" + "\n" + "class Y {\n" + " {\n" + " /*start*/new X<String>().m(\"s\")/*end*/;\n" + " }\n" + "}" ); IBinding binding = ((MethodInvocation) node).resolveMethodBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "m(T) [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a method inside an annotation is correct. * (regression test for bug 83300 [1.5] ClassCastException in #getJavaElement() on binding of annotation element) */ public void testMethod06() throws JavaModelException { ASTNode node = buildAST( "@X(/*start*/value/*end*/=\"Hello\", count=-1)\n" + "@interface X {\n" + " String value();\n" + " int count();\n" + "}" ); IBinding binding = ((SimpleName) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "value() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a method with array parameters is correct. * (regression test for bug 88769 IMethodBinding#getJavaElement() drops extra array dimensions and varargs */ public void testMethod07() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " /*start*/public int[] bar(int a[]) {\n" + " return a;\n" + " }/*end*/\n" + "}" ); IBinding binding = ((MethodDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "bar(int[]) [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a method with array parameters is correct. * (regression test for bug 88769 IMethodBinding#getJavaElement() drops extra array dimensions and varargs */ public void testMethod08() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " /*start*/public Object[] bar2(Object[] o[][]) [][] {\n" + " return o;\n" + " }/*end*/\n" + "}" ); IBinding binding = ((MethodDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "bar2(Object[][][]) [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a method with varargs parameters is correct. * (regression test for bug 88769 IMethodBinding#getJavaElement() drops extra array dimensions and varargs */ public void testMethod09() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " /*start*/public void bar3(Object... objs) {\n" + " }/*end*/\n" + "}" ); IBinding binding = ((MethodDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "bar3(Object[]) [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } /* * Ensures that getting the IJavaElement of an IBinding representing a method in an anonymous type * doesn't throw a ClassCastException if there is a syntax error. * (regression test for bug 149853 CCE in IMethodBinding#getJavaElement() for recovered anonymous type) */ public void testMethod10() throws CoreException { try { // use a compilation unit instead of a working copy to use the ASTParser instead of reconcile createFile( "/P/src/Test.java", "public class X {\n" + " void test() {\n" + " new Object() {\n" + " /*start*/public void yes() {\n" + " System.out.println(\"hello world\");\n" + " }/*end*/\n" + " } // missing semicolon;\n" + " }\n" + "}" ); ICompilationUnit cu = getCompilationUnit("/P/src/Test.java"); ASTNode node = buildAST(null/*use existing contents*/, cu, false/*don't report errors*/, true/*statement recovery*/, false); IBinding binding = ((MethodDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "yes() [in <anonymous #1> [in test() [in X [in Test.java [in <default> [in src [in P]]]]]]]", element ); } finally { deleteFile("/P/src/Test.java"); } } /* * Ensures that no ClassCastException is thrown if the method is in an anonymous * which is inside the initializer of another anonymous. * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=208013) */ public void testMethod11() throws JavaModelException { ASTNode node = buildAST( "public class X {\n" + " public void foo() {\n" + " new Object() {\n" + " Object o;\n" + " {\n"+ " new Object() {\n" + " /*start*/void bar() {\n" + " }/*end*/\n" + " };\n" + " }\n" + " };\n"+ " }\n" + "}" ); IBinding binding = ((MethodDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "bar() [in <anonymous #1> [in <initializer #1> [in <anonymous #1> [in foo() [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a method is correct. * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=249567 ) */ public void testMethod12() throws Exception { try { createFolder("/P/src/p1"); createFile( "/P/src/p1/X249567.java", "package p1;\n" + "public class X249567 {}" ); createFolder("/P/src/p2"); createFile( "/P/src/p2/X249567.java", "package p2;\n" + "public class X249567 {}" ); ASTNode node = buildAST( "public class X {\n" + " void foo(p1.X249567 x) {\n" + " }\n" + " /*start*/void foo(p2.X249567 x) {\n" + " }/*end*/\n" + "}" ); IBinding binding = ((MethodDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "foo(p2.X249567) [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } finally { deleteFolder("/P/src/p1"); deleteFolder("/P/src/p2"); } } /* * Ensures that the IJavaElement of an IBinding representing a method is correct. * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=249567 ) */ public void testMethod13() throws Exception { try { createFolder("/P/src/p1"); createFile( "/P/src/p1/X249567.java", "package p1;\n" + "public class X249567 {\n" + " public class Member {}\n" + "}" ); ASTNode node = buildAST( "public class X {\n" + " /*start*/void foo(p1.X249567.Member x) {\n" + " }/*end*/\n" + "}" ); IBinding binding = ((MethodDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "foo(p1.X249567.Member) [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } finally { deleteFolder("/P/src/p1"); } } /* * Ensures that the IJavaElement of an IBinding representing a method is correct. * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=249567 ) */ public void testMethod14() throws Exception { try { createFolder("/P/src/p1"); createFile( "/P/src/p1/X249567.java", "package p1;\n" + "public class X249567 {\n" + " public class Member<T> {}\n" + "}" ); ASTNode node = buildAST( "public class X {\n" + " /*start*/void foo(p1.X249567.Member<java.lang.String> x) {\n" + " }/*end*/\n" + "}" ); IBinding binding = ((MethodDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "foo(p1.X249567.Member<java.lang.String>) [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); } finally { deleteFolder("/P/src/p1"); } } /* * Ensures that the IJavaElement of an IBinding representing a package is correct. */ public void testPackage1() throws CoreException { ASTNode node = buildAST( "public class X {\n" + " /*start*/java.lang/*end*/.String field;\n" + "}" ); IBinding binding = ((QualifiedName) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "java.lang [in "+ getExternalJCLPathString("1.5") + "]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a package is correct * (case of default package) */ public void testPackage2() throws CoreException { ASTNode node = buildAST( "/*start*/public class X {\n" + "}/*end*/" ); ITypeBinding typeBinding = ((TypeDeclaration) node).resolveBinding(); IPackageBinding binding = typeBinding.getPackage(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "<default> [in src [in P]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a parameterized binary type is correct. * (regression test for bug 78087 [dom] TypeBinding#getJavaElement() throws IllegalArgumentException for parameterized or raw reference to binary type) */ public void testParameterizedBinaryType() throws CoreException { ASTNode node = buildAST( "public class X {\n" + " /*start*/Comparable<String>/*end*/ field;\n" + "}" ); IBinding binding = ((Type) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "Comparable [in Comparable.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a parameterized binary method is correct. * (regression test for bug 88892 [1.5] IMethodBinding#getJavaElement() returns nonexistent IMethods (wrong parameter types)) */ public void testParameterizedBinaryMethod() throws CoreException { ASTNode node = buildAST( "public class X extends p.Y<String> {\n" + " public X(String s) {\n" + " /*start*/super(s);/*end*/\n" + " }\n" + "}" ); IBinding binding = ((SuperConstructorInvocation) node).resolveConstructorBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "Y(T) [in Y [in Y.class [in p [in lib.jar [in P]]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a raw binary type is correct. * (regression test for bug 78087 [dom] TypeBinding#getJavaElement() throws IllegalArgumentException for parameterized or raw reference to binary type) */ public void testRawBinaryType() throws CoreException { ASTNode node = buildAST( "public class X {\n" + " /*start*/Comparable/*end*/ field;\n" + "}" ); IBinding binding = ((Type) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "Comparable [in Comparable.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a recovered type is correct. * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=232037 ) */ public void testRecoveredTypeBinding1() throws Exception { try { IJavaProject p = createJavaProject("P15", new String[] {""}, new String[] {"JCL15_LIB", "/P15/util.jar"}, "", "1.5"); org.eclipse.jdt.core.tests.util.Util.createJar(new String[] { "java/util/List.java", "package java.util;\n" + "public class List<T> {\n" + "}" }, p.getProject().getLocation() + File.separator + "util.jar", "1.5"); p.getProject().refreshLocal(IResource.DEPTH_INFINITE, null); createFile("/P15/X.java", ""); ASTNode node = buildAST( "public class X {\n" + " void m() {\n" + " /*start*/new java.util.List<URL>()/*end*/;\n" + " }\n" + "}", getCompilationUnit("/P15/X.java"), false/*don't report errors*/, true/*statement recovery*/, true/*binding recovery*/ ); IBinding binding = ((ClassInstanceCreation) node).resolveTypeBinding(); IJavaElement element = binding.getJavaElement(); assertEquals(element, element); // equals should not throw an NPE } finally { deleteProject("P15"); } } /* * Ensures that the IJavaElement of an IBinding representing a recovered type is correct. * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=232037 ) */ public void testRecoveredTypeBinding2() throws Exception { try { createJavaProject("P15", new String[] {""}, new String[] {"JCL15_LIB"}, "", "1.5"); createFile("/P15/X.java", ""); ASTNode node = buildAST( "public class X {\n" + " void m() {\n" + " new /*start*/java.util.List<URL>/*end*/();\n" + " }\n" + "}", getCompilationUnit("/P15/X.java"), false/*don't report errors*/, true/*statement recovery*/, true/*binding recovery*/ ); IBinding binding = ((ParameterizedType) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertEquals(element, element); // equals should not throw an NPE } finally { deleteProject("P15"); } } /* * Ensures that the IJavaElement of an IBinding representing a top level type is correct. */ public void testTopLevelType1() throws JavaModelException { ASTNode node = buildAST( "/*start*/public class X {\n" + "}/*end*/" ); IBinding binding = ((TypeDeclaration) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "X [in [Working copy] X.java [in <default> [in src [in P]]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a top level type is correct * (the top level type being in another compilation unit) */ public void testTopLevelType2() throws CoreException { try { createFile( "/P/src/Y.java", "public class Y {\n" + "}" ); ASTNode node = buildAST( "public class X extends /*start*/Y/*end*/ {\n" + "}" ); IBinding binding = ((Type) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "Y [in Y.java [in <default> [in src [in P]]]]", element ); } finally { deleteFile("/P/src/Y.java"); } } /* * Ensures that the IJavaElement of an IBinding representing a top level type is correct * (the top level type being in a jar) */ public void testTopLevelType3() throws CoreException { ASTNode node = buildAST( "public class X {\n" + " /*start*/String/*end*/ field;\n" + "}" ); IBinding binding = ((Type) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "String [in String.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]", element ); } /* * Ensures that the IJavaElement of an IBinding representing a parameter type is correct. * (regression test for bug 78930 ITypeBinding#getJavaElement() throws NPE for type variable) */ public void testTypeParameter() throws JavaModelException { ASTNode node = buildAST( "public class X</*start*/T/*end*/> {\n" + "}" ); IBinding binding = ((TypeParameter) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "<T> [in X [in [Working copy] X.java [in <default> [in src [in P]]]]]", element ); assertEquals("Wrong type", IJavaElement.TYPE_PARAMETER, element.getElementType()); ITypeParameter typeParameter = (ITypeParameter) element; final ITypeRoot typeRoot = typeParameter.getTypeRoot(); assertNotNull("Not type root", typeRoot); assertTrue("Invalid", typeRoot.exists()); } /* * Ensures that we can create a binding for an IJavaElement representing a type parameter (source type) * Bug 466279 - [hovering] IAE on hover when annotation-based null analysis is enabled */ public void testTypeParameter2() throws CoreException { ICompilationUnit cu = null; try { ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setResolveBindings(true); parser.setProject(getJavaProject("P")); createFolder("/P/src/p"); createFile("/P/src/p/X.java", "package p;\n" + "public interface X<T> {\n" + " public T foo(int i, String s);\n" + "}"); cu = (ICompilationUnit) getJavaProject("P").findElement(new Path("p/X.java")); cu.becomeWorkingCopy(null); IJavaElement[] elements = new IJavaElement[] { cu.getType("X"), cu.getType("X").getTypeParameters()[0], }; IBinding[] bindings = parser.createBindings(elements, null); assertBindingsEqual( "Lp/X<TT;>;\n" + "Lp/X;:TT;", bindings); IJavaElement element = bindings[1].getJavaElement(); assertElementExists( "Unexpected Java element", "<T> [in X [in [Working copy] X.java [in p [in src [in P]]]]]", element ); assertEquals("Wrong type", IJavaElement.TYPE_PARAMETER, element.getElementType()); ITypeParameter typeParameter = (ITypeParameter) element; ITypeRoot typeRoot = typeParameter.getTypeRoot(); assertNotNull("Not type root", typeRoot); assertTrue("Invalid", typeRoot.exists()); } finally { if (cu != null) cu.discardWorkingCopy(); deleteFile("/P/src/p/X.java"); deleteFolder("/P/src/p"); } } /* * Ensures that we can create a binding for an IJavaElement representing a type parameter (binary type) * Bug 466279 - [hovering] IAE on hover when annotation-based null analysis is enabled */ public void testTypeParameter3() throws CoreException { try { createClassFile("/P/lib", "A.class", "package lib;\n" + "public interface A<T,Z> {\n" + " public T foo(int i, String s);\n" + "}"); IJavaProject javaProject = getJavaProject("P"); IJavaElement[] elements = new IJavaElement[] { javaProject.findType("lib.A"), javaProject.findType("lib.A").getTypeParameters()[0], javaProject.findType("lib.A").getTypeParameters()[1] }; ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setProject(javaProject); IBinding[] bindings = parser.createBindings(elements, null); assertBindingsEqual( "Llib/A<TT;TZ;>;\n" + "Llib/A;:TT;\n" + "Llib/A;:TZ;", bindings); } finally { deleteFile("/P/lib/A.class"); deleteFolder("/P/lib"); } } /* * Ensures that we can create a binding for an IJavaElement representing a type parameter (binary method) * Bug 466279 - [hovering] IAE on hover when annotation-based null analysis is enabled */ public void testTypeParameter4() throws CoreException { try { createFolder("P/lib"); createClassFile("/P/lib", "A.class", "package lib;\n" + "public interface A {\n" + " public <T,Z> T foo(int i, Z s);\n" + "}"); IJavaProject javaProject = getJavaProject("P"); IMethod method = javaProject.findType("lib.A").getMethod("foo", new String[] { "I", "TZ;" }); IJavaElement[] elements = new IJavaElement[] { method, method.getTypeParameters()[0], method.getTypeParameters()[1] }; ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setProject(javaProject); IBinding[] bindings = parser.createBindings(elements, null); assertBindingsEqual( "Llib/A;.foo<T:Ljava/lang/Object;Z:Ljava/lang/Object;>(ITZ;)TT;\n" + "Llib/A;.foo<T:Ljava/lang/Object;Z:Ljava/lang/Object;>(ITZ;)TT;:TT;\n" + "Llib/A;.foo<T:Ljava/lang/Object;Z:Ljava/lang/Object;>(ITZ;)TT;:TZ;", bindings); } finally { deleteFile("/P/lib/A.class"); deleteFolder("/P/lib"); } } /* * Ensures that the IJavaElement of an IBinding representing a wild card is correct. * (regression test for bug 81417 [dom] getJavaElement() throws a NPE for WildcardBinding) */ public void testWildCard() throws JavaModelException { ASTNode node = buildAST( "public class X<T> {\n" + " X</*start*/? extends Exception/*end*/> field;\n" + "}" ); IBinding binding = ((WildcardType) node).resolveBinding(); IJavaElement element = binding.getJavaElement(); assertElementExists( "Unexpected Java element", "<null>", element ); } /** * Test behavior when the binding key denotes a non existent type. * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=157847" */ public void test157847a() throws CoreException { String filePath = "/P/src/Bug157847A.java"; try { String contents = "public class Bug157847A<T> {\n" + " void add(Y<? extends T> l) {}\n" + "}\n"+ "interface Y<T> {}\n"; createFile(filePath, contents); BindingRequestor requestor = new BindingRequestor(); String[] bindingKeys = new String[] {"LBug157847A~ThisTypeDoesNotExist;"}; resolveASTs( new ICompilationUnit[] {}, bindingKeys, requestor, getJavaProject("P"), this.workingCopy.getOwner() ); IBinding[] bindings = requestor.getBindings(bindingKeys); assertTrue("Constructed non existing type", bindings.length == 0); } finally { deleteFile(filePath); } } /** * Ensures that we don't create internally inconsistent wildcard * bindings of the form '? extends <null>' or '? super <null>' * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=157847" */ public void test157847b() throws CoreException { String filePath = "/P/src/Bug157847B.java"; try { String contents = "public class Bug157847B<T> {\n" + " void add(Y<? super T> l) {}\n" + "}\n"+ "interface Y<T> {}\n"; createFile(filePath, contents); BindingRequestor requestor = new BindingRequestor(); String[] bindingKeys = new String[] {"LBug157847B~Y<LBug157847B~Y;{0}-!LBug157847B;{0}*54;>;"}; resolveASTs( new ICompilationUnit[] {}, bindingKeys, requestor, getJavaProject("P"), this.workingCopy.getOwner() ); IBinding[] bindings = requestor.getBindings(bindingKeys); assertTrue("Constructed bogus wildcard", bindings.length == 0); } finally { deleteFile(filePath); } } /** * Ensures that we don't create internally inconsistent wildcard * bindings of the form '? extends <null>' or '? super <null>' * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=157847" */ public void test157847c() throws CoreException { String filePath = "/P/src/Bug157847C.java"; try { String contents = "public class Bug157847C<T> {\n" + " void add(Y<? extends T> l) {}\n" + "}\n"+ "interface Y<T> {}\n"; createFile(filePath, contents); BindingRequestor requestor = new BindingRequestor(); String[] bindingKeys = new String[] {"LBug157847C~Y<LBug157847C~Y;{0}+!LBug157847C;{0}*54;>;"}; resolveASTs( new ICompilationUnit[] {}, bindingKeys, requestor, getJavaProject("P"), this.workingCopy.getOwner() ); IBinding[] bindings = requestor.getBindings(bindingKeys); assertTrue("Constructed bogus wildcard", bindings.length == 0); } finally { deleteFile(filePath); } } public void test320802() throws CoreException { String filePath = "/P/src/X.java"; String filePathY = "/P/src/p/Y.java"; try { String contents = "import p.Y;\n" + "public class X {\n" + " Y<MissingType1, MissingType2> y;\n" + " public X() {\n" + " this.y = new Y<MissingType1, MissingType2>();\n" + " }\n" + "}"; createFile(filePath, contents); ICompilationUnit compilationUnit = getCompilationUnit("P", "src", "", "X.java"); assertTrue(compilationUnit.exists()); String contents2 = "package p;\n" + "public class Y<T, U> {}"; createFolder("/P/src/p"); createFile(filePathY, contents2); ICompilationUnit compilationUnit2 = getCompilationUnit("P", "src", "p", "Y.java"); assertTrue(compilationUnit2.exists()); final CompilationUnit[] asts = new CompilationUnit[1]; BindingRequestor requestor = new BindingRequestor() { public void acceptAST(ICompilationUnit source, CompilationUnit ast) { asts[0] = ast; } }; resolveASTs( new ICompilationUnit[] {compilationUnit}, new String[0], requestor, getJavaProject("P"), this.workingCopy.getOwner() ); assertNotNull("No ast", asts[0]); final IProblem[] problems = asts[0].getProblems(); String expectedProblems = "1. ERROR in /P/src/X.java (at line 3)\n" + " Y<MissingType1, MissingType2> y;\n" + " ^^^^^^^^^^^^\n" + "MissingType1 cannot be resolved to a type\n" + "----------\n" + "2. ERROR in /P/src/X.java (at line 3)\n" + " Y<MissingType1, MissingType2> y;\n" + " ^^^^^^^^^^^^\n" + "MissingType2 cannot be resolved to a type\n" + "----------\n" + "3. ERROR in /P/src/X.java (at line 5)\n" + " this.y = new Y<MissingType1, MissingType2>();\n" + " ^^^^^^\n" + "MissingType1 cannot be resolved to a type\n" + "----------\n" + "4. ERROR in /P/src/X.java (at line 5)\n" + " this.y = new Y<MissingType1, MissingType2>();\n" + " ^^^^^^\n" + "MissingType2 cannot be resolved to a type\n" + "----------\n" + "5. ERROR in /P/src/X.java (at line 5)\n" + " this.y = new Y<MissingType1, MissingType2>();\n" + " ^^^^^^^^^^^^\n" + "MissingType1 cannot be resolved to a type\n" + "----------\n" + "6. ERROR in /P/src/X.java (at line 5)\n" + " this.y = new Y<MissingType1, MissingType2>();\n" + " ^^^^^^^^^^^^\n" + "MissingType2 cannot be resolved to a type\n" + "----------\n"; assertProblems("Wrong problems", expectedProblems, problems, contents.toCharArray()); } finally { deleteFile(filePath); deleteFile(filePathY); deleteFolder("/P/src/p"); } } }