Formatting: psi2ir
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
apply { plugin("kotlin") }
|
apply { plugin("kotlin") }
|
||||||
|
|
||||||
jvmTarget = "1.6"
|
jvmTarget = "1.6"
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ fun KtElement.deparenthesize(): KtElement =
|
|||||||
fun ResolvedCall<*>.isValueArgumentReorderingRequired(): Boolean {
|
fun ResolvedCall<*>.isValueArgumentReorderingRequired(): Boolean {
|
||||||
var lastValueParameterIndex = -1
|
var lastValueParameterIndex = -1
|
||||||
for (valueArgument in call.valueArguments) {
|
for (valueArgument in call.valueArguments) {
|
||||||
val argumentMapping = getArgumentMapping(valueArgument) as? ArgumentMatch ?:
|
val argumentMapping =
|
||||||
throw Exception("Value argument in function call is mapped with error")
|
getArgumentMapping(valueArgument) as? ArgumentMatch ?: throw Exception("Value argument in function call is mapped with error")
|
||||||
val argumentIndex = argumentMapping.valueParameter.index
|
val argumentIndex = argumentMapping.valueParameter.index
|
||||||
if (argumentIndex < lastValueParameterIndex) {
|
if (argumentIndex < lastValueParameterIndex) {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class PsiSourceManager : SourceManager {
|
|||||||
|
|
||||||
maxOffset = document.textLength
|
maxOffset = document.textLength
|
||||||
|
|
||||||
lineStartOffsets = (0 .. document.lineCount - 1)
|
lineStartOffsets = (0..document.lineCount - 1)
|
||||||
.map { document.getLineStartOffset(it) }
|
.map { document.getLineStartOffset(it) }
|
||||||
.toIntArray()
|
.toIntArray()
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-3
@@ -26,7 +26,10 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
|
||||||
class AnonymousInitializerGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
|
class AnonymousInitializerGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
|
||||||
fun generateAnonymousInitializerDeclaration(ktAnonymousInitializer: KtAnonymousInitializer, classDescriptor: ClassDescriptor): IrDeclaration =
|
fun generateAnonymousInitializerDeclaration(
|
||||||
|
ktAnonymousInitializer: KtAnonymousInitializer,
|
||||||
|
classDescriptor: ClassDescriptor
|
||||||
|
): IrDeclaration =
|
||||||
context.symbolTable.declareAnonymousInitializer(
|
context.symbolTable.declareAnonymousInitializer(
|
||||||
ktAnonymousInitializer.startOffset, ktAnonymousInitializer.endOffset, IrDeclarationOrigin.DEFINED, classDescriptor
|
ktAnonymousInitializer.startOffset, ktAnonymousInitializer.endOffset, IrDeclarationOrigin.DEFINED, classDescriptor
|
||||||
).buildWithScope { irAnonymousInitializer ->
|
).buildWithScope { irAnonymousInitializer ->
|
||||||
@@ -36,8 +39,7 @@ class AnonymousInitializerGenerator(declarationGenerator: DeclarationGenerator)
|
|||||||
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
|
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
|
||||||
if (ktBody is KtBlockExpression) {
|
if (ktBody is KtBlockExpression) {
|
||||||
statementGenerator.generateStatements(ktBody.statements, irBlockBody)
|
statementGenerator.generateStatements(ktBody.statements, irBlockBody)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
irBlockBody.statements.add(statementGenerator.generateStatement(ktBody))
|
irBlockBody.statements.add(statementGenerator.generateStatement(ktBody))
|
||||||
}
|
}
|
||||||
irAnonymousInitializer.body = irBlockBody
|
irAnonymousInitializer.body = irBlockBody
|
||||||
|
|||||||
+84
-47
@@ -56,8 +56,10 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
|
|||||||
if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor))
|
if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor))
|
||||||
generateSingletonReference(receiverClassDescriptor, defaultStartOffset, defaultEndOffset, receiver.type)
|
generateSingletonReference(receiverClassDescriptor, defaultStartOffset, defaultEndOffset, receiver.type)
|
||||||
else
|
else
|
||||||
IrGetValueImpl(defaultStartOffset, defaultEndOffset,
|
IrGetValueImpl(
|
||||||
context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter))
|
defaultStartOffset, defaultEndOffset,
|
||||||
|
context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
is ThisClassReceiver ->
|
is ThisClassReceiver ->
|
||||||
generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
|
generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
|
||||||
@@ -66,11 +68,15 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
|
|||||||
is ExpressionReceiver ->
|
is ExpressionReceiver ->
|
||||||
generateExpression(receiver.expression)
|
generateExpression(receiver.expression)
|
||||||
is ClassValueReceiver ->
|
is ClassValueReceiver ->
|
||||||
IrGetObjectValueImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
|
IrGetObjectValueImpl(
|
||||||
context.symbolTable.referenceClass(receiver.classQualifier.descriptor as ClassDescriptor))
|
receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
|
||||||
|
context.symbolTable.referenceClass(receiver.classQualifier.descriptor as ClassDescriptor)
|
||||||
|
)
|
||||||
is ExtensionReceiver ->
|
is ExtensionReceiver ->
|
||||||
IrGetValueImpl(defaultStartOffset, defaultStartOffset,
|
IrGetValueImpl(
|
||||||
context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!))
|
defaultStartOffset, defaultStartOffset,
|
||||||
|
context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!)
|
||||||
|
)
|
||||||
else ->
|
else ->
|
||||||
TODO("Receiver: ${receiver::class.java.simpleName}")
|
TODO("Receiver: ${receiver::class.java.simpleName}")
|
||||||
}
|
}
|
||||||
@@ -81,19 +87,30 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
|
|||||||
OnceExpressionValue(receiverExpression)
|
OnceExpressionValue(receiverExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun StatementGenerator.generateSingletonReference(descriptor: ClassDescriptor, startOffset: Int, endOffset: Int, type: KotlinType): IrDeclarationReference =
|
fun StatementGenerator.generateSingletonReference(
|
||||||
|
descriptor: ClassDescriptor,
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
type: KotlinType
|
||||||
|
): IrDeclarationReference =
|
||||||
when {
|
when {
|
||||||
DescriptorUtils.isObject(descriptor) ->
|
DescriptorUtils.isObject(descriptor) ->
|
||||||
IrGetObjectValueImpl(startOffset, endOffset, type,
|
IrGetObjectValueImpl(
|
||||||
context.symbolTable.referenceClass(descriptor))
|
startOffset, endOffset, type,
|
||||||
|
context.symbolTable.referenceClass(descriptor)
|
||||||
|
)
|
||||||
DescriptorUtils.isEnumEntry(descriptor) ->
|
DescriptorUtils.isEnumEntry(descriptor) ->
|
||||||
IrGetEnumValueImpl(startOffset, endOffset, type,
|
IrGetEnumValueImpl(
|
||||||
context.symbolTable.referenceEnumEntry(descriptor))
|
startOffset, endOffset, type,
|
||||||
|
context.symbolTable.referenceEnumEntry(descriptor)
|
||||||
|
)
|
||||||
else -> {
|
else -> {
|
||||||
val companionObjectDescriptor = descriptor.companionObjectDescriptor
|
val companionObjectDescriptor = descriptor.companionObjectDescriptor
|
||||||
?: throw java.lang.AssertionError("Class value without companion object: $descriptor")
|
?: throw java.lang.AssertionError("Class value without companion object: $descriptor")
|
||||||
IrGetObjectValueImpl(startOffset, endOffset, type,
|
IrGetObjectValueImpl(
|
||||||
context.symbolTable.referenceClass(companionObjectDescriptor))
|
startOffset, endOffset, type,
|
||||||
|
context.symbolTable.referenceClass(companionObjectDescriptor)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,11 +121,13 @@ private fun StatementGenerator.shouldGenerateReceiverAsSingletonReference(receiv
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun StatementGenerator.generateThisOrSuperReceiver(receiver: ReceiverValue, classDescriptor: ClassDescriptor): IrExpression {
|
private fun StatementGenerator.generateThisOrSuperReceiver(receiver: ReceiverValue, classDescriptor: ClassDescriptor): IrExpression {
|
||||||
val expressionReceiver = receiver as? ExpressionReceiver ?:
|
val expressionReceiver =
|
||||||
throw AssertionError("'this' or 'super' receiver should be an expression receiver")
|
receiver as? ExpressionReceiver ?: throw AssertionError("'this' or 'super' receiver should be an expression receiver")
|
||||||
val ktReceiver = expressionReceiver.expression
|
val ktReceiver = expressionReceiver.expression
|
||||||
return IrGetValueImpl(ktReceiver.startOffset, ktReceiver.endOffset,
|
return IrGetValueImpl(
|
||||||
context.symbolTable.referenceValueParameter(classDescriptor.thisAsReceiverParameter))
|
ktReceiver.startOffset, ktReceiver.endOffset,
|
||||||
|
context.symbolTable.referenceValueParameter(classDescriptor.thisAsReceiverParameter)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun StatementGenerator.generateBackingFieldReceiver(
|
fun StatementGenerator.generateBackingFieldReceiver(
|
||||||
@@ -128,7 +147,7 @@ fun StatementGenerator.generateCallReceiver(
|
|||||||
extensionReceiver: ReceiverValue?,
|
extensionReceiver: ReceiverValue?,
|
||||||
isSafe: Boolean,
|
isSafe: Boolean,
|
||||||
isAssignmentReceiver: Boolean = false
|
isAssignmentReceiver: Boolean = false
|
||||||
) : CallReceiver {
|
): CallReceiver {
|
||||||
val dispatchReceiverValue: IntermediateValue?
|
val dispatchReceiverValue: IntermediateValue?
|
||||||
val extensionReceiverValue: IntermediateValue?
|
val extensionReceiverValue: IntermediateValue?
|
||||||
when (calleeDescriptor) {
|
when (calleeDescriptor) {
|
||||||
@@ -136,7 +155,8 @@ fun StatementGenerator.generateCallReceiver(
|
|||||||
assert(dispatchReceiver == null) {
|
assert(dispatchReceiver == null) {
|
||||||
"Call for member imported from object $calleeDescriptor has non-null dispatch receiver $dispatchReceiver"
|
"Call for member imported from object $calleeDescriptor has non-null dispatch receiver $dispatchReceiver"
|
||||||
}
|
}
|
||||||
dispatchReceiverValue = generateReceiverForCalleeImportedFromObject(ktDefaultElement.startOffset, ktDefaultElement.endOffset, calleeDescriptor)
|
dispatchReceiverValue =
|
||||||
|
generateReceiverForCalleeImportedFromObject(ktDefaultElement.startOffset, ktDefaultElement.endOffset, calleeDescriptor)
|
||||||
extensionReceiverValue = generateReceiverOrNull(ktDefaultElement, extensionReceiver)
|
extensionReceiverValue = generateReceiverOrNull(ktDefaultElement, extensionReceiver)
|
||||||
}
|
}
|
||||||
is TypeAliasConstructorDescriptor -> {
|
is TypeAliasConstructorDescriptor -> {
|
||||||
@@ -156,9 +176,11 @@ fun StatementGenerator.generateCallReceiver(
|
|||||||
return when {
|
return when {
|
||||||
!isSafe ->
|
!isSafe ->
|
||||||
SimpleCallReceiver(dispatchReceiverValue, extensionReceiverValue)
|
SimpleCallReceiver(dispatchReceiverValue, extensionReceiverValue)
|
||||||
extensionReceiverValue != null || dispatchReceiverValue != null->
|
extensionReceiverValue != null || dispatchReceiverValue != null ->
|
||||||
SafeCallReceiver(this, ktDefaultElement.startOffset, ktDefaultElement.endOffset,
|
SafeCallReceiver(
|
||||||
extensionReceiverValue, dispatchReceiverValue, isAssignmentReceiver)
|
this, ktDefaultElement.startOffset, ktDefaultElement.endOffset,
|
||||||
|
extensionReceiverValue, dispatchReceiverValue, isAssignmentReceiver
|
||||||
|
)
|
||||||
else ->
|
else ->
|
||||||
throw AssertionError("Safe call should have an explicit receiver: ${ktDefaultElement.text}")
|
throw AssertionError("Safe call should have an explicit receiver: ${ktDefaultElement.text}")
|
||||||
}
|
}
|
||||||
@@ -172,12 +194,17 @@ private fun StatementGenerator.generateReceiverForCalleeImportedFromObject(
|
|||||||
val objectDescriptor = calleeDescriptor.containingObject
|
val objectDescriptor = calleeDescriptor.containingObject
|
||||||
val objectType = objectDescriptor.defaultType
|
val objectType = objectDescriptor.defaultType
|
||||||
return generateExpressionValue(objectType) {
|
return generateExpressionValue(objectType) {
|
||||||
IrGetObjectValueImpl(startOffset, endOffset, objectType,
|
IrGetObjectValueImpl(
|
||||||
context.symbolTable.referenceClass(objectDescriptor))
|
startOffset, endOffset, objectType,
|
||||||
|
context.symbolTable.referenceClass(objectDescriptor)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun StatementGenerator.generateVarargExpression(varargArgument: VarargValueArgument, valueParameter: ValueParameterDescriptor) : IrExpression? {
|
fun StatementGenerator.generateVarargExpression(
|
||||||
|
varargArgument: VarargValueArgument,
|
||||||
|
valueParameter: ValueParameterDescriptor
|
||||||
|
): IrExpression? {
|
||||||
if (varargArgument.arguments.isEmpty()) {
|
if (varargArgument.arguments.isEmpty()) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -189,18 +216,20 @@ fun StatementGenerator.generateVarargExpression(varargArgument: VarargValueArgum
|
|||||||
Math.max(maxEndOffset, argument.asElement().endOffset)
|
Math.max(maxEndOffset, argument.asElement().endOffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
val varargElementType = valueParameter.varargElementType ?:
|
val varargElementType =
|
||||||
throw AssertionError("Vararg argument for non-vararg parameter $valueParameter")
|
valueParameter.varargElementType ?: throw AssertionError("Vararg argument for non-vararg parameter $valueParameter")
|
||||||
|
|
||||||
val irVararg = IrVarargImpl(varargStartOffset, varargEndOffset, valueParameter.type, varargElementType)
|
val irVararg = IrVarargImpl(varargStartOffset, varargEndOffset, valueParameter.type, varargElementType)
|
||||||
|
|
||||||
for (argument in varargArgument.arguments) {
|
for (argument in varargArgument.arguments) {
|
||||||
val ktArgumentExpression = argument.getArgumentExpression() ?:
|
val ktArgumentExpression = argument.getArgumentExpression()
|
||||||
throw AssertionError("No argument expression for vararg element ${argument.asElement().text}")
|
?: throw AssertionError("No argument expression for vararg element ${argument.asElement().text}")
|
||||||
val irVarargElement =
|
val irVarargElement =
|
||||||
if (argument.getSpreadElement() != null)
|
if (argument.getSpreadElement() != null)
|
||||||
IrSpreadElementImpl(ktArgumentExpression.startOffset, ktArgumentExpression.endOffset,
|
IrSpreadElementImpl(
|
||||||
generateExpression(ktArgumentExpression))
|
ktArgumentExpression.startOffset, ktArgumentExpression.endOffset,
|
||||||
|
generateExpression(ktArgumentExpression)
|
||||||
|
)
|
||||||
else
|
else
|
||||||
generateExpression(ktArgumentExpression)
|
generateExpression(ktArgumentExpression)
|
||||||
|
|
||||||
@@ -210,7 +239,10 @@ fun StatementGenerator.generateVarargExpression(varargArgument: VarargValueArgum
|
|||||||
return irVararg
|
return irVararg
|
||||||
}
|
}
|
||||||
|
|
||||||
fun StatementGenerator.generateValueArgument(valueArgument: ResolvedValueArgument, valueParameter: ValueParameterDescriptor): IrExpression? =
|
fun StatementGenerator.generateValueArgument(
|
||||||
|
valueArgument: ResolvedValueArgument,
|
||||||
|
valueParameter: ValueParameterDescriptor
|
||||||
|
): IrExpression? =
|
||||||
when (valueArgument) {
|
when (valueArgument) {
|
||||||
is DefaultValueArgument ->
|
is DefaultValueArgument ->
|
||||||
null
|
null
|
||||||
@@ -239,11 +271,12 @@ fun StatementGenerator.pregenerateCall(resolvedCall: ResolvedCall<*>): CallBuild
|
|||||||
|
|
||||||
fun StatementGenerator.pregenerateExtensionInvokeCall(resolvedCall: ResolvedCall<*>): CallBuilder {
|
fun StatementGenerator.pregenerateExtensionInvokeCall(resolvedCall: ResolvedCall<*>): CallBuilder {
|
||||||
val extensionInvoke = resolvedCall.resultingDescriptor
|
val extensionInvoke = resolvedCall.resultingDescriptor
|
||||||
val functionNClass = extensionInvoke.containingDeclaration as? ClassDescriptor ?:
|
val functionNClass = extensionInvoke.containingDeclaration as? ClassDescriptor
|
||||||
throw AssertionError("'invoke' should be a class member: $extensionInvoke")
|
?: throw AssertionError("'invoke' should be a class member: $extensionInvoke")
|
||||||
val unsubstitutedPlainInvokes = functionNClass.unsubstitutedMemberScope.getContributedFunctions(extensionInvoke.name, NoLookupLocation.FROM_BACKEND)
|
val unsubstitutedPlainInvokes =
|
||||||
val unsubstitutedPlainInvoke = unsubstitutedPlainInvokes.singleOrNull() ?:
|
functionNClass.unsubstitutedMemberScope.getContributedFunctions(extensionInvoke.name, NoLookupLocation.FROM_BACKEND)
|
||||||
throw AssertionError("There should be a single 'invoke' in FunctionN class: $unsubstitutedPlainInvokes")
|
val unsubstitutedPlainInvoke = unsubstitutedPlainInvokes.singleOrNull()
|
||||||
|
?: throw AssertionError("There should be a single 'invoke' in FunctionN class: $unsubstitutedPlainInvokes")
|
||||||
|
|
||||||
val expectedValueParametersCount = extensionInvoke.valueParameters.size + 1
|
val expectedValueParametersCount = extensionInvoke.valueParameters.size + 1
|
||||||
assert(unsubstitutedPlainInvoke.valueParameters.size == expectedValueParametersCount) {
|
assert(unsubstitutedPlainInvoke.valueParameters.size == expectedValueParametersCount) {
|
||||||
@@ -251,29 +284,31 @@ fun StatementGenerator.pregenerateExtensionInvokeCall(resolvedCall: ResolvedCall
|
|||||||
}
|
}
|
||||||
|
|
||||||
val functionNType = extensionInvoke.dispatchReceiverParameter!!.type
|
val functionNType = extensionInvoke.dispatchReceiverParameter!!.type
|
||||||
val plainInvoke = unsubstitutedPlainInvoke.substitute(TypeSubstitutor.create(functionNType)) ?:
|
val plainInvoke = unsubstitutedPlainInvoke.substitute(TypeSubstitutor.create(functionNType))
|
||||||
throw AssertionError("Substitution failed for $unsubstitutedPlainInvoke, type=$functionNType")
|
?: throw AssertionError("Substitution failed for $unsubstitutedPlainInvoke, type=$functionNType")
|
||||||
|
|
||||||
val ktCallElement = resolvedCall.call.callElement
|
val ktCallElement = resolvedCall.call.callElement
|
||||||
|
|
||||||
val call = CallBuilder(resolvedCall, plainInvoke, isExtensionInvokeCall = true)
|
val call = CallBuilder(resolvedCall, plainInvoke, isExtensionInvokeCall = true)
|
||||||
|
|
||||||
val functionReceiverValue = run {
|
val functionReceiverValue = run {
|
||||||
val dispatchReceiver = resolvedCall.dispatchReceiver ?:
|
val dispatchReceiver =
|
||||||
throw AssertionError("Extension 'invoke' call should have a dispatch receiver")
|
resolvedCall.dispatchReceiver ?: throw AssertionError("Extension 'invoke' call should have a dispatch receiver")
|
||||||
generateReceiver(ktCallElement, dispatchReceiver)
|
generateReceiver(ktCallElement, dispatchReceiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
val extensionInvokeReceiverValue = run {
|
val extensionInvokeReceiverValue = run {
|
||||||
val extensionReceiver = resolvedCall.extensionReceiver ?:
|
val extensionReceiver =
|
||||||
throw AssertionError("Extension 'invoke' call should have an extension receiver")
|
resolvedCall.extensionReceiver ?: throw AssertionError("Extension 'invoke' call should have an extension receiver")
|
||||||
generateReceiver(ktCallElement, extensionReceiver)
|
generateReceiver(ktCallElement, extensionReceiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
call.callReceiver =
|
call.callReceiver =
|
||||||
if (resolvedCall.call.isSafeCall())
|
if (resolvedCall.call.isSafeCall())
|
||||||
SafeExtensionInvokeCallReceiver(this, ktCallElement.startOffset, ktCallElement.endOffset,
|
SafeExtensionInvokeCallReceiver(
|
||||||
call, functionReceiverValue, extensionInvokeReceiverValue)
|
this, ktCallElement.startOffset, ktCallElement.endOffset,
|
||||||
|
call, functionReceiverValue, extensionInvokeReceiverValue
|
||||||
|
)
|
||||||
else
|
else
|
||||||
ExtensionInvokeCallReceiver(call, functionReceiverValue, extensionInvokeReceiverValue)
|
ExtensionInvokeCallReceiver(call, functionReceiverValue, extensionInvokeReceiverValue)
|
||||||
|
|
||||||
@@ -313,11 +348,13 @@ private fun StatementGenerator.pregenerateValueArguments(call: CallBuilder, reso
|
|||||||
fun StatementGenerator.pregenerateCallReceivers(resolvedCall: ResolvedCall<*>): CallBuilder {
|
fun StatementGenerator.pregenerateCallReceivers(resolvedCall: ResolvedCall<*>): CallBuilder {
|
||||||
val call = CallBuilder(resolvedCall, unwrapCallableDescriptor(resolvedCall.resultingDescriptor))
|
val call = CallBuilder(resolvedCall, unwrapCallableDescriptor(resolvedCall.resultingDescriptor))
|
||||||
|
|
||||||
call.callReceiver = generateCallReceiver(resolvedCall.call.callElement,
|
call.callReceiver = generateCallReceiver(
|
||||||
|
resolvedCall.call.callElement,
|
||||||
resolvedCall.resultingDescriptor,
|
resolvedCall.resultingDescriptor,
|
||||||
resolvedCall.dispatchReceiver,
|
resolvedCall.dispatchReceiver,
|
||||||
resolvedCall.extensionReceiver,
|
resolvedCall.extensionReceiver,
|
||||||
isSafe = resolvedCall.call.isSafeCall())
|
isSafe = resolvedCall.call.isSafeCall()
|
||||||
|
)
|
||||||
|
|
||||||
call.superQualifier = getSuperQualifier(resolvedCall)
|
call.superQualifier = getSuperQualifier(resolvedCall)
|
||||||
|
|
||||||
|
|||||||
+15
-11
@@ -58,8 +58,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
|||||||
if (isSimpleAssignment) {
|
if (isSimpleAssignment) {
|
||||||
// Set( Op( Get(), RHS ) )
|
// Set( Op( Get(), RHS ) )
|
||||||
irLValue.store(irOpCall)
|
irLValue.store(irOpCall)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Op( Get(), RHS )
|
// Op( Get(), RHS )
|
||||||
irOpCall
|
irOpCall
|
||||||
}
|
}
|
||||||
@@ -109,7 +108,8 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
|||||||
|
|
||||||
return when (descriptor) {
|
return when (descriptor) {
|
||||||
is SyntheticFieldDescriptor -> {
|
is SyntheticFieldDescriptor -> {
|
||||||
val receiverValue = statementGenerator.generateBackingFieldReceiver(ktLeft.startOffset, ktLeft.endOffset, resolvedCall, descriptor)
|
val receiverValue =
|
||||||
|
statementGenerator.generateBackingFieldReceiver(ktLeft.startOffset, ktLeft.endOffset, resolvedCall, descriptor)
|
||||||
createBackingFieldLValue(ktLeft, descriptor.propertyDescriptor, receiverValue, origin)
|
createBackingFieldLValue(ktLeft, descriptor.propertyDescriptor, receiverValue, origin)
|
||||||
}
|
}
|
||||||
is LocalVariableDescriptor ->
|
is LocalVariableDescriptor ->
|
||||||
@@ -167,12 +167,12 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
|||||||
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter)
|
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter)
|
||||||
)
|
)
|
||||||
createBackingFieldLValue(ktLeft, descriptor, RematerializableValue(irThis), null)
|
createBackingFieldLValue(ktLeft, descriptor, RematerializableValue(irThis), null)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val propertyReceiver = statementGenerator.generateCallReceiver(
|
val propertyReceiver = statementGenerator.generateCallReceiver(
|
||||||
ktLeft, descriptor, resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver,
|
ktLeft, descriptor, resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver,
|
||||||
isSafe = resolvedCall.call.isSafeCall(),
|
isSafe = resolvedCall.call.isSafeCall(),
|
||||||
isAssignmentReceiver = true)
|
isAssignmentReceiver = true
|
||||||
|
)
|
||||||
|
|
||||||
val superQualifier = getSuperQualifier(resolvedCall)
|
val superQualifier = getSuperQualifier(resolvedCall)
|
||||||
|
|
||||||
@@ -208,8 +208,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
|||||||
propertyReceiver,
|
propertyReceiver,
|
||||||
superQualifierSymbol
|
superQualifierSymbol
|
||||||
)
|
)
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
FieldPropertyLValue(
|
FieldPropertyLValue(
|
||||||
scope,
|
scope,
|
||||||
ktExpression.startOffset, ktExpression.endOffset, origin,
|
ktExpression.startOffset, ktExpression.endOffset, origin,
|
||||||
@@ -234,7 +233,10 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateArrayAccessAssignmentReceiver(ktLeft: KtArrayAccessExpression, origin: IrStatementOrigin): ArrayAccessAssignmentReceiver {
|
private fun generateArrayAccessAssignmentReceiver(
|
||||||
|
ktLeft: KtArrayAccessExpression,
|
||||||
|
origin: IrStatementOrigin
|
||||||
|
): ArrayAccessAssignmentReceiver {
|
||||||
val irArray = statementGenerator.generateExpression(ktLeft.arrayExpression!!)
|
val irArray = statementGenerator.generateExpression(ktLeft.arrayExpression!!)
|
||||||
val irIndexExpressions = ktLeft.indexExpressions.map { statementGenerator.generateExpression(it) }
|
val irIndexExpressions = ktLeft.indexExpressions.map { statementGenerator.generateExpression(it) }
|
||||||
|
|
||||||
@@ -244,9 +246,11 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
|||||||
val indexedSetResolvedCall = get(BindingContext.INDEXED_LVALUE_SET, ktLeft)
|
val indexedSetResolvedCall = get(BindingContext.INDEXED_LVALUE_SET, ktLeft)
|
||||||
val indexedSetCall = indexedSetResolvedCall?.let { statementGenerator.pregenerateCallReceivers(it) }
|
val indexedSetCall = indexedSetResolvedCall?.let { statementGenerator.pregenerateCallReceivers(it) }
|
||||||
|
|
||||||
return ArrayAccessAssignmentReceiver(irArray, irIndexExpressions, indexedGetCall, indexedSetCall,
|
return ArrayAccessAssignmentReceiver(
|
||||||
|
irArray, irIndexExpressions, indexedGetCall, indexedSetCall,
|
||||||
CallGenerator(statementGenerator),
|
CallGenerator(statementGenerator),
|
||||||
ktLeft.startOffset, ktLeft.endOffset, origin)
|
ktLeft.startOffset, ktLeft.endOffset, origin
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ class BodyGenerator(
|
|||||||
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
|
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
|
||||||
if (ktBody is KtBlockExpression) {
|
if (ktBody is KtBlockExpression) {
|
||||||
statementGenerator.generateStatements(ktBody.statements, irBlockBody)
|
statementGenerator.generateStatements(ktBody.statements, irBlockBody)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
statementGenerator.generateReturnExpression(ktBody, irBlockBody)
|
statementGenerator.generateReturnExpression(ktBody, irBlockBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,9 +67,11 @@ class BodyGenerator(
|
|||||||
for (ktParameter in ktFun.valueParameters) {
|
for (ktParameter in ktFun.valueParameters) {
|
||||||
val ktDestructuringDeclaration = ktParameter.destructuringDeclaration ?: continue
|
val ktDestructuringDeclaration = ktParameter.destructuringDeclaration ?: continue
|
||||||
val valueParameter = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter)
|
val valueParameter = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter)
|
||||||
val parameterValue = VariableLValue(ktDestructuringDeclaration.startOffset, ktDestructuringDeclaration.endOffset,
|
val parameterValue = VariableLValue(
|
||||||
|
ktDestructuringDeclaration.startOffset, ktDestructuringDeclaration.endOffset,
|
||||||
context.symbolTable.referenceValue(valueParameter),
|
context.symbolTable.referenceValue(valueParameter),
|
||||||
IrStatementOrigin.DESTRUCTURING_DECLARATION)
|
IrStatementOrigin.DESTRUCTURING_DECLARATION
|
||||||
|
)
|
||||||
statementGenerator.declareComponentVariablesInBlock(ktDestructuringDeclaration, irBlockBody, parameterValue)
|
statementGenerator.declareComponentVariablesInBlock(ktDestructuringDeclaration, irBlockBody, parameterValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,12 +82,16 @@ class BodyGenerator(
|
|||||||
}
|
}
|
||||||
val ktReturnedValue = ktBodyStatements.last()
|
val ktReturnedValue = ktBodyStatements.last()
|
||||||
statementGenerator.generateReturnExpression(ktReturnedValue, irBlockBody)
|
statementGenerator.generateReturnExpression(ktReturnedValue, irBlockBody)
|
||||||
}
|
} else {
|
||||||
else {
|
irBlockBody.statements.add(
|
||||||
irBlockBody.statements.add(generateReturnExpression(
|
generateReturnExpression(
|
||||||
ktBody.startOffset, ktBody.endOffset,
|
ktBody.startOffset, ktBody.endOffset,
|
||||||
IrGetObjectValueImpl(ktBody.startOffset, ktBody.endOffset, context.builtIns.unitType,
|
IrGetObjectValueImpl(
|
||||||
context.symbolTable.referenceClass(context.builtIns.unit))))
|
ktBody.startOffset, ktBody.endOffset, context.builtIns.unitType,
|
||||||
|
context.symbolTable.referenceClass(context.builtIns.unit)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return irBlockBody
|
return irBlockBody
|
||||||
@@ -96,8 +101,7 @@ class BodyGenerator(
|
|||||||
val irReturnExpression = generateStatement(ktExpression)
|
val irReturnExpression = generateStatement(ktExpression)
|
||||||
if (irReturnExpression is IrExpression) {
|
if (irReturnExpression is IrExpression) {
|
||||||
irBlockBody.statements.add(irReturnExpression.wrapWithReturn())
|
irBlockBody.statements.add(irReturnExpression.wrapWithReturn())
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
irBlockBody.statements.add(irReturnExpression)
|
irBlockBody.statements.add(irReturnExpression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,15 +110,17 @@ class BodyGenerator(
|
|||||||
if (this is IrReturn || this is IrErrorExpression || this is IrThrow)
|
if (this is IrReturn || this is IrErrorExpression || this is IrThrow)
|
||||||
this
|
this
|
||||||
else {
|
else {
|
||||||
generateReturnExpression(startOffset, endOffset, this) }
|
generateReturnExpression(startOffset, endOffset, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun generateReturnExpression(startOffset: Int, endOffset: Int, returnValue: IrExpression): IrReturnImpl {
|
private fun generateReturnExpression(startOffset: Int, endOffset: Int, returnValue: IrExpression): IrReturnImpl {
|
||||||
val returnTarget = (scopeOwner as? CallableDescriptor) ?:
|
val returnTarget = (scopeOwner as? CallableDescriptor) ?: throw AssertionError("'return' in a non-callable: $scopeOwner")
|
||||||
throw AssertionError("'return' in a non-callable: $scopeOwner")
|
return IrReturnImpl(
|
||||||
return IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType,
|
startOffset, endOffset, context.builtIns.nothingType,
|
||||||
context.symbolTable.referenceFunction(returnTarget),
|
context.symbolTable.referenceFunction(returnTarget),
|
||||||
returnValue)
|
returnValue
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -140,8 +146,7 @@ class BodyGenerator(
|
|||||||
if (delegatingConstructorResolvedCall == null) {
|
if (delegatingConstructorResolvedCall == null) {
|
||||||
if (constructorDescriptor.containingDeclaration.kind == ClassKind.ENUM_CLASS) {
|
if (constructorDescriptor.containingDeclaration.kind == ClassKind.ENUM_CLASS) {
|
||||||
generateEnumSuperConstructorCall(irBlockBody, ktConstructor)
|
generateEnumSuperConstructorCall(irBlockBody, ktConstructor)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
generateAnySuperConstructorCall(irBlockBody, ktConstructor)
|
generateAnySuperConstructorCall(irBlockBody, ktConstructor)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -150,7 +155,8 @@ class BodyGenerator(
|
|||||||
val delegatingConstructorCall = statementGenerator.pregenerateCall(delegatingConstructorResolvedCall)
|
val delegatingConstructorCall = statementGenerator.pregenerateCall(delegatingConstructorResolvedCall)
|
||||||
val irDelegatingConstructorCall = CallGenerator(statementGenerator).generateDelegatingConstructorCall(
|
val irDelegatingConstructorCall = CallGenerator(statementGenerator).generateDelegatingConstructorCall(
|
||||||
ktDelegatingConstructorCall.startOffset, ktDelegatingConstructorCall.endOffset,
|
ktDelegatingConstructorCall.startOffset, ktDelegatingConstructorCall.endOffset,
|
||||||
delegatingConstructorCall)
|
delegatingConstructorCall
|
||||||
|
)
|
||||||
irBlockBody.statements.add(irDelegatingConstructorCall)
|
irBlockBody.statements.add(irDelegatingConstructorCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,8 +175,12 @@ class BodyGenerator(
|
|||||||
generateSuperConstructorCall(irBlockBody, ktClassOrObject)
|
generateSuperConstructorCall(irBlockBody, ktClassOrObject)
|
||||||
|
|
||||||
val classDescriptor = (scopeOwner as ClassConstructorDescriptor).containingDeclaration
|
val classDescriptor = (scopeOwner as ClassConstructorDescriptor).containingDeclaration
|
||||||
irBlockBody.statements.add(IrInstanceInitializerCallImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset,
|
irBlockBody.statements.add(
|
||||||
context.symbolTable.referenceClass(classDescriptor)))
|
IrInstanceInitializerCallImpl(
|
||||||
|
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
|
||||||
|
context.symbolTable.referenceClass(classDescriptor)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return irBlockBody
|
return irBlockBody
|
||||||
}
|
}
|
||||||
@@ -181,8 +191,12 @@ class BodyGenerator(
|
|||||||
generateDelegatingConstructorCall(irBlockBody, ktConstructor)
|
generateDelegatingConstructorCall(irBlockBody, ktConstructor)
|
||||||
|
|
||||||
val classDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor).containingDeclaration as ClassDescriptor
|
val classDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor).containingDeclaration as ClassDescriptor
|
||||||
irBlockBody.statements.add(IrInstanceInitializerCallImpl(ktConstructor.startOffset, ktConstructor.endOffset,
|
irBlockBody.statements.add(
|
||||||
context.symbolTable.referenceClass(classDescriptor)))
|
IrInstanceInitializerCallImpl(
|
||||||
|
ktConstructor.startOffset, ktConstructor.endOffset,
|
||||||
|
context.symbolTable.referenceClass(classDescriptor)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
ktConstructor.bodyExpression?.let { ktBody ->
|
ktConstructor.bodyExpression?.let { ktBody ->
|
||||||
createStatementGenerator().generateStatements(ktBody.statements, irBlockBody)
|
createStatementGenerator().generateStatements(ktBody.statements, irBlockBody)
|
||||||
@@ -209,7 +223,8 @@ class BodyGenerator(
|
|||||||
if (ktSuperTypeListEntry is KtSuperTypeCallEntry) {
|
if (ktSuperTypeListEntry is KtSuperTypeCallEntry) {
|
||||||
val superConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktSuperTypeListEntry)!!)
|
val superConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktSuperTypeListEntry)!!)
|
||||||
val irSuperConstructorCall = CallGenerator(statementGenerator).generateDelegatingConstructorCall(
|
val irSuperConstructorCall = CallGenerator(statementGenerator).generateDelegatingConstructorCall(
|
||||||
ktSuperTypeListEntry.startOffset, ktSuperTypeListEntry.endOffset, superConstructorCall)
|
ktSuperTypeListEntry.startOffset, ktSuperTypeListEntry.endOffset, superConstructorCall
|
||||||
|
)
|
||||||
irBlockBody.statements.add(irSuperConstructorCall)
|
irBlockBody.statements.add(irSuperConstructorCall)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -282,17 +297,22 @@ class BodyGenerator(
|
|||||||
|
|
||||||
// Default enum entry constructor
|
// Default enum entry constructor
|
||||||
val enumClassConstructor =
|
val enumClassConstructor =
|
||||||
enumClassDescriptor.constructors.singleOrNull { it.valueParameters.all { it.hasDefaultValue() } } ?:
|
enumClassDescriptor.constructors.singleOrNull { it.valueParameters.all { it.hasDefaultValue() } }
|
||||||
throw AssertionError("Enum class $enumClassDescriptor should have a default constructor")
|
?: throw AssertionError("Enum class $enumClassDescriptor should have a default constructor")
|
||||||
return IrEnumConstructorCallImpl(
|
return IrEnumConstructorCallImpl(
|
||||||
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
||||||
context.symbolTable.referenceConstructor(enumClassConstructor)
|
context.symbolTable.referenceConstructor(enumClassConstructor)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun StatementGenerator.generateEnumConstructorCall(constructorCall: ResolvedCall<out CallableDescriptor>, ktEnumEntry: KtEnumEntry) =
|
private fun StatementGenerator.generateEnumConstructorCall(
|
||||||
CallGenerator(this).generateEnumConstructorSuperCall(ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
constructorCall: ResolvedCall<out CallableDescriptor>,
|
||||||
pregenerateCall(constructorCall))
|
ktEnumEntry: KtEnumEntry
|
||||||
|
) =
|
||||||
|
CallGenerator(this).generateEnumConstructorSuperCall(
|
||||||
|
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
||||||
|
pregenerateCall(constructorCall)
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-7
@@ -39,7 +39,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
|||||||
val irBranches = SmartList<IrBranch>()
|
val irBranches = SmartList<IrBranch>()
|
||||||
var irElseBranch: IrExpression? = null
|
var irElseBranch: IrExpression? = null
|
||||||
|
|
||||||
whenBranches@while (true) {
|
whenBranches@ while (true) {
|
||||||
val irCondition = statementGenerator.generateExpression(ktLastIf.condition!!)
|
val irCondition = statementGenerator.generateExpression(ktLastIf.condition!!)
|
||||||
val irThenBranch = statementGenerator.generateExpression(ktLastIf.then!!)
|
val irThenBranch = statementGenerator.generateExpression(ktLastIf.then!!)
|
||||||
irBranches.add(IrBranchImpl(irCondition, irThenBranch))
|
irBranches.add(IrBranchImpl(irCondition, irThenBranch))
|
||||||
@@ -66,8 +66,10 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
|||||||
resultType: KotlinType
|
resultType: KotlinType
|
||||||
): IrWhen {
|
): IrWhen {
|
||||||
if (irBranches.size == 1) {
|
if (irBranches.size == 1) {
|
||||||
return IrIfThenElseImpl(ktIf.startOffset, ktIf.endOffset, resultType,
|
return IrIfThenElseImpl(
|
||||||
irBranches[0].condition, irBranches[0].result, irElseResult)
|
ktIf.startOffset, ktIf.endOffset, resultType,
|
||||||
|
irBranches[0].condition, irBranches[0].result, irElseResult
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val irWhen = IrWhenImpl(ktIf.startOffset, ktIf.endOffset, resultType, IrStatementOrigin.WHEN)
|
val irWhen = IrWhenImpl(ktIf.startOffset, ktIf.endOffset, resultType, IrStatementOrigin.WHEN)
|
||||||
@@ -146,14 +148,12 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
|||||||
IrBlockImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType, IrStatementOrigin.WHEN)
|
IrBlockImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType, IrStatementOrigin.WHEN)
|
||||||
else
|
else
|
||||||
irWhen
|
irWhen
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (irWhen.branches.isEmpty()) {
|
if (irWhen.branches.isEmpty()) {
|
||||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType, IrStatementOrigin.WHEN)
|
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType, IrStatementOrigin.WHEN)
|
||||||
irBlock.statements.add(irSubject)
|
irBlock.statements.add(irSubject)
|
||||||
irBlock
|
irBlock
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irWhen.type, IrStatementOrigin.WHEN)
|
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irWhen.type, IrStatementOrigin.WHEN)
|
||||||
irBlock.statements.add(irSubject)
|
irBlock.statements.add(irSubject)
|
||||||
irBlock.statements.add(irWhen)
|
irBlock.statements.add(irWhen)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorExtension(statementGenerator) {
|
class CallGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||||
fun generateCall(startOffset: Int, endOffset: Int, call: CallBuilder, origin: IrStatementOrigin? = null): IrExpression {
|
fun generateCall(startOffset: Int, endOffset: Int, call: CallBuilder, origin: IrStatementOrigin? = null): IrExpression {
|
||||||
val descriptor = call.descriptor
|
val descriptor = call.descriptor
|
||||||
|
|
||||||
@@ -92,24 +92,26 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
|
|||||||
if (descriptor is LocalVariableDescriptor && descriptor.isDelegated) {
|
if (descriptor is LocalVariableDescriptor && descriptor.isDelegated) {
|
||||||
val getterDescriptor = descriptor.getter!!
|
val getterDescriptor = descriptor.getter!!
|
||||||
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
|
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
|
||||||
IrCallImpl(startOffset, endOffset, descriptor.type, getterSymbol, getterDescriptor,
|
IrCallImpl(
|
||||||
typeArguments, origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY)
|
startOffset, endOffset, descriptor.type, getterSymbol, getterDescriptor,
|
||||||
}
|
typeArguments, origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY
|
||||||
else
|
)
|
||||||
|
} else
|
||||||
IrGetValueImpl(startOffset, endOffset, context.symbolTable.referenceValue(descriptor), origin)
|
IrGetValueImpl(startOffset, endOffset, context.symbolTable.referenceValue(descriptor), origin)
|
||||||
|
|
||||||
fun generateDelegatingConstructorCall(startOffset: Int, endOffset: Int, call: CallBuilder) : IrExpression =
|
fun generateDelegatingConstructorCall(startOffset: Int, endOffset: Int, call: CallBuilder): IrExpression =
|
||||||
call.callReceiver.call { dispatchReceiver, extensionReceiver ->
|
call.callReceiver.call { dispatchReceiver, extensionReceiver ->
|
||||||
val descriptor = call.descriptor as? ClassConstructorDescriptor
|
val descriptor = call.descriptor as? ClassConstructorDescriptor
|
||||||
?: throw AssertionError("Class constructor expected: ${call.descriptor}")
|
?: throw AssertionError("Class constructor expected: ${call.descriptor}")
|
||||||
val constructorSymbol = context.symbolTable.referenceConstructor(descriptor.original)
|
val constructorSymbol = context.symbolTable.referenceConstructor(descriptor.original)
|
||||||
val irCall = IrDelegatingConstructorCallImpl(startOffset, endOffset, constructorSymbol, descriptor, getTypeArguments(call.original))
|
val irCall =
|
||||||
|
IrDelegatingConstructorCallImpl(startOffset, endOffset, constructorSymbol, descriptor, getTypeArguments(call.original))
|
||||||
irCall.dispatchReceiver = dispatchReceiver?.load()
|
irCall.dispatchReceiver = dispatchReceiver?.load()
|
||||||
irCall.extensionReceiver = extensionReceiver?.load()
|
irCall.extensionReceiver = extensionReceiver?.load()
|
||||||
addParametersToCall(startOffset, endOffset, call, irCall, descriptor.builtIns.unitType)
|
addParametersToCall(startOffset, endOffset, call, irCall, descriptor.builtIns.unitType)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateEnumConstructorSuperCall(startOffset: Int, endOffset: Int, call: CallBuilder) : IrExpression {
|
fun generateEnumConstructorSuperCall(startOffset: Int, endOffset: Int, call: CallBuilder): IrExpression {
|
||||||
val constructorDescriptor = call.descriptor
|
val constructorDescriptor = call.descriptor
|
||||||
if (constructorDescriptor !is ClassConstructorDescriptor) throw AssertionError("Constructor expected: $constructorDescriptor")
|
if (constructorDescriptor !is ClassConstructorDescriptor) throw AssertionError("Constructor expected: $constructorDescriptor")
|
||||||
val classDescriptor = constructorDescriptor.containingDeclaration
|
val classDescriptor = constructorDescriptor.containingDeclaration
|
||||||
@@ -146,8 +148,7 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
|
|||||||
IrStatementOrigin.GET_PROPERTY,
|
IrStatementOrigin.GET_PROPERTY,
|
||||||
superQualifierSymbol
|
superQualifierSymbol
|
||||||
)
|
)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val fieldSymbol = context.symbolTable.referenceField(descriptor)
|
val fieldSymbol = context.symbolTable.referenceField(descriptor)
|
||||||
IrGetFieldImpl(
|
IrGetFieldImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
@@ -186,11 +187,16 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
|
|||||||
addParametersToCall(startOffset, endOffset, call, irCall, returnType)
|
addParametersToCall(startOffset, endOffset, call, irCall, returnType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addParametersToCall(startOffset: Int, endOffset: Int, call: CallBuilder, irCall: IrFunctionAccessExpression, returnType: KotlinType): IrExpression =
|
private fun addParametersToCall(
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
call: CallBuilder,
|
||||||
|
irCall: IrFunctionAccessExpression,
|
||||||
|
returnType: KotlinType
|
||||||
|
): IrExpression =
|
||||||
if (call.isValueArgumentReorderingRequired()) {
|
if (call.isValueArgumentReorderingRequired()) {
|
||||||
generateCallWithArgumentReordering(irCall, startOffset, endOffset, call, returnType)
|
generateCallWithArgumentReordering(irCall, startOffset, endOffset, call, returnType)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val valueArguments = call.getValueArgumentsInParameterOrder()
|
val valueArguments = call.getValueArgumentsInParameterOrder()
|
||||||
for ((index, valueArgument) in valueArguments.withIndex()) {
|
for ((index, valueArgument) in valueArguments.withIndex()) {
|
||||||
irCall.putValueArgument(index, valueArgument)
|
irCall.putValueArgument(index, valueArgument)
|
||||||
|
|||||||
+33
-14
@@ -23,12 +23,12 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
|
|||||||
import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl
|
import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
|
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
|
||||||
|
import org.jetbrains.kotlin.ir.util.StableDescriptorsComparator
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
|
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
|
||||||
import org.jetbrains.kotlin.psi.KtEnumEntry
|
import org.jetbrains.kotlin.psi.KtEnumEntry
|
||||||
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.ir.util.StableDescriptorsComparator
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
@@ -112,8 +112,8 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
|||||||
val delegateType = getInferredTypeWithImplicitCastsOrFail(ktDelegateExpression)
|
val delegateType = getInferredTypeWithImplicitCastsOrFail(ktDelegateExpression)
|
||||||
val superType = getOrFail(BindingContext.TYPE, ktEntry.typeReference!!)
|
val superType = getOrFail(BindingContext.TYPE, ktEntry.typeReference!!)
|
||||||
val superTypeConstructorDescriptor = superType.constructor.declarationDescriptor
|
val superTypeConstructorDescriptor = superType.constructor.declarationDescriptor
|
||||||
val superClass = superTypeConstructorDescriptor as? ClassDescriptor ?:
|
val superClass = superTypeConstructorDescriptor as? ClassDescriptor
|
||||||
throw AssertionError("Unexpected supertype constructor for delegation: $superTypeConstructorDescriptor")
|
?: throw AssertionError("Unexpected supertype constructor for delegation: $superTypeConstructorDescriptor")
|
||||||
val delegateDescriptor = IrImplementingDelegateDescriptorImpl(irClass.descriptor, delegateType, superType)
|
val delegateDescriptor = IrImplementingDelegateDescriptorImpl(irClass.descriptor, delegateType, superType)
|
||||||
val irDelegateField = context.symbolTable.declareField(
|
val irDelegateField = context.symbolTable.declareField(
|
||||||
ktDelegateExpression.startOffset, ktDelegateExpression.endOffset,
|
ktDelegateExpression.startOffset, ktDelegateExpression.endOffset,
|
||||||
@@ -131,8 +131,10 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateDelegatedMember(irClass: IrClass, irDelegate: IrField,
|
private fun generateDelegatedMember(
|
||||||
delegatedMember: CallableMemberDescriptor, overriddenMember: CallableMemberDescriptor) {
|
irClass: IrClass, irDelegate: IrField,
|
||||||
|
delegatedMember: CallableMemberDescriptor, overriddenMember: CallableMemberDescriptor
|
||||||
|
) {
|
||||||
when (delegatedMember) {
|
when (delegatedMember) {
|
||||||
is FunctionDescriptor ->
|
is FunctionDescriptor ->
|
||||||
generateDelegatedFunction(irClass, irDelegate, delegatedMember, overriddenMember as FunctionDescriptor)
|
generateDelegatedFunction(irClass, irDelegate, delegatedMember, overriddenMember as FunctionDescriptor)
|
||||||
@@ -142,11 +144,20 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateDelegatedProperty(irClass: IrClass, irDelegate: IrField, delegated: PropertyDescriptor, overridden: PropertyDescriptor) {
|
private fun generateDelegatedProperty(
|
||||||
|
irClass: IrClass,
|
||||||
|
irDelegate: IrField,
|
||||||
|
delegated: PropertyDescriptor,
|
||||||
|
overridden: PropertyDescriptor
|
||||||
|
) {
|
||||||
irClass.addMember(generateDelegatedProperty(irDelegate, delegated, overridden))
|
irClass.addMember(generateDelegatedProperty(irDelegate, delegated, overridden))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateDelegatedProperty(irDelegate: IrField, delegated: PropertyDescriptor, overridden: PropertyDescriptor): IrPropertyImpl {
|
private fun generateDelegatedProperty(
|
||||||
|
irDelegate: IrField,
|
||||||
|
delegated: PropertyDescriptor,
|
||||||
|
overridden: PropertyDescriptor
|
||||||
|
): IrPropertyImpl {
|
||||||
val startOffset = irDelegate.startOffset
|
val startOffset = irDelegate.startOffset
|
||||||
val endOffset = irDelegate.endOffset
|
val endOffset = irDelegate.endOffset
|
||||||
|
|
||||||
@@ -160,7 +171,12 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
|||||||
return irProperty
|
return irProperty
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateDelegatedFunction(irClass: IrClass, irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor) {
|
private fun generateDelegatedFunction(
|
||||||
|
irClass: IrClass,
|
||||||
|
irDelegate: IrField,
|
||||||
|
delegated: FunctionDescriptor,
|
||||||
|
overridden: FunctionDescriptor
|
||||||
|
) {
|
||||||
irClass.addMember(generateDelegatedFunction(irDelegate, delegated, overridden))
|
irClass.addMember(generateDelegatedFunction(irDelegate, delegated, overridden))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,13 +190,16 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
|||||||
irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden, irFunction)
|
irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden, irFunction)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateDelegateFunctionBody(irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor,
|
private fun generateDelegateFunctionBody(
|
||||||
irDelegatedFunction: IrSimpleFunction): IrBlockBodyImpl {
|
irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor,
|
||||||
|
irDelegatedFunction: IrSimpleFunction
|
||||||
|
): IrBlockBodyImpl {
|
||||||
val startOffset = irDelegate.startOffset
|
val startOffset = irDelegate.startOffset
|
||||||
val endOffset = irDelegate.endOffset
|
val endOffset = irDelegate.endOffset
|
||||||
val irBlockBody = IrBlockBodyImpl(startOffset, endOffset)
|
val irBlockBody = IrBlockBodyImpl(startOffset, endOffset)
|
||||||
val returnType = overridden.returnType!!
|
val returnType = overridden.returnType!!
|
||||||
val irCall = IrCallImpl(startOffset, endOffset, returnType, context.symbolTable.referenceFunction(overridden.original), overridden, null)
|
val irCall =
|
||||||
|
IrCallImpl(startOffset, endOffset, returnType, context.symbolTable.referenceFunction(overridden.original), overridden, null)
|
||||||
irCall.dispatchReceiver =
|
irCall.dispatchReceiver =
|
||||||
IrGetFieldImpl(
|
IrGetFieldImpl(
|
||||||
startOffset, endOffset, irDelegate.symbol,
|
startOffset, endOffset, irDelegate.symbol,
|
||||||
@@ -197,8 +216,7 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
|||||||
}
|
}
|
||||||
if (KotlinBuiltIns.isUnit(returnType) || KotlinBuiltIns.isNothing(returnType)) {
|
if (KotlinBuiltIns.isUnit(returnType) || KotlinBuiltIns.isNothing(returnType)) {
|
||||||
irBlockBody.statements.add(irCall)
|
irBlockBody.statements.add(irCall)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val irReturn = IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, irDelegatedFunction.symbol, irCall)
|
val irReturn = IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, irDelegatedFunction.symbol, irCall)
|
||||||
irBlockBody.statements.add(irReturn)
|
irBlockBody.statements.add(irReturn)
|
||||||
}
|
}
|
||||||
@@ -217,7 +235,8 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
|||||||
val classDescriptor = irClass.descriptor
|
val classDescriptor = irClass.descriptor
|
||||||
val primaryConstructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor ?: return null
|
val primaryConstructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor ?: return null
|
||||||
|
|
||||||
val irPrimaryConstructor = FunctionGenerator(declarationGenerator).generatePrimaryConstructor(primaryConstructorDescriptor, ktClassOrObject)
|
val irPrimaryConstructor =
|
||||||
|
FunctionGenerator(declarationGenerator).generatePrimaryConstructor(primaryConstructorDescriptor, ktClassOrObject)
|
||||||
|
|
||||||
if (!DescriptorUtils.isAnnotationClass(classDescriptor)) {
|
if (!DescriptorUtils.isAnnotationClass(classDescriptor)) {
|
||||||
irClass.addMember(irPrimaryConstructor)
|
irClass.addMember(irPrimaryConstructor)
|
||||||
|
|||||||
+13
-11
@@ -100,8 +100,8 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor) {
|
override fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor) {
|
||||||
val ktParameter = DescriptorToSourceUtils.descriptorToDeclaration(parameter) ?:
|
val ktParameter = DescriptorToSourceUtils.descriptorToDeclaration(parameter)
|
||||||
throw AssertionError("No definition for data class constructor parameter $parameter")
|
?: throw AssertionError("No definition for data class constructor parameter $parameter")
|
||||||
|
|
||||||
buildMember(function, ktParameter) {
|
buildMember(function, ktParameter) {
|
||||||
+irReturn(irGet(irThis(), getPropertyGetterSymbol(parameter)))
|
+irReturn(irGet(irThis(), getPropertyGetterSymbol(parameter)))
|
||||||
@@ -117,8 +117,8 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
|||||||
context.symbolTable.referenceFunction(property.getter!!)
|
context.symbolTable.referenceFunction(property.getter!!)
|
||||||
|
|
||||||
override fun generateCopyFunction(function: FunctionDescriptor, constructorParameters: List<KtParameter>) {
|
override fun generateCopyFunction(function: FunctionDescriptor, constructorParameters: List<KtParameter>) {
|
||||||
val dataClassConstructor = classDescriptor.unsubstitutedPrimaryConstructor ?:
|
val dataClassConstructor = classDescriptor.unsubstitutedPrimaryConstructor
|
||||||
throw AssertionError("Data class should have a primary constructor: $classDescriptor")
|
?: throw AssertionError("Data class should have a primary constructor: $classDescriptor")
|
||||||
val constructorSymbol = context.symbolTable.referenceConstructor(dataClassConstructor)
|
val constructorSymbol = context.symbolTable.referenceConstructor(dataClassConstructor)
|
||||||
|
|
||||||
buildMember(function, declaration) { irFunction ->
|
buildMember(function, declaration) { irFunction ->
|
||||||
@@ -138,8 +138,11 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
|||||||
val otherWithCast = irTemporary(irAs(irOther(), classDescriptor.defaultType), "other_with_cast")
|
val otherWithCast = irTemporary(irAs(irOther(), classDescriptor.defaultType), "other_with_cast")
|
||||||
for (property in properties) {
|
for (property in properties) {
|
||||||
+irIfThenReturnFalse(
|
+irIfThenReturnFalse(
|
||||||
irNotEquals(irGet(irThis(), getPropertyGetterSymbol(property)),
|
irNotEquals(
|
||||||
irGet(irGet(otherWithCast.symbol), getPropertyGetterSymbol(property))))
|
irGet(irThis(), getPropertyGetterSymbol(property)),
|
||||||
|
irGet(irGet(otherWithCast.symbol), getPropertyGetterSymbol(property))
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
+irReturnTrue()
|
+irReturnTrue()
|
||||||
}
|
}
|
||||||
@@ -163,9 +166,9 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
|||||||
is ClassDescriptor -> {
|
is ClassDescriptor -> {
|
||||||
if (KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor)) {
|
if (KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor)) {
|
||||||
context.irBuiltIns.dataClassArrayMemberHashCodeSymbol
|
context.irBuiltIns.dataClassArrayMemberHashCodeSymbol
|
||||||
}
|
} else {
|
||||||
else {
|
val hashCodeDescriptor: CallableDescriptor =
|
||||||
val hashCodeDescriptor: CallableDescriptor = typeConstructorDescriptor.findFirstFunction("hashCode") { it.valueParameters.isEmpty() }
|
typeConstructorDescriptor.findFirstFunction("hashCode") { it.valueParameters.isEmpty() }
|
||||||
context.symbolTable.referenceFunction(hashCodeDescriptor)
|
context.symbolTable.referenceFunction(hashCodeDescriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,8 +212,7 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
|||||||
irCall(getHashCodeFunction(irValue.type)).apply {
|
irCall(getHashCodeFunction(irValue.type)).apply {
|
||||||
if (descriptor.dispatchReceiverParameter != null) {
|
if (descriptor.dispatchReceiverParameter != null) {
|
||||||
dispatchReceiver = irValue
|
dispatchReceiver = irValue
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
putValueArgument(0, irValue)
|
putValueArgument(0, irValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -69,8 +69,10 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
|||||||
ClassGenerator(this).generateClass(ktClassOrObject)
|
ClassGenerator(this).generateClass(ktClassOrObject)
|
||||||
|
|
||||||
fun generateTypeAliasDeclaration(ktDeclaration: KtTypeAlias): IrDeclaration =
|
fun generateTypeAliasDeclaration(ktDeclaration: KtTypeAlias): IrDeclaration =
|
||||||
IrTypeAliasImpl(ktDeclaration.startOffset, ktDeclaration.endOffset, IrDeclarationOrigin.DEFINED,
|
IrTypeAliasImpl(
|
||||||
getOrFail(BindingContext.TYPE_ALIAS, ktDeclaration))
|
ktDeclaration.startOffset, ktDeclaration.endOffset, IrDeclarationOrigin.DEFINED,
|
||||||
|
getOrFail(BindingContext.TYPE_ALIAS, ktDeclaration)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
fun generateTypeParameterDeclarations(
|
fun generateTypeParameterDeclarations(
|
||||||
|
|||||||
+27
-9
@@ -105,7 +105,12 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
|||||||
|
|
||||||
private fun getKPropertyTypeForDelegatedProperty(propertyDescriptor: PropertyDescriptor): KotlinType {
|
private fun getKPropertyTypeForDelegatedProperty(propertyDescriptor: PropertyDescriptor): KotlinType {
|
||||||
val receivers = listOfNotNull(propertyDescriptor.extensionReceiverParameter, propertyDescriptor.dispatchReceiverParameter)
|
val receivers = listOfNotNull(propertyDescriptor.extensionReceiverParameter, propertyDescriptor.dispatchReceiverParameter)
|
||||||
return context.reflectionTypes.getKPropertyType(Annotations.EMPTY, receivers.map{ it.type }, propertyDescriptor.type, propertyDescriptor.isVar)
|
return context.reflectionTypes.getKPropertyType(
|
||||||
|
Annotations.EMPTY,
|
||||||
|
receivers.map { it.type },
|
||||||
|
propertyDescriptor.type,
|
||||||
|
propertyDescriptor.isVar
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateDelegateFieldForProperty(
|
private fun generateDelegateFieldForProperty(
|
||||||
@@ -143,17 +148,24 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
|||||||
val provideDelegateCall = statementGenerator.pregenerateCall(provideDelegateResolvedCall)
|
val provideDelegateCall = statementGenerator.pregenerateCall(provideDelegateResolvedCall)
|
||||||
provideDelegateCall.setExplicitReceiverValue(OnceExpressionValue(irDelegateInitializer.expression))
|
provideDelegateCall.setExplicitReceiverValue(OnceExpressionValue(irDelegateInitializer.expression))
|
||||||
provideDelegateCall.irValueArgumentsByIndex[1] = createCallableReference(ktDelegate, kPropertyType, property, scopeOwner)
|
provideDelegateCall.irValueArgumentsByIndex[1] = createCallableReference(ktDelegate, kPropertyType, property, scopeOwner)
|
||||||
val irProvideDelegate = CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, provideDelegateCall)
|
val irProvideDelegate =
|
||||||
|
CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, provideDelegateCall)
|
||||||
return IrExpressionBodyImpl(irProvideDelegate)
|
return IrExpressionBodyImpl(irProvideDelegate)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createBackingFieldValueForDelegate(irDelegateField: IrFieldSymbol, thisClass: ClassDescriptor?, ktDelegate: KtPropertyDelegate): IntermediateValue {
|
private fun createBackingFieldValueForDelegate(
|
||||||
|
irDelegateField: IrFieldSymbol,
|
||||||
|
thisClass: ClassDescriptor?,
|
||||||
|
ktDelegate: KtPropertyDelegate
|
||||||
|
): IntermediateValue {
|
||||||
val thisValue = createThisValueForDelegate(thisClass, ktDelegate)
|
val thisValue = createThisValueForDelegate(thisClass, ktDelegate)
|
||||||
return BackingFieldLValue(ktDelegate.startOffset, ktDelegate.endOffset,
|
return BackingFieldLValue(
|
||||||
|
ktDelegate.startOffset, ktDelegate.endOffset,
|
||||||
irDelegateField.descriptor.type,
|
irDelegateField.descriptor.type,
|
||||||
irDelegateField,
|
irDelegateField,
|
||||||
thisValue,
|
thisValue,
|
||||||
null)
|
null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createThisValueForDelegate(thisClass: ClassDescriptor?, ktDelegate: KtPropertyDelegate): IntermediateValue? =
|
private fun createThisValueForDelegate(thisClass: ClassDescriptor?, ktDelegate: KtPropertyDelegate): IntermediateValue? =
|
||||||
@@ -224,7 +236,7 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
|||||||
irLocalDelegatedProperty.getter =
|
irLocalDelegatedProperty.getter =
|
||||||
createLocalPropertyAccessor(getterDescriptor, ktDelegate) { irGetter ->
|
createLocalPropertyAccessor(getterDescriptor, ktDelegate) { irGetter ->
|
||||||
generateDelegatedPropertyGetterBody(
|
generateDelegatedPropertyGetterBody(
|
||||||
irGetter,ktDelegate, getterDescriptor, delegateReceiverValue,
|
irGetter, ktDelegate, getterDescriptor, delegateReceiverValue,
|
||||||
createLocalDelegatedPropertyReference(
|
createLocalDelegatedPropertyReference(
|
||||||
ktDelegate, kPropertyType,
|
ktDelegate, kPropertyType,
|
||||||
variableDescriptor, irDelegate.symbol,
|
variableDescriptor, irDelegate.symbol,
|
||||||
@@ -293,8 +305,8 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
|||||||
val ktDelegateExpression = ktDelegate.expression!!
|
val ktDelegateExpression = ktDelegate.expression!!
|
||||||
val irDelegateInitializer = createBodyGenerator(scopeOwner).createStatementGenerator().generateExpression(ktDelegateExpression)
|
val irDelegateInitializer = createBodyGenerator(scopeOwner).createStatementGenerator().generateExpression(ktDelegateExpression)
|
||||||
|
|
||||||
val provideDelegateResolvedCall = get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, variableDescriptor) ?:
|
val provideDelegateResolvedCall =
|
||||||
return irDelegateInitializer
|
get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, variableDescriptor) ?: return irDelegateInitializer
|
||||||
|
|
||||||
val statementGenerator = createBodyGenerator(scopeOwner).createStatementGenerator()
|
val statementGenerator = createBodyGenerator(scopeOwner).createStatementGenerator()
|
||||||
|
|
||||||
@@ -356,7 +368,13 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
|||||||
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
||||||
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
|
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
|
||||||
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
|
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
|
||||||
+irReturn(CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, conventionMethodCall))
|
+irReturn(
|
||||||
|
CallGenerator(statementGenerator).generateCall(
|
||||||
|
ktDelegate.startOffset,
|
||||||
|
ktDelegate.endOffset,
|
||||||
|
conventionMethodCall
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -35,9 +35,11 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
|
|||||||
|
|
||||||
fun generateErrorExpression(ktElement: KtElement, e: Exception): IrExpression =
|
fun generateErrorExpression(ktElement: KtElement, e: Exception): IrExpression =
|
||||||
generateErrorExpression(ktElement, e) {
|
generateErrorExpression(ktElement, e) {
|
||||||
IrErrorExpressionImpl(ktElement.startOffset, ktElement.endOffset,
|
IrErrorExpressionImpl(
|
||||||
|
ktElement.startOffset, ktElement.endOffset,
|
||||||
if (ktElement is KtExpression) getErrorExpressionType(ktElement) else ErrorUtils.createErrorType(""),
|
if (ktElement is KtExpression) getErrorExpressionType(ktElement) else ErrorUtils.createErrorType(""),
|
||||||
e.message ?: "")
|
e.message ?: ""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateErrorCall(ktCall: KtCallExpression): IrExpression = generateErrorExpression(ktCall) {
|
fun generateErrorCall(ktCall: KtCallExpression): IrExpression = generateErrorExpression(ktCall) {
|
||||||
|
|||||||
+14
-4
@@ -131,7 +131,11 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
|||||||
else -> throw AssertionError("Should be getter or setter: $accessor")
|
else -> throw AssertionError("Should be getter or setter: $accessor")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateDefaultGetterBody(ktProperty: KtElement, getter: PropertyGetterDescriptor, irAccessor: IrSimpleFunction): IrBlockBody {
|
private fun generateDefaultGetterBody(
|
||||||
|
ktProperty: KtElement,
|
||||||
|
getter: PropertyGetterDescriptor,
|
||||||
|
irAccessor: IrSimpleFunction
|
||||||
|
): IrBlockBody {
|
||||||
val property = getter.correspondingProperty
|
val property = getter.correspondingProperty
|
||||||
|
|
||||||
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
|
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
|
||||||
@@ -152,7 +156,11 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
|||||||
return irBody
|
return irBody
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateDefaultSetterBody(ktProperty: KtElement, setter: PropertySetterDescriptor, irAccessor: IrSimpleFunction): IrBlockBody {
|
private fun generateDefaultSetterBody(
|
||||||
|
ktProperty: KtElement,
|
||||||
|
setter: PropertySetterDescriptor,
|
||||||
|
irAccessor: IrSimpleFunction
|
||||||
|
): IrBlockBody {
|
||||||
val property = setter.correspondingProperty
|
val property = setter.correspondingProperty
|
||||||
|
|
||||||
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
|
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
|
||||||
@@ -175,8 +183,10 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
|||||||
val containingDeclaration = property.containingDeclaration
|
val containingDeclaration = property.containingDeclaration
|
||||||
return when (containingDeclaration) {
|
return when (containingDeclaration) {
|
||||||
is ClassDescriptor ->
|
is ClassDescriptor ->
|
||||||
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset,
|
IrGetValueImpl(
|
||||||
context.symbolTable.referenceValue(containingDeclaration.thisAsReceiverParameter))
|
ktProperty.startOffset, ktProperty.endOffset,
|
||||||
|
context.symbolTable.referenceValue(containingDeclaration.thisAsReceiverParameter)
|
||||||
|
)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,15 +62,21 @@ fun Generator.getResolvedCall(key: KtElement): ResolvedCall<out CallableDescript
|
|||||||
key.getResolvedCall(context.bindingContext)
|
key.getResolvedCall(context.bindingContext)
|
||||||
|
|
||||||
fun Generator.createDummyExpression(ktExpression: KtExpression, description: String): IrErrorExpressionImpl =
|
fun Generator.createDummyExpression(ktExpression: KtExpression, description: String): IrErrorExpressionImpl =
|
||||||
IrErrorExpressionImpl(ktExpression.startOffset, ktExpression.endOffset, getInferredTypeWithImplicitCastsOrFail(ktExpression), description)
|
IrErrorExpressionImpl(
|
||||||
|
ktExpression.startOffset,
|
||||||
|
ktExpression.endOffset,
|
||||||
|
getInferredTypeWithImplicitCastsOrFail(ktExpression),
|
||||||
|
description
|
||||||
|
)
|
||||||
|
|
||||||
inline fun GeneratorWithScope.irBlock(ktElement: KtElement?,
|
inline fun GeneratorWithScope.irBlock(
|
||||||
|
ktElement: KtElement?,
|
||||||
origin: IrStatementOrigin? = null, resultType: KotlinType? = null,
|
origin: IrStatementOrigin? = null, resultType: KotlinType? = null,
|
||||||
body: IrBlockBuilder.() -> Unit
|
body: IrBlockBuilder.() -> Unit
|
||||||
): IrExpression =
|
): IrExpression =
|
||||||
this.irBlock(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, origin, resultType, body)
|
this.irBlock(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, origin, resultType, body)
|
||||||
|
|
||||||
inline fun GeneratorWithScope.irBlockBody(ktElement: KtElement?, body: IrBlockBodyBuilder.() -> Unit) : IrBlockBody =
|
inline fun GeneratorWithScope.irBlockBody(ktElement: KtElement?, body: IrBlockBodyBuilder.() -> Unit): IrBlockBody =
|
||||||
this.irBlockBody(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, body)
|
this.irBlockBody(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, body)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -25,16 +25,17 @@ import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
|
|||||||
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
|
||||||
|
|
||||||
class LocalClassGenerator(statementGenerator: StatementGenerator): StatementGeneratorExtension(statementGenerator) {
|
class LocalClassGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||||
fun generateObjectLiteral(ktObjectLiteral: KtObjectLiteralExpression): IrStatement {
|
fun generateObjectLiteral(ktObjectLiteral: KtObjectLiteralExpression): IrStatement {
|
||||||
val objectLiteralType = getInferredTypeWithImplicitCastsOrFail(ktObjectLiteral)
|
val objectLiteralType = getInferredTypeWithImplicitCastsOrFail(ktObjectLiteral)
|
||||||
val irBlock = IrBlockImpl(ktObjectLiteral.startOffset, ktObjectLiteral.endOffset, objectLiteralType, IrStatementOrigin.OBJECT_LITERAL)
|
val irBlock =
|
||||||
|
IrBlockImpl(ktObjectLiteral.startOffset, ktObjectLiteral.endOffset, objectLiteralType, IrStatementOrigin.OBJECT_LITERAL)
|
||||||
|
|
||||||
val irClass = DeclarationGenerator(statementGenerator.context).generateClassOrObjectDeclaration(ktObjectLiteral.objectDeclaration)
|
val irClass = DeclarationGenerator(statementGenerator.context).generateClassOrObjectDeclaration(ktObjectLiteral.objectDeclaration)
|
||||||
irBlock.statements.add(irClass)
|
irBlock.statements.add(irClass)
|
||||||
|
|
||||||
val objectConstructor = irClass.descriptor.unsubstitutedPrimaryConstructor ?:
|
val objectConstructor = irClass.descriptor.unsubstitutedPrimaryConstructor
|
||||||
throw AssertionError("Object literal should have a primary constructor: ${irClass.descriptor}")
|
?: throw AssertionError("Object literal should have a primary constructor: ${irClass.descriptor}")
|
||||||
assert(objectConstructor.dispatchReceiverParameter == null) {
|
assert(objectConstructor.dispatchReceiverParameter == null) {
|
||||||
"Object literal constructor should have no dispatch receiver parameter: $objectConstructor"
|
"Object literal constructor should have no dispatch receiver parameter: $objectConstructor"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -47,8 +47,7 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
|
|||||||
fun generateFunction(ktFun: KtNamedFunction): IrStatement =
|
fun generateFunction(ktFun: KtNamedFunction): IrStatement =
|
||||||
if (ktFun.name != null) {
|
if (ktFun.name != null) {
|
||||||
generateFunctionDeclaration(ktFun)
|
generateFunctionDeclaration(ktFun)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// anonymous function expression
|
// anonymous function expression
|
||||||
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun)
|
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun)
|
||||||
val irBlock = IrBlockImpl(ktFun.startOffset, ktFun.endOffset, funExpressionType, IrStatementOrigin.ANONYMOUS_FUNCTION)
|
val irBlock = IrBlockImpl(ktFun.startOffset, ktFun.endOffset, funExpressionType, IrStatementOrigin.ANONYMOUS_FUNCTION)
|
||||||
|
|||||||
+23
-15
@@ -29,10 +29,12 @@ import org.jetbrains.kotlin.psi2ir.intermediate.VariableLValue
|
|||||||
import org.jetbrains.kotlin.psi2ir.intermediate.setExplicitReceiverValue
|
import org.jetbrains.kotlin.psi2ir.intermediate.setExplicitReceiverValue
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
class LoopExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator){
|
class LoopExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||||
fun generateWhileLoop(ktWhile: KtWhileExpression): IrExpression {
|
fun generateWhileLoop(ktWhile: KtWhileExpression): IrExpression {
|
||||||
val irLoop = IrWhileLoopImpl(ktWhile.startOffset, ktWhile.endOffset,
|
val irLoop = IrWhileLoopImpl(
|
||||||
context.builtIns.unitType, IrStatementOrigin.WHILE_LOOP)
|
ktWhile.startOffset, ktWhile.endOffset,
|
||||||
|
context.builtIns.unitType, IrStatementOrigin.WHILE_LOOP
|
||||||
|
)
|
||||||
|
|
||||||
irLoop.condition = statementGenerator.generateExpression(ktWhile.condition!!)
|
irLoop.condition = statementGenerator.generateExpression(ktWhile.condition!!)
|
||||||
|
|
||||||
@@ -51,8 +53,10 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun generateDoWhileLoop(ktDoWhile: KtDoWhileExpression): IrExpression {
|
fun generateDoWhileLoop(ktDoWhile: KtDoWhileExpression): IrExpression {
|
||||||
val irLoop = IrDoWhileLoopImpl(ktDoWhile.startOffset, ktDoWhile.endOffset,
|
val irLoop = IrDoWhileLoopImpl(
|
||||||
context.builtIns.unitType, IrStatementOrigin.DO_WHILE_LOOP)
|
ktDoWhile.startOffset, ktDoWhile.endOffset,
|
||||||
|
context.builtIns.unitType, IrStatementOrigin.DO_WHILE_LOOP
|
||||||
|
)
|
||||||
|
|
||||||
statementGenerator.bodyGenerator.putLoop(ktDoWhile, irLoop)
|
statementGenerator.bodyGenerator.putLoop(ktDoWhile, irLoop)
|
||||||
|
|
||||||
@@ -86,18 +90,18 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun generateBreak(ktBreak: KtBreakExpression): IrExpression {
|
fun generateBreak(ktBreak: KtBreakExpression): IrExpression {
|
||||||
val parentLoop = findParentLoop(ktBreak) ?:
|
val parentLoop = findParentLoop(ktBreak) ?: return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
|
||||||
return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
|
ktBreak, RuntimeException("Loop not found for break expression: ${ktBreak.text}")
|
||||||
ktBreak, RuntimeException("Loop not found for break expression: ${ktBreak.text}"))
|
)
|
||||||
return IrBreakImpl(ktBreak.startOffset, ktBreak.endOffset, context.builtIns.nothingType, parentLoop).apply {
|
return IrBreakImpl(ktBreak.startOffset, ktBreak.endOffset, context.builtIns.nothingType, parentLoop).apply {
|
||||||
label = ktBreak.getLabelName()
|
label = ktBreak.getLabelName()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateContinue(ktContinue: KtContinueExpression): IrExpression {
|
fun generateContinue(ktContinue: KtContinueExpression): IrExpression {
|
||||||
val parentLoop = findParentLoop(ktContinue) ?:
|
val parentLoop = findParentLoop(ktContinue) ?: return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
|
||||||
return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
|
ktContinue, RuntimeException("Loop not found for continue expression: ${ktContinue.text}")
|
||||||
ktContinue, RuntimeException("Loop not found for continue expression: ${ktContinue.text}"))
|
)
|
||||||
return IrContinueImpl(ktContinue.startOffset, ktContinue.endOffset, context.builtIns.nothingType, parentLoop).apply {
|
return IrContinueImpl(ktContinue.startOffset, ktContinue.endOffset, context.builtIns.nothingType, parentLoop).apply {
|
||||||
label = ktContinue.getLabelName()
|
label = ktContinue.getLabelName()
|
||||||
}
|
}
|
||||||
@@ -118,8 +122,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
|||||||
}
|
}
|
||||||
if (targetLabel == null) {
|
if (targetLabel == null) {
|
||||||
return getLoop(finger) ?: continue
|
return getLoop(finger) ?: continue
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val parent = finger.parent
|
val parent = finger.parent
|
||||||
if (parent is KtLabeledExpression) {
|
if (parent is KtLabeledExpression) {
|
||||||
val label = parent.getLabelName()!!
|
val label = parent.getLabelName()!!
|
||||||
@@ -159,7 +162,8 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
|||||||
val iteratorValue = VariableLValue(irIterator)
|
val iteratorValue = VariableLValue(irIterator)
|
||||||
irForBlock.statements.add(irIterator)
|
irForBlock.statements.add(irIterator)
|
||||||
|
|
||||||
val irInnerWhile = IrWhileLoopImpl(ktFor.startOffset, ktFor.endOffset, context.builtIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE)
|
val irInnerWhile =
|
||||||
|
IrWhileLoopImpl(ktFor.startOffset, ktFor.endOffset, context.builtIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE)
|
||||||
irInnerWhile.label = getLoopLabel(ktFor)
|
irInnerWhile.label = getLoopLabel(ktFor)
|
||||||
statementGenerator.bodyGenerator.putLoop(ktFor, irInnerWhile)
|
statementGenerator.bodyGenerator.putLoop(ktFor, irInnerWhile)
|
||||||
irForBlock.statements.add(irInnerWhile)
|
irForBlock.statements.add(irInnerWhile)
|
||||||
@@ -187,7 +191,11 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
|||||||
irInnerBody.statements.add(irLoopParameter)
|
irInnerBody.statements.add(irLoopParameter)
|
||||||
|
|
||||||
if (ktLoopDestructuringDeclaration != null) {
|
if (ktLoopDestructuringDeclaration != null) {
|
||||||
statementGenerator.declareComponentVariablesInBlock(ktLoopDestructuringDeclaration, irInnerBody, VariableLValue(irLoopParameter))
|
statementGenerator.declareComponentVariablesInBlock(
|
||||||
|
ktLoopDestructuringDeclaration,
|
||||||
|
irInnerBody,
|
||||||
|
VariableLValue(irLoopParameter)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ktForBody != null) {
|
if (ktForBody != null) {
|
||||||
|
|||||||
+11
-2
@@ -83,8 +83,17 @@ val AUGMENTED_ASSIGNMENTS =
|
|||||||
setOf(IrStatementOrigin.PLUSEQ, IrStatementOrigin.MINUSEQ, IrStatementOrigin.MULTEQ, IrStatementOrigin.DIVEQ, IrStatementOrigin.PERCEQ)
|
setOf(IrStatementOrigin.PLUSEQ, IrStatementOrigin.MINUSEQ, IrStatementOrigin.MULTEQ, IrStatementOrigin.DIVEQ, IrStatementOrigin.PERCEQ)
|
||||||
|
|
||||||
val OPERATORS_DESUGARED_TO_CALLS =
|
val OPERATORS_DESUGARED_TO_CALLS =
|
||||||
setOf(IrStatementOrigin.PLUS, IrStatementOrigin.MINUS, IrStatementOrigin.MUL, IrStatementOrigin.DIV, IrStatementOrigin.PERC, IrStatementOrigin.RANGE,
|
setOf(
|
||||||
IrStatementOrigin.EXCL, IrStatementOrigin.UMINUS, IrStatementOrigin.UPLUS)
|
IrStatementOrigin.PLUS,
|
||||||
|
IrStatementOrigin.MINUS,
|
||||||
|
IrStatementOrigin.MUL,
|
||||||
|
IrStatementOrigin.DIV,
|
||||||
|
IrStatementOrigin.PERC,
|
||||||
|
IrStatementOrigin.RANGE,
|
||||||
|
IrStatementOrigin.EXCL,
|
||||||
|
IrStatementOrigin.UMINUS,
|
||||||
|
IrStatementOrigin.UPLUS
|
||||||
|
)
|
||||||
|
|
||||||
val COMPARISON_OPERATORS =
|
val COMPARISON_OPERATORS =
|
||||||
setOf(IrStatementOrigin.LT, IrStatementOrigin.LTEQ, IrStatementOrigin.GT, IrStatementOrigin.GTEQ)
|
setOf(IrStatementOrigin.LT, IrStatementOrigin.LTEQ, IrStatementOrigin.GT, IrStatementOrigin.GTEQ)
|
||||||
|
|||||||
+40
-18
@@ -44,7 +44,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
|
|
||||||
return when (irOperator) {
|
return when (irOperator) {
|
||||||
null -> throw AssertionError("Unexpected prefix operator: $ktOperator")
|
null -> throw AssertionError("Unexpected prefix operator: $ktOperator")
|
||||||
in INCREMENT_DECREMENT_OPERATORS -> AssignmentGenerator(statementGenerator).generatePrefixIncrementDecrement(expression, irOperator)
|
in INCREMENT_DECREMENT_OPERATORS -> AssignmentGenerator(statementGenerator).generatePrefixIncrementDecrement(
|
||||||
|
expression,
|
||||||
|
irOperator
|
||||||
|
)
|
||||||
in OPERATORS_DESUGARED_TO_CALLS -> generatePrefixOperatorAsCall(expression, irOperator)
|
in OPERATORS_DESUGARED_TO_CALLS -> generatePrefixOperatorAsCall(expression, irOperator)
|
||||||
else -> createDummyExpression(expression, ktOperator.toString())
|
else -> createDummyExpression(expression, ktOperator.toString())
|
||||||
}
|
}
|
||||||
@@ -56,7 +59,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
|
|
||||||
return when (irOperator) {
|
return when (irOperator) {
|
||||||
null -> throw AssertionError("Unexpected postfix operator: $ktOperator")
|
null -> throw AssertionError("Unexpected postfix operator: $ktOperator")
|
||||||
in INCREMENT_DECREMENT_OPERATORS -> AssignmentGenerator(statementGenerator).generatePostfixIncrementDecrement(expression, irOperator)
|
in INCREMENT_DECREMENT_OPERATORS -> AssignmentGenerator(statementGenerator).generatePostfixIncrementDecrement(
|
||||||
|
expression,
|
||||||
|
irOperator
|
||||||
|
)
|
||||||
IrStatementOrigin.EXCLEXCL -> generateExclExclOperator(expression, irOperator)
|
IrStatementOrigin.EXCLEXCL -> generateExclExclOperator(expression, irOperator)
|
||||||
else -> createDummyExpression(expression, ktOperator.toString())
|
else -> createDummyExpression(expression, ktOperator.toString())
|
||||||
}
|
}
|
||||||
@@ -76,8 +82,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
throw AssertionError("Unexpected IrTypeOperator: $irOperator")
|
throw AssertionError("Unexpected IrTypeOperator: $irOperator")
|
||||||
}
|
}
|
||||||
|
|
||||||
return IrTypeOperatorCallImpl(expression.startOffset, expression.endOffset, resultType, irOperator, rhsType,
|
return IrTypeOperatorCallImpl(
|
||||||
statementGenerator.generateExpression(expression.left))
|
expression.startOffset, expression.endOffset, resultType, irOperator, rhsType,
|
||||||
|
statementGenerator.generateExpression(expression.left)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateInstanceOfExpression(expression: KtIsExpression): IrStatement {
|
fun generateInstanceOfExpression(expression: KtIsExpression): IrStatement {
|
||||||
@@ -85,8 +93,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
val irOperator = getIrTypeOperator(ktOperator)!!
|
val irOperator = getIrTypeOperator(ktOperator)!!
|
||||||
val againstType = getOrFail(BindingContext.TYPE, expression.typeReference)
|
val againstType = getOrFail(BindingContext.TYPE, expression.typeReference)
|
||||||
|
|
||||||
return IrTypeOperatorCallImpl(expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator,
|
return IrTypeOperatorCallImpl(
|
||||||
againstType, statementGenerator.generateExpression(expression.leftHandSide))
|
expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator,
|
||||||
|
againstType, statementGenerator.generateExpression(expression.leftHandSide)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateBinaryExpression(expression: KtBinaryExpression): IrExpression {
|
fun generateBinaryExpression(expression: KtBinaryExpression): IrExpression {
|
||||||
@@ -140,15 +150,18 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
private fun generateInOperator(expression: KtBinaryExpression, irOperator: IrStatementOrigin): IrExpression {
|
private fun generateInOperator(expression: KtBinaryExpression, irOperator: IrStatementOrigin): IrExpression {
|
||||||
val containsCall = getResolvedCall(expression)!!
|
val containsCall = getResolvedCall(expression)!!
|
||||||
|
|
||||||
val irContainsCall = CallGenerator(statementGenerator).generateCall(expression, statementGenerator.pregenerateCall(containsCall), irOperator)
|
val irContainsCall =
|
||||||
|
CallGenerator(statementGenerator).generateCall(expression, statementGenerator.pregenerateCall(containsCall), irOperator)
|
||||||
|
|
||||||
return when (irOperator) {
|
return when (irOperator) {
|
||||||
IrStatementOrigin.IN ->
|
IrStatementOrigin.IN ->
|
||||||
irContainsCall
|
irContainsCall
|
||||||
IrStatementOrigin.NOT_IN ->
|
IrStatementOrigin.NOT_IN ->
|
||||||
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.NOT_IN,
|
IrUnaryPrimitiveImpl(
|
||||||
|
expression.startOffset, expression.endOffset, IrStatementOrigin.NOT_IN,
|
||||||
context.irBuiltIns.booleanNotSymbol,
|
context.irBuiltIns.booleanNotSymbol,
|
||||||
irContainsCall)
|
irContainsCall
|
||||||
|
)
|
||||||
else ->
|
else ->
|
||||||
throw AssertionError("Unexpected in-operator $irOperator")
|
throw AssertionError("Unexpected in-operator $irOperator")
|
||||||
}
|
}
|
||||||
@@ -160,17 +173,21 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
val irArgument1 = statementGenerator.generateExpression(expression.right!!)
|
val irArgument1 = statementGenerator.generateExpression(expression.right!!)
|
||||||
|
|
||||||
|
|
||||||
val irIdentityEquals = IrBinaryPrimitiveImpl(expression.startOffset, expression.endOffset, irOperator,
|
val irIdentityEquals = IrBinaryPrimitiveImpl(
|
||||||
|
expression.startOffset, expression.endOffset, irOperator,
|
||||||
context.irBuiltIns.eqeqeqSymbol,
|
context.irBuiltIns.eqeqeqSymbol,
|
||||||
irArgument0, irArgument1)
|
irArgument0, irArgument1
|
||||||
|
)
|
||||||
|
|
||||||
return when (irOperator) {
|
return when (irOperator) {
|
||||||
IrStatementOrigin.EQEQEQ ->
|
IrStatementOrigin.EQEQEQ ->
|
||||||
irIdentityEquals
|
irIdentityEquals
|
||||||
IrStatementOrigin.EXCLEQEQ ->
|
IrStatementOrigin.EXCLEQEQ ->
|
||||||
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQEQ,
|
IrUnaryPrimitiveImpl(
|
||||||
|
expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQEQ,
|
||||||
context.irBuiltIns.booleanNotSymbol,
|
context.irBuiltIns.booleanNotSymbol,
|
||||||
irIdentityEquals)
|
irIdentityEquals
|
||||||
|
)
|
||||||
else ->
|
else ->
|
||||||
throw AssertionError("Unexpected identity operator $irOperator")
|
throw AssertionError("Unexpected identity operator $irOperator")
|
||||||
}
|
}
|
||||||
@@ -181,18 +198,22 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
val irArgument0 = statementGenerator.generateExpression(expression.left!!)
|
val irArgument0 = statementGenerator.generateExpression(expression.left!!)
|
||||||
val irArgument1 = statementGenerator.generateExpression(expression.right!!)
|
val irArgument1 = statementGenerator.generateExpression(expression.right!!)
|
||||||
|
|
||||||
val irEquals = IrBinaryPrimitiveImpl(expression.startOffset, expression.endOffset,
|
val irEquals = IrBinaryPrimitiveImpl(
|
||||||
|
expression.startOffset, expression.endOffset,
|
||||||
irOperator,
|
irOperator,
|
||||||
context.irBuiltIns.eqeqSymbol,
|
context.irBuiltIns.eqeqSymbol,
|
||||||
irArgument0, irArgument1)
|
irArgument0, irArgument1
|
||||||
|
)
|
||||||
|
|
||||||
return when (irOperator) {
|
return when (irOperator) {
|
||||||
IrStatementOrigin.EQEQ ->
|
IrStatementOrigin.EQEQ ->
|
||||||
irEquals
|
irEquals
|
||||||
IrStatementOrigin.EXCLEQ ->
|
IrStatementOrigin.EXCLEQ ->
|
||||||
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQ,
|
IrUnaryPrimitiveImpl(
|
||||||
|
expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQ,
|
||||||
context.irBuiltIns.booleanNotSymbol,
|
context.irBuiltIns.booleanNotSymbol,
|
||||||
irEquals)
|
irEquals
|
||||||
|
)
|
||||||
else ->
|
else ->
|
||||||
throw AssertionError("Unexpected equality operator $irOperator")
|
throw AssertionError("Unexpected equality operator $irOperator")
|
||||||
}
|
}
|
||||||
@@ -202,7 +223,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
private fun generateComparisonOperator(expression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
|
private fun generateComparisonOperator(expression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
|
||||||
val compareToCall = getResolvedCall(expression)!!
|
val compareToCall = getResolvedCall(expression)!!
|
||||||
|
|
||||||
val irCompareToCall = CallGenerator(statementGenerator).generateCall(expression, statementGenerator.pregenerateCall(compareToCall), origin)
|
val irCompareToCall =
|
||||||
|
CallGenerator(statementGenerator).generateCall(expression, statementGenerator.pregenerateCall(compareToCall), origin)
|
||||||
|
|
||||||
val compareToZeroSymbol = when (origin) {
|
val compareToZeroSymbol = when (origin) {
|
||||||
IrStatementOrigin.LT -> context.irBuiltIns.lt0Symbol
|
IrStatementOrigin.LT -> context.irBuiltIns.lt0Symbol
|
||||||
|
|||||||
+13
-9
@@ -51,21 +51,25 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
|||||||
).also { irProperty ->
|
).also { irProperty ->
|
||||||
irProperty.backingField =
|
irProperty.backingField =
|
||||||
generatePropertyBackingField(ktParameter, propertyDescriptor) {
|
generatePropertyBackingField(ktParameter, propertyDescriptor) {
|
||||||
IrExpressionBodyImpl(IrGetValueImpl(
|
IrExpressionBodyImpl(
|
||||||
|
IrGetValueImpl(
|
||||||
ktParameter.startOffset, ktParameter.endOffset,
|
ktParameter.startOffset, ktParameter.endOffset,
|
||||||
irValueParameter.symbol,
|
irValueParameter.symbol,
|
||||||
IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
|
IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val getter = propertyDescriptor.getter ?:
|
val getter = propertyDescriptor.getter
|
||||||
throw AssertionError("Property declared in primary constructor has no getter: $propertyDescriptor")
|
?: throw AssertionError("Property declared in primary constructor has no getter: $propertyDescriptor")
|
||||||
irProperty.getter = FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(getter, ktParameter)
|
irProperty.getter =
|
||||||
|
FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(getter, ktParameter)
|
||||||
|
|
||||||
if (propertyDescriptor.isVar) {
|
if (propertyDescriptor.isVar) {
|
||||||
val setter = propertyDescriptor.setter ?:
|
val setter = propertyDescriptor.setter
|
||||||
throw AssertionError("Property declared in primary constructor has no setter: $propertyDescriptor")
|
?: throw AssertionError("Property declared in primary constructor has no setter: $propertyDescriptor")
|
||||||
irProperty.setter = FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(setter, ktParameter)
|
irProperty.setter =
|
||||||
|
FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(setter, ktParameter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,7 +78,7 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
|||||||
ktPropertyElement: KtElement,
|
ktPropertyElement: KtElement,
|
||||||
propertyDescriptor: PropertyDescriptor,
|
propertyDescriptor: PropertyDescriptor,
|
||||||
generateInitializer: (IrField) -> IrExpressionBody?
|
generateInitializer: (IrField) -> IrExpressionBody?
|
||||||
) : IrField =
|
): IrField =
|
||||||
context.symbolTable.declareField(
|
context.symbolTable.declareField(
|
||||||
ktPropertyElement.startOffset, ktPropertyElement.endOffset,
|
ktPropertyElement.startOffset, ktPropertyElement.endOffset,
|
||||||
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
|
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
|
||||||
|
|||||||
+13
-10
@@ -37,15 +37,18 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
|||||||
val resultType = getInferredTypeWithImplicitCastsOrFail(ktClassLiteral)
|
val resultType = getInferredTypeWithImplicitCastsOrFail(ktClassLiteral)
|
||||||
|
|
||||||
return if (lhs is DoubleColonLHS.Expression && !lhs.isObjectQualifier) {
|
return if (lhs is DoubleColonLHS.Expression && !lhs.isObjectQualifier) {
|
||||||
IrGetClassImpl(ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
|
IrGetClassImpl(
|
||||||
statementGenerator.generateExpression(ktArgument))
|
ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
|
||||||
}
|
statementGenerator.generateExpression(ktArgument)
|
||||||
else {
|
)
|
||||||
|
} else {
|
||||||
val typeConstructorDeclaration = lhs.type.constructor.declarationDescriptor
|
val typeConstructorDeclaration = lhs.type.constructor.declarationDescriptor
|
||||||
val typeClass = typeConstructorDeclaration ?:
|
val typeClass = typeConstructorDeclaration
|
||||||
throw AssertionError("Unexpected type constructor for ${lhs.type}: $typeConstructorDeclaration")
|
?: throw AssertionError("Unexpected type constructor for ${lhs.type}: $typeConstructorDeclaration")
|
||||||
IrClassReferenceImpl(ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
|
IrClassReferenceImpl(
|
||||||
context.symbolTable.referenceClassifier(typeClass), lhs.type)
|
ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
|
||||||
|
context.symbolTable.referenceClassifier(typeClass), lhs.type
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,8 +111,8 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
|||||||
irDelegateSymbol: IrVariableSymbol,
|
irDelegateSymbol: IrVariableSymbol,
|
||||||
origin: IrStatementOrigin?
|
origin: IrStatementOrigin?
|
||||||
): IrLocalDelegatedPropertyReference {
|
): IrLocalDelegatedPropertyReference {
|
||||||
val getterDescriptor = variableDescriptor.getter ?:
|
val getterDescriptor =
|
||||||
throw AssertionError("Local delegated property should have a getter: $variableDescriptor")
|
variableDescriptor.getter ?: throw AssertionError("Local delegated property should have a getter: $variableDescriptor")
|
||||||
val setterDescriptor = variableDescriptor.setter
|
val setterDescriptor = variableDescriptor.setter
|
||||||
|
|
||||||
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor)
|
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor)
|
||||||
|
|||||||
+55
-30
@@ -63,8 +63,7 @@ class StatementGenerator(
|
|||||||
private fun KtElement.genStmt(): IrStatement =
|
private fun KtElement.genStmt(): IrStatement =
|
||||||
try {
|
try {
|
||||||
deparenthesize().accept(this@StatementGenerator, null)
|
deparenthesize().accept(this@StatementGenerator, null)
|
||||||
}
|
} catch (e: Exception) {
|
||||||
catch (e: Exception) {
|
|
||||||
ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(this, e)
|
ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(this, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,8 +77,10 @@ class StatementGenerator(
|
|||||||
val variableDescriptor = getOrFail(BindingContext.VARIABLE, property)
|
val variableDescriptor = getOrFail(BindingContext.VARIABLE, property)
|
||||||
|
|
||||||
property.delegate?.let { ktDelegate ->
|
property.delegate?.let { ktDelegate ->
|
||||||
return generateLocalDelegatedProperty(property, ktDelegate, variableDescriptor as VariableDescriptorWithAccessors,
|
return generateLocalDelegatedProperty(
|
||||||
bodyGenerator.scopeOwnerSymbol)
|
property, ktDelegate, variableDescriptor as VariableDescriptorWithAccessors,
|
||||||
|
bodyGenerator.scopeOwnerSymbol
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return context.symbolTable.declareVariable(
|
return context.symbolTable.declareVariable(
|
||||||
@@ -98,8 +99,10 @@ class StatementGenerator(
|
|||||||
.generateLocalDelegatedProperty(ktProperty, ktDelegate, variableDescriptor, scopeOwnerSymbol)
|
.generateLocalDelegatedProperty(ktProperty, ktDelegate, variableDescriptor, scopeOwnerSymbol)
|
||||||
|
|
||||||
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement {
|
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement {
|
||||||
val irBlock = IrCompositeImpl(multiDeclaration.startOffset, multiDeclaration.endOffset,
|
val irBlock = IrCompositeImpl(
|
||||||
context.builtIns.unitType, IrStatementOrigin.DESTRUCTURING_DECLARATION)
|
multiDeclaration.startOffset, multiDeclaration.endOffset,
|
||||||
|
context.builtIns.unitType, IrStatementOrigin.DESTRUCTURING_DECLARATION
|
||||||
|
)
|
||||||
val ktInitializer = multiDeclaration.initializer!!
|
val ktInitializer = multiDeclaration.initializer!!
|
||||||
val containerValue = scope.createTemporaryVariableInBlock(ktInitializer.genExpr(), irBlock, "container")
|
val containerValue = scope.createTemporaryVariableInBlock(ktInitializer.genExpr(), irBlock, "container")
|
||||||
|
|
||||||
@@ -108,7 +111,11 @@ class StatementGenerator(
|
|||||||
return irBlock
|
return irBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
fun declareComponentVariablesInBlock(multiDeclaration: KtDestructuringDeclaration, irBlock: IrStatementContainer, containerValue: IntermediateValue) {
|
fun declareComponentVariablesInBlock(
|
||||||
|
multiDeclaration: KtDestructuringDeclaration,
|
||||||
|
irBlock: IrStatementContainer,
|
||||||
|
containerValue: IntermediateValue
|
||||||
|
) {
|
||||||
val callGenerator = CallGenerator(this)
|
val callGenerator = CallGenerator(this)
|
||||||
for ((index, ktEntry) in multiDeclaration.entries.withIndex()) {
|
for ((index, ktEntry) in multiDeclaration.entries.withIndex()) {
|
||||||
val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry)
|
val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry)
|
||||||
@@ -121,8 +128,10 @@ class StatementGenerator(
|
|||||||
// componentN for '_' SHOULD NOT be evaluated
|
// componentN for '_' SHOULD NOT be evaluated
|
||||||
if (componentVariable.name.isSpecial) continue
|
if (componentVariable.name.isSpecial) continue
|
||||||
|
|
||||||
val irComponentCall = callGenerator.generateCall(ktEntry.startOffset, ktEntry.endOffset, componentSubstitutedCall,
|
val irComponentCall = callGenerator.generateCall(
|
||||||
IrStatementOrigin.COMPONENT_N.withIndex(index + 1))
|
ktEntry.startOffset, ktEntry.endOffset, componentSubstitutedCall,
|
||||||
|
IrStatementOrigin.COMPONENT_N.withIndex(index + 1)
|
||||||
|
)
|
||||||
val irComponentVar = context.symbolTable.declareVariable(
|
val irComponentVar = context.symbolTable.declareVariable(
|
||||||
ktEntry.startOffset, ktEntry.endOffset, IrDeclarationOrigin.DEFINED,
|
ktEntry.startOffset, ktEntry.endOffset, IrDeclarationOrigin.DEFINED,
|
||||||
componentVariable, irComponentCall
|
componentVariable, irComponentCall
|
||||||
@@ -147,11 +156,14 @@ class StatementGenerator(
|
|||||||
|
|
||||||
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrStatement {
|
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrStatement {
|
||||||
val returnTarget = getReturnExpressionTarget(expression)
|
val returnTarget = getReturnExpressionTarget(expression)
|
||||||
val irReturnedExpression = expression.returnedExpression?.genExpr() ?:
|
val irReturnedExpression = expression.returnedExpression?.genExpr() ?: IrGetObjectValueImpl(
|
||||||
IrGetObjectValueImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType,
|
expression.startOffset, expression.endOffset, context.builtIns.unitType,
|
||||||
context.symbolTable.referenceClass(context.builtIns.unit))
|
context.symbolTable.referenceClass(context.builtIns.unit)
|
||||||
return IrReturnImpl(expression.startOffset, expression.endOffset, context.builtIns.nothingType,
|
)
|
||||||
context.symbolTable.referenceFunction(returnTarget), irReturnedExpression)
|
return IrReturnImpl(
|
||||||
|
expression.startOffset, expression.endOffset, context.builtIns.nothingType,
|
||||||
|
context.symbolTable.referenceFunction(returnTarget), irReturnedExpression
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scopeOwnerAsCallable() =
|
private fun scopeOwnerAsCallable() =
|
||||||
@@ -160,8 +172,7 @@ class StatementGenerator(
|
|||||||
private fun getReturnExpressionTarget(expression: KtReturnExpression): CallableDescriptor =
|
private fun getReturnExpressionTarget(expression: KtReturnExpression): CallableDescriptor =
|
||||||
if (!ExpressionTypingUtils.isFunctionLiteral(scopeOwner) && !ExpressionTypingUtils.isFunctionExpression(scopeOwner)) {
|
if (!ExpressionTypingUtils.isFunctionLiteral(scopeOwner) && !ExpressionTypingUtils.isFunctionExpression(scopeOwner)) {
|
||||||
scopeOwnerAsCallable()
|
scopeOwnerAsCallable()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val label = expression.getTargetLabel()
|
val label = expression.getTargetLabel()
|
||||||
when {
|
when {
|
||||||
label != null -> {
|
label != null -> {
|
||||||
@@ -179,13 +190,20 @@ class StatementGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitThrowExpression(expression: KtThrowExpression, data: Nothing?): IrStatement {
|
override fun visitThrowExpression(expression: KtThrowExpression, data: Nothing?): IrStatement {
|
||||||
return IrThrowImpl(expression.startOffset, expression.endOffset, context.builtIns.nothingType, expression.thrownExpression!!.genExpr())
|
return IrThrowImpl(
|
||||||
|
expression.startOffset,
|
||||||
|
expression.endOffset,
|
||||||
|
context.builtIns.nothingType,
|
||||||
|
expression.thrownExpression!!.genExpr()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression =
|
override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression =
|
||||||
generateConstantExpression(expression,
|
generateConstantExpression(
|
||||||
ConstantExpressionEvaluator.getConstant(expression, context.bindingContext) ?:
|
expression,
|
||||||
error("KtConstantExpression was not evaluated: ${expression.text}"))
|
ConstantExpressionEvaluator.getConstant(expression, context.bindingContext)
|
||||||
|
?: error("KtConstantExpression was not evaluated: ${expression.text}")
|
||||||
|
)
|
||||||
|
|
||||||
fun generateConstantExpression(expression: KtExpression, constant: CompileTimeConstant<*>): IrExpression {
|
fun generateConstantExpression(expression: KtExpression, constant: CompileTimeConstant<*>): IrExpression {
|
||||||
val constantValue = constant.toConstantValue(getInferredTypeWithImplicitCastsOrFail(expression))
|
val constantValue = constant.toConstantValue(getInferredTypeWithImplicitCastsOrFail(expression))
|
||||||
@@ -277,8 +295,7 @@ class StatementGenerator(
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun visitCallExpression(expression: KtCallExpression, data: Nothing?): IrStatement {
|
override fun visitCallExpression(expression: KtCallExpression, data: Nothing?): IrStatement {
|
||||||
val resolvedCall = getResolvedCall(expression) ?:
|
val resolvedCall = getResolvedCall(expression) ?: return ErrorExpressionGenerator(this).generateErrorCall(expression)
|
||||||
return ErrorExpressionGenerator(this).generateErrorCall(expression)
|
|
||||||
|
|
||||||
if (resolvedCall is VariableAsFunctionResolvedCall) {
|
if (resolvedCall is VariableAsFunctionResolvedCall) {
|
||||||
val functionCall = pregenerateCall(resolvedCall.functionCall)
|
val functionCall = pregenerateCall(resolvedCall.functionCall)
|
||||||
@@ -291,8 +308,10 @@ class StatementGenerator(
|
|||||||
override fun visitArrayAccessExpression(expression: KtArrayAccessExpression, data: Nothing?): IrStatement {
|
override fun visitArrayAccessExpression(expression: KtArrayAccessExpression, data: Nothing?): IrStatement {
|
||||||
val indexedGetCall = getOrFail(BindingContext.INDEXED_LVALUE_GET, expression)
|
val indexedGetCall = getOrFail(BindingContext.INDEXED_LVALUE_GET, expression)
|
||||||
|
|
||||||
return CallGenerator(this).generateCall(expression.startOffset, expression.endOffset,
|
return CallGenerator(this).generateCall(
|
||||||
pregenerateCall(indexedGetCall), IrStatementOrigin.GET_ARRAY_ELEMENT)
|
expression.startOffset, expression.endOffset,
|
||||||
|
pregenerateCall(indexedGetCall), IrStatementOrigin.GET_ARRAY_ELEMENT
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression, data: Nothing?): IrStatement =
|
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression, data: Nothing?): IrStatement =
|
||||||
@@ -305,12 +324,16 @@ class StatementGenerator(
|
|||||||
val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" }
|
val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" }
|
||||||
return when (referenceTarget) {
|
return when (referenceTarget) {
|
||||||
is ClassDescriptor ->
|
is ClassDescriptor ->
|
||||||
IrGetValueImpl(expression.startOffset, expression.endOffset,
|
IrGetValueImpl(
|
||||||
context.symbolTable.referenceValueParameter(referenceTarget.thisAsReceiverParameter))
|
expression.startOffset, expression.endOffset,
|
||||||
|
context.symbolTable.referenceValueParameter(referenceTarget.thisAsReceiverParameter)
|
||||||
|
)
|
||||||
is CallableDescriptor -> {
|
is CallableDescriptor -> {
|
||||||
val extensionReceiver = referenceTarget.extensionReceiverParameter ?: TODO("No extension receiver: $referenceTarget")
|
val extensionReceiver = referenceTarget.extensionReceiverParameter ?: TODO("No extension receiver: $referenceTarget")
|
||||||
IrGetValueImpl(expression.startOffset, expression.endOffset,
|
IrGetValueImpl(
|
||||||
context.symbolTable.referenceValueParameter(extensionReceiver))
|
expression.startOffset, expression.endOffset,
|
||||||
|
context.symbolTable.referenceValueParameter(extensionReceiver)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
else ->
|
else ->
|
||||||
error("Expected this or receiver: $referenceTarget")
|
error("Expected this or receiver: $referenceTarget")
|
||||||
@@ -369,8 +392,10 @@ class StatementGenerator(
|
|||||||
LocalClassGenerator(this).generateLocalClass(classOrObject)
|
LocalClassGenerator(this).generateLocalClass(classOrObject)
|
||||||
|
|
||||||
override fun visitTypeAlias(typeAlias: KtTypeAlias, data: Nothing?): IrStatement =
|
override fun visitTypeAlias(typeAlias: KtTypeAlias, data: Nothing?): IrStatement =
|
||||||
IrTypeAliasImpl(typeAlias.startOffset, typeAlias.endOffset, IrDeclarationOrigin.DEFINED,
|
IrTypeAliasImpl(
|
||||||
getOrFail(BindingContext.TYPE_ALIAS, typeAlias))
|
typeAlias.startOffset, typeAlias.endOffset, IrDeclarationOrigin.DEFINED,
|
||||||
|
getOrFail(BindingContext.TYPE_ALIAS, typeAlias)
|
||||||
|
)
|
||||||
|
|
||||||
override fun visitClassLiteralExpression(expression: KtClassLiteralExpression, data: Nothing?): IrStatement =
|
override fun visitClassLiteralExpression(expression: KtClassLiteralExpression, data: Nothing?): IrStatement =
|
||||||
ReflectionReferencesGenerator(this).generateClassLiteral(expression)
|
ReflectionReferencesGenerator(this).generateClassLiteral(expression)
|
||||||
|
|||||||
+1
-1
@@ -51,7 +51,7 @@ class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
irTryCatch.catches.add(irCatch)
|
irTryCatch.catches.add(irCatch)
|
||||||
}
|
}
|
||||||
|
|
||||||
irTryCatch.finallyExpression = ktTry.finallyBlock?.let{ statementGenerator.generateExpression(it.finalExpression) }
|
irTryCatch.finallyExpression = ktTry.finallyBlock?.let { statementGenerator.generateExpression(it.finalExpression) }
|
||||||
|
|
||||||
return irTryCatch
|
return irTryCatch
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -35,9 +35,9 @@ class ArrayAccessAssignmentReceiver(
|
|||||||
val endOffset: Int,
|
val endOffset: Int,
|
||||||
val origin: IrStatementOrigin
|
val origin: IrStatementOrigin
|
||||||
) : AssignmentReceiver {
|
) : AssignmentReceiver {
|
||||||
private val type: KotlinType = indexedGetCall?.run { descriptor.returnType!! } ?:
|
private val type: KotlinType =
|
||||||
indexedSetCall?.run { descriptor.valueParameters.last().type } ?:
|
indexedGetCall?.run { descriptor.returnType!! } ?: indexedSetCall?.run { descriptor.valueParameters.last().type }
|
||||||
throw AssertionError("Array access should have either indexed-get call or indexed-set call")
|
?: throw AssertionError("Array access should have either indexed-get call or indexed-set call")
|
||||||
|
|
||||||
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression {
|
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression {
|
||||||
val hasResult = origin.isAssignmentOperatorWithResult()
|
val hasResult = origin.isAssignmentOperatorWithResult()
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ class CallBuilder(
|
|||||||
irValueArgumentsByIndex[valueParameterDescriptor.index + parametersOffset]
|
irValueArgumentsByIndex[valueParameterDescriptor.index + parametersOffset]
|
||||||
}
|
}
|
||||||
|
|
||||||
val CallBuilder.argumentsCount: Int get() =
|
val CallBuilder.argumentsCount: Int
|
||||||
|
get() =
|
||||||
irValueArgumentsByIndex.size
|
irValueArgumentsByIndex.size
|
||||||
|
|
||||||
var CallBuilder.lastArgument: IrExpression?
|
var CallBuilder.lastArgument: IrExpression?
|
||||||
@@ -57,22 +58,28 @@ fun CallBuilder.getValueArgumentsInParameterOrder(): List<IrExpression?> =
|
|||||||
fun CallBuilder.isValueArgumentReorderingRequired() =
|
fun CallBuilder.isValueArgumentReorderingRequired() =
|
||||||
original.isValueArgumentReorderingRequired()
|
original.isValueArgumentReorderingRequired()
|
||||||
|
|
||||||
val CallBuilder.hasExtensionReceiver: Boolean get() =
|
val CallBuilder.hasExtensionReceiver: Boolean
|
||||||
|
get() =
|
||||||
descriptor.extensionReceiverParameter != null
|
descriptor.extensionReceiverParameter != null
|
||||||
|
|
||||||
val CallBuilder.hasDispatchReceiver: Boolean get() =
|
val CallBuilder.hasDispatchReceiver: Boolean
|
||||||
|
get() =
|
||||||
descriptor.dispatchReceiverParameter != null
|
descriptor.dispatchReceiverParameter != null
|
||||||
|
|
||||||
val CallBuilder.extensionReceiverType: KotlinType? get() =
|
val CallBuilder.extensionReceiverType: KotlinType?
|
||||||
|
get() =
|
||||||
descriptor.extensionReceiverParameter?.type
|
descriptor.extensionReceiverParameter?.type
|
||||||
|
|
||||||
val CallBuilder.dispatchReceiverType: KotlinType? get() =
|
val CallBuilder.dispatchReceiverType: KotlinType?
|
||||||
|
get() =
|
||||||
descriptor.dispatchReceiverParameter?.type
|
descriptor.dispatchReceiverParameter?.type
|
||||||
|
|
||||||
val CallBuilder.explicitReceiverParameter: ReceiverParameterDescriptor? get() =
|
val CallBuilder.explicitReceiverParameter: ReceiverParameterDescriptor?
|
||||||
|
get() =
|
||||||
descriptor.extensionReceiverParameter ?: descriptor.dispatchReceiverParameter
|
descriptor.extensionReceiverParameter ?: descriptor.dispatchReceiverParameter
|
||||||
|
|
||||||
val CallBuilder.explicitReceiverType: KotlinType? get() =
|
val CallBuilder.explicitReceiverType: KotlinType?
|
||||||
|
get() =
|
||||||
explicitReceiverParameter?.type
|
explicitReceiverParameter?.type
|
||||||
|
|
||||||
fun CallBuilder.setExplicitReceiverValue(explicitReceiverValue: IntermediateValue) {
|
fun CallBuilder.setExplicitReceiverValue(explicitReceiverValue: IntermediateValue) {
|
||||||
|
|||||||
+2
-3
@@ -32,9 +32,8 @@ class LValueWithGetterAndSetterCalls(
|
|||||||
val origin: IrStatementOrigin? = null
|
val origin: IrStatementOrigin? = null
|
||||||
) : LValue {
|
) : LValue {
|
||||||
private val descriptor: CallableDescriptor =
|
private val descriptor: CallableDescriptor =
|
||||||
getterCall?.descriptor ?:
|
getterCall?.descriptor ?: setterCall?.descriptor
|
||||||
setterCall?.descriptor ?:
|
?: throw AssertionError("Call-based LValue should have either a getter or a setter call")
|
||||||
throw AssertionError("Call-based LValue should have either a getter or a setter call")
|
|
||||||
|
|
||||||
override fun load(): IrExpression {
|
override fun load(): IrExpression {
|
||||||
if (getterCall == null) throw AssertionError("No getter call for $descriptor")
|
if (getterCall == null) throw AssertionError("No getter call for $descriptor")
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class OnceCallValue(
|
|||||||
val statementGenerator: StatementGenerator,
|
val statementGenerator: StatementGenerator,
|
||||||
val call: CallBuilder,
|
val call: CallBuilder,
|
||||||
val origin: IrStatementOrigin? = null
|
val origin: IrStatementOrigin? = null
|
||||||
): IntermediateValue {
|
) : IntermediateValue {
|
||||||
private var instantiated = false
|
private var instantiated = false
|
||||||
|
|
||||||
override fun load(): IrExpression {
|
override fun load(): IrExpression {
|
||||||
|
|||||||
+5
-1
@@ -28,7 +28,11 @@ class RematerializableValue(val irExpression: IrExpressionWithCopy) : Intermedia
|
|||||||
override fun load(): IrExpression = irExpression.copy()
|
override fun load(): IrExpression = irExpression.copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Scope.createTemporaryVariableInBlock(irExpression: IrExpression, block: IrContainerExpressionBase, nameHint: String? = null): IntermediateValue {
|
fun Scope.createTemporaryVariableInBlock(
|
||||||
|
irExpression: IrExpression,
|
||||||
|
block: IrContainerExpressionBase,
|
||||||
|
nameHint: String? = null
|
||||||
|
): IntermediateValue {
|
||||||
val temporaryVariable = createTemporaryVariable(irExpression, nameHint)
|
val temporaryVariable = createTemporaryVariable(irExpression, nameHint)
|
||||||
block.statements.add(temporaryVariable)
|
block.statements.add(temporaryVariable)
|
||||||
return VariableLValue(temporaryVariable)
|
return VariableLValue(temporaryVariable)
|
||||||
|
|||||||
+5
-4
@@ -44,8 +44,7 @@ class SafeCallReceiver(
|
|||||||
if (extensionReceiver != null) {
|
if (extensionReceiver != null) {
|
||||||
dispatchReceiverValue = dispatchReceiver
|
dispatchReceiverValue = dispatchReceiver
|
||||||
extensionReceiverValue = safeReceiverValue
|
extensionReceiverValue = safeReceiverValue
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
dispatchReceiverValue = safeReceiverValue
|
dispatchReceiverValue = safeReceiverValue
|
||||||
extensionReceiverValue = null
|
extensionReceiverValue = null
|
||||||
}
|
}
|
||||||
@@ -57,11 +56,13 @@ class SafeCallReceiver(
|
|||||||
|
|
||||||
irBlock.statements.add(irTmp)
|
irBlock.statements.add(irTmp)
|
||||||
|
|
||||||
val irIfThenElse = IrIfThenElseImpl(startOffset, endOffset, resultType,
|
val irIfThenElse = IrIfThenElseImpl(
|
||||||
|
startOffset, endOffset, resultType,
|
||||||
generator.context.equalsNull(startOffset, endOffset, safeReceiverValue.load()),
|
generator.context.equalsNull(startOffset, endOffset, safeReceiverValue.load()),
|
||||||
generator.context.constNull(startOffset, endOffset),
|
generator.context.constNull(startOffset, endOffset),
|
||||||
irResult,
|
irResult,
|
||||||
IrStatementOrigin.SAFE_CALL)
|
IrStatementOrigin.SAFE_CALL
|
||||||
|
)
|
||||||
irBlock.statements.add(irIfThenElse)
|
irBlock.statements.add(irIfThenElse)
|
||||||
|
|
||||||
return irBlock
|
return irBlock
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.psi2ir.intermediate
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class TransientReceiverValue(override val type: KotlinType): IntermediateValue {
|
class TransientReceiverValue(override val type: KotlinType) : IntermediateValue {
|
||||||
override fun load(): IrExpression {
|
override fun load(): IrExpression {
|
||||||
throw AssertionError("Transient receiver should not be instantiated")
|
throw AssertionError("Transient receiver should not be instantiated")
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -33,7 +33,8 @@ class VariableLValue(
|
|||||||
val origin: IrStatementOrigin? = null
|
val origin: IrStatementOrigin? = null
|
||||||
) : LValue, AssignmentReceiver {
|
) : LValue, AssignmentReceiver {
|
||||||
constructor(irVariable: IrVariable, origin: IrStatementOrigin? = null) : this(
|
constructor(irVariable: IrVariable, origin: IrStatementOrigin? = null) : this(
|
||||||
irVariable.startOffset, irVariable.endOffset, irVariable.symbol, origin)
|
irVariable.startOffset, irVariable.endOffset, irVariable.symbol, origin
|
||||||
|
)
|
||||||
|
|
||||||
override val type: KotlinType get() = symbol.descriptor.type
|
override val type: KotlinType get() = symbol.descriptor.type
|
||||||
|
|
||||||
|
|||||||
+13
-10
@@ -17,8 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.psi2ir.transformations
|
package org.jetbrains.kotlin.psi2ir.transformations
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.isBuiltinExtensionFunctionalType
|
|
||||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||||
@@ -27,7 +25,6 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable
|
|||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
|
||||||
import org.jetbrains.kotlin.psi2ir.containsNull
|
import org.jetbrains.kotlin.psi2ir.containsNull
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
@@ -40,7 +37,7 @@ fun insertImplicitCasts(builtIns: KotlinBuiltIns, element: IrElement) {
|
|||||||
element.transformChildren(InsertImplicitCasts(builtIns), null)
|
element.transformChildren(InsertImplicitCasts(builtIns), null)
|
||||||
}
|
}
|
||||||
|
|
||||||
class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoid() {
|
class InsertImplicitCasts(val builtIns: KotlinBuiltIns) : IrElementTransformerVoid() {
|
||||||
override fun visitCallableReference(expression: IrCallableReference): IrExpression =
|
override fun visitCallableReference(expression: IrCallableReference): IrExpression =
|
||||||
expression.transformPostfix {
|
expression.transformPostfix {
|
||||||
transformReceiverArguments()
|
transformReceiverArguments()
|
||||||
@@ -185,11 +182,15 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoi
|
|||||||
KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType.makeNotNullable(), expectedType) ->
|
KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType.makeNotNullable(), expectedType) ->
|
||||||
this
|
this
|
||||||
KotlinBuiltIns.isInt(valueType) && notNullableExpectedType.isBuiltInIntegerType() ->
|
KotlinBuiltIns.isInt(valueType) && notNullableExpectedType.isBuiltInIntegerType() ->
|
||||||
IrTypeOperatorCallImpl(startOffset, endOffset, notNullableExpectedType,
|
IrTypeOperatorCallImpl(
|
||||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION, notNullableExpectedType, this)
|
startOffset, endOffset, notNullableExpectedType,
|
||||||
|
IrTypeOperator.IMPLICIT_INTEGER_COERCION, notNullableExpectedType, this
|
||||||
|
)
|
||||||
else ->
|
else ->
|
||||||
IrTypeOperatorCallImpl(startOffset, endOffset, expectedType,
|
IrTypeOperatorCallImpl(
|
||||||
IrTypeOperator.IMPLICIT_CAST, expectedType, this)
|
startOffset, endOffset, expectedType,
|
||||||
|
IrTypeOperator.IMPLICIT_CAST, expectedType, this
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,8 +200,10 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoi
|
|||||||
return if (KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, builtIns.unitType))
|
return if (KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, builtIns.unitType))
|
||||||
this
|
this
|
||||||
else
|
else
|
||||||
IrTypeOperatorCallImpl(startOffset, endOffset, builtIns.unitType,
|
IrTypeOperatorCallImpl(
|
||||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, this)
|
startOffset, endOffset, builtIns.unitType,
|
||||||
|
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, this
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KotlinType.isBuiltInIntegerType(): Boolean =
|
private fun KotlinType.isBuiltInIntegerType(): Boolean =
|
||||||
|
|||||||
Reference in New Issue
Block a user