diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt new file mode 100644 index 00000000000..2284bdee2e9 --- /dev/null +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2016 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 + +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.declarations.IrModule +import org.jetbrains.kotlin.ir.declarations.IrModuleImpl +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi2ir.generators.IrGeneratorContext +import org.jetbrains.kotlin.psi2ir.generators.IrModuleGenerator +import org.jetbrains.kotlin.psi2ir.transformations.collapseDesugaredBlocks +import org.jetbrains.kotlin.resolve.BindingContext + +class Psi2IrTranslator(val configuration: Configuration = Configuration()) { + class Configuration( + val shouldCollapseDesugaredBlocks: Boolean = true + ) + + fun generateModule(moduleDescriptor: ModuleDescriptor, ktFiles: List, bindingContext: BindingContext): IrModule { + val irModule = IrModuleImpl(moduleDescriptor) + val irGeneratorContext = IrGeneratorContext(ktFiles, irModule, bindingContext) + IrModuleGenerator(irGeneratorContext).generateModuleContent() + postprocess(irModule) + return irModule + } + + private fun postprocess(irElement: IrElement) { + if (configuration.shouldCollapseDesugaredBlocks) collapseDesugaredBlocks(irElement) + } +} diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrCallGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrCallGenerator.kt similarity index 99% rename from compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrCallGenerator.kt rename to compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrCallGenerator.kt index f89fc54546a..6c477e7b6ae 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrCallGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrCallGenerator.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.psi2ir +package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.expressions.* diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationFactory.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrDeclarationFactory.kt similarity index 99% rename from compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationFactory.kt rename to compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrDeclarationFactory.kt index d8dde51b1f3..40b4e8d80a7 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationFactory.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrDeclarationFactory.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.psi2ir +package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.declarations.* diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrDeclarationGenerator.kt similarity index 99% rename from compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt rename to compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrDeclarationGenerator.kt index 8b68069f818..faa7f180678 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrDeclarationGenerator.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.psi2ir +package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrFileGenerator.kt similarity index 96% rename from compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt rename to compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrFileGenerator.kt index e1aedf8f1c4..0031b340956 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrFileGenerator.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.psi2ir +package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrFile diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrGenerator.kt similarity index 97% rename from compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGenerator.kt rename to compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrGenerator.kt index 648e8e4a0bf..99c2f25ea9c 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrGenerator.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.psi2ir +package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.psi.KtExpression diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGeneratorContext.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrGeneratorContext.kt similarity index 92% rename from compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGeneratorContext.kt rename to compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrGeneratorContext.kt index f376ce89a54..de130152a88 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGeneratorContext.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrGeneratorContext.kt @@ -14,12 +14,13 @@ * limitations under the License. */ -package org.jetbrains.kotlin.psi2ir +package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.declarations.IrModuleImpl import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi2ir.PsiSourceManager import org.jetbrains.kotlin.resolve.BindingContext class IrGeneratorContext( diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrModuleGenerator.kt similarity index 97% rename from compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt rename to compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrModuleGenerator.kt index a19587a602e..65867e52474 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrModuleGenerator.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.psi2ir +package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.ir.declarations.IrFileImpl import org.jetbrains.kotlin.resolve.BindingContext diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrStatementGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrStatementGenerator.kt similarity index 99% rename from compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrStatementGenerator.kt rename to compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrStatementGenerator.kt index 94e15bf4390..f64d305403f 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrStatementGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrStatementGenerator.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.psi2ir +package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.psi2ir.deparenthesize import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/CollapseDesugaredBlocks.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/CollapseDesugaredBlocks.kt new file mode 100644 index 00000000000..8711ef9df69 --- /dev/null +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/CollapseDesugaredBlocks.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2016 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.transformations + +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.detach +import org.jetbrains.kotlin.ir.expressions.IrBlockExpression +import org.jetbrains.kotlin.ir.expressions.IrBlockExpressionImpl +import org.jetbrains.kotlin.ir.replaceWith +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor + +fun collapseDesugaredBlocks(element: IrElement) { + element.accept(CollapseDesugaredBlocks(), null) +} + +class CollapseDesugaredBlocks : IrElementVisitor { + override fun visitElement(element: IrElement, data: Nothing?) { + element.acceptChildren(this, data) + } + + override fun visitBlockExpression(expression: IrBlockExpression, data: Nothing?) { + val transformedBlock = IrBlockExpressionImpl( + expression.startOffset, expression.endOffset, expression.type, + expression.hasResult, expression.isDesugared + ) + for (statement in expression.statements) { + statement.accept(this, data) + if (statement is IrBlockExpression && statement.isDesugared) { + statement.statements.forEach { + transformedBlock.addStatement(it.detach()) + } + } + else { + transformedBlock.addStatement(statement.detach()) + } + } + expression.replaceWith(transformedBlock) + } +} diff --git a/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt index 666a197ad66..184ea41917e 100644 --- a/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt +++ b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt @@ -19,8 +19,10 @@ package org.jetbrains.kotlin.ir import org.jetbrains.kotlin.codegen.CodegenTestCase import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleImpl -import org.jetbrains.kotlin.psi2ir.IrGeneratorContext -import org.jetbrains.kotlin.psi2ir.IrModuleGenerator +import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator +import org.jetbrains.kotlin.psi2ir.generators.IrGeneratorContext +import org.jetbrains.kotlin.psi2ir.generators.IrModuleGenerator +import org.jetbrains.kotlin.psi2ir.transformations.collapseDesugaredBlocks import org.jetbrains.kotlin.resolve.AnalyzingUtils import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil import org.jetbrains.kotlin.test.ConfigurationKind @@ -41,9 +43,8 @@ abstract class AbstractIrGeneratorTestCase : CodegenTestCase() { val analysisResult = JvmResolveUtil.analyzeAndCheckForErrors(myFiles.psiFiles, myEnvironment) analysisResult.throwIfError() AnalyzingUtils.throwExceptionOnErrors(analysisResult.bindingContext) - val irModule = IrModuleImpl(analysisResult.moduleDescriptor) - val irGeneratorContext = IrGeneratorContext(myFiles.psiFiles, irModule, analysisResult.bindingContext) - IrModuleGenerator(irGeneratorContext).generateModuleContent() + val psi2ir = Psi2IrTranslator() + val irModule = psi2ir.generateModule(analysisResult.moduleDescriptor, myFiles.psiFiles, analysisResult.bindingContext) return testFiles.filter { it.name.endsWith(".kt") }.zip(irModule.files).toMap() } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt index a1fa5828272..5a1d9248740 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt @@ -44,12 +44,13 @@ abstract class IrElementBase(override val startOffset: Int, override val endOffs } } -fun IrElement?.detach() { +fun T.detach(): T { this?.setTreeLocation(null, DETACHED_SLOT) + return this } fun IrElement.replaceWith(otherElement: IrElement) { - parent?.replaceChild(slot, otherElement) + parent?.run { replaceChild(slot, otherElement.detach()) } ?: throw AssertionError("Can't replace a non-root element $this") } fun IrElement.assertChild(child: IrElement) { diff --git a/compiler/testData/ir/irText/callWithReorderedArguments.txt b/compiler/testData/ir/irText/callWithReorderedArguments.txt index 5270eac507d..24d3cbbad5e 100644 --- a/compiler/testData/ir/irText/callWithReorderedArguments.txt +++ b/compiler/testData/ir/irText/callWithReorderedArguments.txt @@ -28,11 +28,10 @@ IrFile /callWithReorderedArguments.kt CALL .foo type=kotlin.Unit operator= a: CALL .noReorder1 type=kotlin.Int operator= b: CALL .noReorder2 type=kotlin.Int operator= - BLOCK type=kotlin.Unit hasResult=false isDesugared=true - VAR val tmp0: kotlin.Int - CALL .reordered1 type=kotlin.Int operator= - VAR val tmp1: kotlin.Int - CALL .reordered2 type=kotlin.Int operator= - CALL .foo type=kotlin.Unit operator= - a: GET_VAR tmp1 type=kotlin.Int - b: GET_VAR tmp0 type=kotlin.Int + VAR val tmp0: kotlin.Int + CALL .reordered1 type=kotlin.Int operator= + VAR val tmp1: kotlin.Int + CALL .reordered2 type=kotlin.Int operator= + CALL .foo type=kotlin.Unit operator= + a: GET_VAR tmp1 type=kotlin.Int + b: GET_VAR tmp0 type=kotlin.Int diff --git a/compiler/testData/ir/irText/destructuring1.txt b/compiler/testData/ir/irText/destructuring1.txt index a490a107101..de386acb978 100644 --- a/compiler/testData/ir/irText/destructuring1.txt +++ b/compiler/testData/ir/irText/destructuring1.txt @@ -1,14 +1,13 @@ IrFunction public fun B.test(): kotlin.Unit IrExpressionBody BLOCK type=kotlin.Unit hasResult=false isDesugared=false - BLOCK type=kotlin.Unit hasResult=false isDesugared=true - VAR val tmp0: A - GET_VAR A type=A - VAR val x: kotlin.Int - CALL .component1 type=kotlin.Int operator=COMPONENT_N(index=1) - $this: $RECEIVER of: test type=B - $receiver: GET_VAR tmp0 type=A - VAR val y: kotlin.Int - CALL .component2 type=kotlin.Int operator=COMPONENT_N(index=2) - $this: $RECEIVER of: test type=B - $receiver: GET_VAR tmp0 type=A + VAR val tmp0: A + GET_VAR A type=A + VAR val x: kotlin.Int + CALL .component1 type=kotlin.Int operator=COMPONENT_N(index=1) + $this: $RECEIVER of: test type=B + $receiver: GET_VAR tmp0 type=A + VAR val y: kotlin.Int + CALL .component2 type=kotlin.Int operator=COMPONENT_N(index=2) + $this: $RECEIVER of: test type=B + $receiver: GET_VAR tmp0 type=A