FIR: add support for varargs in annotation calls
This commit is contained in:
committed by
Mikhail Glukhikh
parent
4e6bd33eca
commit
5600eefea5
@@ -1,5 +1,5 @@
|
||||
FILE: annotations.kt
|
||||
@R|kotlin/annotation/Target|(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FILE|, Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FUNCTION|, Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.TYPE|, Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|) public final annotation class Simple : R|kotlin/Annotation| {
|
||||
@R|kotlin/annotation/Target|(vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FILE|, Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FUNCTION|, Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.TYPE|, Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|)) public final annotation class Simple : R|kotlin/Annotation| {
|
||||
public constructor(): R|annotations/Simple| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
FILE: lowPriorityInResolution.kt
|
||||
@R|kotlin/Suppress|(String(INVISIBLE_MEMBER), String(INVISIBLE_REFERENCE)) @R|kotlin/internal/LowPriorityInOverloadResolution|() public final fun foo(): R|kotlin/Int| {
|
||||
@R|kotlin/Suppress|(vararg(String(INVISIBLE_MEMBER), String(INVISIBLE_REFERENCE))) @R|kotlin/internal/LowPriorityInOverloadResolution|() public final fun foo(): R|kotlin/Int| {
|
||||
^foo Int(1)
|
||||
}
|
||||
public final fun foo(): R|kotlin/String| {
|
||||
|
||||
+30
-5
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildErrorExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildVariableAssignment
|
||||
import org.jetbrains.kotlin.fir.references.*
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||
@@ -39,6 +40,7 @@ import org.jetbrains.kotlin.fir.visitors.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import kotlin.math.min
|
||||
|
||||
open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : FirPartialBodyResolveTransformer(transformer) {
|
||||
private inline val builtinTypes: BuiltinTypes get() = session.builtinTypes
|
||||
@@ -692,16 +694,39 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
||||
// TODO: it's temporary incorrect solution until we design resolve and completion for annotation calls
|
||||
it.argumentList.transformArguments(integerLiteralTypeApproximator, null)
|
||||
annotationCall.getCorrespondingConstructorReferenceOrNull(session)?.let { calleeReference ->
|
||||
val argumentMapping =
|
||||
mapArguments(it.arguments, calleeReference.resolvedSymbol.fir as FirFunction<*>)
|
||||
.toArgumentToParameterMapping()
|
||||
it.replaceArgumentList(buildResolvedArgumentList(argumentMapping))
|
||||
val callee = calleeReference.resolvedSymbol.fir as FirFunction<*>
|
||||
val argumentMapping = mapArguments(it.arguments, callee).toArgumentToParameterMapping()
|
||||
val varargParameter = callee.valueParameters.firstOrNull { param -> param.isVararg }
|
||||
if (varargParameter == null) {
|
||||
it.replaceArgumentList(buildResolvedArgumentList(argumentMapping))
|
||||
} else {
|
||||
// TODO: refactor/reuse [Candidate#handleVarargs] in [FirCallCompletionResultsWriterTransformer]
|
||||
val varargParameterTypeRef = varargParameter.returnTypeRef
|
||||
val arrayType = varargParameterTypeRef.coneType
|
||||
val elementType = arrayType.arrayElementType()
|
||||
var firstIndex = it.argumentList.arguments.size
|
||||
val newArgumentMapping = mutableMapOf<FirExpression, FirValueParameter>()
|
||||
val varargArgument = buildVarargArgumentsExpression {
|
||||
varargElementType = varargParameterTypeRef.withReplacedConeType(elementType)
|
||||
this@buildVarargArgumentsExpression.typeRef = varargParameterTypeRef
|
||||
for ((i, arg) in it.argumentList.arguments.withIndex()) {
|
||||
val valueParameter = argumentMapping[arg] ?: continue
|
||||
if (valueParameter.isVararg) {
|
||||
firstIndex = min(firstIndex, i)
|
||||
arguments += arg
|
||||
} else {
|
||||
newArgumentMapping[arg] = valueParameter
|
||||
}
|
||||
}
|
||||
}
|
||||
newArgumentMapping[varargArgument] = varargParameter
|
||||
it.replaceArgumentList(buildResolvedArgumentList(newArgumentMapping))
|
||||
}
|
||||
}
|
||||
it.replaceResolveStatus(status)
|
||||
dataFlowAnalyzer.exitAnnotationCall(it)
|
||||
}.compose()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private inline fun <T> withFirArrayOfCallTransformer(block: () -> T): T {
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: -ProhibitAssigningSingleElementsToVarargsInNamedForm
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// FULL_JDK
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// FULL_JDK
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// WITH_REFLECT
|
||||
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
import java.util.Arrays
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
|
||||
Vendored
+4
-2
@@ -28,12 +28,14 @@ FILE fqName:<root> fileName:/annotationsWithVarargParameters.kt
|
||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
annotations:
|
||||
A(xs = ['abc', 'def'])
|
||||
BLOCK_BODY
|
||||
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
annotations:
|
||||
A(xs = 'abc')
|
||||
A(xs = ['abc'])
|
||||
BLOCK_BODY
|
||||
FUN name:test3 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
annotations:
|
||||
A(xs = <null>)
|
||||
A(xs = [])
|
||||
BLOCK_BODY
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ FILE fqName:test fileName:/fileAnnotations.kt
|
||||
A(x = 'File annotation')
|
||||
CLASS ANNOTATION_CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Annotation]
|
||||
annotations:
|
||||
Target(allowedTargets = GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:FILE' type=kotlin.annotation.AnnotationTarget)
|
||||
Target(allowedTargets = [GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:FILE' type=kotlin.annotation.AnnotationTarget])
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:test.A
|
||||
CONSTRUCTOR visibility:public <> (x:kotlin.String) returnType:test.A [primary]
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.String
|
||||
|
||||
Vendored
+2
@@ -28,4 +28,6 @@ FILE fqName:<root> fileName:/spreadOperatorInAnnotationArguments.kt
|
||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
annotations:
|
||||
A(xs = [SPREAD_ELEMENT, SPREAD_ELEMENT])
|
||||
BLOCK_BODY
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ FILE fqName:<root> fileName:/typeAliasesWithAnnotations.kt
|
||||
TYPEALIAS name:TestTypeAlias visibility:public expandedType:kotlin.String
|
||||
CLASS ANNOTATION_CLASS name:TestAnn modality:FINAL visibility:public superTypes:[kotlin.Annotation]
|
||||
annotations:
|
||||
Target(allowedTargets = GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:TYPEALIAS' type=kotlin.annotation.AnnotationTarget)
|
||||
Target(allowedTargets = [GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:TYPEALIAS' type=kotlin.annotation.AnnotationTarget])
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.TestAnn
|
||||
CONSTRUCTOR visibility:public <> (x:kotlin.String) returnType:<root>.TestAnn [primary]
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.String
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
FILE fqName:<root> fileName:/typeParametersWithAnnotations.kt
|
||||
CLASS ANNOTATION_CLASS name:Anno modality:FINAL visibility:public superTypes:[kotlin.Annotation]
|
||||
annotations:
|
||||
Target(allowedTargets = GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:TYPE_PARAMETER' type=kotlin.annotation.AnnotationTarget)
|
||||
Target(allowedTargets = [GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:TYPE_PARAMETER' type=kotlin.annotation.AnnotationTarget])
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Anno
|
||||
CONSTRUCTOR visibility:public <> () returnType:<root>.Anno [primary]
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
|
||||
+7
-3
@@ -84,10 +84,14 @@ FILE fqName:<root> fileName:/varargsInAnnotationArguments.kt
|
||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
annotations:
|
||||
A1(xs = ['1', '2', '3'])
|
||||
A2(xs = ['a', 'b', 'c'])
|
||||
AA(xs = [A1(xs = ['4']), A1(xs = ['5']), A1(xs = ['6'])])
|
||||
BLOCK_BODY
|
||||
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
annotations:
|
||||
A1(xs = <null>)
|
||||
A2(xs = <null>)
|
||||
AA(xs = <null>)
|
||||
A1(xs = [])
|
||||
A2(xs = [])
|
||||
AA(xs = [])
|
||||
BLOCK_BODY
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FILE fqName:<root> fileName:/castsInsideCoroutineInference.kt
|
||||
FUN name:scopedFlow visibility:public modality:FINAL <R> (block:kotlin.coroutines.SuspendFunction2<<root>.CoroutineScope, <root>.FlowCollector<R of <root>.scopedFlow>, kotlin.Unit>) returnType:<root>.Flow<R of <root>.scopedFlow>
|
||||
annotations:
|
||||
OptIn(markerClass = CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB ANNOTATION_CLASS name:ExperimentalTypeInference modality:FINAL visibility:public superTypes:[kotlin.Annotation]' type=kotlin.reflect.KClass<kotlin.experimental.ExperimentalTypeInference>)
|
||||
OptIn(markerClass = [CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB ANNOTATION_CLASS name:ExperimentalTypeInference modality:FINAL visibility:public superTypes:[kotlin.Annotation]' type=kotlin.reflect.KClass<kotlin.experimental.ExperimentalTypeInference>])
|
||||
TYPE_PARAMETER name:R index:0 variance: superTypes:[kotlin.Any?]
|
||||
VALUE_PARAMETER name:block index:0 type:kotlin.coroutines.SuspendFunction2<<root>.CoroutineScope, <root>.FlowCollector<R of <root>.scopedFlow>, kotlin.Unit>
|
||||
annotations:
|
||||
@@ -53,7 +53,7 @@ FILE fqName:<root> fileName:/castsInsideCoroutineInference.kt
|
||||
BLOCK_BODY
|
||||
FUN name:unsafeFlow visibility:public modality:FINAL <T> (block:kotlin.coroutines.SuspendFunction1<<root>.FlowCollector<T of <root>.unsafeFlow>, kotlin.Unit>) returnType:<root>.Flow<T of <root>.unsafeFlow> [inline]
|
||||
annotations:
|
||||
OptIn(markerClass = CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB ANNOTATION_CLASS name:ExperimentalTypeInference modality:FINAL visibility:public superTypes:[kotlin.Annotation]' type=kotlin.reflect.KClass<kotlin.experimental.ExperimentalTypeInference>)
|
||||
OptIn(markerClass = [CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB ANNOTATION_CLASS name:ExperimentalTypeInference modality:FINAL visibility:public superTypes:[kotlin.Annotation]' type=kotlin.reflect.KClass<kotlin.experimental.ExperimentalTypeInference>])
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?]
|
||||
VALUE_PARAMETER name:block index:0 type:kotlin.coroutines.SuspendFunction1<<root>.FlowCollector<T of <root>.unsafeFlow>, kotlin.Unit> [crossinline]
|
||||
annotations:
|
||||
@@ -191,7 +191,7 @@ FILE fqName:<root> fileName:/castsInsideCoroutineInference.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN name:flow visibility:public modality:FINAL <T> (block:kotlin.coroutines.SuspendFunction1<<root>.FlowCollector<T of <root>.flow>, kotlin.Unit>) returnType:<root>.Flow<T of <root>.flow>
|
||||
annotations:
|
||||
OptIn(markerClass = CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB ANNOTATION_CLASS name:ExperimentalTypeInference modality:FINAL visibility:public superTypes:[kotlin.Annotation]' type=kotlin.reflect.KClass<kotlin.experimental.ExperimentalTypeInference>)
|
||||
OptIn(markerClass = [CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB ANNOTATION_CLASS name:ExperimentalTypeInference modality:FINAL visibility:public superTypes:[kotlin.Annotation]' type=kotlin.reflect.KClass<kotlin.experimental.ExperimentalTypeInference>])
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?]
|
||||
VALUE_PARAMETER name:block index:0 type:kotlin.coroutines.SuspendFunction1<<root>.FlowCollector<T of <root>.flow>, kotlin.Unit>
|
||||
annotations:
|
||||
@@ -201,7 +201,7 @@ FILE fqName:<root> fileName:/castsInsideCoroutineInference.kt
|
||||
CALL 'public final fun TODO (): kotlin.Nothing [inline] declared in kotlin' type=kotlin.Nothing origin=null
|
||||
FUN name:flowScope visibility:public modality:FINAL <R> (block:kotlin.coroutines.SuspendFunction1<<root>.CoroutineScope, R of <root>.flowScope>) returnType:R of <root>.flowScope [suspend]
|
||||
annotations:
|
||||
OptIn(markerClass = CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB ANNOTATION_CLASS name:ExperimentalTypeInference modality:FINAL visibility:public superTypes:[kotlin.Annotation]' type=kotlin.reflect.KClass<kotlin.experimental.ExperimentalTypeInference>)
|
||||
OptIn(markerClass = [CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB ANNOTATION_CLASS name:ExperimentalTypeInference modality:FINAL visibility:public superTypes:[kotlin.Annotation]' type=kotlin.reflect.KClass<kotlin.experimental.ExperimentalTypeInference>])
|
||||
TYPE_PARAMETER name:R index:0 variance: superTypes:[kotlin.Any?]
|
||||
VALUE_PARAMETER name:block index:0 type:kotlin.coroutines.SuspendFunction1<<root>.CoroutineScope, R of <root>.flowScope>
|
||||
annotations:
|
||||
@@ -309,7 +309,7 @@ FILE fqName:<root> fileName:/castsInsideCoroutineInference.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN name:produce visibility:public modality:FINAL <E> ($receiver:<root>.CoroutineScope, block:kotlin.coroutines.SuspendFunction1<<root>.ProducerScope<E of <root>.produce>, kotlin.Unit>) returnType:<root>.ReceiveChannel<E of <root>.produce>
|
||||
annotations:
|
||||
OptIn(markerClass = CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB ANNOTATION_CLASS name:ExperimentalTypeInference modality:FINAL visibility:public superTypes:[kotlin.Annotation]' type=kotlin.reflect.KClass<kotlin.experimental.ExperimentalTypeInference>)
|
||||
OptIn(markerClass = [CLASS_REFERENCE 'CLASS IR_EXTERNAL_DECLARATION_STUB ANNOTATION_CLASS name:ExperimentalTypeInference modality:FINAL visibility:public superTypes:[kotlin.Annotation]' type=kotlin.reflect.KClass<kotlin.experimental.ExperimentalTypeInference>])
|
||||
TYPE_PARAMETER name:E index:0 variance: superTypes:[kotlin.Any?]
|
||||
$receiver: VALUE_PARAMETER name:<this> type:<root>.CoroutineScope
|
||||
VALUE_PARAMETER name:block index:0 type:kotlin.coroutines.SuspendFunction1<<root>.ProducerScope<E of <root>.produce>, kotlin.Unit>
|
||||
|
||||
Reference in New Issue
Block a user