From de7b7ce6d5e67c4f38ec2bf107c9b4358c1067db Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 21 Apr 2017 12:21:01 +0300 Subject: [PATCH] Generate anonymous initializer body in separate scope --- .../AnonymousInitializerGenerator.kt | 45 +++++++++++++++++++ .../kotlin/psi2ir/generators/BodyGenerator.kt | 24 ++-------- .../psi2ir/generators/DeclarationGenerator.kt | 10 +---- .../psi2ir/generators/StatementGenerator.kt | 3 ++ 4 files changed, 52 insertions(+), 30 deletions(-) create mode 100644 compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AnonymousInitializerGenerator.kt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AnonymousInitializerGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AnonymousInitializerGenerator.kt new file mode 100644 index 00000000000..ad58e4c6c0a --- /dev/null +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AnonymousInitializerGenerator.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.psi2ir.generators + +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl +import org.jetbrains.kotlin.psi.KtAnonymousInitializer +import org.jetbrains.kotlin.psi.KtBlockExpression +import org.jetbrains.kotlin.psi.psiUtil.endOffset +import org.jetbrains.kotlin.psi.psiUtil.startOffset + +class AnonymousInitializerGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) { + fun generateAnonymousInitializerDeclaration(ktAnonymousInitializer: KtAnonymousInitializer, classDescriptor: ClassDescriptor): IrDeclaration = + context.symbolTable.declareAnonymousInitializer( + ktAnonymousInitializer.startOffset, ktAnonymousInitializer.endOffset, IrDeclarationOrigin.DEFINED, classDescriptor + ).buildWithScope { irAnonymousInitializer -> + val bodyGenerator = createBodyGenerator(irAnonymousInitializer.symbol) + val statementGenerator = bodyGenerator.createStatementGenerator() + val ktBody = ktAnonymousInitializer.body!! + val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset) + if (ktBody is KtBlockExpression) { + statementGenerator.generateStatements(ktBody.statements, irBlockBody) + } + else { + irBlockBody.statements.add(statementGenerator.generateStatement(ktBody)) + } + irAnonymousInitializer.body = irBlockBody + } +} \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt index 952e4af34f7..437fbecb0a5 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt @@ -47,7 +47,7 @@ class BodyGenerator( val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset) if (ktBody is KtBlockExpression) { - statementGenerator.generateBlockBodyStatements(irBlockBody, ktBody) + statementGenerator.generateStatements(ktBody.statements, irBlockBody) } else { statementGenerator.generateReturnExpression(ktBody, irBlockBody) @@ -94,12 +94,6 @@ class BodyGenerator( return irBlockBody } - private fun StatementGenerator.generateBlockBodyStatements(irBlockBody: IrBlockBodyImpl, ktBody: KtBlockExpression) { - for (ktStatement in ktBody.statements) { - irBlockBody.statements.add(generateStatement(ktStatement)) - } - } - private fun StatementGenerator.generateReturnExpression(ktExpression: KtExpression, irBlockBody: IrBlockBodyImpl) { val irReturnExpression = generateStatement(ktExpression) if (irReturnExpression is IrExpression) { @@ -132,7 +126,7 @@ class BodyGenerator( generateDelegatingConstructorCall(irBlockBody, ktConstructor) ktConstructor.bodyExpression?.let { ktBody -> - createStatementGenerator().generateBlockBodyStatements(irBlockBody, ktBody) + createStatementGenerator().generateStatements(ktBody.statements, irBlockBody) } return irBlockBody @@ -193,7 +187,7 @@ class BodyGenerator( context.symbolTable.referenceClass(classDescriptor))) ktConstructor.bodyExpression?.let { ktBody -> - createStatementGenerator().generateBlockBodyStatements(irBlockBody, ktBody) + createStatementGenerator().generateStatements(ktBody.statements, irBlockBody) } return irBlockBody @@ -259,18 +253,6 @@ class BodyGenerator( return generateEnumConstructorCallOrSuperCall(ktEnumEntry, enumEntryDescriptor.containingDeclaration as ClassDescriptor) } - fun generateAnonymousInitializerBody(ktAnonymousInitializer: KtAnonymousInitializer): IrBlockBody { - val ktBody = ktAnonymousInitializer.body!! - val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset) - if (ktBody is KtBlockExpression) { - createStatementGenerator().generateBlockBodyStatements(irBlockBody, ktBody) - } - else { - irBlockBody.statements.add(createStatementGenerator().generateStatement(ktBody)) - } - return irBlockBody - } - fun generateEnumEntryInitializer(ktEnumEntry: KtEnumEntry, enumEntryDescriptor: ClassDescriptor): IrExpression { if (ktEnumEntry.declarations.isNotEmpty()) { val enumEntryConstructor = enumEntryDescriptor.unsubstitutedPrimaryConstructor!! diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt index 60cef947b3c..3bd05c3c8a4 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrErrorDeclarationImpl -import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl import org.jetbrains.kotlin.ir.declarations.impl.IrTypeAliasImpl import org.jetbrains.kotlin.ir.expressions.IrExpressionBody @@ -53,7 +52,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator { fun generateClassMemberDeclaration(ktDeclaration: KtDeclaration, classDescriptor: ClassDescriptor): IrDeclaration = when (ktDeclaration) { is KtAnonymousInitializer -> - generateAnonymousInitializerDeclaration(ktDeclaration, classDescriptor) + AnonymousInitializerGenerator(this).generateAnonymousInitializerDeclaration(ktDeclaration, classDescriptor) is KtSecondaryConstructor -> FunctionGenerator(this).generateSecondaryConstructor(ktDeclaration) is KtEnumEntry -> @@ -72,13 +71,6 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator { IrTypeAliasImpl(ktDeclaration.startOffset, ktDeclaration.endOffset, IrDeclarationOrigin.DEFINED, getOrFail(BindingContext.TYPE_ALIAS, ktDeclaration)) - fun generateAnonymousInitializerDeclaration(ktAnonymousInitializer: KtAnonymousInitializer, classDescriptor: ClassDescriptor): IrDeclaration = - context.symbolTable.declareAnonymousInitializer( - ktAnonymousInitializer.startOffset, ktAnonymousInitializer.endOffset, IrDeclarationOrigin.DEFINED, classDescriptor - ).apply { - body = createBodyGenerator(symbol).generateAnonymousInitializerBody(ktAnonymousInitializer) - } - fun generateTypeParameterDeclarations( irTypeParametersOwner: IrTypeParametersContainer, diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt index ae637bbc9e1..cbbb1ab9cf0 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt @@ -54,6 +54,9 @@ class StatementGenerator( fun generateStatement(ktElement: KtElement): IrStatement = ktElement.genStmt() + fun generateStatements(ktStatements: List, to: IrStatementContainer) = + ktStatements.mapTo(to.statements) { generateStatement(it) } + fun generateExpression(ktExpression: KtExpression): IrExpression = ktExpression.genExpr()