IR: Collapse desugared blocks as a postprocessing pass.
This commit is contained in:
committed by
Dmitry Petrov
parent
aa7bf4637b
commit
c4bbcadb34
@@ -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<KtFile>, 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)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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.*
|
||||
+1
-1
@@ -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.*
|
||||
+1
-1
@@ -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
|
||||
+1
-1
@@ -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
|
||||
+1
-1
@@ -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
|
||||
+2
-1
@@ -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(
|
||||
+1
-1
@@ -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
|
||||
+2
-1
@@ -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
|
||||
+53
@@ -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<Unit, Nothing?> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,12 +44,13 @@ abstract class IrElementBase(override val startOffset: Int, override val endOffs
|
||||
}
|
||||
}
|
||||
|
||||
fun IrElement?.detach() {
|
||||
fun <T : IrElement?> 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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
+10
-11
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user