IrElementVisitorVoid

This commit is contained in:
Dmitry Petrov
2016-09-05 12:59:11 +03:00
committed by Dmitry Petrov
parent e29b8e356c
commit a1ad828ea8
7 changed files with 264 additions and 40 deletions
@@ -20,27 +20,29 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.detach
import org.jetbrains.kotlin.ir.expressions.IrGeneralCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGeneralCall
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenationImpl
import org.jetbrains.kotlin.ir.replaceWith
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.util.OperatorNameConventions
import java.util.*
fun foldStringConcatenation(element: IrElement) {
element.accept(FoldStringConcatenation(), null)
element.acceptVoid(FoldStringConcatenation())
}
class FoldStringConcatenation : IrElementVisitor<Unit, Nothing?> {
override fun visitElement(element: IrElement, data: Nothing?) {
element.acceptChildren(this, data)
class FoldStringConcatenation : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitGeneralCall(expression: IrGeneralCall, data: Nothing?) {
override fun visitGeneralCall(expression: IrGeneralCall) {
if (!isStringPlus(expression.descriptor)) {
visitElement(expression, data)
visitElement(expression)
return
}
@@ -22,20 +22,23 @@ import org.jetbrains.kotlin.ir.expressions.IrBlock
import org.jetbrains.kotlin.ir.expressions.IrBlockImpl
import org.jetbrains.kotlin.ir.replaceWith
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
fun inlineDesugaredBlocks(element: IrElement) {
element.accept(InlineDesugaredBlocks(), null)
element.acceptVoid(InlineDesugaredBlocks())
}
class InlineDesugaredBlocks : IrElementVisitor<Unit, Nothing?> {
override fun visitElement(element: IrElement, data: Nothing?) {
element.acceptChildren(this, data)
class InlineDesugaredBlocks : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitBlock(expression: IrBlock, data: Nothing?) {
override fun visitBlock(expression: IrBlock) {
val transformedBlock = IrBlockImpl(expression.startOffset, expression.endOffset, expression.type, expression.operator)
for (statement in expression.statements) {
statement.accept(this, data)
statement.acceptVoid(this)
if (statement is IrBlock && statement.operator != null) {
statement.statements.forEach {
transformedBlock.addStatement(it.detach())
@@ -22,7 +22,9 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.detach
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.replaceWith
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.psi2ir.containsNull
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
@@ -31,16 +33,16 @@ import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.types.upperIfFlexible
fun insertImplicitCasts(builtIns: KotlinBuiltIns, element: IrElement) {
element.accept(InsertImplicitCasts(builtIns), null)
element.acceptVoid(InsertImplicitCasts(builtIns))
}
class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitor<Unit, Nothing?> {
override fun visitElement(element: IrElement, data: Nothing?) {
element.acceptChildren(this, null)
class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitGeneralCall(expression: IrGeneralCall, data: Nothing?) {
expression.acceptChildren(this, null)
override fun visitGeneralCall(expression: IrGeneralCall) {
expression.acceptChildrenVoid(this)
with(expression) {
dispatchReceiver?.replaceWithCast(descriptor.dispatchReceiverParameter?.type)
@@ -52,7 +54,7 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitor<Unit,
}
}
override fun visitBlock(expression: IrBlock, data: Nothing?) {
override fun visitBlock(expression: IrBlock) {
expression.acceptChildren(this, null)
val type = expression.type
if (KotlinBuiltIns.isUnit(type)) return
@@ -64,25 +66,25 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitor<Unit,
}
}
override fun visitReturn(expression: IrReturn, data: Nothing?) {
override fun visitReturn(expression: IrReturn) {
expression.acceptChildren(this, null)
expression.value?.replaceWithCast(expression.returnTarget.returnType)
}
override fun visitSetVariable(expression: IrSetVariable, data: Nothing?) {
override fun visitSetVariable(expression: IrSetVariable) {
expression.acceptChildren(this, null)
expression.value.replaceWithCast(expression.descriptor.type)
}
override fun visitVariable(declaration: IrVariable, data: Nothing?) {
override fun visitVariable(declaration: IrVariable) {
declaration.acceptChildren(this, null)
declaration.initializer?.replaceWithCast(declaration.descriptor.type)
}
override fun visitWhen(expression: IrWhen, data: Nothing?) {
override fun visitWhen(expression: IrWhen) {
expression.acceptChildren(this, null)
for (branchIndex in expression.branchIndices) {
@@ -92,19 +94,19 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitor<Unit,
expression.elseBranch?.replaceWithCast(expression.type)
}
override fun visitLoop(loop: IrLoop, data: Nothing?) {
override fun visitLoop(loop: IrLoop) {
loop.acceptChildren(this, null)
loop.condition.replaceWithCast(builtIns.booleanType)
}
override fun visitThrow(expression: IrThrow, data: Nothing?) {
override fun visitThrow(expression: IrThrow) {
expression.acceptChildren(this, null)
expression.value.replaceWithCast(builtIns.throwable.defaultType)
}
override fun visitTryCatch(tryCatch: IrTryCatch, data: Nothing?) {
override fun visitTryCatch(tryCatch: IrTryCatch) {
tryCatch.acceptChildren(this, null)
val resultType = tryCatch.type
@@ -115,8 +117,8 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitor<Unit,
}
}
override fun visitVararg(expression: IrVararg, data: Nothing?) {
expression.acceptChildren(this, data)
override fun visitVararg(expression: IrVararg) {
expression.acceptChildrenVoid(this)
for (element in expression.elements) {
when (element) {
is IrSpreadElement -> element.expression.replaceWithCast(expression.type)
@@ -20,15 +20,16 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrGetVariable
import org.jetbrains.kotlin.ir.replaceWith
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.psi2ir.intermediate.IntermediateValue
class ReplaceTemporaryVariable(val from: IrVariable, val to: IntermediateValue) : IrElementVisitor<Unit, Nothing?> {
override fun visitElement(element: IrElement, data: Nothing?) {
element.acceptChildren(this, data)
class ReplaceTemporaryVariable(val from: IrVariable, val to: IntermediateValue) : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitGetVariable(expression: IrGetVariable, data: Nothing?) {
override fun visitGetVariable(expression: IrGetVariable) {
if (expression.descriptor == from.descriptor) {
expression.replaceWith { to.load() }
}
@@ -21,6 +21,8 @@ import org.jetbrains.kotlin.ir.SourceLocationManager
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.utils.Printer
fun IrElement.dump(): String {
@@ -153,15 +155,15 @@ class DumpTreeFromSourceLineVisitor(
val fileEntry: SourceLocationManager.FileEntry,
val lineNumber: Int,
out: Appendable
): IrElementVisitor<Unit, Nothing?> {
): IrElementVisitorVoid {
val dumper = DumpIrTreeVisitor(out)
override fun visitElement(element: IrElement, data: Nothing?) {
override fun visitElement(element: IrElement) {
if (fileEntry.getLineNumber(element.startOffset) == lineNumber) {
element.accept(dumper, "")
return
}
element.acceptChildren(this, data)
element.acceptChildrenVoid(this)
}
}
@@ -71,7 +71,7 @@ interface IrElementVisitor<out R, in D> {
fun visitEnumConstructorCall(expression: IrEnumConstructorCall, data: D) = visitGeneralCall(expression, data)
fun visitGetClass(expression: IrGetClass, data: D) = visitExpression(expression, data)
fun visitCallableReference(expression: IrCallableReference, data: D) = visitDeclarationReference(expression, data)
fun visitCallableReference(expression: IrCallableReference, data: D) = visitGeneralCall(expression, data)
fun visitClassReference(expression: IrClassReference, data: D) = visitDeclarationReference(expression, data)
fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: D) = visitExpression(expression, data)
@@ -0,0 +1,214 @@
/*
* 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.ir.visitors
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
interface IrElementVisitorVoid : IrElementVisitor<Unit, Nothing?> {
fun visitElement(element: IrElement)
override fun visitElement(element: IrElement, data: Nothing?) = visitElement(element)
fun visitModule(declaration: IrModule) = visitElement(declaration)
override fun visitModule(declaration: IrModule, data: Nothing?) = visitModule(declaration)
fun visitFile(declaration: IrFile) = visitElement(declaration)
override fun visitFile(declaration: IrFile, data: Nothing?) = visitFile(declaration)
fun visitDeclaration(declaration: IrDeclaration) = visitElement(declaration)
override fun visitDeclaration(declaration: IrDeclaration, data: Nothing?) = visitDeclaration(declaration)
fun visitClass(declaration: IrClass) = visitDeclaration(declaration)
override fun visitClass(declaration: IrClass, data: Nothing?) = visitClass(declaration)
fun visitTypeAlias(declaration: IrTypeAlias) = visitDeclaration(declaration)
override fun visitTypeAlias(declaration: IrTypeAlias, data: Nothing?) = visitTypeAlias(declaration)
fun visitGeneralFunction(declaration: IrGeneralFunction) = visitDeclaration(declaration)
override fun visitGeneralFunction(declaration: IrGeneralFunction, data: Nothing?) = visitGeneralFunction(declaration)
fun visitFunction(declaration: IrFunction) = visitGeneralFunction(declaration)
override fun visitFunction(declaration: IrFunction, data: Nothing?) = visitFunction(declaration)
fun visitPropertyGetter(declaration: IrPropertyGetter) = visitGeneralFunction(declaration)
override fun visitPropertyGetter(declaration: IrPropertyGetter, data: Nothing?) = visitPropertyGetter(declaration)
fun visitPropertySetter(declaration: IrPropertySetter) = visitGeneralFunction(declaration)
override fun visitPropertySetter(declaration: IrPropertySetter, data: Nothing?) = visitPropertySetter(declaration)
fun visitConstructor(declaration: IrConstructor) = visitGeneralFunction(declaration)
override fun visitConstructor(declaration: IrConstructor, data: Nothing?) = visitConstructor(declaration)
fun visitProperty(declaration: IrProperty) = visitDeclaration(declaration)
override fun visitProperty(declaration: IrProperty, data: Nothing?) = visitProperty(declaration)
fun visitSimpleProperty(declaration: IrSimpleProperty) = visitProperty(declaration)
override fun visitSimpleProperty(declaration: IrSimpleProperty, data: Nothing?) = visitSimpleProperty(declaration)
fun visitDelegatedProperty(declaration: IrDelegatedProperty) = visitProperty(declaration)
override fun visitDelegatedProperty(declaration: IrDelegatedProperty, data: Nothing?) = visitDelegatedProperty(declaration)
fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty) = visitDeclaration(declaration)
override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty, data: Nothing?) = visitLocalDelegatedProperty(declaration)
fun visitLocalPropertyAccessor(declaration: IrLocalPropertyAccessor) = visitGeneralFunction(declaration)
override fun visitLocalPropertyAccessor(declaration: IrLocalPropertyAccessor, data: Nothing?) = visitLocalPropertyAccessor(declaration)
fun visitVariable(declaration: IrVariable) = visitDeclaration(declaration)
override fun visitVariable(declaration: IrVariable, data: Nothing?) = visitVariable(declaration)
fun visitEnumEntry(declaration: IrEnumEntry) = visitDeclaration(declaration)
override fun visitEnumEntry(declaration: IrEnumEntry, data: Nothing?) = visitEnumEntry(declaration)
fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) = visitDeclaration(declaration)
override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer, data: Nothing?) = visitAnonymousInitializer(declaration)
fun visitBody(body: IrBody) = visitElement(body)
override fun visitBody(body: IrBody, data: Nothing?) = visitBody(body)
fun visitExpressionBody(body: IrExpressionBody) = visitBody(body)
override fun visitExpressionBody(body: IrExpressionBody, data: Nothing?) = visitExpressionBody(body)
fun visitBlockBody(body: IrBlockBody) = visitBody(body)
override fun visitBlockBody(body: IrBlockBody, data: Nothing?) = visitBlockBody(body)
fun visitSyntheticBody(body: IrSyntheticBody) = visitBody(body)
override fun visitSyntheticBody(body: IrSyntheticBody, data: Nothing?) = visitSyntheticBody(body)
fun visitExpression(expression: IrExpression) = visitElement(expression)
override fun visitExpression(expression: IrExpression, data: Nothing?) = visitExpression(expression)
fun <T> visitConst(expression: IrConst<T>) = visitExpression(expression)
override fun <T> visitConst(expression: IrConst<T>, data: Nothing?) = visitConst(expression)
fun visitVararg(expression: IrVararg) = visitExpression(expression)
override fun visitVararg(expression: IrVararg, data: Nothing?) = visitVararg(expression)
fun visitSpreadElement(spread: IrSpreadElement) = visitElement(spread)
override fun visitSpreadElement(spread: IrSpreadElement, data: Nothing?) = visitSpreadElement(spread)
fun visitBlock(expression: IrBlock) = visitExpression(expression)
override fun visitBlock(expression: IrBlock, data: Nothing?) = visitBlock(expression)
fun visitStringConcatenation(expression: IrStringConcatenation) = visitExpression(expression)
override fun visitStringConcatenation(expression: IrStringConcatenation, data: Nothing?) = visitStringConcatenation(expression)
fun visitThisReference(expression: IrThisReference) = visitExpression(expression)
override fun visitThisReference(expression: IrThisReference, data: Nothing?) = visitThisReference(expression)
fun visitDeclarationReference(expression: IrDeclarationReference) = visitExpression(expression)
override fun visitDeclarationReference(expression: IrDeclarationReference, data: Nothing?) = visitDeclarationReference(expression)
fun visitSingletonReference(expression: IrGetSingletonValue) = visitDeclarationReference(expression)
override fun visitSingletonReference(expression: IrGetSingletonValue, data: Nothing?) = visitSingletonReference(expression)
fun visitGetObjectValue(expression: IrGetObjectValue) = visitSingletonReference(expression)
override fun visitGetObjectValue(expression: IrGetObjectValue, data: Nothing?) = visitGetObjectValue(expression)
fun visitGetEnumValue(expression: IrGetEnumValue) = visitSingletonReference(expression)
override fun visitGetEnumValue(expression: IrGetEnumValue, data: Nothing?) = visitGetEnumValue(expression)
fun visitGetVariable(expression: IrGetVariable) = visitDeclarationReference(expression)
override fun visitGetVariable(expression: IrGetVariable, data: Nothing?) = visitGetVariable(expression)
fun visitSetVariable(expression: IrSetVariable) = visitDeclarationReference(expression)
override fun visitSetVariable(expression: IrSetVariable, data: Nothing?) = visitSetVariable(expression)
fun visitGetBackingField(expression: IrGetBackingField) = visitDeclarationReference(expression)
override fun visitGetBackingField(expression: IrGetBackingField, data: Nothing?) = visitGetBackingField(expression)
fun visitSetBackingField(expression: IrSetBackingField) = visitDeclarationReference(expression)
override fun visitSetBackingField(expression: IrSetBackingField, data: Nothing?) = visitSetBackingField(expression)
fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver) = visitDeclarationReference(expression)
override fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: Nothing?) = visitGetExtensionReceiver(expression)
fun visitGeneralCall(expression: IrGeneralCall) = visitDeclarationReference(expression)
override fun visitGeneralCall(expression: IrGeneralCall, data: Nothing?) = visitGeneralCall(expression)
fun visitCall(expression: IrCall) = visitGeneralCall(expression)
override fun visitCall(expression: IrCall, data: Nothing?) = visitCall(expression)
fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) = visitGeneralCall(expression)
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: Nothing?) = visitDelegatingConstructorCall(expression)
fun visitEnumConstructorCall(expression: IrEnumConstructorCall) = visitGeneralCall(expression)
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall, data: Nothing?) = visitEnumConstructorCall(expression)
fun visitGetClass(expression: IrGetClass) = visitExpression(expression)
override fun visitGetClass(expression: IrGetClass, data: Nothing?) = visitGetClass(expression)
fun visitCallableReference(expression: IrCallableReference) = visitGeneralCall(expression)
override fun visitCallableReference(expression: IrCallableReference, data: Nothing?) = visitCallableReference(expression)
fun visitClassReference(expression: IrClassReference) = visitDeclarationReference(expression)
override fun visitClassReference(expression: IrClassReference, data: Nothing?) = visitClassReference(expression)
fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall) = visitExpression(expression)
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: Nothing?) = visitInstanceInitializerCall(expression)
fun visitTypeOperator(expression: IrTypeOperatorCall) = visitExpression(expression)
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: Nothing?) = visitTypeOperator(expression)
fun visitWhen(expression: IrWhen) = visitExpression(expression)
override fun visitWhen(expression: IrWhen, data: Nothing?) = visitWhen(expression)
fun visitLoop(loop: IrLoop) = visitExpression(loop)
override fun visitLoop(loop: IrLoop, data: Nothing?) = visitLoop(loop)
fun visitWhileLoop(loop: IrWhileLoop) = visitLoop(loop)
override fun visitWhileLoop(loop: IrWhileLoop, data: Nothing?) = visitWhileLoop(loop)
fun visitDoWhileLoop(loop: IrDoWhileLoop) = visitLoop(loop)
override fun visitDoWhileLoop(loop: IrDoWhileLoop, data: Nothing?) = visitDoWhileLoop(loop)
fun visitTryCatch(tryCatch: IrTryCatch) = visitExpression(tryCatch)
override fun visitTryCatch(tryCatch: IrTryCatch, data: Nothing?) = visitTryCatch(tryCatch)
fun visitBreakContinue(jump: IrBreakContinue) = visitExpression(jump)
override fun visitBreakContinue(jump: IrBreakContinue, data: Nothing?) = visitBreakContinue(jump)
fun visitBreak(jump: IrBreak) = visitBreakContinue(jump)
override fun visitBreak(jump: IrBreak, data: Nothing?) = visitBreak(jump)
fun visitContinue(jump: IrContinue) = visitBreakContinue(jump)
override fun visitContinue(jump: IrContinue, data: Nothing?) = visitContinue(jump)
fun visitReturn(expression: IrReturn) = visitExpression(expression)
override fun visitReturn(expression: IrReturn, data: Nothing?) = visitReturn(expression)
fun visitThrow(expression: IrThrow) = visitExpression(expression)
override fun visitThrow(expression: IrThrow, data: Nothing?) = visitThrow(expression)
fun visitErrorDeclaration(declaration: IrErrorDeclaration) = visitDeclaration(declaration)
override fun visitErrorDeclaration(declaration: IrErrorDeclaration, data: Nothing?) = visitErrorDeclaration(declaration)
fun visitErrorExpression(expression: IrErrorExpression) = visitExpression(expression)
override fun visitErrorExpression(expression: IrErrorExpression, data: Nothing?) = visitErrorExpression(expression)
fun visitErrorCallExpression(expression: IrErrorCallExpression) = visitErrorExpression(expression)
override fun visitErrorCallExpression(expression: IrErrorCallExpression, data: Nothing?) = visitErrorCallExpression(expression)
}
fun IrElement.acceptVoid(visitor: IrElementVisitorVoid) {
accept(visitor, null)
}
fun IrElement.acceptChildrenVoid(visitor: IrElementVisitorVoid) {
acceptChildren(visitor, null)
}