Fix Show implementation to show inheritance through type-aliases

Show implementation(Ctrl-Hover) now should show classes which inherit such class through type-alias
 #KT-15200 fixed
This commit is contained in:
Simon Ogorodnik
2017-02-10 15:42:11 +03:00
parent 593fbadc98
commit 6dd75f697a
11 changed files with 98 additions and 6 deletions
@@ -51,10 +51,16 @@ public class TargetPlatformDetector {
return contextFile instanceof KtFile ? getPlatform((KtFile) contextFile) : JvmPlatform.INSTANCE;
}
return getPlatform((PsiFile) file);
}
public static TargetPlatform getPlatform(@NotNull PsiFile file) {
VirtualFile virtualFile = file.getOriginalFile().getVirtualFile();
if (virtualFile == null) {
return getDefaultPlatform(file);
}
Module moduleForFile = ProjectFileIndex.SERVICE.getInstance(file.getProject()).getModuleForFile(virtualFile);
if (moduleForFile == null) {
return getDefaultPlatform(file);
@@ -69,7 +75,7 @@ public class TargetPlatformDetector {
}
@NotNull
private static TargetPlatform getDefaultPlatform(@NotNull KtFile file) {
private static TargetPlatform getDefaultPlatform(@NotNull PsiFile file) {
LOG.info("Using default platform for file: " + file.getName());
return JvmPlatform.INSTANCE;
}
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.idea.search.ideaExtensions
import com.intellij.openapi.application.QueryExecutorBase
import com.intellij.openapi.progress.ProgressManager
import com.intellij.psi.PsiClass
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.searches.DirectClassInheritorsSearch
@@ -25,6 +26,7 @@ import org.jetbrains.kotlin.idea.decompiler.navigation.SourceNavigationHelper
import org.jetbrains.kotlin.idea.search.fileScope
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
import org.jetbrains.kotlin.idea.stubindex.KotlinSuperClassIndex
import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasByExpansionShortNameIndex
import org.jetbrains.kotlin.idea.util.application.runReadAction
open class KotlinDirectInheritorsSearcher : QueryExecutorBase<PsiClass, DirectClassInheritorsSearch.SearchParameters>(true) {
@@ -36,13 +38,35 @@ open class KotlinDirectInheritorsSearcher : QueryExecutorBase<PsiClass, DirectCl
val originalScope = queryParameters.scope
val scope = originalScope as? GlobalSearchScope ?: baseClass.containingFile?.fileScope() ?: return
val file = baseClass.containingFile
val names = mutableSetOf(name)
val project = file.project
val typeAliasIndex = KotlinTypeAliasByExpansionShortNameIndex.getInstance()
fun searchForTypeAliasesRecursively(typeName: String) {
ProgressManager.checkCanceled()
typeAliasIndex[typeName, project, scope].asSequence()
.map { it.name }
.filterNotNull()
.filter { it !in names }
.onEach { names.add(it) }
.forEach(::searchForTypeAliasesRecursively)
}
searchForTypeAliasesRecursively(name)
runReadAction {
val noLibrarySourceScope = KotlinSourceFilterScope.projectSourceAndClassFiles(scope, baseClass.project)
KotlinSuperClassIndex.getInstance()
.get(name, baseClass.project, noLibrarySourceScope).asSequence()
.mapNotNull { candidate -> SourceNavigationHelper.getOriginalPsiClassOrCreateLightClass(candidate) }
.filter { candidate -> candidate.isInheritor(baseClass, false) }
.forEach { candidate -> consumer.process(candidate) }
names.forEach { name ->
KotlinSuperClassIndex.getInstance()
.get(name, baseClass.project, noLibrarySourceScope).asSequence()
.mapNotNull { candidate -> SourceNavigationHelper.getOriginalPsiClassOrCreateLightClass(candidate) }
.filter { candidate -> candidate.isInheritor(baseClass, false) }
.forEach { candidate -> consumer.process(candidate) }
}
}
}
}
@@ -0,0 +1,3 @@
<node text="A ()" base="true">
<node text="B ()"/>
</node>
@@ -0,0 +1,6 @@
open class A<caret>
typealias TA = A
typealias TTA = A
class B : TTA()
@@ -0,0 +1,3 @@
<node text="A ()" base="true">
<node text="B ()"/>
</node>
+5
View File
@@ -0,0 +1,5 @@
open class A<caret>
typealias TA = A
class B : TA()
@@ -0,0 +1,5 @@
<node text="B ()" base="true">
<node text="A ()">
<node text="Object (java.lang)"/>
</node>
</node>
@@ -0,0 +1,6 @@
open class A
typealias TA = A
typealias TTA = A
class B<caret> : TTA()
@@ -0,0 +1,5 @@
<node text="B ()" base="true">
<node text="A ()">
<node text="Object (java.lang)"/>
</node>
</node>
+5
View File
@@ -0,0 +1,5 @@
open class A
typealias TA = A
class B<caret> : TA()
@@ -227,11 +227,23 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest {
doSuperClassHierarchyTest(fileName);
}
@TestMetadata("MultiTypeAlias")
public void testMultiTypeAlias() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/class/super/MultiTypeAlias/");
doSuperClassHierarchyTest(fileName);
}
@TestMetadata("TwoTraits")
public void testTwoTraits() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/class/super/TwoTraits/");
doSuperClassHierarchyTest(fileName);
}
@TestMetadata("TypeAlias")
public void testTypeAlias() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/class/super/TypeAlias/");
doSuperClassHierarchyTest(fileName);
}
}
@TestMetadata("idea/testData/hierarchy/class/sub")
@@ -266,6 +278,12 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest {
doSubClassHierarchyTest(fileName);
}
@TestMetadata("MultiTypeAlias")
public void testMultiTypeAlias() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/class/sub/MultiTypeAlias/");
doSubClassHierarchyTest(fileName);
}
@TestMetadata("ObjectFromClass")
public void testObjectFromClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/class/sub/ObjectFromClass/");
@@ -289,6 +307,12 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/class/sub/TraitFromTrait/");
doSubClassHierarchyTest(fileName);
}
@TestMetadata("TypeAlias")
public void testTypeAlias() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/class/sub/TypeAlias/");
doSubClassHierarchyTest(fileName);
}
}
@TestMetadata("idea/testData/hierarchy/calls/callers")