FIR Java: improve symbol provider laziness

This commit is contained in:
Simon Ogorodnik
2019-04-10 21:22:22 +03:00
committed by Mikhail Glukhikh
parent 98f4fa1f6c
commit c3632487d0
3 changed files with 31 additions and 23 deletions
@@ -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 -> {