/*******************************************************************************
 * 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<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
	);
}
}
