[FIR] make FirJavaClass.superTypes to be lazily enhanced
This should solve the problem with deadlocks/performance in the K2 IDE This is a temporary solution until the ^KT-55387 is properly fixed ^KT-55387 ^KT-54890
This commit is contained in:
Generated
+7
@@ -0,0 +1,7 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="darthorimar">
|
||||
<words>
|
||||
<w>unenhnanced</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.typeParameterSymbols
|
||||
import org.jetbrains.kotlin.fir.caches.createCache
|
||||
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
||||
import org.jetbrains.kotlin.fir.caches.getValue
|
||||
@@ -24,21 +23,15 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildTypeParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.classId
|
||||
import org.jetbrains.kotlin.fir.java.declarations.*
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.FirSignatureEnhancement
|
||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.load.java.FakePureImplementationsProvider
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
@@ -181,59 +174,14 @@ abstract class FirJavaFacade(
|
||||
|
||||
// 1. Resolve annotations
|
||||
// 2. Enhance type parameter bounds - may refer to each other, take default nullability from annotations
|
||||
// 3. Enhance super types - may refer to type parameter bounds, take default nullability from annotations
|
||||
// 3. (will happen lazily in FirJavaClass.superTypeRefs) Enhance super types - may refer to type parameter bounds, take default nullability from annotations
|
||||
|
||||
firJavaClass.setAnnotationsFromJava(session, javaClass, javaTypeParameterStack)
|
||||
|
||||
enhancement.enhanceTypeParameterBoundsAfterFirstRound(firJavaClass.typeParameters, initialBounds)
|
||||
|
||||
val enhancedSuperTypes = buildList {
|
||||
val purelyImplementedSupertype = firJavaClass.getPurelyImplementedSupertype()
|
||||
val purelyImplementedSupertypeClassId = purelyImplementedSupertype?.classId
|
||||
firJavaClass.superTypeRefs.mapNotNullTo(this) { superType ->
|
||||
enhancement.enhanceSuperType(superType).takeUnless {
|
||||
purelyImplementedSupertypeClassId != null && it.coneType.classId == purelyImplementedSupertypeClassId
|
||||
}
|
||||
}
|
||||
purelyImplementedSupertype?.let {
|
||||
add(buildResolvedTypeRef { type = it })
|
||||
}
|
||||
}
|
||||
firJavaClass.replaceSuperTypeRefs(enhancedSuperTypes)
|
||||
firJavaClass.replaceDeprecationsProvider(firJavaClass.getDeprecationsProvider(session))
|
||||
return firJavaClass
|
||||
}
|
||||
|
||||
private fun FirJavaClass.getPurelyImplementedSupertype(): ConeKotlinType? {
|
||||
val purelyImplementedClassIdFromAnnotation = annotations
|
||||
.firstOrNull { it.classId?.asSingleFqName() == JvmAnnotationNames.PURELY_IMPLEMENTS_ANNOTATION }
|
||||
?.let { (it.argumentMapping.mapping.values.firstOrNull() as? FirConstExpression<*>) }
|
||||
?.let { it.value as? String }
|
||||
?.takeIf { it.isNotBlank() && isValidJavaFqName(it) }
|
||||
?.let { ClassId.topLevel(FqName(it)) }
|
||||
val purelyImplementedClassId = purelyImplementedClassIdFromAnnotation
|
||||
?: FakePureImplementationsProvider.getPurelyImplementedInterface(symbol.classId)
|
||||
?: return null
|
||||
val superTypeSymbol = session.symbolProvider.getClassLikeSymbolByClassId(purelyImplementedClassId) ?: return null
|
||||
val superTypeParameterSymbols = superTypeSymbol.typeParameterSymbols ?: return null
|
||||
val typeParameters = this.typeParameters
|
||||
val supertypeParameterCount = superTypeParameterSymbols.size
|
||||
val typeParameterCount = typeParameters.size
|
||||
val parametersAsTypeProjections = when {
|
||||
typeParameterCount == supertypeParameterCount ->
|
||||
typeParameters.map { ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(it.symbol), isNullable = false) }
|
||||
typeParameterCount == 1 && supertypeParameterCount > 1 && purelyImplementedClassIdFromAnnotation == null -> {
|
||||
val projection = ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(typeParameters.first().symbol), isNullable = false)
|
||||
(1..supertypeParameterCount).map { projection }
|
||||
}
|
||||
else -> return null
|
||||
}
|
||||
return ConeClassLikeTypeImpl(
|
||||
ConeClassLikeLookupTagImpl(purelyImplementedClassId),
|
||||
parametersAsTypeProjections.toTypedArray(),
|
||||
isNullable = false
|
||||
)
|
||||
}
|
||||
|
||||
private fun createFirJavaClass(
|
||||
javaClass: JavaClass,
|
||||
classSymbol: FirRegularClassSymbol,
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.FirRegularClassBuilder
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.FirSignatureEnhancement
|
||||
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
@@ -44,7 +45,7 @@ class FirJavaClass @FirImplementationDetail internal constructor(
|
||||
override val declarations: MutableList<FirDeclaration>,
|
||||
override val scopeProvider: FirScopeProvider,
|
||||
override val symbol: FirRegularClassSymbol,
|
||||
override val superTypeRefs: MutableList<FirTypeRef>,
|
||||
private val unenhnancedSuperTypes: List<FirTypeRef>,
|
||||
override val typeParameters: MutableList<FirTypeParameterRef>,
|
||||
internal val javaPackage: JavaPackage?,
|
||||
val javaTypeParameterStack: JavaTypeParameterStack,
|
||||
@@ -63,9 +64,14 @@ class FirJavaClass @FirImplementationDetail internal constructor(
|
||||
|
||||
override val attributes: FirDeclarationAttributes = FirDeclarationAttributes()
|
||||
|
||||
// TODO: the lazy superTypeRefs is a workaround for KT-55387, some non-lazy solution should probably be used instead
|
||||
override val superTypeRefs: List<FirTypeRef> by lazy {
|
||||
val enhancement = FirSignatureEnhancement(this@FirJavaClass, moduleData.session, overridden = { emptyList() })
|
||||
enhancement.enhanceSuperTypes(unenhnancedSuperTypes)
|
||||
}
|
||||
|
||||
override fun replaceSuperTypeRefs(newSuperTypeRefs: List<FirTypeRef>) {
|
||||
superTypeRefs.clear()
|
||||
superTypeRefs.addAll(newSuperTypeRefs)
|
||||
error("${::replaceSuperTypeRefs.name} should not be called for ${this::class.simpleName}, ${superTypeRefs::class.simpleName} is lazily calulated")
|
||||
}
|
||||
|
||||
override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) {
|
||||
@@ -101,7 +107,6 @@ class FirJavaClass @FirImplementationDetail internal constructor(
|
||||
}
|
||||
|
||||
override fun <D> transformSuperTypeRefs(transformer: FirTransformer<D>, data: D): FirRegularClass {
|
||||
superTypeRefs.transformInplace(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -152,6 +157,7 @@ class FirJavaClassBuilder : FirRegularClassBuilder(), FirAnnotationContainerBuil
|
||||
|
||||
@OptIn(FirImplementationDetail::class)
|
||||
override fun build(): FirJavaClass {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return FirJavaClass(
|
||||
source,
|
||||
moduleData,
|
||||
|
||||
+58
-4
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fakeElement
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.typeParameterSymbols
|
||||
import org.jetbrains.kotlin.fir.caches.FirCache
|
||||
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
|
||||
import org.jetbrains.kotlin.fir.caches.createCache
|
||||
@@ -25,26 +26,31 @@ import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.classId
|
||||
import org.jetbrains.kotlin.fir.java.FirJavaTypeConversionMode
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.declarations.*
|
||||
import org.jetbrains.kotlin.fir.java.resolveIfJavaType
|
||||
import org.jetbrains.kotlin.fir.java.symbols.FirJavaOverriddenSyntheticPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeProbablyFlexible
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptor
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.load.java.AnnotationQualifierApplicabilityType
|
||||
import org.jetbrains.kotlin.load.java.FakePureImplementationsProvider
|
||||
import org.jetbrains.kotlin.load.java.JavaTypeQualifiersByElementType
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.*
|
||||
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.*
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||
@@ -442,7 +448,55 @@ class FirSignatureEnhancement(
|
||||
AnnotationQualifierApplicabilityType.TYPE_PARAMETER_BOUNDS, contextQualifiers
|
||||
).enhance(bound, emptyList(), FirJavaTypeConversionMode.TYPE_PARAMETER_BOUND_AFTER_FIRST_ROUND)
|
||||
|
||||
fun enhanceSuperType(type: FirTypeRef): FirTypeRef =
|
||||
|
||||
fun enhanceSuperTypes(unenhnancedSuperTypes: List<FirTypeRef>): List<FirTypeRef> {
|
||||
val purelyImplementedSupertype = getPurelyImplementedSupertype(moduleData.session)
|
||||
val purelyImplementedSupertypeClassId = purelyImplementedSupertype?.classId
|
||||
return buildList {
|
||||
unenhnancedSuperTypes.mapNotNullTo(this) { superType ->
|
||||
enhanceSuperType(superType).takeUnless {
|
||||
purelyImplementedSupertypeClassId != null && it.coneType.classId == purelyImplementedSupertypeClassId
|
||||
}
|
||||
}
|
||||
purelyImplementedSupertype?.let {
|
||||
add(buildResolvedTypeRef { type = it })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPurelyImplementedSupertype(session: FirSession): ConeKotlinType? {
|
||||
val purelyImplementedClassIdFromAnnotation = owner.annotations
|
||||
.firstOrNull { it.classId?.asSingleFqName() == JvmAnnotationNames.PURELY_IMPLEMENTS_ANNOTATION }
|
||||
?.let { (it.argumentMapping.mapping.values.firstOrNull() as? FirConstExpression<*>) }
|
||||
?.let { it.value as? String }
|
||||
?.takeIf { it.isNotBlank() && isValidJavaFqName(it) }
|
||||
?.let { ClassId.topLevel(FqName(it)) }
|
||||
val purelyImplementedClassId = purelyImplementedClassIdFromAnnotation
|
||||
?: FakePureImplementationsProvider.getPurelyImplementedInterface(owner.symbol.classId)
|
||||
?: return null
|
||||
val superTypeSymbol = session.symbolProvider.getClassLikeSymbolByClassId(purelyImplementedClassId) ?: return null
|
||||
val superTypeParameterSymbols = superTypeSymbol.typeParameterSymbols ?: return null
|
||||
val typeParameters = owner.typeParameters
|
||||
val supertypeParameterCount = superTypeParameterSymbols.size
|
||||
val typeParameterCount = typeParameters.size
|
||||
val parametersAsTypeProjections = when {
|
||||
typeParameterCount == supertypeParameterCount ->
|
||||
typeParameters.map { ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(it.symbol), isNullable = false) }
|
||||
typeParameterCount == 1 && supertypeParameterCount > 1 && purelyImplementedClassIdFromAnnotation == null -> {
|
||||
val projection = ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(typeParameters.first().symbol), isNullable = false)
|
||||
(1..supertypeParameterCount).map { projection }
|
||||
}
|
||||
else -> return null
|
||||
}
|
||||
return ConeClassLikeTypeImpl(
|
||||
ConeClassLikeLookupTagImpl(purelyImplementedClassId),
|
||||
parametersAsTypeProjections.toTypedArray(),
|
||||
isNullable = false
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun enhanceSuperType(type: FirTypeRef): FirTypeRef =
|
||||
EnhancementSignatureParts(
|
||||
session, typeQualifierResolver, null, isCovariant = false, forceOnlyHeadTypeConstructor = false,
|
||||
AnnotationQualifierApplicabilityType.TYPE_USE, contextQualifiers
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIR_DISABLE_LAZY_RESOLVE_CHECKS
|
||||
// FIR_IDENTICAL
|
||||
// FILE: MapObjectManager.java
|
||||
abstract class MapObjectManager<C extends MapObjectManager.Collection> {
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// FIR_DISABLE_LAZY_RESOLVE_CHECKS
|
||||
// FIR_IDENTICAL
|
||||
// SKIP_TXT
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
Reference in New Issue
Block a user