[FIR] include all binary expression "arguments" in FIR expression For invalid code, binary expressions might have additional operands. This commit includes those operands in the corresponding FIR call, to avoid fir declarations misses during analysis ^ KTIJ-23605
diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/symbols/Fe10IdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/symbols/Fe10IdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java index 1da670f..ff931f1 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/symbols/Fe10IdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/symbols/Fe10IdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java
@@ -53,6 +53,12 @@ } @Test + @TestMetadata("anonymousFunction.kt") + public void testAnonymousFunction() throws Exception { + runTest("analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.kt"); + } + + @Test @TestMetadata("anonymousObject.kt") public void testAnonymousObject() throws Exception { runTest("analysis/analysis-api/testData/symbols/symbolByPsi/anonymousObject.kt");
diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java index 324fe2a..ab6d708 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java
@@ -53,6 +53,12 @@ } @Test + @TestMetadata("anonymousFunction.kt") + public void testAnonymousFunction() throws Exception { + runTest("analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.kt"); + } + + @Test @TestMetadata("anonymousObject.kt") public void testAnonymousObject() throws Exception { runTest("analysis/analysis-api/testData/symbols/symbolByPsi/anonymousObject.kt");
diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java index 149d91a..f003f7a 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java
@@ -53,6 +53,12 @@ } @Test + @TestMetadata("anonymousFunction.kt") + public void testAnonymousFunction() throws Exception { + runTest("analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.kt"); + } + + @Test @TestMetadata("anonymousObject.kt") public void testAnonymousObject() throws Exception { runTest("analysis/analysis-api/testData/symbols/symbolByPsi/anonymousObject.kt");
diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.descriptors.txt b/analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.descriptors.txt new file mode 100644 index 0000000..86a6f07 --- /dev/null +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.descriptors.txt
@@ -0,0 +1,131 @@ +KtEnumEntrySymbol: + annotationsList: [] + callableIdIfNonLocal: /RGB.RED + containingEnumClassIdIfNonLocal: RGB + contextReceivers: [] + isExtension: false + name: RED + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: RGB + symbolKind: CLASS_MEMBER + typeParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtEnumEntrySymbol: + annotationsList: [] + callableIdIfNonLocal: /RGB.GREEN + containingEnumClassIdIfNonLocal: RGB + contextReceivers: [] + isExtension: false + name: GREEN + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: RGB + symbolKind: CLASS_MEMBER + typeParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtEnumEntrySymbol: + annotationsList: [] + callableIdIfNonLocal: /RGB.BLUE + containingEnumClassIdIfNonLocal: RGB + contextReceivers: [] + isExtension: false + name: BLUE + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: RGB + symbolKind: CLASS_MEMBER + typeParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtNamedClassOrObjectSymbol: + annotationsList: [] + classIdIfNonLocal: RGB + classKind: ENUM_CLASS + companionObject: null + contextReceivers: [] + isData: false + isExternal: false + isFun: false + isInline: false + isInner: false + modality: FINAL + name: RGB + origin: SOURCE + superTypes: [ + KtUsualClassType: + annotationsList: [] + ownTypeArguments: [ + KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: RGB + ] + type: kotlin/Enum<RGB> + ] + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + getContainingModule: KtSourceModule "Sources of main" + annotationApplicableTargets: null + deprecationStatus: null + +KtAnonymousFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: null + contextReceivers: [] + hasStableParameterNames: true + isExtension: false + origin: SOURCE + receiverParameter: null + returnType: Could not render due to java.lang.IllegalStateException: Expected unresolved ErrorType but UNAVAILABLE_TYPE_FOR_DECLARATION found for [Error type: Type is unavailable for declaration FUNCTION_LITERAL] + + symbolKind: LOCAL + typeParameters: [] + valueParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: /printAllValues + contextReceivers: [] + contractEffects: [] + hasStableParameterNames: true + isBuiltinFunctionInvoke: false + isExtension: false + isExternal: false + isInfix: false + isInline: true + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: printAllValues + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Unit + symbolKind: TOP_LEVEL + typeParameters: [] + valueParameters: [] + visibility: Public + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null \ No newline at end of file
diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.kt b/analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.kt new file mode 100644 index 0000000..d6e587c --- /dev/null +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.kt
@@ -0,0 +1,6 @@ +// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE +enum class RGB { RED, GREEN, BLUE } + +inline fun printAllValues() { + print()enumValues<T>().joinToString { it.name } +}
diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.pretty.txt b/analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.pretty.txt new file mode 100644 index 0000000..53be233 --- /dev/null +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.pretty.txt
@@ -0,0 +1,7 @@ +inline fun printAllValues() + +enum class RGB { + RED, + GREEN, + BLUE +}
diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.txt b/analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.txt new file mode 100644 index 0000000..ab0f78f --- /dev/null +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/anonymousFunction.txt
@@ -0,0 +1,132 @@ +KtEnumEntrySymbol: + annotationsList: [] + callableIdIfNonLocal: /RGB.RED + containingEnumClassIdIfNonLocal: RGB + contextReceivers: [] + isExtension: false + name: RED + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: RGB + symbolKind: CLASS_MEMBER + typeParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtEnumEntrySymbol: + annotationsList: [] + callableIdIfNonLocal: /RGB.GREEN + containingEnumClassIdIfNonLocal: RGB + contextReceivers: [] + isExtension: false + name: GREEN + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: RGB + symbolKind: CLASS_MEMBER + typeParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtEnumEntrySymbol: + annotationsList: [] + callableIdIfNonLocal: /RGB.BLUE + containingEnumClassIdIfNonLocal: RGB + contextReceivers: [] + isExtension: false + name: BLUE + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: RGB + symbolKind: CLASS_MEMBER + typeParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtNamedClassOrObjectSymbol: + annotationsList: [] + classIdIfNonLocal: RGB + classKind: ENUM_CLASS + companionObject: null + contextReceivers: [] + isData: false + isExternal: false + isFun: false + isInline: false + isInner: false + modality: FINAL + name: RGB + origin: SOURCE + superTypes: [ + KtUsualClassType: + annotationsList: [] + ownTypeArguments: [ + KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: RGB + ] + type: kotlin/Enum<RGB> + ] + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + getContainingModule: KtSourceModule "Sources of main" + annotationApplicableTargets: null + deprecationStatus: null + +KtAnonymousFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: null + contextReceivers: [] + hasStableParameterNames: true + isExtension: false + origin: SOURCE + receiverParameter: null + returnType: KtClassErrorType: + annotationsList: [] + type: ERROR_TYPE + symbolKind: LOCAL + typeParameters: [] + valueParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: /printAllValues + contextReceivers: [] + contractEffects: [] + hasStableParameterNames: true + isBuiltinFunctionInvoke: false + isExtension: false + isExternal: false + isInfix: false + isInline: true + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: printAllValues + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Unit + symbolKind: TOP_LEVEL + typeParameters: [] + valueParameters: [] + visibility: Public + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null \ No newline at end of file
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt index 4904616..cc28eb9 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt
@@ -40,7 +40,6 @@ import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtFile internal abstract class LLFirResolvableResolveSession( @@ -152,7 +151,7 @@ protected abstract fun getModuleKind(module: KtModule): ModuleKind - private fun findDeclarationInSourceViaResolve(ktDeclaration: KtExpression): FirBasedSymbol<*> { + private fun findDeclarationInSourceViaResolve(ktDeclaration: KtDeclaration): FirBasedSymbol<*> { val firDeclaration = when (val fir = getOrBuildFirFor(ktDeclaration)) { is FirDeclaration -> fir is FirAnonymousFunctionExpression -> fir.anonymousFunction
diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirExpressionBuilder.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirExpressionBuilder.kt index 11cbb0e..b2a5557 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirExpressionBuilder.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirExpressionBuilder.kt
@@ -49,6 +49,7 @@ import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.SpecialNames +import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.stubs.elements.KtConstantExpressionElementType import org.jetbrains.kotlin.psi.stubs.elements.KtNameReferenceExpressionElementType import org.jetbrains.kotlin.types.expressions.OperatorConventions @@ -231,6 +232,7 @@ lateinit var operationTokenName: String var leftArgNode: LighterASTNode? = null var rightArg: LighterASTNode? = null + val restArgs = mutableListOf<LighterASTNode>() var operationReferenceSource: KtLightSourceElement? = null binaryExpression.forEachChildren { when (it.tokenType) { @@ -243,7 +245,11 @@ if (isLeftArgument) { leftArgNode = it } else { - rightArg = it + if (rightArg == null) { + rightArg = it + } else { + restArgs.add(it) + } } } } @@ -265,6 +271,10 @@ val leftArgAsFir = getAsFirExpression<FirExpression>(leftArgNode, "No left operand") + val restArguments = + if (restArgs.isNotEmpty()) restArgs.map { getAsFirExpression<FirExpression>(it, "No additional operand") }.toList() else null + + // No need for the callee name since arguments are already generated context.calleeNamesForLambda.removeLast() @@ -287,7 +297,14 @@ name = conventionCallName ?: operationTokenName.nameAsSafeName() } explicitReceiver = leftArgAsFir - argumentList = buildUnaryArgumentList(rightArgAsFir) + argumentList = if (restArguments != null) { + buildArgumentList { + arguments.add(rightArgAsFir) + arguments += restArguments + } + } else { + buildUnaryArgumentList(rightArgAsFir) + } origin = if (conventionCallName != null) FirFunctionCallOrigin.Operator else FirFunctionCallOrigin.Infix } } else {
diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt index fa3231c..fd3a793 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt
@@ -2582,6 +2582,14 @@ val leftArgument = expression.left.toFirExpression("No left operand") val rightArgument = expression.right.toFirExpression("No right operand") + val restArguments = + if (expression.children.filterIsInstance<KtExpression>().size > 3) { + expression.children + .filterIsInstance<KtExpression>() + .drop(3) + .map { it.toFirExpression("No additional operand") } + .toList() + } else null // No need for the callee name since arguments are already generated context.calleeNamesForLambda.removeLast() @@ -2613,7 +2621,14 @@ name = conventionCallName ?: expression.operationReference.getReferencedNameAsName() } explicitReceiver = leftArgument - argumentList = buildUnaryArgumentList(rightArgument) + argumentList = if (restArguments != null) { + buildArgumentList { + arguments += rightArgument + arguments += restArguments + } + } else { + buildUnaryArgumentList(rightArgument) + } origin = if (conventionCallName != null) FirFunctionCallOrigin.Operator else FirFunctionCallOrigin.Infix } } else {