FIR: add mapping to partially resolved arg list
Initially I tried adding `mapping` field to `FirArgumentList` but it seems to be very difficult to make it flexible enough to do what I want. So instead, I am creating a `FirPartialResolvedArgumentList`, which seems to be very simple.
This commit is contained in:
committed by
Mikhail Glukhikh
parent
5d3afbad54
commit
9476175cc2
+1
-1
@@ -465,7 +465,7 @@ class CallAndReferenceGenerator(
|
|||||||
((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirFunctionSymbol<*>)?.fir
|
((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirFunctionSymbol<*>)?.fir
|
||||||
}
|
}
|
||||||
val valueParameters = function?.valueParameters
|
val valueParameters = function?.valueParameters
|
||||||
val argumentMapping = call.argumentMapping
|
val argumentMapping = call.resolvedArgumentMapping
|
||||||
val substitutor = (call as? FirFunctionCall)?.buildSubstitutorByCalledFunction(function) ?: ConeSubstitutor.Empty
|
val substitutor = (call as? FirFunctionCall)?.buildSubstitutorByCalledFunction(function) ?: ConeSubstitutor.Empty
|
||||||
if (argumentMapping != null && (annotationMode || argumentMapping.isNotEmpty())) {
|
if (argumentMapping != null && (annotationMode || argumentMapping.isNotEmpty())) {
|
||||||
if (valueParameters != null) {
|
if (valueParameters != null) {
|
||||||
|
|||||||
+15
-4
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReferenc
|
|||||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.CallableReferenceAdaptation
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer
|
import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.*
|
import org.jetbrains.kotlin.fir.resolve.inference.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
@@ -161,7 +160,11 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
resultType = typeRef.substituteTypeRef(subCandidate)
|
resultType = typeRef.substituteTypeRef(subCandidate)
|
||||||
val expectedArgumentsTypeMapping = runIf(!calleeReference.isError) { subCandidate.createArgumentsMapping() }
|
val expectedArgumentsTypeMapping = runIf(!calleeReference.isError) { subCandidate.createArgumentsMapping() }
|
||||||
result.argumentList.transformArguments(this, expectedArgumentsTypeMapping)
|
result.argumentList.transformArguments(this, expectedArgumentsTypeMapping)
|
||||||
if (!calleeReference.isError) {
|
if (calleeReference.isError) {
|
||||||
|
subCandidate.argumentMapping?.let {
|
||||||
|
result.replaceArgumentList(buildPartiallyResolvedArgumentList(result.argumentList, it))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
subCandidate.handleVarargs()
|
subCandidate.handleVarargs()
|
||||||
subCandidate.argumentMapping?.let {
|
subCandidate.argumentMapping?.let {
|
||||||
result.replaceArgumentList(buildResolvedArgumentList(it))
|
result.replaceArgumentList(buildResolvedArgumentList(it))
|
||||||
@@ -212,7 +215,11 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!calleeReference.isError) {
|
if (calleeReference.isError) {
|
||||||
|
subCandidate.argumentMapping?.let {
|
||||||
|
annotationCall.replaceArgumentList(buildPartiallyResolvedArgumentList(annotationCall.argumentList, it))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
subCandidate.handleVarargs()
|
subCandidate.handleVarargs()
|
||||||
subCandidate.argumentMapping?.let {
|
subCandidate.argumentMapping?.let {
|
||||||
annotationCall.replaceArgumentList(buildResolvedArgumentList(it))
|
annotationCall.replaceArgumentList(buildResolvedArgumentList(it))
|
||||||
@@ -367,7 +374,11 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
|
|
||||||
val argumentsMapping = runIf(!calleeReference.isError) { calleeReference.candidate.createArgumentsMapping() }
|
val argumentsMapping = runIf(!calleeReference.isError) { calleeReference.candidate.createArgumentsMapping() }
|
||||||
delegatedConstructorCall.argumentList.transformArguments(this, argumentsMapping)
|
delegatedConstructorCall.argumentList.transformArguments(this, argumentsMapping)
|
||||||
if (!calleeReference.isError) {
|
if (calleeReference.isError) {
|
||||||
|
subCandidate.argumentMapping?.let {
|
||||||
|
delegatedConstructorCall.replaceArgumentList(buildPartiallyResolvedArgumentList(delegatedConstructorCall.argumentList, it))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
subCandidate.handleVarargs()
|
subCandidate.handleVarargs()
|
||||||
subCandidate.argumentMapping?.let {
|
subCandidate.argumentMapping?.let {
|
||||||
delegatedConstructorCall.replaceArgumentList(buildResolvedArgumentList(it))
|
delegatedConstructorCall.replaceArgumentList(buildResolvedArgumentList(it))
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirSourceElement
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList
|
import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirArraySetArgumentList
|
import org.jetbrains.kotlin.fir.expressions.impl.FirArraySetArgumentList
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirPartiallyResolvedArgumentList
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
|
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
|
||||||
|
|
||||||
fun buildUnaryArgumentList(argument: FirExpression): FirArgumentList = buildArgumentList {
|
fun buildUnaryArgumentList(argument: FirExpression): FirArgumentList = buildArgumentList {
|
||||||
@@ -26,6 +27,16 @@ fun buildArraySetArgumentList(rValue: FirExpression, indexes: List<FirExpression
|
|||||||
fun buildResolvedArgumentList(mapping: LinkedHashMap<FirExpression, FirValueParameter>): FirArgumentList =
|
fun buildResolvedArgumentList(mapping: LinkedHashMap<FirExpression, FirValueParameter>): FirArgumentList =
|
||||||
FirResolvedArgumentList(mapping)
|
FirResolvedArgumentList(mapping)
|
||||||
|
|
||||||
|
fun buildPartiallyResolvedArgumentList(
|
||||||
|
original: FirArgumentList,
|
||||||
|
mapping: LinkedHashMap<FirExpression, FirValueParameter>
|
||||||
|
): FirArgumentList {
|
||||||
|
return FirPartiallyResolvedArgumentList(
|
||||||
|
original.source,
|
||||||
|
original.arguments.map { key -> key to mapping[key] }.toMap(LinkedHashMap())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
object FirEmptyArgumentList : FirAbstractArgumentList() {
|
object FirEmptyArgumentList : FirAbstractArgumentList() {
|
||||||
override val arguments: List<FirExpression>
|
override val arguments: List<FirExpression>
|
||||||
get() = emptyList()
|
get() = emptyList()
|
||||||
|
|||||||
@@ -11,8 +11,10 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
|||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildErrorExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildErrorExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildErrorLoop
|
import org.jetbrains.kotlin.fir.expressions.builder.buildErrorLoop
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirBlockImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirBlockImpl
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirPartiallyResolvedArgumentList
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
@@ -41,8 +43,18 @@ inline val FirCall.arguments: List<FirExpression> get() = argumentList.arguments
|
|||||||
|
|
||||||
inline val FirCall.argument: FirExpression get() = argumentList.arguments.first()
|
inline val FirCall.argument: FirExpression get() = argumentList.arguments.first()
|
||||||
|
|
||||||
|
inline val FirCall.resolvedArgumentMapping: LinkedHashMap<FirExpression, FirValueParameter>?
|
||||||
|
get() = when (val argumentList = argumentList) {
|
||||||
|
is FirResolvedArgumentList -> argumentList.mapping
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
inline val FirCall.argumentMapping: LinkedHashMap<FirExpression, FirValueParameter>?
|
inline val FirCall.argumentMapping: LinkedHashMap<FirExpression, FirValueParameter>?
|
||||||
get() = (argumentList as? FirResolvedArgumentList)?.mapping
|
get() = when (val argumentList = argumentList) {
|
||||||
|
is FirResolvedArgumentList -> argumentList.mapping
|
||||||
|
is FirPartiallyResolvedArgumentList -> argumentList.mapping
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
fun FirExpression.toResolvedCallableReference(): FirResolvedNamedReference? {
|
fun FirExpression.toResolvedCallableReference(): FirResolvedNamedReference? {
|
||||||
if (this is FirWrappedArgumentExpression) return expression.toResolvedCallableReference()
|
if (this is FirWrappedArgumentExpression) return expression.toResolvedCallableReference()
|
||||||
|
|||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.expressions.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirArgumentList
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||||
|
|
||||||
|
class FirPartiallyResolvedArgumentList internal constructor(
|
||||||
|
override var source: FirSourceElement?,
|
||||||
|
private var _mapping: LinkedHashMap<FirExpression, FirValueParameter?>
|
||||||
|
) : FirArgumentList() {
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val mapping: LinkedHashMap<FirExpression, FirValueParameter> =
|
||||||
|
_mapping.filterValues { it != null } as LinkedHashMap<FirExpression, FirValueParameter>
|
||||||
|
|
||||||
|
|
||||||
|
override val arguments: List<FirExpression>
|
||||||
|
get() = _mapping.keys.toList()
|
||||||
|
|
||||||
|
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||||
|
_mapping.forEach { (k, _) -> k.accept(visitor, data) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirPartiallyResolvedArgumentList {
|
||||||
|
transformArguments(transformer, data)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <D> transformArguments(transformer: FirTransformer<D>, data: D): FirPartiallyResolvedArgumentList {
|
||||||
|
_mapping = _mapping.mapKeys { (k, _) -> k.transformSingle(transformer, data) } as LinkedHashMap<FirExpression, FirValueParameter?>
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun replaceSource(newSource: FirSourceElement?) {
|
||||||
|
source = newSource
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -11,5 +11,5 @@ enum class MyEnum {
|
|||||||
A
|
A
|
||||||
}
|
}
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>@AnnE(Test())<!>
|
<!INAPPLICABLE_CANDIDATE!>@AnnE(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>Test()<!>)<!>
|
||||||
class Test2
|
class Test2
|
||||||
|
|||||||
+1
-1
@@ -11,5 +11,5 @@ enum class MyEnum {
|
|||||||
A
|
A
|
||||||
}
|
}
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>@AnnE(Test())<!>
|
<!INAPPLICABLE_CANDIDATE!>@AnnE(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>Test()<!>)<!>
|
||||||
class Test2
|
class Test2
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ fun foo1() {}
|
|||||||
@Anno(x = ["a", "b"], y = "a")
|
@Anno(x = ["a", "b"], y = "a")
|
||||||
fun foo2() {}
|
fun foo2() {}
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>@Anno(x = arrayOf(arrayOf("a"), arrayOf("b")), y = "a")<!>
|
<!INAPPLICABLE_CANDIDATE!>@Anno(x = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>arrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>arrayOf("a")<!>, <!ANNOTATION_ARGUMENT_MUST_BE_CONST!>arrayOf("b")<!>)<!>, y = "a")<!>
|
||||||
fun foo3() {}
|
fun foo3() {}
|
||||||
|
|
||||||
@Anno(x = arrayOf("a", "b"), y = "a")
|
@Anno(x = arrayOf("a", "b"), y = "a")
|
||||||
|
|||||||
Reference in New Issue
Block a user