DiagnosticReporterByTrackingStrategy: refactor positioning
This commit is contained in:
committed by
Space Team
parent
739e7d3a7a
commit
7a58c2e99f
+1
-1
@@ -30,6 +30,6 @@ class ConeLambdaArgumentConstraintPosition(
|
|||||||
|
|
||||||
|
|
||||||
class ConeBuilderInferenceSubstitutionConstraintPosition(initialConstraint: InitialConstraint) :
|
class ConeBuilderInferenceSubstitutionConstraintPosition(initialConstraint: InitialConstraint) :
|
||||||
BuilderInferenceSubstitutionConstraintPosition<Nothing?, InitialConstraint>(null, initialConstraint) // TODO
|
BuilderInferenceSubstitutionConstraintPosition<Nothing?>(null, initialConstraint) // TODO
|
||||||
|
|
||||||
class ConeReceiverConstraintPosition(receiver: FirExpression) : ReceiverConstraintPosition<FirExpression>(receiver)
|
class ConeReceiverConstraintPosition(receiver: FirExpression) : ReceiverConstraintPosition<FirExpression>(receiver)
|
||||||
|
|||||||
+61
-40
@@ -451,16 +451,16 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
|
|
||||||
val argument =
|
val argument =
|
||||||
when (position) {
|
when (position) {
|
||||||
is ArgumentConstraintPositionImpl -> position.argument
|
is ArgumentConstraintPosition<*> -> position.argument as KotlinCallArgument
|
||||||
is ReceiverConstraintPositionImpl -> position.argument
|
is ReceiverConstraintPosition<*> -> position.argument as KotlinCallArgument
|
||||||
is LambdaArgumentConstraintPositionImpl -> position.lambda.atom
|
is LambdaArgumentConstraintPosition<*> -> (position.lambda as ResolvedLambdaAtom).atom
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
val isWarning = error is NewConstraintWarning
|
val isWarning = error is NewConstraintWarning
|
||||||
val typeMismatchDiagnostic = if (isWarning) TYPE_MISMATCH_WARNING else TYPE_MISMATCH
|
val typeMismatchDiagnostic = if (isWarning) TYPE_MISMATCH_WARNING else TYPE_MISMATCH
|
||||||
val report = if (isWarning) trace::reportDiagnosticOnce else trace::report
|
val report = if (isWarning) trace::reportDiagnosticOnce else trace::report
|
||||||
argument?.let {
|
if (argument != null) {
|
||||||
(it as? LambdaKotlinCallArgument)?.let lambda@{ lambda ->
|
(argument as? LambdaKotlinCallArgument)?.let lambda@{ lambda ->
|
||||||
val parameterTypes = lambda.parametersTypes?.toList() ?: return@lambda
|
val parameterTypes = lambda.parametersTypes?.toList() ?: return@lambda
|
||||||
val index = parameterTypes.indexOf(error.upperKotlinType.unwrap())
|
val index = parameterTypes.indexOf(error.upperKotlinType.unwrap())
|
||||||
val lambdaExpression = lambda.psiExpression as? KtLambdaExpression ?: return@lambda
|
val lambdaExpression = lambda.psiExpression as? KtLambdaExpression ?: return@lambda
|
||||||
@@ -471,7 +471,7 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val expression = it.psiExpression ?: return
|
val expression = argument.psiExpression ?: return
|
||||||
val deparenthesized = KtPsiUtil.safeDeparenthesize(expression)
|
val deparenthesized = KtPsiUtil.safeDeparenthesize(expression)
|
||||||
if (reportConstantTypeMismatch(error, deparenthesized)) return
|
if (reportConstantTypeMismatch(error, deparenthesized)) return
|
||||||
|
|
||||||
@@ -485,46 +485,67 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
report(typeMismatchDiagnostic.on(deparenthesized, error.upperKotlinType, error.lowerKotlinType))
|
report(typeMismatchDiagnostic.on(deparenthesized, error.upperKotlinType, error.lowerKotlinType))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
(position as? ExpectedTypeConstraintPositionImpl)?.let {
|
@Suppress("KotlinConstantConditions")
|
||||||
val call = it.topLevelCall.psiKotlinCall.psiCall.callElement as? KtExpression
|
when (position) {
|
||||||
val inferredType =
|
is BuilderInferenceExpectedTypeConstraintPosition -> {
|
||||||
if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType
|
val inferredType =
|
||||||
else error.upperKotlinType.makeNullable()
|
if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType
|
||||||
if (call != null) {
|
else error.upperKotlinType.makeNullable()
|
||||||
report(typeMismatchDiagnostic.on(call, error.upperKotlinType, inferredType))
|
trace.report(TYPE_MISMATCH.on(position.topLevelCall, error.upperKotlinType, inferredType))
|
||||||
}
|
}
|
||||||
}
|
is ExpectedTypeConstraintPosition<*> -> {
|
||||||
|
val call = (position.topLevelCall as? KotlinCall)?.psiKotlinCall?.psiCall?.callElement as? KtExpression
|
||||||
(position as? BuilderInferenceExpectedTypeConstraintPosition)?.let {
|
val inferredType =
|
||||||
val inferredType =
|
if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType
|
||||||
if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType
|
else error.upperKotlinType.makeNullable()
|
||||||
else error.upperKotlinType.makeNullable()
|
if (call != null) {
|
||||||
trace.report(TYPE_MISMATCH.on(it.topLevelCall, error.upperKotlinType, inferredType))
|
report(typeMismatchDiagnostic.on(call, 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
|
|
||||||
}
|
}
|
||||||
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 call = ((position.resolvedAtom as? ResolvedAtom)?.atom as? PSIKotlinCall)?.psiCall ?: call
|
||||||
val expression = call.calleeExpression ?: return
|
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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -24,9 +24,9 @@ abstract class InjectedAnotherStubTypeConstraintPosition<T>(private val builderI
|
|||||||
override fun toString(): String = "Injected from $builderInferenceLambdaOfInjectedStubType builder inference call"
|
override fun toString(): String = "Injected from $builderInferenceLambdaOfInjectedStubType builder inference call"
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class BuilderInferenceSubstitutionConstraintPosition<L, I>(
|
abstract class BuilderInferenceSubstitutionConstraintPosition<L>(
|
||||||
private val builderInferenceLambda: L,
|
private val builderInferenceLambda: L,
|
||||||
val initialConstraint: I,
|
val initialConstraint: InitialConstraint,
|
||||||
val isFromNotSubstitutedDeclaredUpperBound: Boolean = false
|
val isFromNotSubstitutedDeclaredUpperBound: Boolean = false
|
||||||
) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
|
) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
|
||||||
override fun toString(): String = "Incorporated builder inference constraint $initialConstraint " +
|
override fun toString(): String = "Incorporated builder inference constraint $initialConstraint " +
|
||||||
|
|||||||
+1
-1
@@ -458,7 +458,7 @@ class KotlinConstraintSystemCompleter(
|
|||||||
val position = constraint.position.from.let { basicPosition ->
|
val position = constraint.position.from.let { basicPosition ->
|
||||||
if (basicPosition is IncorporationConstraintPosition) basicPosition.from else basicPosition
|
if (basicPosition is IncorporationConstraintPosition) basicPosition.from else basicPosition
|
||||||
}
|
}
|
||||||
if (position is BuilderInferenceSubstitutionConstraintPosition<*, *> && position.isFromNotSubstitutedDeclaredUpperBound) {
|
if (position is BuilderInferenceSubstitutionConstraintPosition<*> && position.isFromNotSubstitutedDeclaredUpperBound) {
|
||||||
upperBoundType = constraint.type
|
upperBoundType = constraint.type
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ class BuilderInferenceSubstitutionConstraintPositionImpl(
|
|||||||
builderInferenceLambda: LambdaKotlinCallArgument,
|
builderInferenceLambda: LambdaKotlinCallArgument,
|
||||||
initialConstraint: InitialConstraint,
|
initialConstraint: InitialConstraint,
|
||||||
isFromNotSubstitutedDeclaredUpperBound: Boolean = false
|
isFromNotSubstitutedDeclaredUpperBound: Boolean = false
|
||||||
) : BuilderInferenceSubstitutionConstraintPosition<LambdaKotlinCallArgument, InitialConstraint>(
|
) : BuilderInferenceSubstitutionConstraintPosition<LambdaKotlinCallArgument>(
|
||||||
builderInferenceLambda, initialConstraint, isFromNotSubstitutedDeclaredUpperBound
|
builderInferenceLambda, initialConstraint, isFromNotSubstitutedDeclaredUpperBound
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user