[FIR] Improve mapping arguments to parameters
This commit is contained in:
@@ -324,16 +324,19 @@ private fun Candidate.getExpectedTypeWithSAMConversion(
|
||||
internal fun FirExpression.getExpectedType(
|
||||
session: FirSession,
|
||||
parameter: FirValueParameter/*, languageVersionSettings: LanguageVersionSettings*/
|
||||
) =
|
||||
// if (this.isSpread || this.isArrayAssignedAsNamedArgumentInAnnotation(parameter, languageVersionSettings)) {
|
||||
// parameter.type.unwrap()
|
||||
// } else {
|
||||
if (parameter.isVararg && (this !is FirWrappedArgumentExpression || !isSpread)) {
|
||||
): ConeKotlinType {
|
||||
val shouldUnwrapVarargType = when (this) {
|
||||
is FirSpreadArgumentExpression -> !isSpread
|
||||
is FirNamedArgumentExpression -> false
|
||||
else -> true
|
||||
}
|
||||
|
||||
return if (parameter.isVararg && shouldUnwrapVarargType) {
|
||||
parameter.returnTypeRef.coneTypeUnsafe<ConeKotlinType>().varargElementType(session)
|
||||
} else {
|
||||
parameter.returnTypeRef.coneTypeUnsafe()
|
||||
}//?.varargElementType?.unwrap() ?: parameter.type.unwrap()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun ConeKotlinType.varargElementType(session: FirSession): ConeKotlinType {
|
||||
@@ -354,4 +357,4 @@ fun FirTypeRef.isExtensionFunctionType(session: FirSession): Boolean {
|
||||
if (typeAlias.expandedTypeRef.annotations.any(FirAnnotationCall::isExtensionFunctionAnnotationCall)) return true
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -109,6 +109,8 @@ class Candidate(
|
||||
var argumentMapping: Map<FirExpression, FirValueParameter>? = null
|
||||
val postponedAtoms = mutableListOf<PostponedResolvedAtomMarker>()
|
||||
|
||||
val diagnostics: MutableList<ResolutionDiagnostic> = mutableListOf()
|
||||
|
||||
fun dispatchReceiverExpression(): FirExpression = when (explicitReceiverKind) {
|
||||
ExplicitReceiverKind.DISPATCH_RECEIVER, ExplicitReceiverKind.BOTH_RECEIVERS -> callInfo.explicitReceiver!!
|
||||
else -> dispatchReceiverValue?.receiverExpression ?: FirNoReceiverExpression
|
||||
|
||||
+257
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirLambdaArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirSpreadArgumentExpression
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.set
|
||||
|
||||
|
||||
data class ArgumentMapping(
|
||||
// This map should be ordered by arguments as written, e.g.:
|
||||
// fun foo(a: Int, b: Int) {}
|
||||
// foo(b = bar(), a = qux())
|
||||
// parameterToCallArgumentMap.values() should be [ 'bar()', 'foo()' ]
|
||||
val parameterToCallArgumentMap: Map<FirValueParameter, ResolvedCallArgument>,
|
||||
val diagnostics: List<ResolutionDiagnostic>
|
||||
)
|
||||
|
||||
private val EmptyArgumentMapping = ArgumentMapping(emptyMap(), emptyList())
|
||||
|
||||
fun mapArguments(
|
||||
arguments: List<FirExpression>,
|
||||
function: FirFunction<*>
|
||||
): ArgumentMapping {
|
||||
if (arguments.isEmpty() && function.valueParameters.isEmpty()) {
|
||||
return EmptyArgumentMapping
|
||||
}
|
||||
val externalArgument: FirExpression? = arguments.lastOrNull { it is FirLambdaArgumentExpression }
|
||||
val argumentsInParenthesis: List<FirExpression> = if (externalArgument == null) {
|
||||
arguments
|
||||
} else {
|
||||
arguments.subList(0, arguments.size - 1)
|
||||
}
|
||||
|
||||
val processor = FirCallArgumentsProcessor(function)
|
||||
processor.processArgumentsInParenthesis(argumentsInParenthesis)
|
||||
if (externalArgument != null) {
|
||||
processor.processExternalArgument(externalArgument)
|
||||
}
|
||||
processor.processDefaultsAndRunChecks()
|
||||
|
||||
return ArgumentMapping(processor.result, processor.diagnostics ?: emptyList())
|
||||
}
|
||||
|
||||
private class FirCallArgumentsProcessor(private val function: FirFunction<*>) {
|
||||
private var state = State.POSITION_ARGUMENTS
|
||||
private var currentPositionedParameterIndex = 0
|
||||
private var varargArguments: MutableList<FirExpression>? = null
|
||||
private var nameToParameter: Map<Name, FirValueParameter>? = null
|
||||
var diagnostics: MutableList<ResolutionDiagnostic>? = null
|
||||
private set
|
||||
val result: MutableMap<FirValueParameter, ResolvedCallArgument> = LinkedHashMap()
|
||||
|
||||
private enum class State {
|
||||
POSITION_ARGUMENTS,
|
||||
VARARG_POSITION,
|
||||
NAMED_ONLY_ARGUMENTS
|
||||
}
|
||||
|
||||
fun processArgumentsInParenthesis(arguments: List<FirExpression>) {
|
||||
for (argument in arguments) {
|
||||
val argumentName = argument.argumentName
|
||||
|
||||
// process position argument
|
||||
if (argumentName == null) {
|
||||
if (processPositionArgument(argument)) {
|
||||
state = State.VARARG_POSITION
|
||||
}
|
||||
}
|
||||
// process named argument
|
||||
else {
|
||||
if (state == State.VARARG_POSITION) {
|
||||
completeVarargPositionArguments()
|
||||
}
|
||||
state = State.NAMED_ONLY_ARGUMENTS
|
||||
|
||||
processNamedArgument(argument, argumentName)
|
||||
}
|
||||
}
|
||||
if (state == State.VARARG_POSITION) {
|
||||
completeVarargPositionArguments()
|
||||
}
|
||||
}
|
||||
|
||||
// return true, if it was mapped to vararg parameter
|
||||
private fun processPositionArgument(argument: FirExpression): Boolean {
|
||||
if (state == State.NAMED_ONLY_ARGUMENTS) {
|
||||
addDiagnostic(MixingNamedAndPositionArguments(argument))
|
||||
return false
|
||||
}
|
||||
|
||||
val parameter = parameters.getOrNull(currentPositionedParameterIndex)
|
||||
if (parameter == null) {
|
||||
addDiagnostic(TooManyArguments(argument, function))
|
||||
return false
|
||||
}
|
||||
|
||||
if (!parameter.isVararg) {
|
||||
currentPositionedParameterIndex++
|
||||
|
||||
result[parameter] = ResolvedCallArgument.SimpleArgument(argument)
|
||||
return false
|
||||
}
|
||||
// all position arguments will be mapped to current vararg parameter
|
||||
else {
|
||||
addVarargArgument(argument)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private fun processNamedArgument(argument: FirExpression, name: Name) {
|
||||
if (!function.hasStableParameterNames) {
|
||||
addDiagnostic(NamedArgumentNotAllowed(argument, function))
|
||||
}
|
||||
|
||||
val parameter = findParameterByName(argument, name) ?: return
|
||||
|
||||
result[parameter]?.let {
|
||||
addDiagnostic(ArgumentPassedTwice(argument, parameter, it))
|
||||
return
|
||||
}
|
||||
|
||||
result[parameter] = ResolvedCallArgument.SimpleArgument(argument)
|
||||
|
||||
if (parameters.getOrNull(currentPositionedParameterIndex) == parameter) {
|
||||
state = State.POSITION_ARGUMENTS
|
||||
currentPositionedParameterIndex++
|
||||
}
|
||||
}
|
||||
|
||||
fun processExternalArgument(externalArgument: FirExpression) {
|
||||
val lastParameter = parameters.lastOrNull()
|
||||
if (lastParameter == null) {
|
||||
addDiagnostic(TooManyArguments(externalArgument, function))
|
||||
return
|
||||
}
|
||||
|
||||
if (lastParameter.isVararg) {
|
||||
addDiagnostic(VarargArgumentOutsideParentheses(externalArgument, lastParameter))
|
||||
return
|
||||
}
|
||||
|
||||
val previousOccurrence = result[lastParameter]
|
||||
if (previousOccurrence != null) {
|
||||
addDiagnostic(TooManyArguments(externalArgument, function))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
result[lastParameter] = ResolvedCallArgument.SimpleArgument(externalArgument)
|
||||
}
|
||||
|
||||
fun processDefaultsAndRunChecks() {
|
||||
for ((parameter, resolvedArgument) in result) {
|
||||
if (!parameter.isVararg) {
|
||||
if (resolvedArgument !is ResolvedCallArgument.SimpleArgument) {
|
||||
error("Incorrect resolved argument for parameter $parameter :$resolvedArgument")
|
||||
} else if (resolvedArgument.callArgument.isSpread) {
|
||||
addDiagnostic(NonVarargSpread(resolvedArgument.callArgument))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (parameter in parameters) {
|
||||
if (!result.containsKey(parameter)) {
|
||||
if (parameter.defaultValue != null) {
|
||||
result[parameter] = ResolvedCallArgument.DefaultArgument
|
||||
} else if (parameter.isVararg) {
|
||||
result[parameter] = ResolvedCallArgument.VarargArgument(emptyList())
|
||||
} else {
|
||||
addDiagnostic(NoValueForParameter(parameter, function))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun completeVarargPositionArguments() {
|
||||
assert(state == State.VARARG_POSITION) { "Incorrect state: $state" }
|
||||
val parameter = parameters[currentPositionedParameterIndex]
|
||||
result.put(parameter, ResolvedCallArgument.VarargArgument(varargArguments!!))
|
||||
}
|
||||
|
||||
private fun addVarargArgument(argument: FirExpression) {
|
||||
if (varargArguments == null) {
|
||||
varargArguments = ArrayList()
|
||||
}
|
||||
varargArguments!!.add(argument)
|
||||
}
|
||||
|
||||
private fun getParameterByName(name: Name): FirValueParameter? {
|
||||
if (nameToParameter == null) {
|
||||
nameToParameter = parameters.associateBy { it.name }
|
||||
}
|
||||
return nameToParameter!![name]
|
||||
}
|
||||
|
||||
private fun findParameterByName(argument: FirExpression, name: Name): FirValueParameter? {
|
||||
val parameter = getParameterByName(name)
|
||||
|
||||
// TODO
|
||||
// if (descriptor is CallableMemberDescriptor && descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||
// if (parameter == null) {
|
||||
// for (valueParameter in descriptor.valueParameters) {
|
||||
// val matchedParameter = valueParameter.overriddenDescriptors.firstOrNull {
|
||||
// it.containingDeclaration.hasStableParameterNames() && it.name == name
|
||||
// }
|
||||
// if (matchedParameter != null) {
|
||||
// addDiagnostic(NamedArgumentReference(argument, valueParameter))
|
||||
// addDiagnostic(NameForAmbiguousParameter(argument, valueParameter, matchedParameter))
|
||||
// return valueParameter
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// parameter.getOverriddenParameterWithOtherName()?.let {
|
||||
// addDiagnostic(NameForAmbiguousParameter(argument, parameter, it))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
if (parameter == null) addDiagnostic(NameNotFound(argument, function))
|
||||
|
||||
return parameter
|
||||
}
|
||||
|
||||
private fun addDiagnostic(diagnostic: ResolutionDiagnostic) {
|
||||
if (diagnostics == null) {
|
||||
diagnostics = mutableListOf()
|
||||
}
|
||||
diagnostics!!.add(diagnostic)
|
||||
}
|
||||
|
||||
private val FirExpression.isSpread: Boolean
|
||||
get() = this is FirSpreadArgumentExpression && isSpread
|
||||
|
||||
private val parameters: List<FirValueParameter>
|
||||
get() = function.valueParameters
|
||||
|
||||
private val FirExpression.argumentName: Name?
|
||||
get() = (this as? FirNamedArgumentExpression)?.name
|
||||
|
||||
// TODO: handle java functions
|
||||
private val FirFunction<*>.hasStableParameterNames: Boolean
|
||||
get() = true
|
||||
}
|
||||
-119
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirLambdaArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
|
||||
class FirCallArgumentsProcessor(
|
||||
private val function: FirFunction<*>,
|
||||
private val arguments: List<FirExpression>
|
||||
) {
|
||||
class Result(val argumentMapping: Map<FirExpression, FirValueParameter>, val isSuccess: Boolean)
|
||||
|
||||
fun process(): Result {
|
||||
var currentState: State = State.PositionalOnly(function.valueParameters)
|
||||
for (argument in arguments) {
|
||||
if (argument is FirNamedArgumentExpression || argument is FirLambdaArgumentExpression) {
|
||||
currentState = State.PositionalThenNamed(
|
||||
function.valueParameters,
|
||||
currentState.argumentMap,
|
||||
currentState.usedParameters
|
||||
)
|
||||
}
|
||||
val status = currentState.processArgument(argument)
|
||||
if (status != MappingStatus.SUCCESS) {
|
||||
// unmapped argument
|
||||
return Result(currentState.argumentMap, isSuccess = false)
|
||||
}
|
||||
}
|
||||
|
||||
for (valueParameter in function.valueParameters) {
|
||||
if (valueParameter !in currentState.usedParameters && !valueParameter.isVararg && valueParameter.defaultValue == null) {
|
||||
// unmapped parameter
|
||||
return Result(currentState.argumentMap, isSuccess = false)
|
||||
}
|
||||
}
|
||||
return Result(currentState.argumentMap, isSuccess = currentState.argumentMap.size == arguments.size)
|
||||
}
|
||||
|
||||
private enum class MappingStatus {
|
||||
SUCCESS,
|
||||
ERROR
|
||||
}
|
||||
|
||||
private sealed class State(
|
||||
val valueParameters: List<FirValueParameter>,
|
||||
val argumentMap: MutableMap<FirExpression, FirValueParameter> = mutableMapOf(),
|
||||
val usedParameters: MutableSet<FirValueParameter> = mutableSetOf()
|
||||
) {
|
||||
abstract fun processArgument(argument: FirExpression): MappingStatus
|
||||
|
||||
class PositionalOnly(valueParameters: List<FirValueParameter>) : State(valueParameters) {
|
||||
var currentParameterIndex: Int = 0
|
||||
|
||||
val currentParameter get() = valueParameters.getOrNull(currentParameterIndex)
|
||||
|
||||
override fun processArgument(argument: FirExpression): MappingStatus {
|
||||
require(argument !is FirNamedArgumentExpression) {
|
||||
"Positional-only argument processor state should not receive ${argument.render()}"
|
||||
}
|
||||
|
||||
val currentParameter = currentParameter ?: return MappingStatus.ERROR
|
||||
argumentMap[argument] = currentParameter
|
||||
|
||||
val isSpread = argument is FirWrappedArgumentExpression && argument.isSpread
|
||||
if (!currentParameter.isVararg || isSpread) {
|
||||
usedParameters += currentParameter
|
||||
currentParameterIndex++
|
||||
}
|
||||
|
||||
if (!currentParameter.isVararg && isSpread) {
|
||||
return MappingStatus.ERROR
|
||||
}
|
||||
|
||||
return MappingStatus.SUCCESS
|
||||
}
|
||||
}
|
||||
|
||||
class PositionalThenNamed(
|
||||
valueParameters: List<FirValueParameter>,
|
||||
argumentMap: MutableMap<FirExpression, FirValueParameter>,
|
||||
usedParameters: MutableSet<FirValueParameter>
|
||||
) : State(valueParameters, argumentMap, usedParameters) {
|
||||
val nameToParameter = valueParameters.associateBy { it.name }
|
||||
|
||||
private fun map(parameter: FirValueParameter, argument: FirExpression): MappingStatus {
|
||||
if (parameter in usedParameters) return MappingStatus.ERROR
|
||||
argumentMap[argument] = parameter
|
||||
usedParameters += parameter
|
||||
return MappingStatus.SUCCESS
|
||||
}
|
||||
|
||||
override fun processArgument(argument: FirExpression): MappingStatus {
|
||||
when (argument) {
|
||||
is FirNamedArgumentExpression -> {
|
||||
val name = argument.name
|
||||
val parameter = nameToParameter[name] ?: return MappingStatus.ERROR
|
||||
return map(parameter, argument)
|
||||
}
|
||||
is FirLambdaArgumentExpression -> {
|
||||
val lastParameter = valueParameters.lastOrNull() ?: return MappingStatus.ERROR
|
||||
return map(lastParameter, argument)
|
||||
}
|
||||
else -> {
|
||||
return MappingStatus.ERROR
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability
|
||||
|
||||
abstract class ResolutionDiagnostic(val applicability: CandidateApplicability)
|
||||
|
||||
abstract class InapplicableArgumentDiagnostic : ResolutionDiagnostic(CandidateApplicability.INAPPLICABLE) {
|
||||
abstract val argument: FirExpression
|
||||
}
|
||||
|
||||
class MixingNamedAndPositionArguments(override val argument: FirExpression) : InapplicableArgumentDiagnostic()
|
||||
class TooManyArguments(
|
||||
val argument: FirExpression,
|
||||
val function: FirFunction<*>
|
||||
) : ResolutionDiagnostic(CandidateApplicability.PARAMETER_MAPPING_ERROR)
|
||||
|
||||
class NamedArgumentNotAllowed(
|
||||
override val argument: FirExpression,
|
||||
val function: FirFunction<*>
|
||||
) : InapplicableArgumentDiagnostic()
|
||||
|
||||
class ArgumentPassedTwice(
|
||||
override val argument: FirExpression,
|
||||
val valueParameter: FirValueParameter,
|
||||
val firstOccurrence: ResolvedCallArgument
|
||||
) : InapplicableArgumentDiagnostic()
|
||||
|
||||
class VarargArgumentOutsideParentheses(
|
||||
override val argument: FirExpression,
|
||||
val valueParameter: FirValueParameter
|
||||
) : InapplicableArgumentDiagnostic()
|
||||
|
||||
class NonVarargSpread(override val argument: FirExpression) : InapplicableArgumentDiagnostic()
|
||||
|
||||
class NoValueForParameter(
|
||||
val valueParameter: FirValueParameter,
|
||||
val function: FirFunction<*>
|
||||
) : ResolutionDiagnostic(CandidateApplicability.PARAMETER_MAPPING_ERROR)
|
||||
|
||||
class NameNotFound(
|
||||
override val argument: FirExpression,
|
||||
val function: FirFunction<*>
|
||||
) : InapplicableArgumentDiagnostic()
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
|
||||
sealed class ResolvedCallArgument {
|
||||
abstract val arguments: List<FirExpression>
|
||||
|
||||
object DefaultArgument : ResolvedCallArgument() {
|
||||
override val arguments: List<FirExpression>
|
||||
get() = emptyList()
|
||||
|
||||
}
|
||||
|
||||
class SimpleArgument(val callArgument: FirExpression) : ResolvedCallArgument() {
|
||||
override val arguments: List<FirExpression>
|
||||
get() = listOf(callArgument)
|
||||
|
||||
}
|
||||
|
||||
class VarargArgument(override val arguments: List<FirExpression>) : ResolvedCallArgument()
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.min
|
||||
|
||||
|
||||
abstract class ResolutionStage {
|
||||
@@ -154,11 +155,26 @@ internal object MapArguments : ResolutionStage() {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val symbol = candidate.symbol as? FirFunctionSymbol<*> ?: return sink.reportApplicability(CandidateApplicability.HIDDEN)
|
||||
val function = symbol.fir
|
||||
val processor = FirCallArgumentsProcessor(function, callInfo.arguments)
|
||||
val mappingResult = processor.process()
|
||||
candidate.argumentMapping = mappingResult.argumentMapping
|
||||
if (!mappingResult.isSuccess) {
|
||||
return sink.yieldApplicability(CandidateApplicability.PARAMETER_MAPPING_ERROR)
|
||||
|
||||
val mapping = mapArguments(callInfo.arguments, function)
|
||||
val argumentToParameterMapping = mutableMapOf<FirExpression, FirValueParameter>()
|
||||
mapping.parameterToCallArgumentMap.forEach { (valueParameter, resolvedArgument) ->
|
||||
when (resolvedArgument) {
|
||||
is ResolvedCallArgument.SimpleArgument -> argumentToParameterMapping[resolvedArgument.callArgument] = valueParameter
|
||||
is ResolvedCallArgument.VarargArgument -> resolvedArgument.arguments.forEach {
|
||||
argumentToParameterMapping[it] = valueParameter
|
||||
}
|
||||
}
|
||||
}
|
||||
candidate.argumentMapping = argumentToParameterMapping
|
||||
|
||||
var applicability = CandidateApplicability.RESOLVED
|
||||
mapping.diagnostics.forEach {
|
||||
candidate.diagnostics += it
|
||||
applicability = min(applicability, it.applicability)
|
||||
}
|
||||
if (applicability < CandidateApplicability.RESOLVED) {
|
||||
return sink.yieldApplicability(applicability)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,24 +4,30 @@ fun baz(f: () -> Unit, other: Boolean = true) {}
|
||||
|
||||
|
||||
fun test() {
|
||||
// OK
|
||||
foo {}
|
||||
foo() {}
|
||||
foo({})
|
||||
|
||||
// Bad
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(1) {}
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(f = {}) {}
|
||||
|
||||
// OK
|
||||
bar(1) {}
|
||||
bar(x = 1) {}
|
||||
bar(1, {})
|
||||
bar(x = 1, f = {})
|
||||
|
||||
// Bad
|
||||
<!INAPPLICABLE_CANDIDATE!>bar<!> {}
|
||||
<!INAPPLICABLE_CANDIDATE!>bar<!>({})
|
||||
|
||||
// OK
|
||||
baz(other = false, f = {})
|
||||
baz({}, false)
|
||||
|
||||
// Bad
|
||||
<!INAPPLICABLE_CANDIDATE!>baz<!> {}
|
||||
<!INAPPLICABLE_CANDIDATE!>baz<!>() {}
|
||||
<!INAPPLICABLE_CANDIDATE!>baz<!>(other = false) {}
|
||||
|
||||
@@ -9,7 +9,7 @@ fun test() {
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>()
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(0.0, false, 0, "")
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(1, 2.0, third = true, "")
|
||||
foo(1, 2.0, third = true, "")
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(second = 0.0, first = 0, fourth = "")
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(first = 0.0, second = 0, third = "", fourth = false)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(first = 0, second = 0.0, third = false, fourth = "", first = 1)
|
||||
|
||||
@@ -9,9 +9,9 @@ FILE: simple.kt
|
||||
R|/foo|(third = Boolean(false), second = Double(2.71), fourth = String(?!), first = Int(0))
|
||||
<Inapplicable(PARAMETER_MAPPING_ERROR): [/foo]>#()
|
||||
<Inapplicable(INAPPLICABLE): [/foo]>#(Double(0.0), Boolean(false), Int(0), String())
|
||||
<Inapplicable(PARAMETER_MAPPING_ERROR): [/foo]>#(Int(1), Double(2.0), third = Boolean(true), String())
|
||||
R|/foo|(Int(1), Double(2.0), third = Boolean(true), String())
|
||||
<Inapplicable(PARAMETER_MAPPING_ERROR): [/foo]>#(second = Double(0.0), first = Int(0), fourth = String())
|
||||
<Inapplicable(INAPPLICABLE): [/foo]>#(first = Double(0.0), second = Int(0), third = String(), fourth = Boolean(false))
|
||||
<Inapplicable(PARAMETER_MAPPING_ERROR): [/foo]>#(first = Int(0), second = Double(0.0), third = Boolean(false), fourth = String(), first = Int(1))
|
||||
<Inapplicable(INAPPLICABLE): [/foo]>#(first = Int(0), second = Double(0.0), third = Boolean(false), fourth = String(), first = Int(1))
|
||||
<Inapplicable(PARAMETER_MAPPING_ERROR): [/foo]>#(Int(0), Double(0.0), Boolean(false), foth = String())
|
||||
}
|
||||
|
||||
@@ -11,6 +11,6 @@ FILE: vararg.kt
|
||||
<Inapplicable(INAPPLICABLE): [/foo]>#(String())
|
||||
<Inapplicable(INAPPLICABLE): [/foo]>#(Int(1), Int(2))
|
||||
R|/bar|(Int(1), z = Boolean(true), vararg(y = *R|kotlin/arrayOf|<R|kotlin/String|>(vararg(String(my), String(yours)))))
|
||||
<Inapplicable(PARAMETER_MAPPING_ERROR): [/bar]>#(Int(0), z = Boolean(false), y = String(), y = String(other))
|
||||
<Inapplicable(INAPPLICABLE): [/bar]>#(Int(0), z = Boolean(false), y = String(), y = String(other))
|
||||
<Inapplicable(PARAMETER_MAPPING_ERROR): [/bar]>#(Int(0), String(), Boolean(true))
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
fun foo(
|
||||
p1: Int = 1,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
fun foo(
|
||||
p1: Int,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
fun barB(vararg args: Byte) = args
|
||||
fun barC(vararg args: Char) = args
|
||||
fun barD(vararg args: Double) = args
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// !LANGUAGE: -ProhibitAssigningSingleElementsToVarargsInNamedForm
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
fun box(): String {
|
||||
if (test1(p = 1) != "1") return "fail 1"
|
||||
|
||||
+2
-2
@@ -12,6 +12,6 @@ fun test() {
|
||||
v1({}, {})
|
||||
<!INAPPLICABLE_CANDIDATE!>v1<!>({}, 1, {})
|
||||
v1({}, {}, {it})
|
||||
v1({}) {}
|
||||
v1 {}
|
||||
<!INAPPLICABLE_CANDIDATE!>v1<!>({}) {}
|
||||
<!INAPPLICABLE_CANDIDATE!>v1<!> {}
|
||||
}
|
||||
@@ -12,47 +12,47 @@ fun main() {
|
||||
join(1, "2", "3")
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(*1, "2")
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(1, *"2")
|
||||
join(x = 1, a = "2")
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(x = 1, a = "2")
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(x = *1, a = *"2")
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(x = 1, a = a)
|
||||
join(x = 1, a = a)
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(x = 1, a = b)
|
||||
join(1, *a)
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(1, *b)
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(1, *a, "3")
|
||||
join(1, *a, "3")
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(1, *b, "3")
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(1, "4", *a, "3")
|
||||
join(1, "4", *a, "3")
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(1, "4", *b, "3")
|
||||
join(1, "4", *a)
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(1, "4", *a, *a, "3")
|
||||
join(1, "4", *a, *a, "3")
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(1, "4", *a, *b, "3")
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(a = a, x = 1)
|
||||
join(a = a, x = 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(a = b, x = 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>join<!>(a = a, x = 1)
|
||||
join(a = a, x = 1)
|
||||
|
||||
joinG<String>(1, "2")
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!><String>(*1, "2")
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!><String>(1, *"2")
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!><String>(x = 1, a = a)
|
||||
joinG<String>(x = 1, a = "2")
|
||||
joinG<String>(x = 1, a = a)
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!><String>(x = 1, a = "2")
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!><String>(x = *1, a = *"2")
|
||||
joinG<String>(1, *a)
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!><String>(1, *a, "3")
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!><String>(1, "4", *a, "3")
|
||||
joinG<String>(1, *a, "3")
|
||||
joinG<String>(1, "4", *a, "3")
|
||||
joinG<String>(1, "4", *a)
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!><String>(1, "4", *a, *a, "3")
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!><String>(a = a, x = 1)
|
||||
joinG<String>(1, "4", *a, *a, "3")
|
||||
joinG<String>(a = a, x = 1)
|
||||
|
||||
joinG(1, "2")
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!>(*1, "2")
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!>(1, *"2")
|
||||
joinG(x = 1, a = a)
|
||||
joinG(x = 1, a = "2")
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!>(x = 1, a = "2")
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!>(x = *1, a = *"2")
|
||||
joinG(1, *a)
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!>(1, *a, "3")
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!>(1, "4", *a, "3")
|
||||
joinG(1, *a, "3")
|
||||
joinG(1, "4", *a, "3")
|
||||
joinG(1, "4", *a)
|
||||
<!INAPPLICABLE_CANDIDATE!>joinG<!>(1, "4", *a, *a, "3")
|
||||
joinG(1, "4", *a, *a, "3")
|
||||
joinG(a = a, x = 1)
|
||||
|
||||
val x1 = joinT(1, "2")
|
||||
@@ -61,18 +61,18 @@ fun main() {
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><String?>(x2)
|
||||
val x6 = joinT(1, *a)
|
||||
checkSubtype<String?>(x6)
|
||||
val x7 = <!INAPPLICABLE_CANDIDATE!>joinT<!>(1, *a, "3")
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><String?>(x7)
|
||||
val x8 = <!INAPPLICABLE_CANDIDATE!>joinT<!>(1, "4", *a, "3")
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><String?>(x8)
|
||||
val x7 = joinT(1, *a, "3")
|
||||
checkSubtype<String?>(x7)
|
||||
val x8 = joinT(1, "4", *a, "3")
|
||||
checkSubtype<String?>(x8)
|
||||
val x9 = joinT(1, "4", *a)
|
||||
checkSubtype<String?>(x9)
|
||||
val x10 = <!INAPPLICABLE_CANDIDATE!>joinT<!>(1, "4", *a, *a, "3")
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><String?>(x10)
|
||||
val x10 = joinT(1, "4", *a, *a, "3")
|
||||
checkSubtype<String?>(x10)
|
||||
val x11 = joinT(a = a, x = 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><String?>(x11)
|
||||
checkSubtype<String?>(x11)
|
||||
val x12 = joinT(x = 1, a = a)
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><String?>(x12)
|
||||
checkSubtype<String?>(x12)
|
||||
}
|
||||
|
||||
fun join(x : Int, vararg a : String) : String {
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ fun test(x: () -> Unit, y: () -> Unit) {
|
||||
}
|
||||
|
||||
fun main() {
|
||||
<!INAPPLICABLE_CANDIDATE!>test<!> {
|
||||
test {
|
||||
1
|
||||
} {
|
||||
2
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ import java.lang.invoke.MethodHandle
|
||||
|
||||
fun test(mh: MethodHandle) {
|
||||
mh.invokeExact("1", "2")
|
||||
mh.<!INAPPLICABLE_CANDIDATE!>invokeExact<!>(*emptyArray(), "X")
|
||||
mh.<!INAPPLICABLE_CANDIDATE!>invokeExact<!>(*arrayOf("A", "B"), "C", *arrayOf("D", "E"))
|
||||
mh.invokeExact(*emptyArray(), "X")
|
||||
mh.invokeExact(*arrayOf("A", "B"), "C", *arrayOf("D", "E"))
|
||||
mh.invoke(*arrayOf("A"))
|
||||
}
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ import java.lang.invoke.MethodHandle
|
||||
|
||||
fun test(mh: MethodHandle) {
|
||||
mh.invokeExact("1", "2")
|
||||
mh.<!INAPPLICABLE_CANDIDATE!>invokeExact<!>(*emptyArray(), "X")
|
||||
mh.<!INAPPLICABLE_CANDIDATE!>invokeExact<!>(*arrayOf("A", "B"), "C", *arrayOf("D", "E"))
|
||||
mh.invokeExact(*emptyArray(), "X")
|
||||
mh.invokeExact(*arrayOf("A", "B"), "C", *arrayOf("D", "E"))
|
||||
mh.invoke(*arrayOf("A"))
|
||||
}
|
||||
|
||||
+3
-3
@@ -10,14 +10,14 @@ fun foo(
|
||||
) {}
|
||||
|
||||
fun main() {
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(p1 = 1, "2", 3.0)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(1, p2 = "2", 3.0)
|
||||
foo(p1 = 1, "2", 3.0)
|
||||
foo(1, p2 = "2", 3.0)
|
||||
foo(1, "2", p3 = 3.0)
|
||||
|
||||
foo(p1 = 1)
|
||||
foo(1, p2 = "2")
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(p1 = 1, p2 = "2", 3.0)
|
||||
foo(p1 = 1, p2 = "2", 3.0)
|
||||
|
||||
foo()
|
||||
foo(1, p2 = "")
|
||||
|
||||
Vendored
+3
-3
@@ -9,11 +9,11 @@ fun foo(
|
||||
) {}
|
||||
|
||||
fun main() {
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(p1 = 1, "2", 3.0)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(1, p2 = "2", 3.0)
|
||||
foo(p1 = 1, "2", 3.0)
|
||||
foo(1, p2 = "2", 3.0)
|
||||
foo(1, "2", p3 = 3.0)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(p1 = 1, p2 = "2", 3.0)
|
||||
foo(p1 = 1, p2 = "2", 3.0)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(1, p3 = 2.0, "")
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(1, p3 = 2.0, 3.0)
|
||||
|
||||
+3
-3
@@ -9,11 +9,11 @@ fun foo(
|
||||
) {}
|
||||
|
||||
fun main() {
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(p1 = 1, "2", 3.0)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(1, p2 = "2", 3.0)
|
||||
foo(p1 = 1, "2", 3.0)
|
||||
foo(1, p2 = "2", 3.0)
|
||||
foo(1, "2", p3 = 3.0)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(p1 = 1, p2 = "2", 3.0)
|
||||
foo(p1 = 1, p2 = "2", 3.0)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(1, p3 = 2.0, "")
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(1, p3 = 2.0, 3.0)
|
||||
|
||||
+3
-3
@@ -9,11 +9,11 @@ fun foo(
|
||||
) {}
|
||||
|
||||
fun main() {
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(p1 = 1, "2", 3.0)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(1, p2 = "2", 3.0)
|
||||
foo(p1 = 1, "2", 3.0)
|
||||
foo(1, p2 = "2", 3.0)
|
||||
foo(1, "2", p3 = 3.0)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(p1 = 1, p2 = "2", 3.0)
|
||||
foo(p1 = 1, p2 = "2", 3.0)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(1, p3 = 2.0, "")
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(1, p3 = 2.0, 3.0)
|
||||
|
||||
+7
-7
@@ -29,16 +29,16 @@ fun foo4(
|
||||
|
||||
fun main() {
|
||||
<!INAPPLICABLE_CANDIDATE!>foo1<!>(1, 2, p2 = "3", 4.0)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo1<!>(p1 = intArrayOf(1, 2), "3", p3 = 4.0)
|
||||
foo1(p1 = intArrayOf(1, 2), "3", p3 = 4.0)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo1<!>(p2 = "3", 4.0)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo2<!>(p1 = 1, "2", "3", p3 = 4.0)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo2<!>(1, p2 = arrayOf("2", "3"), 4.0)
|
||||
foo2(p1 = 1, "2", "3", p3 = 4.0)
|
||||
foo2(1, p2 = arrayOf("2", "3"), 4.0)
|
||||
foo2(1, p3 = 3.0)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo3<!>(p1 = 1, "2", 3.0, 4.0)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo3<!>(p1 = 1, "2", p3 = doubleArrayOf(3.0, 4.0))
|
||||
foo3(p1 = 1, "2", 3.0, 4.0)
|
||||
foo3(p1 = 1, "2", p3 = doubleArrayOf(3.0, 4.0))
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo4<!>(p1 = 1, "2", "3", p3 = 4.0, 5)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo4<!>(1, "2", "3", p3 = 4.0, 5)
|
||||
@@ -50,8 +50,8 @@ fun main() {
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo2<!>(1, p3 = 2.0, "4")
|
||||
<!INAPPLICABLE_CANDIDATE!>foo2<!>(1, p3 = 2.0, *arrayOf("3", "4"))
|
||||
<!INAPPLICABLE_CANDIDATE!>foo2<!>(1, p3 = 2.0, p2 = arrayOf("3", "4"))
|
||||
foo2(1, p3 = 2.0, p2 = arrayOf("3", "4"))
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo3<!>(1, p3 = doubleArrayOf(2.0, 3.0), "4")
|
||||
<!INAPPLICABLE_CANDIDATE!>foo3<!>(1, p3 = doubleArrayOf(2.0, 3.0), p2 = "4")
|
||||
foo3(1, p3 = doubleArrayOf(2.0, 3.0), p2 = "4")
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ fun testTwoLambdas() {
|
||||
)
|
||||
|
||||
fun bar(): () -> Unit {
|
||||
<!INAPPLICABLE_CANDIDATE!>twoLambdaArgs<!>()
|
||||
twoLambdaArgs()
|
||||
{}
|
||||
{}
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -8,6 +8,6 @@ fun overloadedFun(arg: String, vararg args: String) = X1
|
||||
fun overloadedFun(arg: String, vararg args: String, flag: Boolean = true) = X2
|
||||
|
||||
val test1a: X1 = overloadedFun("", "")
|
||||
val test1b: X1 = overloadedFun("", args = "")
|
||||
val test1b: X1 = <!INAPPLICABLE_CANDIDATE!>overloadedFun<!>("", args = "")
|
||||
val test1c: X2 = overloadedFun("", "", "", flag = true)
|
||||
|
||||
|
||||
+2
-2
@@ -9,5 +9,5 @@ fun overloadedFun5(s: String, vararg ss: String) = X2
|
||||
|
||||
val test1 = overloadedFun5("")
|
||||
val test2 = overloadedFun5("", "")
|
||||
val test3: X2 = overloadedFun5(s = "", ss = "")
|
||||
val test4: X1 = overloadedFun5(ss = "")
|
||||
val test3: X2 = <!INAPPLICABLE_CANDIDATE!>overloadedFun5<!>(s = "", ss = "")
|
||||
val test4: X1 = <!INAPPLICABLE_CANDIDATE!>overloadedFun5<!>(ss = "")
|
||||
Vendored
+1
-1
@@ -2,7 +2,7 @@
|
||||
fun <T> array(vararg x: T): Array<T> = null!!
|
||||
|
||||
open class B(vararg y: String) {
|
||||
constructor(x: Int): <!INAPPLICABLE_CANDIDATE!>this<!>(x.toString(), *array("1"), "2")
|
||||
constructor(x: Int): this(x.toString(), *array("1"), "2")
|
||||
}
|
||||
|
||||
class A : B {
|
||||
|
||||
Vendored
+1
-1
@@ -13,5 +13,5 @@ class A : B {
|
||||
|
||||
val b1 = B()
|
||||
val b2 = B("1", "2", "3")
|
||||
val b3 = <!INAPPLICABLE_CANDIDATE!>B<!>("1", *array("2", "3"), "4")
|
||||
val b3 = B("1", *array("2", "3"), "4")
|
||||
val b4 = B(1)
|
||||
|
||||
+2
-2
@@ -12,11 +12,11 @@ fun foo() {}
|
||||
fun test_fun(s: String, arr: Array<String>) {
|
||||
<!INAPPLICABLE_CANDIDATE!>withVararg<!>(arr) // Error
|
||||
withVararg(*arr) // OK
|
||||
<!INAPPLICABLE_CANDIDATE!>withVararg<!>(s = arr) // Error
|
||||
withVararg(s = arr) // Error
|
||||
withVararg(s = *arr) // OK
|
||||
|
||||
withVararg(s) // OK
|
||||
withVararg(s = s) // Error
|
||||
<!INAPPLICABLE_CANDIDATE!>withVararg<!>(s = s) // Error
|
||||
}
|
||||
|
||||
fun test_ann(s: String, arr: Array<String>) {
|
||||
|
||||
+2
-2
@@ -12,11 +12,11 @@ fun foo() {}
|
||||
fun test_fun(s: String, arr: Array<String>) {
|
||||
<!INAPPLICABLE_CANDIDATE!>withVararg<!>(arr) // Error
|
||||
withVararg(*arr) // OK
|
||||
<!INAPPLICABLE_CANDIDATE!>withVararg<!>(s = arr) // OK
|
||||
withVararg(s = arr) // OK
|
||||
withVararg(s = *arr) // Warning
|
||||
|
||||
withVararg(s) // OK
|
||||
withVararg(s = s) // Error
|
||||
<!INAPPLICABLE_CANDIDATE!>withVararg<!>(s = s) // Error
|
||||
}
|
||||
|
||||
fun test_ann(s: String, arr: Array<String>) {
|
||||
|
||||
+15
-15
@@ -7,27 +7,27 @@ fun foo(vararg s: Int) {}
|
||||
open class Cls(vararg p: Long)
|
||||
|
||||
fun test(i: IntArray) {
|
||||
foo(s = 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(s = i)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(s = 1)
|
||||
foo(s = i)
|
||||
foo(s = *i)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(s = intArrayOf(1))
|
||||
foo(s = intArrayOf(1))
|
||||
foo(s = *intArrayOf(1))
|
||||
foo(1)
|
||||
|
||||
Cls(p = 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>Cls<!>(p = 1)
|
||||
|
||||
class Sub : Cls(p = 1)
|
||||
class Sub : <!INAPPLICABLE_CANDIDATE!>Cls<!>(p = 1)
|
||||
|
||||
val c = object : Cls(p = 1) {}
|
||||
val c = object : <!INAPPLICABLE_CANDIDATE!>Cls<!>(p = 1) {}
|
||||
|
||||
foo(s = *intArrayOf(elements = 1))
|
||||
foo(s = *<!INAPPLICABLE_CANDIDATE!>intArrayOf<!>(elements = 1))
|
||||
}
|
||||
|
||||
|
||||
fun anyFoo(vararg a: Any) {}
|
||||
|
||||
fun testAny() {
|
||||
anyFoo(a = "")
|
||||
<!INAPPLICABLE_CANDIDATE!>anyFoo<!>(a = "")
|
||||
anyFoo(a = arrayOf(""))
|
||||
anyFoo(a = *arrayOf(""))
|
||||
}
|
||||
@@ -35,12 +35,12 @@ fun testAny() {
|
||||
fun <T> genFoo(vararg t: T) {}
|
||||
|
||||
fun testGen() {
|
||||
genFoo<Int>(t = 1)
|
||||
genFoo<Int?>(t = null)
|
||||
<!INAPPLICABLE_CANDIDATE!>genFoo<!><Int>(t = 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>genFoo<!><Int?>(t = null)
|
||||
genFoo<Array<Int>>(t = arrayOf())
|
||||
genFoo<Array<Int>>(t = *arrayOf(arrayOf()))
|
||||
|
||||
genFoo(t = "")
|
||||
<!INAPPLICABLE_CANDIDATE!>genFoo<!>(t = "")
|
||||
genFoo(t = arrayOf(""))
|
||||
genFoo(t = *arrayOf(""))
|
||||
}
|
||||
@@ -49,12 +49,12 @@ fun manyFoo(vararg v: Int) {}
|
||||
fun manyFoo(vararg s: String) {}
|
||||
|
||||
fun testMany(a: Any) {
|
||||
manyFoo(v = 1)
|
||||
manyFoo(s = "")
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(v = 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(s = "")
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(a)
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(v = a)
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(s = a)
|
||||
manyFoo(v = a as Int)
|
||||
manyFoo(s = a as String)
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(v = a as Int)
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(s = a as String)
|
||||
}
|
||||
+15
-15
@@ -7,27 +7,27 @@ fun foo(vararg s: Int) {}
|
||||
open class Cls(vararg p: Long)
|
||||
|
||||
fun test(i: IntArray) {
|
||||
foo(s = 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(s = i)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(s = 1)
|
||||
foo(s = i)
|
||||
foo(s = *i)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(s = intArrayOf(1))
|
||||
foo(s = intArrayOf(1))
|
||||
foo(s = *intArrayOf(1))
|
||||
foo(1)
|
||||
|
||||
Cls(p = 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>Cls<!>(p = 1)
|
||||
|
||||
class Sub : Cls(p = 1)
|
||||
class Sub : <!INAPPLICABLE_CANDIDATE!>Cls<!>(p = 1)
|
||||
|
||||
val c = object : Cls(p = 1) {}
|
||||
val c = object : <!INAPPLICABLE_CANDIDATE!>Cls<!>(p = 1) {}
|
||||
|
||||
foo(s = *intArrayOf(elements = 1))
|
||||
foo(s = *<!INAPPLICABLE_CANDIDATE!>intArrayOf<!>(elements = 1))
|
||||
}
|
||||
|
||||
|
||||
fun anyFoo(vararg a: Any) {}
|
||||
|
||||
fun testAny() {
|
||||
anyFoo(a = "")
|
||||
<!INAPPLICABLE_CANDIDATE!>anyFoo<!>(a = "")
|
||||
anyFoo(a = arrayOf(""))
|
||||
anyFoo(a = *arrayOf(""))
|
||||
}
|
||||
@@ -35,12 +35,12 @@ fun testAny() {
|
||||
fun <T> genFoo(vararg t: T) {}
|
||||
|
||||
fun testGen() {
|
||||
genFoo<Int>(t = 1)
|
||||
genFoo<Int?>(t = null)
|
||||
<!INAPPLICABLE_CANDIDATE!>genFoo<!><Int>(t = 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>genFoo<!><Int?>(t = null)
|
||||
genFoo<Array<Int>>(t = arrayOf())
|
||||
genFoo<Array<Int>>(t = *arrayOf(arrayOf()))
|
||||
|
||||
genFoo(t = "")
|
||||
<!INAPPLICABLE_CANDIDATE!>genFoo<!>(t = "")
|
||||
genFoo(t = arrayOf(""))
|
||||
genFoo(t = *arrayOf(""))
|
||||
}
|
||||
@@ -49,12 +49,12 @@ fun manyFoo(vararg v: Int) {}
|
||||
fun manyFoo(vararg s: String) {}
|
||||
|
||||
fun testMany(a: Any) {
|
||||
manyFoo(v = 1)
|
||||
manyFoo(s = "")
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(v = 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(s = "")
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(a)
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(v = a)
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(s = a)
|
||||
manyFoo(v = a as Int)
|
||||
manyFoo(s = a as String)
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(v = a as Int)
|
||||
<!INAPPLICABLE_CANDIDATE!>manyFoo<!>(s = a as String)
|
||||
}
|
||||
+1
-1
@@ -45,5 +45,5 @@ fun foo(vararg i: Int) {}
|
||||
|
||||
@Ann(s = "value")
|
||||
fun dep1() {
|
||||
foo(i = 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(i = 1)
|
||||
}
|
||||
Vendored
+1
-1
@@ -15,6 +15,6 @@ fun f2() {}
|
||||
fun foo(vararg ints: Int) {}
|
||||
|
||||
fun test() {
|
||||
foo(ints = 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>(ints = 1)
|
||||
foo(ints = *intArrayOf(1))
|
||||
}
|
||||
|
||||
+13
-9
@@ -24,15 +24,19 @@ FILE fqName:<root> fileName:/vararg.kt
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test2> (): kotlin.Array<kotlin.String> declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Array<kotlin.String> visibility:private [final,static]' type=kotlin.Array<kotlin.String> origin=null
|
||||
PROPERTY name:test3 visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test3 type:IrErrorType visibility:private [final,static]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test3 type:kotlin.Array<kotlin.String> visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
ERROR_CALL 'Unresolved reference: <Inapplicable(PARAMETER_MAPPING_ERROR): [kotlin/arrayOf]>#' type=IrErrorType
|
||||
CONST String type=kotlin.String value="0"
|
||||
CALL 'public final fun <get-test2> (): kotlin.Array<kotlin.String> declared in <root>' type=kotlin.Array<kotlin.String> origin=null
|
||||
CALL 'public final fun <get-test1> (): kotlin.Array<kotlin.String> declared in <root>' type=kotlin.Array<kotlin.String> origin=null
|
||||
CONST String type=kotlin.String value="4"
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test3> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
CALL 'public final fun arrayOf <T> (vararg elements: T of kotlin.arrayOf): kotlin.Array<T of kotlin.arrayOf> [inline] declared in kotlin' type=kotlin.Array<kotlin.String> origin=null
|
||||
<T>: kotlin.String
|
||||
elements: VARARG type=kotlin.Array<out kotlin.String> varargElementType=kotlin.String
|
||||
CONST String type=kotlin.String value="0"
|
||||
SPREAD_ELEMENT
|
||||
CALL 'public final fun <get-test2> (): kotlin.Array<kotlin.String> declared in <root>' type=kotlin.Array<kotlin.String> origin=null
|
||||
SPREAD_ELEMENT
|
||||
CALL 'public final fun <get-test1> (): kotlin.Array<kotlin.String> declared in <root>' type=kotlin.Array<kotlin.String> origin=null
|
||||
CONST String type=kotlin.String value="4"
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test3> visibility:public modality:FINAL <> () returnType:kotlin.Array<kotlin.String>
|
||||
correspondingProperty: PROPERTY name:test3 visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test3> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test3 type:IrErrorType visibility:private [final,static]' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test3> (): kotlin.Array<kotlin.String> declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test3 type:kotlin.Array<kotlin.String> visibility:private [final,static]' type=kotlin.Array<kotlin.String> origin=null
|
||||
|
||||
@@ -146,3 +146,6 @@ inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.flatMapToNullable(des
|
||||
}
|
||||
return destination
|
||||
}
|
||||
|
||||
fun <E : Enum<E>> min(a: E, b: E): E = if (a < b) a else b
|
||||
fun <E : Comparable<E>> min(a: E, b: E): E = if (a < b) a else b
|
||||
@@ -1,3 +1,5 @@
|
||||
// IGNORE_FIR
|
||||
|
||||
class Foo {
|
||||
fun invoke(vararg a: Any) {}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// IGNORE_FIR
|
||||
|
||||
class Foo {
|
||||
fun invoke(vararg a: Any) {}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// IGNORE_FIR
|
||||
|
||||
class Foo {
|
||||
fun invoke(vararg a: Any) {}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// IGNORE_FIR
|
||||
|
||||
class Foo {
|
||||
fun invoke(vararg a: Any) {}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// IGNORE_FIR
|
||||
|
||||
class Foo {
|
||||
fun invoke(vararg a: Any) {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user