[FIR] Split FirBodyResolveTransformer to separate transformers
This commit is contained in:
@@ -12,7 +12,8 @@ import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedQualifierImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedQualifierImpl
|
||||||
import org.jetbrains.kotlin.fir.references.*
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReference
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirBackingFieldReferenceImpl
|
import org.jetbrains.kotlin.fir.references.impl.FirBackingFieldReferenceImpl
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl
|
import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirResolvedCallableReferenceImpl
|
import org.jetbrains.kotlin.fir.references.impl.FirResolvedCallableReferenceImpl
|
||||||
@@ -20,7 +21,11 @@ import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
|||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack
|
import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
import org.jetbrains.kotlin.fir.resolve.transformers.StoreNameReference
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.phasedFir
|
||||||
import org.jetbrains.kotlin.fir.resolve.typeForQualifier
|
import org.jetbrains.kotlin.fir.resolve.typeForQualifier
|
||||||
import org.jetbrains.kotlin.fir.resolve.typeFromCallee
|
import org.jetbrains.kotlin.fir.resolve.typeFromCallee
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
@@ -32,12 +37,12 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
|
|||||||
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||||
|
|
||||||
class FirCallResolver(
|
class FirCallResolver(
|
||||||
private val transformer: FirBodyResolveTransformer,
|
private val transformer: FirExpressionsResolveTransformer,
|
||||||
topLevelScopes: List<FirScope>,
|
topLevelScopes: List<FirScope>,
|
||||||
localScopes: List<FirLocalScope>,
|
localScopes: List<FirLocalScope>,
|
||||||
override val implicitReceiverStack: ImplicitReceiverStack,
|
override val implicitReceiverStack: ImplicitReceiverStack,
|
||||||
private val qualifiedResolver: FirQualifiedNameResolver
|
private val qualifiedResolver: FirQualifiedNameResolver
|
||||||
) : BodyResolveComponents by transformer {
|
) : BodyResolveComponents by transformer.components {
|
||||||
|
|
||||||
private val towerResolver = FirTowerResolver(
|
private val towerResolver = FirTowerResolver(
|
||||||
returnTypeCalculator, this, resolutionStageRunner,
|
returnTypeCalculator, this, resolutionStageRunner,
|
||||||
@@ -66,7 +71,7 @@ class FirCallResolver(
|
|||||||
typeArguments,
|
typeArguments,
|
||||||
session,
|
session,
|
||||||
file,
|
file,
|
||||||
transformer.container
|
transformer.components.container
|
||||||
) { it.resultType }
|
) { it.resultType }
|
||||||
towerResolver.reset()
|
towerResolver.reset()
|
||||||
|
|
||||||
@@ -155,7 +160,7 @@ class FirCallResolver(
|
|||||||
emptyList(),
|
emptyList(),
|
||||||
session,
|
session,
|
||||||
file,
|
file,
|
||||||
transformer.container
|
transformer.components.container
|
||||||
) { it.resultType }
|
) { it.resultType }
|
||||||
towerResolver.reset()
|
towerResolver.reset()
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
|||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.PackageOrClass
|
import org.jetbrains.kotlin.fir.resolve.transformers.PackageOrClass
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.resolveToPackageOrClass
|
import org.jetbrains.kotlin.fir.resolve.transformers.resolveToPackageOrClass
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.resultType
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.typeForQualifier
|
import org.jetbrains.kotlin.fir.resolve.typeForQualifier
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.fir.references.FirResolvedCallableReference
|
|||||||
import org.jetbrains.kotlin.fir.references.FirThisReference
|
import org.jetbrains.kotlin.fir.references.FirThisReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.resultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScopeProvider
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||||
import org.jetbrains.kotlin.fir.symbols.*
|
import org.jetbrains.kotlin.fir.symbols.*
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
||||||
import org.jetbrains.kotlin.fir.resolve.withNullability
|
import org.jetbrains.kotlin.fir.resolve.withNullability
|
||||||
import org.jetbrains.kotlin.fir.returnExpressions
|
import org.jetbrains.kotlin.fir.returnExpressions
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -18,7 +18,7 @@ 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.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.transformers.FirBodyResolveTransformer
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
@@ -32,13 +32,13 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
class FirDataFlowAnalyzer(transformer: FirBodyResolveTransformer) : BodyResolveComponents by transformer {
|
class FirDataFlowAnalyzer(components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents) : BodyResolveComponents by components {
|
||||||
companion object {
|
companion object {
|
||||||
private val KOTLIN_BOOLEAN_NOT = CallableId(FqName("kotlin"), FqName("Boolean"), Name.identifier("not"))
|
private val KOTLIN_BOOLEAN_NOT = CallableId(FqName("kotlin"), FqName("Boolean"), Name.identifier("not"))
|
||||||
}
|
}
|
||||||
|
|
||||||
private val context: DataFlowInferenceContext get() = inferenceComponents.ctx as DataFlowInferenceContext
|
private val context: DataFlowInferenceContext get() = inferenceComponents.ctx as DataFlowInferenceContext
|
||||||
private val receiverStack: ImplicitReceiverStackImpl = transformer.implicitReceiverStack
|
private val receiverStack: ImplicitReceiverStackImpl = components.implicitReceiverStack as ImplicitReceiverStackImpl
|
||||||
|
|
||||||
private val graphBuilder = ControlFlowGraphBuilder()
|
private val graphBuilder = ControlFlowGraphBuilder()
|
||||||
private val logicSystem: LogicSystem = LogicSystemImpl(context)
|
private val logicSystem: LogicSystem = LogicSystemImpl(context)
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ 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.dfa.*
|
import org.jetbrains.kotlin.fir.resolve.dfa.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.resultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.types.isNothing
|
import org.jetbrains.kotlin.fir.types.isNothing
|
||||||
|
|
||||||
class ControlFlowGraphBuilder {
|
class ControlFlowGraphBuilder {
|
||||||
|
|||||||
+11
-6
@@ -14,8 +14,13 @@ 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.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.*
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.MapArguments
|
import org.jetbrains.kotlin.fir.resolve.transformers.MapArguments
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.StoreType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.typeFromCallee
|
import org.jetbrains.kotlin.fir.resolve.typeFromCallee
|
||||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||||
import org.jetbrains.kotlin.fir.returnExpressions
|
import org.jetbrains.kotlin.fir.returnExpressions
|
||||||
@@ -29,16 +34,16 @@ import org.jetbrains.kotlin.fir.visitors.transformSingle
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
|
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.EmptySubstitutor
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
||||||
import org.jetbrains.kotlin.types.model.StubTypeMarker
|
import org.jetbrains.kotlin.types.model.StubTypeMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
||||||
|
|
||||||
class FirCallCompleter(
|
class FirCallCompleter(
|
||||||
private val transformer: FirBodyResolveTransformer
|
private val transformer: FirBodyResolveTransformer,
|
||||||
) : BodyResolveComponents by transformer {
|
components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents
|
||||||
private val completer = ConstraintSystemCompleter(inferenceComponents)
|
) : BodyResolveComponents by components {
|
||||||
|
private val completer = ConstraintSystemCompleter(components.inferenceComponents)
|
||||||
|
|
||||||
fun <T> completeCall(call: T, expectedTypeRef: FirTypeRef?): T
|
fun <T> completeCall(call: T, expectedTypeRef: FirTypeRef?): T
|
||||||
where T : FirResolvable, T : FirStatement {
|
where T : FirResolvable, T : FirStatement {
|
||||||
@@ -127,7 +132,7 @@ class FirCallCompleter(
|
|||||||
)
|
)
|
||||||
|
|
||||||
replacements[lambdaArgument] =
|
replacements[lambdaArgument] =
|
||||||
newLambdaExpression.transformSingle(transformer, FirBodyResolveTransformer.LambdaResolution(expectedReturnTypeRef))
|
newLambdaExpression.transformSingle(transformer, FirDeclarationsResolveTransformer.LambdaResolution(expectedReturnTypeRef))
|
||||||
|
|
||||||
return (newLambdaExpression.body?.returnExpressions() ?: emptyList()) to InferenceSession.default
|
return (newLambdaExpression.body?.returnExpressions() ?: emptyList()) to InferenceSession.default
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
|||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer
|
||||||
|
|
||||||
abstract class FirAbstractPhaseTransformer<D>(
|
abstract class FirAbstractPhaseTransformer<D>(
|
||||||
protected val transformerPhase: FirResolvePhase
|
val transformerPhase: FirResolvePhase
|
||||||
) : FirDefaultTransformer<D>() {
|
) : FirDefaultTransformer<D>() {
|
||||||
|
|
||||||
abstract val session: FirSession
|
abstract val session: FirSession
|
||||||
|
|||||||
-1098
File diff suppressed because it is too large
Load Diff
+1
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.candidate
|
|||||||
import org.jetbrains.kotlin.fir.resolve.constructFunctionalTypeRef
|
import org.jetbrains.kotlin.fir.resolve.constructFunctionalTypeRef
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substituteOrNull
|
import org.jetbrains.kotlin.fir.resolve.substitution.substituteOrNull
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.withNullability
|
import org.jetbrains.kotlin.fir.resolve.withNullability
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
|||||||
+4
-2
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
|||||||
import org.jetbrains.kotlin.fir.references.impl.FirStubReference
|
import org.jetbrains.kotlin.fir.references.impl.FirStubReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
import org.jetbrains.kotlin.fir.symbols.SyntheticCallableId
|
import org.jetbrains.kotlin.fir.symbols.SyntheticCallableId
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
@@ -33,7 +35,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
class FirSyntheticCallGenerator(private val transformer: FirBodyResolveTransformer) : BodyResolveComponents by transformer {
|
class FirSyntheticCallGenerator(private val components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents) : BodyResolveComponents by components {
|
||||||
private val whenSelectFunction: FirSimpleFunctionImpl = generateSyntheticSelectFunction(SyntheticCallableId.WHEN)
|
private val whenSelectFunction: FirSimpleFunctionImpl = generateSyntheticSelectFunction(SyntheticCallableId.WHEN)
|
||||||
private val trySelectFunction: FirSimpleFunctionImpl = generateSyntheticSelectFunction(SyntheticCallableId.TRY)
|
private val trySelectFunction: FirSimpleFunctionImpl = generateSyntheticSelectFunction(SyntheticCallableId.TRY)
|
||||||
|
|
||||||
@@ -91,7 +93,7 @@ class FirSyntheticCallGenerator(private val transformer: FirBodyResolveTransform
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateCandidate(callInfo: CallInfo, function: FirSimpleFunctionImpl): Candidate =
|
private fun generateCandidate(callInfo: CallInfo, function: FirSimpleFunctionImpl): Candidate =
|
||||||
CandidateFactory(transformer, callInfo).createCandidate(
|
CandidateFactory(components, callInfo).createCandidate(
|
||||||
symbol = function.symbol,
|
symbol = function.symbol,
|
||||||
dispatchReceiverValue = null,
|
dispatchReceiverValue = null,
|
||||||
implicitExtensionReceiverValue = null,
|
implicitExtensionReceiverValue = null,
|
||||||
|
|||||||
+2
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.fir.resolve.transformers
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase.*
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase.*
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformerAdapter
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirImplicitTypeBodyResolveTransformerAdapter
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
|
|
||||||
// TODO: add FirSession parameter
|
// TODO: add FirSession parameter
|
||||||
|
|||||||
+1
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
|||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
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.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
|
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||||
|
|||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* 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.transformers.body.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
|
import org.jetbrains.kotlin.fir.renderWithType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.ConeInferenceContext
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.InferenceComponents
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowInferenceContext
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
||||||
|
import org.jetbrains.kotlin.fir.types.ErrorTypeConstructor
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContextDelegate
|
||||||
|
|
||||||
|
inline fun <reified T : FirElement> FirBasedSymbol<*>.firUnsafe(): T {
|
||||||
|
val fir = this.fir
|
||||||
|
require(fir is T) {
|
||||||
|
"Not an expected fir element type = ${T::class}, symbol = ${this}, fir = ${fir.renderWithType()}"
|
||||||
|
}
|
||||||
|
return fir
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline var FirExpression.resultType: FirTypeRef
|
||||||
|
get() = typeRef
|
||||||
|
set(type) {
|
||||||
|
replaceTypeRef(type)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun inferenceComponents(session: FirSession, returnTypeCalculator: ReturnTypeCalculator, scopeSession: ScopeSession) =
|
||||||
|
InferenceComponents(object : ConeInferenceContext, TypeSystemInferenceExtensionContextDelegate, DataFlowInferenceContext {
|
||||||
|
override fun findCommonIntegerLiteralTypesSuperType(explicitSupertypes: List<SimpleTypeMarker>): SimpleTypeMarker? {
|
||||||
|
// TODO: implement
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun TypeConstructorMarker.getApproximatedIntegerLiteralType(): KotlinTypeMarker {
|
||||||
|
TODO("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override val session: FirSession
|
||||||
|
get() = session
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.removeExactAnnotation(): KotlinTypeMarker {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker {
|
||||||
|
require(this is ErrorTypeConstructor)
|
||||||
|
return ConeClassErrorType(reason)
|
||||||
|
}
|
||||||
|
}, session, returnTypeCalculator, scopeSession)
|
||||||
+118
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* 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.transformers.body.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.FirSymbolOwner
|
||||||
|
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.*
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.InferenceComponents
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionStageRunner
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.inference.FirCallCompleter
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||||
|
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<Any?>(phase) {
|
||||||
|
abstract val components: BodyResolveTransformerComponents
|
||||||
|
|
||||||
|
abstract var implicitTypeOnly: Boolean
|
||||||
|
internal set
|
||||||
|
|
||||||
|
final override val session: FirSession get() = components.session
|
||||||
|
|
||||||
|
final override val <D> AbstractFirBasedSymbol<D>.phasedFir: D where D : FirDeclaration, D : FirSymbolOwner<D>
|
||||||
|
get() {
|
||||||
|
val requiredPhase = transformerPhase.prev
|
||||||
|
return phasedFir(session, requiredPhase)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected inline fun <T> withScopeCleanup(scopes: MutableList<*>, crossinline l: () -> T): T {
|
||||||
|
val sizeBefore = scopes.size
|
||||||
|
return try {
|
||||||
|
l()
|
||||||
|
} finally {
|
||||||
|
val size = scopes.size
|
||||||
|
assert(size >= sizeBefore)
|
||||||
|
repeat(size - sizeBefore) {
|
||||||
|
scopes.let { it.removeAt(it.size - 1) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline fun <T> withFullBodyResolve(crossinline l: () -> T): T {
|
||||||
|
if (!implicitTypeOnly) return l()
|
||||||
|
implicitTypeOnly = false
|
||||||
|
return try {
|
||||||
|
l()
|
||||||
|
} finally {
|
||||||
|
implicitTypeOnly = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected inline val topLevelScopes: MutableList<FirScope> get() = components.topLevelScopes
|
||||||
|
protected inline val localScopes: MutableList<FirLocalScope> get() = components.localScopes
|
||||||
|
|
||||||
|
protected inline val noExpectedType: FirTypeRef get() = components.noExpectedType
|
||||||
|
|
||||||
|
protected inline val symbolProvider: FirSymbolProvider get() = components.symbolProvider
|
||||||
|
|
||||||
|
protected inline val returnTypeCalculator: ReturnTypeCalculator get() = components.returnTypeCalculator
|
||||||
|
protected inline val implicitReceiverStack: ImplicitReceiverStack get() = components.implicitReceiverStack
|
||||||
|
protected inline val inferenceComponents: InferenceComponents get() = components.inferenceComponents
|
||||||
|
protected inline val resolutionStageRunner: ResolutionStageRunner get() = components.resolutionStageRunner
|
||||||
|
protected inline val samResolver: FirSamResolver get() = components.samResolver
|
||||||
|
protected inline val callCompleter: FirCallCompleter get() = components.callCompleter
|
||||||
|
protected inline val dataFlowAnalyzer: FirDataFlowAnalyzer get() = components.dataFlowAnalyzer
|
||||||
|
protected inline val scopeSession: ScopeSession get() = components.scopeSession
|
||||||
|
protected inline val file: FirFile get() = components.file
|
||||||
|
|
||||||
|
class BodyResolveTransformerComponents(
|
||||||
|
override val session: FirSession,
|
||||||
|
override val scopeSession: ScopeSession,
|
||||||
|
val transformer: FirBodyResolveTransformer
|
||||||
|
) : BodyResolveComponents {
|
||||||
|
val topLevelScopes: MutableList<FirScope> = mutableListOf()
|
||||||
|
val localScopes: MutableList<FirLocalScope> = mutableListOf()
|
||||||
|
|
||||||
|
override val noExpectedType: FirTypeRef = FirImplicitTypeRefImpl(null)
|
||||||
|
|
||||||
|
override lateinit var file: FirFile
|
||||||
|
internal set
|
||||||
|
|
||||||
|
override val symbolProvider: FirSymbolProvider = session.firSymbolProvider
|
||||||
|
|
||||||
|
override val returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorWithJump(session, scopeSession)
|
||||||
|
override val implicitReceiverStack: ImplicitReceiverStack = ImplicitReceiverStackImpl()
|
||||||
|
override val inferenceComponents: InferenceComponents = inferenceComponents(session, returnTypeCalculator, scopeSession)
|
||||||
|
override val resolutionStageRunner: ResolutionStageRunner = ResolutionStageRunner(inferenceComponents)
|
||||||
|
override val samResolver: FirSamResolver = FirSamResolverImpl(session, scopeSession)
|
||||||
|
val callCompleter: FirCallCompleter = FirCallCompleter(transformer, this)
|
||||||
|
val dataFlowAnalyzer: FirDataFlowAnalyzer = FirDataFlowAnalyzer(this)
|
||||||
|
|
||||||
|
internal var _container: FirDeclaration? = null
|
||||||
|
override var container: FirDeclaration
|
||||||
|
get() = _container!!
|
||||||
|
private set(value) {
|
||||||
|
_container = value
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline fun <T> withContainer(declaration: FirDeclaration, crossinline f: () -> T): T {
|
||||||
|
val prevContainer = _container
|
||||||
|
_container = declaration
|
||||||
|
val result = f()
|
||||||
|
_container = prevContainer
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+220
@@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
* 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.transformers.body.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
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.ScopeSession
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.addImportingScopes
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.compose
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
|
open class FirBodyResolveTransformer(
|
||||||
|
session: FirSession,
|
||||||
|
phase: FirResolvePhase,
|
||||||
|
override var implicitTypeOnly: Boolean,
|
||||||
|
scopeSession: ScopeSession
|
||||||
|
) : FirAbstractBodyResolveTransformer(phase) {
|
||||||
|
private var packageFqName = FqName.ROOT
|
||||||
|
|
||||||
|
override val components: BodyResolveTransformerComponents = BodyResolveTransformerComponents(session, scopeSession, this)
|
||||||
|
|
||||||
|
private val expressionsTransformer = FirExpressionsResolveTransformer(this)
|
||||||
|
private val declarationsTransformer = FirDeclarationsResolveTransformer(this)
|
||||||
|
private val controlFlowStatementsTransformer = FirControlFlowStatementsResolveTransformer(this)
|
||||||
|
|
||||||
|
override fun transformFile(file: FirFile, data: Any?): CompositeTransformResult<FirFile> {
|
||||||
|
packageFqName = file.packageFqName
|
||||||
|
components.file = file
|
||||||
|
return withScopeCleanup(components.topLevelScopes) {
|
||||||
|
components.topLevelScopes.addImportingScopes(file, session, components.scopeSession)
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
super.transformFile(file, data) as CompositeTransformResult<FirFile>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <E : FirElement> transformElement(element: E, data: Any?): CompositeTransformResult<E> {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return (element.transformChildren(this, data) as E).compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformTypeRef(typeRef: FirTypeRef, data: Any?): CompositeTransformResult<FirTypeRef> {
|
||||||
|
return typeRef.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: Any?): CompositeTransformResult<FirTypeRef> {
|
||||||
|
if (data == null)
|
||||||
|
return implicitTypeRef.compose()
|
||||||
|
require(data is FirTypeRef)
|
||||||
|
return data.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------- Expressions -------------------------------------
|
||||||
|
|
||||||
|
override fun transformExpression(expression: FirExpression, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return expressionsTransformer.transformExpression(expression, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformQualifiedAccessExpression(
|
||||||
|
qualifiedAccessExpression: FirQualifiedAccessExpression,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirStatement> {
|
||||||
|
return expressionsTransformer.transformQualifiedAccessExpression(qualifiedAccessExpression, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformFunctionCall(functionCall: FirFunctionCall, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return expressionsTransformer.transformFunctionCall(functionCall, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformBlock(block: FirBlock, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return expressionsTransformer.transformBlock(block, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformThisReceiverExpression(
|
||||||
|
thisReceiverExpression: FirThisReceiverExpression,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirStatement> {
|
||||||
|
return expressionsTransformer.transformThisReceiverExpression(thisReceiverExpression, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformOperatorCall(operatorCall: FirOperatorCall, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return expressionsTransformer.transformOperatorCall(operatorCall, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return expressionsTransformer.transformTypeOperatorCall(typeOperatorCall, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformBinaryLogicExpression(
|
||||||
|
binaryLogicExpression: FirBinaryLogicExpression,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirStatement> {
|
||||||
|
return expressionsTransformer.transformBinaryLogicExpression(binaryLogicExpression, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformVariableAssignment(
|
||||||
|
variableAssignment: FirVariableAssignment,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirStatement> {
|
||||||
|
return expressionsTransformer.transformVariableAssignment(variableAssignment, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformGetClassCall(getClassCall: FirGetClassCall, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return expressionsTransformer.transformGetClassCall(getClassCall, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformWrappedDelegateExpression(
|
||||||
|
wrappedDelegateExpression: FirWrappedDelegateExpression,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirStatement> {
|
||||||
|
return expressionsTransformer.transformWrappedDelegateExpression(wrappedDelegateExpression, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> transformConstExpression(constExpression: FirConstExpression<T>, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return expressionsTransformer.transformConstExpression(constExpression, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return expressionsTransformer.transformAnnotationCall(annotationCall, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------- Declarations -------------------------------------
|
||||||
|
|
||||||
|
override fun transformDeclaration(declaration: FirDeclaration, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||||
|
return declarationsTransformer.transformDeclaration(declaration, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformProperty(property: FirProperty, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||||
|
return declarationsTransformer.transformProperty(property, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return declarationsTransformer.transformRegularClass(regularClass, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||||
|
return declarationsTransformer.transformSimpleFunction(simpleFunction, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <F : FirFunction<F>> transformFunction(function: FirFunction<F>, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return declarationsTransformer.transformFunction(function, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformConstructor(constructor: FirConstructor, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||||
|
return declarationsTransformer.transformConstructor(constructor, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformAnonymousInitializer(
|
||||||
|
anonymousInitializer: FirAnonymousInitializer,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirDeclaration> {
|
||||||
|
return declarationsTransformer.transformAnonymousInitializer(anonymousInitializer, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return declarationsTransformer.transformAnonymousFunction(anonymousFunction, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformValueParameter(valueParameter: FirValueParameter, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return declarationsTransformer.transformValueParameter(valueParameter, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------- Control flow statements -------------------------------------
|
||||||
|
|
||||||
|
override fun transformWhileLoop(whileLoop: FirWhileLoop, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return controlFlowStatementsTransformer.transformWhileLoop(whileLoop, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return controlFlowStatementsTransformer.transformDoWhileLoop(doWhileLoop, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformWhenExpression(whenExpression: FirWhenExpression, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return controlFlowStatementsTransformer.transformWhenExpression(whenExpression, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformWhenBranch(whenBranch: FirWhenBranch, data: Any?): CompositeTransformResult<FirWhenBranch> {
|
||||||
|
return controlFlowStatementsTransformer.transformWhenBranch(whenBranch, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformWhenSubjectExpression(
|
||||||
|
whenSubjectExpression: FirWhenSubjectExpression,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirStatement> {
|
||||||
|
return controlFlowStatementsTransformer.transformWhenSubjectExpression(whenSubjectExpression, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformTryExpression(tryExpression: FirTryExpression, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return controlFlowStatementsTransformer.transformTryExpression(tryExpression, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformCatch(catch: FirCatch, data: Any?): CompositeTransformResult<FirCatch> {
|
||||||
|
return controlFlowStatementsTransformer.transformCatch(catch, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <E : FirTargetElement> transformJump(jump: FirJump<E>, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return controlFlowStatementsTransformer.transformJump(jump, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformThrowExpression(throwExpression: FirThrowExpression, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return controlFlowStatementsTransformer.transformThrowExpression(throwExpression, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
fun <D> FirElement.visitNoTransform(transformer: FirTransformer<D>, data: D) {
|
||||||
|
val result = this.transform<FirElement, D>(transformer, data)
|
||||||
|
require(result.single === this) { "become ${result.single}: `${result.single.render()}`, was ${this}: `${this.render()}`" }
|
||||||
|
}
|
||||||
|
}
|
||||||
+98
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* 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.transformers.body.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
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.expressions.FirExpression
|
||||||
|
import org.jetbrains.kotlin.fir.renderWithType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.ConeInferenceContext
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.InferenceComponents
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowInferenceContext
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
||||||
|
import org.jetbrains.kotlin.fir.types.ErrorTypeConstructor
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.compose
|
||||||
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContextDelegate
|
||||||
|
|
||||||
|
class FirDesignatedBodyResolveTransformer(
|
||||||
|
private val designation: Iterator<FirElement>,
|
||||||
|
session: FirSession,
|
||||||
|
scopeSession: ScopeSession = ScopeSession(),
|
||||||
|
implicitTypeOnly: Boolean = true
|
||||||
|
) : FirBodyResolveTransformer(
|
||||||
|
session,
|
||||||
|
phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE,
|
||||||
|
implicitTypeOnly = implicitTypeOnly,
|
||||||
|
scopeSession = scopeSession
|
||||||
|
) {
|
||||||
|
override fun <E : FirElement> transformElement(element: E, data: Any?): CompositeTransformResult<E> {
|
||||||
|
if (designation.hasNext()) {
|
||||||
|
designation.next().visitNoTransform(this, data)
|
||||||
|
return element.compose()
|
||||||
|
}
|
||||||
|
return super.transformElement(element, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformDeclaration(declaration: FirDeclaration, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||||
|
return components.withContainer(declaration) {
|
||||||
|
declaration.replaceResolvePhase(transformerPhase)
|
||||||
|
transformElement(declaration, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Deprecated("It is temp", level = DeprecationLevel.WARNING, replaceWith = ReplaceWith("TODO(\"что-то нормальное\")"))
|
||||||
|
class FirImplicitTypeBodyResolveTransformerAdapter : FirTransformer<Nothing?>() {
|
||||||
|
private val scopeSession = ScopeSession()
|
||||||
|
|
||||||
|
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||||
|
return element.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
||||||
|
val transformer = FirBodyResolveTransformer(
|
||||||
|
file.session,
|
||||||
|
phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE,
|
||||||
|
implicitTypeOnly = true,
|
||||||
|
scopeSession = scopeSession
|
||||||
|
)
|
||||||
|
return file.transform(transformer, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Deprecated("It is temp", level = DeprecationLevel.WARNING, replaceWith = ReplaceWith("TODO(\"что-то нормальное\")"))
|
||||||
|
class FirBodyResolveTransformerAdapter : FirTransformer<Nothing?>() {
|
||||||
|
private val scopeSession = ScopeSession()
|
||||||
|
|
||||||
|
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||||
|
return element.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
||||||
|
// Despite of real phase is EXPRESSIONS, we state IMPLICIT_TYPES here, because DECLARATIONS previous phase is OK for us
|
||||||
|
val transformer = FirBodyResolveTransformer(
|
||||||
|
file.session,
|
||||||
|
phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE,
|
||||||
|
implicitTypeOnly = false,
|
||||||
|
scopeSession = scopeSession
|
||||||
|
)
|
||||||
|
return file.transform(transformer, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
+175
@@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* 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.transformers.body.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirTargetElement
|
||||||
|
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.FirResolvedCallableReference
|
||||||
|
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
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||||
|
|
||||||
|
class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
||||||
|
FirPartialBodyResolveTransformer(transformer) {
|
||||||
|
|
||||||
|
private val syntheticCallGenerator: FirSyntheticCallGenerator = FirSyntheticCallGenerator(components)
|
||||||
|
private val whenExhaustivenessTransformer = FirWhenExhaustivenessTransformer(components)
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------- Loops -------------------------------
|
||||||
|
|
||||||
|
override fun transformWhileLoop(whileLoop: FirWhileLoop, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
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<FirStatement> {
|
||||||
|
return doWhileLoop.also(dataFlowAnalyzer::enterDoWhileLoop)
|
||||||
|
.transformBlock(transformer, data).also(dataFlowAnalyzer::enterDoWhileLoopCondition)
|
||||||
|
.transformCondition(transformer, data).also(dataFlowAnalyzer::exitDoWhileLoop)
|
||||||
|
.transformOtherChildren(transformer, data).compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- When expressions -------------------------------
|
||||||
|
|
||||||
|
override fun transformWhenExpression(whenExpression: FirWhenExpression, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
if (whenExpression.calleeReference is FirResolvedCallableReference && whenExpression.resultType !is FirImplicitTypeRef) {
|
||||||
|
return whenExpression.compose()
|
||||||
|
}
|
||||||
|
dataFlowAnalyzer.enterWhenExpression(whenExpression)
|
||||||
|
return withScopeCleanup(localScopes) with@{
|
||||||
|
if (whenExpression.subjectVariable != null) {
|
||||||
|
localScopes += FirLocalScope()
|
||||||
|
}
|
||||||
|
@Suppress("NAME_SHADOWING")
|
||||||
|
var whenExpression = whenExpression.transformSubject(transformer, noExpectedType)
|
||||||
|
|
||||||
|
when {
|
||||||
|
whenExpression.branches.isEmpty() -> {
|
||||||
|
}
|
||||||
|
whenExpression.isOneBranch() -> {
|
||||||
|
whenExpression = whenExpression.transformBranches(transformer, noExpectedType)
|
||||||
|
whenExpression.resultType = whenExpression.branches.first().result.resultType
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
whenExpression = whenExpression.transformBranches(transformer, null)
|
||||||
|
|
||||||
|
whenExpression = syntheticCallGenerator.generateCalleeForWhenExpression(whenExpression) ?: run {
|
||||||
|
dataFlowAnalyzer.exitWhenExpression(whenExpression)
|
||||||
|
whenExpression.resultType = FirErrorTypeRefImpl(null, "")
|
||||||
|
return@with whenExpression.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
val expectedTypeRef = data as FirTypeRef?
|
||||||
|
whenExpression = callCompleter.completeCall(whenExpression, expectedTypeRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
whenExpression = whenExpression.transformSingle(whenExhaustivenessTransformer, null)
|
||||||
|
dataFlowAnalyzer.exitWhenExpression(whenExpression)
|
||||||
|
whenExpression = whenExpression.replaceReturnTypeIfNotExhaustive()
|
||||||
|
whenExpression.compose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirWhenExpression.replaceReturnTypeIfNotExhaustive(): FirWhenExpression {
|
||||||
|
if (!isExhaustive) {
|
||||||
|
resultType = resultType.resolvedTypeFromPrototype(session.builtinTypes.unitType.type)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirWhenExpression.isOneBranch(): Boolean {
|
||||||
|
if (branches.size == 1) return true
|
||||||
|
if (branches.size > 2) return false
|
||||||
|
val lastBranch = branches.last()
|
||||||
|
return lastBranch.condition is FirElseIfTrueCondition && lastBranch.result is FirEmptyExpressionBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformWhenBranch(whenBranch: FirWhenBranch, data: Any?): CompositeTransformResult<FirWhenBranch> {
|
||||||
|
return whenBranch.also { dataFlowAnalyzer.enterWhenBranchCondition(whenBranch) }
|
||||||
|
.transformCondition(transformer, data).also { dataFlowAnalyzer.exitWhenBranchCondition(it) }
|
||||||
|
.transformResult(transformer, data).also { dataFlowAnalyzer.exitWhenBranchResult(it) }
|
||||||
|
.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformWhenSubjectExpression(
|
||||||
|
whenSubjectExpression: FirWhenSubjectExpression,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirStatement> {
|
||||||
|
val parentWhen = whenSubjectExpression.whenSubject.whenExpression
|
||||||
|
val subjectType = parentWhen.subject?.resultType ?: parentWhen.subjectVariable?.returnTypeRef
|
||||||
|
if (subjectType != null) {
|
||||||
|
whenSubjectExpression.resultType = subjectType
|
||||||
|
}
|
||||||
|
return whenSubjectExpression.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- Try/catch expressions -------------------------------
|
||||||
|
|
||||||
|
override fun transformTryExpression(tryExpression: FirTryExpression, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
if (tryExpression.calleeReference is FirResolvedCallableReference && tryExpression.resultType !is FirImplicitTypeRef) {
|
||||||
|
return tryExpression.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
dataFlowAnalyzer.enterTryExpression(tryExpression)
|
||||||
|
tryExpression.transformTryBlock(transformer, null)
|
||||||
|
dataFlowAnalyzer.exitTryMainBlock(tryExpression)
|
||||||
|
tryExpression.transformCatches(this, null)
|
||||||
|
|
||||||
|
@Suppress("NAME_SHADOWING")
|
||||||
|
var result = syntheticCallGenerator.generateCalleeForTryExpression(tryExpression)?.let {
|
||||||
|
val expectedTypeRef = data as FirTypeRef?
|
||||||
|
callCompleter.completeCall(it, expectedTypeRef)
|
||||||
|
} ?: run {
|
||||||
|
tryExpression.resultType = FirErrorTypeRefImpl(null, "")
|
||||||
|
tryExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
result = if (result.finallyBlock != null) {
|
||||||
|
result.also(dataFlowAnalyzer::enterFinallyBlock)
|
||||||
|
.transformFinallyBlock(transformer, noExpectedType)
|
||||||
|
.also(dataFlowAnalyzer::exitFinallyBlock)
|
||||||
|
} else {
|
||||||
|
result
|
||||||
|
}
|
||||||
|
dataFlowAnalyzer.exitTryExpression(result)
|
||||||
|
return result.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformCatch(catch: FirCatch, data: Any?): CompositeTransformResult<FirCatch> {
|
||||||
|
dataFlowAnalyzer.enterCatchClause(catch)
|
||||||
|
return withScopeCleanup(localScopes) {
|
||||||
|
localScopes += FirLocalScope()
|
||||||
|
catch.transformParameter(transformer, noExpectedType)
|
||||||
|
catch.transformBlock(transformer, null)
|
||||||
|
}.also { dataFlowAnalyzer.exitCatchClause(it) }.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- Jumps -------------------------------
|
||||||
|
|
||||||
|
override fun <E : FirTargetElement> transformJump(jump: FirJump<E>, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
val result = transformer.transformExpression(jump, data)
|
||||||
|
dataFlowAnalyzer.exitJump(jump)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformThrowExpression(throwExpression: FirThrowExpression, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return transformer.transformExpression(throwExpression, data).also {
|
||||||
|
dataFlowAnalyzer.exitThrowExceptionNode(it.single as FirThrowExpression)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+421
@@ -0,0 +1,421 @@
|
|||||||
|
/*
|
||||||
|
* 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.transformers.body.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.copy
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.extractLambdaInfoFromFunctionalType
|
||||||
|
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.resolvedTypeFromPrototype
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirComputingImplicitTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.compose
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
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<FirDeclaration> {
|
||||||
|
return components.withContainer(declaration) {
|
||||||
|
declaration.replaceResolvePhase(transformerPhase)
|
||||||
|
transformer.transformElement(declaration, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformProperty(property: FirProperty, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||||
|
if (property.isLocal) return transformLocalVariable(property, data)
|
||||||
|
val returnTypeRef = property.returnTypeRef
|
||||||
|
if (returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly) return property.compose()
|
||||||
|
if (property.resolvePhase == transformerPhase) return property.compose()
|
||||||
|
dataFlowAnalyzer.enterProperty(property)
|
||||||
|
if (returnTypeRef is FirImplicitTypeRef) {
|
||||||
|
property.transformReturnTypeRef(StoreType, FirComputingImplicitTypeRef)
|
||||||
|
}
|
||||||
|
return withFullBodyResolve {
|
||||||
|
withScopeCleanup(localScopes) {
|
||||||
|
localScopes.addIfNotNull(primaryConstructorParametersScope)
|
||||||
|
components.withContainer(property) {
|
||||||
|
property.transformChildrenWithoutAccessors(returnTypeRef)
|
||||||
|
if (property.initializer != null) {
|
||||||
|
storeVariableReturnType(property)
|
||||||
|
}
|
||||||
|
withScopeCleanup(localScopes) {
|
||||||
|
localScopes.add(FirLocalScope().apply {
|
||||||
|
storeBackingField(property)
|
||||||
|
})
|
||||||
|
property.transformAccessors()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
property.replaceResolvePhase(transformerPhase)
|
||||||
|
val controlFlowGraph = dataFlowAnalyzer.exitProperty(property)
|
||||||
|
property.transformControlFlowGraphReference(ControlFlowGraphReferenceTransformer, controlFlowGraph)
|
||||||
|
property.compose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transformLocalVariable(variable: FirProperty, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||||
|
assert(variable.isLocal)
|
||||||
|
variable.transformOtherChildren(transformer, variable.returnTypeRef)
|
||||||
|
if (variable.initializer != null) {
|
||||||
|
storeVariableReturnType(variable)
|
||||||
|
}
|
||||||
|
variable.transformAccessors()
|
||||||
|
localScopes.lastOrNull()?.storeDeclaration(variable)
|
||||||
|
variable.replaceResolvePhase(transformerPhase)
|
||||||
|
dataFlowAnalyzer.exitVariableDeclaration(variable)
|
||||||
|
return variable.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirProperty.transformChildrenWithoutAccessors(returnTypeRef: FirTypeRef): FirProperty {
|
||||||
|
return transformReturnTypeRef(transformer, returnTypeRef).
|
||||||
|
transformOtherChildren(transformer, returnTypeRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <F : FirVariable<F>> FirVariable<F>.transformAccessors() {
|
||||||
|
var enhancedTypeRef = returnTypeRef
|
||||||
|
getter?.let {
|
||||||
|
transformAccessor(it, enhancedTypeRef, this)
|
||||||
|
}
|
||||||
|
if (returnTypeRef is FirImplicitTypeRef) {
|
||||||
|
storeVariableReturnType(this)
|
||||||
|
enhancedTypeRef = returnTypeRef
|
||||||
|
}
|
||||||
|
setter?.let {
|
||||||
|
it.valueParameters[0].transformReturnTypeRef(StoreType, enhancedTypeRef)
|
||||||
|
transformAccessor(it, enhancedTypeRef, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transformAccessor(
|
||||||
|
accessor: FirPropertyAccessor,
|
||||||
|
enhancedTypeRef: FirTypeRef,
|
||||||
|
owner: FirVariable<*>
|
||||||
|
) {
|
||||||
|
if (accessor is FirDefaultPropertyAccessor || accessor.body == null) {
|
||||||
|
transformFunction(accessor, enhancedTypeRef)
|
||||||
|
}
|
||||||
|
val returnTypeRef = accessor.returnTypeRef
|
||||||
|
if (returnTypeRef is FirImplicitTypeRef && enhancedTypeRef !is FirResolvedTypeRef) {
|
||||||
|
accessor.transformReturnTypeRef(StoreType, FirComputingImplicitTypeRef)
|
||||||
|
}
|
||||||
|
val expectedReturnTypeRef = if (enhancedTypeRef is FirResolvedTypeRef && returnTypeRef !is FirResolvedTypeRef) {
|
||||||
|
enhancedTypeRef
|
||||||
|
} else {
|
||||||
|
returnTypeRef
|
||||||
|
}
|
||||||
|
val receiverTypeRef = owner.receiverTypeRef
|
||||||
|
if (receiverTypeRef != null) {
|
||||||
|
withLabelAndReceiverType(owner.name, owner, receiverTypeRef.coneTypeUnsafe()) {
|
||||||
|
transformFunctionWithGivenSignature(accessor, expectedReturnTypeRef)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
transformFunctionWithGivenSignature(accessor, expectedReturnTypeRef)
|
||||||
|
} as CompositeTransformResult<FirStatement>
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
val oldConstructorScope = primaryConstructorParametersScope
|
||||||
|
primaryConstructorParametersScope = null
|
||||||
|
val type = regularClass.defaultType()
|
||||||
|
val result = withLabelAndReceiverType(regularClass.name, regularClass, type) {
|
||||||
|
val constructor = regularClass.declarations.firstOrNull() as? FirConstructor
|
||||||
|
if (constructor?.isPrimary == true) {
|
||||||
|
primaryConstructorParametersScope = FirLocalScope().apply {
|
||||||
|
constructor.valueParameters.forEach { this.storeDeclaration(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transformDeclaration(regularClass, data)
|
||||||
|
}
|
||||||
|
primaryConstructorParametersScope = oldConstructorScope
|
||||||
|
return result as CompositeTransformResult<FirStatement>
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transformAnonymousFunctionWithLambdaResolution(
|
||||||
|
anonymousFunction: FirAnonymousFunction, lambdaResolution: 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 body = result.body
|
||||||
|
return if (result.returnTypeRef is FirImplicitTypeRef && body != null) {
|
||||||
|
result.transformReturnTypeRef(transformer, body.resultType)
|
||||||
|
result
|
||||||
|
} else {
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val label = anonymousFunction.label
|
||||||
|
return if (label != null && receiverTypeRef != null) {
|
||||||
|
withLabelAndReceiverType(Name.identifier(label.name), anonymousFunction, receiverTypeRef.coneTypeUnsafe()) {
|
||||||
|
transform()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
transform()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class LambdaResolution(val expectedReturnTypeRef: FirResolvedTypeRef?)
|
||||||
|
|
||||||
|
override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||||
|
val returnTypeRef = simpleFunction.returnTypeRef
|
||||||
|
if ((returnTypeRef !is FirImplicitTypeRef) && implicitTypeOnly) {
|
||||||
|
return simpleFunction.compose()
|
||||||
|
}
|
||||||
|
return withFullBodyResolve {
|
||||||
|
if (returnTypeRef is FirImplicitTypeRef) {
|
||||||
|
simpleFunction.transformReturnTypeRef(StoreType, FirComputingImplicitTypeRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
val receiverTypeRef = simpleFunction.receiverTypeRef
|
||||||
|
if (receiverTypeRef != null) {
|
||||||
|
withLabelAndReceiverType(simpleFunction.name, simpleFunction, receiverTypeRef.coneTypeUnsafe()) {
|
||||||
|
transformFunctionWithGivenSignature(simpleFunction, returnTypeRef)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
transformFunctionWithGivenSignature(simpleFunction, returnTypeRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transformFunctionWithGivenSignature(
|
||||||
|
function: FirFunction<*>,
|
||||||
|
returnTypeRef: FirTypeRef
|
||||||
|
): CompositeTransformResult<FirDeclaration> {
|
||||||
|
if (function is FirSimpleFunction) {
|
||||||
|
localScopes.lastOrNull()?.storeDeclaration(function)
|
||||||
|
}
|
||||||
|
val result = transformFunction(function, returnTypeRef).single as FirFunction<*>
|
||||||
|
val body = result.body
|
||||||
|
return if (result.returnTypeRef is FirImplicitTypeRef && body != null) {
|
||||||
|
result.transformReturnTypeRef(transformer, body.resultType)
|
||||||
|
result
|
||||||
|
} else {
|
||||||
|
result
|
||||||
|
}.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <F : FirFunction<F>> transformFunction(function: FirFunction<F>, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return withScopeCleanup(localScopes) {
|
||||||
|
localScopes += FirLocalScope()
|
||||||
|
dataFlowAnalyzer.enterFunction(function)
|
||||||
|
transformDeclaration(function, data).also {
|
||||||
|
val result = it.single as FirFunction<*>
|
||||||
|
dataFlowAnalyzer.exitFunction(result)?.let { controlFlowGraph ->
|
||||||
|
result.transformControlFlowGraphReference(ControlFlowGraphReferenceTransformer, controlFlowGraph)
|
||||||
|
}
|
||||||
|
} as CompositeTransformResult<FirStatement>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformConstructor(constructor: FirConstructor, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||||
|
if (implicitTypeOnly) return constructor.compose()
|
||||||
|
return transformFunction(constructor, data) as CompositeTransformResult<FirDeclaration>
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformAnonymousInitializer(
|
||||||
|
anonymousInitializer: FirAnonymousInitializer,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirDeclaration> {
|
||||||
|
if (implicitTypeOnly) return anonymousInitializer.compose()
|
||||||
|
return withScopeCleanup(localScopes) {
|
||||||
|
dataFlowAnalyzer.enterInitBlock(anonymousInitializer)
|
||||||
|
localScopes.addIfNotNull(primaryConstructorParametersScope)
|
||||||
|
transformDeclaration(anonymousInitializer, data).also {
|
||||||
|
dataFlowAnalyzer.exitInitBlock(it.single as FirAnonymousInitializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformValueParameter(valueParameter: FirValueParameter, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
return when (data) {
|
||||||
|
null -> {
|
||||||
|
anonymousFunction.compose()
|
||||||
|
}
|
||||||
|
is LambdaResolution -> {
|
||||||
|
transformAnonymousFunctionWithLambdaResolution(anonymousFunction, data).compose()
|
||||||
|
}
|
||||||
|
is FirTypeRef -> {
|
||||||
|
val resolvedLambdaAtom = (data as? FirResolvedTypeRef)?.let {
|
||||||
|
extractLambdaInfoFromFunctionalType(
|
||||||
|
it.type, it, anonymousFunction
|
||||||
|
)
|
||||||
|
}
|
||||||
|
var af = anonymousFunction
|
||||||
|
val valueParameters =
|
||||||
|
if (resolvedLambdaAtom == null) af.valueParameters
|
||||||
|
else {
|
||||||
|
val singleParameterType = resolvedLambdaAtom.parameters.singleOrNull()
|
||||||
|
val itParam = when {
|
||||||
|
af.valueParameters.isEmpty() && singleParameterType != null -> {
|
||||||
|
val name = Name.identifier("it")
|
||||||
|
FirValueParameterImpl(
|
||||||
|
null,
|
||||||
|
session,
|
||||||
|
FirResolvedTypeRefImpl(null, singleParameterType),
|
||||||
|
name,
|
||||||
|
FirVariableSymbol(name),
|
||||||
|
defaultValue = null,
|
||||||
|
isCrossinline = false,
|
||||||
|
isNoinline = false,
|
||||||
|
isVararg = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
if (itParam != null) {
|
||||||
|
listOf(itParam)
|
||||||
|
} else {
|
||||||
|
af.valueParameters.mapIndexed { index, param ->
|
||||||
|
if (param.returnTypeRef is FirResolvedTypeRef) {
|
||||||
|
param
|
||||||
|
} else {
|
||||||
|
param.transformReturnTypeRef(
|
||||||
|
StoreType,
|
||||||
|
param.returnTypeRef.resolvedTypeFromPrototype(
|
||||||
|
resolvedLambdaAtom.parameters[index]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
param
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
val returnTypeRefFromResolvedAtom = resolvedLambdaAtom?.returnType?.let { af.returnTypeRef.resolvedTypeFromPrototype(it) }
|
||||||
|
af = af.copy(
|
||||||
|
receiverTypeRef = af.receiverTypeRef?.takeIf { it !is FirImplicitTypeRef }
|
||||||
|
?: resolvedLambdaAtom?.receiver?.let { af.receiverTypeRef?.resolvedTypeFromPrototype(it) },
|
||||||
|
valueParameters = valueParameters,
|
||||||
|
returnTypeRef = (af.returnTypeRef as? FirResolvedTypeRef)
|
||||||
|
?: returnTypeRefFromResolvedAtom
|
||||||
|
?: af.returnTypeRef
|
||||||
|
)
|
||||||
|
af = af.transformValueParameters(ImplicitToErrorTypeTransformer, null)
|
||||||
|
val bodyExpectedType = returnTypeRefFromResolvedAtom ?: data
|
||||||
|
af = transformFunction(af, bodyExpectedType).single as FirAnonymousFunction
|
||||||
|
af = af.copy(
|
||||||
|
returnTypeRef = af.body?.resultType ?: FirErrorTypeRefImpl(af.psi, "No result type for lambda")
|
||||||
|
)
|
||||||
|
af.replaceTypeRef(af.constructFunctionalTypeRef(session))
|
||||||
|
af.compose()
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
transformFunction(anonymousFunction, data).single.compose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun <T> withLabelAndReceiverType(
|
||||||
|
labelName: Name,
|
||||||
|
owner: FirDeclaration,
|
||||||
|
type: ConeKotlinType,
|
||||||
|
block: () -> T
|
||||||
|
): T {
|
||||||
|
val implicitReceiverValue = when (owner) {
|
||||||
|
is FirRegularClass -> {
|
||||||
|
ImplicitDispatchReceiverValue(owner.symbol, type, symbolProvider, session, scopeSession)
|
||||||
|
}
|
||||||
|
is FirFunction<*> -> {
|
||||||
|
ImplicitExtensionReceiverValue(owner.symbol, type, session, scopeSession)
|
||||||
|
}
|
||||||
|
is FirVariable<*> -> {
|
||||||
|
ImplicitExtensionReceiverValue(owner.symbol, type, session, scopeSession)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
throw IllegalArgumentException("Incorrect label & receiver owner: ${owner.javaClass}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
implicitReceiverStack.add(labelName, implicitReceiverValue)
|
||||||
|
val result = block()
|
||||||
|
implicitReceiverStack.pop(labelName)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun storeVariableReturnType(variable: FirVariable<*>) {
|
||||||
|
val initializer = variable.initializer
|
||||||
|
if (variable.returnTypeRef is FirImplicitTypeRef) {
|
||||||
|
when {
|
||||||
|
initializer != null -> {
|
||||||
|
variable.transformReturnTypeRef(
|
||||||
|
transformer,
|
||||||
|
when (val resultType = initializer.resultType) {
|
||||||
|
is FirImplicitTypeRef -> FirErrorTypeRefImpl(
|
||||||
|
null,
|
||||||
|
"No result type for initializer"
|
||||||
|
)
|
||||||
|
else -> resultType
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
variable.getter != null && variable.getter !is FirDefaultPropertyAccessor -> {
|
||||||
|
variable.transformReturnTypeRef(
|
||||||
|
transformer,
|
||||||
|
when (val resultType = variable.getter?.returnTypeRef) {
|
||||||
|
is FirImplicitTypeRef -> FirErrorTypeRefImpl(
|
||||||
|
null,
|
||||||
|
"No result type for getter"
|
||||||
|
)
|
||||||
|
else -> resultType
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
variable.transformReturnTypeRef(
|
||||||
|
transformer, FirErrorTypeRefImpl(null, "Cannot infer variable type without initializer / getter / delegate")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (variable.getter?.returnTypeRef is FirImplicitTypeRef) {
|
||||||
|
variable.getter?.transformReturnTypeRef(transformer, variable.returnTypeRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object ImplicitToErrorTypeTransformer : FirTransformer<Nothing?>() {
|
||||||
|
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||||
|
return element.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformValueParameter(valueParameter: FirValueParameter, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||||
|
if (valueParameter.returnTypeRef is FirImplicitTypeRef) {
|
||||||
|
valueParameter.transformReturnTypeRef(
|
||||||
|
StoreType,
|
||||||
|
valueParameter.returnTypeRef.resolvedTypeFromPrototype(ConeKotlinErrorType("No type for parameter"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return valueParameter.compose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+352
@@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
* 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.transformers.body.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.contracts.description.InvocationKind
|
||||||
|
import org.jetbrains.kotlin.fir.*
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionWithSmartcastImpl
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirDelegateFieldReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.impl.FirExplicitThisReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||||
|
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.firSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.typeFromCallee
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.withNullability
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.invoke
|
||||||
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.compose
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
|
class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : FirPartialBodyResolveTransformer(transformer) {
|
||||||
|
private val qualifiedResolver: FirQualifiedNameResolver = FirQualifiedNameResolver(components)
|
||||||
|
private val callResolver: FirCallResolver = FirCallResolver(
|
||||||
|
this,
|
||||||
|
topLevelScopes,
|
||||||
|
localScopes,
|
||||||
|
implicitReceiverStack,
|
||||||
|
qualifiedResolver
|
||||||
|
)
|
||||||
|
|
||||||
|
private inline val builtinTypes: BuiltinTypes get() = session.builtinTypes
|
||||||
|
|
||||||
|
override fun transformExpression(expression: FirExpression, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
if (expression.resultType is FirImplicitTypeRef && expression !is FirWrappedExpression) {
|
||||||
|
val type = FirErrorTypeRefImpl(expression.psi, "Type calculating for ${expression::class} is not supported")
|
||||||
|
expression.resultType = type
|
||||||
|
}
|
||||||
|
return (expression.transformChildren(transformer, data) as FirStatement).compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformQualifiedAccessExpression(
|
||||||
|
qualifiedAccessExpression: FirQualifiedAccessExpression,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirStatement> {
|
||||||
|
var result = when (val callee = qualifiedAccessExpression.calleeReference) {
|
||||||
|
is FirExplicitThisReference -> {
|
||||||
|
val labelName = callee.labelName
|
||||||
|
val implicitReceiver = implicitReceiverStack[labelName]
|
||||||
|
implicitReceiver?.boundSymbol?.let {
|
||||||
|
callee.replaceBoundSymbol(it)
|
||||||
|
}
|
||||||
|
qualifiedAccessExpression.resultType = FirResolvedTypeRefImpl(
|
||||||
|
null, implicitReceiver?.type ?: ConeKotlinErrorType("Unresolved this@$labelName")
|
||||||
|
)
|
||||||
|
qualifiedAccessExpression
|
||||||
|
}
|
||||||
|
is FirSuperReference -> {
|
||||||
|
if (callee.superTypeRef is FirResolvedTypeRef) {
|
||||||
|
qualifiedAccessExpression.resultType = callee.superTypeRef
|
||||||
|
} else {
|
||||||
|
val superTypeRef = implicitReceiverStack.lastDispatchReceiver()
|
||||||
|
?.boundSymbol?.phasedFir?.superTypeRefs?.firstOrNull()
|
||||||
|
?: FirErrorTypeRefImpl(qualifiedAccessExpression.psi, "No super type")
|
||||||
|
qualifiedAccessExpression.resultType = superTypeRef
|
||||||
|
callee.replaceSuperTypeRef(superTypeRef)
|
||||||
|
}
|
||||||
|
qualifiedAccessExpression
|
||||||
|
}
|
||||||
|
is FirDelegateFieldReference -> {
|
||||||
|
val delegateFieldSymbol = callee.resolvedSymbol
|
||||||
|
qualifiedAccessExpression.resultType = delegateFieldSymbol.delegate.typeRef
|
||||||
|
qualifiedAccessExpression
|
||||||
|
}
|
||||||
|
is FirResolvedCallableReference -> {
|
||||||
|
if (qualifiedAccessExpression.typeRef !is FirResolvedTypeRef) {
|
||||||
|
storeTypeFromCallee(qualifiedAccessExpression)
|
||||||
|
}
|
||||||
|
qualifiedAccessExpression
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
val transformedCallee = callResolver.resolveVariableAccessAndSelectCandidate(qualifiedAccessExpression, file)
|
||||||
|
// 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)
|
||||||
|
} else {
|
||||||
|
transformedCallee
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result is FirQualifiedAccessExpression) {
|
||||||
|
result = transformQualifiedAccessUsingSmartcastInfo(result)
|
||||||
|
dataFlowAnalyzer.exitQualifiedAccessExpression(result)
|
||||||
|
}
|
||||||
|
return result.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transformQualifiedAccessUsingSmartcastInfo(qualifiedAccessExpression: FirQualifiedAccessExpression): FirQualifiedAccessExpression {
|
||||||
|
val typesFromSmartCast = dataFlowAnalyzer.getTypeUsingSmartcastInfo(qualifiedAccessExpression) ?: return qualifiedAccessExpression
|
||||||
|
val allTypes = typesFromSmartCast.toMutableList().also {
|
||||||
|
it += qualifiedAccessExpression.resultType.coneTypeUnsafe<ConeKotlinType>()
|
||||||
|
}
|
||||||
|
val intersectedType = ConeTypeIntersector.intersectTypes(inferenceComponents.ctx as ConeInferenceContext, allTypes)
|
||||||
|
// TODO: add check that intersectedType is not equal to original type
|
||||||
|
val intersectedTypeRef = FirResolvedTypeRefImpl(qualifiedAccessExpression.resultType.psi, intersectedType).apply {
|
||||||
|
annotations += qualifiedAccessExpression.resultType.annotations
|
||||||
|
}
|
||||||
|
return FirExpressionWithSmartcastImpl(qualifiedAccessExpression, intersectedTypeRef, typesFromSmartCast)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformFunctionCall(functionCall: FirFunctionCall, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
dataFlowAnalyzer.enterFunctionCall(functionCall)
|
||||||
|
if (functionCall.calleeReference is FirResolvedCallableReference && functionCall.resultType is FirImplicitTypeRef) {
|
||||||
|
storeTypeFromCallee(functionCall)
|
||||||
|
}
|
||||||
|
if (functionCall.calleeReference !is FirSimpleNamedReference) return functionCall.compose()
|
||||||
|
functionCall.transform<FirFunctionCall, InvocationKind?>(InvocationKindTransformer, null)
|
||||||
|
val expectedTypeRef = data as FirTypeRef?
|
||||||
|
val completeInference =
|
||||||
|
try {
|
||||||
|
val initialExplicitReceiver = functionCall.explicitReceiver
|
||||||
|
val resultExpression = callResolver.resolveCallAndSelectCandidate(functionCall, expectedTypeRef, file)
|
||||||
|
val resultExplicitReceiver = resultExpression.explicitReceiver
|
||||||
|
if (initialExplicitReceiver !== resultExplicitReceiver && resultExplicitReceiver is FirQualifiedAccess) {
|
||||||
|
// name.invoke() case
|
||||||
|
callCompleter.completeCall(resultExplicitReceiver, noExpectedType)
|
||||||
|
}
|
||||||
|
callCompleter.completeCall(resultExpression, expectedTypeRef)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
throw RuntimeException("While resolving call ${functionCall.render()}", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
dataFlowAnalyzer.exitFunctionCall(completeInference)
|
||||||
|
return completeInference.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformBlock(block: FirBlock, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
dataFlowAnalyzer.enterBlock(block)
|
||||||
|
@Suppress("NAME_SHADOWING")
|
||||||
|
val block = block.transformChildren(transformer, data) as FirBlock
|
||||||
|
val statement = block.statements.lastOrNull()
|
||||||
|
|
||||||
|
val resultExpression = when (statement) {
|
||||||
|
is FirReturnExpression -> statement.result
|
||||||
|
is FirExpression -> statement
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
block.resultType = if (resultExpression == null) {
|
||||||
|
FirImplicitUnitTypeRef(block.psi)
|
||||||
|
} else {
|
||||||
|
(resultExpression.resultType as? FirResolvedTypeRef) ?: FirErrorTypeRefImpl(null, "No type for block")
|
||||||
|
}
|
||||||
|
dataFlowAnalyzer.exitBlock(block)
|
||||||
|
return block.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformThisReceiverExpression(
|
||||||
|
thisReceiverExpression: FirThisReceiverExpression,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirStatement> {
|
||||||
|
return transformQualifiedAccessExpression(thisReceiverExpression, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformOperatorCall(operatorCall: FirOperatorCall, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
val result = if (operatorCall.operation in FirOperation.BOOLEANS) {
|
||||||
|
(operatorCall.transformChildren(transformer, noExpectedType) as FirOperatorCall).also {
|
||||||
|
it.resultType = builtinTypes.booleanType
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
transformExpression(operatorCall, data).single
|
||||||
|
} as FirOperatorCall
|
||||||
|
dataFlowAnalyzer.exitOperatorCall(result)
|
||||||
|
return result.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
val symbolProvider = session.firSymbolProvider
|
||||||
|
val resolved = transformExpression(typeOperatorCall, data).single
|
||||||
|
when ((resolved as FirTypeOperatorCall).operation) {
|
||||||
|
FirOperation.IS, FirOperation.NOT_IS -> {
|
||||||
|
resolved.resultType = FirResolvedTypeRefImpl(
|
||||||
|
null,
|
||||||
|
StandardClassIds.Boolean(symbolProvider).constructType(emptyArray(), isNullable = false)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
FirOperation.AS -> {
|
||||||
|
resolved.resultType = resolved.conversionTypeRef
|
||||||
|
}
|
||||||
|
FirOperation.SAFE_AS -> {
|
||||||
|
resolved.resultType =
|
||||||
|
resolved.conversionTypeRef.withReplacedConeType(
|
||||||
|
resolved.conversionTypeRef.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> error("Unknown type operator")
|
||||||
|
}
|
||||||
|
dataFlowAnalyzer.exitTypeOperatorCall(typeOperatorCall)
|
||||||
|
return resolved.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformBinaryLogicExpression(
|
||||||
|
binaryLogicExpression: FirBinaryLogicExpression,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirStatement> {
|
||||||
|
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)
|
||||||
|
|
||||||
|
LogicOperationKind.OR ->
|
||||||
|
binaryLogicExpression.also(dataFlowAnalyzer::enterBinaryOr)
|
||||||
|
.transformLeftOperand(this, booleanType).also(dataFlowAnalyzer::exitLeftBinaryOrArgument)
|
||||||
|
.transformRightOperand(this, booleanType).also(dataFlowAnalyzer::exitBinaryOr)
|
||||||
|
}.transformOtherChildren(transformer, booleanType).also {
|
||||||
|
it.resultType = booleanType
|
||||||
|
}.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformVariableAssignment(
|
||||||
|
variableAssignment: FirVariableAssignment,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirStatement> {
|
||||||
|
// val resolvedAssignment = transformCallee(variableAssignment)
|
||||||
|
val resolvedAssignment = callResolver.resolveVariableAccessAndSelectCandidate(variableAssignment, file)
|
||||||
|
val result = if (resolvedAssignment is FirVariableAssignment) {
|
||||||
|
val completeAssignment = callCompleter.completeCall(resolvedAssignment, noExpectedType)
|
||||||
|
val expectedType = components.typeFromCallee(completeAssignment)
|
||||||
|
completeAssignment.transformRValue(transformer, expectedType)
|
||||||
|
} else {
|
||||||
|
// This can happen in erroneous code only
|
||||||
|
resolvedAssignment
|
||||||
|
}
|
||||||
|
// TODO: maybe replace with FirAbstractAssignment for performance?
|
||||||
|
(result as? FirVariableAssignment)?.let { dataFlowAnalyzer.exitVariableAssignment(it) }
|
||||||
|
return result.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformGetClassCall(getClassCall: FirGetClassCall, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
val transformedGetClassCall = transformExpression(getClassCall, data).single as FirGetClassCall
|
||||||
|
val kClassSymbol = ClassId.fromString("kotlin/reflect/KClass")(session.firSymbolProvider)
|
||||||
|
|
||||||
|
val typeOfExpression = when (val lhs = transformedGetClassCall.argument) {
|
||||||
|
is FirResolvedQualifier -> {
|
||||||
|
val classId = lhs.classId
|
||||||
|
if (classId != null) {
|
||||||
|
val symbol = symbolProvider.getClassLikeSymbolByFqName(classId)!!
|
||||||
|
// TODO: Unify logic?
|
||||||
|
symbol.constructType(
|
||||||
|
Array(symbol.phasedFir.typeParameters.size) {
|
||||||
|
ConeStarProjection
|
||||||
|
},
|
||||||
|
isNullable = false
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
lhs.resultType.coneTypeUnsafe<ConeKotlinType>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> lhs.resultType.coneTypeUnsafe<ConeKotlinType>()
|
||||||
|
}
|
||||||
|
|
||||||
|
transformedGetClassCall.resultType =
|
||||||
|
FirResolvedTypeRefImpl(
|
||||||
|
null,
|
||||||
|
kClassSymbol.constructType(arrayOf(typeOfExpression), false)
|
||||||
|
)
|
||||||
|
return transformedGetClassCall.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformWrappedDelegateExpression(
|
||||||
|
wrappedDelegateExpression: FirWrappedDelegateExpression,
|
||||||
|
data: Any?
|
||||||
|
): CompositeTransformResult<FirStatement> {
|
||||||
|
transformExpression(wrappedDelegateExpression, data)
|
||||||
|
with(wrappedDelegateExpression) {
|
||||||
|
val delegateProviderTypeRef = delegateProvider.typeRef
|
||||||
|
val useDelegateProvider = delegateProviderTypeRef is FirResolvedTypeRef &&
|
||||||
|
delegateProviderTypeRef !is FirErrorTypeRef &&
|
||||||
|
delegateProviderTypeRef.type !is ConeKotlinErrorType
|
||||||
|
return if (useDelegateProvider) delegateProvider.compose() else expression.compose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> transformConstExpression(constExpression: FirConstExpression<T>, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
val expectedType = data as FirTypeRef?
|
||||||
|
|
||||||
|
val kind = constExpression.kind
|
||||||
|
if (expectedType == null || expectedType is FirImplicitTypeRef ||
|
||||||
|
kind == IrConstKind.Null || kind == IrConstKind.Boolean || kind == IrConstKind.Char
|
||||||
|
) {
|
||||||
|
val symbol = when (kind) {
|
||||||
|
IrConstKind.Null -> StandardClassIds.Nothing(symbolProvider)
|
||||||
|
IrConstKind.Boolean -> StandardClassIds.Boolean(symbolProvider)
|
||||||
|
IrConstKind.Char -> StandardClassIds.Char(symbolProvider)
|
||||||
|
IrConstKind.Byte -> StandardClassIds.Byte(symbolProvider)
|
||||||
|
IrConstKind.Short -> StandardClassIds.Short(symbolProvider)
|
||||||
|
IrConstKind.Int -> StandardClassIds.Int(symbolProvider)
|
||||||
|
IrConstKind.Long -> StandardClassIds.Long(symbolProvider)
|
||||||
|
IrConstKind.String -> StandardClassIds.String(symbolProvider)
|
||||||
|
IrConstKind.Float -> StandardClassIds.Float(symbolProvider)
|
||||||
|
IrConstKind.Double -> StandardClassIds.Double(symbolProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
val type = ConeClassTypeImpl(symbol.toLookupTag(), emptyArray(), isNullable = kind == IrConstKind.Null)
|
||||||
|
|
||||||
|
constExpression.resultType = FirResolvedTypeRefImpl(null, type)
|
||||||
|
} else {
|
||||||
|
constExpression.resultType = if (kind != IrConstKind.Null) {
|
||||||
|
expectedType.resolvedTypeFromPrototype(
|
||||||
|
expectedType.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NOT_NULL)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
expectedType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return transformExpression(constExpression, data).also {
|
||||||
|
dataFlowAnalyzer.exitConstExpresion(it.single as FirConstExpression<*>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
dataFlowAnalyzer.enterAnnotationCall(annotationCall)
|
||||||
|
return (annotationCall.transformChildren(transformer, data) as FirAnnotationCall).also {
|
||||||
|
dataFlowAnalyzer.exitAnnotationCall(it)
|
||||||
|
}.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
internal fun <T> storeTypeFromCallee(access: T) where T : FirQualifiedAccess, T : FirExpression {
|
||||||
|
access.resultType = callCompleter.typeFromCallee(access)
|
||||||
|
}
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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.transformers.body.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||||
|
|
||||||
|
abstract class FirPartialBodyResolveTransformer(
|
||||||
|
val transformer: FirBodyResolveTransformer
|
||||||
|
) : FirAbstractBodyResolveTransformer(transformer.transformerPhase) {
|
||||||
|
@Suppress("OVERRIDE_BY_INLINE")
|
||||||
|
final override inline val components: BodyResolveTransformerComponents get() = transformer.components
|
||||||
|
|
||||||
|
override var implicitTypeOnly: Boolean
|
||||||
|
get() = transformer.implicitTypeOnly
|
||||||
|
set(value) {
|
||||||
|
transformer.implicitTypeOnly = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <E : FirElement> transformElement(element: E, data: Any?): CompositeTransformResult<E> {
|
||||||
|
return element.transform(transformer, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.ConeTypeVariableTypeConstructor
|
|||||||
import org.jetbrains.kotlin.fir.resolve.calls.hasNullableSuperType
|
import org.jetbrains.kotlin.fir.resolve.calls.hasNullableSuperType
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.fir.*
|
|||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.references.*
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.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
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirSelfImportingScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirSelfImportingScope
|
||||||
|
|||||||
Reference in New Issue
Block a user