[FIR] Introduce ResolutionMode as data for body resolve instead of Any?

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