[FIR] Consider call site in argument mapping handling for set operator call
^KT-56542 Fixed ^KT-56714 Fixed
This commit is contained in:
committed by
Space Team
parent
cbc8b74e89
commit
df47581c5a
+12
@@ -921,6 +921,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/overloadWithDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("setWithTrailingLambda.kt")
|
||||
public void testSetWithTrailingLambda() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
@@ -957,6 +963,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/vararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("varargFromJava.kt")
|
||||
public void testVarargFromJava() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("varargOfLambdasWithReceiver.kt")
|
||||
public void testVarargOfLambdasWithReceiver() throws Exception {
|
||||
|
||||
+10
@@ -784,6 +784,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/overloadWithDefault.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("setWithTrailingLambda.kt")
|
||||
public void testSetWithTrailingLambda() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/simple.kt");
|
||||
@@ -814,6 +819,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/vararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("varargFromJava.kt")
|
||||
public void testVarargFromJava() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("varargOfLambdasWithReceiver.kt")
|
||||
public void testVarargOfLambdasWithReceiver() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/varargOfLambdasWithReceiver.kt");
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
FILE: setWithTrailingLambda.kt
|
||||
public final fun test(m: R|MyMap<EditorData, kotlin/Any>|): R|kotlin/Unit| {
|
||||
R|<local>/m|.R|SubstitutionOverride</MyMap.set: R|kotlin/Unit|>|<R|(kotlin/String, @R|kotlin/ParameterName|(name = String(bar)) kotlin/Any) -> kotlin/Unit|>(Q|SomeKey|, <L> = set@fun <anonymous>(<unused var>: R|kotlin/String|, <unused var>: R|@R|kotlin/ParameterName|(name = String(bar)) kotlin/Any|): R|kotlin/Unit| <inline=NoInline> {
|
||||
^@set Unit
|
||||
}
|
||||
)
|
||||
R|<local>/m|.R|SubstitutionOverride</MyMap.set: R|kotlin/Unit|>|<R|(kotlin/String, @R|kotlin/ParameterName|(name = String(bar)) kotlin/Any) -> kotlin/Unit|>(Q|SomeKey|, fun <anonymous>(<unused var>: R|kotlin/String|, <unused var>: R|@R|kotlin/ParameterName|(name = String(bar)) kotlin/Any|): R|kotlin/Unit| <inline=NoInline> {
|
||||
^ Unit
|
||||
}
|
||||
)
|
||||
}
|
||||
public final data class EditorData : R|kotlin/Any| {
|
||||
public constructor(meta: R|MyMap<EditorData, kotlin/Any>|): R|EditorData| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val meta: R|MyMap<EditorData, kotlin/Any>| = R|<local>/meta|
|
||||
public get(): R|MyMap<EditorData, kotlin/Any>|
|
||||
|
||||
public final operator fun component1(): R|MyMap<EditorData, kotlin/Any>|
|
||||
|
||||
public final fun copy(meta: R|MyMap<EditorData, kotlin/Any>| = this@R|/EditorData|.R|/EditorData.meta|): R|EditorData|
|
||||
|
||||
}
|
||||
public abstract interface MyMap<Domain, V : R|kotlin/Any|> : R|kotlin/Any| {
|
||||
public abstract operator fun <T : R|V|> set(k: R|Key<T, Domain>|, v: R|T|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public abstract interface Key<V : R|kotlin/Any|, in Domain> : R|kotlin/Any| {
|
||||
}
|
||||
public abstract interface EditorDataKey<T : R|kotlin/Any|> : R|Key<T, EditorData>| {
|
||||
}
|
||||
public final object SomeKey : R|EditorDataKey<kotlin/Function2<kotlin/String, @R|kotlin/ParameterName|(name = String(bar)) kotlin/Any, kotlin/Unit>>| {
|
||||
private constructor(): R|SomeKey| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// ISSUE: KT-56714
|
||||
|
||||
fun test(m: MyMap<EditorData, Any>) {
|
||||
m.set(SomeKey) { _, _ -> }
|
||||
m[SomeKey] = { _, _ -> }
|
||||
}
|
||||
|
||||
data class EditorData(val meta: MyMap<EditorData, Any>)
|
||||
|
||||
interface MyMap<Domain, V : Any> {
|
||||
operator fun <T : V> set(k: Key<T, Domain>, v: T)
|
||||
}
|
||||
|
||||
interface Key<V : Any, in Domain>
|
||||
|
||||
interface EditorDataKey<T : Any> : Key<T, EditorData>
|
||||
|
||||
object SomeKey : EditorDataKey<(String, bar: Any) -> Unit>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
FILE: main.kt
|
||||
public final class Some : R|kotlin/Any| {
|
||||
public constructor(): R|Some| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun test(handle: R|VarHandle|): R|kotlin/Unit| {
|
||||
R|<local>/handle|.R|/VarHandle.set|(vararg(this@R|/Some|, Boolean(false)))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// FILE: VarHandle.java
|
||||
public class VarHandle {
|
||||
public void set(Object... args) {}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
class Some {
|
||||
fun test(handle: VarHandle) {
|
||||
handle.set(this, false)
|
||||
}
|
||||
}
|
||||
+12
@@ -921,6 +921,12 @@ public class FirLightTreeDiagnosticsTestGenerated extends AbstractFirLightTreeDi
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/overloadWithDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("setWithTrailingLambda.kt")
|
||||
public void testSetWithTrailingLambda() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
@@ -957,6 +963,12 @@ public class FirLightTreeDiagnosticsTestGenerated extends AbstractFirLightTreeDi
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/vararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("varargFromJava.kt")
|
||||
public void testVarargFromJava() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("varargOfLambdasWithReceiver.kt")
|
||||
public void testVarargOfLambdasWithReceiver() throws Exception {
|
||||
|
||||
+12
@@ -921,6 +921,12 @@ public class FirPsiDiagnosticTestGenerated extends AbstractFirPsiDiagnosticTest
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/overloadWithDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("setWithTrailingLambda.kt")
|
||||
public void testSetWithTrailingLambda() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/setWithTrailingLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
@@ -957,6 +963,12 @@ public class FirPsiDiagnosticTestGenerated extends AbstractFirPsiDiagnosticTest
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/vararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("varargFromJava.kt")
|
||||
public void testVarargFromJava() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/varargFromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("varargOfLambdasWithReceiver.kt")
|
||||
public void testVarargOfLambdasWithReceiver() throws Exception {
|
||||
|
||||
+1
-1
@@ -174,7 +174,7 @@ private fun BodyResolveComponents.getCallableReferenceAdaptation(
|
||||
|
||||
val fakeArguments = createFakeArgumentsForReference(function, expectedArgumentsCount, inputTypes, unboundReceiverCount)
|
||||
// TODO: Use correct originScope
|
||||
val argumentMapping = mapArguments(fakeArguments, function, originScope = null)
|
||||
val argumentMapping = mapArguments(fakeArguments, function, originScope = null, callSiteIsOperatorCall = false)
|
||||
if (argumentMapping.diagnostics.any { !it.applicability.isSuccess }) return null
|
||||
|
||||
/**
|
||||
|
||||
+3
-2
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isOperator
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.isIntersectionOverride
|
||||
import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
|
||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultParameterResolver
|
||||
@@ -65,6 +64,7 @@ fun BodyResolveComponents.mapArguments(
|
||||
arguments: List<FirExpression>,
|
||||
function: FirFunction,
|
||||
originScope: FirScope?,
|
||||
callSiteIsOperatorCall: Boolean
|
||||
): ArgumentMapping {
|
||||
if (arguments.isEmpty() && function.valueParameters.isEmpty()) {
|
||||
return EmptyArgumentMapping
|
||||
@@ -87,7 +87,8 @@ fun BodyResolveComponents.mapArguments(
|
||||
|
||||
// If this is an indexed access set operator, it could have default values or a vararg parameter in the middle.
|
||||
// For proper argument mapping, wrap the last one, which is supposed to be the updated value, as a named argument.
|
||||
val isIndexedSetOperator = function is FirSimpleFunction
|
||||
val isIndexedSetOperator = callSiteIsOperatorCall
|
||||
&& function is FirSimpleFunction
|
||||
&& function.isOperator
|
||||
&& function.name == OperatorNameConventions.SET
|
||||
&& function.origin !is FirDeclarationOrigin.DynamicScope
|
||||
|
||||
@@ -424,8 +424,12 @@ internal object MapArguments : ResolutionStage() {
|
||||
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
|
||||
val symbol = candidate.symbol as? FirFunctionSymbol<*> ?: return sink.reportDiagnostic(HiddenCandidate)
|
||||
val function = symbol.fir
|
||||
|
||||
val mapping = context.bodyResolveComponents.mapArguments(callInfo.arguments, function, candidate.originScope)
|
||||
val mapping = context.bodyResolveComponents.mapArguments(
|
||||
callInfo.arguments,
|
||||
function,
|
||||
candidate.originScope,
|
||||
callSiteIsOperatorCall = (callInfo.callSite as? FirFunctionCall)?.origin == FirFunctionCallOrigin.Operator
|
||||
)
|
||||
candidate.argumentMapping = mapping.toArgumentToParameterMapping()
|
||||
candidate.numDefaults = mapping.numDefaults()
|
||||
|
||||
|
||||
@@ -15,5 +15,5 @@ fun main() {
|
||||
1.set(2, z = 1)
|
||||
1[2] += 1
|
||||
|
||||
1.set(2, 1)
|
||||
1.set(2, <!NO_VALUE_FOR_PARAMETER!>1)<!>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user