[NI] Report diagnostic about spread argument to non vararg parameter

This commit is contained in:
Mikhail Zarechenskiy
2017-11-03 11:34:23 +03:00
parent d45f4e71de
commit 1d6e9c244b
4 changed files with 29 additions and 1 deletions
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.constants.CompileTimeConstantChecker
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class DiagnosticReporterByTrackingStrategy( class DiagnosticReporterByTrackingStrategy(
val constantExpressionEvaluator: ConstantExpressionEvaluator, val constantExpressionEvaluator: ConstantExpressionEvaluator,
@@ -105,6 +106,13 @@ class DiagnosticReporterByTrackingStrategy(
} }
VarargArgumentOutsideParentheses::class.java -> VarargArgumentOutsideParentheses::class.java ->
trace.report(VARARG_OUTSIDE_PARENTHESES.on(callArgument.psiExpression!!)) trace.report(VARARG_OUTSIDE_PARENTHESES.on(callArgument.psiExpression!!))
SpreadArgumentToNonVarargParameter::class.java -> {
val spreadElement = callArgument.safeAs<ExpressionKotlinCallArgumentImpl>()?.valueArgument?.getSpreadElement()
if (spreadElement != null) {
trace.report(NON_VARARG_SPREAD.on(spreadElement))
}
}
} }
} }
@@ -109,6 +109,19 @@ internal object ArgumentsToCandidateParameterDescriptor : ResolutionPart() {
} }
} }
internal object CheckSpreadArgumentToNonVarargParameter : ResolutionPart() {
override fun KotlinResolutionCandidate.process(workIndex: Int) {
for ((_, resolvedCallArgument) in resolvedCall.argumentMappingByOriginal) {
for (argument in resolvedCallArgument.arguments) {
val valueParameter = resolvedCall.argumentToCandidateParameter[argument] ?: continue
if (argument.isSpread && !valueParameter.isVararg) {
addDiagnostic(SpreadArgumentToNonVarargParameter(argument))
}
}
}
}
}
internal object NoArguments : ResolutionPart() { internal object NoArguments : ResolutionPart() {
override fun KotlinResolutionCandidate.process(workIndex: Int) { override fun KotlinResolutionCandidate.process(workIndex: Int) {
assert(kotlinCall.argumentsInParenthesis.isEmpty()) { assert(kotlinCall.argumentsInParenthesis.isEmpty()) {
@@ -156,6 +156,12 @@ object AbstractSuperCall : KotlinCallDiagnostic(RUNTIME_ERROR) {
} }
} }
class SpreadArgumentToNonVarargParameter(val argument: KotlinCallArgument) : KotlinCallDiagnostic(RUNTIME_ERROR) {
override fun report(reporter: DiagnosticReporter) {
reporter.onCallArgument(argument, this)
}
}
// candidates result // candidates result
class NoneCandidatesCallDiagnostic(val kotlinCall: KotlinCall) : KotlinCallDiagnostic(INAPPLICABLE) { class NoneCandidatesCallDiagnostic(val kotlinCall: KotlinCall) : KotlinCallDiagnostic(INAPPLICABLE) {
override fun report(reporter: DiagnosticReporter) { override fun report(reporter: DiagnosticReporter) {
@@ -181,7 +181,8 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
CheckExplicitReceiverKindConsistency, CheckExplicitReceiverKindConsistency,
CheckReceivers, CheckReceivers,
CheckArguments, CheckArguments,
CheckExternalArgument CheckExternalArgument,
CheckSpreadArgumentToNonVarargParameter
), ),
UNSUPPORTED(); UNSUPPORTED();