From 25f7554a31601054a46c0e8f3590278c7c9417b8 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Mon, 15 Aug 2022 11:46:12 -0700 Subject: [PATCH] AA FIR: constant evaluation for Java field --- ...ileTimeConstantEvaluatorTestGenerated.java | 18 ++++++++++++++ .../FirCompileTimeConstantEvaluator.kt | 24 ++++++++++++++++--- ...ileTimeConstantEvaluatorTestGenerated.java | 18 ++++++++++++++ ...ileTimeConstantEvaluatorTestGenerated.java | 18 ++++++++++++++ ...ileTimeConstantEvaluatorTestGenerated.java | 18 ++++++++++++++ .../evaluate/javaFinalField.kt | 17 +++++++++++++ .../evaluate/javaFinalField.txt | 9 +++++++ .../evaluate/javaStaticField.kt | 17 +++++++++++++ .../evaluate/javaStaticField.txt | 9 +++++++ .../evaluate/javaStaticFinalField.kt | 17 +++++++++++++ .../evaluate/javaStaticFinalField.txt | 9 +++++++ .../declarations/utils/FirDeclarationUtil.kt | 12 ++++------ .../fir/symbols/impl/FirVariableSymbol.kt | 11 ++++++++- 13 files changed, 186 insertions(+), 11 deletions(-) create mode 100644 analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaFinalField.kt create mode 100644 analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaFinalField.txt create mode 100644 analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticField.kt create mode 100644 analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticField.txt create mode 100644 analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticFinalField.kt create mode 100644 analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticFinalField.txt diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/compileTimeConstantProvider/Fe10IdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/compileTimeConstantProvider/Fe10IdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java index 880f4221d86..7a387b002d1 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/compileTimeConstantProvider/Fe10IdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/compileTimeConstantProvider/Fe10IdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java @@ -76,6 +76,24 @@ public class Fe10IdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGe runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.kt"); } + @Test + @TestMetadata("javaFinalField.kt") + public void testJavaFinalField() throws Exception { + runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaFinalField.kt"); + } + + @Test + @TestMetadata("javaStaticField.kt") + public void testJavaStaticField() throws Exception { + runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticField.kt"); + } + + @Test + @TestMetadata("javaStaticFinalField.kt") + public void testJavaStaticFinalField() throws Exception { + runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticFinalField.kt"); + } + @Test @TestMetadata("namedReference_const.kt") public void testNamedReference_const() throws Exception { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirCompileTimeConstantEvaluator.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirCompileTimeConstantEvaluator.kt index c82b0c9042b..1af62376230 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirCompileTimeConstantEvaluator.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirCompileTimeConstantEvaluator.kt @@ -14,7 +14,8 @@ import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.utils.isConst -import org.jetbrains.kotlin.fir.declarations.utils.referredPropertySymbol +import org.jetbrains.kotlin.fir.declarations.utils.isFinal +import org.jetbrains.kotlin.fir.declarations.utils.referredVariableSymbol import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression import org.jetbrains.kotlin.fir.psi @@ -22,8 +23,9 @@ import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.resolvedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol -import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase +import org.jetbrains.kotlin.fir.symbols.impl.FirFieldSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.psi.KtElement @@ -44,7 +46,11 @@ internal object FirCompileTimeConstantEvaluator { ): FirConstExpression<*>? = when (fir) { is FirPropertyAccessExpression -> { - fir.referredPropertySymbol?.toConstExpression(mode) + when (val referredVariable = fir.referredVariableSymbol) { + is FirPropertySymbol -> referredVariable.toConstExpression(mode) + is FirFieldSymbol -> referredVariable.toConstExpression(mode) + else -> null + } } is FirConstExpression<*> -> { fir.adaptToConstKind() @@ -75,6 +81,18 @@ internal object FirCompileTimeConstantEvaluator { } } + private fun FirFieldSymbol.toConstExpression( + mode: KtConstantEvaluationMode, + ): FirConstExpression<*>? { + return when { + mode == KtConstantEvaluationMode.CONSTANT_EXPRESSION_EVALUATION && !isFinal -> null + isVal && hasInitializer -> { + evaluate(fir.initializer, mode) + } + else -> null + } + } + fun evaluateAsKtConstantValue( fir: FirElement, mode: KtConstantEvaluationMode, diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeDependentAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeDependentAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java index 90fba40a163..617c8fd6c36 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeDependentAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeDependentAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java @@ -76,6 +76,24 @@ public class FirIdeDependentAnalysisSourceModuleCompileTimeConstantEvaluatorTest runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.kt"); } + @Test + @TestMetadata("javaFinalField.kt") + public void testJavaFinalField() throws Exception { + runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaFinalField.kt"); + } + + @Test + @TestMetadata("javaStaticField.kt") + public void testJavaStaticField() throws Exception { + runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticField.kt"); + } + + @Test + @TestMetadata("javaStaticFinalField.kt") + public void testJavaStaticFinalField() throws Exception { + runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticFinalField.kt"); + } + @Test @TestMetadata("namedReference_const.kt") public void testNamedReference_const() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java index 615329c5c0d..3d4d030c52b 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java @@ -76,6 +76,24 @@ public class FirIdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGen runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.kt"); } + @Test + @TestMetadata("javaFinalField.kt") + public void testJavaFinalField() throws Exception { + runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaFinalField.kt"); + } + + @Test + @TestMetadata("javaStaticField.kt") + public void testJavaStaticField() throws Exception { + runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticField.kt"); + } + + @Test + @TestMetadata("javaStaticFinalField.kt") + public void testJavaStaticFinalField() throws Exception { + runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticFinalField.kt"); + } + @Test @TestMetadata("namedReference_const.kt") public void testNamedReference_const() throws Exception { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirStandaloneNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirStandaloneNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java index ebb39535ba9..6f0fc8f5c42 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirStandaloneNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirStandaloneNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java @@ -76,6 +76,24 @@ public class FirStandaloneNormalAnalysisSourceModuleCompileTimeConstantEvaluator runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.kt"); } + @Test + @TestMetadata("javaFinalField.kt") + public void testJavaFinalField() throws Exception { + runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaFinalField.kt"); + } + + @Test + @TestMetadata("javaStaticField.kt") + public void testJavaStaticField() throws Exception { + runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticField.kt"); + } + + @Test + @TestMetadata("javaStaticFinalField.kt") + public void testJavaStaticFinalField() throws Exception { + runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticFinalField.kt"); + } + @Test @TestMetadata("namedReference_const.kt") public void testNamedReference_const() throws Exception { diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaFinalField.kt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaFinalField.kt new file mode 100644 index 00000000000..d8d86f3abb5 --- /dev/null +++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaFinalField.kt @@ -0,0 +1,17 @@ +// FILE: Build.java +package os; + +public class Build { + public static class VERSION_CODES { + public final int CUPCAKE = 3; + } +} + +// FILE: main.kt +import os.Build + +annotation class Annotation(val api: Int) + +@get:Annotation(api = Build.VERSION_CODES().CUPCAKE) +val versionCheck1: Boolean + get() = false \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaFinalField.txt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaFinalField.txt new file mode 100644 index 00000000000..700c8b47529 --- /dev/null +++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaFinalField.txt @@ -0,0 +1,9 @@ +expression: Build.VERSION_CODES().CUPCAKE + +CONSTANT_EXPRESSION_EVALUATION +constant: 3 +constantValueKind: Int + +CONSTANT_LIKE_EXPRESSION_EVALUATION +constantLike: 3 +constantLikeValueKind: Int diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticField.kt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticField.kt new file mode 100644 index 00000000000..518ec70ba35 --- /dev/null +++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticField.kt @@ -0,0 +1,17 @@ +// FILE: Build.java +package os; + +public class Build { + public static class VERSION_CODES { + public static int CUPCAKE = 3; + } +} + +// FILE: main.kt +import os.Build + +annotation class Annotation(val api: Int) + +@get:Annotation(api = Build.VERSION_CODES.CUPCAKE) +val versionCheck1: Boolean + get() = false \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticField.txt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticField.txt new file mode 100644 index 00000000000..2810bab1c40 --- /dev/null +++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticField.txt @@ -0,0 +1,9 @@ +expression: Build.VERSION_CODES.CUPCAKE + +CONSTANT_EXPRESSION_EVALUATION +constant: NOT_EVALUATED +constantValueKind: NOT_EVALUATED + +CONSTANT_LIKE_EXPRESSION_EVALUATION +constantLike: NOT_EVALUATED +constantLikeValueKind: NOT_EVALUATED diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticFinalField.kt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticFinalField.kt new file mode 100644 index 00000000000..01d396e0e07 --- /dev/null +++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticFinalField.kt @@ -0,0 +1,17 @@ +// FILE: Build.java +package os; + +public class Build { + public static class VERSION_CODES { + public static final int CUPCAKE = 3; + } +} + +// FILE: main.kt +import os.Build + +annotation class Annotation(val api: Int) + +@get:Annotation(api = Build.VERSION_CODES.CUPCAKE) +val versionCheck1: Boolean + get() = false \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticFinalField.txt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticFinalField.txt new file mode 100644 index 00000000000..750df045e0b --- /dev/null +++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/javaStaticFinalField.txt @@ -0,0 +1,9 @@ +expression: Build.VERSION_CODES.CUPCAKE + +CONSTANT_EXPRESSION_EVALUATION +constant: 3 +constantValueKind: Int + +CONSTANT_LIKE_EXPRESSION_EVALUATION +constantLike: 3 +constantLikeValueKind: Int diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirDeclarationUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirDeclarationUtil.kt index 055b227bd60..85c288e9b16 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirDeclarationUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirDeclarationUtil.kt @@ -9,10 +9,7 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess import org.jetbrains.kotlin.fir.resolvedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol +import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.name.ClassId @@ -41,10 +38,11 @@ val FirClass.anonymousInitializers: List val FirClass.delegateFields: List get() = declarations.filterIsInstance().filter { it.isSynthetic } +val FirQualifiedAccess.referredVariableSymbol: FirVariableSymbol<*>? + get() = calleeReference.resolvedSymbol as? FirVariableSymbol<*> + val FirQualifiedAccess.referredPropertySymbol: FirPropertySymbol? - get() { - return calleeReference.resolvedSymbol as? FirPropertySymbol - } + get() = referredVariableSymbol as? FirPropertySymbol inline val FirDeclaration.isJava: Boolean get() = origin is FirDeclarationOrigin.Java diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirVariableSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirVariableSymbol.kt index b18bd78a969..d29f01dcc56 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirVariableSymbol.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirVariableSymbol.kt @@ -76,7 +76,16 @@ class FirBackingFieldSymbol(callableId: CallableId) : FirVariableSymbol(callableId) -class FirFieldSymbol(callableId: CallableId) : FirVariableSymbol(callableId) +class FirFieldSymbol(callableId: CallableId) : FirVariableSymbol(callableId) { + val hasInitializer: Boolean + get() = fir.initializer != null + + val isVal: Boolean + get() = fir.isVal + + val isVar: Boolean + get() = fir.isVar +} class FirEnumEntrySymbol(callableId: CallableId) : FirVariableSymbol(callableId)