FIR IDE: extract KtType building from KtSymbolByFirBuilder

This commit is contained in:
Ilya Kirillov
2021-03-15 17:45:21 +01:00
parent b6d334b303
commit 502087a3c7
8 changed files with 61 additions and 58 deletions
@@ -152,11 +152,11 @@ private object FirToKtConversionCreator {
Visibility::class.createType() Visibility::class.createType()
), ),
ConeKotlinType::class to HLFunctionCallConversion( ConeKotlinType::class to HLFunctionCallConversion(
"firSymbolBuilder.buildKtType({0})", "firSymbolBuilder.typeBuilder.buildKtType({0})",
KtType::class.createType() KtType::class.createType()
), ),
FirTypeRef::class to HLFunctionCallConversion( FirTypeRef::class to HLFunctionCallConversion(
"firSymbolBuilder.buildKtType({0})", "firSymbolBuilder.typeBuilder.buildKtType({0})",
KtType::class.createType() KtType::class.createType()
), ),
FirPropertySymbol::class to HLFunctionCallConversion( FirPropertySymbol::class to HLFunctionCallConversion(
@@ -56,6 +56,7 @@ internal class KtSymbolByFirBuilder private constructor(
val functionLikeBuilder = FunctionLikeSymbolBuilder() val functionLikeBuilder = FunctionLikeSymbolBuilder()
val variableLikeBuilder = VariableLikeSymbolBuilder() val variableLikeBuilder = VariableLikeSymbolBuilder()
val callableBuilder = CallableSymbolBuilder() val callableBuilder = CallableSymbolBuilder()
val typeBuilder = TypeBuilder()
constructor( constructor(
resolveState: FirModuleResolveState, resolveState: FirModuleResolveState,
@@ -110,43 +111,6 @@ internal class KtSymbolByFirBuilder private constructor(
return KtFirPackageSymbol(packageFqName, project, token) return KtFirPackageSymbol(packageFqName, project, token)
} }
fun buildTypeArgument(coneType: ConeTypeProjection): KtTypeArgument = when (coneType) {
is ConeStarProjection -> KtStarProjectionTypeArgument
is ConeKotlinTypeProjection -> KtFirTypeArgumentWithVariance(
buildKtType(coneType.type),
coneType.kind.toVariance()
)
}
private fun ProjectionKind.toVariance() = when (this) {
ProjectionKind.OUT -> Variance.OUT_VARIANCE
ProjectionKind.IN -> Variance.IN_VARIANCE
ProjectionKind.INVARIANT -> Variance.INVARIANT
ProjectionKind.STAR -> error("KtStarProjectionTypeArgument be directly created")
}
fun buildKtType(coneType: FirTypeRef): KtType =
buildKtType(
coneType.coneTypeSafe<ConeKotlinType>()
?: error("")
)
fun buildKtType(coneType: ConeKotlinType): KtType = typesCache.cache(coneType) {
when (coneType) {
is ConeClassLikeTypeImpl -> {
if (coneType.isFunctionalType(rootSession)) KtFirFunctionalType(coneType, token, this)
else KtFirUsualClassType(coneType, token, this)
}
is ConeTypeParameterType -> KtFirTypeParameterType(coneType, token, this)
is ConeClassErrorType -> KtFirErrorType(coneType, token)
is ConeFlexibleType -> KtFirFlexibleType(coneType, token, this)
is ConeIntersectionType -> KtFirIntersectionType(coneType, token, this)
is ConeDefinitelyNotNullType -> buildKtType(coneType.original)
else -> TODO(coneType::class.toString())
}
}
inner class ClassifierSymbolBuilder { inner class ClassifierSymbolBuilder {
fun buildClassifierSymbol(firSymbol: FirClassifierSymbol<*>): KtClassifierSymbol { fun buildClassifierSymbol(firSymbol: FirClassifierSymbol<*>): KtClassifierSymbol {
return when (val fir = firSymbol.fir) { return when (val fir = firSymbol.fir) {
@@ -306,6 +270,45 @@ internal class KtSymbolByFirBuilder private constructor(
return symbolsCache.cache(fir) { KtFirPropertySetterSymbol(fir, resolveState, token, this@KtSymbolByFirBuilder) } return symbolsCache.cache(fir) { KtFirPropertySetterSymbol(fir, resolveState, token, this@KtSymbolByFirBuilder) }
} }
} }
inner class TypeBuilder {
fun buildKtType(coneType: ConeKotlinType): KtType {
return typesCache.cache(coneType) {
when (coneType) {
is ConeClassLikeTypeImpl -> {
if (coneType.isFunctionalType(rootSession)) KtFirFunctionalType(coneType, token, this@KtSymbolByFirBuilder)
else KtFirUsualClassType(coneType, token, this@KtSymbolByFirBuilder)
}
is ConeTypeParameterType -> KtFirTypeParameterType(coneType, token, this@KtSymbolByFirBuilder)
is ConeClassErrorType -> KtFirErrorType(coneType, token)
is ConeFlexibleType -> KtFirFlexibleType(coneType, token, this@KtSymbolByFirBuilder)
is ConeIntersectionType -> KtFirIntersectionType(coneType, token, this@KtSymbolByFirBuilder)
is ConeDefinitelyNotNullType -> buildKtType(coneType.original)
else -> error("Unexpected ${coneType::class.simpleName}")
}
}
}
fun buildKtType(coneType: FirTypeRef): KtType {
return buildKtType(coneType.coneType)
}
fun buildTypeArgument(coneType: ConeTypeProjection): KtTypeArgument = when (coneType) {
is ConeStarProjection -> KtStarProjectionTypeArgument
is ConeKotlinTypeProjection -> KtFirTypeArgumentWithVariance(
buildKtType(coneType.type),
coneType.kind.toVariance()
)
}
private fun ProjectionKind.toVariance(): Variance = when (this) {
ProjectionKind.OUT -> Variance.OUT_VARIANCE
ProjectionKind.IN -> Variance.IN_VARIANCE
ProjectionKind.INVARIANT -> Variance.INVARIANT
ProjectionKind.STAR -> error("KtStarProjectionTypeArgument should not be directly created")
}
}
} }
@@ -25,7 +25,7 @@ internal interface KtFirAnalysisSessionComponent {
val firSymbolBuilder get() = analysisSession.firSymbolBuilder val firSymbolBuilder get() = analysisSession.firSymbolBuilder
val firResolveState get() = analysisSession.firResolveState val firResolveState get() = analysisSession.firResolveState
fun ConeKotlinType.asKtType() = analysisSession.firSymbolBuilder.buildKtType(this) fun ConeKotlinType.asKtType() = analysisSession.firSymbolBuilder.typeBuilder.buildKtType(this)
fun FirPsiDiagnostic<*>.asKtDiagnostic(): KtDiagnosticWithPsi<*> = fun FirPsiDiagnostic<*>.asKtDiagnostic(): KtDiagnosticWithPsi<*> =
KT_DIAGNOSTIC_CONVERTER.convert(analysisSession, this as FirDiagnostic<*>) KT_DIAGNOSTIC_CONVERTER.convert(analysisSession, this as FirDiagnostic<*>)
@@ -148,7 +148,7 @@ internal class KtFirScopeProvider(
val towerDataContext = analysisSession.firResolveState.getTowerDataContextUnsafe(positionInFakeFile) val towerDataContext = analysisSession.firResolveState.getTowerDataContextUnsafe(positionInFakeFile)
val implicitReceivers = towerDataContext.nonLocalTowerDataElements.mapNotNull { it.implicitReceiver }.distinct() val implicitReceivers = towerDataContext.nonLocalTowerDataElements.mapNotNull { it.implicitReceiver }.distinct()
val implicitReceiversTypes = implicitReceivers.map { builder.buildKtType(it.type) } val implicitReceiversTypes = implicitReceivers.map { builder.typeBuilder.buildKtType(it.type) }
val implicitReceiverScopes = implicitReceivers.mapNotNull { it.implicitScope } val implicitReceiverScopes = implicitReceivers.mapNotNull { it.implicitScope }
val nonLocalScopes = towerDataContext.nonLocalTowerDataElements.mapNotNull { it.scope }.distinct() val nonLocalScopes = towerDataContext.nonLocalTowerDataElements.mapNotNull { it.scope }.distinct()
@@ -588,7 +588,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE) { firDiagnostic -> add(FirErrors.INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE) { firDiagnostic ->
InlineClassHasInapplicableParameterTypeImpl( InlineClassHasInapplicableParameterTypeImpl(
firSymbolBuilder.buildKtType(firDiagnostic.a), firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
firDiagnostic as FirPsiDiagnostic<*>, firDiagnostic as FirPsiDiagnostic<*>,
token, token,
) )
@@ -692,8 +692,8 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.TYPE_MISMATCH) { firDiagnostic -> add(FirErrors.TYPE_MISMATCH) { firDiagnostic ->
TypeMismatchImpl( TypeMismatchImpl(
firSymbolBuilder.buildKtType(firDiagnostic.a), firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
firSymbolBuilder.buildKtType(firDiagnostic.b), firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
firDiagnostic as FirPsiDiagnostic<*>, firDiagnostic as FirPsiDiagnostic<*>,
token, token,
) )
@@ -719,7 +719,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.UPPER_BOUND_VIOLATED) { firDiagnostic -> add(FirErrors.UPPER_BOUND_VIOLATED) { firDiagnostic ->
UpperBoundViolatedImpl( UpperBoundViolatedImpl(
firSymbolBuilder.classifierBuilder.buildTypeParameterSymbol(firDiagnostic.a.fir), firSymbolBuilder.classifierBuilder.buildTypeParameterSymbol(firDiagnostic.a.fir),
firSymbolBuilder.buildKtType(firDiagnostic.b), firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
firDiagnostic as FirPsiDiagnostic<*>, firDiagnostic as FirPsiDiagnostic<*>,
token, token,
) )
@@ -1021,7 +1021,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE) { firDiagnostic -> add(FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE) { firDiagnostic ->
ForbiddenVarargParameterTypeImpl( ForbiddenVarargParameterTypeImpl(
firSymbolBuilder.buildKtType(firDiagnostic.a), firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
firDiagnostic as FirPsiDiagnostic<*>, firDiagnostic as FirPsiDiagnostic<*>,
token, token,
) )
@@ -1193,7 +1193,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.COMPONENT_FUNCTION_MISSING) { firDiagnostic -> add(FirErrors.COMPONENT_FUNCTION_MISSING) { firDiagnostic ->
ComponentFunctionMissingImpl( ComponentFunctionMissingImpl(
firDiagnostic.a, firDiagnostic.a,
firSymbolBuilder.buildKtType(firDiagnostic.b), firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
firDiagnostic as FirPsiDiagnostic<*>, firDiagnostic as FirPsiDiagnostic<*>,
token, token,
) )
@@ -1267,14 +1267,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.UNSAFE_CALL) { firDiagnostic -> add(FirErrors.UNSAFE_CALL) { firDiagnostic ->
UnsafeCallImpl( UnsafeCallImpl(
firSymbolBuilder.buildKtType(firDiagnostic.a), firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
firDiagnostic as FirPsiDiagnostic<*>, firDiagnostic as FirPsiDiagnostic<*>,
token, token,
) )
} }
add(FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL) { firDiagnostic -> add(FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL) { firDiagnostic ->
UnsafeImplicitInvokeCallImpl( UnsafeImplicitInvokeCallImpl(
firSymbolBuilder.buildKtType(firDiagnostic.a), firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
firDiagnostic as FirPsiDiagnostic<*>, firDiagnostic as FirPsiDiagnostic<*>,
token, token,
) )
@@ -28,7 +28,7 @@ internal class KtFirTypeAndAnnotations<T : FirDeclaration>(
override val token: ValidityToken get() = containingDeclaration.token override val token: ValidityToken get() = containingDeclaration.token
override val type: KtType by containingDeclaration.withFirAndCache(typeResolvePhase) { fir -> override val type: KtType by containingDeclaration.withFirAndCache(typeResolvePhase) { fir ->
builder.buildKtType(typeRef(fir)) builder.typeBuilder.buildKtType(typeRef(fir))
} }
override val annotations: List<KtAnnotationCall> by containingDeclaration.withFirAndCache { fir -> override val annotations: List<KtAnnotationCall> by containingDeclaration.withFirAndCache { fir ->
@@ -49,7 +49,7 @@ internal class KtSimpleFirTypeAndAnnotations(
private val annotationsListRef by weakRef(annotationsList) private val annotationsListRef by weakRef(annotationsList)
override val type: KtType by cached { override val type: KtType by cached {
builder.buildKtType(coneTypeRef) builder.typeBuilder.buildKtType(coneTypeRef)
} }
override val annotations: List<KtAnnotationCall> get() = annotationsListRef override val annotations: List<KtAnnotationCall> get() = annotationsListRef
@@ -81,6 +81,6 @@ internal fun FirRefWithValidityCheck<FirCallableDeclaration<*>>.receiverTypeAndA
internal fun FirRefWithValidityCheck<FirCallableMemberDeclaration<*>>.dispatchReceiverTypeAndAnnotations(builder: KtSymbolByFirBuilder) = internal fun FirRefWithValidityCheck<FirCallableMemberDeclaration<*>>.dispatchReceiverTypeAndAnnotations(builder: KtSymbolByFirBuilder) =
withFir { fir -> withFir { fir ->
fir.dispatchReceiverType?.let { fir.dispatchReceiverType?.let {
builder.buildKtType(it) builder.typeBuilder.buildKtType(it)
} }
} }
@@ -34,7 +34,7 @@ internal class KtFirTypeParameterSymbol(
override val name: Name get() = firRef.withFir { it.name } override val name: Name get() = firRef.withFir { it.name }
override val upperBounds: List<KtType> by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir -> override val upperBounds: List<KtType> by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir ->
fir.bounds.map { type -> builder.buildKtType(type) } fir.bounds.map { type -> builder.typeBuilder.buildKtType(type) }
} }
override val variance: Variance get() = firRef.withFir { it.variance } override val variance: Variance get() = firRef.withFir { it.variance }
@@ -39,7 +39,7 @@ internal class KtFirUsualClassType(
} }
override val typeArguments: List<KtTypeArgument> by cached { override val typeArguments: List<KtTypeArgument> by cached {
coneType.typeArguments.map { typeArgument -> coneType.typeArguments.map { typeArgument ->
firBuilder.buildTypeArgument(typeArgument) firBuilder.typeBuilder.buildTypeArgument(typeArgument)
} }
} }
@@ -64,7 +64,7 @@ internal class KtFirFunctionalType(
} }
override val typeArguments: List<KtTypeArgument> by cached { override val typeArguments: List<KtTypeArgument> by cached {
coneType.typeArguments.map { typeArgument -> coneType.typeArguments.map { typeArgument ->
firBuilder.buildTypeArgument(typeArgument) firBuilder.typeBuilder.buildTypeArgument(typeArgument)
} }
} }
@@ -133,8 +133,8 @@ internal class KtFirFlexibleType(
) : KtFlexibleType(), KtFirType { ) : KtFlexibleType(), KtFirType {
override val coneType by weakRef(coneType) override val coneType by weakRef(coneType)
override val lowerBound: KtType by cached { firBuilder.buildKtType(coneType.lowerBound) } override val lowerBound: KtType by cached { firBuilder.typeBuilder.buildKtType(coneType.lowerBound) }
override val upperBound: KtType by cached { firBuilder.buildKtType(coneType.upperBound) } override val upperBound: KtType by cached { firBuilder.typeBuilder.buildKtType(coneType.upperBound) }
} }
internal class KtFirIntersectionType( internal class KtFirIntersectionType(
@@ -145,7 +145,7 @@ internal class KtFirIntersectionType(
override val coneType by weakRef(coneType) override val coneType by weakRef(coneType)
override val conjuncts: List<KtType> by cached { override val conjuncts: List<KtType> by cached {
coneType.intersectedTypes.map { conjunct -> firBuilder.buildKtType(conjunct) } coneType.intersectedTypes.map { conjunct -> firBuilder.typeBuilder.buildKtType(conjunct) }
} }
} }