DiagnosticReporterByTrackingStrategy: refactor positioning

This commit is contained in:
Mikhail Glukhikh
2023-02-03 17:52:36 +01:00
committed by Space Team
parent 739e7d3a7a
commit 7a58c2e99f
5 changed files with 66 additions and 45 deletions
@@ -30,6 +30,6 @@ class ConeLambdaArgumentConstraintPosition(
class ConeBuilderInferenceSubstitutionConstraintPosition(initialConstraint: InitialConstraint) :
BuilderInferenceSubstitutionConstraintPosition<Nothing?, InitialConstraint>(null, initialConstraint) // TODO
BuilderInferenceSubstitutionConstraintPosition<Nothing?>(null, initialConstraint) // TODO
class ConeReceiverConstraintPosition(receiver: FirExpression) : ReceiverConstraintPosition<FirExpression>(receiver)
@@ -451,16 +451,16 @@ class DiagnosticReporterByTrackingStrategy(
val argument =
when (position) {
is ArgumentConstraintPositionImpl -> position.argument
is ReceiverConstraintPositionImpl -> position.argument
is LambdaArgumentConstraintPositionImpl -> position.lambda.atom
is ArgumentConstraintPosition<*> -> position.argument as KotlinCallArgument
is ReceiverConstraintPosition<*> -> position.argument as KotlinCallArgument
is LambdaArgumentConstraintPosition<*> -> (position.lambda as ResolvedLambdaAtom).atom
else -> null
}
val isWarning = error is NewConstraintWarning
val typeMismatchDiagnostic = if (isWarning) TYPE_MISMATCH_WARNING else TYPE_MISMATCH
val report = if (isWarning) trace::reportDiagnosticOnce else trace::report
argument?.let {
(it as? LambdaKotlinCallArgument)?.let lambda@{ lambda ->
if (argument != null) {
(argument as? LambdaKotlinCallArgument)?.let lambda@{ lambda ->
val parameterTypes = lambda.parametersTypes?.toList() ?: return@lambda
val index = parameterTypes.indexOf(error.upperKotlinType.unwrap())
val lambdaExpression = lambda.psiExpression as? KtLambdaExpression ?: return@lambda
@@ -471,7 +471,7 @@ class DiagnosticReporterByTrackingStrategy(
return
}
val expression = it.psiExpression ?: return
val expression = argument.psiExpression ?: return
val deparenthesized = KtPsiUtil.safeDeparenthesize(expression)
if (reportConstantTypeMismatch(error, deparenthesized)) return
@@ -485,46 +485,67 @@ class DiagnosticReporterByTrackingStrategy(
}
}
report(typeMismatchDiagnostic.on(deparenthesized, error.upperKotlinType, error.lowerKotlinType))
return
}
(position as? ExpectedTypeConstraintPositionImpl)?.let {
val call = it.topLevelCall.psiKotlinCall.psiCall.callElement as? KtExpression
val inferredType =
if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType
else error.upperKotlinType.makeNullable()
if (call != null) {
report(typeMismatchDiagnostic.on(call, error.upperKotlinType, inferredType))
@Suppress("KotlinConstantConditions")
when (position) {
is BuilderInferenceExpectedTypeConstraintPosition -> {
val inferredType =
if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType
else error.upperKotlinType.makeNullable()
trace.report(TYPE_MISMATCH.on(position.topLevelCall, error.upperKotlinType, inferredType))
}
}
(position as? BuilderInferenceExpectedTypeConstraintPosition)?.let {
val inferredType =
if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType
else error.upperKotlinType.makeNullable()
trace.report(TYPE_MISMATCH.on(it.topLevelCall, error.upperKotlinType, inferredType))
}
(position as? BuilderInferenceSubstitutionConstraintPositionImpl)?.let {
reportConstraintErrorByPosition(error, it.initialConstraint.position)
}
(position as? ExplicitTypeParameterConstraintPositionImpl)?.let {
val typeArgumentReference = (it.typeArgument as SimpleTypeArgumentImpl).typeProjection.typeReference ?: return@let
val diagnosticFactory = if (isWarning) UPPER_BOUND_VIOLATED_WARNING else UPPER_BOUND_VIOLATED
report(diagnosticFactory.on(typeArgumentReference, error.upperKotlinType, error.lowerKotlinType))
}
(position as? FixVariableConstraintPositionImpl)?.let {
val morePreciseDiagnosticExists = allDiagnostics.any { other ->
val otherError = other.constraintSystemError ?: return@any false
otherError is NewConstraintError && otherError.position.from !is FixVariableConstraintPositionImpl
is ExpectedTypeConstraintPosition<*> -> {
val call = (position.topLevelCall as? KotlinCall)?.psiKotlinCall?.psiCall?.callElement as? KtExpression
val inferredType =
if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType
else error.upperKotlinType.makeNullable()
if (call != null) {
report(typeMismatchDiagnostic.on(call, error.upperKotlinType, inferredType))
}
}
if (morePreciseDiagnosticExists) return
is BuilderInferenceSubstitutionConstraintPosition<*> -> {
reportConstraintErrorByPosition(error, position.initialConstraint.position)
}
is ExplicitTypeParameterConstraintPosition<*> -> {
val typeArgumentReference = (position.typeArgument as SimpleTypeArgumentImpl).typeProjection.typeReference ?: return
val diagnosticFactory = if (isWarning) UPPER_BOUND_VIOLATED_WARNING else UPPER_BOUND_VIOLATED
report(diagnosticFactory.on(typeArgumentReference, error.upperKotlinType, error.lowerKotlinType))
}
is FixVariableConstraintPosition<*> -> {
val morePreciseDiagnosticExists = allDiagnostics.any { other ->
val otherError = other.constraintSystemError ?: return@any false
otherError is NewConstraintError && otherError.position.from !is FixVariableConstraintPositionImpl
}
if (morePreciseDiagnosticExists) return
val call = (it.resolvedAtom?.atom as? PSIKotlinCall)?.psiCall ?: call
val expression = call.calleeExpression ?: return
val call = ((position.resolvedAtom as? ResolvedAtom)?.atom as? PSIKotlinCall)?.psiCall ?: call
val expression = call.calleeExpression ?: return
trace.reportDiagnosticOnce(typeMismatchDiagnostic.on(expression, error.upperKotlinType, error.lowerKotlinType))
trace.reportDiagnosticOnce(typeMismatchDiagnostic.on(expression, error.upperKotlinType, error.lowerKotlinType))
}
BuilderInferencePosition -> {
// some error reported later?
}
is CallableReferenceConstraintPosition<*> -> TODO()
is DeclaredUpperBoundConstraintPosition<*> -> TODO()
is DelegatedPropertyConstraintPosition<*> -> {
// DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE, reported later
}
is IncorporationConstraintPosition -> TODO()
is InjectedAnotherStubTypeConstraintPosition<*> -> TODO()
is KnownTypeParameterConstraintPosition<*> -> {
// UPPER_BOUND_VIOLATED, reported later?
}
is LHSArgumentConstraintPosition<*, *> -> TODO()
SimpleConstraintSystemConstraintPosition -> TODO()
// Never reachable
is ArgumentConstraintPosition<*>,
is LambdaArgumentConstraintPosition<*>,
is ReceiverConstraintPosition<*> -> {
throw AssertionError("Should not be here")
}
}
}
@@ -24,9 +24,9 @@ abstract class InjectedAnotherStubTypeConstraintPosition<T>(private val builderI
override fun toString(): String = "Injected from $builderInferenceLambdaOfInjectedStubType builder inference call"
}
abstract class BuilderInferenceSubstitutionConstraintPosition<L, I>(
abstract class BuilderInferenceSubstitutionConstraintPosition<L>(
private val builderInferenceLambda: L,
val initialConstraint: I,
val initialConstraint: InitialConstraint,
val isFromNotSubstitutedDeclaredUpperBound: Boolean = false
) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
override fun toString(): String = "Incorporated builder inference constraint $initialConstraint " +
@@ -458,7 +458,7 @@ class KotlinConstraintSystemCompleter(
val position = constraint.position.from.let { basicPosition ->
if (basicPosition is IncorporationConstraintPosition) basicPosition.from else basicPosition
}
if (position is BuilderInferenceSubstitutionConstraintPosition<*, *> && position.isFromNotSubstitutedDeclaredUpperBound) {
if (position is BuilderInferenceSubstitutionConstraintPosition<*> && position.isFromNotSubstitutedDeclaredUpperBound) {
upperBoundType = constraint.type
true
} else {
@@ -21,7 +21,7 @@ class BuilderInferenceSubstitutionConstraintPositionImpl(
builderInferenceLambda: LambdaKotlinCallArgument,
initialConstraint: InitialConstraint,
isFromNotSubstitutedDeclaredUpperBound: Boolean = false
) : BuilderInferenceSubstitutionConstraintPosition<LambdaKotlinCallArgument, InitialConstraint>(
) : BuilderInferenceSubstitutionConstraintPosition<LambdaKotlinCallArgument>(
builderInferenceLambda, initialConstraint, isFromNotSubstitutedDeclaredUpperBound
)