Remove fallbacking of UL (to LightClasses) by complexity checking

This commit is contained in:
Igor Yakovlev
2019-10-09 21:52:26 +03:00
parent 3f9bffcc5f
commit 58b8d8868a
14 changed files with 46 additions and 145 deletions
@@ -90,7 +90,7 @@ internal open class KtLightClassForAnonymousDeclaration(classOrObject: KtClassOr
companion object { companion object {
fun KtLightClassForSourceDeclaration.getFirstSupertypeFQNameForAnonymousDeclaration(): String { fun KtLightClassForSourceDeclaration.getFirstSupertypeFQNameForAnonymousDeclaration(): String {
val descriptor = descriptor.value ?: return CommonClassNames.JAVA_LANG_OBJECT val descriptor = getDescriptor() ?: return CommonClassNames.JAVA_LANG_OBJECT
val superTypes = descriptor.typeConstructor.supertypes val superTypes = descriptor.typeConstructor.supertypes
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.asJava.classes package org.jetbrains.kotlin.asJava.classes
import com.google.common.annotations.VisibleForTesting
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Comparing import com.intellij.openapi.util.Comparing
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
@@ -53,21 +52,7 @@ open class KtLightClassForFacade constructor(
files: Collection<KtFile> files: Collection<KtFile>
) : KtLazyLightClass(manager) { ) : KtLazyLightClass(manager) {
@Volatile
@VisibleForTesting
var isClsDelegateLoaded = false
override val clsDelegate: PsiClass
get() {
isClsDelegateLoaded = true
return super.clsDelegate
}
protected open val lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade> = myLightClassDataCache protected open val lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade> = myLightClassDataCache
get() {
isClsDelegateLoaded = true
return field
}
val files: Collection<KtFile> = files.toSet() val files: Collection<KtFile> = files.toSet()
@@ -113,9 +113,8 @@ abstract class KtLightClassForSourceDeclaration(
private fun getJavaFileStub(): PsiJavaFileStub = getLightClassDataHolder().javaFileStub private fun getJavaFileStub(): PsiJavaFileStub = getLightClassDataHolder().javaFileStub
public val descriptor = lazyPub { fun getDescriptor() =
LightClassGenerationSupport.getInstance(project).resolveToDescriptor(classOrObject) as? ClassDescriptor LightClassGenerationSupport.getInstance(project).resolveToDescriptor(classOrObject) as? ClassDescriptor
}
protected fun getLightClassDataHolder(): LightClassDataHolder.ForClass { protected fun getLightClassDataHolder(): LightClassDataHolder.ForClass {
val lightClassData = getLightClassDataHolder(classOrObject) val lightClassData = getLightClassDataHolder(classOrObject)
@@ -234,12 +233,9 @@ abstract class KtLightClassForSourceDeclaration(
// AllOpen can affect on modality of the member. We ought to check if the extension could override the modality // AllOpen can affect on modality of the member. We ought to check if the extension could override the modality
// Resolver will produce correct descriptor corresponding to modality from AllOpen. // Resolver will produce correct descriptor corresponding to modality from AllOpen.
// The easiest way to get new modality is to resolve the descriptor // The easiest way to get new modality is to resolve the descriptor
val modifierToAdd = if (kotlinOrigin.isOrdinaryClass && descriptor.value?.modality == Modality.OPEN) { if (!kotlinOrigin.isOrdinaryClass || getDescriptor()?.modality != Modality.OPEN) {
PsiModifier.OPEN psiModifiers.add(PsiModifier.FINAL)
} else {
PsiModifier.FINAL
} }
psiModifiers.add(modifierToAdd)
} }
if (!classOrObject.isTopLevel() && !classOrObject.hasModifier(INNER_KEYWORD)) { if (!classOrObject.isTopLevel() && !classOrObject.hasModifier(INNER_KEYWORD)) {
@@ -274,13 +270,13 @@ abstract class KtLightClassForSourceDeclaration(
LightClassInheritanceHelper.getService(project).isInheritor(this, baseClass, checkDeep).ifSure { return it } LightClassInheritanceHelper.getService(project).isInheritor(this, baseClass, checkDeep).ifSure { return it }
val qualifiedName: String? = if (baseClass is KtLightClassForSourceDeclaration) { val qualifiedName: String? = if (baseClass is KtLightClassForSourceDeclaration) {
val baseDescriptor = baseClass.descriptor.value val baseDescriptor = baseClass.getDescriptor()
if (baseDescriptor != null) DescriptorUtils.getFqName(baseDescriptor).asString() else null if (baseDescriptor != null) DescriptorUtils.getFqName(baseDescriptor).asString() else null
} else { } else {
baseClass.qualifiedName baseClass.qualifiedName
} }
val thisDescriptor = descriptor.value val thisDescriptor = getDescriptor()
return qualifiedName != null && thisDescriptor != null && checkSuperTypeByFQName(thisDescriptor, qualifiedName, checkDeep) return qualifiedName != null && thisDescriptor != null && checkSuperTypeByFQName(thisDescriptor, qualifiedName, checkDeep)
} }
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.asJava.classes package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.HierarchicalMethodSignature import com.intellij.psi.HierarchicalMethodSignature
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.impl.PsiSuperMethodImplUtil import com.intellij.psi.impl.PsiSuperMethodImplUtil
import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightField
@@ -71,7 +70,7 @@ class KtUltraLightInlineClass(
override fun getOwnFields(): List<KtLightField> = emptyList() override fun getOwnFields(): List<KtLightField> = emptyList()
override fun getOwnMethods() = if (tooComplex) super.getOwnMethods() else _ownMethods override fun getOwnMethods() = _ownMethods
override fun getVisibleSignatures(): MutableCollection<HierarchicalMethodSignature> = PsiSuperMethodImplUtil.getVisibleSignatures(this) override fun getVisibleSignatures(): MutableCollection<HierarchicalMethodSignature> = PsiSuperMethodImplUtil.getVisibleSignatures(this)
@@ -24,28 +24,13 @@ class KtUltraLightClassForFacade(
private val filesWithSupports: Collection<Pair<KtFile, KtUltraLightSupport>> private val filesWithSupports: Collection<Pair<KtFile, KtUltraLightSupport>>
) : KtLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files) { ) : KtLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files) {
private inline fun <T> forTooComplex(getter: () -> T): T { override fun getDelegate(): PsiClass = invalidAccess()
check(tooComplex) {
"Cls delegate shouldn't be loaded for not too complex ultra-light classes! Qualified name: $qualifiedName"
}
return getter()
}
override fun getDelegate(): PsiClass = forTooComplex { super.getDelegate() } override val lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade> get() = invalidAccess()
override val lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade> override val clsDelegate: PsiClass get() = invalidAccess()
get() = forTooComplex { super.lightClassDataCache }
override val clsDelegate: PsiClass override fun getScope(): PsiElement? = parent
get() = forTooComplex { super.clsDelegate }
override fun getScope(): PsiElement? = if (!tooComplex) parent else super.getScope()
private val tooComplex: Boolean by lazyPub {
filesWithSupports.any { (file, support) ->
file.declarations.any { support.isTooComplexForUltraLightGeneration(it) }
}
}
private val filesWithSupportsWithCreators by lazyPub { private val filesWithSupportsWithCreators by lazyPub {
filesWithSupports.map { (file, support) -> filesWithSupports.map { (file, support) ->
@@ -86,7 +71,7 @@ class KtUltraLightClassForFacade(
} }
} }
private val ownMethodsForNotTooComplex: List<KtLightMethod> by lazyPub { private val _ownMethods: List<KtLightMethod> by lazyPub {
mutableListOf<KtLightMethod>().also { result -> mutableListOf<KtLightMethod>().also { result ->
for ((file, support, creator) in filesWithSupportsWithCreators) { for ((file, support, creator) in filesWithSupportsWithCreators) {
loadMethodsFromFile(file, support, creator, result) loadMethodsFromFile(file, support, creator, result)
@@ -94,7 +79,7 @@ class KtUltraLightClassForFacade(
} }
} }
private val ownFieldsForNotTooComplex: List<KtLightField> by lazyPub { private val _ownFields: List<KtLightField> by lazyPub {
hashSetOf<String>().let { nameCache -> hashSetOf<String>().let { nameCache ->
filesWithSupportsWithCreators.flatMap { (file, _, creator) -> filesWithSupportsWithCreators.flatMap { (file, _, creator) ->
file.declarations.filterIsInstance<KtProperty>().mapNotNull { file.declarations.filterIsInstance<KtProperty>().mapNotNull {
@@ -104,9 +89,9 @@ class KtUltraLightClassForFacade(
} }
} }
override fun getOwnFields() = if (!tooComplex) ownFieldsForNotTooComplex else super.getOwnFields() override fun getOwnFields() = _ownFields
override fun getOwnMethods() = if (!tooComplex) ownMethodsForNotTooComplex else super.getOwnMethods() override fun getOwnMethods() = _ownMethods
override fun getVisibleSignatures(): MutableCollection<HierarchicalMethodSignature> = PsiSuperMethodImplUtil.getVisibleSignatures(this) override fun getVisibleSignatures(): MutableCollection<HierarchicalMethodSignature> = PsiSuperMethodImplUtil.getVisibleSignatures(this)
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.asJava.classes package org.jetbrains.kotlin.asJava.classes
import com.google.common.annotations.VisibleForTesting
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.impl.InheritanceImplUtil import com.intellij.psi.impl.InheritanceImplUtil
import com.intellij.psi.impl.PsiClassImplUtil import com.intellij.psi.impl.PsiClassImplUtil
@@ -23,7 +22,6 @@ import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
import org.jetbrains.kotlin.codegen.kotlinType import org.jetbrains.kotlin.codegen.kotlinType
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -71,38 +69,22 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
) )
} }
protected val tooComplex: Boolean by lazyPub { support.isTooComplexForUltraLightGeneration(classOrObject) }
private val _deprecated by lazyPub { classOrObject.isDeprecated(support) } private val _deprecated by lazyPub { classOrObject.isDeprecated(support) }
override fun isFinal(isFinalByPsi: Boolean) = if (tooComplex) super.isFinal(isFinalByPsi) else isFinalByPsi override fun isFinal(isFinalByPsi: Boolean) = isFinalByPsi
@Volatile override fun findLightClassData(): LightClassData = invalidAccess()
@VisibleForTesting
var isClsDelegateLoaded = false
private inline fun <T> forTooComplex(getter: () -> T): T { override fun getDelegate(): PsiClass = invalidAccess()
if (!isClsDelegateLoaded) {
isClsDelegateLoaded = true
check(tooComplex) {
"Cls delegate shouldn't be loaded for not too complex ultra-light classes! Qualified name: $qualifiedName"
}
}
return getter()
}
override fun findLightClassData(): LightClassData = forTooComplex { super.findLightClassData() }
override fun getDelegate(): PsiClass = forTooComplex { super.getDelegate() }
private val _modifierList: PsiModifierList? by lazyPub { private val _modifierList: PsiModifierList? by lazyPub {
if (tooComplex) super.getModifierList() else KtUltraLightClassModifierList(this, support) { computeModifiers() } KtUltraLightClassModifierList(this, support) { computeModifiers() }
} }
override fun getModifierList(): PsiModifierList? = _modifierList override fun getModifierList(): PsiModifierList? = _modifierList
private fun allSuperTypes() = private fun allSuperTypes() =
descriptor.value?.typeConstructor?.supertypes.orEmpty() getDescriptor()?.typeConstructor?.supertypes.orEmpty()
private fun mapSupertype(supertype: KotlinType, kotlinCollectionAsIs: Boolean = false) = private fun mapSupertype(supertype: KotlinType, kotlinCollectionAsIs: Boolean = false) =
supertype.asPsiType( supertype.asPsiType(
@@ -121,8 +103,6 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
if (isAnnotationType) return KotlinLightReferenceListBuilder(manager, language, role) if (isAnnotationType) return KotlinLightReferenceListBuilder(manager, language, role)
if (tooComplex) return if (forExtendsList) super.createExtendsList() else super.createImplementsList()
val superTypes = allSuperTypes().filter { val superTypes = allSuperTypes().filter {
isTypeForInheritanceList(it, forExtendsList) isTypeForInheritanceList(it, forExtendsList)
} }
@@ -180,8 +160,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
return forExtendsList == !JvmCodegenUtil.isJvmInterface(supertype) return forExtendsList == !JvmCodegenUtil.isJvmInterface(supertype)
} }
override fun buildTypeParameterList(): PsiTypeParameterList = override fun buildTypeParameterList(): PsiTypeParameterList = buildTypeParameterList(classOrObject, this, support)
if (tooComplex) super.buildTypeParameterList() else buildTypeParameterList(classOrObject, this, support)
// the following logic should be in the platform (super), overrides can be removed once that happens // the following logic should be in the platform (super), overrides can be removed once that happens
override fun getInterfaces(): Array<PsiClass> = PsiClassImplUtil.getInterfaces(this) override fun getInterfaces(): Array<PsiClass> = PsiClassImplUtil.getInterfaces(this)
@@ -217,10 +196,11 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
} }
fun ArrayList<KtLightField>.updateWithCompilerPlugins() = also { fun ArrayList<KtLightField>.updateWithCompilerPlugins() = also {
val lazyDescriptor = lazy { getDescriptor() }
applyCompilerPlugins { applyCompilerPlugins {
it.interceptFieldsBuilding( it.interceptFieldsBuilding(
declaration = kotlinOrigin, declaration = kotlinOrigin,
descriptor = descriptor, descriptor = lazyDescriptor,
containingDeclaration = this@KtUltraLightClass, containingDeclaration = this@KtUltraLightClass,
fieldsList = result fieldsList = result
) )
@@ -275,7 +255,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
private fun isNamedObject() = classOrObject is KtObjectDeclaration && !classOrObject.isCompanion() private fun isNamedObject() = classOrObject is KtObjectDeclaration && !classOrObject.isCompanion()
override fun getOwnFields(): List<KtLightField> = if (tooComplex) super.getOwnFields() else _ownFields override fun getOwnFields(): List<KtLightField> = _ownFields
private fun propertyParameters() = classOrObject.primaryConstructorParameters.filter { it.hasValOrVar() } private fun propertyParameters() = classOrObject.primaryConstructorParameters.filter { it.hasValOrVar() }
@@ -328,10 +308,11 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
addMethodsFromDataClass(result) addMethodsFromDataClass(result)
addDelegatesToInterfaceMethods(result) addDelegatesToInterfaceMethods(result)
val lazyDescriptor = lazy { getDescriptor() }
applyCompilerPlugins { applyCompilerPlugins {
it.interceptMethodsBuilding( it.interceptMethodsBuilding(
declaration = kotlinOrigin, declaration = kotlinOrigin,
descriptor = descriptor, descriptor = lazyDescriptor,
containingDeclaration = this, containingDeclaration = this,
methodsList = result methodsList = result
) )
@@ -467,7 +448,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
private fun isJvmStatic(declaration: KtAnnotated): Boolean = declaration.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) private fun isJvmStatic(declaration: KtAnnotated): Boolean = declaration.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME)
override fun getOwnMethods(): List<KtLightMethod> = if (tooComplex) super.getOwnMethods() else _ownMethods.value override fun getOwnMethods(): List<KtLightMethod> = _ownMethods.value
private fun KtAnnotated.hasAnnotation(name: FqName) = support.findAnnotation(this, name) != null private fun KtAnnotated.hasAnnotation(name: FqName) = support.findAnnotation(this, name) != null
@@ -478,13 +459,15 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
override fun getInitializers(): Array<PsiClassInitializer> = emptyArray() override fun getInitializers(): Array<PsiClassInitializer> = emptyArray()
override fun getContainingClass(): PsiClass? = override fun getContainingClass(): PsiClass? {
if (tooComplex) super.getContainingClass() val containingBody = classOrObject.parent as? KtClassBody
else ((classOrObject.parent as? KtClassBody)?.parent as? KtClassOrObject)?.let(KtLightClassForSourceDeclaration::create) val containingClass = containingBody?.parent as? KtClassOrObject
return containingClass?.let { create(it) }
}
override fun getParent(): PsiElement? = if (tooComplex) super.getParent() else containingClass ?: containingFile override fun getParent(): PsiElement? = containingClass ?: containingFile
override fun getScope(): PsiElement? = if (tooComplex) super.getScope() else parent override fun getScope(): PsiElement? = parent
override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean = override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean =
baseClass?.let { InheritanceImplUtil.isInheritorDeep(this, it, classToByPass) } ?: false baseClass?.let { InheritanceImplUtil.isInheritorDeep(this, it, classToByPass) } ?: false
@@ -144,8 +144,7 @@ internal open class KtUltraLightFieldImpl protected constructor(
override val kotlinOrigin = declaration override val kotlinOrigin = declaration
override val clsDelegate: PsiField override val clsDelegate: PsiField get() = invalidAccess()
get() = throw IllegalStateException("Cls delegate shouldn't be loaded for ultra-light PSI!")
override val lightMemberOrigin = LightMemberOriginForDeclaration(declaration, JvmDeclarationOriginKind.OTHER) override val lightMemberOrigin = LightMemberOriginForDeclaration(declaration, JvmDeclarationOriginKind.OTHER)
@@ -30,8 +30,7 @@ internal class KtUltraLightSuspendContinuationParameter(
override val kotlinTypeForNullabilityAnnotation: KotlinType? get() = ktType override val kotlinTypeForNullabilityAnnotation: KotlinType? get() = ktType
override val psiTypeForNullabilityAnnotation: PsiType? get() = psiType override val psiTypeForNullabilityAnnotation: PsiType? get() = psiType
override val kotlinOrigin: KtParameter? = null override val kotlinOrigin: KtParameter? = null
override val clsDelegate: PsiParameter override val clsDelegate: PsiParameter get() = invalidAccess()
get() = throw IllegalStateException("Cls delegate shouldn't be loaded for ultra-light PSI!")
private val ktType by lazyPub { private val ktType by lazyPub {
val descriptor = ktFunction.resolve() as? FunctionDescriptor val descriptor = ktFunction.resolve() as? FunctionDescriptor
@@ -79,8 +78,7 @@ internal abstract class KtUltraLightParameter(
override fun isEquivalentTo(another: PsiElement?): Boolean = kotlinOrigin == another override fun isEquivalentTo(another: PsiElement?): Boolean = kotlinOrigin == another
override val clsDelegate: PsiParameter override val clsDelegate: PsiParameter get() = invalidAccess()
get() = throw IllegalStateException("Cls delegate shouldn't be loaded for ultra-light PSI!")
private val lightModifierList by lazyPub { KtLightSimpleModifierList(this, emptySet()) } private val lightModifierList by lazyPub { KtLightSimpleModifierList(this, emptySet()) }
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
interface KtUltraLightSupport { interface KtUltraLightSupport {
val moduleName: String val moduleName: String
fun findAnnotation(owner: KtAnnotated, fqName: FqName): Pair<KtAnnotationEntry, AnnotationDescriptor>? fun findAnnotation(owner: KtAnnotated, fqName: FqName): Pair<KtAnnotationEntry, AnnotationDescriptor>?
fun isTooComplexForUltraLightGeneration(element: KtDeclaration): Boolean
val deprecationResolver: DeprecationResolver val deprecationResolver: DeprecationResolver
val typeMapper: KotlinTypeMapper val typeMapper: KotlinTypeMapper
val moduleDescriptor: ModuleDescriptor val moduleDescriptor: ModuleDescriptor
@@ -389,3 +389,6 @@ fun KotlinType.tryResolveMarkerInterfaceFQName(): String? {
return null return null
} }
internal fun <L : Any> L.invalidAccess(): Nothing =
error("Cls delegate shouldn't be loaded for not too complex ultra-light classes! Qualified name: ${javaClass.name}")
@@ -102,8 +102,7 @@ abstract class KtUltraLightModifierList<out T : KtLightElement<KtModifierListOwn
private val support: KtUltraLightSupport private val support: KtUltraLightSupport
) : KtLightModifierList<T>(owner) { ) : KtLightModifierList<T>(owner) {
override val clsDelegate: PsiModifierList override val clsDelegate: PsiModifierList get() = invalidAccess()
get() = throw IllegalStateException("Cls delegate shouldn't be loaded for ultra-light PSI!")
private fun throwInvalidOperation(): Nothing = throw IncorrectOperationException() private fun throwInvalidOperation(): Nothing = throw IncorrectOperationException()
@@ -16,8 +16,6 @@
package org.jetbrains.kotlin.idea.caches.resolve package org.jetbrains.kotlin.idea.caches.resolve
import com.intellij.openapi.diagnostic.debug
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtilCore import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiManager import com.intellij.psi.PsiManager
@@ -29,7 +27,6 @@ import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.containers.ConcurrentFactoryMap import com.intellij.util.containers.ConcurrentFactoryMap
import org.jetbrains.kotlin.asJava.LightClassBuilder import org.jetbrains.kotlin.asJava.LightClassBuilder
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.UltraLightClassModifierExtension
import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
import org.jetbrains.kotlin.asJava.classes.* import org.jetbrains.kotlin.asJava.classes.*
@@ -43,7 +40,6 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.idea.caches.lightClasses.IDELightClassContexts import org.jetbrains.kotlin.idea.caches.lightClasses.IDELightClassContexts
import org.jetbrains.kotlin.idea.caches.lightClasses.LazyLightClassDataHolder import org.jetbrains.kotlin.idea.caches.lightClasses.LazyLightClassDataHolder
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.resolve.frontendService import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasShortNameIndex import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasShortNameIndex
@@ -68,10 +64,6 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
override val isReleasedCoroutine override val isReleasedCoroutine
get() = module?.languageVersionSettings?.supportsFeature(LanguageFeature.ReleaseCoroutines) ?: true get() = module?.languageVersionSettings?.supportsFeature(LanguageFeature.ReleaseCoroutines) ?: true
override fun isTooComplexForUltraLightGeneration(element: KtDeclaration): Boolean {
return false
}
override val moduleDescriptor by lazyPub { override val moduleDescriptor by lazyPub {
element.getResolutionFacade().moduleDescriptor element.getResolutionFacade().moduleDescriptor
} }
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.idea.perf.UltraLightChecker import org.jetbrains.kotlin.idea.perf.UltraLightChecker
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File import java.io.File
@@ -31,9 +30,7 @@ abstract class AbstractUltraLightClassLoadingTest : KotlinLightCodeInsightFixtur
LightClassGenerationSupport.getInstance(ktClass.project).createUltraLightClass(ktClass)?.let { it to ktClass } LightClassGenerationSupport.getInstance(ktClass.project).createUltraLightClass(ktClass)?.let { it to ktClass }
}.joinToString("\n\n") { (ultraLightClass, ktClass) -> }.joinToString("\n\n") { (ultraLightClass, ktClass) ->
with(UltraLightChecker) { with(UltraLightChecker) {
ultraLightClass.renderClass().also { ultraLightClass.renderClass()
checkClassLoadingExpectations(ktClass, ultraLightClass)
}
} }
} }
@@ -42,23 +39,8 @@ abstract class AbstractUltraLightClassLoadingTest : KotlinLightCodeInsightFixtur
} }
for (ktClass in UltraLightChecker.allClasses(file)) { for (ktClass in UltraLightChecker.allClasses(file)) {
val ultraLightClass = UltraLightChecker.checkClassEquivalence(ktClass) UltraLightChecker.checkClassEquivalence(ktClass)
if (ultraLightClass != null) {
checkClassLoadingExpectations(ktClass, ultraLightClass)
}
} }
} }
private fun checkClassLoadingExpectations(
ktClass: KtClassOrObject,
ultraLightClass: KtUltraLightClass
) {
val clsLoadingExpected = ktClass.docComment?.text?.contains("should load cls") == true
assertEquals(
"Cls-loaded status differs from expected for ${ultraLightClass.qualifiedName}",
clsLoadingExpected,
ultraLightClass.isClsDelegateLoaded
)
}
} }
@@ -11,10 +11,8 @@ import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
import org.jetbrains.kotlin.idea.perf.UltraLightChecker import org.jetbrains.kotlin.idea.perf.UltraLightChecker
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
import java.io.File import java.io.File
abstract class AbstractUltraLightFacadeClassTest : KotlinLightCodeInsightFixtureTestCase() { abstract class AbstractUltraLightFacadeClassTest : KotlinLightCodeInsightFixtureTestCase() {
@@ -22,7 +20,7 @@ abstract class AbstractUltraLightFacadeClassTest : KotlinLightCodeInsightFixture
fun doTest(testDataPath: String) { fun doTest(testDataPath: String) {
val sourceText = File(testDataPath).readText() val sourceText = File(testDataPath).readText()
val file = myFixture.addFileToProject(testDataPath, sourceText) as KtFile myFixture.addFileToProject(testDataPath, sourceText) as KtFile
UltraLightChecker.checkForReleaseCoroutine(sourceText, module) UltraLightChecker.checkForReleaseCoroutine(sourceText, module)
@@ -35,24 +33,7 @@ abstract class AbstractUltraLightFacadeClassTest : KotlinLightCodeInsightFixture
val facades = KotlinAsJavaSupport.getInstance(project).getFacadeNames(FqName.ROOT, scope) val facades = KotlinAsJavaSupport.getInstance(project).getFacadeNames(FqName.ROOT, scope)
for (facadeName in facades) { for (facadeName in facades) {
val ultraLightClass = UltraLightChecker.checkFacadeEquivalence(FqName(facadeName), scope, project) UltraLightChecker.checkFacadeEquivalence(FqName(facadeName), scope, project)
if (ultraLightClass != null) {
checkClassLoadingExpectations(file, ultraLightClass)
} }
} }
}
private fun checkClassLoadingExpectations(
primaryFile: KtFile,
ultraLightClass: KtLightClassForFacade
) {
val clsLoadingExpected = primaryFile.findDescendantOfType<KDoc> { it.text?.contains("should load cls") == true } !== null
assertEquals(
"Cls-loaded status differs from expected for ${ultraLightClass.qualifiedName}",
clsLoadingExpected,
ultraLightClass.isClsDelegateLoaded
)
}
} }