diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtFakeLightClass.kt b/compiler/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KtFakeLightClass.kt similarity index 53% rename from compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtFakeLightClass.kt rename to compiler/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KtFakeLightClass.kt index 53a24a173c2..658c33a4077 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtFakeLightClass.kt +++ b/compiler/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KtFakeLightClass.kt @@ -10,19 +10,11 @@ import com.intellij.openapi.project.Project import com.intellij.psi.* import com.intellij.psi.impl.PsiClassImplUtil import com.intellij.psi.impl.light.AbstractLightClass -import com.intellij.psi.impl.light.LightMethod import com.intellij.psi.search.SearchScope import com.intellij.util.IncorrectOperationException -import org.jetbrains.kotlin.asJava.LightClassGenerationSupport -import org.jetbrains.kotlin.asJava.elements.KtLightElement -import org.jetbrains.kotlin.asJava.toFakeLightClass -import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.KtNamedDeclaration -import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject -import org.jetbrains.kotlin.resolve.DescriptorUtils import javax.swing.Icon // Used as a placeholder when actual light class does not exist (expect-classes, for example) @@ -51,63 +43,7 @@ abstract class KtFakeLightClass(override val kotlinOrigin: KtClassOrObject) : override fun isEquivalentTo(another: PsiElement?): Boolean = PsiClassImplUtil.isClassEquivalentTo(this, another) } -class KtDescriptorBasedFakeLightClass(kotlinOrigin: KtClassOrObject) : KtFakeLightClass(kotlinOrigin) { - - override fun copy(): KtFakeLightClass = KtDescriptorBasedFakeLightClass(kotlinOrigin) - - private val _containingClass: KtFakeLightClass? by lazy { - kotlinOrigin.containingClassOrObject?.let { KtDescriptorBasedFakeLightClass(it) } - } - override fun getContainingClass(): KtFakeLightClass? = _containingClass - - override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean { - if (manager.areElementsEquivalent(baseClass, this)) return false - LightClassInheritanceHelper.getService(project).isInheritor(this, baseClass, checkDeep).ifSure { return it } - - val baseKtClass = (baseClass as? KtLightClass)?.kotlinOrigin ?: return false - - val generationSupport = LightClassGenerationSupport.getInstance(project) - - val baseDescriptor = generationSupport.resolveToDescriptor(baseKtClass) as? ClassDescriptor ?: return false - val thisDescriptor = generationSupport.resolveToDescriptor(kotlinOrigin) as? ClassDescriptor ?: return false - - val thisFqName = DescriptorUtils.getFqName(thisDescriptor).asString() - val baseFqName = DescriptorUtils.getFqName(baseDescriptor).asString() - if (thisFqName == baseFqName) return false - - return if (checkDeep) - DescriptorUtils.isSubclass(thisDescriptor, baseDescriptor) - else - DescriptorUtils.isDirectSubclass(thisDescriptor, baseDescriptor) - } -} - -class KtFakeLightMethod private constructor( - val ktDeclaration: KtNamedDeclaration, - ktClassOrObject: KtClassOrObject -) : LightMethod( - ktDeclaration.manager, - DummyJavaPsiFactory.createDummyVoidMethod(ktDeclaration.project), - ktClassOrObject.toFakeLightClass(), - KotlinLanguage.INSTANCE -), KtLightElement { - override val kotlinOrigin get() = ktDeclaration - - override fun getName() = ktDeclaration.name ?: "" - - override fun getNavigationElement() = ktDeclaration - override fun getIcon(flags: Int): Icon? = ktDeclaration.getIcon(flags) - override fun getUseScope() = ktDeclaration.useScope - - companion object { - fun get(ktDeclaration: KtNamedDeclaration): KtFakeLightMethod? { - val ktClassOrObject = ktDeclaration.containingClassOrObject ?: return null - return KtFakeLightMethod(ktDeclaration, ktClassOrObject) - } - } -} - -private object DummyJavaPsiFactory { +object DummyJavaPsiFactory { fun createDummyVoidMethod(project: Project): PsiMethod { // Can't use PsiElementFactory.createMethod() because of formatting in PsiElementFactoryImpl. val name = "dummy" diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtDescriptorBasedFakeLightClass.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtDescriptorBasedFakeLightClass.kt new file mode 100644 index 00000000000..16995501fd1 --- /dev/null +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtDescriptorBasedFakeLightClass.kt @@ -0,0 +1,76 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.asJava.classes + +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiMethod +import com.intellij.psi.impl.light.LightMethod +import org.jetbrains.kotlin.asJava.LightClassGenerationSupport +import org.jetbrains.kotlin.asJava.elements.KtLightElement +import org.jetbrains.kotlin.asJava.toFakeLightClass +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.idea.KotlinLanguage +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject +import org.jetbrains.kotlin.resolve.DescriptorUtils +import javax.swing.Icon + +class KtDescriptorBasedFakeLightClass(kotlinOrigin: KtClassOrObject) : KtFakeLightClass(kotlinOrigin) { + override fun copy(): KtFakeLightClass = KtDescriptorBasedFakeLightClass(kotlinOrigin) + + private val _containingClass: KtFakeLightClass? by lazy { + kotlinOrigin.containingClassOrObject?.let { KtDescriptorBasedFakeLightClass(it) } + } + + override fun getContainingClass(): KtFakeLightClass? = _containingClass + + override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean { + if (manager.areElementsEquivalent(baseClass, this)) return false + LightClassInheritanceHelper.getService(project).isInheritor(this, baseClass, checkDeep).ifSure { return it } + + val baseKtClass = (baseClass as? KtLightClass)?.kotlinOrigin ?: return false + + val generationSupport = LightClassGenerationSupport.getInstance(project) + + val baseDescriptor = generationSupport.resolveToDescriptor(baseKtClass) as? ClassDescriptor ?: return false + val thisDescriptor = generationSupport.resolveToDescriptor(kotlinOrigin) as? ClassDescriptor ?: return false + + val thisFqName = DescriptorUtils.getFqName(thisDescriptor).asString() + val baseFqName = DescriptorUtils.getFqName(baseDescriptor).asString() + if (thisFqName == baseFqName) return false + + return if (checkDeep) + DescriptorUtils.isSubclass(thisDescriptor, baseDescriptor) + else + DescriptorUtils.isDirectSubclass(thisDescriptor, baseDescriptor) + } +} + +class KtFakeLightMethod private constructor( + val ktDeclaration: KtNamedDeclaration, + ktClassOrObject: KtClassOrObject +) : LightMethod( + ktDeclaration.manager, + DummyJavaPsiFactory.createDummyVoidMethod(ktDeclaration.project), + ktClassOrObject.toFakeLightClass(), + KotlinLanguage.INSTANCE +), KtLightElement { + override val kotlinOrigin get() = ktDeclaration + + override fun getName() = ktDeclaration.name ?: "" + + override fun getNavigationElement() = ktDeclaration + override fun getIcon(flags: Int): Icon? = ktDeclaration.getIcon(flags) + override fun getUseScope() = ktDeclaration.useScope + + companion object { + fun get(ktDeclaration: KtNamedDeclaration): KtFakeLightMethod? { + val ktClassOrObject = ktDeclaration.containingClassOrObject ?: return null + return KtFakeLightMethod(ktDeclaration, ktClassOrObject) + } + } +}