[minor] Optimize diagnostic reporting a bit

Eliminating a couple of function calls on reporting, speeds up
diagnostic tests for a few %
This commit is contained in:
Ilya Chernikov
2020-02-20 09:01:47 +01:00
parent 2727507d18
commit b6c9432334
@@ -147,8 +147,8 @@ class DiagnosticReporterByTrackingStrategy(
NoneCallableReferenceCandidates::class.java -> { NoneCallableReferenceCandidates::class.java -> {
val expression = diagnostic.cast<NoneCallableReferenceCandidates>() val expression = diagnostic.cast<NoneCallableReferenceCandidates>()
.argument.safeAs<CallableReferenceKotlinCallArgumentImpl>()?.ktCallableReferenceExpression .argument.safeAs<CallableReferenceKotlinCallArgumentImpl>()?.ktCallableReferenceExpression
reportIfNonNull(expression) { if (expression != null) {
trace.report(UNRESOLVED_REFERENCE.on(it.callableReference, it.callableReference)) trace.report(UNRESOLVED_REFERENCE.on(expression.callableReference, expression.callableReference))
} }
} }
@@ -156,19 +156,20 @@ class DiagnosticReporterByTrackingStrategy(
val ambiguityDiagnostic = diagnostic as CallableReferenceCandidatesAmbiguity val ambiguityDiagnostic = diagnostic as CallableReferenceCandidatesAmbiguity
val expression = ambiguityDiagnostic.argument.psiExpression.safeAs<KtCallableReferenceExpression>() val expression = ambiguityDiagnostic.argument.psiExpression.safeAs<KtCallableReferenceExpression>()
val candidates = ambiguityDiagnostic.candidates.map { it.candidate } val candidates = ambiguityDiagnostic.candidates.map { it.candidate }
reportIfNonNull(expression) { if (expression != null) {
trace.reportDiagnosticOnce(CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY.on(it.callableReference, candidates)) trace.reportDiagnosticOnce(CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY.on(expression.callableReference, candidates))
trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, it.callableReference, candidates) trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, expression.callableReference, candidates)
} }
} }
ArgumentTypeMismatchDiagnostic::class.java -> { ArgumentTypeMismatchDiagnostic::class.java -> {
require(diagnostic is ArgumentTypeMismatchDiagnostic) require(diagnostic is ArgumentTypeMismatchDiagnostic)
reportIfNonNull(callArgument.safeAs<PSIKotlinCallArgument>()?.valueArgument?.getArgumentExpression()) { val expression = callArgument.safeAs<PSIKotlinCallArgument>()?.valueArgument?.getArgumentExpression()
if (it.isNull()) { if (expression != null) {
trace.reportDiagnosticOnce(NULL_FOR_NONNULL_TYPE.on(it, diagnostic.expectedType)) if (expression.isNull() && expression is KtConstantExpression) {
trace.reportDiagnosticOnce(NULL_FOR_NONNULL_TYPE.on(expression, diagnostic.expectedType))
} else { } else {
trace.report(TYPE_MISMATCH.on(it, diagnostic.expectedType, diagnostic.actualType)) trace.report(TYPE_MISMATCH.on(expression, diagnostic.expectedType, diagnostic.actualType))
} }
} }
} }
@@ -201,17 +202,13 @@ class DiagnosticReporterByTrackingStrategy(
if (argumentExpression !is KtLambdaExpression) return if (argumentExpression !is KtLambdaExpression) return
val parameter = argumentExpression.valueParameters.getOrNull(parameterIndex) val parameter = argumentExpression.valueParameters.getOrNull(parameterIndex)
reportIfNonNull(parameter) { if (parameter != null) {
trace.report(CANNOT_INFER_PARAMETER_TYPE.on(it)) trace.report(CANNOT_INFER_PARAMETER_TYPE.on(parameter))
} }
} }
} }
} }
private fun <T> reportIfNonNull(element: T?, report: (T) -> Unit) {
if (element != null) report(element)
}
override fun onCallArgumentName(callArgument: KotlinCallArgument, diagnostic: KotlinCallDiagnostic) { override fun onCallArgumentName(callArgument: KotlinCallArgument, diagnostic: KotlinCallDiagnostic) {
val nameReference = callArgument.psiCallArgument.valueArgument.getArgumentName()?.referenceExpression ?: return val nameReference = callArgument.psiCallArgument.valueArgument.getArgumentName()?.referenceExpression ?: return
when (diagnostic.javaClass) { when (diagnostic.javaClass) {
@@ -236,7 +233,9 @@ class DiagnosticReporterByTrackingStrategy(
when (diagnostic.javaClass) { when (diagnostic.javaClass) {
NonVarargSpread::class.java -> { NonVarargSpread::class.java -> {
val spreadElement = callArgument.safeAs<ExpressionKotlinCallArgumentImpl>()?.valueArgument?.getSpreadElement() val spreadElement = callArgument.safeAs<ExpressionKotlinCallArgumentImpl>()?.valueArgument?.getSpreadElement()
reportIfNonNull(spreadElement) { trace.report(NON_VARARG_SPREAD.on(it)) } if (spreadElement != null) {
trace.report(NON_VARARG_SPREAD.on(spreadElement))
}
} }
} }
} }
@@ -338,10 +337,10 @@ class DiagnosticReporterByTrackingStrategy(
val inferredType = val inferredType =
if (!constraintError.lowerKotlinType.isNullableNothing()) constraintError.lowerKotlinType if (!constraintError.lowerKotlinType.isNullableNothing()) constraintError.lowerKotlinType
else constraintError.upperKotlinType.makeNullable() else constraintError.upperKotlinType.makeNullable()
reportIfNonNull(call) { if (call != null) {
trace.report( trace.report(
Errors.TYPE_MISMATCH.on( Errors.TYPE_MISMATCH.on(
it, call,
constraintError.upperKotlinType, constraintError.upperKotlinType,
inferredType inferredType
) )