[FIR] Allow to evaluate top level const properties in Java world

#KT-57802
This commit is contained in:
Ivan Kylchik
2023-06-26 12:48:18 +02:00
committed by Space Team
parent 886ef1a4b4
commit 7935b2bdb1
11 changed files with 194 additions and 29 deletions
@@ -29066,6 +29066,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter")
@TestDataPath("$PROJECT_ROOT")
public class InvolvesIrInterpreter {
@Test
@TestMetadata("accessTopLevelConstFromJava.kt")
public void testAccessTopLevelConstFromJava() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/accessTopLevelConstFromJava.kt");
}
@Test
public void testAllFilesPresentInInvolvesIrInterpreter() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
@@ -29168,9 +29174,15 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
}
@Test
@TestMetadata("kt57802.kt")
public void testKt57802() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802.kt");
@TestMetadata("kt57802_1.kt")
public void testKt57802_1() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_1.kt");
}
@Test
@TestMetadata("kt57802_2.kt")
public void testKt57802_2() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_2.kt");
}
@Test
@@ -29066,6 +29066,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter")
@TestDataPath("$PROJECT_ROOT")
public class InvolvesIrInterpreter {
@Test
@TestMetadata("accessTopLevelConstFromJava.kt")
public void testAccessTopLevelConstFromJava() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/accessTopLevelConstFromJava.kt");
}
@Test
public void testAllFilesPresentInInvolvesIrInterpreter() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
@@ -29168,9 +29174,15 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
}
@Test
@TestMetadata("kt57802.kt")
public void testKt57802() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802.kt");
@TestMetadata("kt57802_1.kt")
public void testKt57802_1() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_1.kt");
}
@Test
@TestMetadata("kt57802_2.kt")
public void testKt57802_2() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_2.kt");
}
@Test
@@ -29066,6 +29066,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter")
@TestDataPath("$PROJECT_ROOT")
public class InvolvesIrInterpreter {
@Test
@TestMetadata("accessTopLevelConstFromJava.kt")
public void testAccessTopLevelConstFromJava() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/accessTopLevelConstFromJava.kt");
}
@Test
public void testAllFilesPresentInInvolvesIrInterpreter() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
@@ -29168,9 +29174,15 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
}
@Test
@TestMetadata("kt57802.kt")
public void testKt57802() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802.kt");
@TestMetadata("kt57802_1.kt")
public void testKt57802_1() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_1.kt");
}
@Test
@TestMetadata("kt57802_2.kt")
public void testKt57802_2() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_2.kt");
}
@Test
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSessionComponent
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
@@ -32,7 +33,6 @@ import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.fir.utils.exceptions.withConeTypeEntry
import org.jetbrains.kotlin.name.*
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.resolve.jvm.KotlinFinderMarker
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
val FirSession.javaElementFinder: FirJavaElementFinder? by FirSession.nullableSessionComponentAccessor<FirJavaElementFinder>()
@@ -90,8 +91,16 @@ class FirJavaElementFinder(
if (topLevelClass.isRoot) break
val classId = ClassId.topLevel(topLevelClass)
val firClass = firProviders.firstNotNullOfOrNull { it.getFirClassifierByFqName(classId) as? FirRegularClass } ?: continue
// 1. We could be asked to find class of kind "...MainKt" that was created from file "main.kt"
val firFile = firProviders.firstNotNullOfOrNull { it.getFirFilesByPackage(classId.packageFqName) }
?.singleOrNull { classId.relativeClassName.asString() == it.name.removeSuffix(".kt").capitalizeAsciiOnly() + "Kt" }
if (firFile != null) {
val fileStub = createJavaFileStub(classId.packageFqName, psiManager)
return buildFileAsClassStub(firFile, classId, fileStub).psi
}
// 2. Find regular class
val firClass = firProviders.firstNotNullOfOrNull { it.getFirClassifierByFqName(classId) as? FirRegularClass } ?: continue
val fileStub = createJavaFileStub(classId.packageFqName, psiManager)
val topLevelResult = buildStub(firClass, fileStub).psi
val tail = fqName.tail(topLevelClass).pathSegments()
@@ -104,6 +113,26 @@ class FirJavaElementFinder(
return null
}
private fun buildFileAsClassStub(firFile: FirFile, classId: ClassId, parent: StubElement<*>): PsiClassStub<*> {
val stub = PsiClassStubImpl<ClsClassImpl>(
JavaStubElementTypes.CLASS, parent, classId.asSingleFqName().asString(), classId.relativeClassName.asString(), null,
PsiClassStubImpl.packFlags(
false, false, false, false, false, false, false,
false, false, false, false
)
)
firFile.declarations.filterIsInstance<FirProperty>().forEach {
buildFieldStub(it, stub)
}
PsiModifierListStubImpl(stub, ModifierFlags.PUBLIC_MASK or ModifierFlags.FINAL_MASK)
PsiTypeParameterListStubImpl(stub)
newReferenceList(JavaStubElementTypes.EXTENDS_LIST, stub, ArrayUtil.EMPTY_STRING_ARRAY)
newReferenceList(JavaStubElementTypes.IMPLEMENTS_LIST, stub, ArrayUtil.EMPTY_STRING_ARRAY)
return stub
}
private fun buildStub(firClass: FirRegularClass, parent: StubElement<*>): PsiClassStub<*> {
val classId = firClass.classId
val stub = PsiClassStubImpl<ClsClassImpl>(
@@ -121,12 +150,7 @@ class FirJavaElementFinder(
// Note: we must store companion properties in outer clas because java resolver will not find it other way.
val companionProperties = firClass.companionObjectSymbol?.declarationSymbols?.map { it.fir }?.filterIsInstance<FirProperty>() ?: emptyList()
(classProperties + companionProperties).forEach {
// TODO correct type info
val psiField = PsiFieldStubImpl(
stub, it.name.identifier, TypeInfo.fromString("int"), propertyEvaluator?.invoke(it),
PsiFieldStubImpl.packFlags(false, false, false, false)
)
PsiModifierListStubImpl(psiField, ModifierFlags.PUBLIC_MASK + ModifierFlags.FINAL_MASK + ModifierFlags.STATIC_MASK)
buildFieldStub(it, stub)
}
PsiModifierListStubImpl(stub, firClass.packFlags())
@@ -150,6 +174,16 @@ class FirJavaElementFinder(
return stub
}
private fun buildFieldStub(firProperty: FirProperty, classStub: PsiClassStubImpl<ClsClassImpl>) {
// TODO correct type info
val propertyValue = propertyEvaluator?.invoke(firProperty)
val psiField = PsiFieldStubImpl(
classStub, firProperty.name.identifier, TypeInfo.fromString("int"), propertyValue,
PsiFieldStubImpl.packFlags(false, false, false, false)
)
PsiModifierListStubImpl(psiField, ModifierFlags.PUBLIC_MASK + ModifierFlags.FINAL_MASK + ModifierFlags.STATIC_MASK)
}
}
private fun FirRegularClass.resolveSupertypesOnAir(session: FirSession): List<FirTypeRef> {
@@ -0,0 +1,18 @@
// TARGET_BACKEND: JVM
// FILE: Bar.java
package one.two;
public class Bar {
public static final int BAR = MainKt.FOO + 1;
}
// FILE: Main.kt
package one.two
const val FOO = <!EVALUATED("1")!>1<!>
const val BAZ = <!EVALUATED("3")!>Bar.BAR + 1<!>
fun box(): String {
return "OK"
}
@@ -0,0 +1,31 @@
// TARGET_BACKEND: JVM
// FILE: Bar.java
package one.two;
public class Bar {
public static final int BAR = Foo.FOO + 1;
}
// FILE: Boo.java
package one.two;
public class Boo {
public static final int BOO = Foo.BAZ + 1;
}
// FILE: Main.kt
package one.two
class Foo {
companion object {
const val FOO = <!EVALUATED("1")!>1<!>
const val BAZ = <!EVALUATED("3")!>Bar.BAR + 1<!>
const val DOO = <!EVALUATED("5")!>Boo.BOO + 1<!>
}
}
fun box(): String {
return "OK"
}
@@ -27794,6 +27794,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter")
@TestDataPath("$PROJECT_ROOT")
public class InvolvesIrInterpreter {
@Test
@TestMetadata("accessTopLevelConstFromJava.kt")
public void testAccessTopLevelConstFromJava() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/accessTopLevelConstFromJava.kt");
}
@Test
public void testAllFilesPresentInInvolvesIrInterpreter() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
@@ -27824,9 +27830,15 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
}
@Test
@TestMetadata("kt57802.kt")
public void testKt57802() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802.kt");
@TestMetadata("kt57802_1.kt")
public void testKt57802_1() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_1.kt");
}
@Test
@TestMetadata("kt57802_2.kt")
public void testKt57802_2() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_2.kt");
}
@Test
@@ -29066,6 +29066,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter")
@TestDataPath("$PROJECT_ROOT")
public class InvolvesIrInterpreter {
@Test
@TestMetadata("accessTopLevelConstFromJava.kt")
public void testAccessTopLevelConstFromJava() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/accessTopLevelConstFromJava.kt");
}
@Test
public void testAllFilesPresentInInvolvesIrInterpreter() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
@@ -29168,9 +29174,15 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
}
@Test
@TestMetadata("kt57802.kt")
public void testKt57802() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802.kt");
@TestMetadata("kt57802_1.kt")
public void testKt57802_1() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_1.kt");
}
@Test
@TestMetadata("kt57802_2.kt")
public void testKt57802_2() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_2.kt");
}
@Test
@@ -29066,6 +29066,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter")
@TestDataPath("$PROJECT_ROOT")
public class InvolvesIrInterpreter {
@Test
@TestMetadata("accessTopLevelConstFromJava.kt")
public void testAccessTopLevelConstFromJava() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/accessTopLevelConstFromJava.kt");
}
@Test
public void testAllFilesPresentInInvolvesIrInterpreter() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
@@ -29168,9 +29174,15 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
}
@Test
@TestMetadata("kt57802.kt")
public void testKt57802() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802.kt");
@TestMetadata("kt57802_1.kt")
public void testKt57802_1() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_1.kt");
}
@Test
@TestMetadata("kt57802_2.kt")
public void testKt57802_2() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_2.kt");
}
@Test
@@ -24546,6 +24546,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
}
@TestMetadata("accessTopLevelConstFromJava.kt")
public void testAccessTopLevelConstFromJava() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/accessTopLevelConstFromJava.kt");
}
public void testAllFilesPresentInInvolvesIrInterpreter() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@@ -24625,9 +24630,14 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57313.kt");
}
@TestMetadata("kt57802.kt")
public void testKt57802() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802.kt");
@TestMetadata("kt57802_1.kt")
public void testKt57802_1() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_1.kt");
}
@TestMetadata("kt57802_2.kt")
public void testKt57802_2() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57802_2.kt");
}
@TestMetadata("kt58005.kt")