- function with expression bodies are desugared to blocks with return statement;
- property initializers are generated as regular expression bodies.
This commit is contained in:
Dmitry Petrov
2016-08-15 13:32:48 +03:00
committed by Dmitry Petrov
parent 2707d33ca7
commit aa7bf4637b
9 changed files with 112 additions and 47 deletions
@@ -20,11 +20,9 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
import org.jetbrains.kotlin.ir.assertCast
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrExpressionBodyImpl
import org.jetbrains.kotlin.ir.expressions.IrReturnExpressionImpl
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDummyDeclaration
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
@@ -64,25 +62,25 @@ abstract class IrDeclarationGeneratorBase(
fun generateFunctionDeclaration(ktNamedFunction: KtNamedFunction) {
val functionDescriptor = getOrFail(BindingContext.FUNCTION, ktNamedFunction)
val body = generateExpressionBody(functionDescriptor, ktNamedFunction.bodyExpression ?: TODO("function without body expression"))
val body = generateFunctionBody(functionDescriptor, ktNamedFunction.bodyExpression ?: TODO("function without body expression"))
declarationFactory.createFunction(ktNamedFunction, functionDescriptor, body).register()
}
fun generatePropertyDeclaration(ktProperty: KtProperty) {
val propertyDescriptor = getPropertyDescriptor(ktProperty)
if (ktProperty.hasDelegate()) TODO("handle delegated property")
val initializer = ktProperty.initializer?.let { generateExpressionBody(propertyDescriptor, it) }
val initializer = ktProperty.initializer?.let { generateInitializerBody(propertyDescriptor, it) }
val irProperty = declarationFactory.createSimpleProperty(ktProperty, propertyDescriptor, initializer).register()
ktProperty.getter?.let { ktGetter ->
val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktGetter)
val getterDescriptor = accessorDescriptor as? PropertyGetterDescriptor ?: TODO("not a getter?")
val getterBody = generateExpressionBody(getterDescriptor, ktGetter.bodyExpression ?: TODO("default getter"))
val getterBody = generateFunctionBody(getterDescriptor, ktGetter.bodyExpression ?: TODO("default getter"))
declarationFactory.createPropertyGetter(ktGetter, irProperty, getterDescriptor, getterBody).register()
}
ktProperty.setter?.let { ktSetter ->
val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktSetter)
val setterDescriptor = accessorDescriptor as? PropertySetterDescriptor ?: TODO("not a setter?")
val setterBody = generateExpressionBody(setterDescriptor, ktSetter.bodyExpression ?: TODO("default setter"))
val setterBody = generateFunctionBody(setterDescriptor, ktSetter.bodyExpression ?: TODO("default setter"))
declarationFactory.createPropertySetter(ktSetter, irProperty, setterDescriptor, setterBody).register()
}
}
@@ -93,8 +91,22 @@ abstract class IrDeclarationGeneratorBase(
return propertyDescriptor
}
fun generateExpressionBody(scopeOwner: DeclarationDescriptor, ktBody: KtExpression): IrBody =
IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset).apply {
expression = IrStatementGenerator(context, IrLocalDeclarationsFactory(scopeOwner)).generateStatement(ktBody).assertCast()
}
private fun generateExpressionWithinContext(ktExpression: KtExpression, scopeOwner: DeclarationDescriptor): IrExpression =
IrStatementGenerator(context, IrLocalDeclarationsFactory(scopeOwner)).generateExpression(ktExpression)
private fun generateFunctionBody(scopeOwner: DeclarationDescriptor, ktBody: KtExpression): IrBody {
val irRhs = generateExpressionWithinContext(ktBody, scopeOwner)
val irExpressionBody =
if (ktBody is KtBlockExpression)
irRhs
else
IrBlockExpressionImpl(ktBody.startOffset, ktBody.endOffset, null, hasResult = false, isDesugared = true).apply {
addStatement(IrReturnExpressionImpl(ktBody.startOffset, ktBody.endOffset, null, irRhs))
}
return IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset, irExpressionBody)
}
private fun generateInitializerBody(scopeOwner: DeclarationDescriptor, ktBody: KtExpression): IrBody =
IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset,
generateExpressionWithinContext(ktBody, scopeOwner))
}