diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirValueParameterSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirValueParameterSymbol.kt index c82f798833b..4b929bf5ebf 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirValueParameterSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirValueParameterSymbol.kt @@ -8,9 +8,13 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols import com.intellij.psi.PsiElement import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirValueParameter +import org.jetbrains.kotlin.fir.renderWithType +import org.jetbrains.kotlin.fir.types.arrayElementType +import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.idea.fir.findPsi import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder +import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.annotations.KtFirAnnotationCall import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.annotations.containsAnnotation import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.annotations.getAnnotationClassIds import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.annotations.toAnnotationsList @@ -38,8 +42,18 @@ internal class KtFirValueParameterSymbol( override val name: Name get() = firRef.withFir { it.name } override val isVararg: Boolean get() = firRef.withFir { it.isVararg } - override val annotatedType: KtTypeAndAnnotations by cached { - firRef.returnTypeAndAnnotations(FirResolvePhase.TYPES, builder) + override val annotatedType: KtTypeAndAnnotations by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir -> + if (fir.isVararg) { + val annotations = fir.returnTypeRef.annotations.map { annotation -> + KtFirAnnotationCall(firRef, annotation) + } + // There SHOULD always be an array element type (even if it is an error type, e.g., unresolved). + val arrayElementType = fir.returnTypeRef.coneType.arrayElementType() + ?: error("No array element type for vararg value parameter: ${fir.renderWithType()}") + KtSimpleFirTypeAndAnnotations(arrayElementType, annotations, builder, firRef.token) + } else { + firRef.returnTypeAndAnnotations(FirResolvePhase.TYPES, builder) + } } override val hasDefaultValue: Boolean get() = firRef.withFir { it.defaultValue != null } diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithSpreadArgument.txt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithSpreadArgument.txt index 1d9df90e365..02e1fb92990 100644 --- a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithSpreadArgument.txt +++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithSpreadArgument.txt @@ -1,3 +1,3 @@ KtFunctionCall: -argumentMapping = { args -> (vararg a: kotlin.IntArray) } -targetFunction = /function(vararg a: kotlin.IntArray): kotlin.Unit \ No newline at end of file +argumentMapping = { args -> (vararg a: kotlin.Int) } +targetFunction = /function(vararg a: kotlin.Int): kotlin.Unit \ No newline at end of file diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithVarargArgument.txt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithVarargArgument.txt index 5dc3bdaea10..f0a10570161 100644 --- a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithVarargArgument.txt +++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithVarargArgument.txt @@ -1,3 +1,3 @@ KtFunctionCall: -argumentMapping = { 1 -> (vararg a: kotlin.IntArray), 2 -> (vararg a: kotlin.IntArray), 3 -> (vararg a: kotlin.IntArray) } -targetFunction = /function(vararg a: kotlin.IntArray): kotlin.Unit \ No newline at end of file +argumentMapping = { 1 -> (vararg a: kotlin.Int), 2 -> (vararg a: kotlin.Int), 3 -> (vararg a: kotlin.Int) } +targetFunction = /function(vararg a: kotlin.Int): kotlin.Unit \ No newline at end of file diff --git a/idea/idea-frontend-fir/testData/symbols/symbolByPsi/varargFunctions.kt b/idea/idea-frontend-fir/testData/symbols/symbolByPsi/varargFunctions.kt new file mode 100644 index 00000000000..bd345e3042d --- /dev/null +++ b/idea/idea-frontend-fir/testData/symbols/symbolByPsi/varargFunctions.kt @@ -0,0 +1,4 @@ +fun primitive(vararg a: Int) +fun nullablePrimitive(vararg b: Float?) +fun nonPrimitive(vararg c: Any) +fun error(vararg d: Unresolved) diff --git a/idea/idea-frontend-fir/testData/symbols/symbolByPsi/varargFunctions.txt b/idea/idea-frontend-fir/testData/symbols/symbolByPsi/varargFunctions.txt new file mode 100644 index 00000000000..2ca4d1b9f7f --- /dev/null +++ b/idea/idea-frontend-fir/testData/symbols/symbolByPsi/varargFunctions.txt @@ -0,0 +1,163 @@ +KtFirValueParameterSymbol: + annotatedType: [] kotlin/Int + annotationClassIds: [] + annotations: [] + callableIdIfNonLocal: null + hasDefaultValue: false + isExtension: false + isVararg: true + name: a + origin: SOURCE + receiverType: null + symbolKind: LOCAL + deprecationStatus: null + +KtFirFunctionSymbol: + annotatedType: [] kotlin/Unit + annotationClassIds: [] + annotations: [] + callableIdIfNonLocal: /primitive + dispatchType: null + hasStableParameterNames: true + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: primitive + origin: SOURCE + receiverType: null + symbolKind: TOP_LEVEL + typeParameters: [] + valueParameters: [ + KtFirValueParameterSymbol(a) + ] + visibility: Public + deprecationStatus: null + +KtFirValueParameterSymbol: + annotatedType: [] kotlin/Float? + annotationClassIds: [] + annotations: [] + callableIdIfNonLocal: null + hasDefaultValue: false + isExtension: false + isVararg: true + name: b + origin: SOURCE + receiverType: null + symbolKind: LOCAL + deprecationStatus: null + +KtFirFunctionSymbol: + annotatedType: [] kotlin/Unit + annotationClassIds: [] + annotations: [] + callableIdIfNonLocal: /nullablePrimitive + dispatchType: null + hasStableParameterNames: true + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: nullablePrimitive + origin: SOURCE + receiverType: null + symbolKind: TOP_LEVEL + typeParameters: [] + valueParameters: [ + KtFirValueParameterSymbol(b) + ] + visibility: Public + deprecationStatus: null + +KtFirValueParameterSymbol: + annotatedType: [] kotlin/Any + annotationClassIds: [] + annotations: [] + callableIdIfNonLocal: null + hasDefaultValue: false + isExtension: false + isVararg: true + name: c + origin: SOURCE + receiverType: null + symbolKind: LOCAL + deprecationStatus: null + +KtFirFunctionSymbol: + annotatedType: [] kotlin/Unit + annotationClassIds: [] + annotations: [] + callableIdIfNonLocal: /nonPrimitive + dispatchType: null + hasStableParameterNames: true + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: nonPrimitive + origin: SOURCE + receiverType: null + symbolKind: TOP_LEVEL + typeParameters: [] + valueParameters: [ + KtFirValueParameterSymbol(c) + ] + visibility: Public + deprecationStatus: null + +KtFirValueParameterSymbol: + annotatedType: [] ERROR CLASS: Symbol not found for Unresolved + annotationClassIds: [] + annotations: [] + callableIdIfNonLocal: null + hasDefaultValue: false + isExtension: false + isVararg: true + name: d + origin: SOURCE + receiverType: null + symbolKind: LOCAL + deprecationStatus: null + +KtFirFunctionSymbol: + annotatedType: [] kotlin/Unit + annotationClassIds: [] + annotations: [] + callableIdIfNonLocal: /error + dispatchType: null + hasStableParameterNames: true + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: error + origin: SOURCE + receiverType: null + symbolKind: TOP_LEVEL + typeParameters: [] + valueParameters: [ + KtFirValueParameterSymbol(d) + ] + visibility: Public + deprecationStatus: null diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/fir/frontend/api/symbols/SymbolByPsiTestGenerated.java b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/fir/frontend/api/symbols/SymbolByPsiTestGenerated.java index 93420f5ed1d..b9e1596ca5e 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/fir/frontend/api/symbols/SymbolByPsiTestGenerated.java +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/fir/frontend/api/symbols/SymbolByPsiTestGenerated.java @@ -173,4 +173,10 @@ public class SymbolByPsiTestGenerated extends AbstractSymbolByPsiTest { public void testTypeAnnotations() throws Exception { runTest("idea/idea-frontend-fir/testData/symbols/symbolByPsi/typeAnnotations.kt"); } + + @Test + @TestMetadata("varargFunctions.kt") + public void testVarargFunctions() throws Exception { + runTest("idea/idea-frontend-fir/testData/symbols/symbolByPsi/varargFunctions.kt"); + } }