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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.psi2ir
|
package org.jetbrains.kotlin.psi2ir.generators
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.psi2ir
|
package org.jetbrains.kotlin.psi2ir.generators
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* 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.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* 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.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* 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.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
+2
-1
@@ -14,12 +14,13 @@
|
|||||||
* limitations under the License.
|
* 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.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleImpl
|
import org.jetbrains.kotlin.ir.declarations.IrModuleImpl
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
class IrGeneratorContext(
|
class IrGeneratorContext(
|
||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* 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.ir.declarations.IrFileImpl
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
+2
-1
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* 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.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
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.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
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.codegen.CodegenTestCase
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleImpl
|
import org.jetbrains.kotlin.ir.declarations.IrModuleImpl
|
||||||
import org.jetbrains.kotlin.psi2ir.IrGeneratorContext
|
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||||
import org.jetbrains.kotlin.psi2ir.IrModuleGenerator
|
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.AnalyzingUtils
|
||||||
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
|
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
|
||||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||||
@@ -41,9 +43,8 @@ abstract class AbstractIrGeneratorTestCase : CodegenTestCase() {
|
|||||||
val analysisResult = JvmResolveUtil.analyzeAndCheckForErrors(myFiles.psiFiles, myEnvironment)
|
val analysisResult = JvmResolveUtil.analyzeAndCheckForErrors(myFiles.psiFiles, myEnvironment)
|
||||||
analysisResult.throwIfError()
|
analysisResult.throwIfError()
|
||||||
AnalyzingUtils.throwExceptionOnErrors(analysisResult.bindingContext)
|
AnalyzingUtils.throwExceptionOnErrors(analysisResult.bindingContext)
|
||||||
val irModule = IrModuleImpl(analysisResult.moduleDescriptor)
|
val psi2ir = Psi2IrTranslator()
|
||||||
val irGeneratorContext = IrGeneratorContext(myFiles.psiFiles, irModule, analysisResult.bindingContext)
|
val irModule = psi2ir.generateModule(analysisResult.moduleDescriptor, myFiles.psiFiles, analysisResult.bindingContext)
|
||||||
IrModuleGenerator(irGeneratorContext).generateModuleContent()
|
|
||||||
return testFiles.filter { it.name.endsWith(".kt") }.zip(irModule.files).toMap()
|
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)
|
this?.setTreeLocation(null, DETACHED_SLOT)
|
||||||
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrElement.replaceWith(otherElement: IrElement) {
|
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) {
|
fun IrElement.assertChild(child: IrElement) {
|
||||||
|
|||||||
@@ -28,11 +28,10 @@ IrFile /callWithReorderedArguments.kt
|
|||||||
CALL .foo type=kotlin.Unit operator=
|
CALL .foo type=kotlin.Unit operator=
|
||||||
a: CALL .noReorder1 type=kotlin.Int operator=
|
a: CALL .noReorder1 type=kotlin.Int operator=
|
||||||
b: CALL .noReorder2 type=kotlin.Int operator=
|
b: CALL .noReorder2 type=kotlin.Int operator=
|
||||||
BLOCK type=kotlin.Unit hasResult=false isDesugared=true
|
VAR val tmp0: kotlin.Int
|
||||||
VAR val tmp0: kotlin.Int
|
CALL .reordered1 type=kotlin.Int operator=
|
||||||
CALL .reordered1 type=kotlin.Int operator=
|
VAR val tmp1: kotlin.Int
|
||||||
VAR val tmp1: kotlin.Int
|
CALL .reordered2 type=kotlin.Int operator=
|
||||||
CALL .reordered2 type=kotlin.Int operator=
|
CALL .foo type=kotlin.Unit operator=
|
||||||
CALL .foo type=kotlin.Unit operator=
|
a: GET_VAR tmp1 type=kotlin.Int
|
||||||
a: GET_VAR tmp1 type=kotlin.Int
|
b: GET_VAR tmp0 type=kotlin.Int
|
||||||
b: GET_VAR tmp0 type=kotlin.Int
|
|
||||||
|
|||||||
+10
-11
@@ -1,14 +1,13 @@
|
|||||||
IrFunction public fun B.test(): kotlin.Unit
|
IrFunction public fun B.test(): kotlin.Unit
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=kotlin.Unit hasResult=false isDesugared=false
|
BLOCK type=kotlin.Unit hasResult=false isDesugared=false
|
||||||
BLOCK type=kotlin.Unit hasResult=false isDesugared=true
|
VAR val tmp0: A
|
||||||
VAR val tmp0: A
|
GET_VAR A type=A
|
||||||
GET_VAR A type=A
|
VAR val x: kotlin.Int
|
||||||
VAR val x: kotlin.Int
|
CALL .component1 type=kotlin.Int operator=COMPONENT_N(index=1)
|
||||||
CALL .component1 type=kotlin.Int operator=COMPONENT_N(index=1)
|
$this: $RECEIVER of: test type=B
|
||||||
$this: $RECEIVER of: test type=B
|
$receiver: GET_VAR tmp0 type=A
|
||||||
$receiver: GET_VAR tmp0 type=A
|
VAR val y: kotlin.Int
|
||||||
VAR val y: kotlin.Int
|
CALL .component2 type=kotlin.Int operator=COMPONENT_N(index=2)
|
||||||
CALL .component2 type=kotlin.Int operator=COMPONENT_N(index=2)
|
$this: $RECEIVER of: test type=B
|
||||||
$this: $RECEIVER of: test type=B
|
$receiver: GET_VAR tmp0 type=A
|
||||||
$receiver: GET_VAR tmp0 type=A
|
|
||||||
|
|||||||
Reference in New Issue
Block a user