Secondary constructors in classes.
This commit is contained in:
committed by
Dmitry Petrov
parent
ac80195597
commit
225d792939
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.psi2ir.generators
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
|
||||||
import org.jetbrains.kotlin.psi.KtLoopExpression
|
|
||||||
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 java.util.*
|
import java.util.*
|
||||||
@@ -36,38 +33,19 @@ class BodyGenerator(val scopeOwner: CallableDescriptor, override val context: Ge
|
|||||||
|
|
||||||
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
|
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
|
||||||
if (ktBody is KtBlockExpression) {
|
if (ktBody is KtBlockExpression) {
|
||||||
for (ktStatement in ktBody.statements) {
|
statementGenerator.generateBlockBodyStatements(irBlockBody, ktBody)
|
||||||
irBlockBody.addStatement(statementGenerator.generateStatement(ktStatement))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val irBodyExpression = statementGenerator.generateExpression(ktBody)
|
statementGenerator.generateReturnExpression(ktBody, irBlockBody)
|
||||||
irBlockBody.addStatement(irBodyExpression.wrapWithReturn())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return irBlockBody
|
return irBlockBody
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrExpression.wrapWithReturn() =
|
|
||||||
if (KotlinBuiltIns.isNothing(type))
|
|
||||||
this
|
|
||||||
else
|
|
||||||
IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, scopeOwner, this)
|
|
||||||
|
|
||||||
fun generatePropertyInitializerBody(ktInitializer: KtExpression): IrBody =
|
fun generatePropertyInitializerBody(ktInitializer: KtExpression): IrBody =
|
||||||
IrExpressionBodyImpl(ktInitializer.startOffset, ktInitializer.endOffset,
|
IrExpressionBodyImpl(ktInitializer.startOffset, ktInitializer.endOffset,
|
||||||
createStatementGenerator().generateExpression(ktInitializer))
|
createStatementGenerator().generateExpression(ktInitializer))
|
||||||
|
|
||||||
private fun createStatementGenerator() =
|
|
||||||
StatementGenerator(context, scopeOwner, this, scope)
|
|
||||||
|
|
||||||
fun putLoop(expression: KtLoopExpression, irLoop: IrLoop) {
|
|
||||||
loopTable[expression] = irLoop
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLoop(expression: KtExpression): IrLoop? =
|
|
||||||
loopTable[expression]
|
|
||||||
|
|
||||||
fun generateLambdaBody(ktFun: KtFunctionLiteral): IrBody {
|
fun generateLambdaBody(ktFun: KtFunctionLiteral): IrBody {
|
||||||
val statementGenerator = createStatementGenerator()
|
val statementGenerator = createStatementGenerator()
|
||||||
|
|
||||||
@@ -78,13 +56,57 @@ class BodyGenerator(val scopeOwner: CallableDescriptor, override val context: Ge
|
|||||||
irBlockBody.addStatement(statementGenerator.generateStatement(ktStatement))
|
irBlockBody.addStatement(statementGenerator.generateStatement(ktStatement))
|
||||||
}
|
}
|
||||||
val ktReturnedValue = ktBody.statements.last()
|
val ktReturnedValue = ktBody.statements.last()
|
||||||
irBlockBody.addStatement(statementGenerator.generateExpression(ktReturnedValue).wrapWithReturn())
|
statementGenerator.generateReturnExpression(ktReturnedValue, irBlockBody)
|
||||||
}
|
|
||||||
else {
|
|
||||||
irBlockBody.addStatement(statementGenerator.generateExpression(ktBody).wrapWithReturn())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return irBlockBody
|
return irBlockBody
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun StatementGenerator.generateBlockBodyStatements(irBlockBody: IrBlockBodyImpl, ktBody: KtBlockExpression) {
|
||||||
|
for (ktStatement in ktBody.statements) {
|
||||||
|
irBlockBody.addStatement(generateStatement(ktStatement))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun StatementGenerator.generateReturnExpression(ktExpression: KtExpression, irBlockBody: IrBlockBodyImpl) {
|
||||||
|
val irExpression = generateExpression(ktExpression)
|
||||||
|
irBlockBody.addStatement(irExpression.wrapWithReturn())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrExpression.wrapWithReturn() =
|
||||||
|
if (KotlinBuiltIns.isNothing(type))
|
||||||
|
this
|
||||||
|
else
|
||||||
|
IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, scopeOwner, this)
|
||||||
|
|
||||||
|
|
||||||
|
fun generateSecondaryConstructorBody(ktConstructor: KtSecondaryConstructor): IrBody {
|
||||||
|
val statementGenerator = createStatementGenerator()
|
||||||
|
|
||||||
|
val irBlockBody = IrBlockBodyImpl(ktConstructor.startOffset, ktConstructor.endOffset)
|
||||||
|
|
||||||
|
val ktDelegatingConstructorCall = ktConstructor.getDelegationCall()
|
||||||
|
val delegatingConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktDelegatingConstructorCall)!!)
|
||||||
|
val irDelegatingConstructorCall = CallGenerator(statementGenerator).generateCall(
|
||||||
|
ktDelegatingConstructorCall, delegatingConstructorCall, IrOperator.DELEGATING_CONSTRUCTOR_CALL)
|
||||||
|
irBlockBody.addStatement(irDelegatingConstructorCall)
|
||||||
|
|
||||||
|
val ktBody = ktConstructor.bodyExpression
|
||||||
|
if (ktBody != null) {
|
||||||
|
statementGenerator.generateBlockBodyStatements(irBlockBody, ktBody)
|
||||||
|
}
|
||||||
|
|
||||||
|
return irBlockBody
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createStatementGenerator() =
|
||||||
|
StatementGenerator(context, scopeOwner, this, scope)
|
||||||
|
|
||||||
|
fun putLoop(expression: KtLoopExpression, irLoop: IrLoop) {
|
||||||
|
loopTable[expression] = irLoop
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLoop(expression: KtExpression): IrLoop? =
|
||||||
|
loopTable[expression]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -31,7 +31,7 @@ class BranchingExpressionGenerator(val statementGenerator: StatementGenerator) :
|
|||||||
override val context: GeneratorContext get() = statementGenerator.context
|
override val context: GeneratorContext get() = statementGenerator.context
|
||||||
|
|
||||||
fun generateIfExpression(expression: KtIfExpression): IrExpression {
|
fun generateIfExpression(expression: KtIfExpression): IrExpression {
|
||||||
val resultType = getInferredTypeWithSmartcastsOrFail(expression)
|
val resultType = getInferredTypeWithImplicitCastsOrFail(expression)
|
||||||
|
|
||||||
var ktLastIf: KtIfExpression = expression
|
var ktLastIf: KtIfExpression = expression
|
||||||
val irBranches = SmartList<Pair<IrExpression, IrExpression>>()
|
val irBranches = SmartList<Pair<IrExpression, IrExpression>>()
|
||||||
@@ -74,7 +74,7 @@ class BranchingExpressionGenerator(val statementGenerator: StatementGenerator) :
|
|||||||
scope.createTemporaryVariable(statementGenerator.generateExpression(it), "subject")
|
scope.createTemporaryVariable(statementGenerator.generateExpression(it), "subject")
|
||||||
}
|
}
|
||||||
|
|
||||||
val resultType = getInferredTypeWithSmartcastsOrFail(expression)
|
val resultType = getInferredTypeWithImplicitCastsOrFail(expression)
|
||||||
|
|
||||||
val irWhen = IrWhenImpl(expression.startOffset, expression.endOffset, resultType, IrOperator.WHEN)
|
val irWhen = IrWhenImpl(expression.startOffset, expression.endOffset, resultType, IrOperator.WHEN)
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
|||||||
val irClass = IrClassImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset, IrDeclarationOrigin.DEFINED, descriptor)
|
val irClass = IrClassImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset, IrDeclarationOrigin.DEFINED, descriptor)
|
||||||
|
|
||||||
generatePropertiesDeclaredInPrimaryConstructor(irClass, ktClassOrObject)
|
generatePropertiesDeclaredInPrimaryConstructor(irClass, ktClassOrObject)
|
||||||
generateMembersDeclaredInClassbody(irClass, ktClassOrObject)
|
generateMembersDeclaredInClassBody(irClass, ktClassOrObject)
|
||||||
|
|
||||||
return irClass
|
return irClass
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateMembersDeclaredInClassbody(irClass: IrClassImpl, ktClassOrObject: KtClassOrObject) {
|
private fun generateMembersDeclaredInClassBody(irClass: IrClassImpl, ktClassOrObject: KtClassOrObject) {
|
||||||
ktClassOrObject.getBody()?.let { ktClassBody ->
|
ktClassOrObject.getBody()?.let { ktClassBody ->
|
||||||
for (ktDeclaration in ktClassBody.declarations) {
|
for (ktDeclaration in ktClassBody.declarations) {
|
||||||
val irMember = declarationGenerator.generateMemberDeclaration(ktDeclaration)
|
val irMember = declarationGenerator.generateMemberDeclaration(ktDeclaration)
|
||||||
|
|||||||
+9
@@ -29,6 +29,8 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
|||||||
when (ktDeclaration) {
|
when (ktDeclaration) {
|
||||||
is KtNamedFunction ->
|
is KtNamedFunction ->
|
||||||
generateFunctionDeclaration(ktDeclaration)
|
generateFunctionDeclaration(ktDeclaration)
|
||||||
|
is KtSecondaryConstructor ->
|
||||||
|
generateSecondaryConstructor(ktDeclaration)
|
||||||
is KtProperty ->
|
is KtProperty ->
|
||||||
generatePropertyDeclaration(ktDeclaration)
|
generatePropertyDeclaration(ktDeclaration)
|
||||||
is KtClassOrObject ->
|
is KtClassOrObject ->
|
||||||
@@ -56,6 +58,13 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
|||||||
functionDescriptor, body)
|
functionDescriptor, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun generateSecondaryConstructor(ktConstructor: KtSecondaryConstructor) : IrFunction {
|
||||||
|
val constructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor)
|
||||||
|
val body = BodyGenerator(constructorDescriptor, context).generateSecondaryConstructorBody(ktConstructor)
|
||||||
|
return IrFunctionImpl(ktConstructor.startOffset, ktConstructor.endOffset, IrDeclarationOrigin.DEFINED,
|
||||||
|
constructorDescriptor, body)
|
||||||
|
}
|
||||||
|
|
||||||
fun generatePropertyDeclaration(ktProperty: KtProperty): IrProperty {
|
fun generatePropertyDeclaration(ktProperty: KtProperty): IrProperty {
|
||||||
val propertyDescriptor = getPropertyDescriptor(ktProperty)
|
val propertyDescriptor = getPropertyDescriptor(ktProperty)
|
||||||
if (ktProperty.hasDelegate()) TODO("handle delegated property")
|
if (ktProperty.hasDelegate()) TODO("handle delegated property")
|
||||||
|
|||||||
@@ -19,10 +19,7 @@ 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
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrDummyExpression
|
import org.jetbrains.kotlin.ir.expressions.IrDummyExpression
|
||||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtConstantExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
|
|
||||||
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.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
@@ -54,50 +51,14 @@ fun <K, V : Any> Generator.getOrFail(slice: ReadOnlySlice<K, V>, key: K): V =
|
|||||||
inline fun <K, V : Any> Generator.getOrFail(slice: ReadOnlySlice<K, V>, key: K, message: (K) -> String): V =
|
inline fun <K, V : Any> Generator.getOrFail(slice: ReadOnlySlice<K, V>, key: K, message: (K) -> String): V =
|
||||||
context.bindingContext[slice, key] ?: throw RuntimeException(message(key))
|
context.bindingContext[slice, key] ?: throw RuntimeException(message(key))
|
||||||
|
|
||||||
fun Generator.getInferredTypeWithSmartcasts(key: KtExpression): KotlinType? =
|
fun Generator.getInferredTypeWithImplicitCasts(key: KtExpression): KotlinType? =
|
||||||
context.bindingContext.getType(key)
|
context.bindingContext.getType(key)
|
||||||
|
|
||||||
fun Generator.getInferredTypeWithSmartcastsOrFail(key: KtExpression): KotlinType =
|
fun Generator.getInferredTypeWithImplicitCastsOrFail(key: KtExpression): KotlinType =
|
||||||
getInferredTypeWithSmartcasts(key) ?: throw AssertionError("No type for expression: ${key.text}")
|
getInferredTypeWithImplicitCasts(key) ?: throw AssertionError("No type for expression: ${key.text}")
|
||||||
|
|
||||||
fun Generator.getResolvedCall(key: KtExpression): ResolvedCall<out CallableDescriptor>? =
|
fun Generator.getResolvedCall(key: KtElement): ResolvedCall<out CallableDescriptor>? =
|
||||||
key.getResolvedCall(context.bindingContext)
|
key.getResolvedCall(context.bindingContext)
|
||||||
|
|
||||||
fun Generator.getReturnType(key: KtExpression): KotlinType? {
|
|
||||||
val resolvedCall = getResolvedCall(key)
|
|
||||||
if (resolvedCall != null) {
|
|
||||||
return getReturnType(resolvedCall)
|
|
||||||
}
|
|
||||||
|
|
||||||
return when (key) {
|
|
||||||
is KtBlockExpression ->
|
|
||||||
getReturnType(key.statements.last())
|
|
||||||
is KtConstantExpression ->
|
|
||||||
getInferredTypeWithSmartcasts(key)
|
|
||||||
is KtStringTemplateExpression ->
|
|
||||||
context.builtIns.stringType
|
|
||||||
else ->
|
|
||||||
throw AssertionError("Unexpected expression: $key")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getReturnType(resolvedCall: ResolvedCall<*>): KotlinType {
|
|
||||||
val returnType = getReturnType(resolvedCall.resultingDescriptor)
|
|
||||||
return if (resolvedCall.call.isSafeCall()) returnType.makeNullable() else returnType
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getReturnType(descriptor: CallableDescriptor): KotlinType {
|
|
||||||
return when (descriptor) {
|
|
||||||
is ClassDescriptor ->
|
|
||||||
descriptor.classValueType ?: throw AssertionError("Class descriptor without companion object: $descriptor")
|
|
||||||
is CallableDescriptor -> {
|
|
||||||
descriptor.returnType ?: throw AssertionError("Callable descriptor without return type: $descriptor")
|
|
||||||
}
|
|
||||||
else ->
|
|
||||||
throw AssertionError("Unexpected descriptor in resolved call: $descriptor")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Generator.createDummyExpression(ktExpression: KtExpression, description: String): IrDummyExpression =
|
fun Generator.createDummyExpression(ktExpression: KtExpression, description: String): IrDummyExpression =
|
||||||
IrDummyExpression(ktExpression.startOffset, ktExpression.endOffset, getInferredTypeWithSmartcastsOrFail(ktExpression), description)
|
IrDummyExpression(ktExpression.startOffset, ktExpression.endOffset, getInferredTypeWithImplicitCastsOrFail(ktExpression), description)
|
||||||
+2
-2
@@ -35,7 +35,7 @@ class LocalFunctionGenerator(val statementGenerator: StatementGenerator) : Gener
|
|||||||
|
|
||||||
fun generateLambda(ktLambda: KtLambdaExpression): IrStatement {
|
fun generateLambda(ktLambda: KtLambdaExpression): IrStatement {
|
||||||
val ktFun = ktLambda.functionLiteral
|
val ktFun = ktLambda.functionLiteral
|
||||||
val lambdaExpressionType = getInferredTypeWithSmartcastsOrFail(ktLambda)
|
val lambdaExpressionType = getInferredTypeWithImplicitCastsOrFail(ktLambda)
|
||||||
val lambdaDescriptor = getOrFail(BindingContext.FUNCTION, ktFun)
|
val lambdaDescriptor = getOrFail(BindingContext.FUNCTION, ktFun)
|
||||||
val irBlock = IrBlockImpl(ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, IrOperator.LAMBDA)
|
val irBlock = IrBlockImpl(ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, IrOperator.LAMBDA)
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ class LocalFunctionGenerator(val statementGenerator: StatementGenerator) : Gener
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// anonymous function expression
|
// anonymous function expression
|
||||||
val funExpressionType = getInferredTypeWithSmartcastsOrFail(ktFun)
|
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun)
|
||||||
val irBlock = IrBlockImpl(ktFun.startOffset, ktFun.endOffset, funExpressionType, IrOperator.ANONYMOUS_FUNCTION)
|
val irBlock = IrBlockImpl(ktFun.startOffset, ktFun.endOffset, funExpressionType, IrOperator.ANONYMOUS_FUNCTION)
|
||||||
|
|
||||||
val irFun = generateFunctionDeclaration(ktFun)
|
val irFun = generateFunctionDeclaration(ktFun)
|
||||||
|
|||||||
+5
-5
@@ -109,7 +109,7 @@ class StatementGenerator(
|
|||||||
val isBlockBody = expression.parent is KtDeclarationWithBody && expression.parent !is KtFunctionLiteral
|
val isBlockBody = expression.parent is KtDeclarationWithBody && expression.parent !is KtFunctionLiteral
|
||||||
if (isBlockBody) throw AssertionError("Use IrBlockBody and corresponding body generator to generate blocks as function bodies")
|
if (isBlockBody) throw AssertionError("Use IrBlockBody and corresponding body generator to generate blocks as function bodies")
|
||||||
|
|
||||||
val returnType = getInferredTypeWithSmartcasts(expression) ?: context.builtIns.unitType
|
val returnType = getInferredTypeWithImplicitCasts(expression) ?: context.builtIns.unitType
|
||||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, returnType)
|
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, returnType)
|
||||||
|
|
||||||
expression.statements.forEach {
|
expression.statements.forEach {
|
||||||
@@ -151,7 +151,7 @@ class StatementGenerator(
|
|||||||
override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression {
|
override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression {
|
||||||
val compileTimeConstant = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext)
|
val compileTimeConstant = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext)
|
||||||
?: error("KtConstantExpression was not evaluated: ${expression.text}")
|
?: error("KtConstantExpression was not evaluated: ${expression.text}")
|
||||||
val constantValue = compileTimeConstant.toConstantValue(getInferredTypeWithSmartcastsOrFail(expression))
|
val constantValue = compileTimeConstant.toConstantValue(getInferredTypeWithImplicitCastsOrFail(expression))
|
||||||
val constantType = constantValue.type
|
val constantType = constantValue.type
|
||||||
|
|
||||||
return when (constantValue) {
|
return when (constantValue) {
|
||||||
@@ -179,12 +179,12 @@ class StatementGenerator(
|
|||||||
}
|
}
|
||||||
entries.size == 0 -> {
|
entries.size == 0 -> {
|
||||||
return IrConstImpl.string(expression.startOffset, expression.endOffset,
|
return IrConstImpl.string(expression.startOffset, expression.endOffset,
|
||||||
getInferredTypeWithSmartcastsOrFail(expression), "")
|
getInferredTypeWithImplicitCastsOrFail(expression), "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val irStringTemplate = IrStringConcatenationImpl(expression.startOffset, expression.endOffset,
|
val irStringTemplate = IrStringConcatenationImpl(expression.startOffset, expression.endOffset,
|
||||||
getInferredTypeWithSmartcastsOrFail(expression))
|
getInferredTypeWithImplicitCastsOrFail(expression))
|
||||||
entries.forEach { it.expression!!.let { irStringTemplate.addArgument(it.genExpr()) } }
|
entries.forEach { it.expression!!.let { irStringTemplate.addArgument(it.genExpr()) } }
|
||||||
return irStringTemplate
|
return irStringTemplate
|
||||||
}
|
}
|
||||||
@@ -229,7 +229,7 @@ class StatementGenerator(
|
|||||||
IrGetVariableImpl(expression.startOffset, expression.endOffset, descriptor)
|
IrGetVariableImpl(expression.startOffset, expression.endOffset, descriptor)
|
||||||
else ->
|
else ->
|
||||||
IrDummyExpression(
|
IrDummyExpression(
|
||||||
expression.startOffset, expression.endOffset, getInferredTypeWithSmartcastsOrFail(expression),
|
expression.startOffset, expression.endOffset, getInferredTypeWithImplicitCastsOrFail(expression),
|
||||||
expression.text + ": ${descriptor.name} ${descriptor.javaClass.simpleName}"
|
expression.text + ": ${descriptor.name} ${descriptor.javaClass.simpleName}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ class TryCatchExpressionGenerator(val statementGenerator: StatementGenerator) :
|
|||||||
override val context: GeneratorContext get() = statementGenerator.context
|
override val context: GeneratorContext get() = statementGenerator.context
|
||||||
|
|
||||||
fun generateTryCatch(ktTry: KtTryExpression): IrExpression {
|
fun generateTryCatch(ktTry: KtTryExpression): IrExpression {
|
||||||
val resultType = getInferredTypeWithSmartcastsOrFail(ktTry)
|
val resultType = getInferredTypeWithImplicitCastsOrFail(ktTry)
|
||||||
val irTryCatch = IrTryCatchImpl(ktTry.startOffset, ktTry.endOffset, resultType)
|
val irTryCatch = IrTryCatchImpl(ktTry.startOffset, ktTry.endOffset, resultType)
|
||||||
|
|
||||||
irTryCatch.tryResult = statementGenerator.generateExpression(ktTry.tryBlock)
|
irTryCatch.tryResult = statementGenerator.generateExpression(ktTry.tryBlock)
|
||||||
|
|||||||
@@ -88,6 +88,8 @@ interface IrOperator {
|
|||||||
object LAMBDA : IrOperatorImpl("LAMBDA")
|
object LAMBDA : IrOperatorImpl("LAMBDA")
|
||||||
object ANONYMOUS_FUNCTION : IrOperatorImpl("ANONYMOUS_FUNCTION")
|
object ANONYMOUS_FUNCTION : IrOperatorImpl("ANONYMOUS_FUNCTION")
|
||||||
|
|
||||||
|
object DELEGATING_CONSTRUCTOR_CALL : IrOperatorImpl("DELEGATING_CONSTRUCTOR_CALL")
|
||||||
|
|
||||||
data class COMPONENT_N private constructor(val index: Int) : IrOperatorImpl("COMPONENT_$index") {
|
data class COMPONENT_N private constructor(val index: Int) : IrOperatorImpl("COMPONENT_$index") {
|
||||||
companion object {
|
companion object {
|
||||||
private val precreatedComponents = Array(32) { i -> COMPONENT_N(i + 1) }
|
private val precreatedComponents = Array(32) { i -> COMPONENT_N(i + 1) }
|
||||||
|
|||||||
+6
-1
@@ -2,7 +2,12 @@ FILE /classMembers.kt
|
|||||||
CLASS CLASS C
|
CLASS CLASS C
|
||||||
PROPERTY public final val y: kotlin.Int getter=null setter=null
|
PROPERTY public final val y: kotlin.Int getter=null setter=null
|
||||||
PROPERTY public final var z: kotlin.Int getter=null setter=null
|
PROPERTY public final var z: kotlin.Int getter=null setter=null
|
||||||
DUMMY ConstructorDescriptorImpl <init>
|
FUN public constructor C()
|
||||||
|
BLOCK_BODY
|
||||||
|
CALL .<init> type=C operator=DELEGATING_CONSTRUCTOR_CALL
|
||||||
|
x: CONST Int type=kotlin.Int value='0'
|
||||||
|
y: CONST Int type=kotlin.Int value='0'
|
||||||
|
z: CONST Int type=kotlin.Int value='0'
|
||||||
PROPERTY public final val property: kotlin.Int = 0 getter=null setter=null
|
PROPERTY public final val property: kotlin.Int = 0 getter=null setter=null
|
||||||
EXPRESSION_BODY
|
EXPRESSION_BODY
|
||||||
CONST Int type=kotlin.Int value='0'
|
CONST Int type=kotlin.Int value='0'
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
class C {
|
||||||
|
constructor() : this(0) {}
|
||||||
|
constructor(x: Int) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
FILE /secondaryConstructors.kt
|
||||||
|
CLASS CLASS C
|
||||||
|
FUN public constructor C()
|
||||||
|
BLOCK_BODY
|
||||||
|
CALL .<init> type=C operator=DELEGATING_CONSTRUCTOR_CALL
|
||||||
|
x: CONST Int type=kotlin.Int value='0'
|
||||||
|
FUN public constructor C(/*0*/ x: kotlin.Int)
|
||||||
|
BLOCK_BODY
|
||||||
|
CALL .<init> type=kotlin.Any operator=DELEGATING_CONSTRUCTOR_CALL
|
||||||
@@ -48,6 +48,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/classMembers.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/classMembers.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("secondaryConstructors.kt")
|
||||||
|
public void testSecondaryConstructors() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/secondaryConstructors.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/ir/irText/expressions")
|
@TestMetadata("compiler/testData/ir/irText/expressions")
|
||||||
|
|||||||
Reference in New Issue
Block a user