[FIR] Cleanup FIR modules. Part 6 (transformers package)

This commit is contained in:
Dmitriy Novozhilov
2020-06-26 15:52:02 +03:00
parent e817f919c2
commit c6124f6d56
7 changed files with 31 additions and 35 deletions
@@ -57,12 +57,12 @@ class FirCallCompletionResultsWriterTransformer(
Normal, DelegatedPropertyCompletion Normal, DelegatedPropertyCompletion
} }
private fun <T> prepareQualifiedTransform( private fun <T : FirQualifiedAccessExpression> prepareQualifiedTransform(
qualifiedAccess: T, calleeReference: FirNamedReferenceWithCandidate qualifiedAccessExpression: T, calleeReference: FirNamedReferenceWithCandidate
): T where T : FirQualifiedAccess, T : FirExpression { ): T {
val subCandidate = calleeReference.candidate val subCandidate = calleeReference.candidate
val declaration = subCandidate.symbol.phasedFir val declaration: FirDeclaration = subCandidate.symbol.phasedFir
val typeArguments = computeTypeArguments(qualifiedAccess, subCandidate) val typeArguments = computeTypeArguments(qualifiedAccessExpression, subCandidate)
val typeRef = if (declaration is FirTypedDeclaration) { val typeRef = if (declaration is FirTypedDeclaration) {
typeCalculator.tryCalculateReturnType(declaration) typeCalculator.tryCalculateReturnType(declaration)
} else { } else {
@@ -72,12 +72,13 @@ class FirCallCompletionResultsWriterTransformer(
} }
} }
val updatedQualifiedAccess = if (qualifiedAccess is FirFunctionCall) { val updatedQualifiedAccess = if (qualifiedAccessExpression is FirFunctionCall) {
qualifiedAccess.transformSingle(integerOperatorsTypeUpdater, null) qualifiedAccessExpression.transformSingle(integerOperatorsTypeUpdater, null)
} else { } else {
qualifiedAccess qualifiedAccessExpression
} }
@Suppress("UNCHECKED_CAST")
val result = updatedQualifiedAccess val result = updatedQualifiedAccess
.transformCalleeReference( .transformCalleeReference(
StoreCalleeReference, StoreCalleeReference,
@@ -435,9 +436,8 @@ class FirCallCompletionResultsWriterTransformer(
private inline fun <reified D> transformSyntheticCall( private inline fun <reified D> transformSyntheticCall(
syntheticCall: D, syntheticCall: D,
data: ExpectedArgumentType?, data: ExpectedArgumentType?,
): CompositeTransformResult<FirStatement> ): CompositeTransformResult<FirStatement> where D : FirResolvable, D : FirExpression {
where D : FirResolvable, D : FirExpression { syntheticCall.transformChildren(this, data?.getExpectedType(syntheticCall)?.toExpectedType())
val syntheticCall = syntheticCall.transformChildren(this, data?.getExpectedType(syntheticCall)?.toExpectedType()) as D
val calleeReference = syntheticCall.calleeReference as? FirNamedReferenceWithCandidate ?: return syntheticCall.compose() val calleeReference = syntheticCall.calleeReference as? FirNamedReferenceWithCandidate ?: return syntheticCall.compose()
val declaration = calleeReference.candidate.symbol.fir as? FirSimpleFunction ?: return syntheticCall.compose() val declaration = calleeReference.candidate.symbol.fir as? FirSimpleFunction ?: return syntheticCall.compose()
@@ -472,7 +472,6 @@ class FirCallCompletionResultsWriterTransformer(
resolvedSymbol = this@toResolvedReference.candidateSymbol resolvedSymbol = this@toResolvedReference.candidateSymbol
} }
} }
} }
sealed class ExpectedArgumentType { sealed class ExpectedArgumentType {
@@ -347,7 +347,7 @@ private class SupertypeComputationSession {
private val scopesForNestedClassesMap = hashMapOf<FirClass<*>, ScopeImmutableList>() private val scopesForNestedClassesMap = hashMapOf<FirClass<*>, ScopeImmutableList>()
private val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration<*>, SupertypeComputationStatus>() private val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration<*>, SupertypeComputationStatus>()
val supertypesSupplier = object : SupertypeSupplier() { val supertypesSupplier: SupertypeSupplier = object : SupertypeSupplier() {
override fun forClass(firClass: FirClass<*>): List<ConeClassLikeType> { override fun forClass(firClass: FirClass<*>): List<ConeClassLikeType> {
if (firClass.resolvePhase > FirResolvePhase.SUPER_TYPES) return firClass.superConeTypes if (firClass.resolvePhase > FirResolvePhase.SUPER_TYPES) return firClass.superConeTypes
return (getSupertypesComputationStatus(firClass) as? SupertypeComputationStatus.Computed)?.supertypeRefs?.mapNotNull { return (getSupertypesComputationStatus(firClass) as? SupertypeComputationStatus.Computed)?.supertypeRefs?.mapNotNull {
@@ -22,12 +22,10 @@ import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.ConeNullability
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.lowerBoundIfFlexible
import org.jetbrains.kotlin.fir.visitors.* import org.jetbrains.kotlin.fir.visitors.*
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.utils.addToStdlib.runIf
class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyResolveComponents) : FirTransformer<Nothing?>() { class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyResolveComponents) : FirTransformer<Nothing?>() {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> { override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
@@ -50,9 +48,9 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe
?: return null ?: return null
// TODO: add some report logic about flexible type (see WHEN_ENUM_CAN_BE_NULL_IN_JAVA diagnostic in old frontend) // TODO: add some report logic about flexible type (see WHEN_ENUM_CAN_BE_NULL_IN_JAVA diagnostic in old frontend)
val type = (typeRef as? FirResolvedTypeRef)?.type?.lowerBoundIfFlexible() ?: return null val type = typeRef.coneTypeSafe<ConeKotlinType>()?.lowerBoundIfFlexible() ?: return null
val lookupTag = (type as? ConeLookupTagBasedType)?.lookupTag ?: return null val lookupTag = (type as? ConeLookupTagBasedType)?.lookupTag ?: return null
val nullable = typeRef.type.nullability == ConeNullability.NULLABLE val nullable = type.nullability == ConeNullability.NULLABLE
val isExhaustive = when { val isExhaustive = when {
((lookupTag as? ConeClassLikeLookupTag)?.classId == bodyResolveComponents.session.builtinTypes.booleanType.id) -> { ((lookupTag as? ConeClassLikeLookupTag)?.classId == bodyResolveComponents.session.builtinTypes.booleanType.id) -> {
checkBooleanExhaustiveness(whenExpression, nullable) checkBooleanExhaustiveness(whenExpression, nullable)
@@ -70,11 +68,9 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe
} }
} }
return if (isExhaustive) { return runIf(isExhaustive) {
whenExpression.replaceIsExhaustive(true) whenExpression.replaceIsExhaustive(true)
whenExpression whenExpression
} else {
null
} }
} }
@@ -158,8 +154,7 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe
override fun visitOperatorCall(operatorCall: FirOperatorCall, data: SealedExhaustivenessData) { override fun visitOperatorCall(operatorCall: FirOperatorCall, data: SealedExhaustivenessData) {
if (operatorCall.operation == FirOperation.EQ) { if (operatorCall.operation == FirOperation.EQ) {
val argument = operatorCall.arguments[1] when (val argument = operatorCall.arguments[1]) {
when (argument) {
is FirConstExpression<*> -> { is FirConstExpression<*> -> {
if (argument.value == null) { if (argument.value == null) {
data.containsNull = true data.containsNull = true
@@ -217,4 +212,4 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe
} }
} }
} }
} }
@@ -113,8 +113,8 @@ class IntegerLiteralTypeApproximationTransformer(
val expectedType: ConeKotlinType? = when { val expectedType: ConeKotlinType? = when {
!leftIsIlt && !rightIsIlt -> return operatorCall.compose() !leftIsIlt && !rightIsIlt -> return operatorCall.compose()
leftIsIlt && rightIsIlt -> null leftIsIlt && rightIsIlt -> null
leftIsIlt -> rightArgument.typeRef.coneTypeUnsafe<ConeKotlinType>() leftIsIlt -> rightArgument.typeRef.coneTypeUnsafe()
rightIsIlt -> leftArgument.typeRef.coneTypeUnsafe<ConeKotlinType>() rightIsIlt -> leftArgument.typeRef.coneTypeUnsafe()
else -> throw IllegalStateException() else -> throw IllegalStateException()
} }
@@ -151,7 +151,7 @@ fun FirFunctionCall.getOriginalFunction(): FirCallableDeclaration<*>? {
return symbol?.fir as? FirCallableDeclaration<*> return symbol?.fir as? FirCallableDeclaration<*>
} }
class IntegerOperatorsTypeUpdater(val approximator: IntegerLiteralTypeApproximationTransformer) : FirTransformer<Nothing?>() { class IntegerOperatorsTypeUpdater(private val approximator: IntegerLiteralTypeApproximationTransformer) : FirTransformer<Nothing?>() {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> { override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
return element.compose() return element.compose()
} }
@@ -175,9 +175,8 @@ class IntegerOperatorsTypeUpdater(val approximator: IntegerLiteralTypeApproximat
else -> throw IllegalStateException() else -> throw IllegalStateException()
} }
else -> { else -> {
val argumentType = functionCall.argument.typeRef.coneTypeUnsafe<ConeKotlinType>()
// TODO: handle overflow // TODO: handle overflow
when (argumentType) { when (val argumentType = functionCall.argument.typeRef.coneTypeUnsafe<ConeKotlinType>()) {
is ConeIntegerLiteralType -> { is ConeIntegerLiteralType -> {
val argumentValue = argumentType.value val argumentValue = argumentType.value
val divisionByZero = argumentValue == 0L val divisionByZero = argumentValue == 0L
@@ -210,7 +209,13 @@ class IntegerOperatorsTypeUpdater(val approximator: IntegerLiteralTypeApproximat
} }
} }
} }
functionCall.replaceTypeRef(functionCall.resultType.resolvedTypeFromPrototype(ConeIntegerLiteralTypeImpl(resultValue, isUnsigned = receiverType.isUnsigned))) val newTypeRef = functionCall.resultType.resolvedTypeFromPrototype(
ConeIntegerLiteralTypeImpl(
resultValue,
isUnsigned = receiverType.isUnsigned
)
)
functionCall.replaceTypeRef(newTypeRef)
return functionCall.toOperatorCall().compose() return functionCall.toOperatorCall().compose()
} }
} }
@@ -17,7 +17,6 @@ interface ReturnTypeCalculator {
} }
class ReturnTypeCalculatorForFullBodyResolve : ReturnTypeCalculator { class ReturnTypeCalculatorForFullBodyResolve : ReturnTypeCalculator {
override fun tryCalculateReturnType(declaration: FirTypedDeclaration): FirResolvedTypeRef { override fun tryCalculateReturnType(declaration: FirTypedDeclaration): FirResolvedTypeRef {
val returnTypeRef = declaration.returnTypeRef val returnTypeRef = declaration.returnTypeRef
if (returnTypeRef is FirResolvedTypeRef) return returnTypeRef if (returnTypeRef is FirResolvedTypeRef) return returnTypeRef
@@ -64,4 +64,3 @@ class FirGlobalClassGenerationProcessor(
} }
} }
} }
@@ -106,7 +106,6 @@ class FirTransformerBasedExtensionStatusProcessor(
} }
} }
private object ReplaceStatus : FirTransformer<FirDeclarationStatus>() { private object ReplaceStatus : FirTransformer<FirDeclarationStatus>() {
override fun <E : FirElement> transformElement(element: E, data: FirDeclarationStatus): CompositeTransformResult<E> { override fun <E : FirElement> transformElement(element: E, data: FirDeclarationStatus): CompositeTransformResult<E> {
return element.compose() return element.compose()
@@ -118,4 +117,4 @@ private object ReplaceStatus : FirTransformer<FirDeclarationStatus>() {
): CompositeTransformResult<FirDeclarationStatus> { ): CompositeTransformResult<FirDeclarationStatus> {
return data.compose() return data.compose()
} }
} }