| /******************************************************************************* |
| * Copyright (c) 2000, 2009 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.wst.jsdt.core.tests.model; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.HashMap; |
| |
| import org.eclipse.core.resources.IncrementalProjectBuilder; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.Path; |
| |
| import org.eclipse.wst.jsdt.core.*; |
| import org.eclipse.wst.jsdt.core.tests.util.Util; |
| |
| import junit.framework.Test; |
| |
| public class TypeHierarchyTests extends ModifyingResourceTests { |
| /** |
| * A placeholder for a type hierarchy used in some test cases. |
| */ |
| ITypeHierarchy typeHierarchy; |
| |
| public static Test suite() { |
| return buildModelTestSuite(TypeHierarchyTests.class); |
| } |
| public TypeHierarchyTests(String name) { |
| super(name); |
| this.displayName = true; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.tests.model.AbstractJavaModelTests#setUpSuite() |
| */ |
| public void setUpSuite() throws Exception { |
| super.setUpSuite(); |
| |
| setUpJavaProject("TypeHierarchy"); |
| addLibrary("myLib.jar", "myLibsrc.zip", new String[] { |
| "my/pkg/X.js", |
| "package my.pkg;\n" + |
| "public class X {\n" + |
| "}", |
| "my/pkg/Y.js", |
| "package my.pkg;\n" + |
| "public class Y {\n" + |
| " void foo() {\n" + |
| " new X() {};" + |
| " }\n" + |
| "}", |
| }, JavaScriptCore.VERSION_1_4); |
| |
| IPackageFragmentRoot root = this.currentProject.getPackageFragmentRoot(this.currentProject.getProject().getFile("lib.jar")); |
| IRegion region = JavaScriptCore.newRegion(); |
| region.add(root); |
| this.typeHierarchy = this.currentProject.newTypeHierarchy(region, null); |
| |
| IJavaScriptProject project15 = createJavaProject("TypeHierarchy15", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin", "1.5"); |
| addLibrary(project15, "lib15.jar", "lib15src.zip", new String[] { |
| "util/AbstractList.js", |
| "package util;\n" + |
| "public class AbstractList<E> {\n" + |
| "}", |
| "util/ArrayList.js", |
| "package util;\n" + |
| "public class ArrayList<E> extends AbstractList<E> implements List<E> {\n" + |
| "}", |
| "util/List.js", |
| "package util;\n" + |
| "public interface List<E> {\n" + |
| "}", |
| "util/Map.js", |
| "package util;\n" + |
| "public class Map<K,V> extends AbstractList<V> {\n" + |
| "}", |
| }, JavaScriptCore.VERSION_1_5); |
| createFile( |
| "/TypeHierarchy15/src/X.js", |
| "import util.*;\n" + |
| "public class X<E> extends ArrayList<E> implements List<E> {\n" + |
| "}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/Y.js", |
| "import util.*;\n" + |
| "public class Y extends ArrayList implements List {\n" + |
| "}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/I.js", |
| "public interface I<E> {\n" + |
| "}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/A.js", |
| "public class A<E> implements I<E> {\n" + |
| "}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/X99606.js", |
| "public class X99606 extends Y99606<X99606.Color> {\n" + |
| " static class Color {}\n" + |
| "}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/Y99606.js", |
| "public class Y99606<T> {\n" + |
| "}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/A108740.js", |
| "class A108740<T> {}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/B108740.js", |
| "class B108740<T> extends A108740<C108740> {}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/C108740.js", |
| "class C108740 extends B108740<C108740> {}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/D108740.js", |
| "class D108740 extends B108740<D108740> {}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/CycleParent.js", |
| "class CycleParent extends CycleBase<CycleChild> {}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/CycleBase.js", |
| "class CycleBase<T extends CycleBase> {}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/CycleChild.js", |
| "class CycleChild extends CycleParent implements Comparable<CycleChild> {\n" + |
| " public int compareTo(CycleChild o) { return 0; }\n" + |
| "}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/Try.js", |
| "public enum Try {\n" + |
| " THIS,\n" + |
| " THAT(),\n" + |
| " ANONYMOUS() {}\n" + |
| "}" |
| ); |
| |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.wst.jsdt.core.tests.model.SuiteOfTestCases#tearDownSuite() |
| */ |
| public void tearDownSuite() throws Exception { |
| this.typeHierarchy = null; |
| deleteProject("TypeHierarchy"); |
| deleteProject("TypeHierarchy15"); |
| |
| super.tearDownSuite(); |
| } |
| /* |
| * Ensures that a hierarchy on an anonymous type in an initializer is correct. |
| */ |
| public void testAnonymousType01() throws JavaScriptModelException { |
| IType typeA = getCompilationUnit("TypeHierarchy", "src", "p7", "A.js").getType("A"); |
| IType type = typeA.getInitializer(1).getType("", 1); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: <anonymous #1> [in <initializer #1> [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| "Super types:\n" + |
| " X [in X.java [in p7 [in src [in TypeHierarchy]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } |
| /* |
| * Ensures that a hierarchy on an anonymous type in a second initializer is correct. |
| */ |
| public void testAnonymousType02() throws JavaScriptModelException { |
| IType typeA = getCompilationUnit("TypeHierarchy", "src", "p7", "A.js").getType("A"); |
| IType type = typeA.getInitializer(2).getType("", 1); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: <anonymous #1> [in <initializer #2> [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| "Super types:\n" + |
| " X [in X.java [in p7 [in src [in TypeHierarchy]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } |
| /* |
| * Ensures that a hierarchy on an anonymous type in a field declaration is correct. |
| */ |
| public void testAnonymousType03() throws JavaScriptModelException { |
| IType typeA = getCompilationUnit("TypeHierarchy", "src", "p7", "A.js").getType("A"); |
| IType type = typeA.getField("field1").getType("", 1); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: <anonymous #1> [in field1 [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| "Super types:\n" + |
| " X [in X.java [in p7 [in src [in TypeHierarchy]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } |
| /* |
| * Ensures that a hierarchy on an anonymous type in a field declaration is correct. |
| */ |
| public void testAnonymousType04() throws JavaScriptModelException { |
| IType typeA = getCompilationUnit("TypeHierarchy", "src", "p7", "A.js").getType("A"); |
| IType type = typeA.getField("field2").getType("", 1); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: <anonymous #1> [in field2 [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| "Super types:\n" + |
| " X [in X.java [in p7 [in src [in TypeHierarchy]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| type = typeA.getField("field2").getType("", 2); |
| hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: <anonymous #2> [in field2 [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| "Super types:\n" + |
| " X [in X.java [in p7 [in src [in TypeHierarchy]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } |
| /* |
| * Ensures that a hierarchy on an anonymous type in a method declaration is correct. |
| */ |
| public void testAnonymousType05() throws JavaScriptModelException { |
| IType typeA = getCompilationUnit("TypeHierarchy", "src", "p7", "A.js").getType("A"); |
| IType type = typeA.getFunction("foo", new String[] {}).getType("", 1); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: <anonymous #1> [in foo() [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| "Super types:\n" + |
| " X [in X.java [in p7 [in src [in TypeHierarchy]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } |
| /* |
| * Ensures that a hierarchy on an anonymous type that uses a non-default constructor is correct. |
| * (regression test for bug 44506 Type hierarchy is missing anonymous type) |
| */ |
| public void testAnonymousType06() throws JavaScriptModelException { |
| IType typeA = getCompilationUnit("TypeHierarchy", "src", "p8", "X.js").getType("X"); |
| IType type = typeA.getFunction("foo", new String[] {}).getType("", 1); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: <anonymous #1> [in foo() [in X [in X.java [in p8 [in src [in TypeHierarchy]]]]]]\n" + |
| "Super types:\n" + |
| " X [in X.java [in p8 [in src [in TypeHierarchy]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } |
| /* |
| * Ensure that the key of an anonymous binary type in a hierarchy is correct. |
| * (regression test for bug 93826 ArrayIndexOutOfBoundsException when opening type hierarchy) |
| */ |
| public void testAnonymousType07() throws CoreException { |
| IType type = getClassFile("TypeHierarchy","myLib.jar", "my.pkg", "X.class").getType(); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| IType[] subtypes = hierarchy.getSubclasses(type); |
| assertEquals("Unexpected key", "Lmy/pkg/Y$1;", subtypes.length < 1 ? null : subtypes[0].getKey()); |
| } |
| /* |
| * Ensure that hierarchy on an enum also include the anonymous of its enum contants |
| * (regression test for bug 120667 [hierarchy] Type hierarchy for enum type does not include anonymous subtypes) |
| */ |
| public void testAnonymousType08() throws CoreException { |
| IType type = getCompilationUnit("TypeHierarchy15/src/Try.js").getType("Try"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: Try [in Try.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| "Super types:\n" + |
| " Enum [in Enum.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| " Comparable [in Comparable.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| " Serializable [in Serializable.class [in java.io [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| "Sub types:\n" + |
| " <anonymous #1> [in ANONYMOUS [in Try [in Try.java [in <default> [in src [in TypeHierarchy15]]]]]]\n", |
| hierarchy); |
| } |
| /* |
| * Ensure that hierarchy on the anonymous type of an enum constant is correct |
| * (regression test for bug 120667 [hierarchy] Type hierarchy for enum type does not include anonymous subtypes) |
| */ |
| public void testAnonymousType09() throws CoreException { |
| IType type = getCompilationUnit("TypeHierarchy15/src/Try.js").getType("Try").getField("ANONYMOUS").getType("", 1); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: <anonymous #1> [in ANONYMOUS [in Try [in Try.java [in <default> [in src [in TypeHierarchy15]]]]]]\n" + |
| "Super types:\n" + |
| " Try [in Try.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| " Enum [in Enum.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| " Comparable [in Comparable.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| " Serializable [in Serializable.class [in java.io [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } |
| /* |
| * Ensure that hierarchy on the anonymous type of a member type that is opened is correct |
| * (regression test for bug 122444 [hierarchy] Type hierarchy of inner member type misses anonymous subtypes) |
| */ |
| public void testAnonymousType10() throws CoreException { |
| IJavaScriptUnit cu = getCompilationUnit("TypeHierarchy/src/q7/X.js"); |
| cu.open(null); |
| IType type = cu.getType("X").getType("Member"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: Member [in X [in X.java [in q7 [in src [in TypeHierarchy]]]]]\n" + |
| "Super types:\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n" + |
| " <anonymous #1> [in foo(X) [in Y [in X.java [in q7 [in src [in TypeHierarchy]]]]]]\n", |
| hierarchy); |
| } |
| /** |
| * Ensures that the superclass can be retrieved for a binary inner type. |
| */ |
| public void testBinaryInnerTypeGetSuperclass() throws JavaScriptModelException { |
| IClassFile cf = getClassFile("TypeHierarchy", "lib.jar", "binary", "Y$Inner.class"); |
| IType type = cf.getType(); |
| ITypeHierarchy h = type.newSupertypeHierarchy(null); |
| IType superclass = h.getSuperclass(type); |
| assertTrue("Superclass not found for Y$Inner", superclass != null); |
| assertEquals("Unexpected super class", "Z", superclass.getElementName()); |
| } |
| /* |
| * Ensures that the hierarchy lookup mechanism get the right binary if it is missplaced. |
| * (regression test for bug 139279 Fup of bug 134110, got CCE changing an external jar contents and refreshing the project) |
| */ |
| public void testBinaryInWrongPackage() throws CoreException { |
| try { |
| createJavaProject("P", new String[] {"src"}, new String[] {"JCL_LIB", "lib"}); |
| createFolder("/P/src/p"); |
| createFile( |
| "/P/src/p/X.js", |
| "pakage p;\n" + |
| "public class X {\n" + |
| "}" |
| ); |
| getProject("P").build(IncrementalProjectBuilder.FULL_BUILD, null); |
| waitForAutoBuild(); |
| getFile("/P/bin/p/X.class").copy(new Path("/P/lib/X.class"), false, null); |
| ITypeHierarchy hierarchy = getClassFile("P", "/P/lib", "", "X.class").getType().newSupertypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: X [in X.class [in <default> [in lib [in P]]]]\n" + |
| "Super types:\n" + |
| "Sub types:\n" + |
| "Root classes:\n", |
| hierarchy); |
| } finally { |
| deleteProject("P"); |
| } |
| } |
| /* |
| * Ensures that a hierarchy with a binary subclass that is also referenced can be computed |
| * (regression test for bug 48459 NPE in Type hierarchy) |
| */ |
| public void testBinarySubclass() throws JavaScriptModelException { |
| IType type = getCompilationUnit("TypeHierarchy/src/p48459/p1/X48459.js").getType("X48459"); |
| ITypeHierarchy h = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: X48459 [in X48459.java [in p48459.p1 [in src [in TypeHierarchy]]]]\n" + |
| "Super types:\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n" + |
| " <anonymous #1> [in foo [in Z48459 [in Z48459.java [in p48459.p1 [in src [in TypeHierarchy]]]]]]\n" + |
| " Y48459 [in Y48459.class [in p48459.p2 [in lib48459 [in TypeHierarchy]]]]\n", |
| h); |
| } |
| /** |
| * Ensures that the superclass can be retrieved for a binary type's superclass. |
| */ |
| public void testBinaryTypeGetSuperclass() throws JavaScriptModelException { |
| IClassFile cf = getClassFile("TypeHierarchy", "lib.jar", "binary", "Y.class"); |
| IType type = cf.getType(); |
| ITypeHierarchy h= type.newSupertypeHierarchy(null); |
| IType superclass= h.getSuperclass(type); |
| assertTrue("Superclass not found forY", superclass != null); |
| assertEquals("Unexpected superclass of Y", "X", superclass.getElementName()); |
| } |
| /** |
| * Ensures that the superclass can be retrieved for a binary type's superclass. |
| * This is a relatively deep type hierarchy. |
| */ |
| public void testBinaryTypeGetSuperclass2() throws JavaScriptModelException { |
| IClassFile cf = getClassFile("TypeHierarchy", "lib.jar", "binary", "Deep.class"); |
| IType type = cf.getType(); |
| ITypeHierarchy h= type.newSupertypeHierarchy(null); |
| IType superclass= h.getSuperclass(type); |
| assertTrue("Superclass not found for Deep", superclass != null); |
| assertEquals("Unexpected superclass of Deep", "Z", superclass.getElementName()); |
| } |
| /* |
| * Ensures that a hierarchy can be constructed on a binary type in a jar that is hidden by another jar with the same type. |
| * (regression test for bug |
| */ |
| public void testBinaryTypeHiddenByOtherJar() throws CoreException, IOException { |
| String externalJar1 = null; |
| String externalJar2 = null; |
| try { |
| externalJar1 = Util.getOutputDirectory() + File.separator + "test1.jar"; |
| Util.createJar( |
| new String[] { |
| "p/X.js", |
| "package p;\n" + |
| "public class X {\n" + |
| "}" , |
| "p/Y.js", |
| "package p;\n" + |
| "public class Y extends X {\n" + |
| "}" |
| }, |
| new HashMap(), |
| externalJar1 |
| ); |
| externalJar2 = Util.getOutputDirectory() + File.separator + "test2.jar"; |
| Util.createJar( |
| new String[] { |
| "p/X.js", |
| "package p;\n" + |
| "public class X {\n" + |
| "}" , |
| "p/Y.js", |
| "package p;\n" + |
| "public class Y extends X {\n" + |
| "}" |
| }, |
| new HashMap(), |
| externalJar2 |
| ); |
| IJavaScriptProject project = createJavaProject("P", new String[] {}, new String[] {"JCL_LIB", externalJar1, externalJar2}); |
| IType focus = project.getPackageFragmentRoot(externalJar2).getPackageFragment("p").getClassFile("Y.class").getType(); |
| assertHierarchyEquals( |
| "Focus: Y [in Y.class [in p [in " + externalJar2 + "]]]\n" + |
| "Super types:\n" + |
| " X [in X.class [in p [in " + externalJar1 + "]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| focus.newTypeHierarchy(null) |
| ); |
| } finally { |
| if (externalJar1 != null) |
| Util.delete(externalJar1); |
| if (externalJar2 != null) |
| Util.delete(externalJar2); |
| deleteProject("P"); |
| } |
| } |
| /* |
| * Ensures that a hierarchy can be constructed on a binary type in a jar that has '.class' in its name. |
| * (regression test for bug 157035 "Open Type Hierarchy" fails if subtype is anonymous or local class and location for this subtype contains ".class") |
| */ |
| public void testBinaryTypeInDotClassJar() throws CoreException, IOException { |
| String externalJar = null; |
| try { |
| externalJar = Util.getOutputDirectory() + File.separator + "test.classic.jar"; |
| Util.createJar( |
| new String[] { |
| "p/X.js", |
| "package p;\n" + |
| "public class X {\n" + |
| "}" , |
| "p/Y.js", |
| "package p;\n" + |
| "public class Y {\n" + |
| " void foo() {\n" + |
| " new X() {\n" + |
| " };\n" + |
| " }\n" + |
| "}" |
| }, |
| new HashMap(), |
| externalJar |
| ); |
| IJavaScriptProject project = createJavaProject("P", new String[] {}, new String[] {"JCL_LIB", externalJar}); |
| IType focus = project.getPackageFragmentRoot(externalJar).getPackageFragment("p").getClassFile("X.class").getType(); |
| assertHierarchyEquals( |
| "Focus: X [in X.class [in p [in " + externalJar + "]]]\n" + |
| "Super types:\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n" + |
| " <anonymous> [in Y$1.class [in p [in " + externalJar + "]]]\n", |
| focus.newTypeHierarchy(null) |
| ); |
| } finally { |
| if (externalJar != null) |
| Util.delete(externalJar); |
| deleteProject("P"); |
| } |
| } |
| /** |
| * Ensures that the creation of a type hierarchy can be cancelled. |
| */ |
| public void testCancel() throws JavaScriptModelException { |
| boolean isCanceled = false; |
| IType type = getCompilationUnit("TypeHierarchy", "src", "p1", "X.js").getType("X"); |
| IRegion region = JavaScriptCore.newRegion(); |
| region.add(getPackageFragmentRoot("TypeHierarchy", "src")); |
| try { |
| TestProgressMonitor monitor = TestProgressMonitor.getInstance(); |
| monitor.setCancelledCounter(1); |
| type.getJavaScriptProject().newTypeHierarchy(type, region, monitor); |
| } catch (OperationCanceledException e) { |
| isCanceled = true; |
| } |
| assertTrue("Operation should have thrown an operation canceled exception", isCanceled); |
| } |
| /** |
| * Ensures that contains(...) returns true for a type that is part of the |
| * hierarchy and false otherwise. |
| */ |
| public void testContains() throws JavaScriptModelException { |
| // regular class |
| IClassFile cf = getClassFile("TypeHierarchy", "lib.jar", "binary", "X.class"); |
| IType type = cf.getType(); |
| assertTrue("X must be included", this.typeHierarchy.contains(type)); |
| |
| // root class |
| cf = getClassFile("TypeHierarchy", getSystemJsPathString(), "java.lang", "Object.class"); |
| type = cf.getType(); |
| assertTrue("Object must be included", this.typeHierarchy.contains(type)); |
| |
| // interface |
| cf = getClassFile("TypeHierarchy", "lib.jar", "binary", "I.class"); |
| assertTrue("I must be included", this.typeHierarchy.contains(type)); |
| } |
| public void testCycle() throws JavaScriptModelException { |
| IType type = getCompilationUnit("/TypeHierarchy/src/cycle/X.js").getType("X"); |
| ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: X [in X.java [in cycle [in src [in TypeHierarchy]]]]\n" + |
| "Super types:\n" + |
| " Y [in Y.java [in cycle [in src [in TypeHierarchy]]]]\n" + |
| "Sub types:\n", |
| hierarchy |
| ); |
| } |
| public void testCycle2() throws JavaScriptModelException { |
| IType type = getCompilationUnit("/TypeHierarchy15/src/CycleParent.js").getType("CycleParent"); |
| ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: CycleParent [in CycleParent.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| "Super types:\n" + |
| " CycleBase [in CycleBase.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| "Sub types:\n", |
| hierarchy |
| ); |
| } |
| /* |
| * Ensures that creating a type hierarchy accross multiple project is efficient enough. |
| */ |
| public void testEfficiencyMultipleProjects() throws CoreException { |
| try { |
| createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}); |
| createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] {"/P1"}); |
| createJavaProject("P3", new String[] {""}, new String[] {"JCL_LIB"}, new String[] {"/P1"}); |
| createFile("/P1/X.js", "public class X {}"); |
| createFile("/P3/Y.js", "public class Y extends X {}"); |
| createFile("/P3/Z.js", "public class Z extends X {}"); |
| createFile("/P2/W.js", "public class W extends X {}"); |
| IType type = getCompilationUnit("/P1/X.js").getType("X"); |
| class ProgressCounter extends TestProgressMonitor { |
| int count = 0; |
| public boolean isCanceled() { |
| this.count++; |
| return false; |
| } |
| } |
| ProgressCounter counter = new ProgressCounter(); |
| type.newTypeHierarchy(counter); |
| assertEquals("Unexpected work count", 18, counter.count); |
| } finally { |
| deleteProjects(new String[] {"P1", "P2", "P3"}); |
| } |
| } |
| /* |
| * Ensures that a hierarchy can be created with a potential subtype in an empty primary working copy |
| * (regression test for bug 65677 Creating hierarchy failed. See log for details. 0) |
| */ |
| public void testEmptyWorkingCopyPotentialSubtype() throws JavaScriptModelException { |
| IJavaScriptUnit workingCopy = null; |
| try { |
| workingCopy = getCompilationUnit("/TypeHierarchy/src/q4/Y.js"); |
| workingCopy.becomeWorkingCopy(null); |
| workingCopy.getBuffer().setContents(""); |
| workingCopy.makeConsistent(null); |
| |
| IType type = getCompilationUnit("/TypeHierarchy/src/q4/X.js").getType("X"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: X [in X.java [in q4 [in src [in TypeHierarchy]]]]\n" + |
| "Super types:\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } finally { |
| if (workingCopy != null) |
| workingCopy.discardWorkingCopy(); |
| } |
| } |
| /* |
| * Ensures that a hierarchy on a type with local and anonymous types is correct. |
| */ |
| public void testFocusWithLocalAndAnonymousTypes() throws JavaScriptModelException { |
| IType type = getCompilationUnit("TypeHierarchy", "src", "p7", "X.js").getType("X"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: X [in X.java [in p7 [in src [in TypeHierarchy]]]]\n" + |
| "Super types:\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n" + |
| " <anonymous #1> [in <initializer #2> [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| " Y2 [in foo() [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| " <anonymous #1> [in field1 [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| " <anonymous #1> [in field2 [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| " <anonymous #1> [in foo() [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| " <anonymous #1> [in <initializer #1> [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| " <anonymous #2> [in field2 [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| " Y1 [in foo() [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| " Y2 [in <initializer #1> [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| " Y1 [in <initializer #1> [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n", |
| hierarchy); |
| } |
| /* |
| * Ensures that a hierarchy on a generic type can be opened |
| */ |
| public void testGeneric01() throws JavaScriptModelException { |
| IType type = getCompilationUnit("/TypeHierarchy15/src/X.js").getType("X"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: X [in X.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| "Super types:\n" + |
| " ArrayList [in ArrayList.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " List [in List.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " AbstractList [in AbstractList.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " List [in List.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| "Sub types:\n", |
| hierarchy |
| ); |
| } |
| /* |
| * Ensures that a hierarchy on a generic type can be opened |
| */ |
| public void testGeneric02() throws JavaScriptModelException { |
| IType type = getPackageFragmentRoot("/TypeHierarchy15/lib15.jar").getPackageFragment("util").getClassFile("ArrayList.class").getType(); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: ArrayList [in ArrayList.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| "Super types:\n" + |
| " AbstractList [in AbstractList.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " List [in List.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| "Sub types:\n" + |
| " X [in X.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| " Y [in Y.java [in <default> [in src [in TypeHierarchy15]]]]\n", |
| hierarchy |
| ); |
| } |
| /* |
| * Ensures that a hierarchy on a generic type can be opened |
| */ |
| public void testGeneric03() throws JavaScriptModelException { |
| IType type = getCompilationUnit("/TypeHierarchy15/src/Y.js").getType("Y"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: Y [in Y.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| "Super types:\n" + |
| " ArrayList [in ArrayList.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " List [in List.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " AbstractList [in AbstractList.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " List [in List.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| "Sub types:\n", |
| hierarchy |
| ); |
| } |
| /* |
| * Ensures that a super type hierarchy on a generic type can be opened |
| * (regression test for bug 72348 [1.5][Type Hierarchy] Super type hierarchy of class extending generic type is empty) |
| */ |
| public void testGeneric04() throws JavaScriptModelException { |
| IType type = getCompilationUnit("/TypeHierarchy15/src/X.js").getType("X"); |
| ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: X [in X.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| "Super types:\n" + |
| " ArrayList [in ArrayList.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " List [in List.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " AbstractList [in AbstractList.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " List [in List.class [in util [in lib15.jar [in TypeHierarchy15]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| "Sub types:\n", |
| hierarchy |
| ); |
| } |
| /* |
| * Ensures that a hierarchy on a generic interface can be opened |
| * (regression test for bug 82004 [model][5.0] 3.1M4 type hierarchy for generic interface) |
| */ |
| public void testGeneric05() throws JavaScriptModelException { |
| IType type = getCompilationUnit("/TypeHierarchy15/src/I.js").getType("I"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: I [in I.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| "Super types:\n" + |
| "Sub types:\n" + |
| " A [in A.java [in <default> [in src [in TypeHierarchy15]]]]\n", |
| hierarchy |
| ); |
| } |
| /* |
| * Ensure that the key of a binary type in a hierarchy is correct when this type is not part of the Java model cache. |
| * (regression test for bug 93854 IAE in Util.scanTypeSignature when scanning a signature retrieved from a binding key) |
| */ |
| public void testGeneric06() throws CoreException { |
| getJavaProject("TypeHierarcht15").close(); |
| IType type = getClassFile("TypeHierarchy15","lib15.jar", "util", "AbstractList.class").getType(); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| IType[] subtypes = hierarchy.getSubclasses(type); |
| assertEquals("Unexpected key", "Lutil/Map<TK;TV;>;", subtypes.length < 2 ? null : subtypes[1].getKey()); |
| } |
| /* |
| * Ensures that a hierarchy on a generic type that is extended using a member as a type parameter can be opened |
| * (regression test for bug 99606 Subtype not found if parameterized on inner class) |
| */ |
| public void testGeneric07() throws JavaScriptModelException { |
| IType type = getCompilationUnit("/TypeHierarchy15/src/Y99606.js").getType("Y99606"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: Y99606 [in Y99606.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| "Super types:\n" + |
| " Object [in Object.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| "Sub types:\n" + |
| " X99606 [in X99606.java [in <default> [in src [in TypeHierarchy15]]]]\n", |
| hierarchy |
| ); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=108740 |
| public void testGeneric08() throws JavaScriptModelException { |
| IType type = getCompilationUnit("/TypeHierarchy15/src/D108740.js").getType("D108740"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: D108740 [in D108740.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| "Super types:\n" + |
| " B108740 [in B108740.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| " A108740 [in A108740.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| "Sub types:\n", |
| hierarchy |
| ); |
| } |
| /* |
| * Ensures that a hierarchy is where a type inherits conflicting paratemerized types is still correctly reported |
| * (regression test for bug 136095 Type Hierarchy incomplete with illegally parameterized superinterfaces) |
| */ |
| public void testGeneric09() throws CoreException { |
| try { |
| createFile( |
| "/TypeHierarchy15/src/I1_136095.js", |
| "public interface I1_136095<E> {\n" + |
| "}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/I2_136095.js", |
| "public interface I2_136095 extends I1_136095<String>{\n" + |
| "}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/X_136095.js", |
| "public abstract class X_136095 implements I1_136095<Integer>, I2_136095 {\n" + |
| "}" |
| ); |
| IType type = getCompilationUnit("/TypeHierarchy15/src/X_136095.js").getType("X_136095"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: X_136095 [in X_136095.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| "Super types:\n" + |
| " I1_136095 [in I1_136095.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| " I2_136095 [in I2_136095.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| " I1_136095 [in I1_136095.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| "Sub types:\n", |
| hierarchy |
| ); |
| } finally { |
| deleteFile("/TypeHierarchy15/src/I1_136095.js"); |
| deleteFile("/TypeHierarchy15/src/I2_136095.js"); |
| deleteFile("/TypeHierarchy15/src/X_136095.js"); |
| } |
| } |
| /* |
| * Ensures that a super type hierarchy is where the focus type implements a generic type with a qualified type parameter is correct |
| * (regression test for bug 140340 [5.0][templates] foreach template does not work when an Iterable over a static inner class exists) |
| */ |
| public void testGeneric10() throws CoreException { |
| try { |
| createFile( |
| "/TypeHierarchy15/src/Y_140340.js", |
| "public class Y_140340 {\n" + |
| " public static class Z {\n" + |
| " }\n" + |
| "}" |
| ); |
| createFile( |
| "/TypeHierarchy15/src/X_140340.js", |
| "public class X_140340 implements I1_140340<Y_140340.Z> {\n" + |
| "}\n" + |
| "interface I1_140340<T> {\n" + |
| "}" |
| ); |
| IType type = getCompilationUnit("/TypeHierarchy15/src/X_140340.js").getType("X_140340"); |
| ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: X_140340 [in X_140340.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| "Super types:\n" + |
| " I1_140340 [in X_140340.java [in <default> [in src [in TypeHierarchy15]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getExternalJCLPathString("1.5") + "]]]\n" + |
| "Sub types:\n", |
| hierarchy |
| ); |
| } finally { |
| deleteFile("/TypeHierarchy15/src/Y_140340.js"); |
| deleteFile("/TypeHierarchy15/src/X_140340.js"); |
| } |
| } |
| /** |
| * Ensures the correctness of all classes in a type hierarchy based on a region. |
| */ |
| public void testGetAllClassesInRegion() { |
| IType[] types = this.typeHierarchy.getAllClasses(); |
| assertTypesEqual( |
| "Unexpected all classes in hierarchy", |
| "binary.Deep\n" + |
| "binary.X\n" + |
| "binary.Y\n" + |
| "binary.Y$Inner\n" + |
| "binary.Z\n" + |
| "java.lang.Object\n" + |
| "rich.A\n" + |
| "rich.B\n" + |
| "rich.C\n", |
| types); |
| } |
| /** |
| * Ensures that the correct subtypes of a type exist in the type |
| * hierarchy. |
| */ |
| public void testGetAllSubtypes() throws JavaScriptModelException { |
| IType type = getCompilationUnit("TypeHierarchy", "src", "p1", "X.js").getType("X"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| IType[] types = hierarchy.getAllSubtypes(type); |
| this.assertTypesEqual( |
| "Unexpected sub types of X", |
| "p1.Deep\n" + |
| "p1.Y\n" + |
| "p1.Z\n", |
| types |
| ); |
| } |
| /** |
| * Ensures that the correct subtypes of a binary type |
| * exit in the type hierarchy created on a region. |
| */ |
| public void testGetAllSubtypesFromBinary() throws JavaScriptModelException { |
| IType type = getClassFile("TypeHierarchy", "lib.jar", "binary", "X.class").getType(); |
| IRegion region = JavaScriptCore.newRegion(); |
| region.add(type.getPackageFragment()); |
| ITypeHierarchy hierarchy = type.getJavaScriptProject().newTypeHierarchy(type, region, null); |
| IType[] types = hierarchy.getAllSubtypes(type); |
| assertTypesEqual( |
| "Unexpected all subtypes of binary.X", |
| "binary.Deep\n" + |
| "binary.Y\n" + |
| "binary.Y$Inner\n" + |
| "binary.Z\n", |
| types); |
| } |
| |
| /** |
| * Ensures that the correct superclasses of a type exist in the type |
| * hierarchy. |
| */ |
| public void testGetAllSuperclasses() throws JavaScriptModelException { |
| IType type = getCompilationUnit("TypeHierarchy", "src", "p1", "Z.js").getType("Z"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| IType[] types = hierarchy.getAllSuperclasses(type); |
| assertTypesEqual( |
| "Unexpected all super classes of Z", |
| "java.lang.Object\n" + |
| "p1.X\n" + |
| "p1.Y\n", |
| types); |
| } |
| |
| /** |
| * Ensures that the correct superclasses of a binary type exist in the type hierarchy. |
| * (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53095) |
| */ |
| public void testGetAllSuperclassesFromBinary() throws JavaScriptModelException { |
| String fileName = "TypeHierarchy/lib53095/p53095/X53095.class"; //$NON-NLS-1$ |
| IJavaScriptElement javaElement = JavaScriptCore.create(getFile(fileName)); |
| assertNotNull("Problem to get class file \""+fileName+"\"", javaElement); |
| assertTrue("Invalid type for class file \""+fileName+"\"", javaElement instanceof IClassFile); |
| IType type = ((IClassFile) javaElement).getType(); |
| ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null); // it works when we use newTypeHierarchy(null) |
| IType[] types = hierarchy.getAllSuperclasses(type); |
| assertTypesEqual( |
| "Unexpected all super classes of X53095", |
| "java.lang.RuntimeException\n" + |
| "java.lang.Exception\n" + |
| "java.lang.Throwable\n" + |
| "java.lang.Object\n", |
| types, |
| false); |
| } |
| |
| /** |
| * Ensures that the correct superclasses of a binary type exist in the type hierarchy. |
| * (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=54043) |
| */ |
| public void testGetAllSuperclassesFromBinary2() throws JavaScriptModelException { |
| IClassFile cf = getClassFile("TypeHierarchy", "test54043.jar", "p54043", "X54043.class"); |
| IType type = cf.getType(); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| IType[] types = hierarchy.getAllSuperclasses(type); |
| assertTypesEqual( |
| "Unexpected all super classes of X54043", |
| "java.lang.RuntimeException\n" + |
| "java.lang.Exception\n" + |
| "java.lang.Throwable\n" + |
| "java.lang.Object\n", |
| types, |
| false); |
| } |
| /** |
| * Ensures that the correct supertypes of a type exist in the type |
| * hierarchy. |
| */ |
| public void testGetAllSupertypes() throws JavaScriptModelException { |
| IType type = getCompilationUnit("TypeHierarchy", "src", "p1", "Z.js").getType("Z"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| IType[] types = hierarchy.getAllSuperclasses(type); |
| assertTypesEqual( |
| "Unexpected all super types of Z", |
| "java.lang.Object\n" + |
| "p1.I1\n" + |
| "p1.I2\n" + |
| "p1.X\n" + |
| "p1.Y\n", |
| types); |
| } |
| /** |
| * Ensures that the correct supertypes of a type exist in the type |
| * hierarchy. |
| * (regression test for bug 23644 hierarchy: getAllSuperTypes does not include all superinterfaces?) |
| */ |
| public void testGetAllSupertypes2() throws JavaScriptModelException { |
| IType type = getCompilationUnit("TypeHierarchy", "src", "p3", "B.js").getType("B"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| IType[] types = hierarchy.getAllSuperclasses(type); |
| assertTypesEqual( |
| "Unexpected all super types of B", |
| "java.lang.Object\n" + |
| "p3.A\n" + |
| "p3.I\n" + |
| "p3.I1\n", |
| types); |
| } |
| /** |
| * Ensures that the correct types exist in the type |
| * hierarchy. |
| */ |
| public void testGetAllTypes() throws JavaScriptModelException { |
| IType type = getCompilationUnit("TypeHierarchy", "src", "p1", "Y.js").getType("Y"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| this.assertTypesEqual( |
| "Unexpected types in hierarchy of Y", |
| "java.lang.Object\n" + |
| "p1.Deep\n" + |
| "p1.I1\n" + |
| "p1.I2\n" + |
| "p1.X\n" + |
| "p1.Y\n" + |
| "p1.Z\n", |
| hierarchy.getAllClasses() |
| ); |
| } |
| /** |
| * Ensures that the flags for an interface hierarchy are correctly cached |
| * (regression test for bug 60365 hierarchy view shows some interfaces as classes [type hierarchy]) |
| */ |
| public void testGetCachedFlags() throws JavaScriptModelException { |
| IType type1 = getClassFile("TypeHierarchy", "test60365.jar", "q4", "I1.class").getType(); |
| ITypeHierarchy hierarchy = type1.newTypeHierarchy(null); |
| IType type2 = getClassFile("TypeHierarchy", "test60365.jar", "q4", "I2.class").getType(); |
| int flags = hierarchy.getCachedFlags(type2); |
| } |
| /** |
| * Ensures that the correct root classes exist in the type |
| * hierarchy. |
| */ |
| public void testGetRootClasses() { |
| IType[] types = this.typeHierarchy.getRootClasses(); |
| assertTypesEqual( |
| "Unexpected root classes", |
| "java.lang.Object\n", |
| types); |
| } |
| /** |
| * Ensures that the correct number of subclasses exist in the type |
| * hierarchy created on a region. |
| */ |
| public void testGetSubclasses() throws JavaScriptModelException { |
| IType type = getClassFile("TypeHierarchy", "lib.jar", "binary", "X.class").getType(); |
| IType[] types = this.typeHierarchy.getSubclasses(type); |
| this.assertTypesEqual( |
| "Unexpected subclasses of binary.X", |
| "binary.Y\n", |
| types |
| ); |
| |
| type = getClassFile("TypeHierarchy", "lib.jar", "binary", "I.class").getType(); |
| types = this.typeHierarchy.getSubclasses(type); |
| this.assertTypesEqual( |
| "Unexpected subclasses of binary.I", |
| "", // interfaces cannot have a subclass |
| types |
| ); |
| } |
| /** |
| * Ensures that the correct number of subtypes exist in the type |
| * hierarchy created on a region. |
| */ |
| public void testGetSubtypes() throws JavaScriptModelException { |
| IType type = getClassFile("TypeHierarchy", "lib.jar", "binary", "X.class").getType(); |
| IType[] types = this.typeHierarchy.getSubclasses(type); |
| this.assertTypesEqual( |
| "Unexpected subtypes of binary.X", |
| "binary.Y\n", |
| types |
| ); |
| |
| type = getClassFile("TypeHierarchy", "lib.jar", "binary", "I.class").getType(); |
| types = this.typeHierarchy.getSubclasses(type); |
| this.assertTypesEqual( |
| "Unexpected subtypes of binary.I", |
| "binary.X\n" + |
| "binary.Y$Inner\n", |
| types |
| ); |
| } |
| |
| /** |
| * Ensures that the superclass is correct in the type |
| * hierarchy a type created on a region containing a package. |
| */ |
| public void testGetSuperclassInRegion() throws JavaScriptModelException { |
| IRegion r = JavaScriptCore.newRegion(); |
| IPackageFragment p = getPackageFragment("TypeHierarchy", "src", "p1"); |
| r.add(p); |
| ITypeHierarchy hierarchy = p.getJavaScriptProject().newTypeHierarchy(r, null); |
| |
| IType type = getCompilationUnit("TypeHierarchy", "src", "p1", "Y.js").getType("Y"); |
| IType superclass= hierarchy.getSuperclass(type); |
| assertEquals("Unexpected super class of Y", "X", superclass.getElementName()); |
| } |
| /** |
| * Ensures that the correct supertypes exist in the type |
| * hierarchy created on a region. |
| */ |
| public void testGetSupertypesInRegion() throws JavaScriptModelException { |
| IType type = getClassFile("TypeHierarchy", "lib.jar", "binary", "Y.class").getType(); |
| IType superType = this.typeHierarchy.getSuperclass(type); |
| assertTypesEqual( |
| "Unexpected super types of Y", |
| "binary.X\n", |
| new IType[]{superType}); |
| } |
| /** |
| * Ensures that the correct supertypes exist in the type |
| * hierarchy created on a region containing a project. |
| */ |
| public void testGetSupertypesWithProjectRegion() throws JavaScriptModelException { |
| IJavaScriptProject project = getJavaProject("TypeHierarchy"); |
| IRegion region= JavaScriptCore.newRegion(); |
| region.add(project); |
| IType type = getClassFile("TypeHierarchy", "lib.jar", "binary", "Y.class").getType(); |
| ITypeHierarchy hierarchy = project.newTypeHierarchy(type, region, null); |
| IType superType = hierarchy.getSuperclass(type); |
| assertTypesEqual( |
| "Unexpected super types of Y", |
| "binary.X\n", |
| new IType[]{superType}); |
| } |
| /** |
| * Ensures that getType() returns the type the hierarchy was created for. |
| */ |
| public void testGetType() throws JavaScriptModelException { |
| // hierarchy created on a type |
| IClassFile cf = getClassFile("TypeHierarchy", "lib.jar", "binary", "Y.class"); |
| IType type = cf.getType(); |
| ITypeHierarchy hierarchy = null; |
| try { |
| hierarchy = type.newSupertypeHierarchy(null); |
| } catch (IllegalArgumentException iae) { |
| assertTrue("IllegalArgumentException", false); |
| } |
| assertEquals("Unexpected focus type", type, hierarchy.getType()); |
| |
| // hierarchy created on a region |
| assertTrue("Unexpected focus type for hierarchy on region", this.typeHierarchy.getType() == null); |
| } |
| /* |
| * Ensures that a hierarchy on an type that implements a binary inner interface is correct. |
| * (regression test for bug 58440 type hierarchy incomplete when implementing fully qualified interface) |
| */ |
| public void testImplementBinaryInnerInterface() throws JavaScriptModelException { |
| IClassFile cf = getClassFile("TypeHierarchy", "test58440.jar", "p58440", "Y.class"); |
| IType type = cf.getType(); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: Y [in Y.class [in p58440 [in test58440.jar [in TypeHierarchy]]]]\n" + |
| "Super types:\n" + |
| " Inner [in X$Inner.class [in p58440 [in test58440.jar [in TypeHierarchy]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } |
| /** |
| * Ensures that a hierarchy on an inner type is correctly rooted. |
| */ |
| public void testInnerType1() throws JavaScriptModelException { |
| IType type = getCompilationUnit("TypeHierarchy", "src", "p5", "X.js").getType("X").getType("Inner"); |
| ITypeHierarchy hierarchy = null; |
| try { |
| hierarchy = type.newTypeHierarchy(null); |
| } catch (IllegalArgumentException iae) { |
| assertTrue("IllegalArgumentException", false); |
| } |
| assertHierarchyEquals( |
| "Focus: Inner [in X [in X.java [in p5 [in src [in TypeHierarchy]]]]]\n" + |
| "Super types:\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } |
| |
| |
| /** |
| * Ensures that a hierarchy on an inner type has the correct subtype. |
| * (regression test for bug 43274 Type hierarchy broken) |
| */ |
| public void testInnerType2() throws JavaScriptModelException { |
| IType type = getCompilationUnit("TypeHierarchy", "src", "p6", "A.js").getType("A").getType("Inner"); |
| ITypeHierarchy hierarchy = null; |
| try { |
| hierarchy = type.newTypeHierarchy(null); |
| } catch (IllegalArgumentException iae) { |
| assertTrue("IllegalArgumentException", false); |
| } |
| assertHierarchyEquals( |
| "Focus: Inner [in A [in A.java [in p6 [in src [in TypeHierarchy]]]]]\n" + |
| "Super types:\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n" + |
| " B [in A.java [in p6 [in src [in TypeHierarchy]]]]\n", |
| hierarchy); |
| } |
| /* |
| * Ensures that a hierarchy on a local type in an initializer is correct. |
| */ |
| public void testLocalType1() throws JavaScriptModelException { |
| IType typeA = getCompilationUnit("TypeHierarchy", "src", "p7", "A.js").getType("A"); |
| IType type = typeA.getInitializer(1).getType("Y1", 1); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: Y1 [in <initializer #1> [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| "Super types:\n" + |
| " X [in X.java [in p7 [in src [in TypeHierarchy]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n" + |
| " Y2 [in <initializer #1> [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n", |
| hierarchy); |
| } |
| /* |
| * Ensures that a hierarchy on a local type in a second initializer is correct. |
| */ |
| public void testLocalType2() throws JavaScriptModelException { |
| IType typeA = getCompilationUnit("TypeHierarchy", "src", "p7", "A.js").getType("A"); |
| IType type = typeA.getInitializer(2).getType("Y3", 1); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: Y3 [in <initializer #2> [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| "Super types:\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } |
| /* |
| * Ensures that a hierarchy on a local type in a method declaration is correct. |
| */ |
| public void testLocalType3() throws JavaScriptModelException { |
| IType typeA = getCompilationUnit("TypeHierarchy", "src", "p7", "A.js").getType("A"); |
| IType type = typeA.getFunction("foo", new String[] {}).getType("Y2", 1); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: Y2 [in foo() [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| "Super types:\n" + |
| " Y1 [in foo() [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| " X [in X.java [in p7 [in src [in TypeHierarchy]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } |
| /* |
| * Ensures that a super type hierarchy on a local type in a method declaration is correct. |
| * (regression test for bug 44073 Override methods action does not work for local types [code manipulation]) |
| */ |
| public void testLocalType4() throws JavaScriptModelException { |
| IType typeA = getCompilationUnit("TypeHierarchy", "src", "p7", "A.js").getType("A"); |
| IType type = typeA.getFunction("foo", new String[] {}).getType("Y1", 1); |
| ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: Y1 [in foo() [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + |
| "Super types:\n" + |
| " X [in X.java [in p7 [in src [in TypeHierarchy]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } |
| /* |
| * Ensures that a type hierarchy on a member type with subtypes in another project is correct |
| * (regression test for bug 101019 RC3: Type Hierarchy does not find implementers/extenders of inner class/interface in other project) |
| */ |
| public void testMemberTypeSubtypeDifferentProject() throws CoreException { |
| try { |
| createJavaProject("P1"); |
| createFile( |
| "/P1/X.js", |
| "public class X {\n" + |
| " public class Member {\n" + |
| " }\n" + |
| "}" |
| ); |
| createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] {"/P1"}); |
| createFile( |
| "/P2/Y.js", |
| "public class Y extends X.Member {\n" + |
| "}" |
| ); |
| IType focus = getCompilationUnit("/P1/X.js").getType("X").getType("Member"); |
| ITypeHierarchy hierarchy = focus.newTypeHierarchy(null/*no progress*/); |
| assertHierarchyEquals( |
| "Focus: Member [in X [in X.java [in <default> [in <project root> [in P1]]]]]\n" + |
| "Super types:\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n" + |
| " Y [in Y.java [in <default> [in <project root> [in P2]]]]\n", |
| hierarchy); |
| } finally { |
| deleteProjects(new String[] {"P1", "P2"}); |
| } |
| } |
| /** |
| * Ensures that a hierarchy on a type that implements a missing interface is correctly rooted. |
| * (regression test for bug 24691 Missing interface makes hierarchy incomplete) |
| */ |
| public void testMissingInterface() throws JavaScriptModelException { |
| IType type = getCompilationUnit("TypeHierarchy", "src", "p4", "X.js").getType("X"); |
| ITypeHierarchy hierarchy = null; |
| try { |
| hierarchy = type.newTypeHierarchy(null); |
| } catch (IllegalArgumentException iae) { |
| assertTrue("IllegalArgumentException", false); |
| } |
| assertHierarchyEquals( |
| "Focus: X [in X.java [in p4 [in src [in TypeHierarchy]]]]\n" + |
| "Super types:\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } |
| /** |
| * Ensures that a potential subtype that is not in the classpth is handle correctly. |
| * (Regression test for PR #1G4GL9R) |
| */ |
| public void testPotentialSubtypeNotInClasspath() throws JavaScriptModelException { |
| IJavaScriptProject project = getJavaProject("TypeHierarchy"); |
| IJavaScriptUnit cu = getCompilationUnit("TypeHierarchy", "src", "p1", "X.js"); |
| IType type = cu.getType("X"); |
| ITypeHierarchy h = type.newTypeHierarchy(project, null); |
| IType[] types = h.getSubclasses(type); |
| this.assertTypesEqual( |
| "Unexpected sub types of X", |
| "p1.Y\n", |
| types |
| ); |
| } |
| /* |
| * Ensures that a type hierarchy on a region contains all subtypes |
| * (regression test for bug 47743 Open type hiearchy problems [type hierarchy]) |
| */ |
| public void testRegion1() throws JavaScriptModelException { |
| IPackageFragment pkg = getPackageFragment("TypeHierarchy", "src", "q1"); |
| IRegion region = JavaScriptCore.newRegion(); |
| region.add(pkg); |
| ITypeHierarchy h = pkg.getJavaScriptProject().newTypeHierarchy(region, null); |
| assertTypesEqual( |
| "Unexpected types in hierarchy", |
| "java.lang.Object\n" + |
| "q1.X\n" + |
| "q1.Z\n" + |
| "q2.Y\n", |
| h.getAllClasses() |
| ); |
| } |
| /* |
| * Ensures that a type hierarchy on a region contains all subtypes |
| * (regression test for bug 47743 Open type hiearchy problems [type hierarchy]) |
| */ |
| public void testRegion2() throws JavaScriptModelException { |
| IPackageFragment pkg = getPackageFragment("TypeHierarchy", "src", "q2"); |
| IRegion region = JavaScriptCore.newRegion(); |
| region.add(pkg); |
| ITypeHierarchy h = pkg.getJavaScriptProject().newTypeHierarchy(region, null); |
| assertTypesEqual( |
| "Unexpected types in hierarchy", |
| "java.lang.Object\n" + |
| "q1.X\n" + |
| "q2.Y\n", |
| h.getAllClasses() |
| ); |
| } |
| /* |
| * Ensures that a type hierarchy on a region contains anonymous/local types in this region |
| * (regression test for bug 48395 Hierarchy on region misses local classes) |
| */ |
| public void testRegion3() throws JavaScriptModelException { |
| IPackageFragment pkg = getPackageFragment("TypeHierarchy", "src", "p9"); |
| IRegion region = JavaScriptCore.newRegion(); |
| region.add(pkg); |
| ITypeHierarchy h = pkg.getJavaScriptProject().newTypeHierarchy(region, null); |
| assertTypesEqual( |
| "Unexpected types in hierarchy", |
| "java.lang.Object\n" + |
| "p9.X\n" + |
| "p9.X$1\n" + |
| "p9.X$Y\n", |
| h.getAllClasses() |
| ); |
| } |
| public void testRegion4() throws CoreException { |
| try { |
| IJavaScriptProject p1 = createJavaProject("P1"); |
| IJavaScriptProject p2 = createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] {"/P1"}); |
| IJavaScriptProject p3 = createJavaProject("P3", new String[] {""}, new String[] {"JCL_LIB"}, new String[] {"/P1"}); |
| createFile( |
| "/P1/X.js", |
| "public class X {\n" + |
| "}" |
| ); |
| createFile( |
| "/P2/Y.js", |
| "public class Y extends X X {\n" + |
| "}" |
| ); |
| createFile( |
| "/P3/Z.js", |
| "public class Z extends X X {\n" + |
| "}" |
| ); |
| IRegion region = JavaScriptCore.newRegion(); |
| region.add(p1); |
| region.add(p2); |
| region.add(p3); |
| ITypeHierarchy hierarchy = JavaScriptCore.newTypeHierarchy(region, null, null); |
| assertHierarchyEquals( |
| "Focus: <NONE>\n" + |
| "Sub types of root classes:\n" + |
| " Class [in Class.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| " Y [in Y.java [in <default> [in <project root> [in P2]]]]\n" + |
| " Z [in Z.java [in <default> [in <project root> [in P3]]]]\n" + |
| " String [in String.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| " Error [in Error.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| " CloneNotSupportedException [in CloneNotSupportedException.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| " IllegalMonitorStateException [in IllegalMonitorStateException.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| " InterruptedException [in InterruptedException.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| " RuntimeException [in RuntimeException.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| " Exception [in Exception.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| " Throwable [in Throwable.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| " X [in X.java [in <default> [in <project root> [in P1]]]]\n", |
| hierarchy); |
| } finally { |
| deleteProjects(new String[] {"P1", "P2", "P3"}); |
| } |
| } |
| /** |
| * @bug 150289: [hierarchy] NPE in hierarchy builder when region is empy |
| * @test Ensure that no NPE is thrown when IRegion has no associated project |
| * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=150289" |
| */ |
| public void testRegion_Bug150289() throws JavaScriptModelException { |
| ITypeHierarchy h = this.currentProject.newTypeHierarchy(JavaScriptCore.newRegion(), null); |
| assertEquals("Unexpected number of types in hierarchy", 0, h.getAllClasses().length); |
| } |
| //https://bugs.eclipse.org/bugs/show_bug.cgi?id=144976 |
| public void testResilienceToMissingBinaries() throws CoreException { |
| try { |
| createJavaProject("P", new String[] {"src"}, new String[] {"JCL_LIB", "/TypeHierarchy/test144976.jar"}); |
| createFolder("/P/src/tools/"); |
| createFile( |
| "/P/src/tools/DisplayTestResult2.js", |
| "pakage tools;\n" + |
| "import servlet.*;\n" + |
| "public class DisplayTestResult2 extends TmrServlet2 {\n" + |
| "}" |
| ); |
| createFolder("/P/src/servlet/"); |
| createFile( |
| "/P/src/servlet/TmrServlet2.js", |
| "pakage servlet;\n" + |
| "public class TmrServlet2 extends TmrServlet {\n" + |
| "}" |
| ); |
| createFile( |
| "/P/src/servlet/TmrServlet.js", |
| "pakage servlet;\n" + |
| "import gk.*;\n" + |
| "public class TmrServlet extends GKServlet {\n" + |
| "}" |
| ); |
| IType type = getCompilationUnit("P", "src", "tools", "DisplayTestResult2.js").getType("DisplayTestResult2"); |
| ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null); |
| assertNotNull(hierarchy.getSuperclass(type)); |
| assertHierarchyEquals( |
| "Focus: DisplayTestResult2 [in DisplayTestResult2.java [in tools [in src [in P]]]]\n" + |
| "Super types:\n" + |
| " TmrServlet2 [in TmrServlet2.java [in servlet [in src [in P]]]]\n" + |
| " TmrServlet [in TmrServlet.java [in servlet [in src [in P]]]]\n" + |
| " GKServlet [in GKServlet.class [in gk [in /TypeHierarchy/test144976.jar [in P]]]]\n" + |
| "Sub types:\n", |
| hierarchy); |
| } finally { |
| deleteProject("P"); |
| } |
| } |
| /* |
| * Ensures that the focus type is put as a non-resolved type |
| * (regression test for bug 92357 ITypeHierarchy#getType() should return an unresolved handle) |
| */ |
| public void testResolvedTypeAsFocus() throws CoreException { |
| try { |
| createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "", "1.5"); |
| String source = |
| "public class X {\n" + |
| " Y<String> field;\n" + |
| "}\n" + |
| "class Y<E> {\n" + |
| "}"; |
| createFile("/P/X.js", source); |
| int start = source.indexOf("Y"); |
| int end = source.indexOf("<String>"); |
| IJavaScriptElement[] elements = getCompilationUnit("/P/X.js").codeSelect(start, end-start); |
| IType focus = (IType) elements[0]; |
| ITypeHierarchy hierarchy = focus.newTypeHierarchy(null); |
| assertElementsEqual( |
| "Unexpected focus type in hierarchy", |
| "Y [in X.java [in <default> [in <project root> [in P]]]]", |
| new IJavaScriptElement[] {hierarchy.getType()}, |
| true/*show resolved info*/); |
| } finally { |
| deleteProject("P"); |
| } |
| } |
| /* |
| * Ensure that the order of roots is taken into account when a type is present in multiple roots. |
| * (regression test for bug 139555 [hierarchy] Opening a class from Type hierarchy will give the wrong one if source and compiled are in defined in project) |
| */ |
| public void testRootOrder() throws CoreException, IOException { |
| try { |
| IJavaScriptProject project = createJavaProject("P", new String[] {"abc"}, new String[] {"JCL_LIB"}); |
| createFolder("/P/abc/p"); |
| createFile( |
| "/P/abc/p/X.js", |
| "package p;\n"+ |
| "public class X {}" |
| ); |
| createFile( |
| "/P/abc/p/Y.js", |
| "package p;\n"+ |
| "public class Y extends X {}" |
| ); |
| addLibrary(project, "lib.jar", "libsrc.zip", new String[] { |
| "p/X.js", |
| "package p;\n"+ |
| "public class X {}", |
| "p/Y.js", |
| "package p;\n"+ |
| "public class Y extends X {}" |
| }, "1.4"); |
| IType type = getCompilationUnit("/P/abc/p/X.js").getType("X"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: X [in X.java [in p [in abc [in P]]]]\n" + |
| "Super types:\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n" + |
| " Y [in Y.java [in p [in abc [in P]]]]\n", |
| hierarchy); |
| } finally { |
| deleteProject("P"); |
| } |
| } |
| /** |
| * Ensures that the superclass can be retrieved for a source type's unqualified superclass. |
| */ |
| public void testSourceTypeGetSuperclass() throws JavaScriptModelException { |
| //unqualified superclass in a source type |
| IJavaScriptUnit cu = getCompilationUnit("TypeHierarchy", "src", "p1", "Y.js"); |
| IType type = cu.getType("Y"); |
| ITypeHierarchy h = type.newSupertypeHierarchy(null); |
| IType superclass = h.getSuperclass(type); |
| assertTrue("Superclass not found for Y", superclass != null); |
| assertEquals("Unexpected super class for Y", "X", superclass.getElementName()); |
| } |
| /** |
| * Ensures that the superclass can be retrieved for a source type's superclass when no superclass is specified |
| * in the source type. |
| */ |
| public void testSourceTypeGetSuperclass2() throws JavaScriptModelException { |
| //no superclass specified for a source type |
| IJavaScriptUnit cu = getCompilationUnit("TypeHierarchy", "src", "p1", "X.js"); |
| IType type = cu.getType("X"); |
| ITypeHierarchy h = type.newSupertypeHierarchy(null); |
| IType superclass = h.getSuperclass(type); |
| assertTrue("Superclass not found for X", superclass != null); |
| assertEquals("Unexpected super class for X", "Object", superclass.getElementName()); |
| } |
| /** |
| * Ensures that the superclass can be retrieved for a source type's superclass. |
| * This type hierarchy is relatively deep. |
| */ |
| public void testSourceTypeGetSuperclass3() throws JavaScriptModelException { |
| //no superclass specified for a source type |
| IJavaScriptUnit cu = getCompilationUnit("TypeHierarchy", "src", "p1", "Deep.js"); |
| IType type = cu.getType("Deep"); |
| ITypeHierarchy h = type.newSupertypeHierarchy(null); |
| IType superclass = h.getSuperclass(type); |
| assertTrue("Superclass not found for Deep", superclass != null); |
| assertEquals("Unexpected super class for Deep", "Z", superclass.getElementName()); |
| } |
| /** |
| * Ensures that the superclass can be retrieved when it is defined |
| * in the same compilation unit. |
| */ |
| public void testSourceTypeGetSuperclass4() throws JavaScriptModelException { |
| IJavaScriptUnit cu = getCompilationUnit("TypeHierarchy", "src", "p1", "A.js"); |
| IType type = cu.getType("A"); |
| ITypeHierarchy h = type.newSupertypeHierarchy(null); |
| IType superclass = h.getSuperclass(type); |
| assertTrue("Superclass not found for A", superclass != null); |
| assertEquals("Unexpected super class for A", "B", superclass.getElementName()); |
| } |
| |
| /** |
| * Ensures that no subclasses exist in a super type hierarchy for the focus type. |
| */ |
| public void testSupertypeHierarchyGetSubclasses() throws JavaScriptModelException { |
| IType type = getClassFile("TypeHierarchy", getSystemJsPathString(), "java.lang", "Object.class").getType(); |
| ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null); |
| IType[] types = hierarchy.getSubclasses(type); |
| assertTypesEqual( |
| "Unexpected subclasses of Object", |
| "", |
| types); |
| |
| IJavaScriptUnit cu = getCompilationUnit("TypeHierarchy", "src", "p1", "Y.js"); |
| type = cu.getType("Y"); |
| hierarchy = type.newSupertypeHierarchy(null); |
| types = hierarchy.getSubclasses(type); |
| assertTypesEqual( |
| "Unexpected subclasses of Y", |
| "", |
| types); |
| } |
| /** |
| * Ensures that no subtypes exist in a super type hierarchy for the focus type. |
| */ |
| public void testSupertypeHierarchyGetSubtypes() throws JavaScriptModelException { |
| IType type = getClassFile("TypeHierarchy", getSystemJsPathString(), "java.lang", "Object.class").getType(); |
| ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null); |
| IType[] types = hierarchy.getSubclasses(type); |
| assertTypesEqual( |
| "Unexpected subtypes of Object", |
| "", |
| types); |
| |
| IJavaScriptUnit cu = getCompilationUnit("TypeHierarchy", "src", "p1", "Y.js"); |
| type = cu.getType("Y"); |
| hierarchy = type.newSupertypeHierarchy(null); |
| types = hierarchy.getSubclasses(type); |
| assertTypesEqual( |
| "Unexpected subtypes of Y", |
| "", |
| types); |
| } |
| /** |
| * Ensures that a super type hierarchy can be created on a working copy. |
| * (regression test for bug 3446 type hierarchy: incorrect behavior wrt working copies (1GLDHOA)) |
| */ |
| public void testSupertypeHierarchyOnWorkingCopy() throws JavaScriptModelException { |
| IJavaScriptUnit cu = this.getCompilationUnit("TypeHierarchy", "src", "wc", "X.js"); |
| IJavaScriptUnit workingCopy = null; |
| try { |
| workingCopy = cu.getWorkingCopy(null); |
| workingCopy.createType( |
| "class B{\n" + |
| " void m(){\n" + |
| " }\n" + |
| " void f(){\n" + |
| " m();\n" + |
| " }\n" + |
| "}\n", |
| null, |
| true, |
| null); |
| workingCopy.createType( |
| "class A extends B{\n" + |
| " void m(){\n" + |
| " }\n" + |
| "}", |
| null, |
| true, |
| null); |
| IType typeA = workingCopy.getType("A"); |
| ITypeHierarchy hierarchy = typeA.newSupertypeHierarchy(null); |
| IType typeB = workingCopy.getType("B"); |
| assertTrue("hierarchy should contain B", hierarchy.contains(typeB)); |
| } finally { |
| if (workingCopy != null) { |
| workingCopy.discardWorkingCopy(); |
| } |
| } |
| } |
| /* |
| * Ensures that creating a hierarchy on a project with classpath problem doesn't throw a NPE |
| * (regression test for bug 49809 NPE from MethodVerifier) |
| */ |
| public void testSuperTypeHierarchyWithMissingBinary() throws JavaScriptModelException { |
| IJavaScriptProject project = getJavaProject("TypeHierarchy"); |
| IIncludePathEntry[] originalClasspath = project.getRawIncludepath(); |
| try { |
| int length = originalClasspath.length; |
| IIncludePathEntry[] newClasspath = new IIncludePathEntry[length+1]; |
| System.arraycopy(originalClasspath, 0, newClasspath, 0, length); |
| newClasspath[length] = JavaScriptCore.newLibraryEntry(new Path("/TypeHierarchy/test49809.jar"), null, null); |
| project.setRawIncludepath(newClasspath, null); |
| IJavaScriptUnit cu = getCompilationUnit("/TypeHierarchy/src/q3/Z.js"); |
| IType type = cu.getType("Z"); |
| ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: Z [in Z.java [in q3 [in src [in TypeHierarchy]]]]\n" + |
| "Super types:\n" + |
| " Y49809 [in Y49809.class [in p49809 [in test49809.jar [in TypeHierarchy]]]]\n" + |
| "Sub types:\n", |
| hierarchy |
| ); |
| } finally { |
| project.setRawIncludepath(originalClasspath, null); |
| } |
| } |
| /* |
| * Ensures that a hierarchy where the super type is not visible can still be constructed. |
| */ |
| public void testVisibility1() throws JavaScriptModelException { |
| IType type = getCompilationUnit("/TypeHierarchy/src/q6/Y.js").getType("Y"); |
| ITypeHierarchy hierarchy = type.newTypeHierarchy(null); |
| assertHierarchyEquals( |
| "Focus: Y [in Y.java [in q6 [in src [in TypeHierarchy]]]]\n" + |
| "Super types:\n" + |
| " NonVisibleClass [in X.java [in q5 [in src [in TypeHierarchy]]]]\n" + |
| " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + |
| "Sub types:\n", |
| hierarchy |
| ); |
| } |
| } |