package com.intellij.flex.codeInsight; import com.intellij.flex.util.FlexTestUtils; import com.intellij.ide.hierarchy.CallHierarchyBrowserBase; import com.intellij.ide.hierarchy.HierarchyBrowserManager; import com.intellij.ide.hierarchy.TypeHierarchyBrowserBase; import com.intellij.javascript.flex.css.FlexStylesIndexableSetContributor; import com.intellij.javascript.flex.mxml.schema.FlexSchemaHandler; import com.intellij.lang.javascript.JSTestOption; import com.intellij.lang.javascript.JSTestOptions; import com.intellij.lang.javascript.JavaScriptSupportLoader; import com.intellij.lang.javascript.dialects.JSDialectSpecificHandlersFactory; import com.intellij.lang.javascript.flex.FlexModuleType; import com.intellij.lang.javascript.hierarchy.call.JSCalleeMethodsTreeStructure; import com.intellij.lang.javascript.hierarchy.call.JSCallerMethodsTreeStructure; import com.intellij.lang.javascript.hierarchy.method.JSMethodHierarchyTreeStructure; import com.intellij.lang.javascript.hierarchy.type.jsclass.JSSubtypesHierarchyTreeStructure; import com.intellij.lang.javascript.hierarchy.type.jsclass.JSSupertypesHierarchyTreeStructure; import com.intellij.lang.javascript.hierarchy.type.jsclass.JSTypeHierarchyTreeStructure; import com.intellij.lang.javascript.psi.JSFunction; import com.intellij.lang.javascript.psi.ecmal4.JSClass; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.testFramework.codeInsight.hierarchy.HierarchyViewTestBase; import static com.intellij.openapi.vfs.VfsUtilCore.convertFromUrl; import static com.intellij.openapi.vfs.VfsUtilCore.urlToPath; public class FlexHierarchyTest extends HierarchyViewTestBase { @Override protected void setUp() throws Exception { VfsRootAccess.allowRootAccess(getTestRootDisposable(), urlToPath(convertFromUrl(FlexSchemaHandler.class.getResource("z.xsd"))), urlToPath(convertFromUrl(FlexStylesIndexableSetContributor.class.getResource("FlexStyles.as")))); super.setUp(); } @Override protected String getTestDataPath() { return FlexTestUtils.getTestDataPath(""); } @Override protected String getBasePath() { return "hierarchy"; } @Override protected ModuleType getModuleType() { return FlexModuleType.getInstance(); } @Override protected void setUpJdk() { FlexTestUtils.setupFlexSdk(myModule, getTestName(false), getClass()); } private void doJSTypeHierarchyTest(final String hierarchyType, final String classFqn) throws Exception { doJSTypeHierarchyTest(hierarchyType, classFqn, getTestName(false) + ".as"); } private void doJSTypeHierarchyTest(final String hierarchyType, final String classFqn, final String... fileNames) throws Exception { doHierarchyTest(() -> { final JSClass jsClass = (JSClass)JSDialectSpecificHandlersFactory.forLanguage(JavaScriptSupportLoader.ECMA_SCRIPT_L4).getClassResolver() .findClassByQName(classFqn, GlobalSearchScope.moduleScope(myModule)); assert jsClass != null; if (TypeHierarchyBrowserBase.TYPE_HIERARCHY_TYPE.equals(hierarchyType)) { return new JSTypeHierarchyTreeStructure(myProject, jsClass); } else if (TypeHierarchyBrowserBase.SUBTYPES_HIERARCHY_TYPE.equals(hierarchyType)) { return new JSSubtypesHierarchyTreeStructure(myProject, jsClass); } else if (TypeHierarchyBrowserBase.SUPERTYPES_HIERARCHY_TYPE.equals(hierarchyType)) { return new JSSupertypesHierarchyTreeStructure(myProject, jsClass); } throw new IllegalArgumentException("Wrong hierarchy type: " + hierarchyType); }, fileNames); } private void doJSMethodHierarchyTest(final String classFqn, final String methodName, final boolean hideClassesWhereMethodNotImplemented, final String... fileNames) throws Exception { final HierarchyBrowserManager.State state = HierarchyBrowserManager.getInstance(myProject).getState(); final boolean oldState = state.HIDE_CLASSES_WHERE_METHOD_NOT_IMPLEMENTED; state.HIDE_CLASSES_WHERE_METHOD_NOT_IMPLEMENTED = hideClassesWhereMethodNotImplemented; doHierarchyTest(() -> { final JSClass jsClass = (JSClass)JSDialectSpecificHandlersFactory.forLanguage(JavaScriptSupportLoader.ECMA_SCRIPT_L4).getClassResolver() .findClassByQName(classFqn, GlobalSearchScope.moduleScope(myModule)); assert jsClass != null; final JSFunction jsFunction = jsClass.findFunctionByName(methodName); assert jsFunction != null; return new JSMethodHierarchyTreeStructure(myProject, jsFunction); }, fileNames); state.HIDE_CLASSES_WHERE_METHOD_NOT_IMPLEMENTED = oldState; } private void doJSCallHierarchyTest(final String hierarchyType, final String classFqn, final String methodName, final String scope, final String... fileNames) throws Exception { doHierarchyTest(() -> { final JSClass jsClass = (JSClass)JSDialectSpecificHandlersFactory.forLanguage(JavaScriptSupportLoader.ECMA_SCRIPT_L4).getClassResolver() .findClassByQName(classFqn, GlobalSearchScope.moduleScope(myModule)); assert jsClass != null; final JSFunction jsFunction = jsClass.findFunctionByName(methodName); assert jsFunction != null; if (CallHierarchyBrowserBase.CALLEE_TYPE.equals(hierarchyType)) { return new JSCalleeMethodsTreeStructure(myProject, jsFunction, scope); } else if (CallHierarchyBrowserBase.CALLER_TYPE.equals(hierarchyType)) { return new JSCallerMethodsTreeStructure(myProject, jsFunction, scope); } throw new IllegalArgumentException("Wrong hierarchy type: " + hierarchyType); }, fileNames); } public void testTypeHierarchy() throws Exception { doJSTypeHierarchyTest(TypeHierarchyBrowserBase.TYPE_HIERARCHY_TYPE, "mypack.SomeClass"); } public void testInterfacesHierarchy() throws Exception { final String testName = getTestName(false); doJSTypeHierarchyTest(TypeHierarchyBrowserBase.SUBTYPES_HIERARCHY_TYPE, "pack.Interface2", testName + ".as", testName + ".mxml"); } @JSTestOptions(JSTestOption.WithFlexSdk) public void testSupertypesHierarchy() throws Exception { final String testName = getTestName(false); doJSTypeHierarchyTest(TypeHierarchyBrowserBase.SUPERTYPES_HIERARCHY_TYPE, "pack2.Class2", testName + ".as", testName + ".mxml"); } private static final String COMMON_METHOD_HIERARCHY_RESOURCE_NAME = "MethodHierarchyCommon"; @JSTestOptions(JSTestOption.WithFlexSdk) public void testMethodHierarchyFromInterface() throws Exception { doJSMethodHierarchyTest("pack.Interface1", "foo", true, COMMON_METHOD_HIERARCHY_RESOURCE_NAME + ".as", COMMON_METHOD_HIERARCHY_RESOURCE_NAME + ".mxml"); } @JSTestOptions(JSTestOption.WithFlexSdk) public void testMethodHierarchyFromMxml() throws Exception { doJSMethodHierarchyTest(COMMON_METHOD_HIERARCHY_RESOURCE_NAME, "foo", false, COMMON_METHOD_HIERARCHY_RESOURCE_NAME + ".as", COMMON_METHOD_HIERARCHY_RESOURCE_NAME + ".mxml"); } @JSTestOptions(JSTestOption.WithFlexSdk) public void testMethodHierarchyFromAs() throws Exception { doJSMethodHierarchyTest("pack.Class2", "foo", true, COMMON_METHOD_HIERARCHY_RESOURCE_NAME + ".as", COMMON_METHOD_HIERARCHY_RESOURCE_NAME + ".mxml"); } @JSTestOptions(JSTestOption.WithFlexFacet) public void testMethodCalleeHierarchy() throws Exception { final String testName = getTestName(false); doJSCallHierarchyTest(CallHierarchyBrowserBase.CALLEE_TYPE, "pack.subpack.Class1", "someFunction", CallHierarchyBrowserBase.SCOPE_ALL, testName + ".as", testName + ".mxml"); } @JSTestOptions(JSTestOption.WithFlexFacet) public void testMethodCallerHierarchy() throws Exception { final String testName = getTestName(false); doJSCallHierarchyTest(CallHierarchyBrowserBase.CALLER_TYPE, "pack.Class1", "bar", CallHierarchyBrowserBase.SCOPE_PROJECT, testName + ".as"); } }