Introduce IrFunctionExpression IR element
Use it to represent proper function expressions (lambdas and anonymous functions).
This commit is contained in:
+1
-1
@@ -42,7 +42,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
|
||||
constructor(context: GeneratorContext) : this(DeclarationGenerator(context))
|
||||
|
||||
fun generateFunctionDeclaration(ktFunction: KtNamedFunction): IrFunction =
|
||||
fun generateFunctionDeclaration(ktFunction: KtNamedFunction): IrSimpleFunction =
|
||||
declareSimpleFunction(
|
||||
ktFunction,
|
||||
ktFunction.receiverTypeReference,
|
||||
|
||||
+11
-36
@@ -17,55 +17,30 @@
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionExpressionImpl
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
class LocalFunctionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
|
||||
fun generateLambda(ktLambda: KtLambdaExpression): IrStatement {
|
||||
val ktFun = ktLambda.functionLiteral
|
||||
val lambdaExpressionType = getInferredTypeWithImplicitCastsOrFail(ktLambda).toIrType()
|
||||
val irLambdaFunction = FunctionGenerator(context).generateLambdaFunctionDeclaration(ktFun)
|
||||
|
||||
val irBlock = IrBlockImpl(ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, IrStatementOrigin.LAMBDA)
|
||||
irBlock.statements.add(irLambdaFunction)
|
||||
irBlock.statements.add(
|
||||
IrFunctionReferenceImpl(
|
||||
ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType,
|
||||
irLambdaFunction.symbol, irLambdaFunction.symbol.descriptor, 0,
|
||||
IrStatementOrigin.LAMBDA
|
||||
)
|
||||
)
|
||||
return irBlock
|
||||
return IrFunctionExpressionImpl(ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, irLambdaFunction)
|
||||
}
|
||||
|
||||
fun generateFunction(ktFun: KtNamedFunction): IrStatement =
|
||||
if (ktFun.name != null) {
|
||||
generateFunctionDeclaration(ktFun)
|
||||
} else {
|
||||
// anonymous function expression
|
||||
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun).toIrType()
|
||||
val irBlock = IrBlockImpl(ktFun.startOffsetSkippingComments, ktFun.endOffset, funExpressionType, IrStatementOrigin.ANONYMOUS_FUNCTION)
|
||||
fun generateFunction(ktFun: KtNamedFunction): IrStatement {
|
||||
val irFun = generateFunctionDeclaration(ktFun)
|
||||
if (ktFun.name != null) return irFun
|
||||
|
||||
val irFun = generateFunctionDeclaration(ktFun)
|
||||
irBlock.statements.add(irFun)
|
||||
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun).toIrType()
|
||||
return IrFunctionExpressionImpl(ktFun.startOffset, ktFun.endOffset, funExpressionType, irFun)
|
||||
}
|
||||
|
||||
irBlock.statements.add(
|
||||
IrFunctionReferenceImpl(
|
||||
ktFun.startOffsetSkippingComments, ktFun.endOffset, funExpressionType,
|
||||
irFun.symbol, irFun.symbol.descriptor, 0,
|
||||
IrStatementOrigin.ANONYMOUS_FUNCTION
|
||||
)
|
||||
)
|
||||
|
||||
irBlock
|
||||
}
|
||||
|
||||
private fun generateFunctionDeclaration(ktFun: KtNamedFunction): IrFunction =
|
||||
private fun generateFunctionDeclaration(ktFun: KtNamedFunction) =
|
||||
FunctionGenerator(context).generateFunctionDeclaration(ktFun)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
|
||||
interface IrFunctionExpression : IrExpression {
|
||||
|
||||
var function: IrSimpleFunction
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions.impl
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionExpression
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
class IrFunctionExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: IrType,
|
||||
override var function: IrSimpleFunction
|
||||
) :
|
||||
IrExpressionBase(startOffset, endOffset, type),
|
||||
IrFunctionExpression {
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitFunctionExpression(this, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
function.accept(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
function = function.transform(transformer, data) as IrSimpleFunction
|
||||
}
|
||||
}
|
||||
@@ -589,6 +589,13 @@ open class DeepCopyIrTreeWithSymbols(
|
||||
mapStatementOrigin(expression.origin)
|
||||
)
|
||||
|
||||
override fun visitFunctionExpression(expression: IrFunctionExpression): IrFunctionExpression =
|
||||
IrFunctionExpressionImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
expression.type.remapType(),
|
||||
expression.function.transform()
|
||||
)
|
||||
|
||||
override fun visitClassReference(expression: IrClassReference): IrClassReference =
|
||||
IrClassReferenceImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
|
||||
@@ -601,6 +601,11 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
append("origin=${expression.origin}")
|
||||
}
|
||||
|
||||
override fun visitFunctionExpression(expression: IrFunctionExpression, data: Nothing?): String =
|
||||
buildTrimEnd {
|
||||
append("FUN_EXPR type=${expression.type.render()}")
|
||||
}
|
||||
|
||||
override fun visitClassReference(expression: IrClassReference, data: Nothing?): String =
|
||||
"CLASS_REFERENCE '${expression.symbol.renderReference()}' type=${expression.type.render()}"
|
||||
|
||||
|
||||
@@ -98,6 +98,8 @@ interface IrElementTransformer<in D> : IrElementVisitor<IrElement, D> {
|
||||
override fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference, data: D) =
|
||||
visitCallableReference(expression, data)
|
||||
|
||||
override fun visitFunctionExpression(expression: IrFunctionExpression, data: D): IrElement = visitExpression(expression, data)
|
||||
|
||||
override fun visitClassReference(expression: IrClassReference, data: D) = visitDeclarationReference(expression, data)
|
||||
|
||||
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: D) = visitExpression(expression, data)
|
||||
|
||||
@@ -194,6 +194,10 @@ abstract class IrElementTransformerVoid : IrElementTransformer<Nothing?> {
|
||||
final override fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference, data: Nothing?) =
|
||||
visitLocalDelegatedPropertyReference(expression)
|
||||
|
||||
open fun visitFunctionExpression(expression: IrFunctionExpression) = visitExpression(expression)
|
||||
final override fun visitFunctionExpression(expression: IrFunctionExpression, data: Nothing?): IrElement =
|
||||
visitFunctionExpression(expression)
|
||||
|
||||
open fun visitClassReference(expression: IrClassReference) = visitDeclarationReference(expression)
|
||||
final override fun visitClassReference(expression: IrClassReference, data: Nothing?) = visitClassReference(expression)
|
||||
|
||||
|
||||
@@ -84,6 +84,8 @@ interface IrElementVisitor<out R, in D> {
|
||||
fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference, data: D) =
|
||||
visitCallableReference(expression, data)
|
||||
|
||||
fun visitFunctionExpression(expression: IrFunctionExpression, data: D) = visitExpression(expression, data)
|
||||
|
||||
fun visitClassReference(expression: IrClassReference, data: D) = visitDeclarationReference(expression, data)
|
||||
|
||||
fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: D) = visitExpression(expression, data)
|
||||
|
||||
@@ -184,6 +184,9 @@ interface IrElementVisitorVoid : IrElementVisitor<Unit, Nothing?> {
|
||||
override fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference, data: Nothing?) =
|
||||
visitLocalDelegatedPropertyReference(expression)
|
||||
|
||||
fun visitFunctionExpression(expression: IrFunctionExpression) = visitExpression(expression)
|
||||
override fun visitFunctionExpression(expression: IrFunctionExpression, data: Nothing?) = visitFunctionExpression(expression)
|
||||
|
||||
fun visitClassReference(expression: IrClassReference) = visitDeclarationReference(expression)
|
||||
override fun visitClassReference(expression: IrClassReference, data: Nothing?) = visitClassReference(expression)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user