/******************************************************************************* * Copyright (c) 2004, 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 *******************************************************************************/ package org.eclipse.jdt.core.tests.dom; import java.io.IOException; import java.util.ArrayList; import junit.framework.Test; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.BindingKey; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IProblemRequestor; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.WorkingCopyOwner; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.ASTRequestor; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.IVariableBinding; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.tests.util.Util; @SuppressWarnings({"rawtypes", "unchecked"}) public class BatchASTCreationTests extends AbstractASTTests { /** * Internal synonym for deprecated constant AST.JSL3 * to alleviate deprecation warnings. * @deprecated */ /*package*/ static final int JLS3_INTERNAL = AST.JLS3; public class TestASTRequestor extends ASTRequestor { public ArrayList asts = new ArrayList(); public void acceptAST(ICompilationUnit source, CompilationUnit ast) { this.asts.add(ast); } public void acceptBinding(String bindingKey, IBinding binding) { } } class BindingResolver extends TestASTRequestor { private ArrayList bindingKeys = new ArrayList(); int index = -1; private ArrayList foundKeys = new ArrayList(); MarkerInfo[] markerInfos; public BindingResolver(MarkerInfo[] markerInfos) { this.markerInfos = markerInfos; } public void acceptAST(ICompilationUnit source, CompilationUnit cu) { super.acceptAST(source, cu); ASTNode[] nodes = findNodes(cu, this.markerInfos[++this.index]); for (int i = 0, length = nodes.length; i < length; i++) { IBinding binding = resolveBinding(nodes[i]); String bindingKey = binding == null ? "null" : binding.getKey(); // case of a capture binding if (bindingKey.indexOf('!') != -1 && binding.getKind() == IBinding.METHOD) { bindingKey = ((IMethodBinding) binding).getReturnType().getKey(); } this.bindingKeys.add(bindingKey); } } public void acceptBinding(String key, IBinding binding) { super.acceptBinding(key, binding); this.foundKeys.add(binding == null ? "null" : binding.getKey()); } public String[] getBindingKeys() { int length = this.bindingKeys.size(); String[] result = new String[length]; this.bindingKeys.toArray(result); return result; } public String[] getFoundKeys() { int length = this.foundKeys.size(); String[] result = new String[length]; this.foundKeys.toArray(result); return result; } } public WorkingCopyOwner owner = new WorkingCopyOwner() {}; public BatchASTCreationTests(String name) { super(name); } public static Test suite() { return buildModelTestSuite(BatchASTCreationTests.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[] { "test072a" }; // TESTS_NUMBERS = new int[] { 72 }; // TESTS_RANGE = new int[] { 83304, -1 }; } public void setUpSuite() throws Exception { super.setUpSuite(); createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "", "1.5"); } public void tearDownSuite() throws Exception { deleteProject("P"); super.tearDownSuite(); } /* * Resolves the given cus and binding key as a batch. * While resolving, for the ASTNode that is marked, ensures that its binding key is the expected one. * Ensures that the returned binding corresponds to the expected key. */ private void assertRequestedBindingFound(String[] pathAndSources, final String expectedKey) throws JavaModelException { assertRequestedBindingsFound(pathAndSources, new String[] {expectedKey}); } /* * Resolves the given cus and binding key as a batch. * While resolving, for the ASTNode that is marked, ensures that its binding key is the expected one. * Ensures that the returned binding corresponds to the expected key. */ private void assertRequestedBindingsFound(String[] pathAndSources, final String[] expectedKeys) throws JavaModelException { BindingResolver resolver = requestBindings(pathAndSources, expectedKeys); assertStringsEqual("Unexpected binding for marked node", expectedKeys, resolver.getBindingKeys()); assertStringsEqual("Unexpected binding found by acceptBinding", expectedKeys, resolver.getFoundKeys()); } /* * Creates working copies from the given path and sources. * Resolves a dummy cu as a batch and on the first accept, create a binding with the expected key using ASTRequestor#createBindings. * Ensures that the returned binding corresponds to the expected key. */ private void assertBindingCreated(String[] pathAndSources, final String expectedKey) throws JavaModelException { assertBindingsCreated(pathAndSources, new String[] {expectedKey}); } /* * Creates working copies from the given path and sources. * Resolves a dummy cu as a batch and on the first accept, create a binding with the expected key using ASTRequestor#createBindings. * Ensures that the returned binding corresponds to the expected key. */ private void assertBindingsCreated(String[] pathAndSources, final String[] expectedKeys) throws JavaModelException { ICompilationUnit[] copies = null; try { copies = createWorkingCopies(pathAndSources); class Requestor extends TestASTRequestor { ArrayList createdBindingKeys = new ArrayList(); public void acceptAST(ICompilationUnit source, CompilationUnit cu) { super.acceptAST(source, cu); IBinding[] bindings = createBindings(expectedKeys); if (bindings != null && bindings.length > 0 && bindings[0] != null) this.createdBindingKeys.add(bindings[0].getKey()); } public String getCreatedKeys() { StringBuffer buffer = new StringBuffer(); for (int i = 0, length = this.createdBindingKeys.size(); i < length; i++) { buffer.append(this.createdBindingKeys.get(i)); if (i < length - 1) buffer.append('\n'); } return buffer.toString(); } } Requestor requestor = new Requestor(); ICompilationUnit[] dummyWorkingCopies = null; try { dummyWorkingCopies = createWorkingCopies(new String[] { "/P/Test.java", "public class Test {\n" + "}" }); resolveASTs(dummyWorkingCopies, new String[] {}, requestor, getJavaProject("P"), this.owner); } finally { discardWorkingCopies(dummyWorkingCopies); } String expectedKey = toString(expectedKeys); String actualKey = requestor.getCreatedKeys(); if (!expectedKey.equals(actualKey)) { BindingResolver resolver = requestBindings(pathAndSources, null); String[] markedKeys = resolver.getBindingKeys(); if (markedKeys.length > 0) { assertStringsEqual("Inconsistent expected key ", expectedKeys, markedKeys); } } assertEquals("Unexpected created binding", expectedKey, actualKey); } finally { discardWorkingCopies(copies); } } private void createASTs(ICompilationUnit[] cus, TestASTRequestor requestor) { ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.createASTs(cus, new String[] {}, requestor, null); } protected ICompilationUnit[] createWorkingCopies(String[] pathAndSources) throws JavaModelException { return createWorkingCopies(pathAndSources, this.owner); } protected ICompilationUnit[] createWorkingCopies(String[] pathAndSources, boolean resolve) throws JavaModelException { IProblemRequestor problemRequestor = resolve ? new IProblemRequestor() { public void acceptProblem(IProblem problem) {} public void beginReporting() {} public void endReporting() {} public boolean isActive() { return true; } } : null; MarkerInfo[] markerInfos = createMarkerInfos(pathAndSources); this.owner = newWorkingCopyOwner(problemRequestor); return createWorkingCopies(markerInfos, this.owner); } private void resolveASTs(ICompilationUnit[] cus, TestASTRequestor requestor) { resolveASTs(cus, new String[0], requestor, getJavaProject("P"), this.owner); } private BindingResolver requestBindings(String[] pathAndSources, final String[] expectedKeys) throws JavaModelException { ICompilationUnit[] copies = null; try { MarkerInfo[] markerInfos = createMarkerInfos(pathAndSources); copies = createWorkingCopies(markerInfos, this.owner); BindingResolver resolver = new BindingResolver(markerInfos); resolveASTs(copies, expectedKeys == null ? new String[0] : expectedKeys, resolver, copies.length > 0 ? copies[0].getJavaProject() : getJavaProject("P"), this.owner); return resolver; } finally { discardWorkingCopies(copies); } } /* * Tests the batch creation of 2 ASTs without resolving. */ public void test001() throws CoreException { this.workingCopies = createWorkingCopies(new String[] { "/P/p1/X.java", "package p1;\n" + "public class X extends Y {\n" + "}", "/P/p1/Y.java", "package p1;\n" + "public class Y {\n" + "}", }); TestASTRequestor requestor = new TestASTRequestor(); createASTs(this.workingCopies, requestor); assertASTNodesEqual( "package p1;\n" + "public class X extends Y {\n" + "}\n" + "\n" + "package p1;\n" + "public class Y {\n" + "}\n" + "\n", requestor.asts ); } /* * Tests the batch creation of 2 ASTs with resolving. */ public void test002() throws CoreException { MarkerInfo[] markerInfos = createMarkerInfos(new String[] { "/P/p1/X.java", "package p1;\n" + "public class X extends /*start*/Y/*end*/ {\n" + "}", "/P/p1/Y.java", "package p1;\n" + "/*start*/public class Y {\n" + "}/*end*/", }); this.workingCopies = createWorkingCopies(markerInfos, this.owner); TestASTRequestor requestor = new TestASTRequestor(); resolveASTs(this.workingCopies, requestor); assertASTNodesEqual( "package p1;\n" + "public class X extends Y {\n" + "}\n" + "\n" + "package p1;\n" + "public class Y {\n" + "}\n" + "\n", requestor.asts ); // compare the bindings coming from the 2 ASTs Type superX = (Type) findNode((CompilationUnit) requestor.asts.get(0), markerInfos[0]); TypeDeclaration typeY = (TypeDeclaration) findNode((CompilationUnit) requestor.asts.get(1), markerInfos[1]); IBinding superXBinding = superX.resolveBinding(); IBinding typeYBinding = typeY.resolveBinding(); assertTrue("Super of X and Y should be the same", superXBinding == typeYBinding); } /* * Ensures that ASTs that are required by original source but were not asked for are not handled. */ public void test003() throws CoreException { ICompilationUnit[] otherWorkingCopies = null; try { this.workingCopies = createWorkingCopies(new String[] { "/P/p1/X.java", "package p1;\n" + "public class X extends Y {\n" + "}", }); otherWorkingCopies = createWorkingCopies(new String[] { "/P/p1/Y.java", "package p1;\n" + "public class Y {\n" + "}", }); TestASTRequestor requestor = new TestASTRequestor(); resolveASTs(this.workingCopies, requestor); assertASTNodesEqual( "package p1;\n" + "public class X extends Y {\n" + "}\n" + "\n", requestor.asts ); } finally { // Note: this.workingCopies are discarded in tearDown discardWorkingCopies(otherWorkingCopies); } } /* * Ensures that a package binding can be retrieved using its key. */ public void test004() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "/*start*/package p1;/*end*/\n" + "public class X {\n" + "}", }, "p1"); } /* * Ensures that a type binding can be retrieved using its key. */ public void test005() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "/*start*/public class X extends Y {\n" + "}/*end*/", "/P/p1/Y.java", "package p1;\n" + "public class Y {\n" + "}", }, "Lp1/X;"); } /* * Ensures that a type binding can be retrieved using its key. */ public void test006() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X extends Y {\n" + "}", "/P/p1/Y.java", "package p1;\n" + "/*start*/public class Y {\n" + "}/*end*/", }, "Lp1/Y;"); } /* * Ensures that a member type binding can be retrieved using its key. */ public void test007() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " /*start*/class Member {\n" + " }/*end*/" + "}", }, "Lp1/X$Member;"); } /* * Ensures that a member type binding can be retrieved using its key. */ public void test008() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " class Member1 {\n" + " /*start*/class Member2 {\n" + " }/*end*/" + " }\n" + "}", }, "Lp1/X$Member1$Member2;"); } /* * Ensures that an anonymous type binding can be retrieved using its key. */ public void test009() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " void foo() {\n" + " new X() /*start*/{\n" + " }/*end*/;" + " }\n" + "}", }, "Lp1/X$52;"); } /* * Ensures that a local type binding can be retrieved using its key. */ public void test010() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " void foo() {\n" + " /*start*/class Y {\n" + " }/*end*/;" + " }\n" + "}", }, "Lp1/X$54$Y;"); } /* * Ensures that a package binding can be created using its key in ASTRequestor#createBindings. */ public void test011() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + "}", }, "p1"); } /* * Ensures that a type binding can be created using its key in ASTRequestor#createBindings. */ public void test012() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X extends Y {\n" + "}", "/P/p1/Y.java", "package p1;\n" + "public class Y {\n" + "}", }, "Lp1/X;"); } /* * Ensures that a type binding can be created using its key in ASTRequestor#createBindings. */ public void test013() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X extends Y {\n" + "}", "/P/p1/Y.java", "package p1;\n" + "public class Y {\n" + "}", }, "Lp1/Y;"); } /* * Ensures that a member type binding can be created using its key in ASTRequestor#createBindings. */ public void test014() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " class Member {\n" + " }" + "}", }, "Lp1/X$Member;"); } /* * Ensures that a member type binding can be created using its key in ASTRequestor#createBindings. */ public void test015() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " class Member1 {\n" + " class Member2 {\n" + " }" + " }\n" + "}", }, "Lp1/X$Member1$Member2;"); } /* * Ensures that an anonymous type binding can be created using its key in ASTRequestor#createBindings. */ public void test016() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " void foo() {\n" + " new X() /*start*/{\n" + " }/*end*/;" + " }\n" + "}", }, "Lp1/X$52;"); } /* * Ensures that a local type binding can be created using its key in ASTRequestor#createBindings. */ public void test017() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " void foo() {\n" + " /*start*/class Y {\n" + " }/*end*/;" + " }\n" + "}", }, "Lp1/X$54$Y;"); } /* * Ensures that a method binding can be created using its key in ASTRequestor#createBindings. */ public void test018() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " void foo() {\n" + " }\n" + "}", }, "Lp1/X;.foo()V"); } /* * Ensures that a method binding can be created using its key in ASTRequestor#createBindings. */ public void test019() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " void foo(Object o) {\n" + " }\n" + "}", }, "Lp1/X;.foo(Ljava/lang/Object;)V"); } /* * Ensures that a method binding can be created using its key in ASTRequestor#createBindings. */ public void test020() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " X(Object o) {\n" + " }\n" + "}", }, "Lp1/X;.(Ljava/lang/Object;)V"); } /* * Ensures that a field binding can be created using its key in ASTRequestor#createBindings. */ public void test021() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " int field;\n" + "}", }, "Lp1/X;.field)I"); } /* * Ensures that a base type binding can be created using its key in ASTRequestor#createBindings. */ public void test022() throws CoreException { assertBindingCreated(new String[0],"I"); } /* * Ensures that an array binding can be created using its key in ASTRequestor#createBindings. */ public void test023() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + "}", }, "[Lp1/X;"); } /* * Ensures that an array binding can be created using its key in ASTRequestor#createBindings. */ public void test024() throws CoreException { assertBindingCreated(new String[0],"[[I"); } /* * Ensures that a method binding in an anonymous type with several kind of parameters can be created using its key in ASTRequestor#createBindings */ public void test025() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " class Y {\n" + " }\n" + " void foo() {\n" + " new X() {\n" + " /*start*/void bar(int i, X x, String[][] s, Y[] args, boolean b, Object o) {\n" + " }/*end*/\n" + " };\n" + " }\n" + "}", }, "Lp1/X$68;.bar(ILp1/X;[[Ljava/lang/String;[Lp1/X$Y;ZLjava/lang/Object;)V" ); } /* * Ensures that a generic type binding can be created using its key in ASTRequestor#createBindings. */ public void test026() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T> {\n" + "}", }, "Lp1/X<TT;>;"); } /* * Ensures that a generic type binding can be created using its key in ASTRequestor#createBindings. */ public void test027() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T extends Y & I, U extends Y> {\n" + "}", "/P/p1/Y.java", "package p1;\n" + "public class Y {\n" + "}", "/P/p1/I.java", "package p1;\n" + "public interface I {\n" + "}", }, "Lp1/X<TT;TU;>;"); } /* * Ensures that a parameterized type binding can be created using its key in ASTRequestor#createBindings. */ public void test028() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T> {\n" + " X<String> field;\n" + "}", }, "Lp1/X<Ljava/lang/String;>;"); } /* * Ensures that a member parameterized type binding can be created using its key in ASTRequestor#createBindings. */ public void test029() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T,U> {\n" + " class Y<V> {\n" + " X<Error,Exception>.Y<String> field;\n" + " }\n" + "}", }, "Lp1/X<Ljava/lang/Error;Ljava/lang/Exception;>.Y<Ljava/lang/String;>;"); } /* * Ensures that a raw type binding can be created using its key in ASTRequestor#createBindings. */ public void test030() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T,U> {\n" + " X field;\n" + "}", }, "Lp1/X<>;"); } /* * Ensures that a member raw type binding can be created using its key in ASTRequestor#createBindings. */ public void test031() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T,U> {\n" + " class Y<V> {\n" + " X<Error,Exception>.Y field;\n" + " }\n" + "}", }, "Lp1/X<Ljava/lang/Error;Ljava/lang/Exception;>.Y<>;"); } /* * Ensures that a parameterized method binding can be created using its key in ASTRequestor#createBindings */ public void test032() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " <T> void foo() {\n" + " }\n" + "}", }, "Lp1/X;.foo<T:Ljava/lang/Object;>()V"); } /* * Ensures that a local variable binding can be created using its key in ASTRequestor#createBindings */ public void test033() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " void foo() {\n" + " int i;\n" + " }\n" + "}", }, "Lp1/X;.foo()V#i"); } /* * Ensures that a local variable binding can be created using its key in ASTRequestor#createBindings */ public void test034() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " void foo() {\n" + " int i = 1;\n" + " if (i == 0) {\n" + " int a;\n" + " } else {\n" + " int b;\n" + " }\n" + " }\n" + "}", }, "Lp1/X;.foo()V#1#b"); } /* * Ensures that a parameterized method binding can be created using its key in ASTRequestor#createBindings. */ public void test035() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T> {\n" + " void foo(T t) {\n" + " }\n" + " void bar() {\n" + " new X<String>().foo(\"\");\n" + " }\n" + "}", }, "Lp1/X<Ljava/lang/String;>;.foo(Ljava/lang/String;)V"); } /* * Ensures that a parameterized generic method binding can be created using its key in ASTRequestor#createBindings. */ public void test036() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T> {\n" + " <U> void foo(T t, U u) {\n" + " }\n" + " void bar() {\n" + " /*start*/new X<String>().foo(\"\", this)/*end*/;\n" + " }\n" + "}", }, "Lp1/X<Ljava/lang/String;>;.foo<U:Ljava/lang/Object;>(Ljava/lang/String;TU;)V%<Lp1/X;>" ); } /* * Ensures that a raw generic method binding can be created using its key in ASTRequestor#createBindings. */ public void test037() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T> {\n" + " <U> void foo(T t, U u) {\n" + " }\n" + " void bar() {\n" + " /*start*/new X().foo(\"\", this)/*end*/;\n" + " }\n" + "}", }, "Lp1/X;.foo<U:Ljava/lang/Object;>(TT;TU;)V%<>"); } /* * Ensures that a parameterized method binding (where the parameter is an unbound wildcard) can be created using its key in ASTRequestor#createBindings. */ public void test038() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T> {\n" + " void foo() {\n" + " }\n" + " void bar(X<?> x) {\n" + " x.foo();\n" + " }\n" + "}", }, "Lp1/X<Lp1/X;{0}*>;.foo()V"); } /* * Ensures that a parameterized method binding (where the parameter is an extends wildcard) can be created using its key in ASTRequestor#createBindings. */ public void test039() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T> {\n" + " void foo() {\n" + " }\n" + " void bar(X<? extends Object> x) {\n" + " x.foo();\n" + " }\n" + "}", }, "Lp1/X<Lp1/X;{0}+Ljava/lang/Object;>;.foo()V"); } /* * Ensures that a parameterized method binding (where the parameter is a super wildcard) can be created using its key in ASTRequestor#createBindings. */ public void test040() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T> {\n" + " void foo() {\n" + " }\n" + " void bar(X<? super Error> x) {\n" + " x.foo();\n" + " }\n" + "}", }, "Lp1/X<Lp1/X;{0}-Ljava/lang/Error;>;.foo()V"); } /* * Ensures that a parameterized method binding (where the parameters contain wildcards) can be created using its key in ASTRequestor#createBindings. */ public void test041() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T, U, V, W> {\n" + " void foo() {\n" + " }\n" + " void bar(X<? super Error, ?, String, ? extends Object> x) {\n" + " x.foo();\n" + " }\n" + "}", }, "Lp1/X<Lp1/X;{0}-Ljava/lang/Error;Lp1/X;{1}*Ljava/lang/String;Lp1/X;{2}+Ljava/lang/Object;>;.foo()V"); } /* * Ensures that requesting 2 bindings and an AST for the same compilation unit reports the 2 bindings. */ public void test042() throws CoreException { ICompilationUnit workingCopy = null; try { workingCopy = getWorkingCopy( "/P/X.java", "public class X {\n" + " int field;\n" + "}" ); BindingRequestor requestor = new BindingRequestor(); String[] bindingKeys = new String[] { "LX;", "LX;.field)I" }; resolveASTs( new ICompilationUnit[] {workingCopy}, bindingKeys, requestor, getJavaProject("P"), workingCopy.getOwner() ); assertBindingsEqual( "LX;\n" + "LX;.field)I", requestor.getBindings(bindingKeys)); } finally { if (workingCopy != null) workingCopy.discardWorkingCopy(); } } /* * Ensures that a source parameterized type binding (where the parameters contain wildcard with a super bound) can be created using its key in ASTRequestor#createBindings. */ public void test043() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T> {\n" + " X<? super T> field;\n" + "}", }, "Lp1/X<Lp1/X;{0}-Lp1/X;:TT;>;"); } /* * Ensures that a binary parameterized type binding (where the parameters contain wildcard with a super bound) can be created using its key in ASTRequestor#createBindings. * (regression test for 83499 ClassCastException when restoring ITypeBinding from key) */ public void test044() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<E> {\n" + " Class<? extends E> field;\n" + "}", }, "Ljava/lang/Class<Lp1/X;{0}+Lp1/X;:TE;>;"); } /* * Ensures that restoring a second key that references a type in a first key doesn't throw a NPE * (regression test for bug 83499 NPE when restoring ITypeBinding from key) */ public void test045() throws CoreException { ITypeBinding[] bindings = createTypeBindings( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + "}", "/P/p1/Y.java", "package p1;\n" + "public class Y<E> {\n" + "}" }, new String[] { "Lp1/X;", "Lp1/Y<Lp1/Y;{0}+Lp1/X;>;" } ); assertBindingsEqual( "Lp1/X;\n" + "Lp1/Y<Lp1/Y;{0}+Lp1/X;>;", bindings); } /* * Ensures that a binary array parameterized type binding can be created using its key in ASTRequestor#createBindings. */ public void test046() throws CoreException { assertBindingCreated( new String[] {}, "[Ljava/lang/Class<Ljava/lang/Object;>;"); } /* * Ensures that the null type binding can be created using its key in batch creation. */ public void test047() throws CoreException { ITypeBinding[] bindings = createTypeBindings( new String[] {}, new String[] {"N"}); assertBindingsEqual( "N", bindings); } /* * Ensures that a binary array type binding can be created using its key in batch creation. */ public void test048() throws CoreException { ITypeBinding[] bindings = createTypeBindings( new String[] {}, new String[] {"[Ljava/lang/Object;"}); assertBindingsEqual( "[Ljava/lang/Object;", bindings); } /* * Ensures that a type variable binding can be created using its key in batch creation. */ public void test049() throws CoreException { ITypeBinding[] bindings = createTypeBindings( new String[] {}, new String[] {"Ljava/lang/Class<TT;>;:TT;"}); assertBindingsEqual( "Ljava/lang/Class;:TT;", bindings); } /* * Ensures that a parameterized type binding with a wildcard that extends an array the can be created using its key in batch creation. */ public void test050() throws CoreException { ITypeBinding[] bindings = createTypeBindings( new String[] {}, new String[] {"Ljava/lang/Class<Ljava/lang/Class<TT;>;{0}+[Ljava/lang/Object;>;"}); assertBindingsEqual( "Ljava/lang/Class<Ljava/lang/Class;{0}+[Ljava/lang/Object;>;", bindings); } /* * Ensures that attempting to create a top level type that doesn't exist using its key i in batch creation. * returns null. */ public void test051() throws CoreException { ITypeBinding[] bindings = createTypeBindings( new String[] {}, new String[] {"Lp1/DoesNotExist;"}); assertBindingsEqual( "<null>", bindings); } /* * Ensures that a secondary type binding can be created using its key in ASTRequestor#createBindings. */ public void test052() throws CoreException { try { createFolder("/P/p1"); createFile( "/P/p1/X.java", "package p1;\n" + "public class X {\n" + "}\n" + "class Y {\n" + "}" ); assertBindingCreated(new String[] {}, "Lp1/X~Y;"); } finally { deleteFolder("/P/p1"); } } /* * Ensures that an anonymous type binding coming from secondary type can be created using its key in ASTRequestor#createBindings. */ public void test053() throws CoreException { try { createFolder("/P/p1"); createFile( "/P/p1/X.java", "package p1;\n" + "public class X {\n" + "}\n" + "class Y {\n" + " void foo() {\n" + " new Y() {};\n" + " }\n" + "}" ); assertBindingCreated(new String[] {}, "Lp1/X~Y$64;"); } finally { deleteFolder("/P/p1"); } } /* * Ensures that an anonymous type binding inside a local type can be retrieved using its key. */ public void test054() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " void foo() {\n" + " class Y {\n" + " void bar() {\n" + " new X() /*start*/{\n" + " }/*end*/;" + " }\n" + " }\n" + " }\n" + "}", }, "Lp1/X$89;" ); } /* * Ensures that a parameterized generic method binding can be created using its key in ASTRequestor#createBindings. */ public void test055() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T> {\n" + " <U> void foo(U u) {\n" + " }\n" + " void bar() {\n" + " /*start*/new X<String>().foo(new X() {})/*end*/;\n" + " }\n" + "}", }, "Lp1/X<Ljava/lang/String;>;.foo<U:Ljava/lang/Object;>(TU;)V%<Lp1/X$101;>" ); } /* * Ensures that creating a binary member type binding returns the correct binding * (regression test for bug 86967 [1.5][dom] NPE in BindingKeyResolver for multi-level parameterized type binding) */ public void test056() throws CoreException, IOException { try { IJavaProject project = createJavaProject("BinaryProject", new String[0], new String[] {"JCL15_LIB"}, "", "1.5"); addLibrary(project, "lib.jar", "src.zip", new String[] { "/BinaryProject/p/X.java", "package p;\n" + "public class X<K, V> {\n" + " public class Y<K1, V1> {\n" + " }\n" + "}" }, "1.5"); ITypeBinding[] bindings = createTypeBindings(new String[0], new String[] { "Lp/X<>.Y<Lp/X;:TK;Lp/X;:TV;>;" }, project); assertBindingsEqual( "Lp/X<>.Y<Lp/X;:TK;Lp/X;:TV;>;", bindings); } finally { deleteProject("BinaryProject"); } } /* * Ensures that creating a missing binary member type binding doesn't throw a NPE * (regression test for bug 86967 [1.5][dom] NPE in BindingKeyResolver for multi-level parameterized type binding) */ public void test057() throws CoreException { ITypeBinding[] bindings = createTypeBindings( new String[] {}, new String[] {"Lp/Missing$Member;"}); assertBindingsEqual( "<null>", bindings); } /* * Ensures that a type parameter binding can be created using its key in batch creation. * (regression test for bug 87050 ASTParser#createASTs(..) cannot resolve method type parameter binding from key) */ public void test058() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " </*start*/T/*end*/> void foo(T t) {\n" + " }" + "}", }, "Lp1/X;.foo<T:Ljava/lang/Object;>(TT;)V:TT;"); } /* * Ensures that a capture binding can be created using its key in batch creation. */ public void test059() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<T> {\n" + " Object foo(X<?> list) {\n" + " return /*start*/list.get()/*end*/;\n" + " }\n" + " T get() {\n" + " return null;\n" + " }\n" + "}", }, "Lp1/X;&!Lp1/X;{0}*77;" ); } /* * Ensures that a capture binding can be created using its key in batch creation. */ public void test060() throws CoreException { assertRequestedBindingFound( new String[] { "/P/xy/Cap.java", "package xy;\n" + "import java.util.Vector;\n" + "public class Cap {\n" + " {\n" + " Vector<?> v= null;\n" + " /*start*/v.get(0)/*end*/;\n" + " }\n" + "}", "/P/java/util/Vector.java", "package java.util;\n" + "public class Vector<T> {\n" + " public T get(int i) {\n" + " return null;\n" + " }\n" + "}" }, "Lxy/Cap;&!Ljava/util/Vector;{0}*82;" ); } /* * Ensures that a generic constructor binding can be created using its key in batch creation. */ public void test061() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " /*start*/<T> X() {\n" + " }/*end*/\n" + "}", }, "Lp1/X;.<T:Ljava/lang/Object;>()V" ); } /* * Ensures that an array binding whose leaf type is a type variable binding can be created using its key in batch creation. * (regression test for bug 94206 CCE in BindingKeyResolver when restoring array type of method type parameter) */ public void test062() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " <T> /*start*/T[]/*end*/ foo(T[] a) {\n" + " return null;\n" + " }\n" + "}", }, "[Lp1/X;.foo<T:Ljava/lang/Object;>([TT;)[TT;:TT;" ); } /* * Ensures that a raw method binding can be created using its key in batch creation. * (regression test for bug 87749 different IMethodBindings of generic method have equal getKey()) */ public void test063() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " public static <T extends Y<? super T>> void foo(Z<T> z) {\n" + " }\n" + " /**\n" + " * @see #foo(Z)\n" + " */\n" + " void bar() {\n" + " /*start*/foo(new W())/*end*/;\n" + " }\n" + "}\n" + "class Y<T> {\n" + "}\n" + "class Z<T> {\n" + "}\n" + "class W<T> extends Z<T> {\n" + "}", }, "Lp1/X;.foo<T:Lp1/Y<-TT;>;>(Lp1/Z<TT;>;)V%<Lp1/X~Y<Lp1/X~Y;{0}-Lp1/X~Y<Lp1/X~Y;{0}-Lp1/X;:2TT;>;>;>" ); } /* * Ensures that a raw method binding can be created using its key in batch creation. * (regression test for bug 87749 different IMethodBindings of generic method have equal getKey()) */ public void test063a() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<U extends X<T>> {\n" + " public void foo(Z<U> z) {\n" + " }\n" + " /**\n" + " * @see #foo(Z)\n" + " */\n" + " static void bar(X x) {\n" + " /*start*/x.foo(new W())/*end*/;\n" + " }\n" + "}\n" + "class Y<T> {\n" + "}\n" + "class Z<T> {\n" + "}\n" + "class W<T> extends Z<T> {\n" + "}", }, "Lp1/X<>;.foo(Lp1/Z;)V" ); } /* * Ensures that a parameterized type binding with a capture binding in its arguments can be created using its key in batch creation. * (regression test for bug 94092 ASTParser#createASTs(..) restores wrong bindings from capture keys) */ public void test064() throws CoreException { assertRequestedBindingsFound( new String[] { "/P/p1/X.java", "package p1;\n" + "/*start1*/public class X {\n" + " Object o= null;\n" + " Y<?> field;\n" + " void foo() {\n" + " /*start2*/o = field/*end2*/;\n" + " }\n" + "}/*end1*/\n", "/P/p1/Y.java", "package p1;\n" + "public class Y<T> {\n" + "}", }, new String[] { "Lp1/X;", "Lp1/X;&Lp1/Y<!Lp1/Y;{0}*83;>;", } ); } /* * Ensures that a parameterized type binding with a type variable of the current's method in its arguments can be created using its key in batch creation. * (regression test for bug 97902 NPE on Open Declaration on reference to generic type) */ public void test065() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " <T> void foo(/*start*/Y<T>/*end*/ y) {\n" + " }\n" + "}\n" + "class Y<E> {\n" + "}", }, "Lp1/X~Y<Lp1/X;:1TT;>;" ); } /* * Ensures that the compilation with a owner is used instead of a primary working copy when looking up a type. * (regression test for bug 97542 ASTParser#createASTs does not correctly resolve bindings in working copies) */ public void test066() throws CoreException { ICompilationUnit primaryWorkingCopy = null; ICompilationUnit ownedWorkingcopy = null; try { // primary working copy with no method foo() primaryWorkingCopy = getCompilationUnit("/P/p1/X.java"); primaryWorkingCopy.becomeWorkingCopy(null/*no progress*/); primaryWorkingCopy.getBuffer().setContents( "package p1;\n" + "public class X {\n" + "}" ); primaryWorkingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); // working copy for the test's owner with a method foo() ownedWorkingcopy = getWorkingCopy( "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " void foo() {}\n" + "}", this.owner ); // create bindings assertRequestedBindingFound( new String[] { "/P/p1/Y.java", "package p1;\n" + "public class Y {\n" + " void bar() {\n" + " /*start*/new X().foo()/*end*/;\n" + "}", }, "Lp1/X;.foo()V" ); } finally { if (primaryWorkingCopy != null) primaryWorkingCopy.discardWorkingCopy(); if (ownedWorkingcopy != null) ownedWorkingcopy.discardWorkingCopy(); } } /* * Ensures that the declaring class of a member parameterized type binding with a raw enclosing type is correct */ public void test067() throws CoreException { ITypeBinding[] bindings = createTypeBindings( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X<K, V> {\n" + " public class Y<K1, V1> {\n" + " }\n" + " /*start*/Y<K, V>/*end*/ field;\n" + "}" }, new String[] {"Lp1/X$Y<Lp1/X;:TK;Lp1/X;:TV;>;"} ); assertBindingEquals( "Lp1/X<>;", bindings.length == 0 ? null : bindings[0].getDeclaringClass() ); } /* * Ensures that a raw member type can be created using its key in batch creation. */ public void test068() throws CoreException, IOException { try { IJavaProject project = createJavaProject("P1", new String[] {""}, new String[] {"JCL15_LIB"}, "", "1.5"); addLibrary(project, "lib.jar", "src.zip", new String[] { "/P1/p/X.java", "package p;\n" + "public class X<K, V> {\n" + " public static class Member<K1, V1> {\n" + " }\n" + "}", "/P1/p/Y.java", "package p;\n" + "public class Y {\n" + " void foo(X.Member x) {\n" + " }\n" + "}", }, "1.5"); assertRequestedBindingFound( new String[] { "/P1/p1/Z.java", "package p1;\n" + "public class Z extends p.Y {\n" + " /*start*/p.X.Member/*end*/ field;\n" + "}" }, "Lp/X$Member<>;" ); } finally { deleteProject("P1"); } } /* * Ensures that requesting a CU needing a constant in a previously processed CU doesn't throw an NPE * (regression test for bug 111822 DOMParser.createASTs() NPE at FieldReference.getConstantFor(FieldReference.java:408)) */ public void test069() throws CoreException { this.workingCopies = createWorkingCopies(new String[] { "/P/pkg/RefAnnoAndClassWithAnno.java", "package pkg;\n" + "public class RefMyAnnoAndClassWithAnno {\n" + " final Class anno = MyAnno.class;\n" + " final Class withAnno = ClassWithAnnotation.class;\n" + "}", "/P/pkg/MyAnno.java", "package pkg;\n" + "public @interface MyAnno {\n" + " public enum EnumColor{\n" + " BLUE, RED, WHITE;\n" + " }\n" + " EnumColor aEnum();\n" + "}", "/P/pkg/ClassWithAnnotation.java", "package pkg;\n" + "import pkg.MyAnno.EnumColor;\n" + "@MyAnno(aEnum = EnumColor.BLUE)\n" + "public class ClassWithAnnotation {}" }); String key = BindingKey.createTypeBindingKey("pkg.RefMyAnnoAndClassWithAnno"); BindingResolver resolver = new BindingResolver(new MarkerInfo[0]); resolveASTs(new ICompilationUnit[0], new String[] {key}, resolver, getJavaProject("P"), this.owner); assertStringsEqual( "Unexpected bindings", "Lpkg/RefAnnoAndClassWithAnno~RefMyAnnoAndClassWithAnno;\n", resolver.getFoundKeys()); } /* * Ensures that unrequested compilation units are not resolved * (regression test for bug 114935 ASTParser.createASTs parses more CUs then required) */ public void test070() throws CoreException { MarkerInfo[] markerInfos = createMarkerInfos(new String[] { "/P/p1/X.java", "package p1;\n" + "public class X extends /*start*/Y/*end*/ {\n" + "}", "/P/p1/Y.java", "package p1;\n" + "public class Y {\n" + " static final int CONST = 2 + 3;\n" + "}", }); this.workingCopies = createWorkingCopies(markerInfos, this.owner); TestASTRequestor requestor = new TestASTRequestor(); resolveASTs(new ICompilationUnit[] {this.workingCopies[0]}, requestor); // get the binding for Y Type y = (Type) findNode((CompilationUnit) requestor.asts.get(0), markerInfos[0]); ITypeBinding yBinding = y.resolveBinding(); // ensure that the fields for Y are not resolved assertBindingsEqual("", yBinding.getDeclaredFields()); } /* * Ensures that unrequested compilation units are not resolved * (regression test for bug 117018 IVariableBinding#getConstantValue() could be lazy resolved) */ public void test071() throws CoreException { final MarkerInfo[] markerInfos = createMarkerInfos(new String[] { "/P/p1/X.java", "package p1;\n" + "public class X extends /*start*/Y/*end*/ {\n" + "}", "/P/p1/Y.java", "package p1;\n" + "public class Y {\n" + " static final int CONST = 2 + 3;\n" + "}", }); this.workingCopies = createWorkingCopies(markerInfos, this.owner); class Requestor extends TestASTRequestor { Object constantValue = null; public void acceptAST(ICompilationUnit source, CompilationUnit ast) { super.acceptAST(source, ast); Type y = (Type) findNode(ast, markerInfos[0]); ITypeBinding typeBinding = y.resolveBinding(); IVariableBinding fieldBinding = typeBinding.getDeclaredFields()[0]; this.constantValue = fieldBinding.getConstantValue(); } } Requestor requestor = new Requestor(); resolveASTs(new ICompilationUnit[] {this.workingCopies[0]}, requestor); assertEquals("Unexpected constant value", 5, requestor.constantValue); } /* * Ensures that the declaring method of a local variable binding retrieved using its key * is not null * (regression test for bug 129804 Local variable bindings from ASTParser#createASTs(.., String[], .., ..) have no declaring method) */ public void test072() throws CoreException { IVariableBinding[] bindings = createVariableBindings( new String[] { "/P/X.java", "public class X {\n" + " void m() {\n" + " Object o;\n" + " }\n" + "}" }, new String[] { "LX;.m()V#o" } ); assertBindingEquals( "LX;.m()V", bindings[0].getDeclaringMethod()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=159631 public void test073() throws CoreException, IOException { try { IJavaProject project = createJavaProject("P072", new String[] {}, Util.getJavaClassLibs(), "", "1.5"); ICompilationUnit compilationUnits[] = new ICompilationUnit[3]; compilationUnits[0] = getWorkingCopy( "P072/X.java", "public class X {\n" + " @Override" + " public boolean equals(Object o) {\n" + " return true;\n" + " }\n" + "}"); compilationUnits[1] = getWorkingCopy( "P072/Y.java", "public class Y extends X {\n" + "}"); compilationUnits[2] = getWorkingCopy( "P072/Z.java", "public class Z {\n" + " Y m;\n" + " boolean foo(Object p) {\n" + " return this.m.equals(p);\n" + " }\n" + "}"); ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setResolveBindings(true); parser.setProject(project); class Requestor extends ASTRequestor { } parser.createASTs(compilationUnits, new String[0], new Requestor(), null); // will throw an unexpected NPE, until the bug is fixed } finally { deleteProject("P072"); } } /** * @bug 155003: [model] Missing exception types / wrong signature? * @test Ensure that thrown exceptions are added in method unique key (not in signature) * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=155003" */ public void test074_Bug155003() throws CoreException { assertBindingCreated( new String[] { "/P/X.java", "public class X {\n" + " public void foo() throws InterruptedException, IllegalMonitorStateException {\n" + " }\n" + " void test() throws InterruptedException, IllegalMonitorStateException {\n" + " /*start*/foo()/*end*/;\n" + " }\n" + "}", }, "LX;.foo()V|Ljava/lang/InterruptedException;|Ljava/lang/IllegalMonitorStateException;" ); String content = "public class X {\n" + " public void foo() throws InterruptedException, IllegalMonitorStateException {\n" + " }\n" + " void test() throws InterruptedException, IllegalMonitorStateException {\n" + " /*start*/foo()/*end*/;\n" + " }\n" + "}"; this.workingCopies = createWorkingCopies(new String[] { "/P/X.java", content }, true /*resolve*/); ASTNode node = buildAST(content, this.workingCopies[0]); assertEquals("Invalid node type!", ASTNode.METHOD_INVOCATION, node.getNodeType()); IBinding binding = resolveBinding(node); BindingKey bindingKey = new BindingKey(binding.getKey()); assertStringsEqual("Unexpected thrown exceptions", "Ljava.lang.InterruptedException;\n" + "Ljava.lang.IllegalMonitorStateException;\n", bindingKey.getThrownExceptions() ); } public void test075_Bug155003() throws CoreException { String content = "public class X<T> {\n" + " <U extends Exception> X<T> foo(X<T> x) throws RuntimeException, U {\n" + " return null;\n" + " }\n" + " void test() throws Exception {\n" + " /*start*/foo(this)/*end*/;\n" + " }\n" + "}"; this.workingCopies = createWorkingCopies(new String[] { "/P/X.java", content }, true /*resolve*/); ASTNode node = buildAST(content, this.workingCopies[0]); assertEquals("Invalid node type!", ASTNode.METHOD_INVOCATION, node.getNodeType()); IBinding binding = resolveBinding(node); BindingKey bindingKey = new BindingKey(binding.getKey()); assertStringsEqual("Unexpected thrown exceptions", "Ljava.lang.RuntimeException;\n" + "TU;\n", bindingKey.getThrownExceptions() ); } public void test076_Bug155003() throws CoreException { String content = "public class X<T> {\n" + " <K, V> V bar(K key, V value) throws Exception {\n" + " return value;\n" + " }\n" + " void test() throws Exception {\n" + " /*start*/bar(\"\", \"\")/*end*/;\n" + " }\n" + "}"; this.workingCopies = createWorkingCopies(new String[] { "/P/X.java", content }, true /*resolve*/); ASTNode node = buildAST(content, this.workingCopies[0]); assertEquals("Invalid node type!", ASTNode.METHOD_INVOCATION, node.getNodeType()); IBinding binding = resolveBinding(node); BindingKey bindingKey = new BindingKey(binding.getKey()); assertStringsEqual("Unexpected thrown exceptions", "Ljava.lang.Exception;\n", bindingKey.getThrownExceptions() ); } /** * @bug 163647: [model] Thrown exceptions are not found in method binding key which have a capture as declaring class * @test Ensure that thrown exceptions are added in method unique key (not in signature) * even when declaring class is a capture * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=163647" */ public void test077_Bug163647() throws CoreException { String content = "public class Test {\n" + " public X<? extends Object> getX() { return null; }\n" + " public void bar() {\n" + " try {\n" + " /*start*/getX().foo()/*end*/;\n" + " } catch (Exception e) {\n" + " // skip\n" + " }\n" + " }\n" + "}\n" + "class X<T> {\n" + " public void foo() throws CloneNotSupportedException, IllegalMonitorStateException, InterruptedException {\n" + " }\n" + "}"; this.workingCopies = createWorkingCopies(new String[] { "/P/Test.java", content }, true /*resolve*/); ASTNode node = buildAST(content, this.workingCopies[0]); assertEquals("Invalid node type!", ASTNode.METHOD_INVOCATION, node.getNodeType()); IBinding binding = resolveBinding(node); BindingKey bindingKey = new BindingKey(binding.getKey()); assertStringsEqual("Unexpected thrown exceptions", "Ljava.lang.CloneNotSupportedException;\n" + "Ljava.lang.IllegalMonitorStateException;\n" + "Ljava.lang.InterruptedException;\n", bindingKey.getThrownExceptions() ); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=152060 public void test078() throws CoreException, IOException { try { IJavaProject project = createJavaProject("P078", new String[] {}, Util.getJavaClassLibs(), "", "1.5"); ICompilationUnit compilationUnits[] = new ICompilationUnit[1]; compilationUnits[0] = getWorkingCopy( "P078/Test.java", "import java.util.*;\n" + "public class Test {\n" + " public interface ExtraIterator<T> extends Iterator {\n" + " public void extra();\n" + " }\n" + " public class Test2<T> implements ExtraIterator<T> {\n" + " public boolean hasNext() {\n" + " return false;\n" + " }\n" + " public T next() {\n" + " return null;\n" + " }\n" + " public void remove() {\n" + " }\n" + " public void extra() {\n" + " }\n" + " }\n" + "}"); ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setResolveBindings(true); parser.setProject(project); final IBinding[] bindings = new IBinding[1]; final String key = "LTest$ExtraIterator<>;"; parser.createASTs( compilationUnits, new String[] { key }, new ASTRequestor() { public void acceptAST(ICompilationUnit source, CompilationUnit localAst) { // do nothing } public void acceptBinding(String bindingKey, IBinding binding) { if (key.equals(bindingKey)) { bindings[0] = binding; } } }, null); IBinding binding = bindings[0]; assertNotNull("Should not be null", binding); assertEquals("Not a type binding", IBinding.TYPE, binding.getKind()); ITypeBinding typeBinding = (ITypeBinding) binding; assertEquals("Wrong name", "Test.ExtraIterator", typeBinding.getQualifiedName()); assertTrue("Not a raw type", typeBinding.isRawType()); } finally { deleteProject("P078"); } } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=152060 public void test079() throws CoreException, IOException { try { IJavaProject project = createJavaProject("P079", new String[] {"src"}, Util.getJavaClassLibs(), "bin", "1.5"); createFolder("/P079/src/test"); createFile("/P079/src/test/Test.java", "package test;\n" + "import java.util.*;\n" + "interface ExtraIterator<T> extends Iterator {\n" + " public void extra();\n" + "}\n" + "public class Test<T> implements ExtraIterator<T> {\n" + " public boolean hasNext() {\n" + " return false;\n" + " }\n" + " public T next() {\n" + " return null;\n" + " }\n" + " public void remove() {\n" + " }\n" + " public void extra() {\n" + " }\n" + "}"); ICompilationUnit compilationUnits[] = new ICompilationUnit[1]; compilationUnits[0] = getCompilationUnit("P079", "src", "test", "Test.java"); ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setResolveBindings(true); parser.setProject(project); final IBinding[] bindings = new IBinding[1]; final String key = "Ltest/Test~ExtraIterator<>;"; parser.createASTs( compilationUnits, new String[] { key }, new ASTRequestor() { public void acceptAST(ICompilationUnit source, CompilationUnit localAst) { // do nothing } public void acceptBinding(String bindingKey, IBinding binding) { if (key.equals(bindingKey)) { bindings[0] = binding; } } }, null); IBinding binding = bindings[0]; assertNotNull("Should not be null", binding); assertEquals("Not a type binding", IBinding.TYPE, binding.getKind()); ITypeBinding typeBinding = (ITypeBinding) binding; assertEquals("Wrong type", "test.ExtraIterator", typeBinding.getQualifiedName()); } finally { deleteProject("P079"); } } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=152060 public void test080() throws CoreException, IOException { final String projectName = "P080"; try { IJavaProject project = createJavaProject(projectName, new String[] {"src"}, Util.getJavaClassLibs(), "bin", "1.5"); createFolder("/" + projectName + "/src/test"); createFile("/" + projectName + "/src/test/Test.java", "package test;\n" + "import java.util.*;\n" + "public class Test {\n" + " public interface ExtraIterator<T> extends Iterator {\n" + " public void extra();\n" + " }\n" + " public class Test2<T> implements ExtraIterator<T> {\n" + " public boolean hasNext() {\n" + " return false;\n" + " }\n" + " public T next() {\n" + " return null;\n" + " }\n" + " public void remove() {\n" + " }\n" + " public void extra() {\n" + " }\n" + " }\n" + "}"); ICompilationUnit compilationUnits[] = new ICompilationUnit[1]; compilationUnits[0] = getCompilationUnit(projectName, "src", "test", "Test.java"); ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setResolveBindings(true); parser.setProject(project); final IBinding[] bindings = new IBinding[1]; final String key = "Ltest/Test$ExtraIterator<>;"; parser.createASTs( compilationUnits, new String[] { key }, new ASTRequestor() { public void acceptAST(ICompilationUnit source, CompilationUnit localAst) { // do nothing } public void acceptBinding(String bindingKey, IBinding binding) { if (key.equals(bindingKey)) { bindings[0] = binding; } } }, null); IBinding binding = bindings[0]; assertNotNull("Should not be null", binding); assertEquals("Not a type binding", IBinding.TYPE, binding.getKind()); ITypeBinding typeBinding = (ITypeBinding) binding; assertEquals("Wrong name", "test.Test.ExtraIterator", typeBinding.getQualifiedName()); assertTrue("Not a raw type", typeBinding.isRawType()); } finally { deleteProject(projectName); } } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=111529 public void test081() throws CoreException, IOException { final String projectName = "P081"; try { IJavaProject javaProject = createJavaProject(projectName, new String[] {"src"}, Util.getJavaClassLibs(), "bin", "1.5"); String typeName = "java.util.List<java.lang.Integer>"; 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; } } String[] keys = new String[] { BindingKey.createTypeBindingKey(typeName) }; final BindingRequestor requestor = new BindingRequestor(); final ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setResolveBindings(true); parser.setProject(javaProject); // this doesn't really do a parse; it's a type lookup parser.createASTs(new ICompilationUnit[] {}, keys, requestor, null); ITypeBinding typeBinding = requestor._result; assertNotNull("No binding", typeBinding); assertTrue("Not a parameterized type binding", typeBinding.isParameterizedType()); } finally { deleteProject(projectName); } } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=111529 public void test082() throws CoreException, IOException { final String projectName = "P082"; try { IJavaProject javaProject = createJavaProject(projectName, new String[] {"src"}, Util.getJavaClassLibs(), "bin", "1.5"); String typeName = "java.util.List<Integer>"; 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; } } String[] keys = new String[] { BindingKey.createTypeBindingKey(typeName) }; final BindingRequestor requestor = new BindingRequestor(); final ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setResolveBindings(true); parser.setProject(javaProject); // this doesn't really do a parse; it's a type lookup parser.createASTs(new ICompilationUnit[] {}, keys, requestor, null); ITypeBinding typeBinding = requestor._result; assertNull("Got a binding", typeBinding); } finally { deleteProject(projectName); } } /* * Ensures that a secondary type binding can be retrieved using its key, even if the primary type doesn't exist. * (regression test for bug 177115 NullPointerException in BindingKeyResolver.consumeTypeVariable(...)) */ public void test083() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "/*start*/class Y {\n" + "}/*end*/", }, "Lp1/X~Y;"); } /* * Ensures that a duplicate local variable binding can be created using its key in ASTRequestor#createBindings * (regression test for bug 149590 [model] bindings for duplicate local variables share same key) */ public void test084() throws CoreException { assertBindingCreated( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " void foo() {\n" + " int i;\n" + " int i;\n" + " }\n" + "}", }, "Lp1/X;.foo()V#i#1"); } /* * Ensures that an annotation binding can be retrieved using its key. */ public void test085() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "/*start*/@MyAnnot/*end*/\n" + "public class X {\n" + "}", "/P/p1/MyAnnot.java", "package p1;\n" + "public @interface MyAnnot {\n" + "}", }, "Lp1/X;@Lp1/MyAnnot;"); } /* * Ensures that an annotation binding can be retrieved using its key. */ public void test086() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " /*start*/@MyAnnot/*end*/\n" + " int field;\n" + "}", "/P/p1/MyAnnot.java", "package p1;\n" + "public @interface MyAnnot {\n" + "}", }, "Lp1/X;.field)I@Lp1/MyAnnot;"); } /* * Ensures that an annotation binding can be retrieved using its key. */ public void test087() throws CoreException { assertRequestedBindingFound( new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " /*start*/@MyAnnot/*end*/\n" + " void foo() {\n" + " }\n" + "}", "/P/p1/MyAnnot.java", "package p1;\n" + "public @interface MyAnnot {\n" + "}", }, "Lp1/X;.foo()V@Lp1/MyAnnot;"); } /* * Ensures that a parameterized type with 2 arguments referring to the same cu that contains an anonymous type with a non-default constructor * can be created using its key in ASTRequestor#createBindings * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=236445 ) */ public void test088() throws CoreException { assertBindingCreated( new String[] { "/P/A.java", "public class A {\n" + " public void foo(C c) {\n" + " c.bar(B //|<---Ctrl+Space after B\n" + " }\n" + "}\n" + "class B<V, E> {\n" + "}", "/P/C.java", "public class C {\n" + " public <V, E> void bar(B<V, E> code) {\n" + " new D(null) {}; \n" + " }\n" + "}\n" + "class D {\n" + " D(Object o) {}\n" + "}" }, "LA~B<LC;:1TV;LC;:1TE;>;"); } public void testIgnoreMethodBodies1() throws CoreException { this.workingCopies = createWorkingCopies(new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " public int foo() {\n" + " int i = 0;\n" + " }\n" + " public int bar() {\n" + " int i = 0;\n" + " new X() /*start*/{\n" + " }/*end*/;" + " }\n" + "}", }); TestASTRequestor requestor = new TestASTRequestor(); ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setIgnoreMethodBodies(true); parser.createASTs(this.workingCopies, new String[] {}, requestor, null); // statement declaring i should not be in the AST assertASTNodesEqual( "package p1;\n" + "public class X {\n" + " public int foo(){\n" + " }\n" + " public int bar(){\n" + " }\n" + "}\n" + "\n", requestor.asts ); } public void testIgnoreMethodBodies2() throws CoreException { this.workingCopies = createWorkingCopies(new String[] { "/P/p1/X.java", "package p1;\n" + "public class X {\n" + " public int foo() {\n" + " int i = 0;\n" + " }\n" + " public int bar() {\n" + " int i = 0;\n" + " new X() /*start*/{\n" + " }/*end*/;" + " }\n" + "}", }); TestASTRequestor requestor = new TestASTRequestor(); ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setIgnoreMethodBodies(true); parser.setResolveBindings(true); parser.setProject(getJavaProject("P")); parser.createASTs(this.workingCopies, new String[] {}, requestor, null); // statement declaring i should not be in the AST assertASTNodesEqual( "package p1;\n" + "public class X {\n" + " public int foo(){\n" + " }\n" + " public int bar(){\n" + " }\n" + "}\n" + "\n", requestor.asts ); } }