/******************************************************************************* * 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 v2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * 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 {\n" + "}", "util/ArrayList.js", "package util;\n" + "public class ArrayList extends AbstractList implements List {\n" + "}", "util/List.js", "package util;\n" + "public interface List {\n" + "}", "util/Map.js", "package util;\n" + "public class Map extends AbstractList {\n" + "}", }, JavaScriptCore.VERSION_1_5); createFile( "/TypeHierarchy15/src/X.js", "import util.*;\n" + "public class X extends ArrayList implements List {\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 {\n" + "}" ); createFile( "/TypeHierarchy15/src/A.js", "public class A implements I {\n" + "}" ); createFile( "/TypeHierarchy15/src/X99606.js", "public class X99606 extends Y99606 {\n" + " static class Color {}\n" + "}" ); createFile( "/TypeHierarchy15/src/Y99606.js", "public class Y99606 {\n" + "}" ); createFile( "/TypeHierarchy15/src/A108740.js", "class A108740 {}" ); createFile( "/TypeHierarchy15/src/B108740.js", "class B108740 extends A108740 {}" ); createFile( "/TypeHierarchy15/src/C108740.js", "class C108740 extends B108740 {}" ); createFile( "/TypeHierarchy15/src/D108740.js", "class D108740 extends B108740 {}" ); createFile( "/TypeHierarchy15/src/CycleParent.js", "class CycleParent extends CycleBase {}" ); createFile( "/TypeHierarchy15/src/CycleBase.js", "class CycleBase {}" ); createFile( "/TypeHierarchy15/src/CycleChild.js", "class CycleChild extends CycleParent implements Comparable {\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: [in [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: [in [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: [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: [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: [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: [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: [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 [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" + " [in ANONYMOUS [in Try [in Try.java [in [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: [in ANONYMOUS [in Try [in Try.java [in [in src [in TypeHierarchy15]]]]]]\n" + "Super types:\n" + " Try [in Try.java [in [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" + " [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 [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" + " [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" + " [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 [in src [in TypeHierarchy15]]]]\n" + "Super types:\n" + " CycleBase [in CycleBase.java [in [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" + " [in [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" + " [in field1 [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + " [in field2 [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + " [in foo() [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + " [in [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + " [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 [in A [in A.java [in p7 [in src [in TypeHierarchy]]]]]]\n" + " Y1 [in [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 [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 [in src [in TypeHierarchy15]]]]\n" + " Y [in Y.java [in [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 [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 [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 [in src [in TypeHierarchy15]]]]\n" + "Super types:\n" + "Sub types:\n" + " A [in A.java [in [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;", 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 [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 [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 [in src [in TypeHierarchy15]]]]\n" + "Super types:\n" + " B108740 [in B108740.java [in [in src [in TypeHierarchy15]]]]\n" + " A108740 [in A108740.java [in [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 {\n" + "}" ); createFile( "/TypeHierarchy15/src/I2_136095.js", "public interface I2_136095 extends I1_136095{\n" + "}" ); createFile( "/TypeHierarchy15/src/X_136095.js", "public abstract class X_136095 implements I1_136095, 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 [in src [in TypeHierarchy15]]]]\n" + "Super types:\n" + " I1_136095 [in I1_136095.java [in [in src [in TypeHierarchy15]]]]\n" + " I2_136095 [in I2_136095.java [in [in src [in TypeHierarchy15]]]]\n" + " I1_136095 [in I1_136095.java [in [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 {\n" + "}\n" + "interface I1_140340 {\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 [in src [in TypeHierarchy15]]]]\n" + "Super types:\n" + " I1_140340 [in X_140340.java [in [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 [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 [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 [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 [in [in P1]]]]]\n" + "Super types:\n" + " Object [in Object.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + "Sub types:\n" + " Y [in Y.java [in [in [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: \n" + "Sub types of root classes:\n" + " Class [in Class.class [in java.lang [in "+ getSystemJsPathString() + "]]]\n" + " Y [in Y.java [in [in [in P2]]]]\n" + " Z [in Z.java [in [in [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 [in [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 field;\n" + "}\n" + "class Y {\n" + "}"; createFile("/P/X.js", source); int start = source.indexOf("Y"); int end = source.indexOf(""); 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 [in [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 ); } }