From 9091becbea5b254ea1fb64736756400b521323f0 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Wed, 20 Mar 2013 16:36:15 +0400 Subject: [PATCH] Implement Class Hierarchy View #KT-3419 --- ...otlinLightClassForExplicitDeclaration.java | 7 + .../jet/generators/tests/GenerateTests.java | 18 +- idea/src/META-INF/plugin.xml | 2 + .../KotlinTypeHierarchyProvider.java | 109 ++++++++++ .../libraries/JetSourceNavigationHelper.java | 70 +++++++ .../KotlinDirectInheritorsSearcher.java | 8 +- .../ClassFromClass_verification.xml | 3 + .../class/sub/ClassFromClass/main.kt | 3 + .../TwoTraits/TwoTraits_verification.xml | 5 + .../hierarchy/class/super/TwoTraits/main.kt | 4 + .../CaretAtAnnotation_verification.xml | 1 + .../class/type/CaretAtAnnotation/main.kt | 5 + .../CaretAtConstructor_verification.xml | 3 + .../class/type/CaretAtConstructor/main.kt | 7 + .../CaretAtFabricMethod_verification.xml | 3 + .../class/type/CaretAtFabricMethod/main.kt | 9 + .../class/type/CaretAtImport/1_main.kt | 2 + .../class/type/CaretAtImport/2_kotlin.kt | 3 + .../CaretAtImport_verification.xml | 3 + .../CaretAtJavaType_verification.xml | 3 + .../class/type/CaretAtJavaType/main.kt | 3 + .../CaretAtModifierList_verification.xml | 3 + .../class/type/CaretAtModifierList/main.kt | 4 + .../CaretAtReceiverExtFun_verification.xml | 3 + .../class/type/CaretAtReceiverExtFun/main.kt | 5 + .../CaretAtSuperCall_verification.xml | 5 + .../class/type/CaretAtSuperCall/main.kt | 9 + .../CaretAtSupertypesList_verification.xml | 5 + .../class/type/CaretAtSupertypesList/main.kt | 6 + .../CaretAtTypeReference_verification.xml | 3 + .../class/type/CaretAtTypeReference/main.kt | 9 + .../CaretInClassBody_verification.xml | 3 + .../class/type/CaretInClassBody/main.kt | 5 + .../ClassFromClass_verification.xml | 5 + .../class/type/ClassFromClass/main.kt | 3 + .../ClassFromObject_verification.xml | 3 + .../class/type/ClassFromObject/main.kt | 2 + .../ClassInClassObject_verification.xml | 3 + .../class/type/ClassInClassObject/main.kt | 7 + .../ClassInPackage_verification.xml | 3 + .../class/type/ClassInPackage/main.kt | 3 + .../InnerClass/InnerClass_verification.xml | 3 + .../hierarchy/class/type/InnerClass/main.kt | 3 + .../class/type/JKJHierarchy/1_MyClass.java | 3 + .../class/type/JKJHierarchy/2_main.kt | 1 + .../type/JKJHierarchy/3_SecondClass.java | 3 + .../JKJHierarchy_verification.xml | 7 + .../class/type/JavaFromKotlin/1_MyClass.java | 3 + .../class/type/JavaFromKotlin/2_main.kt | 1 + .../JavaFromKotlin_verification.xml | 5 + .../JavaFromKotlinForKotlinClass/1_main.kt | 1 + .../2_MyClass.java | 3 + ...aFromKotlinForKotlinClass_verification.xml | 5 + .../class/type/KotlinFromJava/1_main.kt | 1 + .../type/KotlinFromJava/2_JavaClass.java | 3 + .../KotlinFromJava_verification.xml | 5 + .../class/type/Object/Object_verification.xml | 3 + .../hierarchy/class/type/Object/main.kt | 3 + .../TwoChildren/TwoChildren_verification.xml | 4 + .../hierarchy/class/type/TwoChildren/main.kt | 4 + .../hierarchy/AbstractHierarchyTest.java | 148 ++++++++++++++ .../hierarchy/HierarchyTestGenerated.java | 186 ++++++++++++++++++ 62 files changed, 749 insertions(+), 6 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/hierarchy/KotlinTypeHierarchyProvider.java create mode 100644 idea/testData/hierarchy/class/sub/ClassFromClass/ClassFromClass_verification.xml create mode 100644 idea/testData/hierarchy/class/sub/ClassFromClass/main.kt create mode 100644 idea/testData/hierarchy/class/super/TwoTraits/TwoTraits_verification.xml create mode 100644 idea/testData/hierarchy/class/super/TwoTraits/main.kt create mode 100644 idea/testData/hierarchy/class/type/CaretAtAnnotation/CaretAtAnnotation_verification.xml create mode 100644 idea/testData/hierarchy/class/type/CaretAtAnnotation/main.kt create mode 100644 idea/testData/hierarchy/class/type/CaretAtConstructor/CaretAtConstructor_verification.xml create mode 100644 idea/testData/hierarchy/class/type/CaretAtConstructor/main.kt create mode 100644 idea/testData/hierarchy/class/type/CaretAtFabricMethod/CaretAtFabricMethod_verification.xml create mode 100644 idea/testData/hierarchy/class/type/CaretAtFabricMethod/main.kt create mode 100644 idea/testData/hierarchy/class/type/CaretAtImport/1_main.kt create mode 100644 idea/testData/hierarchy/class/type/CaretAtImport/2_kotlin.kt create mode 100644 idea/testData/hierarchy/class/type/CaretAtImport/CaretAtImport_verification.xml create mode 100644 idea/testData/hierarchy/class/type/CaretAtJavaType/CaretAtJavaType_verification.xml create mode 100644 idea/testData/hierarchy/class/type/CaretAtJavaType/main.kt create mode 100644 idea/testData/hierarchy/class/type/CaretAtModifierList/CaretAtModifierList_verification.xml create mode 100644 idea/testData/hierarchy/class/type/CaretAtModifierList/main.kt create mode 100644 idea/testData/hierarchy/class/type/CaretAtReceiverExtFun/CaretAtReceiverExtFun_verification.xml create mode 100644 idea/testData/hierarchy/class/type/CaretAtReceiverExtFun/main.kt create mode 100644 idea/testData/hierarchy/class/type/CaretAtSuperCall/CaretAtSuperCall_verification.xml create mode 100644 idea/testData/hierarchy/class/type/CaretAtSuperCall/main.kt create mode 100644 idea/testData/hierarchy/class/type/CaretAtSupertypesList/CaretAtSupertypesList_verification.xml create mode 100644 idea/testData/hierarchy/class/type/CaretAtSupertypesList/main.kt create mode 100644 idea/testData/hierarchy/class/type/CaretAtTypeReference/CaretAtTypeReference_verification.xml create mode 100644 idea/testData/hierarchy/class/type/CaretAtTypeReference/main.kt create mode 100644 idea/testData/hierarchy/class/type/CaretInClassBody/CaretInClassBody_verification.xml create mode 100644 idea/testData/hierarchy/class/type/CaretInClassBody/main.kt create mode 100644 idea/testData/hierarchy/class/type/ClassFromClass/ClassFromClass_verification.xml create mode 100644 idea/testData/hierarchy/class/type/ClassFromClass/main.kt create mode 100644 idea/testData/hierarchy/class/type/ClassFromObject/ClassFromObject_verification.xml create mode 100644 idea/testData/hierarchy/class/type/ClassFromObject/main.kt create mode 100644 idea/testData/hierarchy/class/type/ClassInClassObject/ClassInClassObject_verification.xml create mode 100644 idea/testData/hierarchy/class/type/ClassInClassObject/main.kt create mode 100644 idea/testData/hierarchy/class/type/ClassInPackage/ClassInPackage_verification.xml create mode 100644 idea/testData/hierarchy/class/type/ClassInPackage/main.kt create mode 100644 idea/testData/hierarchy/class/type/InnerClass/InnerClass_verification.xml create mode 100644 idea/testData/hierarchy/class/type/InnerClass/main.kt create mode 100644 idea/testData/hierarchy/class/type/JKJHierarchy/1_MyClass.java create mode 100644 idea/testData/hierarchy/class/type/JKJHierarchy/2_main.kt create mode 100644 idea/testData/hierarchy/class/type/JKJHierarchy/3_SecondClass.java create mode 100644 idea/testData/hierarchy/class/type/JKJHierarchy/JKJHierarchy_verification.xml create mode 100644 idea/testData/hierarchy/class/type/JavaFromKotlin/1_MyClass.java create mode 100644 idea/testData/hierarchy/class/type/JavaFromKotlin/2_main.kt create mode 100644 idea/testData/hierarchy/class/type/JavaFromKotlin/JavaFromKotlin_verification.xml create mode 100644 idea/testData/hierarchy/class/type/JavaFromKotlinForKotlinClass/1_main.kt create mode 100644 idea/testData/hierarchy/class/type/JavaFromKotlinForKotlinClass/2_MyClass.java create mode 100644 idea/testData/hierarchy/class/type/JavaFromKotlinForKotlinClass/JavaFromKotlinForKotlinClass_verification.xml create mode 100644 idea/testData/hierarchy/class/type/KotlinFromJava/1_main.kt create mode 100644 idea/testData/hierarchy/class/type/KotlinFromJava/2_JavaClass.java create mode 100644 idea/testData/hierarchy/class/type/KotlinFromJava/KotlinFromJava_verification.xml create mode 100644 idea/testData/hierarchy/class/type/Object/Object_verification.xml create mode 100644 idea/testData/hierarchy/class/type/Object/main.kt create mode 100644 idea/testData/hierarchy/class/type/TwoChildren/TwoChildren_verification.xml create mode 100644 idea/testData/hierarchy/class/type/TwoChildren/main.kt create mode 100644 idea/tests/org/jetbrains/jet/plugin/hierarchy/AbstractHierarchyTest.java create mode 100644 idea/tests/org/jetbrains/jet/plugin/hierarchy/HierarchyTestGenerated.java diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java index 872921375c8..71164d21b73 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java @@ -231,6 +231,13 @@ public class KotlinLightClassForExplicitDeclaration extends AbstractLightClass i return super.getContainingClass(); } + @Nullable + @Override + public PsiElement getParent() { + if (classOrObject.getParent() == classOrObject.getContainingFile()) return getContainingFile(); + return getContainingClass(); + } + @Nullable @Override public PsiTypeParameterList getTypeParameterList() { diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 6a43c2062c2..c584a151485 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -32,6 +32,7 @@ import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveNamespaceComparing import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveTest; import org.jetbrains.jet.plugin.codeInsight.surroundWith.AbstractSurroundWithTest; import org.jetbrains.jet.plugin.folding.AbstractKotlinFoldingTest; +import org.jetbrains.jet.plugin.hierarchy.AbstractHierarchyTest; import org.jetbrains.jet.plugin.highlighter.AbstractDeprecatedHighlightingTest; import org.jetbrains.jet.plugin.quickfix.AbstractQuickFixMultiFileTest; import org.jetbrains.jet.plugin.quickfix.AbstractQuickFixTest; @@ -83,7 +84,7 @@ public class GenerateTests { "compiler/tests/", "BlackBoxMultiFileCodegenTestGenerated", AbstractBlackBoxCodegenTest.class, - new SimpleTestClassModel(new File("compiler/testData/codegen/boxMultiFile"), false, Pattern.compile("^(.+)$"), "doTestMultiFile") + testModelWithDirectories(("compiler/testData/codegen/boxMultiFile"), "doTestMultiFile") ); generateTest( @@ -111,7 +112,7 @@ public class GenerateTests { "compiler/tests/", "TopLevelMembersInvocationTestGenerated", AbstractTopLevelMembersInvocationTest.class, - new SimpleTestClassModel(new File("compiler/testData/codegen/topLevelMemberInvocation"), false, Pattern.compile("^(.+)$"), "doTest") + testModelWithDirectories("compiler/testData/codegen/topLevelMemberInvocation", "doTest") ); generateTest( @@ -248,6 +249,15 @@ public class GenerateTests { testModel("idea/testData/codeInsight/surroundWith/tryFinally", "doTestWithTryFinallySurrounder"), testModel("idea/testData/codeInsight/surroundWith/functionLiteral", "doTestWithFunctionLiteralSurrounder") ); + + generateTest( + "idea/tests/", + "HierarchyTestGenerated", + AbstractHierarchyTest.class, + testModelWithDirectories("idea/testData/hierarchy/class/type", "doTypeClassHierarchyTest"), + testModelWithDirectories("idea/testData/hierarchy/class/super", "doSuperClassHierarchyTest"), + testModelWithDirectories("idea/testData/hierarchy/class/sub", "doSubClassHierarchyTest") + ); } private static SimpleTestClassModel testModel(@NotNull String rootPath) { @@ -258,6 +268,10 @@ public class GenerateTests { return testModel(rootPath, true, "kt", methodName); } + private static SimpleTestClassModel testModelWithDirectories(@NotNull String rootPath, @NotNull String methodName) { + return new SimpleTestClassModel(new File(rootPath), false, Pattern.compile("^(.+)$"), methodName); + } + private static SimpleTestClassModel testModel( @NotNull String rootPath, boolean recursive, diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 61cd3de7e53..8188ed8fae0 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -225,6 +225,8 @@ + + diff --git a/idea/src/org/jetbrains/jet/plugin/hierarchy/KotlinTypeHierarchyProvider.java b/idea/src/org/jetbrains/jet/plugin/hierarchy/KotlinTypeHierarchyProvider.java new file mode 100644 index 00000000000..e37489b0305 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/hierarchy/KotlinTypeHierarchyProvider.java @@ -0,0 +1,109 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.hierarchy; + +import com.intellij.codeInsight.TargetElementUtilBase; +import com.intellij.ide.hierarchy.type.JavaTypeHierarchyProvider; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.psi.JetClassOrObject; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetNamedFunction; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.plugin.JetPluginUtil; +import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager; +import org.jetbrains.jet.plugin.libraries.JetSourceNavigationHelper; +import org.jetbrains.jet.plugin.stubindex.JetShortClassNameIndex; +import org.jetbrains.jet.renderer.DescriptorRenderer; + +import java.util.Collection; + +public class KotlinTypeHierarchyProvider extends JavaTypeHierarchyProvider { + + @Override + public PsiElement getTarget(@NotNull final DataContext dataContext) { + Project project = PlatformDataKeys.PROJECT.getData(dataContext); + if (project == null) return null; + + Editor editor = PlatformDataKeys.EDITOR.getData(dataContext); + if (editor != null) { + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (!(file instanceof JetFile)) return null; + + PsiElement target = TargetElementUtilBase.findTargetElement(editor, TargetElementUtilBase.getInstance().getAllAccepted()); + + if (target instanceof PsiClass) { + return target; + } + + if (target instanceof JetClassOrObject) { + return JetSourceNavigationHelper.getOriginalPsiClassOrCreateLightClass((JetClassOrObject) target); + } + // Factory methods + else if (target instanceof JetNamedFunction) { + JetNamedFunction function = (JetNamedFunction) target; + String functionName = function.getName(); + FunctionDescriptor functionDescriptor = KotlinCacheManager.getInstance(project).getDeclarationsFromProject().getBindingContext() + .get(BindingContext.FUNCTION, target); + if (functionDescriptor != null) { + JetType type = functionDescriptor.getReturnType(); + if (type != null) { + String returnTypeText = DescriptorRenderer.TEXT.renderType(type); + if (returnTypeText.equals(functionName)) { + Collection classOrObjects = + JetShortClassNameIndex.getInstance().get(functionName, project, GlobalSearchScope.allScope(project)); + if (classOrObjects.size() == 1) { + JetClassOrObject classOrObject = classOrObjects.iterator().next(); + return JetSourceNavigationHelper.getOriginalPsiClassOrCreateLightClass(classOrObject); + } + } + } + } + } + + int offset = editor.getCaretModel().getOffset(); + PsiElement element = file.findElementAt(offset); + if (element == null) return null; + + JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(element, JetClassOrObject.class); + if (classOrObject != null) { + return JetSourceNavigationHelper.getOriginalPsiClassOrCreateLightClass(classOrObject); + } + } + else { + PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext); + if (element instanceof JetClassOrObject) { + return JetSourceNavigationHelper.getOriginalPsiClassOrCreateLightClass((JetClassOrObject) element); + } + } + + return null; + } +} + diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/JetSourceNavigationHelper.java b/idea/src/org/jetbrains/jet/plugin/libraries/JetSourceNavigationHelper.java index 4595714ea54..8bb0cdcff9a 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/JetSourceNavigationHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/libraries/JetSourceNavigationHelper.java @@ -19,12 +19,16 @@ package org.jetbrains.jet.plugin.libraries; import com.google.common.base.Predicate; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.search.GlobalSearchScope; @@ -32,13 +36,17 @@ import com.intellij.psi.search.GlobalSearchScopes; import com.intellij.psi.stubs.StringStubIndexExtension; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.ContainerUtil; +import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; +import org.jetbrains.jet.asJava.LightClassUtil; +import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor; import org.jetbrains.jet.lang.DefaultModuleConfiguration; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory; import org.jetbrains.jet.lang.resolve.lazy.KotlinCodeAnalyzer; import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedStorageManager; @@ -327,4 +335,66 @@ public class JetSourceNavigationHelper { static void setForceResolve(boolean forceResolve) { JetSourceNavigationHelper.forceResolve = forceResolve; } + + @Nullable + public static PsiClass getOriginalPsiClassOrCreateLightClass(@NotNull JetClassOrObject classOrObject) { + PsiClass originalClass = getOriginalClass(classOrObject); + if (originalClass != null) { + return originalClass; + } + if (!JetPsiUtil.isLocalClass(classOrObject)) { + return LightClassUtil.createLightClass(classOrObject); + } + return null; + } + + @Nullable + public static PsiClass getOriginalClass(@NotNull JetClassOrObject classOrObject) { + // Copied from JavaPsiImplementationHelperImpl:getOriginalClass() + JvmClassName className = PsiCodegenPredictor.getPredefinedJvmClassName(classOrObject); + if (className == null) { + return null; + } + String fqName = className.getFqName().getFqName(); + + JetFile file = (JetFile) classOrObject.getContainingFile(); + + VirtualFile vFile = file.getVirtualFile(); + Project project = file.getProject(); + + final ProjectFileIndex idx = ProjectRootManager.getInstance(project).getFileIndex(); + + if (vFile == null || !idx.isInLibrarySource(vFile)) return null; + final Set orderEntries = new THashSet(idx.getOrderEntriesForFile(vFile)); + + PsiClass original = JavaPsiFacade.getInstance(project).findClass(fqName, new GlobalSearchScope(project) { + @Override + public int compare(VirtualFile file1, VirtualFile file2) { + return 0; + } + + @Override + public boolean contains(VirtualFile file) { + List entries = idx.getOrderEntriesForFile(file); + //noinspection ForLoopReplaceableByForEach + for (int i = 0; i < entries.size(); i++) { + final OrderEntry entry = entries.get(i); + if (orderEntries.contains(entry)) return true; + } + return false; + } + + @Override + public boolean isSearchInModuleContent(@NotNull Module aModule) { + return false; + } + + @Override + public boolean isSearchInLibraries() { + return true; + } + }); + + return original; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/search/KotlinDirectInheritorsSearcher.java b/idea/src/org/jetbrains/jet/plugin/search/KotlinDirectInheritorsSearcher.java index a7f63f713fd..cab4b6ee39c 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/KotlinDirectInheritorsSearcher.java +++ b/idea/src/org/jetbrains/jet/plugin/search/KotlinDirectInheritorsSearcher.java @@ -23,7 +23,6 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.DirectClassInheritorsSearch; import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.asJava.LightClassUtil; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.psi.JetClass; @@ -32,6 +31,7 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.lazy.KotlinCodeAnalyzer; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.plugin.libraries.JetSourceNavigationHelper; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import org.jetbrains.jet.plugin.stubindex.JetSuperClassIndex; @@ -70,9 +70,9 @@ public class KotlinDirectInheritorsSearcher extends QueryExecutorBase + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/sub/ClassFromClass/main.kt b/idea/testData/hierarchy/class/sub/ClassFromClass/main.kt new file mode 100644 index 00000000000..cf9a72996c7 --- /dev/null +++ b/idea/testData/hierarchy/class/sub/ClassFromClass/main.kt @@ -0,0 +1,3 @@ +class MyClass: A() + +open class A \ No newline at end of file diff --git a/idea/testData/hierarchy/class/super/TwoTraits/TwoTraits_verification.xml b/idea/testData/hierarchy/class/super/TwoTraits/TwoTraits_verification.xml new file mode 100644 index 00000000000..8226074bbf5 --- /dev/null +++ b/idea/testData/hierarchy/class/super/TwoTraits/TwoTraits_verification.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/idea/testData/hierarchy/class/super/TwoTraits/main.kt b/idea/testData/hierarchy/class/super/TwoTraits/main.kt new file mode 100644 index 00000000000..144226e98f5 --- /dev/null +++ b/idea/testData/hierarchy/class/super/TwoTraits/main.kt @@ -0,0 +1,4 @@ +class MyClass: A, B + +trait A +trait B \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/CaretAtAnnotation/CaretAtAnnotation_verification.xml b/idea/testData/hierarchy/class/type/CaretAtAnnotation/CaretAtAnnotation_verification.xml new file mode 100644 index 00000000000..d7a069ce129 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtAnnotation/CaretAtAnnotation_verification.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/CaretAtAnnotation/main.kt b/idea/testData/hierarchy/class/type/CaretAtAnnotation/main.kt new file mode 100644 index 00000000000..fd39b1e3d55 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtAnnotation/main.kt @@ -0,0 +1,5 @@ +A class MyClass + +annotation class A + + diff --git a/idea/testData/hierarchy/class/type/CaretAtConstructor/CaretAtConstructor_verification.xml b/idea/testData/hierarchy/class/type/CaretAtConstructor/CaretAtConstructor_verification.xml new file mode 100644 index 00000000000..a05bb9985d8 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtConstructor/CaretAtConstructor_verification.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/CaretAtConstructor/main.kt b/idea/testData/hierarchy/class/type/CaretAtConstructor/main.kt new file mode 100644 index 00000000000..844772d4427 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtConstructor/main.kt @@ -0,0 +1,7 @@ +fun foo() { + A() +} + +class A + + diff --git a/idea/testData/hierarchy/class/type/CaretAtFabricMethod/CaretAtFabricMethod_verification.xml b/idea/testData/hierarchy/class/type/CaretAtFabricMethod/CaretAtFabricMethod_verification.xml new file mode 100644 index 00000000000..a05bb9985d8 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtFabricMethod/CaretAtFabricMethod_verification.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/CaretAtFabricMethod/main.kt b/idea/testData/hierarchy/class/type/CaretAtFabricMethod/main.kt new file mode 100644 index 00000000000..05527623798 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtFabricMethod/main.kt @@ -0,0 +1,9 @@ +fun foo() { + A() +} + +class A (x: Int) + +fun A(): A = A(1) + + diff --git a/idea/testData/hierarchy/class/type/CaretAtImport/1_main.kt b/idea/testData/hierarchy/class/type/CaretAtImport/1_main.kt new file mode 100644 index 00000000000..281e50d9489 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtImport/1_main.kt @@ -0,0 +1,2 @@ +import test.A + diff --git a/idea/testData/hierarchy/class/type/CaretAtImport/2_kotlin.kt b/idea/testData/hierarchy/class/type/CaretAtImport/2_kotlin.kt new file mode 100644 index 00000000000..1b0178fd9be --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtImport/2_kotlin.kt @@ -0,0 +1,3 @@ +package test + +class A diff --git a/idea/testData/hierarchy/class/type/CaretAtImport/CaretAtImport_verification.xml b/idea/testData/hierarchy/class/type/CaretAtImport/CaretAtImport_verification.xml new file mode 100644 index 00000000000..de0c7b4cc98 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtImport/CaretAtImport_verification.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/CaretAtJavaType/CaretAtJavaType_verification.xml b/idea/testData/hierarchy/class/type/CaretAtJavaType/CaretAtJavaType_verification.xml new file mode 100644 index 00000000000..8fb6ae50a83 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtJavaType/CaretAtJavaType_verification.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/CaretAtJavaType/main.kt b/idea/testData/hierarchy/class/type/CaretAtJavaType/main.kt new file mode 100644 index 00000000000..d8c577953e9 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtJavaType/main.kt @@ -0,0 +1,3 @@ +import java.lang.String + + diff --git a/idea/testData/hierarchy/class/type/CaretAtModifierList/CaretAtModifierList_verification.xml b/idea/testData/hierarchy/class/type/CaretAtModifierList/CaretAtModifierList_verification.xml new file mode 100644 index 00000000000..b116497bbef --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtModifierList/CaretAtModifierList_verification.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/CaretAtModifierList/main.kt b/idea/testData/hierarchy/class/type/CaretAtModifierList/main.kt new file mode 100644 index 00000000000..e16bdcd958c --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtModifierList/main.kt @@ -0,0 +1,4 @@ +public class MyClass { +} + + diff --git a/idea/testData/hierarchy/class/type/CaretAtReceiverExtFun/CaretAtReceiverExtFun_verification.xml b/idea/testData/hierarchy/class/type/CaretAtReceiverExtFun/CaretAtReceiverExtFun_verification.xml new file mode 100644 index 00000000000..a05bb9985d8 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtReceiverExtFun/CaretAtReceiverExtFun_verification.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/CaretAtReceiverExtFun/main.kt b/idea/testData/hierarchy/class/type/CaretAtReceiverExtFun/main.kt new file mode 100644 index 00000000000..2551ad16039 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtReceiverExtFun/main.kt @@ -0,0 +1,5 @@ +class A + +fun A.foo() {} + + diff --git a/idea/testData/hierarchy/class/type/CaretAtSuperCall/CaretAtSuperCall_verification.xml b/idea/testData/hierarchy/class/type/CaretAtSuperCall/CaretAtSuperCall_verification.xml new file mode 100644 index 00000000000..8ed1115ebe1 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtSuperCall/CaretAtSuperCall_verification.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/CaretAtSuperCall/main.kt b/idea/testData/hierarchy/class/type/CaretAtSuperCall/main.kt new file mode 100644 index 00000000000..bc37a175595 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtSuperCall/main.kt @@ -0,0 +1,9 @@ +public class MyClass: A() { + override fun foo() { + super>.foo() + } +} + +open class A { + fun foo() {} +} \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/CaretAtSupertypesList/CaretAtSupertypesList_verification.xml b/idea/testData/hierarchy/class/type/CaretAtSupertypesList/CaretAtSupertypesList_verification.xml new file mode 100644 index 00000000000..8ed1115ebe1 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtSupertypesList/CaretAtSupertypesList_verification.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/CaretAtSupertypesList/main.kt b/idea/testData/hierarchy/class/type/CaretAtSupertypesList/main.kt new file mode 100644 index 00000000000..165fe2974fb --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtSupertypesList/main.kt @@ -0,0 +1,6 @@ +public class MyClass: A() { +} + +open class A + + diff --git a/idea/testData/hierarchy/class/type/CaretAtTypeReference/CaretAtTypeReference_verification.xml b/idea/testData/hierarchy/class/type/CaretAtTypeReference/CaretAtTypeReference_verification.xml new file mode 100644 index 00000000000..a05bb9985d8 --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtTypeReference/CaretAtTypeReference_verification.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/CaretAtTypeReference/main.kt b/idea/testData/hierarchy/class/type/CaretAtTypeReference/main.kt new file mode 100644 index 00000000000..f5002a239ef --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretAtTypeReference/main.kt @@ -0,0 +1,9 @@ +public class MyClass { + fun foo() { + val a : A = A() + } +} + +class A + + diff --git a/idea/testData/hierarchy/class/type/CaretInClassBody/CaretInClassBody_verification.xml b/idea/testData/hierarchy/class/type/CaretInClassBody/CaretInClassBody_verification.xml new file mode 100644 index 00000000000..b116497bbef --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretInClassBody/CaretInClassBody_verification.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/CaretInClassBody/main.kt b/idea/testData/hierarchy/class/type/CaretInClassBody/main.kt new file mode 100644 index 00000000000..c0178a5c51a --- /dev/null +++ b/idea/testData/hierarchy/class/type/CaretInClassBody/main.kt @@ -0,0 +1,5 @@ +class MyClass { + +} + + diff --git a/idea/testData/hierarchy/class/type/ClassFromClass/ClassFromClass_verification.xml b/idea/testData/hierarchy/class/type/ClassFromClass/ClassFromClass_verification.xml new file mode 100644 index 00000000000..3e3975cacfd --- /dev/null +++ b/idea/testData/hierarchy/class/type/ClassFromClass/ClassFromClass_verification.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/ClassFromClass/main.kt b/idea/testData/hierarchy/class/type/ClassFromClass/main.kt new file mode 100644 index 00000000000..f4412a67a4f --- /dev/null +++ b/idea/testData/hierarchy/class/type/ClassFromClass/main.kt @@ -0,0 +1,3 @@ +class MyClass: A() + +open class A \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/ClassFromObject/ClassFromObject_verification.xml b/idea/testData/hierarchy/class/type/ClassFromObject/ClassFromObject_verification.xml new file mode 100644 index 00000000000..b116497bbef --- /dev/null +++ b/idea/testData/hierarchy/class/type/ClassFromObject/ClassFromObject_verification.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/ClassFromObject/main.kt b/idea/testData/hierarchy/class/type/ClassFromObject/main.kt new file mode 100644 index 00000000000..e8f6fccedd6 --- /dev/null +++ b/idea/testData/hierarchy/class/type/ClassFromObject/main.kt @@ -0,0 +1,2 @@ +class MyClass + diff --git a/idea/testData/hierarchy/class/type/ClassInClassObject/ClassInClassObject_verification.xml b/idea/testData/hierarchy/class/type/ClassInClassObject/ClassInClassObject_verification.xml new file mode 100644 index 00000000000..7fe91201793 --- /dev/null +++ b/idea/testData/hierarchy/class/type/ClassInClassObject/ClassInClassObject_verification.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/ClassInClassObject/main.kt b/idea/testData/hierarchy/class/type/ClassInClassObject/main.kt new file mode 100644 index 00000000000..8de59dac67f --- /dev/null +++ b/idea/testData/hierarchy/class/type/ClassInClassObject/main.kt @@ -0,0 +1,7 @@ +class A { + class object { + class MyClass + } +} + + diff --git a/idea/testData/hierarchy/class/type/ClassInPackage/ClassInPackage_verification.xml b/idea/testData/hierarchy/class/type/ClassInPackage/ClassInPackage_verification.xml new file mode 100644 index 00000000000..fdb05aae141 --- /dev/null +++ b/idea/testData/hierarchy/class/type/ClassInPackage/ClassInPackage_verification.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/ClassInPackage/main.kt b/idea/testData/hierarchy/class/type/ClassInPackage/main.kt new file mode 100644 index 00000000000..a6c008f0ece --- /dev/null +++ b/idea/testData/hierarchy/class/type/ClassInPackage/main.kt @@ -0,0 +1,3 @@ +package foo.foo1 + +class MyClass diff --git a/idea/testData/hierarchy/class/type/InnerClass/InnerClass_verification.xml b/idea/testData/hierarchy/class/type/InnerClass/InnerClass_verification.xml new file mode 100644 index 00000000000..e8c2485bb46 --- /dev/null +++ b/idea/testData/hierarchy/class/type/InnerClass/InnerClass_verification.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/InnerClass/main.kt b/idea/testData/hierarchy/class/type/InnerClass/main.kt new file mode 100644 index 00000000000..c7e8f20cdc1 --- /dev/null +++ b/idea/testData/hierarchy/class/type/InnerClass/main.kt @@ -0,0 +1,3 @@ +class Base { + inner class MyClass {} +} \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/JKJHierarchy/1_MyClass.java b/idea/testData/hierarchy/class/type/JKJHierarchy/1_MyClass.java new file mode 100644 index 00000000000..9f5f607ba38 --- /dev/null +++ b/idea/testData/hierarchy/class/type/JKJHierarchy/1_MyClass.java @@ -0,0 +1,3 @@ +public class MyClass extends KotlinClass { + +} \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/JKJHierarchy/2_main.kt b/idea/testData/hierarchy/class/type/JKJHierarchy/2_main.kt new file mode 100644 index 00000000000..94f6b46f72c --- /dev/null +++ b/idea/testData/hierarchy/class/type/JKJHierarchy/2_main.kt @@ -0,0 +1 @@ +public open class KotlinClass: SecondClass() \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/JKJHierarchy/3_SecondClass.java b/idea/testData/hierarchy/class/type/JKJHierarchy/3_SecondClass.java new file mode 100644 index 00000000000..4afb65bcdbb --- /dev/null +++ b/idea/testData/hierarchy/class/type/JKJHierarchy/3_SecondClass.java @@ -0,0 +1,3 @@ +public class SecondClass { + +} \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/JKJHierarchy/JKJHierarchy_verification.xml b/idea/testData/hierarchy/class/type/JKJHierarchy/JKJHierarchy_verification.xml new file mode 100644 index 00000000000..953ef583673 --- /dev/null +++ b/idea/testData/hierarchy/class/type/JKJHierarchy/JKJHierarchy_verification.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/JavaFromKotlin/1_MyClass.java b/idea/testData/hierarchy/class/type/JavaFromKotlin/1_MyClass.java new file mode 100644 index 00000000000..9f5f607ba38 --- /dev/null +++ b/idea/testData/hierarchy/class/type/JavaFromKotlin/1_MyClass.java @@ -0,0 +1,3 @@ +public class MyClass extends KotlinClass { + +} \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/JavaFromKotlin/2_main.kt b/idea/testData/hierarchy/class/type/JavaFromKotlin/2_main.kt new file mode 100644 index 00000000000..d035c7b5e63 --- /dev/null +++ b/idea/testData/hierarchy/class/type/JavaFromKotlin/2_main.kt @@ -0,0 +1 @@ +public open class KotlinClass \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/JavaFromKotlin/JavaFromKotlin_verification.xml b/idea/testData/hierarchy/class/type/JavaFromKotlin/JavaFromKotlin_verification.xml new file mode 100644 index 00000000000..5d73ee035ad --- /dev/null +++ b/idea/testData/hierarchy/class/type/JavaFromKotlin/JavaFromKotlin_verification.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/JavaFromKotlinForKotlinClass/1_main.kt b/idea/testData/hierarchy/class/type/JavaFromKotlinForKotlinClass/1_main.kt new file mode 100644 index 00000000000..dec08783da1 --- /dev/null +++ b/idea/testData/hierarchy/class/type/JavaFromKotlinForKotlinClass/1_main.kt @@ -0,0 +1 @@ +public open class KotlinClass \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/JavaFromKotlinForKotlinClass/2_MyClass.java b/idea/testData/hierarchy/class/type/JavaFromKotlinForKotlinClass/2_MyClass.java new file mode 100644 index 00000000000..9cb89f81871 --- /dev/null +++ b/idea/testData/hierarchy/class/type/JavaFromKotlinForKotlinClass/2_MyClass.java @@ -0,0 +1,3 @@ +public class MyClass extends KotlinClass { + +} \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/JavaFromKotlinForKotlinClass/JavaFromKotlinForKotlinClass_verification.xml b/idea/testData/hierarchy/class/type/JavaFromKotlinForKotlinClass/JavaFromKotlinForKotlinClass_verification.xml new file mode 100644 index 00000000000..43cfa5b9ad3 --- /dev/null +++ b/idea/testData/hierarchy/class/type/JavaFromKotlinForKotlinClass/JavaFromKotlinForKotlinClass_verification.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/KotlinFromJava/1_main.kt b/idea/testData/hierarchy/class/type/KotlinFromJava/1_main.kt new file mode 100644 index 00000000000..6c5e4288648 --- /dev/null +++ b/idea/testData/hierarchy/class/type/KotlinFromJava/1_main.kt @@ -0,0 +1 @@ +class MyClass: JavaClass() {} \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/KotlinFromJava/2_JavaClass.java b/idea/testData/hierarchy/class/type/KotlinFromJava/2_JavaClass.java new file mode 100644 index 00000000000..871149005c7 --- /dev/null +++ b/idea/testData/hierarchy/class/type/KotlinFromJava/2_JavaClass.java @@ -0,0 +1,3 @@ +public class JavaClass { + +} \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/KotlinFromJava/KotlinFromJava_verification.xml b/idea/testData/hierarchy/class/type/KotlinFromJava/KotlinFromJava_verification.xml new file mode 100644 index 00000000000..7e09adaa09e --- /dev/null +++ b/idea/testData/hierarchy/class/type/KotlinFromJava/KotlinFromJava_verification.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/Object/Object_verification.xml b/idea/testData/hierarchy/class/type/Object/Object_verification.xml new file mode 100644 index 00000000000..b116497bbef --- /dev/null +++ b/idea/testData/hierarchy/class/type/Object/Object_verification.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/Object/main.kt b/idea/testData/hierarchy/class/type/Object/main.kt new file mode 100644 index 00000000000..14840bcf4fd --- /dev/null +++ b/idea/testData/hierarchy/class/type/Object/main.kt @@ -0,0 +1,3 @@ +object MyClass { + +} diff --git a/idea/testData/hierarchy/class/type/TwoChildren/TwoChildren_verification.xml b/idea/testData/hierarchy/class/type/TwoChildren/TwoChildren_verification.xml new file mode 100644 index 00000000000..2157a93dc11 --- /dev/null +++ b/idea/testData/hierarchy/class/type/TwoChildren/TwoChildren_verification.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/idea/testData/hierarchy/class/type/TwoChildren/main.kt b/idea/testData/hierarchy/class/type/TwoChildren/main.kt new file mode 100644 index 00000000000..d3963e8d997 --- /dev/null +++ b/idea/testData/hierarchy/class/type/TwoChildren/main.kt @@ -0,0 +1,4 @@ +trait MyClass + +class A: MyClass +class B: MyClass \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/hierarchy/AbstractHierarchyTest.java b/idea/tests/org/jetbrains/jet/plugin/hierarchy/AbstractHierarchyTest.java new file mode 100644 index 00000000000..30aa95a72a6 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/hierarchy/AbstractHierarchyTest.java @@ -0,0 +1,148 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.hierarchy; + +import com.intellij.ide.hierarchy.HierarchyBrowserBaseEx; +import com.intellij.ide.hierarchy.HierarchyTreeStructure; +import com.intellij.ide.hierarchy.LanguageTypeHierarchy; +import com.intellij.ide.hierarchy.type.SubtypesHierarchyTreeStructure; +import com.intellij.ide.hierarchy.type.SupertypesHierarchyTreeStructure; +import com.intellij.ide.hierarchy.type.TypeHierarchyTreeStructure; +import com.intellij.lang.Language; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.testFramework.MapDataContext; +import com.intellij.testFramework.codeInsight.hierarchy.HierarchyViewTestBase; +import com.intellij.util.Processor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.plugin.PluginTestCaseBase; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/* +Test Hierarchy view +Format: test build hierarchy for element at caret, file with caret should be the first in the sorted list of files. +Test accept more than one file, file extension should be .java or .kt + */ +public abstract class AbstractHierarchyTest extends HierarchyViewTestBase { + + private String folderName; + + protected void doTypeClassHierarchyTest(@NotNull String folderName) throws Exception { + this.folderName = folderName; + doHierarchyTest(getTypeHierarchyStructure(), getFilesToConfigure()); + } + + protected void doSuperClassHierarchyTest(@NotNull String folderName) throws Exception { + this.folderName = folderName; + doHierarchyTest(getSuperTypesHierarchyStructure(), getFilesToConfigure()); + } + + protected void doSubClassHierarchyTest(@NotNull String folderName) throws Exception { + this.folderName = folderName; + doHierarchyTest(getSubTypesHierarchyStructure(), getFilesToConfigure()); + } + + private Computable getSuperTypesHierarchyStructure() { + return new Computable() { + @Override + public HierarchyTreeStructure compute() { + return new SupertypesHierarchyTreeStructure(getProject(), (PsiClass) getElementAtCaret()); + } + }; + } + + private Computable getSubTypesHierarchyStructure() { + return new Computable() { + @Override + public HierarchyTreeStructure compute() { + return new SubtypesHierarchyTreeStructure(getProject(), (PsiClass) getElementAtCaret(), + HierarchyBrowserBaseEx.SCOPE_PROJECT); + } + }; + } + + private Computable getTypeHierarchyStructure() { + return new Computable() { + @Override + public HierarchyTreeStructure compute() { + return new TypeHierarchyTreeStructure(getProject(), (PsiClass) getElementAtCaret(), + HierarchyBrowserBaseEx.SCOPE_PROJECT); + } + }; + } + + private PsiElement getElementAtCaret() { + PsiElement target = LanguageTypeHierarchy.INSTANCE.forLanguage(getLanguage()).getTarget(getDataContext()); + assert target != null : "Cannot apply action for element at caret"; + return target; + } + + private Language getLanguage() { + PsiFile file = PsiDocumentManager.getInstance(getProject()).getPsiFile(getEditor().getDocument()); + assert file != null : "Cannot find file in editor"; + return file.getLanguage(); + } + + private DataContext getDataContext() { + MapDataContext context = new MapDataContext(); + context.put(PlatformDataKeys.PROJECT, getProject()); + context.put(PlatformDataKeys.EDITOR, getEditor()); + return context; + } + + private String[] getFilesToConfigure() { + final List files = new ArrayList(2); + FileUtil.processFilesRecursively(new File(folderName), new Processor() { + @Override + public boolean process(File file) { + String fileName = file.getName(); + if (fileName.endsWith(".kt") || fileName.endsWith(".java")) { + files.add(fileName); + } + return true; + } + }); + Collections.sort(files); + return files.toArray(new String[files.size()]); + } + + @Override + protected String getBasePath() { + return folderName.substring("idea/testData/".length()); + } + + @Override + protected String getTestDataPath() { + return PluginTestCaseBase.getTestDataPathBase(); + } + + @Override + protected Sdk getTestProjectJdk() { + return PluginTestCaseBase.jdkFromIdeaHome(); + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/hierarchy/HierarchyTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/hierarchy/HierarchyTestGenerated.java new file mode 100644 index 00000000000..bd23f963245 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/hierarchy/HierarchyTestGenerated.java @@ -0,0 +1,186 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.hierarchy; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.plugin.hierarchy.AbstractHierarchyTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@InnerTestClasses({HierarchyTestGenerated.Type.class, HierarchyTestGenerated.Super.class, HierarchyTestGenerated.Sub.class}) +public class HierarchyTestGenerated extends AbstractHierarchyTest { + @TestMetadata("idea/testData/hierarchy/class/type") + public static class Type extends AbstractHierarchyTest { + public void testAllFilesPresentInType() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/hierarchy/class/type"), Pattern.compile("^(.+)$"), false); + } + + @TestMetadata("CaretAtAnnotation") + public void testCaretAtAnnotation() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/CaretAtAnnotation"); + } + + @TestMetadata("CaretAtConstructor") + public void testCaretAtConstructor() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/CaretAtConstructor"); + } + + @TestMetadata("CaretAtFabricMethod") + public void testCaretAtFabricMethod() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/CaretAtFabricMethod"); + } + + @TestMetadata("CaretAtImport") + public void testCaretAtImport() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/CaretAtImport"); + } + + @TestMetadata("CaretAtJavaType") + public void testCaretAtJavaType() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/CaretAtJavaType"); + } + + @TestMetadata("CaretAtModifierList") + public void testCaretAtModifierList() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/CaretAtModifierList"); + } + + @TestMetadata("CaretAtReceiverExtFun") + public void testCaretAtReceiverExtFun() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/CaretAtReceiverExtFun"); + } + + @TestMetadata("CaretAtSuperCall") + public void testCaretAtSuperCall() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/CaretAtSuperCall"); + } + + @TestMetadata("CaretAtSupertypesList") + public void testCaretAtSupertypesList() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/CaretAtSupertypesList"); + } + + @TestMetadata("CaretAtTypeReference") + public void testCaretAtTypeReference() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/CaretAtTypeReference"); + } + + @TestMetadata("CaretInClassBody") + public void testCaretInClassBody() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/CaretInClassBody"); + } + + @TestMetadata("ClassFromClass") + public void testClassFromClass() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/ClassFromClass"); + } + + @TestMetadata("ClassFromObject") + public void testClassFromObject() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/ClassFromObject"); + } + + @TestMetadata("ClassInClassObject") + public void testClassInClassObject() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/ClassInClassObject"); + } + + @TestMetadata("ClassInPackage") + public void testClassInPackage() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/ClassInPackage"); + } + + @TestMetadata("InnerClass") + public void testInnerClass() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/InnerClass"); + } + + @TestMetadata("JKJHierarchy") + public void testJKJHierarchy() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/JKJHierarchy"); + } + + @TestMetadata("JavaFromKotlin") + public void testJavaFromKotlin() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/JavaFromKotlin"); + } + + @TestMetadata("JavaFromKotlinForKotlinClass") + public void testJavaFromKotlinForKotlinClass() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/JavaFromKotlinForKotlinClass"); + } + + @TestMetadata("KotlinFromJava") + public void testKotlinFromJava() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/KotlinFromJava"); + } + + @TestMetadata("Object") + public void testObject() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/Object"); + } + + @TestMetadata("TwoChildren") + public void testTwoChildren() throws Exception { + doTypeClassHierarchyTest("idea/testData/hierarchy/class/type/TwoChildren"); + } + + } + + @TestMetadata("idea/testData/hierarchy/class/super") + public static class Super extends AbstractHierarchyTest { + public void testAllFilesPresentInSuper() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/hierarchy/class/super"), Pattern.compile("^(.+)$"), false); + } + + @TestMetadata("TwoTraits") + public void testTwoTraits() throws Exception { + doSuperClassHierarchyTest("idea/testData/hierarchy/class/super/TwoTraits"); + } + + } + + @TestMetadata("idea/testData/hierarchy/class/sub") + public static class Sub extends AbstractHierarchyTest { + public void testAllFilesPresentInSub() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/hierarchy/class/sub"), Pattern.compile("^(.+)$"), false); + } + + @TestMetadata("ClassFromClass") + public void testClassFromClass() throws Exception { + doSubClassHierarchyTest("idea/testData/hierarchy/class/sub/ClassFromClass"); + } + + } + + public static Test suite() { + TestSuite suite = new TestSuite("HierarchyTestGenerated"); + suite.addTestSuite(Type.class); + suite.addTestSuite(Super.class); + suite.addTestSuite(Sub.class); + return suite; + } +}