Implement Class Hierarchy View
#KT-3419
This commit is contained in:
+7
@@ -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() {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -225,6 +225,8 @@
|
||||
<library.presentationProvider implementation="org.jetbrains.jet.plugin.framework.JSLibraryStdPresentationProvider"/>
|
||||
<library.presentationProvider implementation="org.jetbrains.jet.plugin.framework.JsHeaderLibraryPresentationProvider"/>
|
||||
|
||||
<typeHierarchyProvider language="jet" implementationClass="org.jetbrains.jet.plugin.hierarchy.KotlinTypeHierarchyProvider"/>
|
||||
|
||||
<java.elementFinder implementation="org.jetbrains.jet.asJava.JavaElementFinder"/>
|
||||
<java.shortNamesCache implementation="org.jetbrains.jet.plugin.caches.JetShortNamesCache"/>
|
||||
|
||||
|
||||
@@ -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<JetClassOrObject> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<OrderEntry> orderEntries = new THashSet<OrderEntry>(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<OrderEntry> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<PsiClass,
|
||||
if (declarationDescriptor != null) {
|
||||
String fqName = DescriptorUtils.getFQName(declarationDescriptor).getFqName();
|
||||
if (qualifiedName.equals(fqName)) {
|
||||
PsiClass lightClass = LightClassUtil.createLightClass(candidate);
|
||||
if (lightClass != null) {
|
||||
consumer.process(lightClass);
|
||||
PsiClass psiClass = JetSourceNavigationHelper.getOriginalPsiClassOrCreateLightClass(candidate);
|
||||
if (psiClass != null) {
|
||||
consumer.process(psiClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<node text="A ()" base="true">
|
||||
<node text="MyClass ()"/>
|
||||
</node>
|
||||
@@ -0,0 +1,3 @@
|
||||
class MyClass: A()
|
||||
|
||||
open class <caret>A
|
||||
@@ -0,0 +1,5 @@
|
||||
<node text="MyClass ()" base="true">
|
||||
<node text="Object (java.lang)"/>
|
||||
<node text="A ()"/>
|
||||
<node text="B ()"/>
|
||||
</node>
|
||||
@@ -0,0 +1,4 @@
|
||||
class MyClass<caret>: A, B
|
||||
|
||||
trait A
|
||||
trait B
|
||||
+1
@@ -0,0 +1 @@
|
||||
<node text="A ()" base="true"/>
|
||||
@@ -0,0 +1,5 @@
|
||||
<caret>A class MyClass
|
||||
|
||||
annotation class A
|
||||
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="A ()" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,7 @@
|
||||
fun foo() {
|
||||
A<caret>()
|
||||
}
|
||||
|
||||
class A
|
||||
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="A ()" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,9 @@
|
||||
fun foo() {
|
||||
A<caret>()
|
||||
}
|
||||
|
||||
class A (x: Int)
|
||||
|
||||
fun A(): A = A(1)
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
import test.A<caret>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
class A
|
||||
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="A (test)" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="String (java.lang)" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,3 @@
|
||||
import java.lang.String<caret>
|
||||
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="MyClass ()" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,4 @@
|
||||
<caret>public class MyClass {
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="A ()" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,5 @@
|
||||
class A
|
||||
|
||||
fun A<caret>.foo() {}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="A ()" base="true">
|
||||
<node text="MyClass ()"/>
|
||||
</node>
|
||||
</node>
|
||||
@@ -0,0 +1,9 @@
|
||||
public class MyClass: A() {
|
||||
override fun foo() {
|
||||
super<A<caret>>.foo()
|
||||
}
|
||||
}
|
||||
|
||||
open class A {
|
||||
fun foo() {}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="A ()" base="true">
|
||||
<node text="MyClass ()"/>
|
||||
</node>
|
||||
</node>
|
||||
@@ -0,0 +1,6 @@
|
||||
public class MyClass: A<caret>() {
|
||||
}
|
||||
|
||||
open class A
|
||||
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="A ()" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,9 @@
|
||||
public class MyClass {
|
||||
fun foo() {
|
||||
val a : A<caret> = A()
|
||||
}
|
||||
}
|
||||
|
||||
class A
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="MyClass ()" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,5 @@
|
||||
class MyClass {
|
||||
<caret>
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="A ()">
|
||||
<node text="MyClass ()" base="true"/>
|
||||
</node>
|
||||
</node>
|
||||
@@ -0,0 +1,3 @@
|
||||
class MyClass<caret>: A()
|
||||
|
||||
open class A
|
||||
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="MyClass ()" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,2 @@
|
||||
class MyClass
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="MyClass in object in A ()" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,7 @@
|
||||
class A {
|
||||
class object {
|
||||
class MyClass<caret>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="MyClass (foo.foo1)" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,3 @@
|
||||
package foo.foo1
|
||||
|
||||
class MyClass<caret>
|
||||
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="MyClass in Base ()" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,3 @@
|
||||
class Base {
|
||||
inner class MyClass<caret> {}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
public class MyClass<caret> extends KotlinClass {
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
public open class KotlinClass: SecondClass()
|
||||
@@ -0,0 +1,3 @@
|
||||
public class SecondClass {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="SecondClass ()">
|
||||
<node text="KotlinClass ()">
|
||||
<node text="MyClass ()" base="true"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
@@ -0,0 +1,3 @@
|
||||
public class MyClass<caret> extends KotlinClass {
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
public open class KotlinClass
|
||||
@@ -0,0 +1,5 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="KotlinClass ()">
|
||||
<node text="MyClass ()" base="true"/>
|
||||
</node>
|
||||
</node>
|
||||
@@ -0,0 +1 @@
|
||||
public open class KotlinClass<caret>
|
||||
@@ -0,0 +1,3 @@
|
||||
public class MyClass extends KotlinClass {
|
||||
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="KotlinClass ()" base="true">
|
||||
<node text="MyClass ()"/>
|
||||
</node>
|
||||
</node>
|
||||
@@ -0,0 +1 @@
|
||||
class MyClass<caret>: JavaClass() {}
|
||||
@@ -0,0 +1,3 @@
|
||||
public class JavaClass {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="JavaClass ()">
|
||||
<node text="MyClass ()" base="true"/>
|
||||
</node>
|
||||
</node>
|
||||
@@ -0,0 +1,3 @@
|
||||
<node text="Object (java.lang)">
|
||||
<node text="MyClass ()" base="true"/>
|
||||
</node>
|
||||
@@ -0,0 +1,3 @@
|
||||
object MyClass<caret> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<node text="MyClass ()" base="true">
|
||||
<node text="A ()"/>
|
||||
<node text="B ()"/>
|
||||
</node>
|
||||
@@ -0,0 +1,4 @@
|
||||
trait MyClass<caret>
|
||||
|
||||
class A: MyClass
|
||||
class B: MyClass
|
||||
@@ -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<HierarchyTreeStructure> getSuperTypesHierarchyStructure() {
|
||||
return new Computable<HierarchyTreeStructure>() {
|
||||
@Override
|
||||
public HierarchyTreeStructure compute() {
|
||||
return new SupertypesHierarchyTreeStructure(getProject(), (PsiClass) getElementAtCaret());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Computable<HierarchyTreeStructure> getSubTypesHierarchyStructure() {
|
||||
return new Computable<HierarchyTreeStructure>() {
|
||||
@Override
|
||||
public HierarchyTreeStructure compute() {
|
||||
return new SubtypesHierarchyTreeStructure(getProject(), (PsiClass) getElementAtCaret(),
|
||||
HierarchyBrowserBaseEx.SCOPE_PROJECT);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Computable<HierarchyTreeStructure> getTypeHierarchyStructure() {
|
||||
return new Computable<HierarchyTreeStructure>() {
|
||||
@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<String> files = new ArrayList<String>(2);
|
||||
FileUtil.processFilesRecursively(new File(folderName), new Processor<File>() {
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user