Type Hierarchy: Do not use JVM class mapping in non-JVM modules
#KT-21424 In Progress
This commit is contained in:
-16
@@ -18,7 +18,6 @@ import com.intellij.psi.stubs.StringStubIndexExtension
|
|||||||
import com.intellij.util.containers.ContainerUtil
|
import com.intellij.util.containers.ContainerUtil
|
||||||
import gnu.trove.THashSet
|
import gnu.trove.THashSet
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getBinaryLibrariesModuleInfos
|
import org.jetbrains.kotlin.idea.caches.resolve.getBinaryLibrariesModuleInfos
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getLibrarySourcesModuleInfos
|
import org.jetbrains.kotlin.idea.caches.resolve.getLibrarySourcesModuleInfos
|
||||||
@@ -31,7 +30,6 @@ import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelTypeAliasFqNameIndex
|
|||||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
||||||
|
|
||||||
@@ -201,20 +199,6 @@ object SourceNavigationHelper {
|
|||||||
name == declaration.nameAsSafeName
|
name == declaration.nameAsSafeName
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getOriginalPsiClassOrCreateLightClass(classOrObject: KtClassOrObject): PsiClass? {
|
|
||||||
val fqName = classOrObject.fqName
|
|
||||||
if (fqName != null) {
|
|
||||||
val javaClassId = JavaToKotlinClassMap.mapKotlinToJava(fqName.toUnsafe())
|
|
||||||
if (javaClassId != null) {
|
|
||||||
return JavaPsiFacade.getInstance(classOrObject.project).findClass(
|
|
||||||
javaClassId.asSingleFqName().asString(),
|
|
||||||
GlobalSearchScope.allScope(classOrObject.project)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return classOrObject.toLightClass()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getOriginalClass(classOrObject: KtClassOrObject): PsiClass? {
|
fun getOriginalClass(classOrObject: KtClassOrObject): PsiClass? {
|
||||||
// Copied from JavaPsiImplementationHelperImpl:getOriginalClass()
|
// Copied from JavaPsiImplementationHelperImpl:getOriginalClass()
|
||||||
val fqName = classOrObject.fqName ?: return null
|
val fqName = classOrObject.fqName ?: return null
|
||||||
|
|||||||
@@ -22,16 +22,20 @@ import com.intellij.openapi.actionSystem.DataContext
|
|||||||
import com.intellij.openapi.actionSystem.LangDataKeys
|
import com.intellij.openapi.actionSystem.LangDataKeys
|
||||||
import com.intellij.openapi.actionSystem.PlatformDataKeys
|
import com.intellij.openapi.actionSystem.PlatformDataKeys
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiClass
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.PsiElement
|
import org.jetbrains.kotlin.asJava.toLightClass
|
||||||
import com.intellij.psi.PsiFile
|
import org.jetbrains.kotlin.config.TargetPlatformKind
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.SourceNavigationHelper
|
import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.KtFakeLightClass
|
||||||
|
import org.jetbrains.kotlin.idea.project.targetPlatform
|
||||||
import org.jetbrains.kotlin.idea.search.allScope
|
import org.jetbrains.kotlin.idea.search.allScope
|
||||||
import org.jetbrains.kotlin.idea.stubindex.KotlinClassShortNameIndex
|
import org.jetbrains.kotlin.idea.stubindex.KotlinClassShortNameIndex
|
||||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||||
|
import org.jetbrains.kotlin.idea.util.module
|
||||||
|
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
@@ -39,12 +43,30 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
class KotlinTypeHierarchyProvider : JavaTypeHierarchyProvider() {
|
class KotlinTypeHierarchyProvider : JavaTypeHierarchyProvider() {
|
||||||
private fun getTargetByReference(project: Project, editor: Editor): PsiElement? {
|
private fun getOriginalPsiClassOrCreateLightClass(classOrObject: KtClassOrObject, module: Module?): PsiClass? {
|
||||||
|
val fqName = classOrObject.fqName
|
||||||
|
if (fqName != null && module?.targetPlatform is TargetPlatformKind.Jvm) {
|
||||||
|
val javaClassId = JavaToKotlinClassMap.mapKotlinToJava(fqName.toUnsafe())
|
||||||
|
if (javaClassId != null) {
|
||||||
|
return JavaPsiFacade.getInstance(classOrObject.project).findClass(
|
||||||
|
javaClassId.asSingleFqName().asString(),
|
||||||
|
GlobalSearchScope.allScope(classOrObject.project)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return classOrObject.toLightClass() ?: KtFakeLightClass(classOrObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getTargetByReference(
|
||||||
|
project: Project,
|
||||||
|
editor: Editor,
|
||||||
|
module: Module?
|
||||||
|
): PsiElement? {
|
||||||
val target = TargetElementUtil.findTargetElement(editor, TargetElementUtil.getInstance().allAccepted)
|
val target = TargetElementUtil.findTargetElement(editor, TargetElementUtil.getInstance().allAccepted)
|
||||||
|
|
||||||
return when (target) {
|
return when (target) {
|
||||||
is PsiClass -> target
|
is PsiClass -> target
|
||||||
is KtClassOrObject -> SourceNavigationHelper.getOriginalPsiClassOrCreateLightClass(target)
|
is KtClassOrObject -> getOriginalPsiClassOrCreateLightClass(target, module)
|
||||||
is KtNamedFunction -> { // Factory methods
|
is KtNamedFunction -> { // Factory methods
|
||||||
val functionName = target.name
|
val functionName = target.name
|
||||||
val functionDescriptor = target.analyze()[BindingContext.FUNCTION, target] ?: return null
|
val functionDescriptor = target.analyze()[BindingContext.FUNCTION, target] ?: return null
|
||||||
@@ -53,7 +75,7 @@ class KotlinTypeHierarchyProvider : JavaTypeHierarchyProvider() {
|
|||||||
if (returnTypeText != functionName) return null
|
if (returnTypeText != functionName) return null
|
||||||
val classOrObject = KotlinClassShortNameIndex.getInstance()[functionName, project, project.allScope()].singleOrNull()
|
val classOrObject = KotlinClassShortNameIndex.getInstance()[functionName, project, project.allScope()].singleOrNull()
|
||||||
?: return null
|
?: return null
|
||||||
SourceNavigationHelper.getOriginalPsiClassOrCreateLightClass(classOrObject)
|
getOriginalPsiClassOrCreateLightClass(classOrObject, module)
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -63,7 +85,7 @@ class KotlinTypeHierarchyProvider : JavaTypeHierarchyProvider() {
|
|||||||
val offset = editor.caretModel.offset
|
val offset = editor.caretModel.offset
|
||||||
val element = file.findElementAt(offset) ?: return null
|
val element = file.findElementAt(offset) ?: return null
|
||||||
val classOrObject = element.getNonStrictParentOfType<KtClassOrObject>() ?: return null
|
val classOrObject = element.getNonStrictParentOfType<KtClassOrObject>() ?: return null
|
||||||
return SourceNavigationHelper.getOriginalPsiClassOrCreateLightClass(classOrObject)
|
return getOriginalPsiClassOrCreateLightClass(classOrObject, file.module)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTarget(dataContext: DataContext): PsiElement? {
|
override fun getTarget(dataContext: DataContext): PsiElement? {
|
||||||
@@ -73,11 +95,11 @@ class KotlinTypeHierarchyProvider : JavaTypeHierarchyProvider() {
|
|||||||
if (editor != null) {
|
if (editor != null) {
|
||||||
val file = PsiDocumentManager.getInstance(project).getPsiFile(editor.document) ?: return null
|
val file = PsiDocumentManager.getInstance(project).getPsiFile(editor.document) ?: return null
|
||||||
if (!ProjectRootsUtil.isInProjectOrLibSource(file)) return null
|
if (!ProjectRootsUtil.isInProjectOrLibSource(file)) return null
|
||||||
return getTargetByReference(project, editor) ?: getTargetByContainingElement(editor, file)
|
return getTargetByReference(project, editor, file.module) ?: getTargetByContainingElement(editor, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
val element = LangDataKeys.PSI_ELEMENT.getData(dataContext)
|
val element = LangDataKeys.PSI_ELEMENT.getData(dataContext)
|
||||||
if (element is KtClassOrObject) return SourceNavigationHelper.getOriginalPsiClassOrCreateLightClass((element as KtClassOrObject?)!!)
|
if (element is KtClassOrObject) return getOriginalPsiClassOrCreateLightClass(element, element.module)
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user