From c58ca27b2e91b4ba2525fadc7fd46a2df5997542 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 5 Nov 2019 15:13:42 +0300 Subject: [PATCH] [FIR] Introduce `ResolutionMode` as data for body resolve instead of `Any?` --- .../jetbrains/kotlin/fir/FirCallResolver.kt | 6 +- .../kotlin/fir/resolve/ResolutionMode.kt | 19 ++++ .../fir/resolve/dfa/FirDataFlowAnalyzer.kt | 3 +- .../fir/resolve/inference/FirCallCompleter.kt | 3 +- .../transformers/ReturnTypeCalculator.kt | 3 +- .../FirAbstractBodyResolveTransformer.kt | 9 +- .../body/resolve/FirBodyResolveTransformer.kt | 80 ++++++++-------- .../FirBodyResolveTransformerAdapters.kt | 9 +- ...ControlFlowStatementsResolveTransformer.kt | 40 ++++---- .../FirDeclarationsResolveTransformer.kt | 94 ++++++++++--------- .../FirExpressionsResolveTransformer.kt | 69 +++++++------- .../FirPartialBodyResolveTransformer.kt | 3 +- .../kotlin/idea/fir/FirResolutionApi.kt | 3 +- 13 files changed, 186 insertions(+), 155 deletions(-) create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index f83796d9dd5..55f7ce4d898 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -66,8 +66,8 @@ class FirCallResolver( fun resolveCallAndSelectCandidate(functionCall: FirFunctionCall, expectedTypeRef: FirTypeRef?, file: FirFile): FirFunctionCall { qualifiedResolver.reset() @Suppress("NAME_SHADOWING") - val functionCall = functionCall.transformExplicitReceiver(transformer, noExpectedType) - .transformArguments(transformer, null) + val functionCall = functionCall.transformExplicitReceiver(transformer, ResolutionMode.ContextIndependent) + .transformArguments(transformer, ResolutionMode.ContextDependent) val name = functionCall.calleeReference.name @@ -161,7 +161,7 @@ class FirCallResolver( qualifiedResolver.initProcessingQualifiedAccess(qualifiedAccess, callee) @Suppress("NAME_SHADOWING") - val qualifiedAccess = qualifiedAccess.transformExplicitReceiver(transformer, noExpectedType) + val qualifiedAccess = qualifiedAccess.transformExplicitReceiver(transformer, ResolutionMode.ContextIndependent) qualifiedResolver.replacedQualifier(qualifiedAccess)?.let { return it } val info = CallInfo( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt new file mode 100644 index 00000000000..fe253ee777f --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.resolve + +import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef +import org.jetbrains.kotlin.fir.types.FirTypeRef + +sealed class ResolutionMode { + object ContextDependent : ResolutionMode() + object ContextIndependent : ResolutionMode() + class WithExpectedType(val expectedTypeRef: FirTypeRef) : ResolutionMode() + class LambdaResolution(val expectedReturnTypeRef: FirResolvedTypeRef?) : ResolutionMode() +} + +fun withExpectedType(expectedTypeRef: FirTypeRef?): ResolutionMode = + expectedTypeRef?.let { ResolutionMode.WithExpectedType(it) } ?: ResolutionMode.ContextDependent \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index 8e7a46e8afc..c3a3ee26604 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.impl.FirExplicitThisReference import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStackImpl +import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.dfa.Condition.* import org.jetbrains.kotlin.fir.resolve.dfa.cfg.* import org.jetbrains.kotlin.fir.resolve.dfa.contracts.buildContractFir @@ -485,7 +486,7 @@ class FirDataFlowAnalyzer(private val components: FirAbstractBodyResolveTransfor for (conditionalEffect in conditionalEffects) { val fir = conditionalEffect.buildContractFir(argumentsMapping) ?: continue val effect = conditionalEffect.effect as? ConeReturnsEffectDeclaration ?: continue - fir.transformSingle(components.transformer, null) + fir.transformSingle(components.transformer, ResolutionMode.ContextDependent) val argumentVariable = getOrCreateVariable(fir) val lastNode = graphBuilder.lastNode when (val value = effect.value) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt index 77be869075f..6662805f8a5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirResolvable import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents +import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer @@ -141,7 +142,7 @@ class FirCallCompleter( ) replacements[lambdaArgument] = - newLambdaExpression.transformSingle(transformer, FirDeclarationsResolveTransformer.LambdaResolution(expectedReturnTypeRef)) + newLambdaExpression.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef)) return (newLambdaExpression.body?.returnExpressions() ?: emptyList()) to InferenceSession.default } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ReturnTypeCalculator.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ReturnTypeCalculator.kt index 6c0ec141893..e87e5e45495 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ReturnTypeCalculator.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ReturnTypeCalculator.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.render +import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.firProvider import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDesignatedBodyResolveTransformer @@ -84,7 +85,7 @@ class ReturnTypeCalculatorWithJump(val session: FirSession, val scopeSession: Sc scopeSession ) - file.transform(transformer, null) + file.transform(transformer, ResolutionMode.ContextDependent) val newReturnTypeRef = declaration.returnTypeRef diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt index 0f69b6b1da8..432227833ac 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl -abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAbstractPhaseTransformer(phase) { +abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAbstractPhaseTransformer(phase) { abstract val components: BodyResolveTransformerComponents abstract var implicitTypeOnly: Boolean @@ -78,6 +78,13 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb protected inline val scopeSession: ScopeSession get() = components.scopeSession protected inline val file: FirFile get() = components.file + val ResolutionMode.expectedType: FirTypeRef? + get() = when (this) { + is ResolutionMode.WithExpectedType -> expectedTypeRef + is ResolutionMode.ContextIndependent -> noExpectedType + else -> null + } + class BodyResolveTransformerComponents( override val session: FirSession, override val scopeSession: ScopeSession, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt index d1abbb27ab7..02b46b43583 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.FirTargetElement import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.render +import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.scopes.addImportingScopes import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef @@ -34,7 +35,7 @@ open class FirBodyResolveTransformer( private val declarationsTransformer = FirDeclarationsResolveTransformer(this) private val controlFlowStatementsTransformer = FirControlFlowStatementsResolveTransformer(this) - override fun transformFile(file: FirFile, data: Any?): CompositeTransformResult { + override fun transformFile(file: FirFile, data: ResolutionMode): CompositeTransformResult { packageFqName = file.packageFqName components.file = file return withScopeCleanup(components.topLevelScopes) { @@ -44,181 +45,180 @@ open class FirBodyResolveTransformer( } } - override fun transformElement(element: E, data: Any?): CompositeTransformResult { + override fun transformElement(element: E, data: ResolutionMode): CompositeTransformResult { @Suppress("UNCHECKED_CAST") return (element.transformChildren(this, data) as E).compose() } - override fun transformTypeRef(typeRef: FirTypeRef, data: Any?): CompositeTransformResult { + override fun transformTypeRef(typeRef: FirTypeRef, data: ResolutionMode): CompositeTransformResult { return typeRef.compose() } - override fun transformImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: Any?): CompositeTransformResult { - if (data == null) + override fun transformImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: ResolutionMode): CompositeTransformResult { + if (data !is ResolutionMode.WithExpectedType) return implicitTypeRef.compose() - require(data is FirTypeRef) - return data.compose() + return data.expectedTypeRef.compose() } // ------------------------------------- Expressions ------------------------------------- - override fun transformExpression(expression: FirExpression, data: Any?): CompositeTransformResult { + override fun transformExpression(expression: FirExpression, data: ResolutionMode): CompositeTransformResult { return expressionsTransformer.transformExpression(expression, data) } override fun transformQualifiedAccessExpression( qualifiedAccessExpression: FirQualifiedAccessExpression, - data: Any? + data: ResolutionMode ): CompositeTransformResult { return expressionsTransformer.transformQualifiedAccessExpression(qualifiedAccessExpression, data) } - override fun transformFunctionCall(functionCall: FirFunctionCall, data: Any?): CompositeTransformResult { + override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): CompositeTransformResult { return expressionsTransformer.transformFunctionCall(functionCall, data) } override fun transformCallableReferenceAccess( callableReferenceAccess: FirCallableReferenceAccess, - data: Any? + data: ResolutionMode ): CompositeTransformResult { return expressionsTransformer.transformCallableReferenceAccess(callableReferenceAccess, data) } - override fun transformBlock(block: FirBlock, data: Any?): CompositeTransformResult { + override fun transformBlock(block: FirBlock, data: ResolutionMode): CompositeTransformResult { return expressionsTransformer.transformBlock(block, data) } override fun transformThisReceiverExpression( thisReceiverExpression: FirThisReceiverExpression, - data: Any? + data: ResolutionMode ): CompositeTransformResult { return expressionsTransformer.transformThisReceiverExpression(thisReceiverExpression, data) } - override fun transformOperatorCall(operatorCall: FirOperatorCall, data: Any?): CompositeTransformResult { + override fun transformOperatorCall(operatorCall: FirOperatorCall, data: ResolutionMode): CompositeTransformResult { return expressionsTransformer.transformOperatorCall(operatorCall, data) } - override fun transformTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: Any?): CompositeTransformResult { + override fun transformTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: ResolutionMode): CompositeTransformResult { return expressionsTransformer.transformTypeOperatorCall(typeOperatorCall, data) } override fun transformBinaryLogicExpression( binaryLogicExpression: FirBinaryLogicExpression, - data: Any? + data: ResolutionMode ): CompositeTransformResult { return expressionsTransformer.transformBinaryLogicExpression(binaryLogicExpression, data) } override fun transformVariableAssignment( variableAssignment: FirVariableAssignment, - data: Any? + data: ResolutionMode ): CompositeTransformResult { return expressionsTransformer.transformVariableAssignment(variableAssignment, data) } - override fun transformGetClassCall(getClassCall: FirGetClassCall, data: Any?): CompositeTransformResult { + override fun transformGetClassCall(getClassCall: FirGetClassCall, data: ResolutionMode): CompositeTransformResult { return expressionsTransformer.transformGetClassCall(getClassCall, data) } override fun transformWrappedDelegateExpression( wrappedDelegateExpression: FirWrappedDelegateExpression, - data: Any? + data: ResolutionMode ): CompositeTransformResult { return expressionsTransformer.transformWrappedDelegateExpression(wrappedDelegateExpression, data) } - override fun transformConstExpression(constExpression: FirConstExpression, data: Any?): CompositeTransformResult { + override fun transformConstExpression(constExpression: FirConstExpression, data: ResolutionMode): CompositeTransformResult { return expressionsTransformer.transformConstExpression(constExpression, data) } - override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: Any?): CompositeTransformResult { + override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: ResolutionMode): CompositeTransformResult { return expressionsTransformer.transformAnnotationCall(annotationCall, data) } // ------------------------------------- Declarations ------------------------------------- - override fun transformDeclaration(declaration: FirDeclaration, data: Any?): CompositeTransformResult { + override fun transformDeclaration(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult { return declarationsTransformer.transformDeclaration(declaration, data) } - override fun transformProperty(property: FirProperty, data: Any?): CompositeTransformResult { + override fun transformProperty(property: FirProperty, data: ResolutionMode): CompositeTransformResult { return declarationsTransformer.transformProperty(property, data) } - override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): CompositeTransformResult { + override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): CompositeTransformResult { return declarationsTransformer.transformRegularClass(regularClass, data) } - override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?): CompositeTransformResult { + override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: ResolutionMode): CompositeTransformResult { return declarationsTransformer.transformAnonymousObject(anonymousObject, data) } - override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): CompositeTransformResult { + override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: ResolutionMode): CompositeTransformResult { return declarationsTransformer.transformSimpleFunction(simpleFunction, data) } - override fun > transformFunction(function: FirFunction, data: Any?): CompositeTransformResult { + override fun > transformFunction(function: FirFunction, data: ResolutionMode): CompositeTransformResult { return declarationsTransformer.transformFunction(function, data) } - override fun transformConstructor(constructor: FirConstructor, data: Any?): CompositeTransformResult { + override fun transformConstructor(constructor: FirConstructor, data: ResolutionMode): CompositeTransformResult { return declarationsTransformer.transformConstructor(constructor, data) } override fun transformAnonymousInitializer( anonymousInitializer: FirAnonymousInitializer, - data: Any? + data: ResolutionMode ): CompositeTransformResult { return declarationsTransformer.transformAnonymousInitializer(anonymousInitializer, data) } - override fun transformAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: Any?): CompositeTransformResult { + override fun transformAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: ResolutionMode): CompositeTransformResult { return declarationsTransformer.transformAnonymousFunction(anonymousFunction, data) } - override fun transformValueParameter(valueParameter: FirValueParameter, data: Any?): CompositeTransformResult { + override fun transformValueParameter(valueParameter: FirValueParameter, data: ResolutionMode): CompositeTransformResult { return declarationsTransformer.transformValueParameter(valueParameter, data) } // ------------------------------------- Control flow statements ------------------------------------- - override fun transformWhileLoop(whileLoop: FirWhileLoop, data: Any?): CompositeTransformResult { + override fun transformWhileLoop(whileLoop: FirWhileLoop, data: ResolutionMode): CompositeTransformResult { return controlFlowStatementsTransformer.transformWhileLoop(whileLoop, data) } - override fun transformDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: Any?): CompositeTransformResult { + override fun transformDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: ResolutionMode): CompositeTransformResult { return controlFlowStatementsTransformer.transformDoWhileLoop(doWhileLoop, data) } - override fun transformWhenExpression(whenExpression: FirWhenExpression, data: Any?): CompositeTransformResult { + override fun transformWhenExpression(whenExpression: FirWhenExpression, data: ResolutionMode): CompositeTransformResult { return controlFlowStatementsTransformer.transformWhenExpression(whenExpression, data) } - override fun transformWhenBranch(whenBranch: FirWhenBranch, data: Any?): CompositeTransformResult { + override fun transformWhenBranch(whenBranch: FirWhenBranch, data: ResolutionMode): CompositeTransformResult { return controlFlowStatementsTransformer.transformWhenBranch(whenBranch, data) } override fun transformWhenSubjectExpression( whenSubjectExpression: FirWhenSubjectExpression, - data: Any? + data: ResolutionMode ): CompositeTransformResult { return controlFlowStatementsTransformer.transformWhenSubjectExpression(whenSubjectExpression, data) } - override fun transformTryExpression(tryExpression: FirTryExpression, data: Any?): CompositeTransformResult { + override fun transformTryExpression(tryExpression: FirTryExpression, data: ResolutionMode): CompositeTransformResult { return controlFlowStatementsTransformer.transformTryExpression(tryExpression, data) } - override fun transformCatch(catch: FirCatch, data: Any?): CompositeTransformResult { + override fun transformCatch(catch: FirCatch, data: ResolutionMode): CompositeTransformResult { return controlFlowStatementsTransformer.transformCatch(catch, data) } - override fun transformJump(jump: FirJump, data: Any?): CompositeTransformResult { + override fun transformJump(jump: FirJump, data: ResolutionMode): CompositeTransformResult { return controlFlowStatementsTransformer.transformJump(jump, data) } - override fun transformThrowExpression(throwExpression: FirThrowExpression, data: Any?): CompositeTransformResult { + override fun transformThrowExpression(throwExpression: FirThrowExpression, data: ResolutionMode): CompositeTransformResult { return controlFlowStatementsTransformer.transformThrowExpression(throwExpression, data) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformerAdapters.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformerAdapters.kt index 89dfa2fbecd..cfdeb7cad99 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformerAdapters.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformerAdapters.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.FirTransformer @@ -26,7 +27,7 @@ class FirDesignatedBodyResolveTransformer( implicitTypeOnly = implicitTypeOnly, scopeSession = scopeSession ) { - override fun transformElement(element: E, data: Any?): CompositeTransformResult { + override fun transformElement(element: E, data: ResolutionMode): CompositeTransformResult { if (designation.hasNext()) { designation.next().visitNoTransform(this, data) return element.compose() @@ -34,7 +35,7 @@ class FirDesignatedBodyResolveTransformer( return super.transformElement(element, data) } - override fun transformDeclaration(declaration: FirDeclaration, data: Any?): CompositeTransformResult { + override fun transformDeclaration(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult { return components.withContainer(declaration) { declaration.replaceResolvePhase(transformerPhase) transformElement(declaration, data) @@ -58,7 +59,7 @@ class FirImplicitTypeBodyResolveTransformerAdapter : FirTransformer() implicitTypeOnly = true, scopeSession = scopeSession ) - return file.transform(transformer, null) + return file.transform(transformer, ResolutionMode.ContextDependent) } } @@ -79,6 +80,6 @@ class FirBodyResolveTransformerAdapter : FirTransformer() { implicitTypeOnly = false, scopeSession = scopeSession ) - return file.transform(transformer, null) + return file.transform(transformer, ResolutionMode.ContextDependent) } } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt index 7ae35da1793..d5686590bd1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt @@ -12,12 +12,12 @@ import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference +import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.transformers.FirSyntheticCallGenerator import org.jetbrains.kotlin.fir.resolve.transformers.FirWhenExhaustivenessTransformer import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef -import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.compose @@ -32,14 +32,14 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran // ------------------------------- Loops ------------------------------- - override fun transformWhileLoop(whileLoop: FirWhileLoop, data: Any?): CompositeTransformResult { + override fun transformWhileLoop(whileLoop: FirWhileLoop, data: ResolutionMode): CompositeTransformResult { return whileLoop.also(dataFlowAnalyzer::enterWhileLoop) .transformCondition(transformer, data).also(dataFlowAnalyzer::exitWhileLoopCondition) .transformBlock(transformer, data).also(dataFlowAnalyzer::exitWhileLoop) .transformOtherChildren(transformer, data).compose() } - override fun transformDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: Any?): CompositeTransformResult { + override fun transformDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: ResolutionMode): CompositeTransformResult { return doWhileLoop.also(dataFlowAnalyzer::enterDoWhileLoop) .transformBlock(transformer, data).also(dataFlowAnalyzer::enterDoWhileLoopCondition) .transformCondition(transformer, data).also(dataFlowAnalyzer::exitDoWhileLoop) @@ -48,7 +48,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran // ------------------------------- When expressions ------------------------------- - override fun transformWhenExpression(whenExpression: FirWhenExpression, data: Any?): CompositeTransformResult { + override fun transformWhenExpression(whenExpression: FirWhenExpression, data: ResolutionMode): CompositeTransformResult { if (whenExpression.calleeReference is FirResolvedNamedReference && whenExpression.resultType !is FirImplicitTypeRef) { return whenExpression.compose() } @@ -58,17 +58,17 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran localScopes += FirLocalScope() } @Suppress("NAME_SHADOWING") - var whenExpression = whenExpression.transformSubject(transformer, noExpectedType) + var whenExpression = whenExpression.transformSubject(transformer, ResolutionMode.ContextIndependent) when { whenExpression.branches.isEmpty() -> { } whenExpression.isOneBranch() -> { - whenExpression = whenExpression.transformBranches(transformer, noExpectedType) + whenExpression = whenExpression.transformBranches(transformer, ResolutionMode.ContextIndependent) whenExpression.resultType = whenExpression.branches.first().result.resultType } else -> { - whenExpression = whenExpression.transformBranches(transformer, null) + whenExpression = whenExpression.transformBranches(transformer, ResolutionMode.ContextDependent) whenExpression = syntheticCallGenerator.generateCalleeForWhenExpression(whenExpression) ?: run { whenExpression = whenExpression.transformSingle(whenExhaustivenessTransformer, null) @@ -77,7 +77,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran return@with whenExpression.compose() } - val expectedTypeRef = data as FirTypeRef? + val expectedTypeRef = data.expectedType whenExpression = callCompleter.completeCall(whenExpression, expectedTypeRef) } } @@ -102,7 +102,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran return lastBranch.condition is FirElseIfTrueCondition && lastBranch.result is FirEmptyExpressionBlock } - override fun transformWhenBranch(whenBranch: FirWhenBranch, data: Any?): CompositeTransformResult { + override fun transformWhenBranch(whenBranch: FirWhenBranch, data: ResolutionMode): CompositeTransformResult { return whenBranch.also { dataFlowAnalyzer.enterWhenBranchCondition(whenBranch) } .transformCondition(transformer, data).also { dataFlowAnalyzer.exitWhenBranchCondition(it) } .transformResult(transformer, data).also { dataFlowAnalyzer.exitWhenBranchResult(it) } @@ -111,7 +111,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran override fun transformWhenSubjectExpression( whenSubjectExpression: FirWhenSubjectExpression, - data: Any? + data: ResolutionMode ): CompositeTransformResult { val parentWhen = whenSubjectExpression.whenSubject.whenExpression val subjectType = parentWhen.subject?.resultType ?: parentWhen.subjectVariable?.returnTypeRef @@ -123,19 +123,19 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran // ------------------------------- Try/catch expressions ------------------------------- - override fun transformTryExpression(tryExpression: FirTryExpression, data: Any?): CompositeTransformResult { + override fun transformTryExpression(tryExpression: FirTryExpression, data: ResolutionMode): CompositeTransformResult { if (tryExpression.calleeReference is FirResolvedNamedReference && tryExpression.resultType !is FirImplicitTypeRef) { return tryExpression.compose() } dataFlowAnalyzer.enterTryExpression(tryExpression) - tryExpression.transformTryBlock(transformer, null) + tryExpression.transformTryBlock(transformer, ResolutionMode.ContextDependent) dataFlowAnalyzer.exitTryMainBlock(tryExpression) - tryExpression.transformCatches(this, null) + tryExpression.transformCatches(this, ResolutionMode.ContextDependent) @Suppress("NAME_SHADOWING") var result = syntheticCallGenerator.generateCalleeForTryExpression(tryExpression)?.let { - val expectedTypeRef = data as FirTypeRef? + val expectedTypeRef = data.expectedType callCompleter.completeCall(it, expectedTypeRef) } ?: run { tryExpression.resultType = FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Can't resolve try expression", DiagnosticKind.InferenceError)) @@ -144,7 +144,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran result = if (result.finallyBlock != null) { result.also(dataFlowAnalyzer::enterFinallyBlock) - .transformFinallyBlock(transformer, noExpectedType) + .transformFinallyBlock(transformer, ResolutionMode.ContextIndependent) .also(dataFlowAnalyzer::exitFinallyBlock) } else { result @@ -153,24 +153,24 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran return result.compose() } - override fun transformCatch(catch: FirCatch, data: Any?): CompositeTransformResult { + override fun transformCatch(catch: FirCatch, data: ResolutionMode): CompositeTransformResult { dataFlowAnalyzer.enterCatchClause(catch) return withScopeCleanup(localScopes) { localScopes += FirLocalScope() - catch.transformParameter(transformer, noExpectedType) - catch.transformBlock(transformer, null) + catch.transformParameter(transformer, ResolutionMode.ContextIndependent) + catch.transformBlock(transformer, ResolutionMode.ContextDependent) }.also { dataFlowAnalyzer.exitCatchClause(it) }.compose() } // ------------------------------- Jumps ------------------------------- - override fun transformJump(jump: FirJump, data: Any?): CompositeTransformResult { + override fun transformJump(jump: FirJump, data: ResolutionMode): CompositeTransformResult { val result = transformer.transformExpression(jump, data) dataFlowAnalyzer.exitJump(jump) return result } - override fun transformThrowExpression(throwExpression: FirThrowExpression, data: Any?): CompositeTransformResult { + override fun transformThrowExpression(throwExpression: FirThrowExpression, data: ResolutionMode): CompositeTransformResult { return transformer.transformExpression(throwExpression, data).also { dataFlowAnalyzer.exitThrowExceptionNode(it.single as FirThrowExpression) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 91978df3714..ccd86397f2d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.expressions.FirStatement +import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue import org.jetbrains.kotlin.fir.resolve.calls.extractLambdaInfoFromFunctionalType @@ -20,6 +21,7 @@ import org.jetbrains.kotlin.fir.resolve.constructFunctionalTypeRef import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.transformers.ControlFlowGraphReferenceTransformer import org.jetbrains.kotlin.fir.resolve.transformers.StoreType +import org.jetbrains.kotlin.fir.resolve.withExpectedType import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol @@ -36,14 +38,14 @@ import org.jetbrains.kotlin.utils.addIfNotNull class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) : FirPartialBodyResolveTransformer(transformer) { private var primaryConstructorParametersScope: FirLocalScope? = null - override fun transformDeclaration(declaration: FirDeclaration, data: Any?): CompositeTransformResult { + override fun transformDeclaration(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult { return components.withContainer(declaration) { declaration.replaceResolvePhase(transformerPhase) transformer.transformElement(declaration, data) } } - override fun transformProperty(property: FirProperty, data: Any?): CompositeTransformResult { + override fun transformProperty(property: FirProperty, data: ResolutionMode): CompositeTransformResult { if (property.isLocal) return transformLocalVariable(property, data) val returnTypeRef = property.returnTypeRef if (returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly) return property.compose() @@ -75,9 +77,9 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } } - private fun transformLocalVariable(variable: FirProperty, data: Any?): CompositeTransformResult { + private fun transformLocalVariable(variable: FirProperty, data: ResolutionMode): CompositeTransformResult { assert(variable.isLocal) - variable.transformOtherChildren(transformer, variable.returnTypeRef) + variable.transformOtherChildren(transformer, withExpectedType(variable.returnTypeRef)) if (variable.initializer != null) { storeVariableReturnType(variable) } @@ -89,8 +91,8 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } private fun FirProperty.transformChildrenWithoutAccessors(returnTypeRef: FirTypeRef): FirProperty { - return transformReturnTypeRef(transformer, returnTypeRef). - transformOtherChildren(transformer, returnTypeRef) + val data = withExpectedType(returnTypeRef) + return transformReturnTypeRef(transformer, data).transformOtherChildren(transformer, data) } private fun > FirVariable.transformAccessors() { @@ -114,7 +116,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) owner: FirVariable<*> ) { if (accessor is FirDefaultPropertyAccessor || accessor.body == null) { - transformFunction(accessor, enhancedTypeRef) + transformFunction(accessor, withExpectedType(enhancedTypeRef)) } val returnTypeRef = accessor.returnTypeRef if (returnTypeRef is FirImplicitTypeRef && enhancedTypeRef !is FirResolvedTypeRef) { @@ -135,7 +137,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } as CompositeTransformResult } - override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): CompositeTransformResult { + override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): CompositeTransformResult { localScopes.lastOrNull()?.storeDeclaration(regularClass) val oldConstructorScope = primaryConstructorParametersScope primaryConstructorParametersScope = null @@ -153,7 +155,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) return result as CompositeTransformResult } - override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?): CompositeTransformResult { + override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: ResolutionMode): CompositeTransformResult { val type = anonymousObject.defaultType() anonymousObject.resultType = FirResolvedTypeRefImpl(anonymousObject.source, type) val result = withLabelAndReceiverType(null, anonymousObject, type) { @@ -163,16 +165,16 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } private fun transformAnonymousFunctionWithLambdaResolution( - anonymousFunction: FirAnonymousFunction, lambdaResolution: LambdaResolution + anonymousFunction: FirAnonymousFunction, lambdaResolution: ResolutionMode.LambdaResolution ): FirAnonymousFunction { val receiverTypeRef = anonymousFunction.receiverTypeRef fun transform(): FirAnonymousFunction { val expectedReturnType = lambdaResolution.expectedReturnTypeRef ?: anonymousFunction.returnTypeRef.takeUnless { it is FirImplicitTypeRef } - val result = transformFunction(anonymousFunction, expectedReturnType).single as FirAnonymousFunction + val result = transformFunction(anonymousFunction, withExpectedType(expectedReturnType)).single as FirAnonymousFunction val body = result.body return if (result.returnTypeRef is FirImplicitTypeRef && body != null) { - result.transformReturnTypeRef(transformer, body.resultType) + result.transformReturnTypeRef(transformer, withExpectedType(body.resultType)) result } else { result @@ -189,9 +191,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } } - data class LambdaResolution(val expectedReturnTypeRef: FirResolvedTypeRef?) - - override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): CompositeTransformResult { + override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: ResolutionMode): CompositeTransformResult { val returnTypeRef = simpleFunction.returnTypeRef if ((returnTypeRef !is FirImplicitTypeRef) && implicitTypeOnly) { return simpleFunction.compose() @@ -219,17 +219,17 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) if (function is FirSimpleFunction) { localScopes.lastOrNull()?.storeDeclaration(function) } - val result = transformFunction(function, returnTypeRef).single as FirFunction<*> + val result = transformFunction(function, withExpectedType(returnTypeRef)).single as FirFunction<*> val body = result.body return if (result.returnTypeRef is FirImplicitTypeRef && body != null) { - result.transformReturnTypeRef(transformer, body.resultType) + result.transformReturnTypeRef(transformer, withExpectedType(body.resultType)) result } else { result }.compose() } - override fun > transformFunction(function: FirFunction, data: Any?): CompositeTransformResult { + override fun > transformFunction(function: FirFunction, data: ResolutionMode): CompositeTransformResult { return withScopeCleanup(localScopes) { localScopes += FirLocalScope() dataFlowAnalyzer.enterFunction(function) @@ -242,14 +242,14 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } } - override fun transformConstructor(constructor: FirConstructor, data: Any?): CompositeTransformResult { + override fun transformConstructor(constructor: FirConstructor, data: ResolutionMode): CompositeTransformResult { if (implicitTypeOnly) return constructor.compose() return transformFunction(constructor, data) as CompositeTransformResult } override fun transformAnonymousInitializer( anonymousInitializer: FirAnonymousInitializer, - data: Any? + data: ResolutionMode ): CompositeTransformResult { if (implicitTypeOnly) return anonymousInitializer.compose() return withScopeCleanup(localScopes) { @@ -261,25 +261,25 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } } - override fun transformValueParameter(valueParameter: FirValueParameter, data: Any?): CompositeTransformResult { + override fun transformValueParameter(valueParameter: FirValueParameter, data: ResolutionMode): CompositeTransformResult { localScopes.lastOrNull()?.storeDeclaration(valueParameter) if (valueParameter.returnTypeRef is FirImplicitTypeRef) { valueParameter.replaceResolvePhase(transformerPhase) return valueParameter.compose() // TODO } - return (transformDeclaration(valueParameter, valueParameter.returnTypeRef).single as FirStatement).compose() + return (transformDeclaration(valueParameter, withExpectedType(valueParameter.returnTypeRef)).single as FirStatement).compose() } - override fun transformAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: Any?): CompositeTransformResult { + override fun transformAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: ResolutionMode): CompositeTransformResult { return when (data) { - null -> { + ResolutionMode.ContextDependent -> { anonymousFunction.compose() } - is LambdaResolution -> { + is ResolutionMode.LambdaResolution -> { transformAnonymousFunctionWithLambdaResolution(anonymousFunction, data).compose() } - is FirTypeRef -> { - val resolvedLambdaAtom = (data as? FirResolvedTypeRef)?.let { + is ResolutionMode.WithExpectedType -> { + val resolvedLambdaAtom = (data.expectedTypeRef as? FirResolvedTypeRef)?.let { extractLambdaInfoFromFunctionalType( it.type, it, anonymousFunction ) @@ -335,15 +335,15 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) ?: af.returnTypeRef ) af = af.transformValueParameters(ImplicitToErrorTypeTransformer, null) - val bodyExpectedType = returnTypeRefFromResolvedAtom ?: data - af = transformFunction(af, bodyExpectedType).single as FirAnonymousFunction + val bodyExpectedType = returnTypeRefFromResolvedAtom ?: data.expectedTypeRef + af = transformFunction(af, withExpectedType(bodyExpectedType)).single as FirAnonymousFunction af = af.copy( returnTypeRef = af.body?.resultType ?: FirErrorTypeRefImpl(af.source, FirSimpleDiagnostic("No result type for lambda", DiagnosticKind.InferenceError)) ) af.replaceTypeRef(af.constructFunctionalTypeRef(session)) af.compose() } - else -> { + is ResolutionMode.ContextIndependent -> { transformFunction(anonymousFunction, data).single.compose() } } @@ -380,37 +380,39 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) if (variable.returnTypeRef is FirImplicitTypeRef) { when { initializer != null -> { + val expectedType = when (val resultType = initializer.resultType) { + is FirImplicitTypeRef -> FirErrorTypeRefImpl( + null, + FirSimpleDiagnostic("No result type for initializer", DiagnosticKind.InferenceError) + ) + else -> resultType + } variable.transformReturnTypeRef( transformer, - when (val resultType = initializer.resultType) { - is FirImplicitTypeRef -> FirErrorTypeRefImpl( - null, - FirSimpleDiagnostic("No result type for initializer", DiagnosticKind.InferenceError) - ) - else -> resultType - } + withExpectedType(expectedType) ) } variable.getter != null && variable.getter !is FirDefaultPropertyAccessor -> { + val expectedType = when (val resultType = variable.getter?.returnTypeRef) { + is FirImplicitTypeRef -> FirErrorTypeRefImpl( + null, + FirSimpleDiagnostic("No result type for getter", DiagnosticKind.InferenceError) + ) + else -> resultType + } variable.transformReturnTypeRef( transformer, - when (val resultType = variable.getter?.returnTypeRef) { - is FirImplicitTypeRef -> FirErrorTypeRefImpl( - null, - FirSimpleDiagnostic("No result type for getter", DiagnosticKind.InferenceError) - ) - else -> resultType - } + withExpectedType(expectedType) ) } else -> { variable.transformReturnTypeRef( - transformer, FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Cannot infer variable type without initializer / getter / delegate", DiagnosticKind.InferenceError)) + transformer, withExpectedType(FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Cannot infer variable type without initializer / getter / delegate", DiagnosticKind.InferenceError))) ) } } if (variable.getter?.returnTypeRef is FirImplicitTypeRef) { - variable.getter?.transformReturnTypeRef(transformer, variable.returnTypeRef) + variable.getter?.transformReturnTypeRef(transformer, withExpectedType(variable.returnTypeRef)) } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 152eea01d69..477d2951ef5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -22,16 +22,13 @@ import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl import org.jetbrains.kotlin.fir.references.impl.FirExplicitThisReference import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference import org.jetbrains.kotlin.fir.render +import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.ConeInferenceContext import org.jetbrains.kotlin.fir.resolve.calls.candidate -import org.jetbrains.kotlin.fir.resolve.constructType import org.jetbrains.kotlin.fir.resolve.diagnostics.FirOperatorAmbiguityError import org.jetbrains.kotlin.fir.resolve.diagnostics.FirUnresolvedReferenceError -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver -import org.jetbrains.kotlin.fir.resolve.typeFromCallee -import org.jetbrains.kotlin.fir.resolve.withNullability import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.symbols.StandardClassIds @@ -57,7 +54,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : components.callResolver.initTransformer(this) } - override fun transformExpression(expression: FirExpression, data: Any?): CompositeTransformResult { + override fun transformExpression(expression: FirExpression, data: ResolutionMode): CompositeTransformResult { if (expression.resultType is FirImplicitTypeRef && expression !is FirWrappedExpression) { val type = FirErrorTypeRefImpl(expression.source, FirSimpleDiagnostic("Type calculating for ${expression::class} is not supported", DiagnosticKind.InferenceError)) expression.resultType = type @@ -67,7 +64,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : override fun transformQualifiedAccessExpression( qualifiedAccessExpression: FirQualifiedAccessExpression, - data: Any? + data: ResolutionMode ): CompositeTransformResult { var result = when (val callee = qualifiedAccessExpression.calleeReference) { is FirExplicitThisReference -> { @@ -109,7 +106,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : // NB: here we can get raw expression because of dropped qualifiers (see transform callee), // so candidate existence must be checked before calling completion if (transformedCallee is FirQualifiedAccessExpression && transformedCallee.candidate() != null) { - callCompleter.completeCall(transformedCallee, data as? FirTypeRef) + callCompleter.completeCall(transformedCallee, data.expectedType) } else { transformedCallee } @@ -135,14 +132,14 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : return FirExpressionWithSmartcastImpl(qualifiedAccessExpression, intersectedTypeRef, typesFromSmartCast) } - override fun transformFunctionCall(functionCall: FirFunctionCall, data: Any?): CompositeTransformResult { + override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): CompositeTransformResult { if (functionCall.calleeReference is FirResolvedNamedReference && functionCall.resultType is FirImplicitTypeRef) { storeTypeFromCallee(functionCall) } dataFlowAnalyzer.enterFunctionCall(functionCall) if (functionCall.calleeReference !is FirSimpleNamedReference) return functionCall.compose() functionCall.transform(InvocationKindTransformer, null) - val expectedTypeRef = data as FirTypeRef? + val expectedTypeRef = data.expectedType val completeInference = try { val initialExplicitReceiver = functionCall.explicitReceiver @@ -161,7 +158,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : return completeInference.compose() } - override fun transformBlock(block: FirBlock, data: Any?): CompositeTransformResult { + override fun transformBlock(block: FirBlock, data: ResolutionMode): CompositeTransformResult { dataFlowAnalyzer.enterBlock(block) @Suppress("NAME_SHADOWING") val block = block.transformChildren(transformer, data) as FirBlock @@ -183,14 +180,14 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : override fun transformThisReceiverExpression( thisReceiverExpression: FirThisReceiverExpression, - data: Any? + data: ResolutionMode ): CompositeTransformResult { return transformQualifiedAccessExpression(thisReceiverExpression, data) } - override fun transformOperatorCall(operatorCall: FirOperatorCall, data: Any?): CompositeTransformResult { + override fun transformOperatorCall(operatorCall: FirOperatorCall, data: ResolutionMode): CompositeTransformResult { val result = if (operatorCall.operation in FirOperation.BOOLEANS) { - (operatorCall.transformChildren(transformer, noExpectedType) as FirOperatorCall).also { + (operatorCall.transformChildren(transformer, ResolutionMode.ContextIndependent) as FirOperatorCall).also { it.resultType = builtinTypes.booleanType } } else { @@ -200,7 +197,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : if (operatorCall.operation in FirOperation.ASSIGNMENTS) { require(operatorCall.operation != FirOperation.ASSIGN) @Suppress("NAME_SHADOWING") - val operatorCall = operatorCall.transformArguments(this, noExpectedType) + val operatorCall = operatorCall.transformArguments(this, ResolutionMode.ContextIndependent) val (leftArgument, rightArgument) = operatorCall.arguments fun createFunctionCall(name: Name) = FirFunctionCallImpl(operatorCall.source).apply { @@ -217,12 +214,12 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : // x.plusAssign(y) val assignmentOperatorName = FirOperationNameConventions.ASSIGNMENTS.getValue(operatorCall.operation) val assignOperatorCall = createFunctionCall(assignmentOperatorName) - val resolvedAssignCall = assignOperatorCall.transformSingle(this, noExpectedType) + val resolvedAssignCall = assignOperatorCall.transformSingle(this, ResolutionMode.ContextIndependent) val assignCallReference = resolvedAssignCall.toResolvedCallableReference() // x + y val simpleOperatorName = FirOperationNameConventions.ASSIGNMENTS_TO_SIMPLE_OPERATOR.getValue(operatorCall.operation) val simpleOperatorCall = createFunctionCall(simpleOperatorName) - val resolvedOperatorCall = simpleOperatorCall.transformSingle(this, noExpectedType) + val resolvedOperatorCall = simpleOperatorCall.transformSingle(this, ResolutionMode.ContextIndependent) val operatorCallReference = resolvedOperatorCall.toResolvedCallableReference() val property = (leftArgument.toResolvedCallableSymbol() as? FirPropertySymbol)?.fir @@ -234,7 +231,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : lValue = (leftArgument as? FirQualifiedAccess)?.calleeReference ?: FirErrorNamedReferenceImpl(null, FirUnresolvedReferenceError()) } - assignment.transform(transformer, noExpectedType) + assignment.transform(transformer, ResolutionMode.ContextIndependent) } else -> FirErrorExpressionImpl( operatorCall.source, @@ -247,7 +244,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : return result.compose() } - override fun transformTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: Any?): CompositeTransformResult { + override fun transformTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: ResolutionMode): CompositeTransformResult { val symbolProvider = session.firSymbolProvider val resolved = transformExpression(typeOperatorCall, data).single when ((resolved as FirTypeOperatorCall).operation) { @@ -274,34 +271,34 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : override fun transformBinaryLogicExpression( binaryLogicExpression: FirBinaryLogicExpression, - data: Any? + data: ResolutionMode ): CompositeTransformResult { val booleanType = builtinTypes.booleanType return when (binaryLogicExpression.kind) { LogicOperationKind.AND -> binaryLogicExpression.also(dataFlowAnalyzer::enterBinaryAnd) - .transformLeftOperand(this, booleanType).also(dataFlowAnalyzer::exitLeftBinaryAndArgument) - .transformRightOperand(this, booleanType).also(dataFlowAnalyzer::exitBinaryAnd) + .transformLeftOperand(this, ResolutionMode.WithExpectedType(booleanType)).also(dataFlowAnalyzer::exitLeftBinaryAndArgument) + .transformRightOperand(this, ResolutionMode.WithExpectedType(booleanType)).also(dataFlowAnalyzer::exitBinaryAnd) LogicOperationKind.OR -> binaryLogicExpression.also(dataFlowAnalyzer::enterBinaryOr) - .transformLeftOperand(this, booleanType).also(dataFlowAnalyzer::exitLeftBinaryOrArgument) - .transformRightOperand(this, booleanType).also(dataFlowAnalyzer::exitBinaryOr) - }.transformOtherChildren(transformer, booleanType).also { + .transformLeftOperand(this, ResolutionMode.WithExpectedType(booleanType)).also(dataFlowAnalyzer::exitLeftBinaryOrArgument) + .transformRightOperand(this, ResolutionMode.WithExpectedType(booleanType)).also(dataFlowAnalyzer::exitBinaryOr) + }.transformOtherChildren(transformer, ResolutionMode.WithExpectedType(booleanType)).also { it.resultType = booleanType }.compose() } override fun transformVariableAssignment( variableAssignment: FirVariableAssignment, - data: Any? + data: ResolutionMode ): CompositeTransformResult { // val resolvedAssignment = transformCallee(variableAssignment) val resolvedAssignment = callResolver.resolveVariableAccessAndSelectCandidate(variableAssignment, file) val result = if (resolvedAssignment is FirVariableAssignment) { - val completeAssignment = callCompleter.completeCall(resolvedAssignment, noExpectedType) + val completeAssignment = callCompleter.completeCall(resolvedAssignment, noExpectedType) // TODO: check val expectedType = components.typeFromCallee(completeAssignment) - completeAssignment.transformRValue(transformer, expectedType) + completeAssignment.transformRValue(transformer, withExpectedType(expectedType)) } else { // This can happen in erroneous code only resolvedAssignment @@ -313,14 +310,14 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : override fun transformCallableReferenceAccess( callableReferenceAccess: FirCallableReferenceAccess, - data: Any? + data: ResolutionMode ): CompositeTransformResult { if (callableReferenceAccess.calleeReference is FirResolvedNamedReference) { return callableReferenceAccess.compose() } val transformedLHS = - callableReferenceAccess.explicitReceiver?.transformSingle(this, noExpectedType) + callableReferenceAccess.explicitReceiver?.transformSingle(this, ResolutionMode.ContextIndependent) val callableReferenceAccessWithTransformedLHS = if (transformedLHS != null) @@ -328,10 +325,10 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : else callableReferenceAccess - if (data != null) { + if (data !is ResolutionMode.ContextDependent) { val resolvedReference = components.syntheticCallGenerator.resolveCallableReferenceWithSyntheticOuterCall( - callableReferenceAccess, data as? FirTypeRef + callableReferenceAccess, data.expectedType ) ?: callableReferenceAccess return resolvedReference.compose() @@ -340,7 +337,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : return callableReferenceAccessWithTransformedLHS.compose() } - override fun transformGetClassCall(getClassCall: FirGetClassCall, data: Any?): CompositeTransformResult { + override fun transformGetClassCall(getClassCall: FirGetClassCall, data: ResolutionMode): CompositeTransformResult { val transformedGetClassCall = transformExpression(getClassCall, data).single as FirGetClassCall val kClassSymbol = ClassId.fromString("kotlin/reflect/KClass")(session.firSymbolProvider) @@ -371,7 +368,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : override fun transformWrappedDelegateExpression( wrappedDelegateExpression: FirWrappedDelegateExpression, - data: Any? + data: ResolutionMode ): CompositeTransformResult { transformExpression(wrappedDelegateExpression, data) with(wrappedDelegateExpression) { @@ -383,8 +380,8 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : } } - override fun transformConstExpression(constExpression: FirConstExpression, data: Any?): CompositeTransformResult { - val expectedType = data as FirTypeRef? + override fun transformConstExpression(constExpression: FirConstExpression, data: ResolutionMode): CompositeTransformResult { + val expectedType = data.expectedType val kind = constExpression.kind if (expectedType == null || expectedType is FirImplicitTypeRef || @@ -422,7 +419,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : } } - override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: Any?): CompositeTransformResult { + override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: ResolutionMode): CompositeTransformResult { dataFlowAnalyzer.enterAnnotationCall(annotationCall) return (annotationCall.transformChildren(transformer, data) as FirAnnotationCall).also { dataFlowAnalyzer.exitAnnotationCall(it) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirPartialBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirPartialBodyResolveTransformer.kt index 4e909d51158..5396b4a0926 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirPartialBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirPartialBodyResolveTransformer.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult abstract class FirPartialBodyResolveTransformer( @@ -20,7 +21,7 @@ abstract class FirPartialBodyResolveTransformer( transformer.implicitTypeOnly = value } - override fun transformElement(element: E, data: Any?): CompositeTransformResult { + override fun transformElement(element: E, data: ResolutionMode): CompositeTransformResult { return element.transform(transformer, data) } } \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirResolutionApi.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirResolutionApi.kt index e9a055e8fdd..1269fcf63df 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirResolutionApi.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirResolutionApi.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.FirProvider +import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDesignatedBodyResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.runResolve import org.jetbrains.kotlin.fir.scopes.ProcessorAction @@ -143,7 +144,7 @@ private fun FirDeclaration.runResolve( designation.iterator(), state.getSession(psi as KtElement), implicitTypeOnly = toPhase == FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE ) - file.transform(transformer, null) + file.transform(transformer, ResolutionMode.ContextDependent) } }