[FIR] Cleanup FIR modules. Part 3 (inference package)

This commit is contained in:
Dmitriy Novozhilov
2020-06-26 13:40:42 +03:00
parent 1766c22f6f
commit 1d90302848
7 changed files with 43 additions and 56 deletions
@@ -27,9 +27,6 @@ import org.jetbrains.kotlin.types.model.typeConstructor
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
val Candidate.csBuilder: NewConstraintSystemImpl get() = system.getBuilder()
class ConstraintSystemCompleter(private val components: BodyResolveComponents) { class ConstraintSystemCompleter(private val components: BodyResolveComponents) {
val variableFixationFinder = VariableFixationFinder(components.inferenceComponents.trivialConstraintTypeInferenceOracle) val variableFixationFinder = VariableFixationFinder(components.inferenceComponents.trivialConstraintTypeInferenceOracle)
@@ -76,10 +73,6 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) {
if (completionMode == ConstraintSystemCompletionMode.FULL) { if (completionMode == ConstraintSystemCompletionMode.FULL) {
// force resolution for all not-analyzed argument's // force resolution for all not-analyzed argument's
getOrderedNotAnalyzedPostponedArguments(topLevelAtoms).forEach(analyze) getOrderedNotAnalyzedPostponedArguments(topLevelAtoms).forEach(analyze)
//
// if (c.notFixedTypeVariables.isNotEmpty() && c.postponedTypeVariables.isEmpty()) {
// runCompletion(c, completionMode, topLevelAtoms, topLevelType, analyze)
// }
} }
} }
@@ -211,14 +204,6 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) {
postponedResolveKtPrimitives: List<PostponedResolvedAtom> postponedResolveKtPrimitives: List<PostponedResolvedAtom>
) { ) {
val direction = TypeVariableDirectionCalculator(c, postponedResolveKtPrimitives, topLevelType).getDirection(variableWithConstraints) val direction = TypeVariableDirectionCalculator(c, postponedResolveKtPrimitives, topLevelType).getDirection(variableWithConstraints)
fixVariable(c, variableWithConstraints, direction)
}
fun fixVariable(
c: KotlinConstraintSystemCompleter.Context,
variableWithConstraints: VariableWithConstraints,
direction: TypeVariableDirectionCalculator.ResolveDirection
) {
val resultType = components.inferenceComponents.resultTypeResolver.findResultType(c, variableWithConstraints, direction) val resultType = components.inferenceComponents.resultTypeResolver.findResultType(c, variableWithConstraints, direction)
c.fixVariable(variableWithConstraints.typeVariable, resultType, atom = null) // TODO: obtain atom for diagnostics c.fixVariable(variableWithConstraints.typeVariable, resultType, atom = null) // TODO: obtain atom for diagnostics
} }
@@ -325,3 +310,5 @@ private fun FirResolvable.processCandidateIfApplicable(
} }
} }
} }
val Candidate.csBuilder: NewConstraintSystemImpl get() = system.getBuilder()
@@ -10,7 +10,6 @@ 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.Candidate import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeStubType import org.jetbrains.kotlin.fir.types.ConeStubType
import org.jetbrains.kotlin.fir.types.ConeTypeVariable import org.jetbrains.kotlin.fir.types.ConeTypeVariable
@@ -87,7 +86,7 @@ class FirBuilderInferenceSession(
): Map<ConeTypeVariableTypeConstructor, ConeKotlinType>? { ): Map<ConeTypeVariableTypeConstructor, ConeKotlinType>? {
val (commonSystem, effectivelyEmptyConstraintSystem) = buildCommonSystem(initialStorage) val (commonSystem, effectivelyEmptyConstraintSystem) = buildCommonSystem(initialStorage)
if (effectivelyEmptyConstraintSystem) { if (effectivelyEmptyConstraintSystem) {
updateCalls(commonSystem, lambda) updateCalls(commonSystem)
return null return null
} }
@@ -103,7 +102,7 @@ class FirBuilderInferenceSession(
error("Shouldn't be called in complete constraint system mode") error("Shouldn't be called in complete constraint system mode")
} }
updateCalls(commonSystem, lambda) updateCalls(commonSystem)
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return commonSystem.fixedTypeVariables as Map<ConeTypeVariableTypeConstructor, ConeKotlinType> return commonSystem.fixedTypeVariables as Map<ConeTypeVariableTypeConstructor, ConeKotlinType>
@@ -199,7 +198,7 @@ class FirBuilderInferenceSession(
return introducedConstraint return introducedConstraint
} }
private fun updateCalls(commonSystem: NewConstraintSystemImpl, lambda: ResolvedLambdaAtom) { private fun updateCalls(commonSystem: NewConstraintSystemImpl) {
val nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor() val nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor()
val commonSystemSubstitutor = commonSystem.buildCurrentSubstitutor() as ConeSubstitutor val commonSystemSubstitutor = commonSystem.buildCurrentSubstitutor() as ConeSubstitutor
val nonFixedTypesToResultSubstitutor = ConeComposedSubstitutor(commonSystemSubstitutor, nonFixedToVariablesSubstitutor) val nonFixedTypesToResultSubstitutor = ConeComposedSubstitutor(commonSystemSubstitutor, nonFixedToVariablesSubstitutor)
@@ -115,7 +115,6 @@ class FirDelegatedPropertyInferenceSession(
addConstraintForThis(commonSystem) addConstraintForThis(commonSystem)
} }
private fun Candidate.addConstraintsForSetValueMethod(commonSystem: ConstraintSystemBuilder) { private fun Candidate.addConstraintsForSetValueMethod(commonSystem: ConstraintSystemBuilder) {
if (expectedType != null) { if (expectedType != null) {
val accessor = symbol.fir as? FirSimpleFunction ?: return val accessor = symbol.fir as? FirSimpleFunction ?: return
@@ -31,9 +31,7 @@ class InferenceComponents(
return ConeClassErrorType(message) return ConeClassErrorType(message)
} }
} }
val trivialConstraintTypeInferenceOracle = val trivialConstraintTypeInferenceOracle = TrivialConstraintTypeInferenceOracle.create(ctx)
TrivialConstraintTypeInferenceOracle
.create(ctx)
private val incorporator = ConstraintIncorporator(approximator, trivialConstraintTypeInferenceOracle) private val incorporator = ConstraintIncorporator(approximator, trivialConstraintTypeInferenceOracle)
private val injector = ConstraintInjector(incorporator, approximator, KotlinTypeRefiner.Default) private val injector = ConstraintInjector(incorporator, approximator, KotlinTypeRefiner.Default)
val resultTypeResolver = ResultTypeResolver(approximator, trivialConstraintTypeInferenceOracle) val resultTypeResolver = ResultTypeResolver(approximator, trivialConstraintTypeInferenceOracle)
@@ -55,5 +53,4 @@ class InferenceComponents(
fun createConstraintSystem(): NewConstraintSystemImpl { fun createConstraintSystem(): NewConstraintSystemImpl {
return NewConstraintSystemImpl(injector, ctx) return NewConstraintSystemImpl(injector, ctx)
} }
}
}
@@ -13,41 +13,41 @@ import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.resolve.calls.isExtensionFunctionType import org.jetbrains.kotlin.fir.resolve.calls.isExtensionFunctionType
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun ConeKotlinType.isBuiltinFunctionalType(session: FirSession): Boolean { fun ConeKotlinType.isBuiltinFunctionalType(session: FirSession): Boolean {
return when (this) { contract {
is ConeClassLikeType -> { returns(true) implies (this@isBuiltinFunctionalType is ConeClassLikeType)
val classId = fullyExpandedType(session).lookupTag.classId
val kind =
FunctionClassDescriptor.Kind.byClassNamePrefix(classId.packageFqName, classId.relativeClassName.asString()) ?: return false
kind == FunctionClassDescriptor.Kind.Function || kind == FunctionClassDescriptor.Kind.SuspendFunction
}
else -> false
} }
if (this !is ConeClassLikeType) return false
val classId = fullyExpandedType(session).lookupTag.classId
val kind = FunctionClassDescriptor.Kind.byClassNamePrefix(classId.packageFqName, classId.relativeClassName.asString()) ?: return false
return kind == FunctionClassDescriptor.Kind.Function || kind == FunctionClassDescriptor.Kind.SuspendFunction
} }
@OptIn(ExperimentalContracts::class)
fun ConeKotlinType.isSuspendFunctionType(session: FirSession): Boolean { fun ConeKotlinType.isSuspendFunctionType(session: FirSession): Boolean {
return when (val type = this) { contract {
is ConeClassLikeType -> { returns(true) implies (this@isSuspendFunctionType is ConeClassLikeType)
val classId = type.fullyExpandedType(session).lookupTag.classId
val kind =
FunctionClassDescriptor.Kind.byClassNamePrefix(classId.packageFqName, classId.relativeClassName.asString()) ?: return false
kind == FunctionClassDescriptor.Kind.SuspendFunction
}
else -> false
} }
if (this !is ConeClassLikeType) return false
val classId = this.fullyExpandedType(session).lookupTag.classId
val kind = FunctionClassDescriptor.Kind.byClassNamePrefix(classId.packageFqName, classId.relativeClassName.asString()) ?: return false
return kind == FunctionClassDescriptor.Kind.SuspendFunction
} }
fun ConeKotlinType.receiverType(expectedTypeRef: FirTypeRef?, session: FirSession): ConeKotlinType? { fun ConeKotlinType.receiverType(expectedTypeRef: FirTypeRef?, session: FirSession): ConeKotlinType? {
if (isBuiltinFunctionalType(session) && expectedTypeRef?.isExtensionFunctionType(session) == true) { if (isBuiltinFunctionalType(session) && expectedTypeRef?.isExtensionFunctionType(session) == true) {
return ((this as ConeClassLikeType).fullyExpandedType(session).typeArguments.first() as ConeKotlinTypeProjection).type return (this.fullyExpandedType(session).typeArguments.first() as ConeKotlinTypeProjection).type
} }
return null return null
} }
fun ConeKotlinType.receiverType(session: FirSession): ConeKotlinType? { fun ConeKotlinType.receiverType(session: FirSession): ConeKotlinType? {
if (isBuiltinFunctionalType(session)) { if (isBuiltinFunctionalType(session)) {
return ((this as ConeClassLikeType).fullyExpandedType(session).typeArguments.first() as ConeKotlinTypeProjection).type return (this.fullyExpandedType(session).typeArguments.first() as ConeKotlinTypeProjection).type
} }
return null return null
} }
@@ -65,8 +65,8 @@ fun ConeKotlinType.valueParameterTypesIncludingReceiver(session: FirSession): Li
} }
} }
val FirAnonymousFunction.returnType get() = returnTypeRef.coneTypeSafe<ConeKotlinType>() val FirAnonymousFunction.returnType: ConeKotlinType? get() = returnTypeRef.coneTypeSafe()
val FirAnonymousFunction.receiverType get() = receiverTypeRef?.coneTypeSafe<ConeKotlinType>() val FirAnonymousFunction.receiverType: ConeKotlinType? get() = receiverTypeRef?.coneTypeSafe()
fun extractLambdaInfoFromFunctionalType( fun extractLambdaInfoFromFunctionalType(
expectedType: ConeKotlinType?, expectedType: ConeKotlinType?,
@@ -79,7 +79,14 @@ fun extractLambdaInfoFromFunctionalType(
val session = components.session val session = components.session
if (expectedType == null) return null if (expectedType == null) return null
if (expectedType is ConeFlexibleType) { if (expectedType is ConeFlexibleType) {
return extractLambdaInfoFromFunctionalType(expectedType.lowerBound, expectedTypeRef, argument, returnTypeVariable, components, candidate) return extractLambdaInfoFromFunctionalType(
expectedType.lowerBound,
expectedTypeRef,
argument,
returnTypeVariable,
components,
candidate
)
} }
if (!expectedType.isBuiltinFunctionalType(session)) return null if (!expectedType.isBuiltinFunctionalType(session)) return null
@@ -41,7 +41,6 @@ interface LambdaAnalyzer {
): ReturnArgumentsAnalysisResult ): ReturnArgumentsAnalysisResult
} }
class PostponedArgumentsAnalyzer( class PostponedArgumentsAnalyzer(
private val lambdaAnalyzer: LambdaAnalyzer, private val lambdaAnalyzer: LambdaAnalyzer,
private val components: InferenceComponents, private val components: InferenceComponents,
@@ -74,24 +73,24 @@ class PostponedArgumentsAnalyzer(
val callableReferenceAccess = atom.reference val callableReferenceAccess = atom.reference
atom.analyzed = true atom.analyzed = true
val (candidate, applicability) = atom.resultingCandidate val (resultingCandidate, applicability) = atom.resultingCandidate
?: Pair(null, CandidateApplicability.INAPPLICABLE) ?: Pair(null, CandidateApplicability.INAPPLICABLE)
val namedReference = when { val namedReference = when {
candidate == null || applicability < CandidateApplicability.SYNTHETIC_RESOLVED -> resultingCandidate == null || applicability < CandidateApplicability.SYNTHETIC_RESOLVED ->
buildErrorNamedReference { buildErrorNamedReference {
source = callableReferenceAccess.source source = callableReferenceAccess.source
diagnostic = ConeUnresolvedReferenceError(callableReferenceAccess.calleeReference.name) diagnostic = ConeUnresolvedReferenceError(callableReferenceAccess.calleeReference.name)
} }
else -> FirNamedReferenceWithCandidate(callableReferenceAccess.source, callableReferenceAccess.calleeReference.name, candidate) else -> FirNamedReferenceWithCandidate(callableReferenceAccess.source, callableReferenceAccess.calleeReference.name, resultingCandidate)
} }
val transformedCalleeReference = callableReferenceAccess.transformCalleeReference( callableReferenceAccess.transformCalleeReference(
StoreNameReference, StoreNameReference,
namedReference namedReference
).apply { ).apply {
if (candidate != null) { if (resultingCandidate != null) {
replaceTypeRef(buildResolvedTypeRef { type = candidate.resultingTypeForCallableReference!! }) replaceTypeRef(buildResolvedTypeRef { type = resultingCandidate.resultingTypeForCallableReference!! })
} }
} }
} }
@@ -102,7 +101,7 @@ class PostponedArgumentsAnalyzer(
candidate: Candidate candidate: Candidate
//diagnosticHolder: KotlinDiagnosticsHolder //diagnosticHolder: KotlinDiagnosticsHolder
) { ) {
val unitType = components.session.builtinTypes.unitType.type//Unit(components.session.firSymbolProvider).constructType(emptyArray(), false) val unitType = components.session.builtinTypes.unitType.type
val stubsForPostponedVariables = c.bindingStubsForPostponedVariables() val stubsForPostponedVariables = c.bindingStubsForPostponedVariables()
val currentSubstitutor = c.buildCurrentSubstitutor(stubsForPostponedVariables.mapKeys { it.key.freshTypeConstructor(c) }) val currentSubstitutor = c.buildCurrentSubstitutor(stubsForPostponedVariables.mapKeys { it.key.freshTypeConstructor(c) })
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
// --------------------------- Variables --------------------------- // --------------------------- Variables ---------------------------
class ConeTypeVariableForLambdaReturnType(val argument: FirAnonymousFunction, name: String) : ConeTypeVariable(name) class ConeTypeVariableForLambdaReturnType(val argument: FirAnonymousFunction, name: String) : ConeTypeVariable(name)
// -------------------------- Atoms -------------------------- // -------------------------- Atoms --------------------------
@@ -44,7 +43,7 @@ class ResolvedLambdaAtom(
val parameters: List<ConeKotlinType>, val parameters: List<ConeKotlinType>,
val returnType: ConeKotlinType, val returnType: ConeKotlinType,
val typeVariableForLambdaReturnType: ConeTypeVariableForLambdaReturnType?, val typeVariableForLambdaReturnType: ConeTypeVariableForLambdaReturnType?,
val candidateOfOuterCall: Candidate? candidateOfOuterCall: Candidate?
) : PostponedResolvedAtom() { ) : PostponedResolvedAtom() {
init { init {
candidateOfOuterCall?.let { candidateOfOuterCall?.let {