FIR Java: improve symbol provider laziness
This commit is contained in:
committed by
Mikhail Glukhikh
parent
98f4fa1f6c
commit
c3632487d0
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.java.types.FirJavaTypeRef
|
|||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
import org.jetbrains.kotlin.fir.resolve.constructClassType
|
||||||
import org.jetbrains.kotlin.fir.resolve.getClassDeclaredCallableSymbols
|
import org.jetbrains.kotlin.fir.resolve.getClassDeclaredCallableSymbols
|
||||||
import org.jetbrains.kotlin.fir.service
|
import org.jetbrains.kotlin.fir.service
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTagImpl
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTagImpl
|
||||||
@@ -133,12 +133,15 @@ internal fun JavaClassifierType.toConeKotlinTypeWithNullability(session: FirSess
|
|||||||
return when (val classifier = classifier) {
|
return when (val classifier = classifier) {
|
||||||
is JavaClass -> {
|
is JavaClass -> {
|
||||||
val classId = classifier.classId!!
|
val classId = classifier.classId!!
|
||||||
val symbol = session.service<FirSymbolProvider>().getClassLikeSymbolByFqName(classId) as? FirClassSymbol
|
val lookupTag = ConeClassLikeLookupTagImpl(classId)
|
||||||
symbol?.constructType(
|
lookupTag.constructClassType(
|
||||||
typeArguments.mapIndexed { index, argument ->
|
typeArguments.mapIndexed { index, argument ->
|
||||||
argument.toConeProjection(session, symbol.fir.typeParameters.getOrNull(index))
|
argument.toConeProjection(
|
||||||
|
session, null
|
||||||
|
//symbol.fir.typeParameters.getOrNull(index)
|
||||||
|
)
|
||||||
}.toTypedArray(), isNullable
|
}.toTypedArray(), isNullable
|
||||||
) ?: ConeClassErrorType("Symbol not found, for `$classId`")
|
)
|
||||||
}
|
}
|
||||||
is JavaTypeParameter -> {
|
is JavaTypeParameter -> {
|
||||||
// TODO: it's unclear how to identify type parameter by the symbol
|
// TODO: it's unclear how to identify type parameter by the symbol
|
||||||
|
|||||||
@@ -21,16 +21,10 @@ import org.jetbrains.kotlin.fir.java.toNotNullConeKotlinType
|
|||||||
import org.jetbrains.kotlin.fir.java.types.FirJavaTypeRef
|
import org.jetbrains.kotlin.fir.java.types.FirJavaTypeRef
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||||
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
|
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
import org.jetbrains.kotlin.fir.resolve.constructType
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.toTypeProjection
|
import org.jetbrains.kotlin.fir.resolve.toTypeProjection
|
||||||
import org.jetbrains.kotlin.fir.service
|
import org.jetbrains.kotlin.fir.symbols.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassifierSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||||
@@ -137,7 +131,7 @@ private fun JavaClassifierType.enhanceInflexibleType(
|
|||||||
qualifiers: IndexedJavaTypeQualifiers,
|
qualifiers: IndexedJavaTypeQualifiers,
|
||||||
index: Int
|
index: Int
|
||||||
): ConeLookupTagBasedType {
|
): ConeLookupTagBasedType {
|
||||||
val originalSymbol = when (val classifier = classifier) {
|
val originalTag = when (val classifier = classifier) {
|
||||||
is JavaClass -> {
|
is JavaClass -> {
|
||||||
val classId = classifier.classId!!
|
val classId = classifier.classId!!
|
||||||
var mappedId = JavaToKotlinClassMap.mapJavaToKotlin(classId.asSingleFqName())
|
var mappedId = JavaToKotlinClassMap.mapJavaToKotlin(classId.asSingleFqName())
|
||||||
@@ -147,15 +141,14 @@ private fun JavaClassifierType.enhanceInflexibleType(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val kotlinClassId = mappedId ?: classId
|
val kotlinClassId = mappedId ?: classId
|
||||||
session.service<FirSymbolProvider>().getClassLikeSymbolByFqName(kotlinClassId)
|
ConeClassLikeLookupTagImpl(kotlinClassId)
|
||||||
?: return ConeClassErrorType("Cannot find class-like symbol for $kotlinClassId during enhancement")
|
|
||||||
}
|
}
|
||||||
is JavaTypeParameter -> createTypeParameterSymbol(session, classifier.name)
|
is JavaTypeParameter -> createTypeParameterSymbol(session, classifier.name)
|
||||||
else -> return toNotNullConeKotlinType(session)
|
else -> return toNotNullConeKotlinType(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
val effectiveQualifiers = qualifiers(index)
|
val effectiveQualifiers = qualifiers(index)
|
||||||
val enhancedSymbol = originalSymbol.enhanceMutability(effectiveQualifiers, position)
|
val enhancedTag = originalTag.enhanceMutability(effectiveQualifiers, position)
|
||||||
|
|
||||||
var globalArgIndex = index + 1
|
var globalArgIndex = index + 1
|
||||||
val enhancedArguments = arguments.mapIndexed { localArgIndex, arg ->
|
val enhancedArguments = arguments.mapIndexed { localArgIndex, arg ->
|
||||||
@@ -163,7 +156,7 @@ private fun JavaClassifierType.enhanceInflexibleType(
|
|||||||
globalArgIndex++
|
globalArgIndex++
|
||||||
arg.toConeProjection(
|
arg.toConeProjection(
|
||||||
session,
|
session,
|
||||||
((originalSymbol as? FirBasedSymbol<*>)?.fir as? FirCallableMemberDeclaration)?.typeParameters?.getOrNull(localArgIndex)
|
((originalTag as? FirBasedSymbol<*>)?.fir as? FirCallableMemberDeclaration)?.typeParameters?.getOrNull(localArgIndex)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val argEnhancedTypeRef = arg.enhancePossiblyFlexible(session, annotations, qualifiers, globalArgIndex)
|
val argEnhancedTypeRef = arg.enhancePossiblyFlexible(session, annotations, qualifiers, globalArgIndex)
|
||||||
@@ -174,7 +167,7 @@ private fun JavaClassifierType.enhanceInflexibleType(
|
|||||||
|
|
||||||
val enhancedNullability = getEnhancedNullability(effectiveQualifiers, position)
|
val enhancedNullability = getEnhancedNullability(effectiveQualifiers, position)
|
||||||
|
|
||||||
val enhancedType = enhancedSymbol.constructType(enhancedArguments.toTypedArray(), enhancedNullability)
|
val enhancedType = enhancedTag.constructType(enhancedArguments.toTypedArray(), enhancedNullability)
|
||||||
|
|
||||||
// TODO: why all of these is needed
|
// TODO: why all of these is needed
|
||||||
// val enhancement = if (effectiveQualifiers.isNotNullTypeParameter) NotNullTypeParameter(enhancedType) else enhancedType
|
// val enhancement = if (effectiveQualifiers.isNotNullTypeParameter) NotNullTypeParameter(enhancedType) else enhancedType
|
||||||
@@ -197,24 +190,24 @@ private fun getEnhancedNullability(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeClassifierSymbol.enhanceMutability(
|
private fun ConeClassifierLookupTag.enhanceMutability(
|
||||||
qualifiers: JavaTypeQualifiers,
|
qualifiers: JavaTypeQualifiers,
|
||||||
position: TypeComponentPosition
|
position: TypeComponentPosition
|
||||||
): ConeClassifierSymbol {
|
): ConeClassifierLookupTag {
|
||||||
if (!position.shouldEnhance()) return this
|
if (!position.shouldEnhance()) return this
|
||||||
if (this !is FirClassSymbol) return this // mutability is not applicable for type parameters
|
if (this !is ConeClassLikeLookupTag) return this // mutability is not applicable for type parameters
|
||||||
|
|
||||||
when (qualifiers.mutability) {
|
when (qualifiers.mutability) {
|
||||||
MutabilityQualifier.READ_ONLY -> {
|
MutabilityQualifier.READ_ONLY -> {
|
||||||
val readOnlyId = classId.mutableToReadOnly()
|
val readOnlyId = classId.mutableToReadOnly()
|
||||||
if (position == TypeComponentPosition.FLEXIBLE_LOWER && readOnlyId != null) {
|
if (position == TypeComponentPosition.FLEXIBLE_LOWER && readOnlyId != null) {
|
||||||
return FirClassSymbol(readOnlyId)
|
return ConeClassLikeLookupTagImpl(readOnlyId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MutabilityQualifier.MUTABLE -> {
|
MutabilityQualifier.MUTABLE -> {
|
||||||
val mutableId = classId.readOnlyToMutable()
|
val mutableId = classId.readOnlyToMutable()
|
||||||
if (position == TypeComponentPosition.FLEXIBLE_UPPER && mutableId != null) {
|
if (position == TypeComponentPosition.FLEXIBLE_UPPER && mutableId != null) {
|
||||||
return FirClassSymbol(mutableId)
|
return ConeClassLikeLookupTagImpl(mutableId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,18 @@ fun ConeClassifierLookupTag.toSymbol(useSiteSession: FirSession): ConeClassifier
|
|||||||
else -> error("sealed")
|
else -> error("sealed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun ConeClassLikeLookupTag.constructClassType(typeArguments: Array<ConeKotlinTypeProjection>, isNullable: Boolean): ConeLookupTagBasedType {
|
||||||
|
return ConeClassTypeImpl(this, typeArguments, isNullable)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ConeClassifierLookupTag.constructType(typeArguments: Array<ConeKotlinTypeProjection>, isNullable: Boolean): ConeLookupTagBasedType {
|
||||||
|
return when (this) {
|
||||||
|
is ConeTypeParameterLookupTag -> ConeTypeParameterTypeImpl(this, isNullable)
|
||||||
|
is ConeClassLikeLookupTag -> this.constructClassType(typeArguments, isNullable)
|
||||||
|
else -> error("! ${this::class}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun ConeClassifierSymbol.constructType(typeArguments: Array<ConeKotlinTypeProjection>, isNullable: Boolean): ConeLookupTagBasedType {
|
fun ConeClassifierSymbol.constructType(typeArguments: Array<ConeKotlinTypeProjection>, isNullable: Boolean): ConeLookupTagBasedType {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeTypeParameterSymbol -> {
|
is ConeTypeParameterSymbol -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user