[FIR] Allow to evaluate top level const properties in Java world
#KT-57802
This commit is contained in:
+15
-3
@@ -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
|
||||
|
||||
+15
-3
@@ -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
|
||||
|
||||
+15
-3
@@ -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> {
|
||||
|
||||
+18
@@ -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"
|
||||
}
|
||||
+15
-3
@@ -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
|
||||
|
||||
+15
-3
@@ -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
|
||||
|
||||
+15
-3
@@ -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
|
||||
|
||||
+13
-3
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user