diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt index 0ecd509e170..7353153964e 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt @@ -24,23 +24,20 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl import org.jetbrains.kotlin.ir.expressions.impl.IrEnumConstructorCallImpl -import org.jetbrains.kotlin.ir.symbols.IrClassSymbol -import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol -import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol -import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol -import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl -import org.jetbrains.kotlin.ir.symbols.impl.IrEnumEntrySymbolImpl -import org.jetbrains.kotlin.ir.symbols.impl.IrTypeAliasSymbolImpl -import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl +import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.constructors +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds class Fir2IrClassifierStorage( + private val converter: Fir2IrConverter, private val components: Fir2IrComponents ) : Fir2IrComponents by components { private val firProvider = session.firProvider @@ -168,16 +165,17 @@ class Fir2IrClassifierStorage( } } - private fun createLocalIrClass(klass: FirClass, parent: IrDeclarationParent? = null): IrClass { + // This function is called when we refer local class earlier than we reach its declaration + // This can happen e.g. when implicit return type has a local class constructor + private fun createLocalIrClassOnTheFly(klass: FirClass): IrClass { // NB: klass can be either FirRegularClass or FirAnonymousObject - if (klass is FirAnonymousObject) { - return createIrAnonymousObject(klass, irParent = parent) + val result = when (klass) { + is FirAnonymousObject -> createIrAnonymousObject(klass, irParent = temporaryParent).apply { + converter.processAnonymousObjectMembers(klass, this) + } + is FirRegularClass -> converter.processLocalClassAndNestedClasses(klass, temporaryParent) } - val regularClass = klass as FirRegularClass - val origin = regularClass.irOrigin(firProvider) - val irClass = registerIrClass(regularClass, parent, origin) - processClassHeader(regularClass, irClass) - return irClass + return result } fun processClassHeader(regularClass: FirRegularClass, irClass: IrClass = getCachedIrClass(regularClass)!!): IrClass { @@ -434,7 +432,7 @@ class Fir2IrClassifierStorage( val firClass = firClassSymbol.fir getCachedIrClass(firClass)?.let { return it.symbol } if (firClass is FirAnonymousObject || firClass is FirRegularClass && firClass.visibility == Visibilities.Local) { - return createLocalIrClass(firClass).symbol + return createLocalIrClassOnTheFly(firClass).symbol } val signature = signatureComposer.composeSignature(firClass)!! symbolTable.referenceClassIfAny(signature)?.let { irClassSymbol -> @@ -500,4 +498,16 @@ class Fir2IrClassifierStorage( ?: typeParameterCache[firTypeParameter]?.symbol ?: error("Cannot find cached type parameter by FIR symbol: ${firTypeParameterSymbol.name}") } + + private val temporaryParent by lazy { + irFactory.createFunction( + startOffset = UNDEFINED_OFFSET, endOffset = UNDEFINED_OFFSET, + IrDeclarationOrigin.DEFINED, IrSimpleFunctionSymbolImpl(), + Name.special(""), DescriptorVisibilities.PRIVATE, Modality.FINAL, irBuiltIns.unitType, + isInline = false, isExternal = false, isTailrec = false, + isSuspend = false, isOperator = false, isInfix = false, isExpect = false + ).apply { + parent = IrExternalPackageFragmentImpl(IrExternalPackageFragmentSymbolImpl(), FqName.ROOT) + } + } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index bb06ac47521..28c10de139a 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -39,7 +39,6 @@ import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions @@ -53,24 +52,15 @@ class Fir2IrConverter( private val generatorExtensions = session.extensionService.declarationGenerators - fun processLocalClassAndNestedClasses(regularClass: FirRegularClass, parent: IrDeclarationParent) { + fun processLocalClassAndNestedClasses(regularClass: FirRegularClass, parent: IrDeclarationParent): IrClass { val irClass = registerClassAndNestedClasses(regularClass, parent) processClassAndNestedClassHeaders(regularClass) processClassMembers(regularClass, irClass) bindFakeOverridesInClass(irClass) + return irClass } - fun processRegisteredLocalClassAndNestedClasses(regularClass: FirRegularClass, irClass: IrClass) { - regularClass.declarations.forEach { - if (it is FirRegularClass) { - registerClassAndNestedClasses(it, irClass) - } - } - processClassAndNestedClassHeaders(regularClass) - processClassMembers(regularClass, irClass) - } - - fun registerFileAndClasses(file: FirFile, moduleFragment: IrModuleFragment) { + private fun registerFileAndClasses(file: FirFile, moduleFragment: IrModuleFragment) { val fileEntry = when (file.origin) { FirDeclarationOrigin.Source -> PsiIrFileEntry(file.psi as KtFile) FirDeclarationOrigin.Synthetic -> object : IrFileEntry { @@ -117,7 +107,7 @@ class Fir2IrConverter( } } - fun processFileAndClassMembers(file: FirFile) { + private fun processFileAndClassMembers(file: FirFile) { val irFile = declarationStorage.getIrFile(file) for (declaration in file.declarations) { val irDeclaration = processMemberDeclaration(declaration, null, irFile) ?: continue @@ -129,40 +119,29 @@ class Fir2IrConverter( anonymousObject: FirAnonymousObject, irClass: IrClass = classifierStorage.getCachedIrClass(anonymousObject)!! ): IrClass { + registerNestedClasses(anonymousObject, irClass) + processNestedClassHeaders(anonymousObject) anonymousObject.primaryConstructorIfAny(session)?.let { irClass.declarations += declarationStorage.createIrConstructor( it.fir, irClass, isLocal = true ) } - val processedCallableNames = mutableSetOf() - val classes = mutableListOf() for (declaration in syntheticPropertiesLast(anonymousObject.declarations)) { - val irDeclaration = if (declaration is FirRegularClass) { - classes += declaration - registerClassAndNestedClasses(declaration, irClass) - } else { - when (declaration) { - is FirSimpleFunction -> processedCallableNames += declaration.name - is FirProperty -> processedCallableNames += declaration.name - else -> {} - } - processMemberDeclaration(declaration, anonymousObject, irClass) ?: continue - } + val irDeclaration = processMemberDeclaration(declaration, anonymousObject, irClass) ?: continue irClass.declarations += irDeclaration } - classes.forEach { processClassAndNestedClassHeaders(it) } - classes.forEach { processClassMembers(it) } // Add delegated members *before* fake override generations. // Otherwise, fake overrides for delegated members, which are redundant, will be added. val realDeclarations = delegatedMembers(irClass) + anonymousObject.declarations with(fakeOverrideGenerator) { irClass.addFakeOverrides(anonymousObject, realDeclarations) } + bindFakeOverridesInClass(irClass) return irClass } - private fun processClassMembers( + internal fun processClassMembers( regularClass: FirRegularClass, irClass: IrClass = classifierStorage.getCachedIrClass(regularClass)!! ): IrClass { @@ -241,37 +220,44 @@ class Fir2IrConverter( } private fun registerClassAndNestedClasses(regularClass: FirRegularClass, parent: IrDeclarationParent): IrClass { + // Local classes might be referenced before they declared (see usages of Fir2IrClassifierStorage.createLocalIrClassOnTheFly) + // So, we only need to set its parent properly 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 { + } ?: classifierStorage.registerIrClass(regularClass, parent) + registerNestedClasses(regularClass, irClass) + return irClass + } + + private fun registerNestedClasses(klass: FirClass, irClass: IrClass) { + klass.declarations.forEach { if (it is FirRegularClass) { registerClassAndNestedClasses(it, irClass) } } if (generatorExtensions.isNotEmpty()) { - regularClass.generatedNestedClassifiers(session).forEach { + klass.generatedNestedClassifiers(session).forEach { if (it is FirRegularClass) { registerClassAndNestedClasses(it, irClass) } } } - return irClass } private fun processClassAndNestedClassHeaders(regularClass: FirRegularClass) { classifierStorage.processClassHeader(regularClass) - regularClass.declarations.forEach { + processNestedClassHeaders(regularClass) + } + + private fun processNestedClassHeaders(klass: FirClass) { + klass.declarations.forEach { if (it is FirRegularClass) { processClassAndNestedClassHeaders(it) } } if (generatorExtensions.isNotEmpty()) { - regularClass.generatedNestedClassifiers(session).forEach { + klass.generatedNestedClassifiers(session).forEach { if (it is FirRegularClass) { processClassAndNestedClassHeaders(it) } @@ -349,7 +335,8 @@ class Fir2IrConverter( val symbolTable = SymbolTable(signaturer, irFactory) val signatureComposer = FirBasedSignatureComposer(mangler) val components = Fir2IrComponentsStorage(session, scopeSession, symbolTable, irFactory, signatureComposer) - val classifierStorage = Fir2IrClassifierStorage(components) + val converter = Fir2IrConverter(moduleDescriptor, components) + val classifierStorage = Fir2IrClassifierStorage(converter, components) components.classifierStorage = classifierStorage components.delegatedMemberGenerator = DelegatedMemberGenerator(components) val declarationStorage = Fir2IrDeclarationStorage(components, moduleDescriptor) @@ -363,7 +350,6 @@ class Fir2IrConverter( languageVersionSettings.getFlag(AnalysisFlags.builtInsFromSources) ) components.irBuiltIns = irBuiltIns - val converter = Fir2IrConverter(moduleDescriptor, components) val conversionScope = Fir2IrConversionScope() val fir2irVisitor = Fir2IrVisitor(converter, components, conversionScope) val builtIns = Fir2IrBuiltIns(components, specialSymbolProvider) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index da481d1d150..cf34c7e839d 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -1171,8 +1171,7 @@ class Fir2IrDeclarationStorage( dispatchReceiverIrClass.declarations.find { it is IrSimpleFunction && it.isFakeOverride && it.name == fir.name && it.overrides(originalSymbol.owner as IrSimpleFunction) - }?.symbol as? IrFunctionSymbol - ?: originalSymbol // Fallback (normally we should not be here, but f/o are bound too late for local classes) + }?.symbol as IrFunctionSymbol } else { originalSymbol } @@ -1227,8 +1226,7 @@ class Fir2IrDeclarationStorage( classifierStorage.getIrClassSymbol(dispatchReceiverLookupTag.toSymbol(session) as FirClassSymbol).owner dispatchReceiverIrClass.declarations.find { it is IrProperty && it.isFakeOverride && it.name == fir.name && it.overrides(originalSymbol.owner as IrProperty) - }?.symbol as? IrPropertySymbol - ?: originalSymbol // Fallback (normally we should not be here, but f/o are bound too late for local classes) + }?.symbol as IrPropertySymbol } else { originalSymbol } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index f652d77f5f4..9094c51c025 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -116,7 +116,6 @@ class Fir2IrVisitor( classifierStorage.putEnumEntryClassInScope(enumEntry, correspondingClass) val anonymousObject = (enumEntry.initializer as FirAnonymousObjectExpression).anonymousObject converter.processAnonymousObjectMembers(anonymousObject, correspondingClass) - converter.bindFakeOverridesInClass(correspondingClass) conversionScope.withParent(correspondingClass) { conversionScope.withContainingFirClass(anonymousObject) { memberGenerator.convertClassContent(correspondingClass, anonymousObject) @@ -153,7 +152,6 @@ class Fir2IrVisitor( // NB: for implicit types it is possible that local class is already cached val irClass = classifierStorage.getCachedIrClass(regularClass)?.apply { this.parent = irParent } if (irClass != null) { - converter.processRegisteredLocalClassAndNestedClasses(regularClass, irClass) return conversionScope.withParent(irClass) { memberGenerator.convertClassContent(irClass, regularClass) } @@ -179,9 +177,9 @@ class Fir2IrVisitor( val irParent = conversionScope.parentFromStack() // NB: for implicit types it is possible that anonymous object is already cached val irAnonymousObject = classifierStorage.getCachedIrClass(anonymousObject)?.apply { this.parent = irParent } - ?: classifierStorage.createIrAnonymousObject(anonymousObject, irParent = irParent) - converter.processAnonymousObjectMembers(anonymousObject, irAnonymousObject) - converter.bindFakeOverridesInClass(irAnonymousObject) + ?: classifierStorage.createIrAnonymousObject(anonymousObject, irParent = irParent).also { + converter.processAnonymousObjectMembers(anonymousObject, it) + } conversionScope.withParent(irAnonymousObject) { conversionScope.withContainingFirClass(anonymousObject) { memberGenerator.convertClassContent(irAnonymousObject, anonymousObject) diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java index ef170775ceb..fa801eb2498 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java @@ -2296,6 +2296,12 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/firProblems/FirBuilder.kt"); } + @Test + @TestMetadata("FlushFromAnonymous.kt") + public void testFlushFromAnonymous() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/FlushFromAnonymous.kt"); + } + @Test @TestMetadata("ImplicitReceiverStack.kt") public void testImplicitReceiverStack() throws Exception { @@ -2332,6 +2338,12 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/firProblems/kt43342.kt"); } + @Test + @TestMetadata("localClassUsedBeforeDeclaration.kt") + public void testLocalClassUsedBeforeDeclaration() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.kt"); + } + @Test @TestMetadata("Modality.kt") public void testModality() throws Exception { diff --git a/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.fir.ir.txt b/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.fir.ir.txt new file mode 100644 index 00000000000..8b9423b81ac --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.fir.ir.txt @@ -0,0 +1,62 @@ +FILE fqName: fileName:/FlushFromAnonymous.kt + CLASS CLASS name:Serializer modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Serializer + CONSTRUCTOR visibility:public <> () returnType:.Serializer [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Serializer modality:FINAL visibility:public superTypes:[kotlin.Any]' + FUN name:serialize visibility:public modality:FINAL <> ($this:.Serializer) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.Serializer + BLOCK_BODY + VAR name:messageCollector type:.Serializer.createMessageCollector. [val] + CALL 'private final fun createMessageCollector (): .Serializer.createMessageCollector. declared in .Serializer' type=.Serializer.createMessageCollector. origin=null + $this: GET_VAR ': .Serializer declared in .Serializer.serialize' type=.Serializer origin=null + TRY type=kotlin.Unit + try: BLOCK type=kotlin.Unit origin=null + CATCH parameter=val e: kotlin.Throwable [val] declared in .Serializer.serialize + VAR name:e type:kotlin.Throwable [val] + BLOCK type=kotlin.Unit origin=null + CALL 'public open fun flush (): kotlin.Unit [fake_override] declared in .Serializer.createMessageCollector.' type=kotlin.Unit origin=null + $this: GET_VAR 'val messageCollector: .Serializer.createMessageCollector. [val] declared in .Serializer.serialize' type=.Serializer.createMessageCollector. origin=null + FUN name:createMessageCollector visibility:private modality:FINAL <> ($this:.Serializer) returnType:.Serializer.createMessageCollector. + $this: VALUE_PARAMETER name: type:.Serializer + BLOCK_BODY + RETURN type=kotlin.Nothing from='private final fun createMessageCollector (): .Serializer.createMessageCollector. declared in .Serializer' + BLOCK type=.Serializer.createMessageCollector. origin=OBJECT_LITERAL + CLASS CLASS name: modality:FINAL visibility:local superTypes:[.Collector] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Serializer.createMessageCollector. + CONSTRUCTOR visibility:private <> () returnType:.Serializer.createMessageCollector. [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in .Collector' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name: modality:FINAL visibility:local superTypes:[.Collector]' + FUN FAKE_OVERRIDE name:flush visibility:public modality:OPEN <> ($this:.Collector) returnType:kotlin.Unit [fake_override] + overridden: + public open fun flush (): kotlin.Unit declared in .Collector + $this: VALUE_PARAMETER name: type:.Collector + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .Collector + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in .Collector + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in .Collector + $this: VALUE_PARAMETER name: type:kotlin.Any + CONSTRUCTOR_CALL 'private constructor () [primary] declared in .Serializer.createMessageCollector.' type=.Serializer.createMessageCollector. origin=OBJECT_LITERAL + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.fir.kt.txt b/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.fir.kt.txt new file mode 100644 index 00000000000..2c5f9340cdd --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.fir.kt.txt @@ -0,0 +1,33 @@ +class Serializer { + constructor() /* primary */ { + super/*Any*/() + /* () */ + + } + + fun serialize() { + val messageCollector: = .createMessageCollector() + try { // BLOCK + } + catch (e: Throwable){ // BLOCK + messageCollector.flush() + } + + } + + private fun createMessageCollector(): { + return { // BLOCK + local class : Collector { + private constructor() /* primary */ { + super/*Collector*/() + /* () */ + + } + + } + + () + } + } + +} diff --git a/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.ir.txt b/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.ir.txt new file mode 100644 index 00000000000..c9a8a343047 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.ir.txt @@ -0,0 +1,62 @@ +FILE fqName: fileName:/FlushFromAnonymous.kt + CLASS CLASS name:Serializer modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Serializer + CONSTRUCTOR visibility:public <> () returnType:.Serializer [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Serializer modality:FINAL visibility:public superTypes:[kotlin.Any]' + FUN name:serialize visibility:public modality:FINAL <> ($this:.Serializer) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.Serializer + BLOCK_BODY + VAR name:messageCollector type:.Serializer.createMessageCollector. [val] + CALL 'private final fun createMessageCollector (): .Serializer.createMessageCollector. declared in .Serializer' type=.Serializer.createMessageCollector. origin=null + $this: GET_VAR ': .Serializer declared in .Serializer.serialize' type=.Serializer origin=null + TRY type=kotlin.Unit + try: BLOCK type=kotlin.Unit origin=null + CATCH parameter=val e: kotlin.Throwable [val] declared in .Serializer.serialize + VAR CATCH_PARAMETER name:e type:kotlin.Throwable [val] + BLOCK type=kotlin.Unit origin=null + CALL 'public open fun flush (): kotlin.Unit [fake_override] declared in .Serializer.createMessageCollector.' type=kotlin.Unit origin=null + $this: GET_VAR 'val messageCollector: .Serializer.createMessageCollector. [val] declared in .Serializer.serialize' type=.Serializer.createMessageCollector. origin=null + FUN name:createMessageCollector visibility:private modality:FINAL <> ($this:.Serializer) returnType:.Serializer.createMessageCollector. + $this: VALUE_PARAMETER name: type:.Serializer + BLOCK_BODY + RETURN type=kotlin.Nothing from='private final fun createMessageCollector (): .Serializer.createMessageCollector. declared in .Serializer' + BLOCK type=.Serializer.createMessageCollector. origin=OBJECT_LITERAL + CLASS CLASS name: modality:FINAL visibility:local superTypes:[.Collector] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Serializer.createMessageCollector. + CONSTRUCTOR visibility:public <> () returnType:.Serializer.createMessageCollector. [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in .Collector' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name: modality:FINAL visibility:local superTypes:[.Collector]' + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .Collector + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in .Collector + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in .Collector + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:flush visibility:public modality:OPEN <> ($this:.Collector) returnType:kotlin.Unit [fake_override] + overridden: + public open fun flush (): kotlin.Unit declared in .Collector + $this: VALUE_PARAMETER name: type:.Collector + CONSTRUCTOR_CALL 'public constructor () [primary] declared in .Serializer.createMessageCollector.' type=.Serializer.createMessageCollector. origin=OBJECT_LITERAL + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.kt b/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.kt new file mode 100644 index 00000000000..f9a585d0a00 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.kt @@ -0,0 +1,21 @@ +// SKIP_KLIB_TEST +// FILE: Collector.java + +public class Collector { + public void flush() {} +} + +// FILE: FlushFromAnonymous.kt + +class Serializer() { + fun serialize() { + val messageCollector = createMessageCollector() + try { + + } catch (e: Throwable) { + messageCollector.flush() + } + } + + private fun createMessageCollector() = object : Collector() {} +} diff --git a/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.kt.txt b/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.kt.txt new file mode 100644 index 00000000000..28f92c64e3d --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/FlushFromAnonymous.kt.txt @@ -0,0 +1,33 @@ +class Serializer { + constructor() /* primary */ { + super/*Any*/() + /* () */ + + } + + fun serialize() { + val messageCollector: = .createMessageCollector() + try { // BLOCK + } + catch (e: Throwable){ // BLOCK + messageCollector.flush() + } + + } + + private fun createMessageCollector(): { + return { // BLOCK + local class : Collector { + constructor() /* primary */ { + super/*Collector*/() + /* () */ + + } + + } + + () + } + } + +} diff --git a/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.fir.ir.txt b/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.fir.ir.txt new file mode 100644 index 00000000000..69d100e8338 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.fir.ir.txt @@ -0,0 +1,72 @@ +FILE fqName: fileName:/localClassUsedBeforeDeclaration.kt + FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CALL 'public final fun (): kotlin.String declared in .box..A' type=kotlin.String origin=GET_PROPERTY + $this: CALL 'public final fun (): .box..A declared in .box.' type=.box..A origin=GET_PROPERTY + $this: BLOCK type=.box. origin=OBJECT_LITERAL + CLASS CLASS name: modality:FINAL visibility:local superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.box. + CONSTRUCTOR visibility:private <> () returnType:.box. [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name: modality:FINAL visibility:local superTypes:[kotlin.Any]' + PROPERTY name:a visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:a type:.box..A visibility:private [final] + EXPRESSION_BODY + CONSTRUCTOR_CALL 'public constructor (ok: kotlin.String) [primary] declared in .box..A' type=.box..A origin=null + $outer: GET_VAR ': .box. declared in .box.' type=.box. origin=null + ok: CONST String type=kotlin.String value="OK" + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.box.) returnType:.box..A + correspondingProperty: PROPERTY name:a visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.box. + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): .box..A declared in .box.' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:a type:.box..A visibility:private [final]' type=.box..A origin=null + receiver: GET_VAR ': .box. declared in .box..' type=.box. origin=null + CLASS CLASS name:A modality:FINAL visibility:local [inner] superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.box..A + CONSTRUCTOR visibility:public <> ($this:.box., ok:kotlin.String) returnType:.box..A [primary] + $outer: VALUE_PARAMETER name: type:.box. + VALUE_PARAMETER name:ok index:0 type:kotlin.String + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:FINAL visibility:local [inner] superTypes:[kotlin.Any]' + PROPERTY name:ok visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:ok type:kotlin.String visibility:private [final] + EXPRESSION_BODY + GET_VAR 'ok: kotlin.String declared in .box..A.' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.box..A) returnType:kotlin.String + correspondingProperty: PROPERTY name:ok visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.box..A + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in .box..A' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:ok type:kotlin.String visibility:private [final]' type=kotlin.String origin=null + receiver: GET_VAR ': .box..A declared in .box..A.' type=.box..A origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CONSTRUCTOR_CALL 'private constructor () [primary] declared in .box.' type=.box. origin=OBJECT_LITERAL diff --git a/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.fir.kt.txt b/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.fir.kt.txt new file mode 100644 index 00000000000..2ef84cb6326 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.fir.kt.txt @@ -0,0 +1,31 @@ +fun box(): String { + return { // BLOCK + local class { + private constructor() /* primary */ { + super/*Any*/() + /* () */ + + } + + val a: A + field = .A(ok = "OK") + get + + local inner class A { + constructor(ok: String) /* primary */ { + super/*Any*/() + /* () */ + + } + + val ok: String + field = ok + get + + } + + } + + () + }.().() +} diff --git a/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.ir.txt b/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.ir.txt new file mode 100644 index 00000000000..54ccba6d9be --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.ir.txt @@ -0,0 +1,72 @@ +FILE fqName: fileName:/localClassUsedBeforeDeclaration.kt + FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CALL 'public final fun (): kotlin.String declared in .box..A' type=kotlin.String origin=GET_PROPERTY + $this: CALL 'public final fun (): .box..A declared in .box.' type=.box..A origin=GET_PROPERTY + $this: BLOCK type=.box. origin=OBJECT_LITERAL + CLASS CLASS name: modality:FINAL visibility:local superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.box. + CONSTRUCTOR visibility:public <> () returnType:.box. [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name: modality:FINAL visibility:local superTypes:[kotlin.Any]' + PROPERTY name:a visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:a type:.box..A visibility:private [final] + EXPRESSION_BODY + CONSTRUCTOR_CALL 'public constructor (ok: kotlin.String) [primary] declared in .box..A' type=.box..A origin=null + $outer: GET_VAR ': .box. declared in .box.' type=.box. origin=null + ok: CONST String type=kotlin.String value="OK" + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.box.) returnType:.box..A + correspondingProperty: PROPERTY name:a visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.box. + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): .box..A declared in .box.' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:a type:.box..A visibility:private [final]' type=.box..A origin=null + receiver: GET_VAR ': .box. declared in .box..' type=.box. origin=null + CLASS CLASS name:A modality:FINAL visibility:local [inner] superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.box..A + CONSTRUCTOR visibility:public <> ($this:.box., ok:kotlin.String) returnType:.box..A [primary] + $outer: VALUE_PARAMETER name: type:.box. + VALUE_PARAMETER name:ok index:0 type:kotlin.String + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:FINAL visibility:local [inner] superTypes:[kotlin.Any]' + PROPERTY name:ok visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:ok type:kotlin.String visibility:private [final] + EXPRESSION_BODY + GET_VAR 'ok: kotlin.String declared in .box..A.' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.box..A) returnType:kotlin.String + correspondingProperty: PROPERTY name:ok visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.box..A + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in .box..A' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:ok type:kotlin.String visibility:private [final]' type=kotlin.String origin=null + receiver: GET_VAR ': .box..A declared in .box..A.' type=.box..A origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CONSTRUCTOR_CALL 'public constructor () [primary] declared in .box.' type=.box. origin=OBJECT_LITERAL diff --git a/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.kt b/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.kt new file mode 100644 index 00000000000..0e5a5c087fd --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.kt @@ -0,0 +1,6 @@ +fun box(): String { + return object { + val a = A("OK") + inner class A(val ok: String) + }.a.ok +} diff --git a/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.kt.txt b/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.kt.txt new file mode 100644 index 00000000000..9ee2b9779ab --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.kt.txt @@ -0,0 +1,31 @@ +fun box(): String { + return { // BLOCK + local class { + constructor() /* primary */ { + super/*Any*/() + /* () */ + + } + + val a: A + field = .A(ok = "OK") + get + + local inner class A { + constructor(ok: String) /* primary */ { + super/*Any*/() + /* () */ + + } + + val ok: String + field = ok + get + + } + + } + + () + }.().() +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java index 51681a53842..89c06b8801d 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java @@ -2296,6 +2296,12 @@ public class IrTextTestGenerated extends AbstractIrTextTest { runTest("compiler/testData/ir/irText/firProblems/FirBuilder.kt"); } + @Test + @TestMetadata("FlushFromAnonymous.kt") + public void testFlushFromAnonymous() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/FlushFromAnonymous.kt"); + } + @Test @TestMetadata("ImplicitReceiverStack.kt") public void testImplicitReceiverStack() throws Exception { @@ -2332,6 +2338,12 @@ public class IrTextTestGenerated extends AbstractIrTextTest { runTest("compiler/testData/ir/irText/firProblems/kt43342.kt"); } + @Test + @TestMetadata("localClassUsedBeforeDeclaration.kt") + public void testLocalClassUsedBeforeDeclaration() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.kt"); + } + @Test @TestMetadata("Modality.kt") public void testModality() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/ir/KlibTextTestCaseGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/ir/KlibTextTestCaseGenerated.java index beaa84139e7..6900c5767ad 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/ir/KlibTextTestCaseGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/ir/KlibTextTestCaseGenerated.java @@ -1738,6 +1738,11 @@ public class KlibTextTestCaseGenerated extends AbstractKlibTextTestCase { runTest("compiler/testData/ir/irText/firProblems/FirBuilder.kt"); } + @TestMetadata("FlushFromAnonymous.kt") + public void testFlushFromAnonymous() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/FlushFromAnonymous.kt"); + } + @TestMetadata("ImplicitReceiverStack.kt") public void testImplicitReceiverStack() throws Exception { runTest("compiler/testData/ir/irText/firProblems/ImplicitReceiverStack.kt"); @@ -1758,6 +1763,11 @@ public class KlibTextTestCaseGenerated extends AbstractKlibTextTestCase { runTest("compiler/testData/ir/irText/firProblems/kt43342.kt"); } + @TestMetadata("localClassUsedBeforeDeclaration.kt") + public void testLocalClassUsedBeforeDeclaration() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/localClassUsedBeforeDeclaration.kt"); + } + @TestMetadata("readWriteProperty.kt") public void testReadWriteProperty() throws Exception { runTest("compiler/testData/ir/irText/firProblems/readWriteProperty.kt");