[light classes] move descriptors from KtLightClassForSourceDeclaration to KtLightClassImpl
^KT-53097
This commit is contained in:
@@ -108,7 +108,7 @@ class CliKotlinAsJavaSupport(
|
|||||||
).mapNotNull { member -> (member as? PackageViewDescriptor)?.fqName }
|
).mapNotNull { member -> (member as? PackageViewDescriptor)?.fqName }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? = KtLightClassForSourceDeclaration.create(classOrObject)
|
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? = KtLightClassImpl.create(classOrObject)
|
||||||
|
|
||||||
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = KtLightClassForScript.create(script)
|
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = KtLightClassForScript.create(script)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -85,7 +85,7 @@ abstract class KtLightClassForScript(val script: KtScript) : KtLightClassBase(sc
|
|||||||
// inner classes with null names can't be searched for and can't be used from java anyway
|
// inner classes with null names can't be searched for and can't be used from java anyway
|
||||||
// we can't prohibit creating light classes with null names either since they can contain members
|
// we can't prohibit creating light classes with null names either since they can contain members
|
||||||
.filter { it.name != null }
|
.filter { it.name != null }
|
||||||
.mapNotNull { KtLightClassForSourceDeclaration.create(it) }
|
.mapNotNull { KtLightClassImpl.create(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getInitializers(): Array<PsiClassInitializer> = PsiClassInitializer.EMPTY_ARRAY
|
override fun getInitializers(): Array<PsiClassInitializer> = PsiClassInitializer.EMPTY_ARRAY
|
||||||
|
|||||||
+4
-110
@@ -11,23 +11,15 @@ import com.intellij.openapi.util.TextRange
|
|||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.impl.source.PsiImmediateClassType
|
import com.intellij.psi.impl.source.PsiImmediateClassType
|
||||||
import com.intellij.psi.impl.source.tree.TreeUtil
|
import com.intellij.psi.impl.source.tree.TreeUtil
|
||||||
import com.intellij.psi.scope.PsiScopeProcessor
|
|
||||||
import com.intellij.psi.search.SearchScope
|
import com.intellij.psi.search.SearchScope
|
||||||
import com.intellij.psi.stubs.IStubElementType
|
import com.intellij.psi.stubs.IStubElementType
|
||||||
import com.intellij.psi.stubs.StubElement
|
import com.intellij.psi.stubs.StubElement
|
||||||
import com.intellij.psi.util.CachedValueProvider
|
|
||||||
import com.intellij.psi.util.CachedValuesManager
|
|
||||||
import com.intellij.psi.util.PsiUtilCore
|
import com.intellij.psi.util.PsiUtilCore
|
||||||
import com.intellij.util.IncorrectOperationException
|
import com.intellij.util.IncorrectOperationException
|
||||||
import org.jetbrains.annotations.NonNls
|
import org.jetbrains.annotations.NonNls
|
||||||
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
|
||||||
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult
|
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult
|
||||||
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.UNSURE
|
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.UNSURE
|
||||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
|
||||||
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
|
|
||||||
import org.jetbrains.kotlin.asJava.hasInterfaceDefaultImpls
|
|
||||||
import org.jetbrains.kotlin.config.JvmDefaultMode
|
import org.jetbrains.kotlin.config.JvmDefaultMode
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||||
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
|
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
|
||||||
@@ -38,16 +30,6 @@ import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
|||||||
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
|
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
|
||||||
import javax.swing.Icon
|
import javax.swing.Icon
|
||||||
|
|
||||||
private class KtLightClassModifierList(containingClass: KtLightClassForSourceDeclaration, computeModifiers: () -> Set<String>) :
|
|
||||||
KtLightModifierList<KtLightClassForSourceDeclaration>(containingClass) {
|
|
||||||
|
|
||||||
private val modifiers by lazyPub { computeModifiers() }
|
|
||||||
|
|
||||||
override fun hasModifierProperty(name: String): Boolean =
|
|
||||||
if (name != PsiModifier.FINAL) name in modifiers else owner.isFinal(PsiModifier.FINAL in modifiers)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class KtLightClassForSourceDeclaration(
|
abstract class KtLightClassForSourceDeclaration(
|
||||||
protected val classOrObject: KtClassOrObject,
|
protected val classOrObject: KtClassOrObject,
|
||||||
protected val jvmDefaultMode: JvmDefaultMode,
|
protected val jvmDefaultMode: JvmDefaultMode,
|
||||||
@@ -75,7 +57,6 @@ abstract class KtLightClassForSourceDeclaration(
|
|||||||
|
|
||||||
private val _extendsList by lazyPub { createExtendsList() }
|
private val _extendsList by lazyPub { createExtendsList() }
|
||||||
private val _implementsList by lazyPub { createImplementsList() }
|
private val _implementsList by lazyPub { createImplementsList() }
|
||||||
private val _deprecated by lazyPub { classOrObject.isDeprecated() }
|
|
||||||
|
|
||||||
protected abstract fun createExtendsList(): PsiReferenceList?
|
protected abstract fun createExtendsList(): PsiReferenceList?
|
||||||
protected abstract fun createImplementsList(): PsiReferenceList?
|
protected abstract fun createImplementsList(): PsiReferenceList?
|
||||||
@@ -86,35 +67,7 @@ abstract class KtLightClassForSourceDeclaration(
|
|||||||
abstract override fun getParent(): PsiElement?
|
abstract override fun getParent(): PsiElement?
|
||||||
abstract override fun getQualifiedName(): String?
|
abstract override fun getQualifiedName(): String?
|
||||||
|
|
||||||
private val _containingFile: PsiFile by lazyPub {
|
abstract override fun getContainingFile(): PsiFile?
|
||||||
object : FakeFileForLightClass(
|
|
||||||
classOrObject.containingKtFile,
|
|
||||||
{ if (classOrObject.isTopLevel()) this else create(getOutermostClassOrObject(classOrObject))!! },
|
|
||||||
) {
|
|
||||||
override fun findReferenceAt(offset: Int) = ktFile.findReferenceAt(offset)
|
|
||||||
|
|
||||||
override fun processDeclarations(
|
|
||||||
processor: PsiScopeProcessor,
|
|
||||||
state: ResolveState,
|
|
||||||
lastParent: PsiElement?,
|
|
||||||
place: PsiElement
|
|
||||||
): Boolean {
|
|
||||||
if (!super.processDeclarations(processor, state, lastParent, place)) return false
|
|
||||||
|
|
||||||
// We have to explicitly process package declarations if current file belongs to default package
|
|
||||||
// so that Java resolve can find classes located in that package
|
|
||||||
val packageName = packageName
|
|
||||||
if (!packageName.isEmpty()) return true
|
|
||||||
|
|
||||||
val aPackage = JavaPsiFacade.getInstance(myManager.project).findPackage(packageName)
|
|
||||||
if (aPackage != null && !aPackage.processDeclarations(processor, state, null, place)) return false
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getContainingFile(): PsiFile? = _containingFile
|
|
||||||
|
|
||||||
override fun getNavigationElement(): PsiElement = classOrObject
|
override fun getNavigationElement(): PsiElement = classOrObject
|
||||||
|
|
||||||
@@ -140,17 +93,6 @@ abstract class KtLightClassForSourceDeclaration(
|
|||||||
|
|
||||||
override fun hashCode(): Int = classOrObject.hashCode() * 31 + jvmDefaultMode.hashCode()
|
override fun hashCode(): Int = classOrObject.hashCode() * 31 + jvmDefaultMode.hashCode()
|
||||||
|
|
||||||
override fun getContainingClass(): PsiClass? {
|
|
||||||
if (classOrObject.parent === classOrObject.containingFile) return null
|
|
||||||
|
|
||||||
val containingClassOrObject = (classOrObject.parent as? KtClassBody)?.parent as? KtClassOrObject
|
|
||||||
if (containingClassOrObject != null) {
|
|
||||||
return create(containingClassOrObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: should return null
|
|
||||||
return super.getContainingClass()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val _typeParameterList: PsiTypeParameterList by lazyPub { buildTypeParameterList() }
|
private val _typeParameterList: PsiTypeParameterList by lazyPub { buildTypeParameterList() }
|
||||||
|
|
||||||
@@ -162,15 +104,11 @@ abstract class KtLightClassForSourceDeclaration(
|
|||||||
|
|
||||||
override fun getName(): String? = classOrObject.nameAsName?.asString()
|
override fun getName(): String? = classOrObject.nameAsName?.asString()
|
||||||
|
|
||||||
private val _modifierList: PsiModifierList by lazyPub { KtLightClassModifierList(this) { computeModifiers() } }
|
abstract override fun getModifierList(): PsiModifierList?
|
||||||
|
|
||||||
override fun getModifierList(): PsiModifierList? = _modifierList
|
|
||||||
|
|
||||||
protected abstract fun computeModifiers(): Set<String>
|
protected abstract fun computeModifiers(): Set<String>
|
||||||
|
|
||||||
override fun hasModifierProperty(@NonNls name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false
|
override fun hasModifierProperty(@NonNls name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false
|
||||||
|
abstract override fun isDeprecated(): Boolean
|
||||||
override fun isDeprecated(): Boolean = _deprecated
|
|
||||||
|
|
||||||
override fun isInterface(): Boolean {
|
override fun isInterface(): Boolean {
|
||||||
if (classOrObject !is KtClass) return false
|
if (classOrObject !is KtClass) return false
|
||||||
@@ -195,25 +133,7 @@ abstract class KtLightClassForSourceDeclaration(
|
|||||||
|
|
||||||
override fun toString() = "${this::class.java.simpleName}:${classOrObject.getDebugText()}"
|
override fun toString() = "${this::class.java.simpleName}:${classOrObject.getDebugText()}"
|
||||||
|
|
||||||
override fun getOwnInnerClasses(): List<PsiClass> {
|
abstract override fun getOwnInnerClasses(): List<PsiClass>
|
||||||
val result = ArrayList<PsiClass>()
|
|
||||||
classOrObject.declarations.filterIsInstance<KtClassOrObject>()
|
|
||||||
// workaround for ClassInnerStuffCache not supporting classes with null names, see KT-13927
|
|
||||||
// inner classes with null names can't be searched for and can't be used from java anyway
|
|
||||||
// we can't prohibit creating light classes with null names either since they can contain members
|
|
||||||
.filter { it.name != null }
|
|
||||||
.mapNotNullTo(result) {
|
|
||||||
create(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (classOrObject.hasInterfaceDefaultImpls && jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE) {
|
|
||||||
result.add(createClassForInterfaceDefaultImpls())
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun createClassForInterfaceDefaultImpls(): PsiClass
|
|
||||||
|
|
||||||
override fun getUseScope(): SearchScope = kotlinOrigin.useScope
|
override fun getUseScope(): SearchScope = kotlinOrigin.useScope
|
||||||
|
|
||||||
@@ -225,32 +145,6 @@ abstract class KtLightClassForSourceDeclaration(
|
|||||||
override fun getExtendsList(): PsiReferenceList? = _extendsList
|
override fun getExtendsList(): PsiReferenceList? = _extendsList
|
||||||
override fun getImplementsList(): PsiReferenceList? = _implementsList
|
override fun getImplementsList(): PsiReferenceList? = _implementsList
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun create(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? =
|
|
||||||
CachedValuesManager.getCachedValue(classOrObject) {
|
|
||||||
CachedValueProvider.Result.create(
|
|
||||||
createNoCache(classOrObject),
|
|
||||||
KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createNoCache(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? {
|
|
||||||
val containingFile = classOrObject.containingFile
|
|
||||||
if (containingFile is KtCodeFragment) {
|
|
||||||
// Avoid building light classes for code fragments
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (classOrObject.shouldNotBeVisibleAsLightClass()) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return LightClassGenerationSupport.getInstance(classOrObject.project).run {
|
|
||||||
createUltraLightClass(classOrObject)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract override fun getSupers(): Array<PsiClass>
|
abstract override fun getSupers(): Array<PsiClass>
|
||||||
|
|
||||||
abstract override fun getSuperTypes(): Array<PsiClassType>
|
abstract override fun getSuperTypes(): Array<PsiClassType>
|
||||||
|
|||||||
+144
-32
@@ -5,20 +5,35 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.asJava.classes
|
package org.jetbrains.kotlin.asJava.classes
|
||||||
|
|
||||||
import com.intellij.psi.CommonClassNames
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.PsiClass
|
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.psi.PsiModifier
|
|
||||||
import com.intellij.psi.impl.InheritanceImplUtil
|
import com.intellij.psi.impl.InheritanceImplUtil
|
||||||
|
import com.intellij.psi.scope.PsiScopeProcessor
|
||||||
|
import com.intellij.psi.util.CachedValueProvider
|
||||||
|
import com.intellij.psi.util.CachedValuesManager
|
||||||
|
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
||||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
|
||||||
|
import org.jetbrains.kotlin.asJava.hasInterfaceDefaultImpls
|
||||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||||
import org.jetbrains.kotlin.config.JvmDefaultMode
|
import org.jetbrains.kotlin.config.JvmDefaultMode
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
|
import org.jetbrains.kotlin.psi.KtClassBody
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
|
import org.jetbrains.kotlin.psi.KtCodeFragment
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
|
||||||
|
private class KtLightClassModifierList(containingClass: KtLightClassForSourceDeclaration, computeModifiers: () -> Set<String>) :
|
||||||
|
KtLightModifierList<KtLightClassForSourceDeclaration>(containingClass) {
|
||||||
|
|
||||||
|
private val modifiers by lazyPub { computeModifiers() }
|
||||||
|
|
||||||
|
override fun hasModifierProperty(name: String): Boolean =
|
||||||
|
if (name != PsiModifier.FINAL) name in modifiers else owner.isFinal(PsiModifier.FINAL in modifiers)
|
||||||
|
}
|
||||||
|
|
||||||
// light class for top level or (inner/nested of top level) source declarations
|
// light class for top level or (inner/nested of top level) source declarations
|
||||||
abstract class KtLightClassImpl @JvmOverloads constructor(
|
abstract class KtLightClassImpl @JvmOverloads constructor(
|
||||||
classOrObject: KtClassOrObject,
|
classOrObject: KtClassOrObject,
|
||||||
@@ -28,6 +43,15 @@ abstract class KtLightClassImpl @JvmOverloads constructor(
|
|||||||
fun getDescriptor() =
|
fun getDescriptor() =
|
||||||
LightClassGenerationSupport.getInstance(project).resolveToDescriptor(classOrObject) as? ClassDescriptor
|
LightClassGenerationSupport.getInstance(project).resolveToDescriptor(classOrObject) as? ClassDescriptor
|
||||||
|
|
||||||
|
private val _deprecated by lazyPub { classOrObject.isDeprecated() }
|
||||||
|
|
||||||
|
override fun isDeprecated(): Boolean = _deprecated
|
||||||
|
|
||||||
|
|
||||||
|
private val _modifierList: PsiModifierList by lazyPub { KtLightClassModifierList(this) { computeModifiers() } }
|
||||||
|
|
||||||
|
override fun getModifierList(): PsiModifierList? = _modifierList
|
||||||
|
|
||||||
override fun computeModifiers(): Set<String> {
|
override fun computeModifiers(): Set<String> {
|
||||||
val psiModifiers = hashSetOf<String>()
|
val psiModifiers = hashSetOf<String>()
|
||||||
|
|
||||||
@@ -110,41 +134,129 @@ abstract class KtLightClassImpl @JvmOverloads constructor(
|
|||||||
containingClass
|
containingClass
|
||||||
|
|
||||||
abstract override fun copy(): PsiElement
|
abstract override fun copy(): PsiElement
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkSuperTypeByFQName(classDescriptor: ClassDescriptor, qualifiedName: String, deep: Boolean): Boolean {
|
private val _containingFile: PsiFile by lazyPub {
|
||||||
if (CommonClassNames.JAVA_LANG_OBJECT == qualifiedName) return true
|
object : FakeFileForLightClass(
|
||||||
|
classOrObject.containingKtFile,
|
||||||
|
{ if (classOrObject.isTopLevel()) this else create(getOutermostClassOrObject(classOrObject))!! },
|
||||||
|
) {
|
||||||
|
override fun findReferenceAt(offset: Int) = ktFile.findReferenceAt(offset)
|
||||||
|
|
||||||
if (qualifiedName == DescriptorUtils.getFqName(classDescriptor).asString()) return true
|
override fun processDeclarations(
|
||||||
|
processor: PsiScopeProcessor,
|
||||||
|
state: ResolveState,
|
||||||
|
lastParent: PsiElement?,
|
||||||
|
place: PsiElement
|
||||||
|
): Boolean {
|
||||||
|
if (!super.processDeclarations(processor, state, lastParent, place)) return false
|
||||||
|
|
||||||
val fqName = FqNameUnsafe(qualifiedName)
|
// We have to explicitly process package declarations if current file belongs to default package
|
||||||
val mappedQName =
|
// so that Java resolve can find classes located in that package
|
||||||
if (fqName.isSafe)
|
val packageName = packageName
|
||||||
JavaToKotlinClassMap.mapJavaToKotlin(fqName.toSafe())?.asSingleFqName()?.asString()
|
if (packageName.isNotEmpty()) return true
|
||||||
else null
|
|
||||||
if (qualifiedName == mappedQName) return true
|
|
||||||
|
|
||||||
for (superType in classDescriptor.typeConstructor.supertypes) {
|
val aPackage = JavaPsiFacade.getInstance(myManager.project).findPackage(packageName)
|
||||||
val superDescriptor = superType.constructor.declarationDescriptor
|
if (aPackage != null && !aPackage.processDeclarations(processor, state, null, place)) return false
|
||||||
|
|
||||||
if (superDescriptor is ClassDescriptor) {
|
return true
|
||||||
val superQName = DescriptorUtils.getFqName(superDescriptor).asString()
|
|
||||||
if (superQName == qualifiedName || superQName == mappedQName) return true
|
|
||||||
|
|
||||||
if (deep) {
|
|
||||||
if (checkSuperTypeByFQName(superDescriptor, qualifiedName, true)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
override fun getContainingFile(): PsiFile? = _containingFile
|
||||||
}
|
|
||||||
|
|
||||||
private val jetTokenToPsiModifier = listOf(
|
override fun getOwnInnerClasses(): List<PsiClass> {
|
||||||
KtTokens.PUBLIC_KEYWORD to PsiModifier.PUBLIC,
|
val result = ArrayList<PsiClass>()
|
||||||
KtTokens.INTERNAL_KEYWORD to PsiModifier.PUBLIC,
|
classOrObject.declarations.filterIsInstance<KtClassOrObject>()
|
||||||
KtTokens.PROTECTED_KEYWORD to PsiModifier.PROTECTED,
|
// workaround for ClassInnerStuffCache not supporting classes with null names, see KT-13927
|
||||||
KtTokens.FINAL_KEYWORD to PsiModifier.FINAL,
|
// inner classes with null names can't be searched for and can't be used from java anyway
|
||||||
)
|
// we can't prohibit creating light classes with null names either since they can contain members
|
||||||
|
.filter { it.name != null }
|
||||||
|
.mapNotNullTo(result) {
|
||||||
|
create(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classOrObject.hasInterfaceDefaultImpls && jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE) {
|
||||||
|
result.add(createClassForInterfaceDefaultImpls())
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun createClassForInterfaceDefaultImpls(): PsiClass
|
||||||
|
|
||||||
|
override fun getContainingClass(): PsiClass? {
|
||||||
|
if (classOrObject.parent === classOrObject.containingFile) return null
|
||||||
|
|
||||||
|
val containingClassOrObject = (classOrObject.parent as? KtClassBody)?.parent as? KtClassOrObject
|
||||||
|
if (containingClassOrObject != null) {
|
||||||
|
return create(containingClassOrObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: should return null
|
||||||
|
return super.getContainingClass()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private fun checkSuperTypeByFQName(classDescriptor: ClassDescriptor, qualifiedName: String, deep: Boolean): Boolean {
|
||||||
|
if (CommonClassNames.JAVA_LANG_OBJECT == qualifiedName) return true
|
||||||
|
|
||||||
|
if (qualifiedName == DescriptorUtils.getFqName(classDescriptor).asString()) return true
|
||||||
|
|
||||||
|
val fqName = FqNameUnsafe(qualifiedName)
|
||||||
|
val mappedQName =
|
||||||
|
if (fqName.isSafe)
|
||||||
|
JavaToKotlinClassMap.mapJavaToKotlin(fqName.toSafe())?.asSingleFqName()?.asString()
|
||||||
|
else null
|
||||||
|
if (qualifiedName == mappedQName) return true
|
||||||
|
|
||||||
|
for (superType in classDescriptor.typeConstructor.supertypes) {
|
||||||
|
val superDescriptor = superType.constructor.declarationDescriptor
|
||||||
|
|
||||||
|
if (superDescriptor is ClassDescriptor) {
|
||||||
|
val superQName = DescriptorUtils.getFqName(superDescriptor).asString()
|
||||||
|
if (superQName == qualifiedName || superQName == mappedQName) return true
|
||||||
|
|
||||||
|
if (deep) {
|
||||||
|
if (checkSuperTypeByFQName(superDescriptor, qualifiedName, true)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private val jetTokenToPsiModifier = listOf(
|
||||||
|
KtTokens.PUBLIC_KEYWORD to PsiModifier.PUBLIC,
|
||||||
|
KtTokens.INTERNAL_KEYWORD to PsiModifier.PUBLIC,
|
||||||
|
KtTokens.PROTECTED_KEYWORD to PsiModifier.PROTECTED,
|
||||||
|
KtTokens.FINAL_KEYWORD to PsiModifier.FINAL,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun create(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? =
|
||||||
|
CachedValuesManager.getCachedValue(classOrObject) {
|
||||||
|
CachedValueProvider.Result.create(
|
||||||
|
createNoCache(classOrObject),
|
||||||
|
KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNoCache(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? {
|
||||||
|
val containingFile = classOrObject.containingFile
|
||||||
|
if (containingFile is KtCodeFragment) {
|
||||||
|
// Avoid building light classes for code fragments
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classOrObject.shouldNotBeVisibleAsLightClass()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return LightClassGenerationSupport.getInstance(classOrObject.project).run {
|
||||||
|
createUltraLightClass(classOrObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user