FIR2IR: Fix exception when local class used before declaration
This commit is contained in:
@@ -168,7 +168,7 @@ class Fir2IrClassifierStorage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createIrClass(klass: FirClass, parent: IrDeclarationParent? = null): IrClass {
|
private fun createLocalIrClass(klass: FirClass, parent: IrDeclarationParent? = null): IrClass {
|
||||||
// NB: klass can be either FirRegularClass or FirAnonymousObject
|
// NB: klass can be either FirRegularClass or FirAnonymousObject
|
||||||
if (klass is FirAnonymousObject) {
|
if (klass is FirAnonymousObject) {
|
||||||
return createIrAnonymousObject(klass, irParent = parent)
|
return createIrAnonymousObject(klass, irParent = parent)
|
||||||
@@ -434,7 +434,7 @@ class Fir2IrClassifierStorage(
|
|||||||
val firClass = firClassSymbol.fir
|
val firClass = firClassSymbol.fir
|
||||||
getCachedIrClass(firClass)?.let { return it.symbol }
|
getCachedIrClass(firClass)?.let { return it.symbol }
|
||||||
if (firClass is FirAnonymousObject || firClass is FirRegularClass && firClass.visibility == Visibilities.Local) {
|
if (firClass is FirAnonymousObject || firClass is FirRegularClass && firClass.visibility == Visibilities.Local) {
|
||||||
return createIrClass(firClass).symbol
|
return createLocalIrClass(firClass).symbol
|
||||||
}
|
}
|
||||||
val signature = signatureComposer.composeSignature(firClass)!!
|
val signature = signatureComposer.composeSignature(firClass)!!
|
||||||
symbolTable.referenceClassIfAny(signature)?.let { irClassSymbol ->
|
symbolTable.referenceClassIfAny(signature)?.let { irClassSymbol ->
|
||||||
|
|||||||
@@ -221,7 +221,13 @@ class Fir2IrConverter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun registerClassAndNestedClasses(regularClass: FirRegularClass, parent: IrDeclarationParent): IrClass {
|
private fun registerClassAndNestedClasses(regularClass: FirRegularClass, parent: IrDeclarationParent): IrClass {
|
||||||
val irClass = classifierStorage.registerIrClass(regularClass, parent)
|
val irClass =
|
||||||
|
// Local classes might be referenced before they declared (see usages of Fir2IrClassifierStorage.createLocalIrClass)
|
||||||
|
// So, we only need to set its parent properly
|
||||||
|
classifierStorage.getCachedIrClass(regularClass)?.apply {
|
||||||
|
this.parent = parent
|
||||||
|
}
|
||||||
|
?: classifierStorage.registerIrClass(regularClass, parent)
|
||||||
regularClass.declarations.forEach {
|
regularClass.declarations.forEach {
|
||||||
if (it is FirRegularClass) {
|
if (it is FirRegularClass) {
|
||||||
registerClassAndNestedClasses(it, irClass)
|
registerClassAndNestedClasses(it, irClass)
|
||||||
|
|||||||
+6
@@ -26508,6 +26508,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localClassUsedBeforeDeclaration.kt")
|
||||||
|
public void testLocalClassUsedBeforeDeclaration() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/localClasses/localClassUsedBeforeDeclaration.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("localDataClass.kt")
|
@TestMetadata("localDataClass.kt")
|
||||||
public void testLocalDataClass() throws Exception {
|
public void testLocalDataClass() throws Exception {
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun box(): String {
|
||||||
|
return object {
|
||||||
|
val a = A("OK")
|
||||||
|
inner class A(val ok: String)
|
||||||
|
}.a.ok
|
||||||
|
}
|
||||||
+6
@@ -26370,6 +26370,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localClassUsedBeforeDeclaration.kt")
|
||||||
|
public void testLocalClassUsedBeforeDeclaration() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/localClasses/localClassUsedBeforeDeclaration.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("localDataClass.kt")
|
@TestMetadata("localDataClass.kt")
|
||||||
public void testLocalDataClass() throws Exception {
|
public void testLocalDataClass() throws Exception {
|
||||||
|
|||||||
+6
@@ -26508,6 +26508,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localClassUsedBeforeDeclaration.kt")
|
||||||
|
public void testLocalClassUsedBeforeDeclaration() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/localClasses/localClassUsedBeforeDeclaration.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("localDataClass.kt")
|
@TestMetadata("localDataClass.kt")
|
||||||
public void testLocalDataClass() throws Exception {
|
public void testLocalDataClass() throws Exception {
|
||||||
|
|||||||
+5
@@ -22277,6 +22277,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localClassUsedBeforeDeclaration.kt")
|
||||||
|
public void testLocalClassUsedBeforeDeclaration() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/localClasses/localClassUsedBeforeDeclaration.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("localDataClass.kt")
|
@TestMetadata("localDataClass.kt")
|
||||||
public void testLocalDataClass() throws Exception {
|
public void testLocalDataClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/localClasses/localDataClass.kt");
|
runTest("compiler/testData/codegen/box/localClasses/localDataClass.kt");
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+5
@@ -17261,6 +17261,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
|||||||
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localClassUsedBeforeDeclaration.kt")
|
||||||
|
public void testLocalClassUsedBeforeDeclaration() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/localClasses/localClassUsedBeforeDeclaration.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("localDataClass.kt")
|
@TestMetadata("localDataClass.kt")
|
||||||
public void testLocalDataClass() throws Exception {
|
public void testLocalDataClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/localClasses/localDataClass.kt");
|
runTest("compiler/testData/codegen/box/localClasses/localDataClass.kt");
|
||||||
|
|||||||
Generated
+5
@@ -16667,6 +16667,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localClassUsedBeforeDeclaration.kt")
|
||||||
|
public void testLocalClassUsedBeforeDeclaration() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/localClasses/localClassUsedBeforeDeclaration.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("localDataClass.kt")
|
@TestMetadata("localDataClass.kt")
|
||||||
public void testLocalDataClass() throws Exception {
|
public void testLocalDataClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/localClasses/localDataClass.kt");
|
runTest("compiler/testData/codegen/box/localClasses/localDataClass.kt");
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+5
@@ -15963,6 +15963,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localClassUsedBeforeDeclaration.kt")
|
||||||
|
public void testLocalClassUsedBeforeDeclaration() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/localClasses/localClassUsedBeforeDeclaration.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("localDataClass.kt")
|
@TestMetadata("localDataClass.kt")
|
||||||
public void testLocalDataClass() throws Exception {
|
public void testLocalDataClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/localClasses/localDataClass.kt");
|
runTest("compiler/testData/codegen/box/localClasses/localDataClass.kt");
|
||||||
|
|||||||
+6
@@ -18704,6 +18704,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
runTest("compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localClassUsedBeforeDeclaration.kt")
|
||||||
|
public void testLocalClassUsedBeforeDeclaration() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/localClasses/localClassUsedBeforeDeclaration.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("localDataClass.kt")
|
@TestMetadata("localDataClass.kt")
|
||||||
public void testLocalDataClass() throws Exception {
|
public void testLocalDataClass() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user