Handle empty lambdas properly.
This commit is contained in:
committed by
Dmitry Petrov
parent
539d7ccf6f
commit
a4b9f6b215
@@ -70,11 +70,17 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
|
||||
val ktBody = ktFun.bodyExpression!!
|
||||
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
|
||||
if (ktBody is KtBlockExpression) {
|
||||
for (ktStatement in ktBody.statements.subList(0, ktBody.statements.size - 1)) {
|
||||
irBlockBody.addStatement(statementGenerator.generateStatement(ktStatement))
|
||||
val ktBodyStatements = ktBody.statements
|
||||
if (ktBodyStatements.isNotEmpty()) {
|
||||
for (ktStatement in ktBodyStatements.dropLast(1)) {
|
||||
irBlockBody.addStatement(statementGenerator.generateStatement(ktStatement))
|
||||
}
|
||||
val ktReturnedValue = ktBodyStatements.last()
|
||||
statementGenerator.generateReturnExpression(ktReturnedValue, irBlockBody)
|
||||
}
|
||||
else {
|
||||
irBlockBody.addStatement(generateReturnExpression(ktBody.startOffset, ktBody.endOffset, null))
|
||||
}
|
||||
val ktReturnedValue = ktBody.statements.last()
|
||||
statementGenerator.generateReturnExpression(ktReturnedValue, irBlockBody)
|
||||
}
|
||||
|
||||
return irBlockBody
|
||||
@@ -100,12 +106,15 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
|
||||
if (KotlinBuiltIns.isNothing(type))
|
||||
this
|
||||
else {
|
||||
val returnTarget = (scopeOwner as? CallableDescriptor) ?:
|
||||
throw AssertionError("'return' in a non-callable: $scopeOwner")
|
||||
IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType,
|
||||
returnTarget, this)
|
||||
generateReturnExpression(startOffset, endOffset, this)
|
||||
}
|
||||
|
||||
private fun generateReturnExpression(startOffset: Int, endOffset: Int, returnValue: IrExpression?): IrReturnImpl {
|
||||
val returnTarget = (scopeOwner as? CallableDescriptor) ?:
|
||||
throw AssertionError("'return' in a non-callable: $scopeOwner")
|
||||
return IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, returnTarget, returnValue)
|
||||
}
|
||||
|
||||
|
||||
fun generateSecondaryConstructorBody(ktConstructor: KtSecondaryConstructor): IrBody {
|
||||
val irBlockBody = IrBlockBodyImpl(ktConstructor.startOffset, ktConstructor.endOffset)
|
||||
|
||||
+10
-7
@@ -27,17 +27,20 @@ import org.jetbrains.kotlin.types.ErrorUtils
|
||||
class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
private val ignoreErrors: Boolean get() = context.configuration.ignoreErrors
|
||||
|
||||
private inline fun generateErrorExpression(message: String? = null, body: () -> IrExpression) =
|
||||
if (ignoreErrors) body() else throw RuntimeException(message)
|
||||
private inline fun generateErrorExpression(ktElement: KtElement, e: Exception? = null, body: () -> IrExpression) =
|
||||
if (ignoreErrors)
|
||||
body()
|
||||
else
|
||||
throw RuntimeException("${e?.message}: ${ktElement.javaClass.simpleName}:\n${ktElement.text}", e)
|
||||
|
||||
fun generateErrorExpression(ktElement: KtElement, message: String?): IrExpression =
|
||||
generateErrorExpression {
|
||||
fun generateErrorExpression(ktElement: KtElement, e: Exception): IrExpression =
|
||||
generateErrorExpression(ktElement, e) {
|
||||
IrErrorExpressionImpl(ktElement.startOffset, ktElement.endOffset,
|
||||
if (ktElement is KtExpression) getErrorExpressionType(ktElement) else ErrorUtils.createErrorType(""),
|
||||
message ?: "")
|
||||
e.message ?: "")
|
||||
}
|
||||
|
||||
fun generateErrorCall(ktCall: KtCallExpression): IrExpression = generateErrorExpression {
|
||||
fun generateErrorCall(ktCall: KtCallExpression): IrExpression = generateErrorExpression(ktCall) {
|
||||
val type = getErrorExpressionType(ktCall)
|
||||
|
||||
val irErrorCall = IrErrorCallExpressionImpl(ktCall.startOffset, ktCall.endOffset, type, "") // TODO problem description?
|
||||
@@ -62,7 +65,7 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
|
||||
private fun getErrorExpressionType(ktExpression: KtExpression) =
|
||||
getInferredTypeWithImplicitCasts(ktExpression) ?: ErrorUtils.createErrorType("")
|
||||
|
||||
fun generateErrorSimpleName(ktName: KtSimpleNameExpression): IrExpression = generateErrorExpression {
|
||||
fun generateErrorSimpleName(ktName: KtSimpleNameExpression): IrExpression = generateErrorExpression(ktName) {
|
||||
val type = getErrorExpressionType(ktName)
|
||||
|
||||
val irErrorCall = IrErrorCallExpressionImpl(ktName.startOffset, ktName.endOffset, type, "") // TODO problem description?
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ class StatementGenerator(
|
||||
deparenthesize().accept(this@StatementGenerator, null)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(this, e.message)
|
||||
ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(this, e)
|
||||
}
|
||||
|
||||
private fun KtElement.genExpr(): IrExpression =
|
||||
|
||||
+3
-1
@@ -1 +1,3 @@
|
||||
val lambda = { 42 }
|
||||
val test1 = { 42 }
|
||||
|
||||
val test2 = { }
|
||||
+8
-1
@@ -1,5 +1,5 @@
|
||||
FILE /justLambda.kt
|
||||
PROPERTY public val lambda: () -> kotlin.Int
|
||||
PROPERTY public val test1: () -> kotlin.Int
|
||||
EXPRESSION_BODY
|
||||
BLOCK type=() -> kotlin.Int operator=LAMBDA
|
||||
FUN local final fun <anonymous>(): kotlin.Int
|
||||
@@ -7,3 +7,10 @@ FILE /justLambda.kt
|
||||
RETURN type=kotlin.Nothing from=<anonymous>
|
||||
CONST Int type=kotlin.Int value='42'
|
||||
CALLABLE_REFERENCE <anonymous> type=() -> kotlin.Int operator=LAMBDA
|
||||
PROPERTY public val test2: () -> kotlin.Unit
|
||||
EXPRESSION_BODY
|
||||
BLOCK type=() -> kotlin.Unit operator=LAMBDA
|
||||
FUN local final fun <anonymous>(): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=<anonymous>
|
||||
CALLABLE_REFERENCE <anonymous> type=() -> kotlin.Unit operator=LAMBDA
|
||||
|
||||
Reference in New Issue
Block a user