Formatting: psi2ir
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
apply { plugin("kotlin") }
|
||||
|
||||
jvmTarget = "1.6"
|
||||
|
||||
@@ -21,5 +21,5 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
|
||||
fun IrVariable.defaultLoad(): IrExpression =
|
||||
IrGetValueImpl(startOffset, endOffset, symbol)
|
||||
IrGetValueImpl(startOffset, endOffset, symbol)
|
||||
|
||||
|
||||
@@ -40,16 +40,16 @@ import org.jetbrains.kotlin.types.TypeUtils
|
||||
import java.lang.Exception
|
||||
|
||||
fun KotlinType.containsNull() =
|
||||
TypeUtils.isNullableType(this)
|
||||
TypeUtils.isNullableType(this)
|
||||
|
||||
fun KtElement.deparenthesize(): KtElement =
|
||||
if (this is KtExpression) KtPsiUtil.safeDeparenthesize(this) else this
|
||||
if (this is KtExpression) KtPsiUtil.safeDeparenthesize(this) else this
|
||||
|
||||
fun ResolvedCall<*>.isValueArgumentReorderingRequired(): Boolean {
|
||||
var lastValueParameterIndex = -1
|
||||
for (valueArgument in call.valueArguments) {
|
||||
val argumentMapping = getArgumentMapping(valueArgument) as? ArgumentMatch ?:
|
||||
throw Exception("Value argument in function call is mapped with error")
|
||||
val argumentMapping =
|
||||
getArgumentMapping(valueArgument) as? ArgumentMatch ?: throw Exception("Value argument in function call is mapped with error")
|
||||
val argumentIndex = argumentMapping.valueParameter.index
|
||||
if (argumentIndex < lastValueParameterIndex) {
|
||||
return true
|
||||
@@ -68,16 +68,16 @@ fun KtSecondaryConstructor.isConstructorDelegatingToSuper(bindingContext: Bindin
|
||||
}
|
||||
|
||||
inline fun ClassDescriptor.findFirstFunction(name: String, predicate: (CallableMemberDescriptor) -> Boolean) =
|
||||
unsubstitutedMemberScope.findFirstFunction(name, predicate)
|
||||
unsubstitutedMemberScope.findFirstFunction(name, predicate)
|
||||
|
||||
inline fun MemberScope.findFirstFunction(name: String, predicate: (CallableMemberDescriptor) -> Boolean) =
|
||||
getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).first(predicate)
|
||||
getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).first(predicate)
|
||||
|
||||
fun MemberScope.findSingleFunction(name: Name): FunctionDescriptor =
|
||||
getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).single()
|
||||
getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).single()
|
||||
|
||||
fun KotlinBuiltIns.findSingleFunction(name: Name): FunctionDescriptor =
|
||||
builtInsPackageScope.findSingleFunction(name)
|
||||
builtInsPackageScope.findSingleFunction(name)
|
||||
|
||||
val PsiElement?.startOffsetOrUndefined get() = this?.startOffset ?: UNDEFINED_OFFSET
|
||||
val PsiElement?.endOffsetOrUndefined get() = this?.endOffset ?: UNDEFINED_OFFSET
|
||||
|
||||
@@ -17,5 +17,5 @@
|
||||
package org.jetbrains.kotlin.psi2ir
|
||||
|
||||
class Psi2IrConfiguration(
|
||||
val ignoreErrors: Boolean = false
|
||||
val ignoreErrors: Boolean = false
|
||||
)
|
||||
|
||||
@@ -43,7 +43,7 @@ class Psi2IrTranslator(val configuration: Psi2IrConfiguration = Psi2IrConfigurat
|
||||
}
|
||||
|
||||
fun createGeneratorContext(moduleDescriptor: ModuleDescriptor, bindingContext: BindingContext) =
|
||||
GeneratorContext(configuration, moduleDescriptor, bindingContext)
|
||||
GeneratorContext(configuration, moduleDescriptor, bindingContext)
|
||||
|
||||
fun generateModuleFragment(context: GeneratorContext, ktFiles: Collection<KtFile>): IrModuleFragment {
|
||||
val irModule = ModuleGenerator(context).generateModuleFragment(ktFiles)
|
||||
|
||||
@@ -35,9 +35,9 @@ class PsiSourceManager : SourceManager {
|
||||
|
||||
maxOffset = document.textLength
|
||||
|
||||
lineStartOffsets = (0 .. document.lineCount - 1)
|
||||
.map { document.getLineStartOffset(it) }
|
||||
.toIntArray()
|
||||
lineStartOffsets = (0..document.lineCount - 1)
|
||||
.map { document.getLineStartOffset(it) }
|
||||
.toIntArray()
|
||||
}
|
||||
|
||||
override fun getLineNumber(offset: Int): Int {
|
||||
@@ -53,15 +53,15 @@ class PsiSourceManager : SourceManager {
|
||||
}
|
||||
|
||||
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo =
|
||||
SourceRangeInfo(
|
||||
filePath = getRecognizableName(),
|
||||
startOffset = beginOffset,
|
||||
startLineNumber = getLineNumber(beginOffset),
|
||||
startColumnNumber = getColumnNumber(beginOffset),
|
||||
endOffset = endOffset,
|
||||
endLineNumber = getLineNumber(endOffset),
|
||||
endColumnNumber = getColumnNumber(endOffset)
|
||||
)
|
||||
SourceRangeInfo(
|
||||
filePath = getRecognizableName(),
|
||||
startOffset = beginOffset,
|
||||
startLineNumber = getLineNumber(beginOffset),
|
||||
startColumnNumber = getColumnNumber(beginOffset),
|
||||
endOffset = endOffset,
|
||||
endLineNumber = getLineNumber(endOffset),
|
||||
endColumnNumber = getColumnNumber(endOffset)
|
||||
)
|
||||
|
||||
private fun getRecognizableName(): String = psiFileName
|
||||
|
||||
@@ -87,14 +87,14 @@ class PsiSourceManager : SourceManager {
|
||||
}
|
||||
|
||||
fun getOrCreateFileEntry(ktFile: KtFile): PsiFileEntry =
|
||||
fileEntriesByKtFile.getOrElse(ktFile) { createFileEntry(ktFile) }
|
||||
fileEntriesByKtFile.getOrElse(ktFile) { createFileEntry(ktFile) }
|
||||
|
||||
fun getKtFile(fileEntry: PsiFileEntry): KtFile? =
|
||||
ktFileByFileEntry[fileEntry]
|
||||
ktFileByFileEntry[fileEntry]
|
||||
|
||||
fun getKtFile(irFile: IrFile): KtFile? =
|
||||
(irFile.fileEntry as? PsiFileEntry)?.let { ktFileByFileEntry[it] }
|
||||
(irFile.fileEntry as? PsiFileEntry)?.let { ktFileByFileEntry[it] }
|
||||
|
||||
override fun getFileEntry(irFile: IrFile): SourceManager.FileEntry =
|
||||
fileEntriesByIrFile[irFile]!!
|
||||
fileEntriesByIrFile[irFile]!!
|
||||
}
|
||||
|
||||
+17
-15
@@ -26,20 +26,22 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
class AnonymousInitializerGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
|
||||
fun generateAnonymousInitializerDeclaration(ktAnonymousInitializer: KtAnonymousInitializer, classDescriptor: ClassDescriptor): IrDeclaration =
|
||||
context.symbolTable.declareAnonymousInitializer(
|
||||
ktAnonymousInitializer.startOffset, ktAnonymousInitializer.endOffset, IrDeclarationOrigin.DEFINED, classDescriptor
|
||||
).buildWithScope { irAnonymousInitializer ->
|
||||
val bodyGenerator = createBodyGenerator(irAnonymousInitializer.symbol)
|
||||
val statementGenerator = bodyGenerator.createStatementGenerator()
|
||||
val ktBody = ktAnonymousInitializer.body!!
|
||||
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
|
||||
if (ktBody is KtBlockExpression) {
|
||||
statementGenerator.generateStatements(ktBody.statements, irBlockBody)
|
||||
}
|
||||
else {
|
||||
irBlockBody.statements.add(statementGenerator.generateStatement(ktBody))
|
||||
}
|
||||
irAnonymousInitializer.body = irBlockBody
|
||||
fun generateAnonymousInitializerDeclaration(
|
||||
ktAnonymousInitializer: KtAnonymousInitializer,
|
||||
classDescriptor: ClassDescriptor
|
||||
): IrDeclaration =
|
||||
context.symbolTable.declareAnonymousInitializer(
|
||||
ktAnonymousInitializer.startOffset, ktAnonymousInitializer.endOffset, IrDeclarationOrigin.DEFINED, classDescriptor
|
||||
).buildWithScope { irAnonymousInitializer ->
|
||||
val bodyGenerator = createBodyGenerator(irAnonymousInitializer.symbol)
|
||||
val statementGenerator = bodyGenerator.createStatementGenerator()
|
||||
val ktBody = ktAnonymousInitializer.body!!
|
||||
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
|
||||
if (ktBody is KtBlockExpression) {
|
||||
statementGenerator.generateStatements(ktBody.statements, irBlockBody)
|
||||
} else {
|
||||
irBlockBody.statements.add(statementGenerator.generateStatement(ktBody))
|
||||
}
|
||||
irAnonymousInitializer.body = irBlockBody
|
||||
}
|
||||
}
|
||||
+157
-120
@@ -41,94 +41,113 @@ import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import java.lang.AssertionError
|
||||
|
||||
fun StatementGenerator.generateReceiverOrNull(ktDefaultElement: KtElement, receiver: ReceiverValue?): IntermediateValue? =
|
||||
receiver?.let { generateReceiver(ktDefaultElement, receiver) }
|
||||
receiver?.let { generateReceiver(ktDefaultElement, receiver) }
|
||||
|
||||
fun StatementGenerator.generateReceiver(ktDefaultElement: KtElement, receiver: ReceiverValue): IntermediateValue =
|
||||
generateReceiver(ktDefaultElement.startOffset, ktDefaultElement.endOffset, receiver)
|
||||
generateReceiver(ktDefaultElement.startOffset, ktDefaultElement.endOffset, receiver)
|
||||
|
||||
fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffset: Int, receiver: ReceiverValue): IntermediateValue =
|
||||
if (receiver is TransientReceiver)
|
||||
TransientReceiverValue(receiver.type)
|
||||
else generateDelegatedValue(receiver.type) {
|
||||
val receiverExpression = when (receiver) {
|
||||
is ImplicitClassReceiver -> {
|
||||
val receiverClassDescriptor = receiver.classDescriptor
|
||||
if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor))
|
||||
generateSingletonReference(receiverClassDescriptor, defaultStartOffset, defaultEndOffset, receiver.type)
|
||||
else
|
||||
IrGetValueImpl(defaultStartOffset, defaultEndOffset,
|
||||
context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter))
|
||||
}
|
||||
is ThisClassReceiver ->
|
||||
generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
|
||||
is SuperCallReceiverValue ->
|
||||
generateThisOrSuperReceiver(receiver, receiver.thisType.constructor.declarationDescriptor as ClassDescriptor)
|
||||
is ExpressionReceiver ->
|
||||
generateExpression(receiver.expression)
|
||||
is ClassValueReceiver ->
|
||||
IrGetObjectValueImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
|
||||
context.symbolTable.referenceClass(receiver.classQualifier.descriptor as ClassDescriptor))
|
||||
is ExtensionReceiver ->
|
||||
IrGetValueImpl(defaultStartOffset, defaultStartOffset,
|
||||
context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!))
|
||||
else ->
|
||||
TODO("Receiver: ${receiver::class.java.simpleName}")
|
||||
if (receiver is TransientReceiver)
|
||||
TransientReceiverValue(receiver.type)
|
||||
else generateDelegatedValue(receiver.type) {
|
||||
val receiverExpression = when (receiver) {
|
||||
is ImplicitClassReceiver -> {
|
||||
val receiverClassDescriptor = receiver.classDescriptor
|
||||
if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor))
|
||||
generateSingletonReference(receiverClassDescriptor, defaultStartOffset, defaultEndOffset, receiver.type)
|
||||
else
|
||||
IrGetValueImpl(
|
||||
defaultStartOffset, defaultEndOffset,
|
||||
context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter)
|
||||
)
|
||||
}
|
||||
|
||||
if (receiverExpression is IrExpressionWithCopy)
|
||||
RematerializableValue(receiverExpression)
|
||||
else
|
||||
OnceExpressionValue(receiverExpression)
|
||||
is ThisClassReceiver ->
|
||||
generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
|
||||
is SuperCallReceiverValue ->
|
||||
generateThisOrSuperReceiver(receiver, receiver.thisType.constructor.declarationDescriptor as ClassDescriptor)
|
||||
is ExpressionReceiver ->
|
||||
generateExpression(receiver.expression)
|
||||
is ClassValueReceiver ->
|
||||
IrGetObjectValueImpl(
|
||||
receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
|
||||
context.symbolTable.referenceClass(receiver.classQualifier.descriptor as ClassDescriptor)
|
||||
)
|
||||
is ExtensionReceiver ->
|
||||
IrGetValueImpl(
|
||||
defaultStartOffset, defaultStartOffset,
|
||||
context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!)
|
||||
)
|
||||
else ->
|
||||
TODO("Receiver: ${receiver::class.java.simpleName}")
|
||||
}
|
||||
|
||||
fun StatementGenerator.generateSingletonReference(descriptor: ClassDescriptor, startOffset: Int, endOffset: Int, type: KotlinType): IrDeclarationReference =
|
||||
when {
|
||||
DescriptorUtils.isObject(descriptor) ->
|
||||
IrGetObjectValueImpl(startOffset, endOffset, type,
|
||||
context.symbolTable.referenceClass(descriptor))
|
||||
DescriptorUtils.isEnumEntry(descriptor) ->
|
||||
IrGetEnumValueImpl(startOffset, endOffset, type,
|
||||
context.symbolTable.referenceEnumEntry(descriptor))
|
||||
else -> {
|
||||
val companionObjectDescriptor = descriptor.companionObjectDescriptor
|
||||
?: throw java.lang.AssertionError("Class value without companion object: $descriptor")
|
||||
IrGetObjectValueImpl(startOffset, endOffset, type,
|
||||
context.symbolTable.referenceClass(companionObjectDescriptor))
|
||||
}
|
||||
if (receiverExpression is IrExpressionWithCopy)
|
||||
RematerializableValue(receiverExpression)
|
||||
else
|
||||
OnceExpressionValue(receiverExpression)
|
||||
}
|
||||
|
||||
fun StatementGenerator.generateSingletonReference(
|
||||
descriptor: ClassDescriptor,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType
|
||||
): IrDeclarationReference =
|
||||
when {
|
||||
DescriptorUtils.isObject(descriptor) ->
|
||||
IrGetObjectValueImpl(
|
||||
startOffset, endOffset, type,
|
||||
context.symbolTable.referenceClass(descriptor)
|
||||
)
|
||||
DescriptorUtils.isEnumEntry(descriptor) ->
|
||||
IrGetEnumValueImpl(
|
||||
startOffset, endOffset, type,
|
||||
context.symbolTable.referenceEnumEntry(descriptor)
|
||||
)
|
||||
else -> {
|
||||
val companionObjectDescriptor = descriptor.companionObjectDescriptor
|
||||
?: throw java.lang.AssertionError("Class value without companion object: $descriptor")
|
||||
IrGetObjectValueImpl(
|
||||
startOffset, endOffset, type,
|
||||
context.symbolTable.referenceClass(companionObjectDescriptor)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun StatementGenerator.shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor: ClassDescriptor): Boolean {
|
||||
return receiverClassDescriptor.kind.isSingleton &&
|
||||
this.scopeOwner != receiverClassDescriptor && //For anonymous initializers
|
||||
this.scopeOwner.containingDeclaration != receiverClassDescriptor
|
||||
this.scopeOwner != receiverClassDescriptor && //For anonymous initializers
|
||||
this.scopeOwner.containingDeclaration != receiverClassDescriptor
|
||||
}
|
||||
|
||||
private fun StatementGenerator.generateThisOrSuperReceiver(receiver: ReceiverValue, classDescriptor: ClassDescriptor): IrExpression {
|
||||
val expressionReceiver = receiver as? ExpressionReceiver ?:
|
||||
throw AssertionError("'this' or 'super' receiver should be an expression receiver")
|
||||
val expressionReceiver =
|
||||
receiver as? ExpressionReceiver ?: throw AssertionError("'this' or 'super' receiver should be an expression receiver")
|
||||
val ktReceiver = expressionReceiver.expression
|
||||
return IrGetValueImpl(ktReceiver.startOffset, ktReceiver.endOffset,
|
||||
context.symbolTable.referenceValueParameter(classDescriptor.thisAsReceiverParameter))
|
||||
return IrGetValueImpl(
|
||||
ktReceiver.startOffset, ktReceiver.endOffset,
|
||||
context.symbolTable.referenceValueParameter(classDescriptor.thisAsReceiverParameter)
|
||||
)
|
||||
}
|
||||
|
||||
fun StatementGenerator.generateBackingFieldReceiver(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
resolvedCall: ResolvedCall<*>?,
|
||||
fieldDescriptor: SyntheticFieldDescriptor
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
resolvedCall: ResolvedCall<*>?,
|
||||
fieldDescriptor: SyntheticFieldDescriptor
|
||||
): IntermediateValue? {
|
||||
val receiver = resolvedCall?.dispatchReceiver ?: fieldDescriptor.getDispatchReceiverForBackend() ?: return null
|
||||
return this.generateReceiver(startOffset, endOffset, receiver)
|
||||
}
|
||||
|
||||
fun StatementGenerator.generateCallReceiver(
|
||||
ktDefaultElement: KtElement,
|
||||
calleeDescriptor: CallableDescriptor,
|
||||
dispatchReceiver: ReceiverValue?,
|
||||
extensionReceiver: ReceiverValue?,
|
||||
isSafe: Boolean,
|
||||
isAssignmentReceiver: Boolean = false
|
||||
) : CallReceiver {
|
||||
ktDefaultElement: KtElement,
|
||||
calleeDescriptor: CallableDescriptor,
|
||||
dispatchReceiver: ReceiverValue?,
|
||||
extensionReceiver: ReceiverValue?,
|
||||
isSafe: Boolean,
|
||||
isAssignmentReceiver: Boolean = false
|
||||
): CallReceiver {
|
||||
val dispatchReceiverValue: IntermediateValue?
|
||||
val extensionReceiverValue: IntermediateValue?
|
||||
when (calleeDescriptor) {
|
||||
@@ -136,13 +155,14 @@ fun StatementGenerator.generateCallReceiver(
|
||||
assert(dispatchReceiver == null) {
|
||||
"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)
|
||||
}
|
||||
is TypeAliasConstructorDescriptor -> {
|
||||
assert(!(dispatchReceiver != null && extensionReceiver != null)) {
|
||||
"Type alias constructor call for $calleeDescriptor can't have both dispatch receiver and extension receiver: " +
|
||||
"$dispatchReceiver, $extensionReceiver"
|
||||
"$dispatchReceiver, $extensionReceiver"
|
||||
}
|
||||
dispatchReceiverValue = generateReceiverOrNull(ktDefaultElement, extensionReceiver ?: dispatchReceiver)
|
||||
extensionReceiverValue = null
|
||||
@@ -156,28 +176,35 @@ fun StatementGenerator.generateCallReceiver(
|
||||
return when {
|
||||
!isSafe ->
|
||||
SimpleCallReceiver(dispatchReceiverValue, extensionReceiverValue)
|
||||
extensionReceiverValue != null || dispatchReceiverValue != null->
|
||||
SafeCallReceiver(this, ktDefaultElement.startOffset, ktDefaultElement.endOffset,
|
||||
extensionReceiverValue, dispatchReceiverValue, isAssignmentReceiver)
|
||||
extensionReceiverValue != null || dispatchReceiverValue != null ->
|
||||
SafeCallReceiver(
|
||||
this, ktDefaultElement.startOffset, ktDefaultElement.endOffset,
|
||||
extensionReceiverValue, dispatchReceiverValue, isAssignmentReceiver
|
||||
)
|
||||
else ->
|
||||
throw AssertionError("Safe call should have an explicit receiver: ${ktDefaultElement.text}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun StatementGenerator.generateReceiverForCalleeImportedFromObject(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
calleeDescriptor: ImportedFromObjectCallableDescriptor<*>
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
calleeDescriptor: ImportedFromObjectCallableDescriptor<*>
|
||||
): ExpressionValue {
|
||||
val objectDescriptor = calleeDescriptor.containingObject
|
||||
val objectType = objectDescriptor.defaultType
|
||||
return generateExpressionValue(objectType) {
|
||||
IrGetObjectValueImpl(startOffset, endOffset, objectType,
|
||||
context.symbolTable.referenceClass(objectDescriptor))
|
||||
IrGetObjectValueImpl(
|
||||
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()) {
|
||||
return null
|
||||
}
|
||||
@@ -189,20 +216,22 @@ fun StatementGenerator.generateVarargExpression(varargArgument: VarargValueArgum
|
||||
Math.max(maxEndOffset, argument.asElement().endOffset)
|
||||
}
|
||||
|
||||
val varargElementType = valueParameter.varargElementType ?:
|
||||
throw AssertionError("Vararg argument for non-vararg parameter $valueParameter")
|
||||
val varargElementType =
|
||||
valueParameter.varargElementType ?: throw AssertionError("Vararg argument for non-vararg parameter $valueParameter")
|
||||
|
||||
val irVararg = IrVarargImpl(varargStartOffset, varargEndOffset, valueParameter.type, varargElementType)
|
||||
|
||||
for (argument in varargArgument.arguments) {
|
||||
val ktArgumentExpression = argument.getArgumentExpression() ?:
|
||||
throw AssertionError("No argument expression for vararg element ${argument.asElement().text}")
|
||||
val ktArgumentExpression = argument.getArgumentExpression()
|
||||
?: throw AssertionError("No argument expression for vararg element ${argument.asElement().text}")
|
||||
val irVarargElement =
|
||||
if (argument.getSpreadElement() != null)
|
||||
IrSpreadElementImpl(ktArgumentExpression.startOffset, ktArgumentExpression.endOffset,
|
||||
generateExpression(ktArgumentExpression))
|
||||
else
|
||||
if (argument.getSpreadElement() != null)
|
||||
IrSpreadElementImpl(
|
||||
ktArgumentExpression.startOffset, ktArgumentExpression.endOffset,
|
||||
generateExpression(ktArgumentExpression)
|
||||
)
|
||||
else
|
||||
generateExpression(ktArgumentExpression)
|
||||
|
||||
irVararg.addElement(irVarargElement)
|
||||
}
|
||||
@@ -210,17 +239,20 @@ fun StatementGenerator.generateVarargExpression(varargArgument: VarargValueArgum
|
||||
return irVararg
|
||||
}
|
||||
|
||||
fun StatementGenerator.generateValueArgument(valueArgument: ResolvedValueArgument, valueParameter: ValueParameterDescriptor): IrExpression? =
|
||||
when (valueArgument) {
|
||||
is DefaultValueArgument ->
|
||||
null
|
||||
is ExpressionValueArgument ->
|
||||
generateExpression(valueArgument.valueArgument!!.getArgumentExpression()!!)
|
||||
is VarargValueArgument ->
|
||||
generateVarargExpression(valueArgument, valueParameter)
|
||||
else ->
|
||||
TODO("Unexpected valueArgument: ${valueArgument::class.java.simpleName}")
|
||||
}
|
||||
fun StatementGenerator.generateValueArgument(
|
||||
valueArgument: ResolvedValueArgument,
|
||||
valueParameter: ValueParameterDescriptor
|
||||
): IrExpression? =
|
||||
when (valueArgument) {
|
||||
is DefaultValueArgument ->
|
||||
null
|
||||
is ExpressionValueArgument ->
|
||||
generateExpression(valueArgument.valueArgument!!.getArgumentExpression()!!)
|
||||
is VarargValueArgument ->
|
||||
generateVarargExpression(valueArgument, valueParameter)
|
||||
else ->
|
||||
TODO("Unexpected valueArgument: ${valueArgument::class.java.simpleName}")
|
||||
}
|
||||
|
||||
fun Generator.getSuperQualifier(resolvedCall: ResolvedCall<*>): ClassDescriptor? {
|
||||
val superCallExpression = getSuperCallExpression(resolvedCall.call) ?: return null
|
||||
@@ -239,11 +271,12 @@ fun StatementGenerator.pregenerateCall(resolvedCall: ResolvedCall<*>): CallBuild
|
||||
|
||||
fun StatementGenerator.pregenerateExtensionInvokeCall(resolvedCall: ResolvedCall<*>): CallBuilder {
|
||||
val extensionInvoke = resolvedCall.resultingDescriptor
|
||||
val functionNClass = extensionInvoke.containingDeclaration as? ClassDescriptor ?:
|
||||
throw AssertionError("'invoke' should be a class member: $extensionInvoke")
|
||||
val unsubstitutedPlainInvokes = functionNClass.unsubstitutedMemberScope.getContributedFunctions(extensionInvoke.name, NoLookupLocation.FROM_BACKEND)
|
||||
val unsubstitutedPlainInvoke = unsubstitutedPlainInvokes.singleOrNull() ?:
|
||||
throw AssertionError("There should be a single 'invoke' in FunctionN class: $unsubstitutedPlainInvokes")
|
||||
val functionNClass = extensionInvoke.containingDeclaration as? ClassDescriptor
|
||||
?: throw AssertionError("'invoke' should be a class member: $extensionInvoke")
|
||||
val unsubstitutedPlainInvokes =
|
||||
functionNClass.unsubstitutedMemberScope.getContributedFunctions(extensionInvoke.name, NoLookupLocation.FROM_BACKEND)
|
||||
val unsubstitutedPlainInvoke = unsubstitutedPlainInvokes.singleOrNull()
|
||||
?: throw AssertionError("There should be a single 'invoke' in FunctionN class: $unsubstitutedPlainInvokes")
|
||||
|
||||
val expectedValueParametersCount = extensionInvoke.valueParameters.size + 1
|
||||
assert(unsubstitutedPlainInvoke.valueParameters.size == expectedValueParametersCount) {
|
||||
@@ -251,29 +284,31 @@ fun StatementGenerator.pregenerateExtensionInvokeCall(resolvedCall: ResolvedCall
|
||||
}
|
||||
|
||||
val functionNType = extensionInvoke.dispatchReceiverParameter!!.type
|
||||
val plainInvoke = unsubstitutedPlainInvoke.substitute(TypeSubstitutor.create(functionNType)) ?:
|
||||
throw AssertionError("Substitution failed for $unsubstitutedPlainInvoke, type=$functionNType")
|
||||
val plainInvoke = unsubstitutedPlainInvoke.substitute(TypeSubstitutor.create(functionNType))
|
||||
?: throw AssertionError("Substitution failed for $unsubstitutedPlainInvoke, type=$functionNType")
|
||||
|
||||
val ktCallElement = resolvedCall.call.callElement
|
||||
|
||||
val call = CallBuilder(resolvedCall, plainInvoke, isExtensionInvokeCall = true)
|
||||
|
||||
val functionReceiverValue = run {
|
||||
val dispatchReceiver = resolvedCall.dispatchReceiver ?:
|
||||
throw AssertionError("Extension 'invoke' call should have a dispatch receiver")
|
||||
val dispatchReceiver =
|
||||
resolvedCall.dispatchReceiver ?: throw AssertionError("Extension 'invoke' call should have a dispatch receiver")
|
||||
generateReceiver(ktCallElement, dispatchReceiver)
|
||||
}
|
||||
|
||||
val extensionInvokeReceiverValue = run {
|
||||
val extensionReceiver = resolvedCall.extensionReceiver ?:
|
||||
throw AssertionError("Extension 'invoke' call should have an extension receiver")
|
||||
val extensionReceiver =
|
||||
resolvedCall.extensionReceiver ?: throw AssertionError("Extension 'invoke' call should have an extension receiver")
|
||||
generateReceiver(ktCallElement, extensionReceiver)
|
||||
}
|
||||
|
||||
call.callReceiver =
|
||||
if (resolvedCall.call.isSafeCall())
|
||||
SafeExtensionInvokeCallReceiver(this, ktCallElement.startOffset, ktCallElement.endOffset,
|
||||
call, functionReceiverValue, extensionInvokeReceiverValue)
|
||||
SafeExtensionInvokeCallReceiver(
|
||||
this, ktCallElement.startOffset, ktCallElement.endOffset,
|
||||
call, functionReceiverValue, extensionInvokeReceiverValue
|
||||
)
|
||||
else
|
||||
ExtensionInvokeCallReceiver(call, functionReceiverValue, extensionInvokeReceiverValue)
|
||||
|
||||
@@ -313,11 +348,13 @@ private fun StatementGenerator.pregenerateValueArguments(call: CallBuilder, reso
|
||||
fun StatementGenerator.pregenerateCallReceivers(resolvedCall: ResolvedCall<*>): CallBuilder {
|
||||
val call = CallBuilder(resolvedCall, unwrapCallableDescriptor(resolvedCall.resultingDescriptor))
|
||||
|
||||
call.callReceiver = generateCallReceiver(resolvedCall.call.callElement,
|
||||
resolvedCall.resultingDescriptor,
|
||||
resolvedCall.dispatchReceiver,
|
||||
resolvedCall.extensionReceiver,
|
||||
isSafe = resolvedCall.call.isSafeCall())
|
||||
call.callReceiver = generateCallReceiver(
|
||||
resolvedCall.call.callElement,
|
||||
resolvedCall.resultingDescriptor,
|
||||
resolvedCall.dispatchReceiver,
|
||||
resolvedCall.extensionReceiver,
|
||||
isSafe = resolvedCall.call.isSafeCall()
|
||||
)
|
||||
|
||||
call.superQualifier = getSuperQualifier(resolvedCall)
|
||||
|
||||
@@ -325,11 +362,11 @@ fun StatementGenerator.pregenerateCallReceivers(resolvedCall: ResolvedCall<*>):
|
||||
}
|
||||
|
||||
fun unwrapCallableDescriptor(resultingDescriptor: CallableDescriptor): CallableDescriptor =
|
||||
when (resultingDescriptor) {
|
||||
is ImportedFromObjectCallableDescriptor<*> ->
|
||||
resultingDescriptor.callableFromObject
|
||||
is TypeAliasConstructorDescriptor ->
|
||||
resultingDescriptor.underlyingConstructorDescriptor
|
||||
else ->
|
||||
resultingDescriptor
|
||||
}
|
||||
when (resultingDescriptor) {
|
||||
is ImportedFromObjectCallableDescriptor<*> ->
|
||||
resultingDescriptor.callableFromObject
|
||||
is TypeAliasConstructorDescriptor ->
|
||||
resultingDescriptor.underlyingConstructorDescriptor
|
||||
else ->
|
||||
resultingDescriptor
|
||||
}
|
||||
|
||||
+79
-75
@@ -58,8 +58,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
||||
if (isSimpleAssignment) {
|
||||
// Set( Op( Get(), RHS ) )
|
||||
irLValue.store(irOpCall)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Op( Get(), RHS )
|
||||
irOpCall
|
||||
}
|
||||
@@ -109,32 +108,33 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
||||
|
||||
return when (descriptor) {
|
||||
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)
|
||||
}
|
||||
is LocalVariableDescriptor ->
|
||||
@Suppress("DEPRECATION")
|
||||
if (descriptor.isDelegated)
|
||||
DelegatedLocalPropertyLValue(
|
||||
ktLeft.startOffset, ktLeft.endOffset,
|
||||
descriptor.type,
|
||||
descriptor.getter?.let { context.symbolTable.referenceDeclaredFunction(it) },
|
||||
descriptor.setter?.let { context.symbolTable.referenceDeclaredFunction(it) },
|
||||
origin
|
||||
ktLeft.startOffset, ktLeft.endOffset,
|
||||
descriptor.type,
|
||||
descriptor.getter?.let { context.symbolTable.referenceDeclaredFunction(it) },
|
||||
descriptor.setter?.let { context.symbolTable.referenceDeclaredFunction(it) },
|
||||
origin
|
||||
)
|
||||
else
|
||||
VariableLValue(
|
||||
ktLeft.startOffset, ktLeft.endOffset,
|
||||
context.symbolTable.referenceVariable(descriptor),
|
||||
origin
|
||||
ktLeft.startOffset, ktLeft.endOffset,
|
||||
context.symbolTable.referenceVariable(descriptor),
|
||||
origin
|
||||
)
|
||||
is PropertyDescriptor ->
|
||||
generateAssignmentReceiverForProperty(descriptor, origin, ktLeft, resolvedCall)
|
||||
is ValueDescriptor ->
|
||||
VariableLValue(
|
||||
ktLeft.startOffset, ktLeft.endOffset,
|
||||
context.symbolTable.referenceValue(descriptor),
|
||||
origin
|
||||
ktLeft.startOffset, ktLeft.endOffset,
|
||||
context.symbolTable.referenceValue(descriptor),
|
||||
origin
|
||||
)
|
||||
else ->
|
||||
OnceExpressionValue(statementGenerator.generateExpression(ktLeft))
|
||||
@@ -142,50 +142,50 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
||||
}
|
||||
|
||||
private fun createBackingFieldLValue(
|
||||
ktExpression: KtExpression,
|
||||
descriptor: PropertyDescriptor,
|
||||
receiverValue: IntermediateValue?,
|
||||
origin: IrStatementOrigin?
|
||||
ktExpression: KtExpression,
|
||||
descriptor: PropertyDescriptor,
|
||||
receiverValue: IntermediateValue?,
|
||||
origin: IrStatementOrigin?
|
||||
): BackingFieldLValue =
|
||||
BackingFieldLValue(
|
||||
ktExpression.startOffset, ktExpression.endOffset,
|
||||
descriptor.type,
|
||||
context.symbolTable.referenceField(descriptor),
|
||||
receiverValue, origin
|
||||
)
|
||||
BackingFieldLValue(
|
||||
ktExpression.startOffset, ktExpression.endOffset,
|
||||
descriptor.type,
|
||||
context.symbolTable.referenceField(descriptor),
|
||||
receiverValue, origin
|
||||
)
|
||||
|
||||
private fun generateAssignmentReceiverForProperty(
|
||||
descriptor: PropertyDescriptor,
|
||||
origin: IrStatementOrigin,
|
||||
ktLeft: KtExpression,
|
||||
resolvedCall: ResolvedCall<*>
|
||||
descriptor: PropertyDescriptor,
|
||||
origin: IrStatementOrigin,
|
||||
ktLeft: KtExpression,
|
||||
resolvedCall: ResolvedCall<*>
|
||||
): AssignmentReceiver =
|
||||
if (isValInitializationInConstructor(descriptor, resolvedCall)) {
|
||||
val thisClass = getThisClass()
|
||||
val irThis = IrGetValueImpl(
|
||||
ktLeft.startOffset, ktLeft.endOffset,
|
||||
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter)
|
||||
)
|
||||
createBackingFieldLValue(ktLeft, descriptor, RematerializableValue(irThis), null)
|
||||
}
|
||||
else {
|
||||
val propertyReceiver = statementGenerator.generateCallReceiver(
|
||||
ktLeft, descriptor, resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver,
|
||||
isSafe = resolvedCall.call.isSafeCall(),
|
||||
isAssignmentReceiver = true)
|
||||
if (isValInitializationInConstructor(descriptor, resolvedCall)) {
|
||||
val thisClass = getThisClass()
|
||||
val irThis = IrGetValueImpl(
|
||||
ktLeft.startOffset, ktLeft.endOffset,
|
||||
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter)
|
||||
)
|
||||
createBackingFieldLValue(ktLeft, descriptor, RematerializableValue(irThis), null)
|
||||
} else {
|
||||
val propertyReceiver = statementGenerator.generateCallReceiver(
|
||||
ktLeft, descriptor, resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver,
|
||||
isSafe = resolvedCall.call.isSafeCall(),
|
||||
isAssignmentReceiver = true
|
||||
)
|
||||
|
||||
val superQualifier = getSuperQualifier(resolvedCall)
|
||||
val superQualifier = getSuperQualifier(resolvedCall)
|
||||
|
||||
createPropertyLValue(ktLeft, descriptor, propertyReceiver, getTypeArguments(resolvedCall), origin, superQualifier)
|
||||
}
|
||||
createPropertyLValue(ktLeft, descriptor, propertyReceiver, getTypeArguments(resolvedCall), origin, superQualifier)
|
||||
}
|
||||
|
||||
private fun createPropertyLValue(
|
||||
ktExpression: KtExpression,
|
||||
descriptor: PropertyDescriptor,
|
||||
propertyReceiver: CallReceiver,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
origin: IrStatementOrigin?,
|
||||
superQualifier: ClassDescriptor?
|
||||
ktExpression: KtExpression,
|
||||
descriptor: PropertyDescriptor,
|
||||
propertyReceiver: CallReceiver,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
origin: IrStatementOrigin?,
|
||||
superQualifier: ClassDescriptor?
|
||||
): PropertyLValueBase {
|
||||
val superQualifierSymbol = superQualifier?.let { context.symbolTable.referenceClass(it) }
|
||||
|
||||
@@ -197,33 +197,32 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
||||
|
||||
return if (getterSymbol != null || setterSymbol != null) {
|
||||
AccessorPropertyLValue(
|
||||
scope,
|
||||
ktExpression.startOffset, ktExpression.endOffset, origin,
|
||||
descriptor.type,
|
||||
getterSymbol,
|
||||
getterDescriptor,
|
||||
setterSymbol,
|
||||
setterDescriptor,
|
||||
typeArguments,
|
||||
propertyReceiver,
|
||||
superQualifierSymbol
|
||||
scope,
|
||||
ktExpression.startOffset, ktExpression.endOffset, origin,
|
||||
descriptor.type,
|
||||
getterSymbol,
|
||||
getterDescriptor,
|
||||
setterSymbol,
|
||||
setterDescriptor,
|
||||
typeArguments,
|
||||
propertyReceiver,
|
||||
superQualifierSymbol
|
||||
)
|
||||
}
|
||||
else
|
||||
} else
|
||||
FieldPropertyLValue(
|
||||
scope,
|
||||
ktExpression.startOffset, ktExpression.endOffset, origin,
|
||||
context.symbolTable.referenceField(descriptor),
|
||||
propertyReceiver,
|
||||
superQualifierSymbol
|
||||
scope,
|
||||
ktExpression.startOffset, ktExpression.endOffset, origin,
|
||||
context.symbolTable.referenceField(descriptor),
|
||||
propertyReceiver,
|
||||
superQualifierSymbol
|
||||
)
|
||||
}
|
||||
|
||||
private fun isValInitializationInConstructor(descriptor: PropertyDescriptor, resolvedCall: ResolvedCall<*>): Boolean =
|
||||
!descriptor.isVar &&
|
||||
descriptor.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
|
||||
statementGenerator.scopeOwner.let { it is ConstructorDescriptor || it is ClassDescriptor } &&
|
||||
resolvedCall.dispatchReceiver is ThisClassReceiver
|
||||
!descriptor.isVar &&
|
||||
descriptor.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
|
||||
statementGenerator.scopeOwner.let { it is ConstructorDescriptor || it is ClassDescriptor } &&
|
||||
resolvedCall.dispatchReceiver is ThisClassReceiver
|
||||
|
||||
private fun getThisClass(): ClassDescriptor {
|
||||
val scopeOwner = statementGenerator.scopeOwner
|
||||
@@ -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 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 indexedSetCall = indexedSetResolvedCall?.let { statementGenerator.pregenerateCallReceivers(it) }
|
||||
|
||||
return ArrayAccessAssignmentReceiver(irArray, irIndexExpressions, indexedGetCall, indexedSetCall,
|
||||
CallGenerator(statementGenerator),
|
||||
ktLeft.startOffset, ktLeft.endOffset, origin)
|
||||
return ArrayAccessAssignmentReceiver(
|
||||
irArray, irIndexExpressions, indexedGetCall, indexedSetCall,
|
||||
CallGenerator(statementGenerator),
|
||||
ktLeft.startOffset, ktLeft.endOffset, origin
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ import java.lang.AssertionError
|
||||
import java.util.*
|
||||
|
||||
class BodyGenerator(
|
||||
val scopeOwnerSymbol: IrSymbol,
|
||||
override val context: GeneratorContext
|
||||
val scopeOwnerSymbol: IrSymbol,
|
||||
override val context: GeneratorContext
|
||||
) : GeneratorWithScope {
|
||||
val scopeOwner: DeclarationDescriptor get() = scopeOwnerSymbol.descriptor
|
||||
|
||||
@@ -48,8 +48,7 @@ class BodyGenerator(
|
||||
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
|
||||
if (ktBody is KtBlockExpression) {
|
||||
statementGenerator.generateStatements(ktBody.statements, irBlockBody)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
statementGenerator.generateReturnExpression(ktBody, irBlockBody)
|
||||
}
|
||||
|
||||
@@ -57,7 +56,7 @@ class BodyGenerator(
|
||||
}
|
||||
|
||||
fun generateExpressionBody(ktExpression: KtExpression): IrExpressionBody =
|
||||
IrExpressionBodyImpl(createStatementGenerator().generateExpression(ktExpression))
|
||||
IrExpressionBodyImpl(createStatementGenerator().generateExpression(ktExpression))
|
||||
|
||||
fun generateLambdaBody(ktFun: KtFunctionLiteral): IrBody {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
@@ -68,9 +67,11 @@ class BodyGenerator(
|
||||
for (ktParameter in ktFun.valueParameters) {
|
||||
val ktDestructuringDeclaration = ktParameter.destructuringDeclaration ?: continue
|
||||
val valueParameter = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter)
|
||||
val parameterValue = VariableLValue(ktDestructuringDeclaration.startOffset, ktDestructuringDeclaration.endOffset,
|
||||
context.symbolTable.referenceValue(valueParameter),
|
||||
IrStatementOrigin.DESTRUCTURING_DECLARATION)
|
||||
val parameterValue = VariableLValue(
|
||||
ktDestructuringDeclaration.startOffset, ktDestructuringDeclaration.endOffset,
|
||||
context.symbolTable.referenceValue(valueParameter),
|
||||
IrStatementOrigin.DESTRUCTURING_DECLARATION
|
||||
)
|
||||
statementGenerator.declareComponentVariablesInBlock(ktDestructuringDeclaration, irBlockBody, parameterValue)
|
||||
}
|
||||
|
||||
@@ -81,12 +82,16 @@ class BodyGenerator(
|
||||
}
|
||||
val ktReturnedValue = ktBodyStatements.last()
|
||||
statementGenerator.generateReturnExpression(ktReturnedValue, irBlockBody)
|
||||
}
|
||||
else {
|
||||
irBlockBody.statements.add(generateReturnExpression(
|
||||
} else {
|
||||
irBlockBody.statements.add(
|
||||
generateReturnExpression(
|
||||
ktBody.startOffset, ktBody.endOffset,
|
||||
IrGetObjectValueImpl(ktBody.startOffset, ktBody.endOffset, context.builtIns.unitType,
|
||||
context.symbolTable.referenceClass(context.builtIns.unit))))
|
||||
IrGetObjectValueImpl(
|
||||
ktBody.startOffset, ktBody.endOffset, context.builtIns.unitType,
|
||||
context.symbolTable.referenceClass(context.builtIns.unit)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return irBlockBody
|
||||
@@ -96,25 +101,26 @@ class BodyGenerator(
|
||||
val irReturnExpression = generateStatement(ktExpression)
|
||||
if (irReturnExpression is IrExpression) {
|
||||
irBlockBody.statements.add(irReturnExpression.wrapWithReturn())
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
irBlockBody.statements.add(irReturnExpression)
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrExpression.wrapWithReturn() =
|
||||
if (this is IrReturn || this is IrErrorExpression || this is IrThrow)
|
||||
this
|
||||
else {
|
||||
generateReturnExpression(startOffset, endOffset, this) }
|
||||
if (this is IrReturn || this is IrErrorExpression || this is IrThrow)
|
||||
this
|
||||
else {
|
||||
generateReturnExpression(startOffset, endOffset, this)
|
||||
}
|
||||
|
||||
|
||||
private fun generateReturnExpression(startOffset: Int, endOffset: Int, returnValue: IrExpression): IrReturnImpl {
|
||||
val returnTarget = (scopeOwner as? CallableDescriptor) ?:
|
||||
throw AssertionError("'return' in a non-callable: $scopeOwner")
|
||||
return IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType,
|
||||
context.symbolTable.referenceFunction(returnTarget),
|
||||
returnValue)
|
||||
val returnTarget = (scopeOwner as? CallableDescriptor) ?: throw AssertionError("'return' in a non-callable: $scopeOwner")
|
||||
return IrReturnImpl(
|
||||
startOffset, endOffset, context.builtIns.nothingType,
|
||||
context.symbolTable.referenceFunction(returnTarget),
|
||||
returnValue
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -140,8 +146,7 @@ class BodyGenerator(
|
||||
if (delegatingConstructorResolvedCall == null) {
|
||||
if (constructorDescriptor.containingDeclaration.kind == ClassKind.ENUM_CLASS) {
|
||||
generateEnumSuperConstructorCall(irBlockBody, ktConstructor)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
generateAnySuperConstructorCall(irBlockBody, ktConstructor)
|
||||
}
|
||||
return
|
||||
@@ -149,8 +154,9 @@ class BodyGenerator(
|
||||
|
||||
val delegatingConstructorCall = statementGenerator.pregenerateCall(delegatingConstructorResolvedCall)
|
||||
val irDelegatingConstructorCall = CallGenerator(statementGenerator).generateDelegatingConstructorCall(
|
||||
ktDelegatingConstructorCall.startOffset, ktDelegatingConstructorCall.endOffset,
|
||||
delegatingConstructorCall)
|
||||
ktDelegatingConstructorCall.startOffset, ktDelegatingConstructorCall.endOffset,
|
||||
delegatingConstructorCall
|
||||
)
|
||||
irBlockBody.statements.add(irDelegatingConstructorCall)
|
||||
}
|
||||
|
||||
@@ -161,7 +167,7 @@ class BodyGenerator(
|
||||
}
|
||||
|
||||
fun getLoop(expression: KtExpression): IrLoop? =
|
||||
loopTable[expression]
|
||||
loopTable[expression]
|
||||
|
||||
fun generatePrimaryConstructorBody(ktClassOrObject: KtClassOrObject): IrBody {
|
||||
val irBlockBody = IrBlockBodyImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset)
|
||||
@@ -169,8 +175,12 @@ class BodyGenerator(
|
||||
generateSuperConstructorCall(irBlockBody, ktClassOrObject)
|
||||
|
||||
val classDescriptor = (scopeOwner as ClassConstructorDescriptor).containingDeclaration
|
||||
irBlockBody.statements.add(IrInstanceInitializerCallImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset,
|
||||
context.symbolTable.referenceClass(classDescriptor)))
|
||||
irBlockBody.statements.add(
|
||||
IrInstanceInitializerCallImpl(
|
||||
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
|
||||
context.symbolTable.referenceClass(classDescriptor)
|
||||
)
|
||||
)
|
||||
|
||||
return irBlockBody
|
||||
}
|
||||
@@ -181,8 +191,12 @@ class BodyGenerator(
|
||||
generateDelegatingConstructorCall(irBlockBody, ktConstructor)
|
||||
|
||||
val classDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor).containingDeclaration as ClassDescriptor
|
||||
irBlockBody.statements.add(IrInstanceInitializerCallImpl(ktConstructor.startOffset, ktConstructor.endOffset,
|
||||
context.symbolTable.referenceClass(classDescriptor)))
|
||||
irBlockBody.statements.add(
|
||||
IrInstanceInitializerCallImpl(
|
||||
ktConstructor.startOffset, ktConstructor.endOffset,
|
||||
context.symbolTable.referenceClass(classDescriptor)
|
||||
)
|
||||
)
|
||||
|
||||
ktConstructor.bodyExpression?.let { ktBody ->
|
||||
createStatementGenerator().generateStatements(ktBody.statements, irBlockBody)
|
||||
@@ -209,7 +223,8 @@ class BodyGenerator(
|
||||
if (ktSuperTypeListEntry is KtSuperTypeCallEntry) {
|
||||
val superConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktSuperTypeListEntry)!!)
|
||||
val irSuperConstructorCall = CallGenerator(statementGenerator).generateDelegatingConstructorCall(
|
||||
ktSuperTypeListEntry.startOffset, ktSuperTypeListEntry.endOffset, superConstructorCall)
|
||||
ktSuperTypeListEntry.startOffset, ktSuperTypeListEntry.endOffset, superConstructorCall
|
||||
)
|
||||
irBlockBody.statements.add(irSuperConstructorCall)
|
||||
return
|
||||
}
|
||||
@@ -228,22 +243,22 @@ class BodyGenerator(
|
||||
private fun generateAnySuperConstructorCall(irBlockBody: IrBlockBodyImpl, ktElement: KtElement) {
|
||||
val anyConstructor = context.builtIns.any.constructors.single()
|
||||
irBlockBody.statements.add(
|
||||
IrDelegatingConstructorCallImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
context.symbolTable.referenceConstructor(anyConstructor),
|
||||
anyConstructor,
|
||||
null
|
||||
)
|
||||
IrDelegatingConstructorCallImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
context.symbolTable.referenceConstructor(anyConstructor),
|
||||
anyConstructor,
|
||||
null
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateEnumSuperConstructorCall(irBlockBody: IrBlockBodyImpl, ktElement: KtElement) {
|
||||
val enumConstructor = context.builtIns.enum.constructors.single()
|
||||
irBlockBody.statements.add(
|
||||
IrEnumConstructorCallImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
context.symbolTable.referenceConstructor(enumConstructor)
|
||||
)
|
||||
IrEnumConstructorCallImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
context.symbolTable.referenceConstructor(enumConstructor)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -255,8 +270,8 @@ class BodyGenerator(
|
||||
if (ktEnumEntry.declarations.isNotEmpty()) {
|
||||
val enumEntryConstructor = enumEntryDescriptor.unsubstitutedPrimaryConstructor!!
|
||||
return IrEnumConstructorCallImpl(
|
||||
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
||||
context.symbolTable.referenceConstructor(enumEntryConstructor)
|
||||
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
||||
context.symbolTable.referenceConstructor(enumEntryConstructor)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -264,8 +279,8 @@ class BodyGenerator(
|
||||
}
|
||||
|
||||
private fun generateEnumConstructorCallOrSuperCall(
|
||||
ktEnumEntry: KtEnumEntry,
|
||||
enumClassDescriptor: ClassDescriptor
|
||||
ktEnumEntry: KtEnumEntry,
|
||||
enumClassDescriptor: ClassDescriptor
|
||||
): IrExpression {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
|
||||
@@ -282,17 +297,22 @@ class BodyGenerator(
|
||||
|
||||
// Default enum entry constructor
|
||||
val enumClassConstructor =
|
||||
enumClassDescriptor.constructors.singleOrNull { it.valueParameters.all { it.hasDefaultValue() } } ?:
|
||||
throw AssertionError("Enum class $enumClassDescriptor should have a default constructor")
|
||||
enumClassDescriptor.constructors.singleOrNull { it.valueParameters.all { it.hasDefaultValue() } }
|
||||
?: throw AssertionError("Enum class $enumClassDescriptor should have a default constructor")
|
||||
return IrEnumConstructorCallImpl(
|
||||
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
||||
context.symbolTable.referenceConstructor(enumClassConstructor)
|
||||
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
||||
context.symbolTable.referenceConstructor(enumClassConstructor)
|
||||
)
|
||||
}
|
||||
|
||||
private fun StatementGenerator.generateEnumConstructorCall(constructorCall: ResolvedCall<out CallableDescriptor>, ktEnumEntry: KtEnumEntry) =
|
||||
CallGenerator(this).generateEnumConstructorSuperCall(ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
||||
pregenerateCall(constructorCall))
|
||||
private fun StatementGenerator.generateEnumConstructorCall(
|
||||
constructorCall: ResolvedCall<out CallableDescriptor>,
|
||||
ktEnumEntry: KtEnumEntry
|
||||
) =
|
||||
CallGenerator(this).generateEnumConstructorSuperCall(
|
||||
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
||||
pregenerateCall(constructorCall)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
+27
-27
@@ -39,7 +39,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
val irBranches = SmartList<IrBranch>()
|
||||
var irElseBranch: IrExpression? = null
|
||||
|
||||
whenBranches@while (true) {
|
||||
whenBranches@ while (true) {
|
||||
val irCondition = statementGenerator.generateExpression(ktLastIf.condition!!)
|
||||
val irThenBranch = statementGenerator.generateExpression(ktLastIf.then!!)
|
||||
irBranches.add(IrBranchImpl(irCondition, irThenBranch))
|
||||
@@ -60,14 +60,16 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
}
|
||||
|
||||
private fun createIrWhen(
|
||||
ktIf: KtIfExpression,
|
||||
irBranches: List<IrBranch>,
|
||||
irElseResult: IrExpression?,
|
||||
resultType: KotlinType
|
||||
ktIf: KtIfExpression,
|
||||
irBranches: List<IrBranch>,
|
||||
irElseResult: IrExpression?,
|
||||
resultType: KotlinType
|
||||
): IrWhen {
|
||||
if (irBranches.size == 1) {
|
||||
return IrIfThenElseImpl(ktIf.startOffset, ktIf.endOffset, resultType,
|
||||
irBranches[0].condition, irBranches[0].result, irElseResult)
|
||||
return IrIfThenElseImpl(
|
||||
ktIf.startOffset, ktIf.endOffset, resultType,
|
||||
irBranches[0].condition, irBranches[0].result, irElseResult
|
||||
)
|
||||
}
|
||||
|
||||
val irWhen = IrWhenImpl(ktIf.startOffset, ktIf.endOffset, resultType, IrStatementOrigin.WHEN)
|
||||
@@ -110,10 +112,10 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
var irBranchCondition: IrExpression? = null
|
||||
for (ktCondition in ktEntry.conditions) {
|
||||
val irCondition =
|
||||
if (irSubject != null)
|
||||
generateWhenConditionWithSubject(ktCondition, irSubject)
|
||||
else
|
||||
generateWhenConditionNoSubject(ktCondition)
|
||||
if (irSubject != null)
|
||||
generateWhenConditionWithSubject(ktCondition, irSubject)
|
||||
else
|
||||
generateWhenConditionNoSubject(ktCondition)
|
||||
irBranchCondition = irBranchCondition?.let { context.whenComma(it, irCondition) } ?: irCondition
|
||||
|
||||
}
|
||||
@@ -131,7 +133,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
val bindingContext = context.bindingContext
|
||||
//TODO: check condition: seems it's safe to always generate exception
|
||||
val isExhaustive = java.lang.Boolean.TRUE == bindingContext.get(BindingContext.IMPLICIT_EXHAUSTIVE_WHEN, whenExpression) ||
|
||||
java.lang.Boolean.TRUE == bindingContext.get(BindingContext.EXHAUSTIVE_WHEN, whenExpression)
|
||||
java.lang.Boolean.TRUE == bindingContext.get(BindingContext.EXHAUSTIVE_WHEN, whenExpression)
|
||||
|
||||
if (isExhaustive) {
|
||||
val call = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.noWhenBranchMatchedExceptionSymbol)
|
||||
@@ -146,14 +148,12 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
IrBlockImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType, IrStatementOrigin.WHEN)
|
||||
else
|
||||
irWhen
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (irWhen.branches.isEmpty()) {
|
||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType, IrStatementOrigin.WHEN)
|
||||
irBlock.statements.add(irSubject)
|
||||
irBlock
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irWhen.type, IrStatementOrigin.WHEN)
|
||||
irBlock.statements.add(irSubject)
|
||||
irBlock.statements.add(irWhen)
|
||||
@@ -163,7 +163,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
}
|
||||
|
||||
private fun generateWhenConditionNoSubject(ktCondition: KtWhenCondition): IrExpression =
|
||||
statementGenerator.generateExpression((ktCondition as KtWhenConditionWithExpression).expression!!)
|
||||
statementGenerator.generateExpression((ktCondition as KtWhenConditionWithExpression).expression!!)
|
||||
|
||||
private fun generateWhenConditionWithSubject(ktCondition: KtWhenCondition, irSubject: IrVariable): IrExpression {
|
||||
return when (ktCondition) {
|
||||
@@ -181,8 +181,8 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
private fun generateIsPatternCondition(irSubject: IrVariable, ktCondition: KtWhenConditionIsPattern): IrExpression {
|
||||
val isType = getOrFail(BindingContext.TYPE, ktCondition.typeReference)
|
||||
return IrTypeOperatorCallImpl(
|
||||
ktCondition.startOffset, ktCondition.endOffset, context.builtIns.booleanType,
|
||||
IrTypeOperator.INSTANCEOF, isType, irSubject.defaultLoad()
|
||||
ktCondition.startOffset, ktCondition.endOffset, context.builtIns.booleanType,
|
||||
IrTypeOperator.INSTANCEOF, isType, irSubject.defaultLoad()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -196,18 +196,18 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
irInCall
|
||||
IrStatementOrigin.NOT_IN ->
|
||||
IrUnaryPrimitiveImpl(
|
||||
ktCondition.startOffset, ktCondition.endOffset,
|
||||
IrStatementOrigin.EXCL, context.irBuiltIns.booleanNotSymbol,
|
||||
irInCall
|
||||
ktCondition.startOffset, ktCondition.endOffset,
|
||||
IrStatementOrigin.EXCL, context.irBuiltIns.booleanNotSymbol,
|
||||
irInCall
|
||||
)
|
||||
else -> throw AssertionError("Expected 'in' or '!in', got $inOperator")
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateEqualsCondition(irSubject: IrVariable, ktCondition: KtWhenConditionWithExpression): IrBinaryPrimitiveImpl =
|
||||
IrBinaryPrimitiveImpl(
|
||||
ktCondition.startOffset, ktCondition.endOffset,
|
||||
IrStatementOrigin.EQEQ, context.irBuiltIns.eqeqSymbol,
|
||||
irSubject.defaultLoad(), statementGenerator.generateExpression(ktCondition.expression!!)
|
||||
)
|
||||
IrBinaryPrimitiveImpl(
|
||||
ktCondition.startOffset, ktCondition.endOffset,
|
||||
IrStatementOrigin.EQEQ, context.irBuiltIns.eqeqSymbol,
|
||||
irSubject.defaultLoad(), statementGenerator.generateExpression(ktCondition.expression!!)
|
||||
)
|
||||
}
|
||||
+116
-110
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
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 {
|
||||
val descriptor = call.descriptor
|
||||
|
||||
@@ -52,64 +52,66 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
|
||||
}
|
||||
|
||||
fun generateValueReference(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: DeclarationDescriptor,
|
||||
resolvedCall: ResolvedCall<*>?,
|
||||
origin: IrStatementOrigin?
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: DeclarationDescriptor,
|
||||
resolvedCall: ResolvedCall<*>?,
|
||||
origin: IrStatementOrigin?
|
||||
): IrExpression =
|
||||
when (descriptor) {
|
||||
is FakeCallableDescriptorForObject ->
|
||||
generateValueReference(startOffset, endOffset, descriptor.getReferencedDescriptor(), resolvedCall, origin)
|
||||
is TypeAliasDescriptor ->
|
||||
generateValueReference(startOffset, endOffset, descriptor.classDescriptor!!, null, origin)
|
||||
is ClassDescriptor -> {
|
||||
val classValueType = descriptor.classValueType!!
|
||||
statementGenerator.generateSingletonReference(descriptor, startOffset, endOffset, classValueType)
|
||||
}
|
||||
is PropertyDescriptor -> {
|
||||
generateCall(startOffset, endOffset, statementGenerator.pregenerateCall(resolvedCall!!))
|
||||
}
|
||||
is SyntheticFieldDescriptor -> {
|
||||
val receiver = statementGenerator.generateBackingFieldReceiver(startOffset, endOffset, resolvedCall, descriptor)
|
||||
val field = statementGenerator.context.symbolTable.referenceField(descriptor.propertyDescriptor)
|
||||
IrGetFieldImpl(startOffset, endOffset, field, receiver?.load())
|
||||
}
|
||||
is VariableDescriptor ->
|
||||
generateGetVariable(startOffset, endOffset, descriptor, getTypeArguments(resolvedCall), origin)
|
||||
else ->
|
||||
TODO("Unexpected callable descriptor: $descriptor ${descriptor::class.java.simpleName}")
|
||||
when (descriptor) {
|
||||
is FakeCallableDescriptorForObject ->
|
||||
generateValueReference(startOffset, endOffset, descriptor.getReferencedDescriptor(), resolvedCall, origin)
|
||||
is TypeAliasDescriptor ->
|
||||
generateValueReference(startOffset, endOffset, descriptor.classDescriptor!!, null, origin)
|
||||
is ClassDescriptor -> {
|
||||
val classValueType = descriptor.classValueType!!
|
||||
statementGenerator.generateSingletonReference(descriptor, startOffset, endOffset, classValueType)
|
||||
}
|
||||
is PropertyDescriptor -> {
|
||||
generateCall(startOffset, endOffset, statementGenerator.pregenerateCall(resolvedCall!!))
|
||||
}
|
||||
is SyntheticFieldDescriptor -> {
|
||||
val receiver = statementGenerator.generateBackingFieldReceiver(startOffset, endOffset, resolvedCall, descriptor)
|
||||
val field = statementGenerator.context.symbolTable.referenceField(descriptor.propertyDescriptor)
|
||||
IrGetFieldImpl(startOffset, endOffset, field, receiver?.load())
|
||||
}
|
||||
is VariableDescriptor ->
|
||||
generateGetVariable(startOffset, endOffset, descriptor, getTypeArguments(resolvedCall), origin)
|
||||
else ->
|
||||
TODO("Unexpected callable descriptor: $descriptor ${descriptor::class.java.simpleName}")
|
||||
}
|
||||
|
||||
private fun generateGetVariable(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: VariableDescriptor,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
origin: IrStatementOrigin? = null
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: VariableDescriptor,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
origin: IrStatementOrigin? = null
|
||||
) =
|
||||
@Suppress("DEPRECATION")
|
||||
if (descriptor is LocalVariableDescriptor && descriptor.isDelegated) {
|
||||
val getterDescriptor = descriptor.getter!!
|
||||
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
|
||||
IrCallImpl(startOffset, endOffset, descriptor.type, getterSymbol, getterDescriptor,
|
||||
typeArguments, origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY)
|
||||
}
|
||||
else
|
||||
IrGetValueImpl(startOffset, endOffset, context.symbolTable.referenceValue(descriptor), origin)
|
||||
@Suppress("DEPRECATION")
|
||||
if (descriptor is LocalVariableDescriptor && descriptor.isDelegated) {
|
||||
val getterDescriptor = descriptor.getter!!
|
||||
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
|
||||
IrCallImpl(
|
||||
startOffset, endOffset, descriptor.type, getterSymbol, getterDescriptor,
|
||||
typeArguments, origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY
|
||||
)
|
||||
} else
|
||||
IrGetValueImpl(startOffset, endOffset, context.symbolTable.referenceValue(descriptor), origin)
|
||||
|
||||
fun generateDelegatingConstructorCall(startOffset: Int, endOffset: Int, call: CallBuilder) : IrExpression =
|
||||
call.callReceiver.call { dispatchReceiver, extensionReceiver ->
|
||||
val descriptor = call.descriptor as? ClassConstructorDescriptor
|
||||
?: throw AssertionError("Class constructor expected: ${call.descriptor}")
|
||||
val constructorSymbol = context.symbolTable.referenceConstructor(descriptor.original)
|
||||
val irCall = IrDelegatingConstructorCallImpl(startOffset, endOffset, constructorSymbol, descriptor, getTypeArguments(call.original))
|
||||
irCall.dispatchReceiver = dispatchReceiver?.load()
|
||||
irCall.extensionReceiver = extensionReceiver?.load()
|
||||
addParametersToCall(startOffset, endOffset, call, irCall, descriptor.builtIns.unitType)
|
||||
}
|
||||
fun generateDelegatingConstructorCall(startOffset: Int, endOffset: Int, call: CallBuilder): IrExpression =
|
||||
call.callReceiver.call { dispatchReceiver, extensionReceiver ->
|
||||
val descriptor = call.descriptor as? ClassConstructorDescriptor
|
||||
?: throw AssertionError("Class constructor expected: ${call.descriptor}")
|
||||
val constructorSymbol = context.symbolTable.referenceConstructor(descriptor.original)
|
||||
val irCall =
|
||||
IrDelegatingConstructorCallImpl(startOffset, endOffset, constructorSymbol, descriptor, getTypeArguments(call.original))
|
||||
irCall.dispatchReceiver = dispatchReceiver?.load()
|
||||
irCall.extensionReceiver = extensionReceiver?.load()
|
||||
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
|
||||
if (constructorDescriptor !is ClassConstructorDescriptor) throw AssertionError("Constructor expected: $constructorDescriptor")
|
||||
val classDescriptor = constructorDescriptor.containingDeclaration
|
||||
@@ -125,10 +127,10 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
|
||||
}
|
||||
|
||||
private fun generatePropertyGetterCall(
|
||||
descriptor: PropertyDescriptor,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
call: CallBuilder
|
||||
descriptor: PropertyDescriptor,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
call: CallBuilder
|
||||
): IrExpression {
|
||||
return call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
val superQualifierSymbol = call.superQualifier?.let { context.symbolTable.referenceClass(it) }
|
||||
@@ -137,73 +139,77 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
|
||||
if (getterDescriptor != null) {
|
||||
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
|
||||
IrGetterCallImpl(
|
||||
startOffset, endOffset,
|
||||
getterSymbol,
|
||||
getterDescriptor,
|
||||
getTypeArguments(call.original),
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
IrStatementOrigin.GET_PROPERTY,
|
||||
superQualifierSymbol
|
||||
startOffset, endOffset,
|
||||
getterSymbol,
|
||||
getterDescriptor,
|
||||
getTypeArguments(call.original),
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
IrStatementOrigin.GET_PROPERTY,
|
||||
superQualifierSymbol
|
||||
)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
val fieldSymbol = context.symbolTable.referenceField(descriptor)
|
||||
IrGetFieldImpl(
|
||||
startOffset, endOffset,
|
||||
fieldSymbol,
|
||||
dispatchReceiverValue?.load(),
|
||||
IrStatementOrigin.GET_PROPERTY,
|
||||
superQualifierSymbol
|
||||
startOffset, endOffset,
|
||||
fieldSymbol,
|
||||
dispatchReceiverValue?.load(),
|
||||
IrStatementOrigin.GET_PROPERTY,
|
||||
superQualifierSymbol
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateFunctionCall(
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrStatementOrigin?,
|
||||
call: CallBuilder
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrStatementOrigin?,
|
||||
call: CallBuilder
|
||||
): IrExpression =
|
||||
call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
val returnType = functionDescriptor.returnType!!
|
||||
val functionSymbol = context.symbolTable.referenceFunction(functionDescriptor.original)
|
||||
val superQualifierSymbol = call.superQualifier?.let { context.symbolTable.referenceClass(it) }
|
||||
val irCall = IrCallImpl(
|
||||
startOffset, endOffset,
|
||||
returnType,
|
||||
functionSymbol,
|
||||
functionDescriptor,
|
||||
getTypeArguments(call.original),
|
||||
origin,
|
||||
superQualifierSymbol
|
||||
)
|
||||
irCall.dispatchReceiver = dispatchReceiverValue?.load()
|
||||
irCall.extensionReceiver = extensionReceiverValue?.load()
|
||||
call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
val returnType = functionDescriptor.returnType!!
|
||||
val functionSymbol = context.symbolTable.referenceFunction(functionDescriptor.original)
|
||||
val superQualifierSymbol = call.superQualifier?.let { context.symbolTable.referenceClass(it) }
|
||||
val irCall = IrCallImpl(
|
||||
startOffset, endOffset,
|
||||
returnType,
|
||||
functionSymbol,
|
||||
functionDescriptor,
|
||||
getTypeArguments(call.original),
|
||||
origin,
|
||||
superQualifierSymbol
|
||||
)
|
||||
irCall.dispatchReceiver = dispatchReceiverValue?.load()
|
||||
irCall.extensionReceiver = extensionReceiverValue?.load()
|
||||
|
||||
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 =
|
||||
if (call.isValueArgumentReorderingRequired()) {
|
||||
generateCallWithArgumentReordering(irCall, startOffset, endOffset, call, returnType)
|
||||
}
|
||||
else {
|
||||
val valueArguments = call.getValueArgumentsInParameterOrder()
|
||||
for ((index, valueArgument) in valueArguments.withIndex()) {
|
||||
irCall.putValueArgument(index, valueArgument)
|
||||
}
|
||||
irCall
|
||||
private fun addParametersToCall(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
call: CallBuilder,
|
||||
irCall: IrFunctionAccessExpression,
|
||||
returnType: KotlinType
|
||||
): IrExpression =
|
||||
if (call.isValueArgumentReorderingRequired()) {
|
||||
generateCallWithArgumentReordering(irCall, startOffset, endOffset, call, returnType)
|
||||
} else {
|
||||
val valueArguments = call.getValueArgumentsInParameterOrder()
|
||||
for ((index, valueArgument) in valueArguments.withIndex()) {
|
||||
irCall.putValueArgument(index, valueArgument)
|
||||
}
|
||||
irCall
|
||||
}
|
||||
|
||||
private fun generateCallWithArgumentReordering(
|
||||
irCall: IrFunctionAccessExpression,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
call: CallBuilder,
|
||||
resultType: KotlinType
|
||||
irCall: IrFunctionAccessExpression,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
call: CallBuilder,
|
||||
resultType: KotlinType
|
||||
): IrExpression {
|
||||
val resolvedCall = call.original
|
||||
|
||||
@@ -239,7 +245,7 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
|
||||
}
|
||||
|
||||
fun CallGenerator.generateCall(ktElement: KtElement, call: CallBuilder, origin: IrStatementOrigin? = null) =
|
||||
generateCall(ktElement.startOffset, ktElement.endOffset, call, origin)
|
||||
generateCall(ktElement.startOffset, ktElement.endOffset, call, origin)
|
||||
|
||||
fun CallGenerator.generateCall(irExpression: IrExpression, call: CallBuilder, origin: IrStatementOrigin? = null) =
|
||||
generateCall(irExpression.startOffset, irExpression.endOffset, call, origin)
|
||||
generateCall(irExpression.startOffset, irExpression.endOffset, call, origin)
|
||||
|
||||
+77
-58
@@ -23,12 +23,12 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
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.KtDelegatedSuperTypeEntry
|
||||
import org.jetbrains.kotlin.psi.KtEnumEntry
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
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.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
@@ -40,14 +40,14 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
val descriptor = getOrFail(BindingContext.CLASS, ktClassOrObject)
|
||||
|
||||
return context.symbolTable.declareClass(
|
||||
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
descriptor
|
||||
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
descriptor
|
||||
).buildWithScope { irClass ->
|
||||
irClass.thisReceiver = context.symbolTable.declareValueParameter(
|
||||
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
|
||||
IrDeclarationOrigin.INSTANCE_RECEIVER,
|
||||
irClass.descriptor.thisAsReceiverParameter
|
||||
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
|
||||
IrDeclarationOrigin.INSTANCE_RECEIVER,
|
||||
irClass.descriptor.thisAsReceiverParameter
|
||||
)
|
||||
|
||||
declarationGenerator.generateTypeParameterDeclarations(irClass, descriptor.declaredTypeParameters)
|
||||
@@ -75,24 +75,24 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
|
||||
private fun generateFakeOverrideMemberDeclarations(irClass: IrClass, ktClassOrObject: KtClassOrObject) {
|
||||
irClass.descriptor.unsubstitutedMemberScope.getContributedDescriptors()
|
||||
.mapNotNull {
|
||||
it.safeAs<CallableMemberDescriptor>().takeIf {
|
||||
it?.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
||||
}
|
||||
}
|
||||
.sortedWith(StableDescriptorsComparator)
|
||||
.forEach { fakeOverride ->
|
||||
irClass.addMember(declarationGenerator.generateFakeOverrideDeclaration(fakeOverride, ktClassOrObject))
|
||||
.mapNotNull {
|
||||
it.safeAs<CallableMemberDescriptor>().takeIf {
|
||||
it?.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
||||
}
|
||||
}
|
||||
.sortedWith(StableDescriptorsComparator)
|
||||
.forEach { fakeOverride ->
|
||||
irClass.addMember(declarationGenerator.generateFakeOverrideDeclaration(fakeOverride, ktClassOrObject))
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateMembersDeclaredInSupertypeList(irClass: IrClass, ktClassOrObject: KtClassOrObject) {
|
||||
ktClassOrObject.getSuperTypeList()?.let { ktSuperTypeList ->
|
||||
val delegatedMembers = irClass.descriptor.unsubstitutedMemberScope
|
||||
.getContributedDescriptors(DescriptorKindFilter.CALLABLES)
|
||||
.filterIsInstance<CallableMemberDescriptor>()
|
||||
.filter { it.kind == CallableMemberDescriptor.Kind.DELEGATION }
|
||||
.sortedWith(StableDescriptorsComparator)
|
||||
.getContributedDescriptors(DescriptorKindFilter.CALLABLES)
|
||||
.filterIsInstance<CallableMemberDescriptor>()
|
||||
.filter { it.kind == CallableMemberDescriptor.Kind.DELEGATION }
|
||||
.sortedWith(StableDescriptorsComparator)
|
||||
if (delegatedMembers.isEmpty()) return
|
||||
|
||||
for (ktEntry in ktSuperTypeList.entries) {
|
||||
@@ -104,22 +104,22 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
}
|
||||
|
||||
private fun generateDelegatedImplementationMembers(
|
||||
irClass: IrClass,
|
||||
ktEntry: KtDelegatedSuperTypeEntry,
|
||||
delegatedMembers: List<CallableMemberDescriptor>
|
||||
irClass: IrClass,
|
||||
ktEntry: KtDelegatedSuperTypeEntry,
|
||||
delegatedMembers: List<CallableMemberDescriptor>
|
||||
) {
|
||||
val ktDelegateExpression = ktEntry.delegateExpression!!
|
||||
val delegateType = getInferredTypeWithImplicitCastsOrFail(ktDelegateExpression)
|
||||
val superType = getOrFail(BindingContext.TYPE, ktEntry.typeReference!!)
|
||||
val superTypeConstructorDescriptor = superType.constructor.declarationDescriptor
|
||||
val superClass = superTypeConstructorDescriptor as? ClassDescriptor ?:
|
||||
throw AssertionError("Unexpected supertype constructor for delegation: $superTypeConstructorDescriptor")
|
||||
val superClass = superTypeConstructorDescriptor as? ClassDescriptor
|
||||
?: throw AssertionError("Unexpected supertype constructor for delegation: $superTypeConstructorDescriptor")
|
||||
val delegateDescriptor = IrImplementingDelegateDescriptorImpl(irClass.descriptor, delegateType, superType)
|
||||
val irDelegateField = context.symbolTable.declareField(
|
||||
ktDelegateExpression.startOffset, ktDelegateExpression.endOffset,
|
||||
IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor,
|
||||
createBodyGenerator(irClass.symbol).generateExpressionBody(ktDelegateExpression)
|
||||
ktDelegateExpression.startOffset, ktDelegateExpression.endOffset,
|
||||
IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor,
|
||||
createBodyGenerator(irClass.symbol).generateExpressionBody(ktDelegateExpression)
|
||||
)
|
||||
irClass.addMember(irDelegateField)
|
||||
|
||||
@@ -131,8 +131,10 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateDelegatedMember(irClass: IrClass, irDelegate: IrField,
|
||||
delegatedMember: CallableMemberDescriptor, overriddenMember: CallableMemberDescriptor) {
|
||||
private fun generateDelegatedMember(
|
||||
irClass: IrClass, irDelegate: IrField,
|
||||
delegatedMember: CallableMemberDescriptor, overriddenMember: CallableMemberDescriptor
|
||||
) {
|
||||
when (delegatedMember) {
|
||||
is 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))
|
||||
}
|
||||
|
||||
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 endOffset = irDelegate.endOffset
|
||||
|
||||
@@ -160,31 +171,39 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
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))
|
||||
}
|
||||
|
||||
private fun generateDelegatedFunction(irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor): IrFunction =
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
irDelegate.startOffset, irDelegate.endOffset,
|
||||
IrDeclarationOrigin.DELEGATED_MEMBER,
|
||||
delegated
|
||||
).buildWithScope { irFunction ->
|
||||
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irFunction)
|
||||
irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden, irFunction)
|
||||
}
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
irDelegate.startOffset, irDelegate.endOffset,
|
||||
IrDeclarationOrigin.DELEGATED_MEMBER,
|
||||
delegated
|
||||
).buildWithScope { irFunction ->
|
||||
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irFunction)
|
||||
irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden, irFunction)
|
||||
}
|
||||
|
||||
private fun generateDelegateFunctionBody(irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor,
|
||||
irDelegatedFunction: IrSimpleFunction): IrBlockBodyImpl {
|
||||
private fun generateDelegateFunctionBody(
|
||||
irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor,
|
||||
irDelegatedFunction: IrSimpleFunction
|
||||
): IrBlockBodyImpl {
|
||||
val startOffset = irDelegate.startOffset
|
||||
val endOffset = irDelegate.endOffset
|
||||
val irBlockBody = IrBlockBodyImpl(startOffset, endOffset)
|
||||
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 =
|
||||
IrGetFieldImpl(
|
||||
startOffset, endOffset, irDelegate.symbol,
|
||||
IrGetValueImpl(startOffset, endOffset, irDelegatedFunction.dispatchReceiverParameter!!.symbol)
|
||||
startOffset, endOffset, irDelegate.symbol,
|
||||
IrGetValueImpl(startOffset, endOffset, irDelegatedFunction.dispatchReceiverParameter!!.symbol)
|
||||
)
|
||||
irCall.extensionReceiver =
|
||||
irDelegatedFunction.extensionReceiverParameter?.let { extensionReceiver ->
|
||||
@@ -197,8 +216,7 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
}
|
||||
if (KotlinBuiltIns.isUnit(returnType) || KotlinBuiltIns.isNothing(returnType)) {
|
||||
irBlockBody.statements.add(irCall)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
val irReturn = IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, irDelegatedFunction.symbol, irCall)
|
||||
irBlockBody.statements.add(irReturn)
|
||||
}
|
||||
@@ -217,7 +235,8 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
val classDescriptor = irClass.descriptor
|
||||
val primaryConstructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor ?: return null
|
||||
|
||||
val irPrimaryConstructor = FunctionGenerator(declarationGenerator).generatePrimaryConstructor(primaryConstructorDescriptor, ktClassOrObject)
|
||||
val irPrimaryConstructor =
|
||||
FunctionGenerator(declarationGenerator).generatePrimaryConstructor(primaryConstructorDescriptor, ktClassOrObject)
|
||||
|
||||
if (!DescriptorUtils.isAnnotationClass(classDescriptor)) {
|
||||
irClass.addMember(irPrimaryConstructor)
|
||||
@@ -227,9 +246,9 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
}
|
||||
|
||||
private fun generateDeclarationsForPrimaryConstructorParameters(
|
||||
irClass: IrClass,
|
||||
irPrimaryConstructor: IrConstructor,
|
||||
ktClassOrObject: KtClassOrObject
|
||||
irClass: IrClass,
|
||||
irPrimaryConstructor: IrConstructor,
|
||||
ktClassOrObject: KtClassOrObject
|
||||
) {
|
||||
ktClassOrObject.primaryConstructor?.let { ktPrimaryConstructor ->
|
||||
irPrimaryConstructor.valueParameters.forEach {
|
||||
@@ -240,7 +259,7 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
val irValueParameter = irPrimaryConstructor.valueParameters[i]
|
||||
if (ktParameter.hasValOrVar()) {
|
||||
val irProperty = PropertyGenerator(declarationGenerator)
|
||||
.generatePropertyForPrimaryConstructorParameter(ktParameter, irValueParameter)
|
||||
.generatePropertyForPrimaryConstructorParameter(ktParameter, irValueParameter)
|
||||
irClass.addMember(irProperty)
|
||||
}
|
||||
}
|
||||
@@ -258,14 +277,14 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
fun generateEnumEntry(ktEnumEntry: KtEnumEntry): IrEnumEntry {
|
||||
val enumEntryDescriptor = getOrFail(BindingContext.CLASS, ktEnumEntry)
|
||||
return context.symbolTable.declareEnumEntry(
|
||||
ktEnumEntry.startOffset,
|
||||
ktEnumEntry.endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
enumEntryDescriptor
|
||||
ktEnumEntry.startOffset,
|
||||
ktEnumEntry.endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
enumEntryDescriptor
|
||||
).buildWithScope { irEnumEntry ->
|
||||
irEnumEntry.initializerExpression =
|
||||
createBodyGenerator(irEnumEntry.symbol)
|
||||
.generateEnumEntryInitializer(ktEnumEntry, enumEntryDescriptor)
|
||||
.generateEnumEntryInitializer(ktEnumEntry, enumEntryDescriptor)
|
||||
|
||||
if (ktEnumEntry.declarations.isNotEmpty()) {
|
||||
irEnumEntry.correspondingClass = generateClass(ktEnumEntry)
|
||||
|
||||
+49
-47
@@ -48,16 +48,16 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
}
|
||||
|
||||
private fun declareSimpleFunction(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, function: FunctionDescriptor) =
|
||||
context.symbolTable.declareSimpleFunction(startOffset, endOffset, origin, function)
|
||||
context.symbolTable.declareSimpleFunction(startOffset, endOffset, origin, function)
|
||||
|
||||
private inner class MemberFunctionBuilder(
|
||||
val irClass: IrClass,
|
||||
val function: FunctionDescriptor,
|
||||
val origin: IrDeclarationOrigin,
|
||||
startOffset: Int = UNDEFINED_OFFSET,
|
||||
endOffset: Int = UNDEFINED_OFFSET,
|
||||
val irFunction: IrFunction = declareSimpleFunction(startOffset, endOffset, origin, function)
|
||||
) : IrBlockBodyBuilder(context, Scope(irFunction.symbol), startOffset, endOffset) {
|
||||
val irClass: IrClass,
|
||||
val function: FunctionDescriptor,
|
||||
val origin: IrDeclarationOrigin,
|
||||
startOffset: Int = UNDEFINED_OFFSET,
|
||||
endOffset: Int = UNDEFINED_OFFSET,
|
||||
val irFunction: IrFunction = declareSimpleFunction(startOffset, endOffset, origin, function)
|
||||
) : IrBlockBodyBuilder(context, Scope(irFunction.symbol), startOffset, endOffset) {
|
||||
inline fun addToClass(builder: MemberFunctionBuilder.(IrFunction) -> Unit): IrFunction {
|
||||
irFunction.buildWithScope {
|
||||
builder(irFunction)
|
||||
@@ -73,24 +73,24 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
}
|
||||
|
||||
fun irThis(): IrExpression =
|
||||
IrGetValueImpl(startOffset, endOffset, irFunction.dispatchReceiverParameter!!.symbol)
|
||||
IrGetValueImpl(startOffset, endOffset, irFunction.dispatchReceiverParameter!!.symbol)
|
||||
|
||||
fun irOther(): IrExpression =
|
||||
IrGetValueImpl(startOffset, endOffset, irFunction.valueParameters[0].symbol)
|
||||
IrGetValueImpl(startOffset, endOffset, irFunction.valueParameters[0].symbol)
|
||||
}
|
||||
|
||||
private inner class MyDataClassMethodGenerator(
|
||||
ktClassOrObject: KtClassOrObject,
|
||||
val irClass: IrClass
|
||||
ktClassOrObject: KtClassOrObject,
|
||||
val irClass: IrClass
|
||||
) : DataClassMethodGenerator(ktClassOrObject, declarationGenerator.context.bindingContext) {
|
||||
private inline fun buildMember(
|
||||
function: FunctionDescriptor,
|
||||
psiElement: PsiElement? = null,
|
||||
body: MemberFunctionBuilder.(IrFunction) -> Unit
|
||||
function: FunctionDescriptor,
|
||||
psiElement: PsiElement? = null,
|
||||
body: MemberFunctionBuilder.(IrFunction) -> Unit
|
||||
) {
|
||||
MemberFunctionBuilder(
|
||||
irClass, function, IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER,
|
||||
psiElement.startOffsetOrUndefined, psiElement.endOffsetOrUndefined
|
||||
irClass, function, IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER,
|
||||
psiElement.startOffsetOrUndefined, psiElement.endOffsetOrUndefined
|
||||
).addToClass { irFunction ->
|
||||
irFunction.buildWithScope {
|
||||
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irFunction)
|
||||
@@ -100,8 +100,8 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
}
|
||||
|
||||
override fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor) {
|
||||
val ktParameter = DescriptorToSourceUtils.descriptorToDeclaration(parameter) ?:
|
||||
throw AssertionError("No definition for data class constructor parameter $parameter")
|
||||
val ktParameter = DescriptorToSourceUtils.descriptorToDeclaration(parameter)
|
||||
?: throw AssertionError("No definition for data class constructor parameter $parameter")
|
||||
|
||||
buildMember(function, ktParameter) {
|
||||
+irReturn(irGet(irThis(), getPropertyGetterSymbol(parameter)))
|
||||
@@ -114,11 +114,11 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
}
|
||||
|
||||
private fun getPropertyGetterSymbol(property: PropertyDescriptor) =
|
||||
context.symbolTable.referenceFunction(property.getter!!)
|
||||
context.symbolTable.referenceFunction(property.getter!!)
|
||||
|
||||
override fun generateCopyFunction(function: FunctionDescriptor, constructorParameters: List<KtParameter>) {
|
||||
val dataClassConstructor = classDescriptor.unsubstitutedPrimaryConstructor ?:
|
||||
throw AssertionError("Data class should have a primary constructor: $classDescriptor")
|
||||
val dataClassConstructor = classDescriptor.unsubstitutedPrimaryConstructor
|
||||
?: throw AssertionError("Data class should have a primary constructor: $classDescriptor")
|
||||
val constructorSymbol = context.symbolTable.referenceConstructor(dataClassConstructor)
|
||||
|
||||
buildMember(function, declaration) { irFunction ->
|
||||
@@ -138,8 +138,11 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
val otherWithCast = irTemporary(irAs(irOther(), classDescriptor.defaultType), "other_with_cast")
|
||||
for (property in properties) {
|
||||
+irIfThenReturnFalse(
|
||||
irNotEquals(irGet(irThis(), getPropertyGetterSymbol(property)),
|
||||
irGet(irGet(otherWithCast.symbol), getPropertyGetterSymbol(property))))
|
||||
irNotEquals(
|
||||
irGet(irThis(), getPropertyGetterSymbol(property)),
|
||||
irGet(irGet(otherWithCast.symbol), getPropertyGetterSymbol(property))
|
||||
)
|
||||
)
|
||||
}
|
||||
+irReturnTrue()
|
||||
}
|
||||
@@ -149,12 +152,12 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
private val intType = context.builtIns.intType
|
||||
|
||||
private val intTimes =
|
||||
intClass.findFirstFunction("times") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, intType) }
|
||||
.let { context.symbolTable.referenceFunction(it) }
|
||||
intClass.findFirstFunction("times") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, intType) }
|
||||
.let { context.symbolTable.referenceFunction(it) }
|
||||
|
||||
private val intPlus =
|
||||
intClass.findFirstFunction("plus") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, intType) }
|
||||
.let { context.symbolTable.referenceFunction(it) }
|
||||
intClass.findFirstFunction("plus") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, intType) }
|
||||
.let { context.symbolTable.referenceFunction(it) }
|
||||
|
||||
|
||||
private fun getHashCodeFunction(type: KotlinType): IrFunctionSymbol {
|
||||
@@ -163,9 +166,9 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
is ClassDescriptor -> {
|
||||
if (KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor)) {
|
||||
context.irBuiltIns.dataClassArrayMemberHashCodeSymbol
|
||||
}
|
||||
else {
|
||||
val hashCodeDescriptor: CallableDescriptor = typeConstructorDescriptor.findFirstFunction("hashCode") { it.valueParameters.isEmpty() }
|
||||
} else {
|
||||
val hashCodeDescriptor: CallableDescriptor =
|
||||
typeConstructorDescriptor.findFirstFunction("hashCode") { it.valueParameters.isEmpty() }
|
||||
context.symbolTable.referenceFunction(hashCodeDescriptor)
|
||||
}
|
||||
}
|
||||
@@ -184,8 +187,8 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
for (property in properties) {
|
||||
val hashCodeOfProperty = getHashCodeOfProperty(irThis(), property)
|
||||
val irNewValue =
|
||||
if (first) hashCodeOfProperty
|
||||
else irCallOp(intPlus, irCallOp(intTimes, irGet(result), irInt(31)), hashCodeOfProperty)
|
||||
if (first) hashCodeOfProperty
|
||||
else irCallOp(intPlus, irCallOp(intTimes, irGet(result), irInt(31)), hashCodeOfProperty)
|
||||
+irSetVar(result, irNewValue)
|
||||
first = false
|
||||
}
|
||||
@@ -206,14 +209,13 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
}
|
||||
|
||||
private fun MemberFunctionBuilder.getHashCodeOf(irValue: IrExpression): IrExpression =
|
||||
irCall(getHashCodeFunction(irValue.type)).apply {
|
||||
if (descriptor.dispatchReceiverParameter != null) {
|
||||
dispatchReceiver = irValue
|
||||
}
|
||||
else {
|
||||
putValueArgument(0, irValue)
|
||||
}
|
||||
irCall(getHashCodeFunction(irValue.type)).apply {
|
||||
if (descriptor.dispatchReceiverParameter != null) {
|
||||
dispatchReceiver = irValue
|
||||
} else {
|
||||
putValueArgument(0, irValue)
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateToStringMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||
buildMember(function, declaration) {
|
||||
@@ -226,13 +228,13 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
val irPropertyValue = irGet(irThis(), getPropertyGetterSymbol(property))
|
||||
val typeConstructorDescriptor = property.type.constructor.declarationDescriptor
|
||||
val irPropertyStringValue =
|
||||
if (typeConstructorDescriptor is ClassDescriptor &&
|
||||
KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor))
|
||||
irCall(context.irBuiltIns.dataClassArrayMemberToStringSymbol).apply {
|
||||
putValueArgument(0, irPropertyValue)
|
||||
}
|
||||
else
|
||||
irPropertyValue
|
||||
if (typeConstructorDescriptor is ClassDescriptor &&
|
||||
KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor))
|
||||
irCall(context.irBuiltIns.dataClassArrayMemberToStringSymbol).apply {
|
||||
putValueArgument(0, irPropertyValue)
|
||||
}
|
||||
else
|
||||
irPropertyValue
|
||||
irConcat.addArgument(irPropertyStringValue)
|
||||
first = false
|
||||
}
|
||||
|
||||
+54
-52
@@ -34,48 +34,50 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
|
||||
class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
fun generateMemberDeclaration(ktDeclaration: KtDeclaration): IrDeclaration =
|
||||
when (ktDeclaration) {
|
||||
is KtNamedFunction ->
|
||||
FunctionGenerator(this).generateFunctionDeclaration(ktDeclaration)
|
||||
is KtProperty ->
|
||||
PropertyGenerator(this).generatePropertyDeclaration(ktDeclaration)
|
||||
is KtClassOrObject ->
|
||||
generateClassOrObjectDeclaration(ktDeclaration)
|
||||
is KtTypeAlias ->
|
||||
generateTypeAliasDeclaration(ktDeclaration)
|
||||
else ->
|
||||
IrErrorDeclarationImpl(
|
||||
ktDeclaration.startOffset, ktDeclaration.endOffset,
|
||||
getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration)
|
||||
)
|
||||
}
|
||||
when (ktDeclaration) {
|
||||
is KtNamedFunction ->
|
||||
FunctionGenerator(this).generateFunctionDeclaration(ktDeclaration)
|
||||
is KtProperty ->
|
||||
PropertyGenerator(this).generatePropertyDeclaration(ktDeclaration)
|
||||
is KtClassOrObject ->
|
||||
generateClassOrObjectDeclaration(ktDeclaration)
|
||||
is KtTypeAlias ->
|
||||
generateTypeAliasDeclaration(ktDeclaration)
|
||||
else ->
|
||||
IrErrorDeclarationImpl(
|
||||
ktDeclaration.startOffset, ktDeclaration.endOffset,
|
||||
getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration)
|
||||
)
|
||||
}
|
||||
|
||||
fun generateClassMemberDeclaration(ktDeclaration: KtDeclaration, classDescriptor: ClassDescriptor): IrDeclaration =
|
||||
when (ktDeclaration) {
|
||||
is KtAnonymousInitializer ->
|
||||
AnonymousInitializerGenerator(this).generateAnonymousInitializerDeclaration(ktDeclaration, classDescriptor)
|
||||
is KtSecondaryConstructor ->
|
||||
FunctionGenerator(this).generateSecondaryConstructor(ktDeclaration)
|
||||
is KtEnumEntry ->
|
||||
generateEnumEntryDeclaration(ktDeclaration)
|
||||
else ->
|
||||
generateMemberDeclaration(ktDeclaration)
|
||||
}
|
||||
when (ktDeclaration) {
|
||||
is KtAnonymousInitializer ->
|
||||
AnonymousInitializerGenerator(this).generateAnonymousInitializerDeclaration(ktDeclaration, classDescriptor)
|
||||
is KtSecondaryConstructor ->
|
||||
FunctionGenerator(this).generateSecondaryConstructor(ktDeclaration)
|
||||
is KtEnumEntry ->
|
||||
generateEnumEntryDeclaration(ktDeclaration)
|
||||
else ->
|
||||
generateMemberDeclaration(ktDeclaration)
|
||||
}
|
||||
|
||||
private fun generateEnumEntryDeclaration(ktEnumEntry: KtEnumEntry): IrEnumEntry =
|
||||
ClassGenerator(this).generateEnumEntry(ktEnumEntry)
|
||||
ClassGenerator(this).generateEnumEntry(ktEnumEntry)
|
||||
|
||||
fun generateClassOrObjectDeclaration(ktClassOrObject: KtClassOrObject): IrClass =
|
||||
ClassGenerator(this).generateClass(ktClassOrObject)
|
||||
ClassGenerator(this).generateClass(ktClassOrObject)
|
||||
|
||||
fun generateTypeAliasDeclaration(ktDeclaration: KtTypeAlias): IrDeclaration =
|
||||
IrTypeAliasImpl(ktDeclaration.startOffset, ktDeclaration.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
getOrFail(BindingContext.TYPE_ALIAS, ktDeclaration))
|
||||
IrTypeAliasImpl(
|
||||
ktDeclaration.startOffset, ktDeclaration.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
getOrFail(BindingContext.TYPE_ALIAS, ktDeclaration)
|
||||
)
|
||||
|
||||
|
||||
fun generateTypeParameterDeclarations(
|
||||
irTypeParametersOwner: IrTypeParametersContainer,
|
||||
from: List<TypeParameterDescriptor>
|
||||
irTypeParametersOwner: IrTypeParametersContainer,
|
||||
from: List<TypeParameterDescriptor>
|
||||
) {
|
||||
from.mapTo(irTypeParametersOwner.typeParameters) { typeParameterDescriptor ->
|
||||
val ktTypeParameterDeclaration = DescriptorToSourceUtils.getSourceFromDescriptor(typeParameterDescriptor)
|
||||
@@ -86,7 +88,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
}
|
||||
|
||||
fun generateInitializerBody(scopeOwnerSymbol: IrSymbol, ktBody: KtExpression): IrExpressionBody =
|
||||
createBodyGenerator(scopeOwnerSymbol).generateExpressionBody(ktBody)
|
||||
createBodyGenerator(scopeOwnerSymbol).generateExpressionBody(ktBody)
|
||||
|
||||
fun generateFakeOverrideDeclaration(memberDescriptor: CallableMemberDescriptor, ktElement: KtElement): IrDeclaration {
|
||||
assert(memberDescriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||
@@ -103,35 +105,35 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
}
|
||||
|
||||
private fun generateFakeOverrideProperty(propertyDescriptor: PropertyDescriptor, ktElement: KtElement): IrProperty =
|
||||
IrPropertyImpl(
|
||||
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
false,
|
||||
propertyDescriptor,
|
||||
if (propertyDescriptor.getter == null)
|
||||
context.symbolTable.declareField(
|
||||
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
propertyDescriptor
|
||||
)
|
||||
else null,
|
||||
propertyDescriptor.getter?.let { generateFakeOverrideFunction(it, ktElement) },
|
||||
propertyDescriptor.setter?.let { generateFakeOverrideFunction(it, ktElement) }
|
||||
)
|
||||
IrPropertyImpl(
|
||||
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
false,
|
||||
propertyDescriptor,
|
||||
if (propertyDescriptor.getter == null)
|
||||
context.symbolTable.declareField(
|
||||
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
propertyDescriptor
|
||||
)
|
||||
else null,
|
||||
propertyDescriptor.getter?.let { generateFakeOverrideFunction(it, ktElement) },
|
||||
propertyDescriptor.setter?.let { generateFakeOverrideFunction(it, ktElement) }
|
||||
)
|
||||
|
||||
private fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtElement): IrFunction =
|
||||
FunctionGenerator(this).generateFakeOverrideFunction(functionDescriptor, ktElement)
|
||||
FunctionGenerator(this).generateFakeOverrideFunction(functionDescriptor, ktElement)
|
||||
}
|
||||
|
||||
abstract class DeclarationGeneratorExtension(val declarationGenerator: DeclarationGenerator) : Generator {
|
||||
override val context: GeneratorContext get() = declarationGenerator.context
|
||||
|
||||
inline fun <T : IrDeclaration> T.buildWithScope(builder: (T) -> Unit): T =
|
||||
also { irDeclaration ->
|
||||
context.symbolTable.withScope(irDeclaration.descriptor) {
|
||||
builder(irDeclaration)
|
||||
}
|
||||
also { irDeclaration ->
|
||||
context.symbolTable.withScope(irDeclaration.descriptor) {
|
||||
builder(irDeclaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Generator.createBodyGenerator(scopeOwnerSymbol: IrSymbol) =
|
||||
BodyGenerator(scopeOwnerSymbol, context)
|
||||
BodyGenerator(scopeOwnerSymbol, context)
|
||||
+170
-152
@@ -46,16 +46,16 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
constructor(context: GeneratorContext) : this(DeclarationGenerator(context))
|
||||
|
||||
fun generateDelegatedProperty(
|
||||
ktProperty: KtProperty,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
propertyDescriptor: PropertyDescriptor
|
||||
ktProperty: KtProperty,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
propertyDescriptor: PropertyDescriptor
|
||||
): IrProperty {
|
||||
|
||||
val kPropertyType = getKPropertyTypeForDelegatedProperty(propertyDescriptor)
|
||||
|
||||
val irProperty = IrPropertyImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED, true,
|
||||
propertyDescriptor
|
||||
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED, true,
|
||||
propertyDescriptor
|
||||
).apply {
|
||||
backingField = generateDelegateFieldForProperty(propertyDescriptor, kPropertyType, ktDelegate)
|
||||
}
|
||||
@@ -67,9 +67,9 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
val getterDescriptor = propertyDescriptor.getter!!
|
||||
irProperty.getter = generateDelegatedPropertyAccessor(ktProperty, ktDelegate, getterDescriptor) { irGetter ->
|
||||
generateDelegatedPropertyGetterBody(
|
||||
irGetter,
|
||||
ktDelegate, getterDescriptor, delegateReceiverValue,
|
||||
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor, irGetter.symbol)
|
||||
irGetter,
|
||||
ktDelegate, getterDescriptor, delegateReceiverValue,
|
||||
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor, irGetter.symbol)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -77,9 +77,9 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
val setterDescriptor = propertyDescriptor.setter!!
|
||||
irProperty.setter = generateDelegatedPropertyAccessor(ktProperty, ktDelegate, setterDescriptor) { irSetter ->
|
||||
generateDelegatedPropertySetterBody(
|
||||
irSetter,
|
||||
ktDelegate, setterDescriptor, delegateReceiverValue,
|
||||
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor, irSetter.symbol)
|
||||
irSetter,
|
||||
ktDelegate, setterDescriptor, delegateReceiverValue,
|
||||
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor, irSetter.symbol)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -88,131 +88,143 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
}
|
||||
|
||||
private inline fun generateDelegatedPropertyAccessor(
|
||||
ktProperty: KtProperty,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
accessorDescriptor: PropertyAccessorDescriptor,
|
||||
generateBody: (IrFunction) -> IrBody
|
||||
ktProperty: KtProperty,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
accessorDescriptor: PropertyAccessorDescriptor,
|
||||
generateBody: (IrFunction) -> IrBody
|
||||
): IrFunction =
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset,
|
||||
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
|
||||
accessorDescriptor
|
||||
).buildWithScope { irAccessor ->
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irAccessor, ktProperty, null)
|
||||
irAccessor.body = generateBody(irAccessor)
|
||||
}
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset,
|
||||
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
|
||||
accessorDescriptor
|
||||
).buildWithScope { irAccessor ->
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irAccessor, ktProperty, null)
|
||||
irAccessor.body = generateBody(irAccessor)
|
||||
}
|
||||
|
||||
|
||||
private fun getKPropertyTypeForDelegatedProperty(propertyDescriptor: PropertyDescriptor): KotlinType {
|
||||
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(
|
||||
propertyDescriptor: PropertyDescriptor,
|
||||
kPropertyType: KotlinType,
|
||||
ktDelegate: KtPropertyDelegate
|
||||
propertyDescriptor: PropertyDescriptor,
|
||||
kPropertyType: KotlinType,
|
||||
ktDelegate: KtPropertyDelegate
|
||||
): IrField {
|
||||
val delegateType = getDelegatedPropertyDelegateType(propertyDescriptor, ktDelegate)
|
||||
val delegateDescriptor = createPropertyDelegateDescriptor(propertyDescriptor, delegateType, kPropertyType)
|
||||
|
||||
return context.symbolTable.declareField(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor
|
||||
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor
|
||||
).also { irDelegate ->
|
||||
irDelegate.initializer = generateInitializerBodyForPropertyDelegate(
|
||||
propertyDescriptor, kPropertyType, ktDelegate,
|
||||
irDelegate.symbol
|
||||
propertyDescriptor, kPropertyType, ktDelegate,
|
||||
irDelegate.symbol
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateInitializerBodyForPropertyDelegate(
|
||||
property: VariableDescriptorWithAccessors,
|
||||
kPropertyType: KotlinType,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
scopeOwner: IrSymbol
|
||||
property: VariableDescriptorWithAccessors,
|
||||
kPropertyType: KotlinType,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
scopeOwner: IrSymbol
|
||||
): IrExpressionBody {
|
||||
val ktDelegateExpression = ktDelegate.expression!!
|
||||
val irDelegateInitializer = declarationGenerator.generateInitializerBody(scopeOwner, ktDelegateExpression)
|
||||
|
||||
val provideDelegateResolvedCall = get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, property)
|
||||
?: return irDelegateInitializer
|
||||
?: return irDelegateInitializer
|
||||
|
||||
val statementGenerator = createBodyGenerator(scopeOwner).createStatementGenerator()
|
||||
val provideDelegateCall = statementGenerator.pregenerateCall(provideDelegateResolvedCall)
|
||||
provideDelegateCall.setExplicitReceiverValue(OnceExpressionValue(irDelegateInitializer.expression))
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
return BackingFieldLValue(ktDelegate.startOffset, ktDelegate.endOffset,
|
||||
irDelegateField.descriptor.type,
|
||||
irDelegateField,
|
||||
thisValue,
|
||||
null)
|
||||
return BackingFieldLValue(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset,
|
||||
irDelegateField.descriptor.type,
|
||||
irDelegateField,
|
||||
thisValue,
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
private fun createThisValueForDelegate(thisClass: ClassDescriptor?, ktDelegate: KtPropertyDelegate): IntermediateValue? =
|
||||
thisClass?.let {
|
||||
generateExpressionValue(it.thisAsReceiverParameter.type) {
|
||||
IrGetValueImpl(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset,
|
||||
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter)
|
||||
)
|
||||
}
|
||||
thisClass?.let {
|
||||
generateExpressionValue(it.thisAsReceiverParameter.type) {
|
||||
IrGetValueImpl(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset,
|
||||
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createCallableReference(
|
||||
ktElement: KtElement,
|
||||
type: KotlinType,
|
||||
referencedDescriptor: CallableDescriptor,
|
||||
statementGenerator: StatementGenerator
|
||||
ktElement: KtElement,
|
||||
type: KotlinType,
|
||||
referencedDescriptor: CallableDescriptor,
|
||||
statementGenerator: StatementGenerator
|
||||
): IrCallableReference =
|
||||
ReflectionReferencesGenerator(statementGenerator).generateCallableReference(
|
||||
ktElement.startOffset, ktElement.endOffset, type,
|
||||
referencedDescriptor,
|
||||
null, IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
)
|
||||
ReflectionReferencesGenerator(statementGenerator).generateCallableReference(
|
||||
ktElement.startOffset, ktElement.endOffset, type,
|
||||
referencedDescriptor,
|
||||
null, IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
)
|
||||
|
||||
private fun createCallableReference(
|
||||
ktElement: KtElement,
|
||||
type: KotlinType,
|
||||
referencedDescriptor: CallableDescriptor,
|
||||
scopeOwner: IrSymbol
|
||||
ktElement: KtElement,
|
||||
type: KotlinType,
|
||||
referencedDescriptor: CallableDescriptor,
|
||||
scopeOwner: IrSymbol
|
||||
): IrCallableReference =
|
||||
createCallableReference(
|
||||
ktElement, type, referencedDescriptor,
|
||||
createBodyGenerator(scopeOwner).createStatementGenerator()
|
||||
)
|
||||
createCallableReference(
|
||||
ktElement, type, referencedDescriptor,
|
||||
createBodyGenerator(scopeOwner).createStatementGenerator()
|
||||
)
|
||||
|
||||
private fun createLocalDelegatedPropertyReference(
|
||||
ktElement: KtElement,
|
||||
type: KotlinType,
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
irDelegateSymbol: IrVariableSymbol,
|
||||
scopeOwner: IrSymbol
|
||||
ktElement: KtElement,
|
||||
type: KotlinType,
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
irDelegateSymbol: IrVariableSymbol,
|
||||
scopeOwner: IrSymbol
|
||||
): IrLocalDelegatedPropertyReference =
|
||||
ReflectionReferencesGenerator(createBodyGenerator(scopeOwner).createStatementGenerator()).generateLocalDelegatedPropertyReference(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
type, variableDescriptor, irDelegateSymbol,
|
||||
IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
)
|
||||
ReflectionReferencesGenerator(createBodyGenerator(scopeOwner).createStatementGenerator()).generateLocalDelegatedPropertyReference(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
type, variableDescriptor, irDelegateSymbol,
|
||||
IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
)
|
||||
|
||||
fun generateLocalDelegatedProperty(
|
||||
ktProperty: KtProperty,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
scopeOwnerSymbol: IrSymbol
|
||||
ktProperty: KtProperty,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
scopeOwnerSymbol: IrSymbol
|
||||
): IrLocalDelegatedProperty {
|
||||
val kPropertyType = getKPropertyTypeForLocalDelegatedProperty(variableDescriptor)
|
||||
|
||||
val irLocalDelegatedProperty = IrLocalDelegatedPropertyImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
variableDescriptor
|
||||
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
variableDescriptor
|
||||
).apply {
|
||||
delegate = generateDelegateVariableForLocalDelegatedProperty(ktDelegate, variableDescriptor, kPropertyType, scopeOwnerSymbol)
|
||||
}
|
||||
@@ -224,12 +236,12 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
irLocalDelegatedProperty.getter =
|
||||
createLocalPropertyAccessor(getterDescriptor, ktDelegate) { irGetter ->
|
||||
generateDelegatedPropertyGetterBody(
|
||||
irGetter,ktDelegate, getterDescriptor, delegateReceiverValue,
|
||||
createLocalDelegatedPropertyReference(
|
||||
ktDelegate, kPropertyType,
|
||||
variableDescriptor, irDelegate.symbol,
|
||||
irGetter.symbol
|
||||
)
|
||||
irGetter, ktDelegate, getterDescriptor, delegateReceiverValue,
|
||||
createLocalDelegatedPropertyReference(
|
||||
ktDelegate, kPropertyType,
|
||||
variableDescriptor, irDelegate.symbol,
|
||||
irGetter.symbol
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -238,12 +250,12 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
irLocalDelegatedProperty.setter =
|
||||
createLocalPropertyAccessor(setterDescriptor, ktDelegate) { irSetter ->
|
||||
generateDelegatedPropertySetterBody(
|
||||
irSetter, ktDelegate, setterDescriptor, delegateReceiverValue,
|
||||
createLocalDelegatedPropertyReference(
|
||||
ktDelegate, kPropertyType,
|
||||
variableDescriptor, irDelegate.symbol,
|
||||
irSetter.symbol
|
||||
)
|
||||
irSetter, ktDelegate, setterDescriptor, delegateReceiverValue,
|
||||
createLocalDelegatedPropertyReference(
|
||||
ktDelegate, kPropertyType,
|
||||
variableDescriptor, irDelegate.symbol,
|
||||
irSetter.symbol
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -252,29 +264,29 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
}
|
||||
|
||||
private fun generateDelegateVariableForLocalDelegatedProperty(
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
kPropertyType: KotlinType,
|
||||
scopeOwner: IrSymbol
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
kPropertyType: KotlinType,
|
||||
scopeOwner: IrSymbol
|
||||
): IrVariable {
|
||||
val delegateType = getDelegatedPropertyDelegateType(variableDescriptor, ktDelegate)
|
||||
val delegateDescriptor = createLocalPropertyDelegatedDescriptor(variableDescriptor, delegateType, kPropertyType)
|
||||
|
||||
return context.symbolTable.declareVariable(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor
|
||||
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor
|
||||
).also { irVariable ->
|
||||
irVariable.initializer = generateInitializerForLocalDelegatedPropertyDelegate(
|
||||
variableDescriptor, kPropertyType, ktDelegate,
|
||||
irVariable.symbol,
|
||||
scopeOwner
|
||||
variableDescriptor, kPropertyType, ktDelegate,
|
||||
irVariable.symbol,
|
||||
scopeOwner
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getDelegatedPropertyDelegateType(
|
||||
delegatedPropertyDescriptor: VariableDescriptorWithAccessors,
|
||||
ktDelegate: KtPropertyDelegate
|
||||
delegatedPropertyDescriptor: VariableDescriptorWithAccessors,
|
||||
ktDelegate: KtPropertyDelegate
|
||||
): KotlinType {
|
||||
val provideDelegateResolvedCall = get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, delegatedPropertyDescriptor)
|
||||
return if (provideDelegateResolvedCall != null)
|
||||
@@ -284,17 +296,17 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
}
|
||||
|
||||
private fun generateInitializerForLocalDelegatedPropertyDelegate(
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
kPropertyType: KotlinType,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
delegateSymbol: IrVariableSymbol,
|
||||
scopeOwner: IrSymbol
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
kPropertyType: KotlinType,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
delegateSymbol: IrVariableSymbol,
|
||||
scopeOwner: IrSymbol
|
||||
): IrExpression {
|
||||
val ktDelegateExpression = ktDelegate.expression!!
|
||||
val irDelegateInitializer = createBodyGenerator(scopeOwner).createStatementGenerator().generateExpression(ktDelegateExpression)
|
||||
|
||||
val provideDelegateResolvedCall = get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, variableDescriptor) ?:
|
||||
return irDelegateInitializer
|
||||
val provideDelegateResolvedCall =
|
||||
get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, variableDescriptor) ?: return irDelegateInitializer
|
||||
|
||||
val statementGenerator = createBodyGenerator(scopeOwner).createStatementGenerator()
|
||||
|
||||
@@ -308,64 +320,70 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
}
|
||||
|
||||
private fun createVariableValueForDelegate(irDelegate: IrVariableSymbol, ktDelegate: KtPropertyDelegate) =
|
||||
VariableLValue(ktDelegate.startOffset, ktDelegate.endOffset, irDelegate)
|
||||
VariableLValue(ktDelegate.startOffset, ktDelegate.endOffset, irDelegate)
|
||||
|
||||
private inline fun createLocalPropertyAccessor(
|
||||
getterDescriptor: VariableAccessorDescriptor,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
generateBody: (IrFunction) -> IrBody
|
||||
getterDescriptor: VariableAccessorDescriptor,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
generateBody: (IrFunction) -> IrBody
|
||||
) =
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset,
|
||||
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
|
||||
getterDescriptor
|
||||
).buildWithScope { irAccessor ->
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irAccessor, ktDelegate, null)
|
||||
irAccessor.body = generateBody(irAccessor)
|
||||
}
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset,
|
||||
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
|
||||
getterDescriptor
|
||||
).buildWithScope { irAccessor ->
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irAccessor, ktDelegate, null)
|
||||
irAccessor.body = generateBody(irAccessor)
|
||||
}
|
||||
|
||||
private fun createLocalPropertyDelegatedDescriptor(
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
delegateType: KotlinType,
|
||||
kPropertyType: KotlinType
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
delegateType: KotlinType,
|
||||
kPropertyType: KotlinType
|
||||
): IrLocalDelegatedPropertyDelegateDescriptor {
|
||||
return IrLocalDelegatedPropertyDelegateDescriptorImpl(variableDescriptor, delegateType, kPropertyType)
|
||||
}
|
||||
|
||||
private fun getKPropertyTypeForLocalDelegatedProperty(variableDescriptor: VariableDescriptorWithAccessors) =
|
||||
context.reflectionTypes.getKPropertyType(Annotations.EMPTY, emptyList(), variableDescriptor.type, variableDescriptor.isVar)
|
||||
context.reflectionTypes.getKPropertyType(Annotations.EMPTY, emptyList(), variableDescriptor.type, variableDescriptor.isVar)
|
||||
|
||||
private fun createPropertyDelegateDescriptor(
|
||||
propertyDescriptor: PropertyDescriptor,
|
||||
delegateType: KotlinType,
|
||||
kPropertyType: KotlinType
|
||||
propertyDescriptor: PropertyDescriptor,
|
||||
delegateType: KotlinType,
|
||||
kPropertyType: KotlinType
|
||||
): IrPropertyDelegateDescriptor =
|
||||
IrPropertyDelegateDescriptorImpl(propertyDescriptor, delegateType, kPropertyType)
|
||||
IrPropertyDelegateDescriptorImpl(propertyDescriptor, delegateType, kPropertyType)
|
||||
|
||||
private fun generateDelegatedPropertyGetterBody(
|
||||
irGetter: IrFunction,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
getterDescriptor: VariableAccessorDescriptor,
|
||||
delegateReceiverValue: IntermediateValue,
|
||||
irPropertyReference: IrCallableReference
|
||||
irGetter: IrFunction,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
getterDescriptor: VariableAccessorDescriptor,
|
||||
delegateReceiverValue: IntermediateValue,
|
||||
irPropertyReference: IrCallableReference
|
||||
): IrBody =
|
||||
with(createBodyGenerator(irGetter.symbol)) {
|
||||
irBlockBody(ktDelegate) {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor)
|
||||
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
||||
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
|
||||
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
|
||||
+irReturn(CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, conventionMethodCall))
|
||||
}
|
||||
with(createBodyGenerator(irGetter.symbol)) {
|
||||
irBlockBody(ktDelegate) {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor)
|
||||
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
||||
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
|
||||
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
|
||||
+irReturn(
|
||||
CallGenerator(statementGenerator).generateCall(
|
||||
ktDelegate.startOffset,
|
||||
ktDelegate.endOffset,
|
||||
conventionMethodCall
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateDelegatedPropertySetterBody(
|
||||
irSetter: IrFunction,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
setterDescriptor: VariableAccessorDescriptor,
|
||||
delegateReceiverValue: IntermediateValue,
|
||||
irPropertyReference: IrCallableReference
|
||||
irSetter: IrFunction,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
setterDescriptor: VariableAccessorDescriptor,
|
||||
delegateReceiverValue: IntermediateValue,
|
||||
irPropertyReference: IrCallableReference
|
||||
): IrBody = with(createBodyGenerator(irSetter.symbol)) {
|
||||
irBlockBody(ktDelegate) {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
|
||||
+20
-20
@@ -33,38 +33,38 @@ class EnumClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
private fun generateValues(irClass: IrClass) {
|
||||
val valuesFunction = irClass.descriptor.staticScope.findFirstFunction("values") {
|
||||
it.dispatchReceiverParameter == null &&
|
||||
it.extensionReceiverParameter == null &&
|
||||
it.valueParameters.size == 0
|
||||
it.extensionReceiverParameter == null &&
|
||||
it.valueParameters.size == 0
|
||||
}
|
||||
|
||||
irClass.addMember(
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
irClass.startOffset, irClass.endOffset,
|
||||
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER,
|
||||
valuesFunction
|
||||
).also { irFunction ->
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irFunction, null, null)
|
||||
irFunction.body = IrSyntheticBodyImpl(irClass.startOffset, irClass.endOffset, IrSyntheticBodyKind.ENUM_VALUES)
|
||||
}
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
irClass.startOffset, irClass.endOffset,
|
||||
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER,
|
||||
valuesFunction
|
||||
).also { irFunction ->
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irFunction, null, null)
|
||||
irFunction.body = IrSyntheticBodyImpl(irClass.startOffset, irClass.endOffset, IrSyntheticBodyKind.ENUM_VALUES)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateValueOf(irClass: IrClass) {
|
||||
val valueOfFunction = irClass.descriptor.staticScope.findFirstFunction("valueOf") {
|
||||
it.dispatchReceiverParameter == null &&
|
||||
it.extensionReceiverParameter == null &&
|
||||
it.valueParameters.size == 1
|
||||
it.extensionReceiverParameter == null &&
|
||||
it.valueParameters.size == 1
|
||||
}
|
||||
|
||||
irClass.addMember(
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER,
|
||||
valueOfFunction
|
||||
).also { irFunction ->
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irFunction, null, null)
|
||||
irFunction.body = IrSyntheticBodyImpl(irClass.startOffset, irClass.endOffset, IrSyntheticBodyKind.ENUM_VALUEOF)
|
||||
}
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER,
|
||||
valueOfFunction
|
||||
).also { irFunction ->
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irFunction, null, null)
|
||||
irFunction.body = IrSyntheticBodyImpl(irClass.startOffset, irClass.endOffset, IrSyntheticBodyKind.ENUM_VALUEOF)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+12
-10
@@ -28,17 +28,19 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
|
||||
private val ignoreErrors: Boolean get() = context.configuration.ignoreErrors
|
||||
|
||||
private inline fun generateErrorExpression(ktElement: KtElement, e: Exception? = null, body: () -> IrExpression) =
|
||||
if (ignoreErrors)
|
||||
body()
|
||||
else
|
||||
throw RuntimeException("${e?.message}: ${ktElement::class.java.simpleName}:\n${ktElement.text}", e)
|
||||
if (ignoreErrors)
|
||||
body()
|
||||
else
|
||||
throw RuntimeException("${e?.message}: ${ktElement::class.java.simpleName}:\n${ktElement.text}", e)
|
||||
|
||||
fun generateErrorExpression(ktElement: KtElement, e: Exception): IrExpression =
|
||||
generateErrorExpression(ktElement, e) {
|
||||
IrErrorExpressionImpl(ktElement.startOffset, ktElement.endOffset,
|
||||
if (ktElement is KtExpression) getErrorExpressionType(ktElement) else ErrorUtils.createErrorType(""),
|
||||
e.message ?: "")
|
||||
}
|
||||
generateErrorExpression(ktElement, e) {
|
||||
IrErrorExpressionImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
if (ktElement is KtExpression) getErrorExpressionType(ktElement) else ErrorUtils.createErrorType(""),
|
||||
e.message ?: ""
|
||||
)
|
||||
}
|
||||
|
||||
fun generateErrorCall(ktCall: KtCallExpression): IrExpression = generateErrorExpression(ktCall) {
|
||||
val type = getErrorExpressionType(ktCall)
|
||||
@@ -63,7 +65,7 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
|
||||
}
|
||||
|
||||
private fun getErrorExpressionType(ktExpression: KtExpression) =
|
||||
getInferredTypeWithImplicitCasts(ktExpression) ?: ErrorUtils.createErrorType("")
|
||||
getInferredTypeWithImplicitCasts(ktExpression) ?: ErrorUtils.createErrorType("")
|
||||
|
||||
fun generateErrorSimpleName(ktName: KtSimpleNameExpression): IrExpression = generateErrorExpression(ktName) {
|
||||
val type = getErrorExpressionType(ktName)
|
||||
|
||||
+152
-142
@@ -35,103 +35,107 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
constructor(context: GeneratorContext) : this(DeclarationGenerator(context))
|
||||
|
||||
fun generateFunctionDeclaration(ktFunction: KtNamedFunction): IrFunction =
|
||||
declareSimpleFunction(
|
||||
ktFunction,
|
||||
ktFunction.receiverTypeReference,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
getOrFail(BindingContext.FUNCTION, ktFunction)
|
||||
) {
|
||||
ktFunction.bodyExpression?.let { generateFunctionBody(it) }
|
||||
}
|
||||
declareSimpleFunction(
|
||||
ktFunction,
|
||||
ktFunction.receiverTypeReference,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
getOrFail(BindingContext.FUNCTION, ktFunction)
|
||||
) {
|
||||
ktFunction.bodyExpression?.let { generateFunctionBody(it) }
|
||||
}
|
||||
|
||||
fun generateLambdaFunctionDeclaration(ktFunction: KtFunctionLiteral): IrFunction =
|
||||
declareSimpleFunction(
|
||||
ktFunction,
|
||||
null,
|
||||
IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA,
|
||||
getOrFail(BindingContext.FUNCTION, ktFunction)
|
||||
) {
|
||||
generateLambdaBody(ktFunction)
|
||||
}
|
||||
declareSimpleFunction(
|
||||
ktFunction,
|
||||
null,
|
||||
IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA,
|
||||
getOrFail(BindingContext.FUNCTION, ktFunction)
|
||||
) {
|
||||
generateLambdaBody(ktFunction)
|
||||
}
|
||||
|
||||
fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtElement): IrFunction =
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
functionDescriptor
|
||||
).buildWithScope { irFunction ->
|
||||
generateFunctionParameterDeclarations(irFunction, ktElement, null)
|
||||
}
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
functionDescriptor
|
||||
).buildWithScope { irFunction ->
|
||||
generateFunctionParameterDeclarations(irFunction, ktElement, null)
|
||||
}
|
||||
|
||||
private inline fun declareSimpleFunction(
|
||||
ktFunction: KtFunction,
|
||||
ktReceiver: KtElement?,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: FunctionDescriptor,
|
||||
generateBody: BodyGenerator.() -> IrBody?
|
||||
ktFunction: KtFunction,
|
||||
ktReceiver: KtElement?,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: FunctionDescriptor,
|
||||
generateBody: BodyGenerator.() -> IrBody?
|
||||
): IrSimpleFunction =
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
ktFunction.startOffset, ktFunction.endOffset, origin, descriptor
|
||||
).buildWithScope { irFunction ->
|
||||
generateFunctionParameterDeclarations(irFunction, ktFunction, ktReceiver)
|
||||
irFunction.body = createBodyGenerator(irFunction.symbol).generateBody()
|
||||
}
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
ktFunction.startOffset, ktFunction.endOffset, origin, descriptor
|
||||
).buildWithScope { irFunction ->
|
||||
generateFunctionParameterDeclarations(irFunction, ktFunction, ktReceiver)
|
||||
irFunction.body = createBodyGenerator(irFunction.symbol).generateBody()
|
||||
}
|
||||
|
||||
fun generateFunctionParameterDeclarations(
|
||||
irFunction: IrFunction,
|
||||
ktParameterOwner: KtElement?,
|
||||
ktReceiverParameterElement: KtElement?
|
||||
irFunction: IrFunction,
|
||||
ktParameterOwner: KtElement?,
|
||||
ktReceiverParameterElement: KtElement?
|
||||
) {
|
||||
declarationGenerator.generateTypeParameterDeclarations(irFunction, irFunction.descriptor.typeParameters)
|
||||
generateValueParameterDeclarations(irFunction, ktParameterOwner, ktReceiverParameterElement)
|
||||
}
|
||||
|
||||
fun generatePropertyAccessor(
|
||||
descriptor: PropertyAccessorDescriptor,
|
||||
ktProperty: KtProperty,
|
||||
ktAccessor: KtPropertyAccessor?
|
||||
descriptor: PropertyAccessorDescriptor,
|
||||
ktProperty: KtProperty,
|
||||
ktAccessor: KtPropertyAccessor?
|
||||
): IrSimpleFunction =
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
ktAccessor?.startOffset ?: ktProperty.startOffset,
|
||||
ktAccessor?.endOffset ?: ktProperty.endOffset,
|
||||
if (ktAccessor != null) IrDeclarationOrigin.DEFINED else IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
|
||||
descriptor
|
||||
).buildWithScope { irAccessor ->
|
||||
generateFunctionParameterDeclarations(irAccessor, ktAccessor ?: ktProperty, ktProperty.receiverTypeReference)
|
||||
val ktBodyExpression = ktAccessor?.bodyExpression
|
||||
irAccessor.body =
|
||||
if (ktBodyExpression != null)
|
||||
createBodyGenerator(irAccessor.symbol).generateFunctionBody(ktBodyExpression)
|
||||
else
|
||||
generateDefaultAccessorBody(ktProperty, descriptor, irAccessor)
|
||||
}
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
ktAccessor?.startOffset ?: ktProperty.startOffset,
|
||||
ktAccessor?.endOffset ?: ktProperty.endOffset,
|
||||
if (ktAccessor != null) IrDeclarationOrigin.DEFINED else IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
|
||||
descriptor
|
||||
).buildWithScope { irAccessor ->
|
||||
generateFunctionParameterDeclarations(irAccessor, ktAccessor ?: ktProperty, ktProperty.receiverTypeReference)
|
||||
val ktBodyExpression = ktAccessor?.bodyExpression
|
||||
irAccessor.body =
|
||||
if (ktBodyExpression != null)
|
||||
createBodyGenerator(irAccessor.symbol).generateFunctionBody(ktBodyExpression)
|
||||
else
|
||||
generateDefaultAccessorBody(ktProperty, descriptor, irAccessor)
|
||||
}
|
||||
|
||||
fun generateDefaultAccessorForPrimaryConstructorParameter(
|
||||
descriptor: PropertyAccessorDescriptor,
|
||||
ktParameter: KtParameter
|
||||
descriptor: PropertyAccessorDescriptor,
|
||||
ktParameter: KtParameter
|
||||
): IrFunction =
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
ktParameter.startOffsetOrUndefined,
|
||||
ktParameter.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
|
||||
descriptor
|
||||
).buildWithScope { irAccessor ->
|
||||
declarationGenerator.generateTypeParameterDeclarations(irAccessor, descriptor.typeParameters)
|
||||
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irAccessor)
|
||||
irAccessor.body = generateDefaultAccessorBody(ktParameter, descriptor, irAccessor)
|
||||
}
|
||||
context.symbolTable.declareSimpleFunction(
|
||||
ktParameter.startOffsetOrUndefined,
|
||||
ktParameter.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
|
||||
descriptor
|
||||
).buildWithScope { irAccessor ->
|
||||
declarationGenerator.generateTypeParameterDeclarations(irAccessor, descriptor.typeParameters)
|
||||
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irAccessor)
|
||||
irAccessor.body = generateDefaultAccessorBody(ktParameter, descriptor, irAccessor)
|
||||
}
|
||||
|
||||
private fun generateDefaultAccessorBody(ktProperty: KtElement, accessor: PropertyAccessorDescriptor, irAccessor: IrSimpleFunction) =
|
||||
if (accessor.modality == Modality.ABSTRACT)
|
||||
null
|
||||
else
|
||||
when (accessor) {
|
||||
is PropertyGetterDescriptor -> generateDefaultGetterBody(ktProperty, accessor, irAccessor)
|
||||
is PropertySetterDescriptor -> generateDefaultSetterBody(ktProperty, accessor, irAccessor)
|
||||
else -> throw AssertionError("Should be getter or setter: $accessor")
|
||||
}
|
||||
if (accessor.modality == Modality.ABSTRACT)
|
||||
null
|
||||
else
|
||||
when (accessor) {
|
||||
is PropertyGetterDescriptor -> generateDefaultGetterBody(ktProperty, accessor, irAccessor)
|
||||
is PropertySetterDescriptor -> generateDefaultSetterBody(ktProperty, accessor, irAccessor)
|
||||
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 irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
|
||||
@@ -139,20 +143,24 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
|
||||
|
||||
irBody.statements.add(
|
||||
IrReturnImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset, context.builtIns.nothingType,
|
||||
irAccessor.symbol,
|
||||
IrGetFieldImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset,
|
||||
context.symbolTable.referenceField(property),
|
||||
receiver
|
||||
)
|
||||
IrReturnImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset, context.builtIns.nothingType,
|
||||
irAccessor.symbol,
|
||||
IrGetFieldImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset,
|
||||
context.symbolTable.referenceField(property),
|
||||
receiver
|
||||
)
|
||||
)
|
||||
)
|
||||
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 irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
|
||||
@@ -161,12 +169,12 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
|
||||
val setterParameter = irAccessor.valueParameters.single().symbol
|
||||
irBody.statements.add(
|
||||
IrSetFieldImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset,
|
||||
context.symbolTable.referenceField(property),
|
||||
receiver,
|
||||
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset, setterParameter)
|
||||
)
|
||||
IrSetFieldImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset,
|
||||
context.symbolTable.referenceField(property),
|
||||
receiver,
|
||||
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset, setterParameter)
|
||||
)
|
||||
)
|
||||
return irBody
|
||||
}
|
||||
@@ -175,44 +183,46 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
val containingDeclaration = property.containingDeclaration
|
||||
return when (containingDeclaration) {
|
||||
is ClassDescriptor ->
|
||||
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset,
|
||||
context.symbolTable.referenceValue(containingDeclaration.thisAsReceiverParameter))
|
||||
IrGetValueImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset,
|
||||
context.symbolTable.referenceValue(containingDeclaration.thisAsReceiverParameter)
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun generatePrimaryConstructor(
|
||||
primaryConstructorDescriptor: ClassConstructorDescriptor,
|
||||
ktClassOrObject: KtClassOrObject
|
||||
primaryConstructorDescriptor: ClassConstructorDescriptor,
|
||||
ktClassOrObject: KtClassOrObject
|
||||
): IrConstructor =
|
||||
declareConstructor(ktClassOrObject, ktClassOrObject.primaryConstructor ?: ktClassOrObject, primaryConstructorDescriptor) {
|
||||
generatePrimaryConstructorBody(ktClassOrObject)
|
||||
}
|
||||
declareConstructor(ktClassOrObject, ktClassOrObject.primaryConstructor ?: ktClassOrObject, primaryConstructorDescriptor) {
|
||||
generatePrimaryConstructorBody(ktClassOrObject)
|
||||
}
|
||||
|
||||
fun generateSecondaryConstructor(ktConstructor: KtSecondaryConstructor): IrConstructor =
|
||||
declareConstructor(
|
||||
ktConstructor, ktConstructor,
|
||||
getOrFail(BindingContext.CONSTRUCTOR, ktConstructor) as ClassConstructorDescriptor
|
||||
) {
|
||||
if (ktConstructor.isConstructorDelegatingToSuper(context.bindingContext))
|
||||
generateSecondaryConstructorBodyWithNestedInitializers(ktConstructor)
|
||||
else
|
||||
generateSecondaryConstructorBody(ktConstructor)
|
||||
}
|
||||
declareConstructor(
|
||||
ktConstructor, ktConstructor,
|
||||
getOrFail(BindingContext.CONSTRUCTOR, ktConstructor) as ClassConstructorDescriptor
|
||||
) {
|
||||
if (ktConstructor.isConstructorDelegatingToSuper(context.bindingContext))
|
||||
generateSecondaryConstructorBodyWithNestedInitializers(ktConstructor)
|
||||
else
|
||||
generateSecondaryConstructorBody(ktConstructor)
|
||||
}
|
||||
|
||||
|
||||
private inline fun declareConstructor(
|
||||
ktConstructorElement: KtElement,
|
||||
ktParametersElement: KtElement,
|
||||
constructorDescriptor: ClassConstructorDescriptor,
|
||||
generateBody: BodyGenerator.() -> IrBody
|
||||
ktConstructorElement: KtElement,
|
||||
ktParametersElement: KtElement,
|
||||
constructorDescriptor: ClassConstructorDescriptor,
|
||||
generateBody: BodyGenerator.() -> IrBody
|
||||
): IrConstructor =
|
||||
context.symbolTable.declareConstructor(
|
||||
ktConstructorElement.startOffset, ktConstructorElement.endOffset, IrDeclarationOrigin.DEFINED, constructorDescriptor
|
||||
).buildWithScope { irConstructor ->
|
||||
generateValueParameterDeclarations(irConstructor, ktParametersElement, null)
|
||||
irConstructor.body = createBodyGenerator(irConstructor.symbol).generateBody()
|
||||
}
|
||||
context.symbolTable.declareConstructor(
|
||||
ktConstructorElement.startOffset, ktConstructorElement.endOffset, IrDeclarationOrigin.DEFINED, constructorDescriptor
|
||||
).buildWithScope { irConstructor ->
|
||||
generateValueParameterDeclarations(irConstructor, ktParametersElement, null)
|
||||
irConstructor.body = createBodyGenerator(irConstructor.symbol).generateBody()
|
||||
}
|
||||
|
||||
fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction) {
|
||||
declarationGenerator.generateTypeParameterDeclarations(irFunction, irFunction.descriptor.typeParameters)
|
||||
@@ -220,10 +230,10 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
}
|
||||
|
||||
private fun generateValueParameterDeclarations(
|
||||
irFunction: IrFunction,
|
||||
ktParameterOwner: KtElement?,
|
||||
ktReceiverParameterElement: KtElement?,
|
||||
withDefaultValues: Boolean = true
|
||||
irFunction: IrFunction,
|
||||
ktParameterOwner: KtElement?,
|
||||
ktReceiverParameterElement: KtElement?,
|
||||
withDefaultValues: Boolean = true
|
||||
) {
|
||||
val functionDescriptor = irFunction.descriptor
|
||||
|
||||
@@ -243,33 +253,33 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
}
|
||||
|
||||
private fun generateValueParameterDeclaration(
|
||||
valueParameterDescriptor: ValueParameterDescriptor,
|
||||
ktParameter: KtParameter?,
|
||||
bodyGenerator: BodyGenerator,
|
||||
withDefaultValues: Boolean
|
||||
valueParameterDescriptor: ValueParameterDescriptor,
|
||||
ktParameter: KtParameter?,
|
||||
bodyGenerator: BodyGenerator,
|
||||
withDefaultValues: Boolean
|
||||
): IrValueParameter =
|
||||
context.symbolTable.declareValueParameter(
|
||||
ktParameter.startOffsetOrUndefined,
|
||||
ktParameter.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
valueParameterDescriptor
|
||||
).also {
|
||||
if (withDefaultValues) {
|
||||
it.defaultValue = ktParameter?.defaultValue?.let {
|
||||
bodyGenerator.generateExpressionBody(it)
|
||||
}
|
||||
context.symbolTable.declareValueParameter(
|
||||
ktParameter.startOffsetOrUndefined,
|
||||
ktParameter.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
valueParameterDescriptor
|
||||
).also {
|
||||
if (withDefaultValues) {
|
||||
it.defaultValue = ktParameter?.defaultValue?.let {
|
||||
bodyGenerator.generateExpressionBody(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateReceiverParameterDeclaration(
|
||||
receiverParameterDescriptor: ReceiverParameterDescriptor,
|
||||
ktElement: KtElement?
|
||||
receiverParameterDescriptor: ReceiverParameterDescriptor,
|
||||
ktElement: KtElement?
|
||||
): IrValueParameter =
|
||||
context.symbolTable.declareValueParameter(
|
||||
ktElement.startOffsetOrUndefined,
|
||||
ktElement.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
receiverParameterDescriptor
|
||||
)
|
||||
context.symbolTable.declareValueParameter(
|
||||
ktElement.startOffsetOrUndefined,
|
||||
ktElement.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
receiverParameterDescriptor
|
||||
)
|
||||
|
||||
}
|
||||
@@ -44,33 +44,39 @@ interface GeneratorWithScope : Generator, IrGeneratorWithScope {
|
||||
|
||||
|
||||
fun <K, V : Any> Generator.get(slice: ReadOnlySlice<K, V>, key: K): V? =
|
||||
context.bindingContext[slice, key]
|
||||
context.bindingContext[slice, key]
|
||||
|
||||
fun <K, V : Any> Generator.getOrFail(slice: ReadOnlySlice<K, V>, key: K): V =
|
||||
context.bindingContext[slice, key] ?: throw RuntimeException("No $slice for $key")
|
||||
context.bindingContext[slice, key] ?: throw RuntimeException("No $slice for $key")
|
||||
|
||||
inline fun <K, V : Any> Generator.getOrFail(slice: ReadOnlySlice<K, V>, key: K, message: (K) -> String): V =
|
||||
context.bindingContext[slice, key] ?: throw RuntimeException(message(key))
|
||||
context.bindingContext[slice, key] ?: throw RuntimeException(message(key))
|
||||
|
||||
fun Generator.getInferredTypeWithImplicitCasts(key: KtExpression): KotlinType? =
|
||||
context.bindingContext.getType(key)
|
||||
context.bindingContext.getType(key)
|
||||
|
||||
fun Generator.getInferredTypeWithImplicitCastsOrFail(key: KtExpression): KotlinType =
|
||||
getInferredTypeWithImplicitCasts(key) ?: throw RuntimeException("No type for expression: ${key.text}")
|
||||
getInferredTypeWithImplicitCasts(key) ?: throw RuntimeException("No type for expression: ${key.text}")
|
||||
|
||||
fun Generator.getResolvedCall(key: KtElement): ResolvedCall<out CallableDescriptor>? =
|
||||
key.getResolvedCall(context.bindingContext)
|
||||
key.getResolvedCall(context.bindingContext)
|
||||
|
||||
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?,
|
||||
origin: IrStatementOrigin? = null, resultType: KotlinType? = null,
|
||||
body: IrBlockBuilder.() -> Unit
|
||||
inline fun GeneratorWithScope.irBlock(
|
||||
ktElement: KtElement?,
|
||||
origin: IrStatementOrigin? = null, resultType: KotlinType? = null,
|
||||
body: IrBlockBuilder.() -> Unit
|
||||
): 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 =
|
||||
this.irBlockBody(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, body)
|
||||
inline fun GeneratorWithScope.irBlockBody(ktElement: KtElement?, body: IrBlockBodyBuilder.() -> Unit): IrBlockBody =
|
||||
this.irBlockBody(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, body)
|
||||
|
||||
|
||||
|
||||
+3
-3
@@ -28,9 +28,9 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
|
||||
class GeneratorContext(
|
||||
val configuration: Psi2IrConfiguration,
|
||||
val moduleDescriptor: ModuleDescriptor,
|
||||
val bindingContext: BindingContext
|
||||
val configuration: Psi2IrConfiguration,
|
||||
val moduleDescriptor: ModuleDescriptor,
|
||||
val bindingContext: BindingContext
|
||||
) : IrGeneratorContext(IrBuiltIns(moduleDescriptor.builtIns)) {
|
||||
val sourceManager = PsiSourceManager()
|
||||
|
||||
|
||||
+13
-12
@@ -25,16 +25,17 @@ import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
class LocalClassGenerator(statementGenerator: StatementGenerator): StatementGeneratorExtension(statementGenerator) {
|
||||
class LocalClassGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
fun generateObjectLiteral(ktObjectLiteral: KtObjectLiteralExpression): IrStatement {
|
||||
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)
|
||||
irBlock.statements.add(irClass)
|
||||
|
||||
val objectConstructor = irClass.descriptor.unsubstitutedPrimaryConstructor ?:
|
||||
throw AssertionError("Object literal should have a primary constructor: ${irClass.descriptor}")
|
||||
val objectConstructor = irClass.descriptor.unsubstitutedPrimaryConstructor
|
||||
?: throw AssertionError("Object literal should have a primary constructor: ${irClass.descriptor}")
|
||||
assert(objectConstructor.dispatchReceiverParameter == null) {
|
||||
"Object literal constructor should have no dispatch receiver parameter: $objectConstructor"
|
||||
}
|
||||
@@ -46,19 +47,19 @@ class LocalClassGenerator(statementGenerator: StatementGenerator): StatementGene
|
||||
}
|
||||
|
||||
irBlock.statements.add(
|
||||
IrCallImpl(
|
||||
ktObjectLiteral.startOffset, ktObjectLiteral.endOffset, objectLiteralType,
|
||||
context.symbolTable.referenceConstructor(objectConstructor),
|
||||
objectConstructor,
|
||||
null,
|
||||
IrStatementOrigin.OBJECT_LITERAL
|
||||
)
|
||||
IrCallImpl(
|
||||
ktObjectLiteral.startOffset, ktObjectLiteral.endOffset, objectLiteralType,
|
||||
context.symbolTable.referenceConstructor(objectConstructor),
|
||||
objectConstructor,
|
||||
null,
|
||||
IrStatementOrigin.OBJECT_LITERAL
|
||||
)
|
||||
)
|
||||
|
||||
return irBlock
|
||||
}
|
||||
|
||||
fun generateLocalClass(ktClassOrObject: KtClassOrObject): IrStatement =
|
||||
DeclarationGenerator(statementGenerator.context).generateClassOrObjectDeclaration(ktClassOrObject)
|
||||
DeclarationGenerator(statementGenerator.context).generateClassOrObjectDeclaration(ktClassOrObject)
|
||||
|
||||
}
|
||||
|
||||
+22
-23
@@ -35,38 +35,37 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
|
||||
val irBlock = IrBlockImpl(ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, IrStatementOrigin.LAMBDA)
|
||||
irBlock.statements.add(irLambdaFunction)
|
||||
irBlock.statements.add(
|
||||
IrFunctionReferenceImpl(
|
||||
ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType,
|
||||
irLambdaFunction.symbol, irLambdaFunction.symbol.descriptor,
|
||||
null, IrStatementOrigin.LAMBDA
|
||||
)
|
||||
IrFunctionReferenceImpl(
|
||||
ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType,
|
||||
irLambdaFunction.symbol, irLambdaFunction.symbol.descriptor,
|
||||
null, IrStatementOrigin.LAMBDA
|
||||
)
|
||||
)
|
||||
return irBlock
|
||||
}
|
||||
|
||||
fun generateFunction(ktFun: KtNamedFunction): IrStatement =
|
||||
if (ktFun.name != null) {
|
||||
generateFunctionDeclaration(ktFun)
|
||||
}
|
||||
else {
|
||||
// anonymous function expression
|
||||
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun)
|
||||
val irBlock = IrBlockImpl(ktFun.startOffset, ktFun.endOffset, funExpressionType, IrStatementOrigin.ANONYMOUS_FUNCTION)
|
||||
if (ktFun.name != null) {
|
||||
generateFunctionDeclaration(ktFun)
|
||||
} else {
|
||||
// anonymous function expression
|
||||
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun)
|
||||
val irBlock = IrBlockImpl(ktFun.startOffset, ktFun.endOffset, funExpressionType, IrStatementOrigin.ANONYMOUS_FUNCTION)
|
||||
|
||||
val irFun = generateFunctionDeclaration(ktFun)
|
||||
irBlock.statements.add(irFun)
|
||||
val irFun = generateFunctionDeclaration(ktFun)
|
||||
irBlock.statements.add(irFun)
|
||||
|
||||
irBlock.statements.add(
|
||||
IrFunctionReferenceImpl(
|
||||
ktFun.startOffset, ktFun.endOffset, funExpressionType,
|
||||
irFun.symbol, irFun.symbol.descriptor,
|
||||
null, IrStatementOrigin.ANONYMOUS_FUNCTION
|
||||
)
|
||||
irBlock.statements.add(
|
||||
IrFunctionReferenceImpl(
|
||||
ktFun.startOffset, ktFun.endOffset, funExpressionType,
|
||||
irFun.symbol, irFun.symbol.descriptor,
|
||||
null, IrStatementOrigin.ANONYMOUS_FUNCTION
|
||||
)
|
||||
)
|
||||
|
||||
irBlock
|
||||
}
|
||||
irBlock
|
||||
}
|
||||
|
||||
private fun generateFunctionDeclaration(ktFun: KtNamedFunction): IrFunction =
|
||||
FunctionGenerator(context).generateFunctionDeclaration(ktFun)
|
||||
FunctionGenerator(context).generateFunctionDeclaration(ktFun)
|
||||
}
|
||||
+41
-33
@@ -29,10 +29,12 @@ import org.jetbrains.kotlin.psi2ir.intermediate.VariableLValue
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.setExplicitReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class LoopExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator){
|
||||
class LoopExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
fun generateWhileLoop(ktWhile: KtWhileExpression): IrExpression {
|
||||
val irLoop = IrWhileLoopImpl(ktWhile.startOffset, ktWhile.endOffset,
|
||||
context.builtIns.unitType, IrStatementOrigin.WHILE_LOOP)
|
||||
val irLoop = IrWhileLoopImpl(
|
||||
ktWhile.startOffset, ktWhile.endOffset,
|
||||
context.builtIns.unitType, IrStatementOrigin.WHILE_LOOP
|
||||
)
|
||||
|
||||
irLoop.condition = statementGenerator.generateExpression(ktWhile.condition!!)
|
||||
|
||||
@@ -51,8 +53,10 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
}
|
||||
|
||||
fun generateDoWhileLoop(ktDoWhile: KtDoWhileExpression): IrExpression {
|
||||
val irLoop = IrDoWhileLoopImpl(ktDoWhile.startOffset, ktDoWhile.endOffset,
|
||||
context.builtIns.unitType, IrStatementOrigin.DO_WHILE_LOOP)
|
||||
val irLoop = IrDoWhileLoopImpl(
|
||||
ktDoWhile.startOffset, ktDoWhile.endOffset,
|
||||
context.builtIns.unitType, IrStatementOrigin.DO_WHILE_LOOP
|
||||
)
|
||||
|
||||
statementGenerator.bodyGenerator.putLoop(ktDoWhile, irLoop)
|
||||
|
||||
@@ -73,41 +77,41 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
}
|
||||
|
||||
private fun generateWhileLoopBody(ktLoopBody: KtBlockExpression): IrExpression =
|
||||
IrBlockImpl(
|
||||
ktLoopBody.startOffset, ktLoopBody.endOffset, context.builtIns.unitType, null,
|
||||
ktLoopBody.statements.map { statementGenerator.generateStatement(it) }
|
||||
)
|
||||
IrBlockImpl(
|
||||
ktLoopBody.startOffset, ktLoopBody.endOffset, context.builtIns.unitType, null,
|
||||
ktLoopBody.statements.map { statementGenerator.generateStatement(it) }
|
||||
)
|
||||
|
||||
|
||||
private fun generateDoWhileLoopBody(ktLoopBody: KtBlockExpression): IrExpression =
|
||||
IrCompositeImpl(
|
||||
ktLoopBody.startOffset, ktLoopBody.endOffset, context.builtIns.unitType, null,
|
||||
ktLoopBody.statements.map { statementGenerator.generateStatement(it) }
|
||||
)
|
||||
IrCompositeImpl(
|
||||
ktLoopBody.startOffset, ktLoopBody.endOffset, context.builtIns.unitType, null,
|
||||
ktLoopBody.statements.map { statementGenerator.generateStatement(it) }
|
||||
)
|
||||
|
||||
fun generateBreak(ktBreak: KtBreakExpression): IrExpression {
|
||||
val parentLoop = findParentLoop(ktBreak) ?:
|
||||
return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
|
||||
ktBreak, RuntimeException("Loop not found for break expression: ${ktBreak.text}"))
|
||||
val parentLoop = findParentLoop(ktBreak) ?: return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
|
||||
ktBreak, RuntimeException("Loop not found for break expression: ${ktBreak.text}")
|
||||
)
|
||||
return IrBreakImpl(ktBreak.startOffset, ktBreak.endOffset, context.builtIns.nothingType, parentLoop).apply {
|
||||
label = ktBreak.getLabelName()
|
||||
}
|
||||
}
|
||||
|
||||
fun generateContinue(ktContinue: KtContinueExpression): IrExpression {
|
||||
val parentLoop = findParentLoop(ktContinue) ?:
|
||||
return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
|
||||
ktContinue, RuntimeException("Loop not found for continue expression: ${ktContinue.text}"))
|
||||
val parentLoop = findParentLoop(ktContinue) ?: return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
|
||||
ktContinue, RuntimeException("Loop not found for continue expression: ${ktContinue.text}")
|
||||
)
|
||||
return IrContinueImpl(ktContinue.startOffset, ktContinue.endOffset, context.builtIns.nothingType, parentLoop).apply {
|
||||
label = ktContinue.getLabelName()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLoopLabel(ktLoop: KtLoopExpression): String? =
|
||||
(ktLoop.parent as? KtLabeledExpression)?.getLabelName()
|
||||
(ktLoop.parent as? KtLabeledExpression)?.getLabelName()
|
||||
|
||||
private fun findParentLoop(ktWithLabel: KtExpressionWithLabel): IrLoop? =
|
||||
findParentLoop(ktWithLabel, ktWithLabel.getLabelName())
|
||||
findParentLoop(ktWithLabel, ktWithLabel.getLabelName())
|
||||
|
||||
private fun findParentLoop(ktExpression: KtExpression, targetLabel: String?): IrLoop? {
|
||||
var finger: KtExpression? = ktExpression
|
||||
@@ -118,8 +122,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
}
|
||||
if (targetLabel == null) {
|
||||
return getLoop(finger) ?: continue
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
val parent = finger.parent
|
||||
if (parent is KtLabeledExpression) {
|
||||
val label = parent.getLabelName()!!
|
||||
@@ -159,7 +162,8 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
val iteratorValue = VariableLValue(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)
|
||||
statementGenerator.bodyGenerator.putLoop(ktFor, irInnerWhile)
|
||||
irForBlock.statements.add(irInnerWhile)
|
||||
@@ -176,18 +180,22 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
nextCall.setExplicitReceiverValue(iteratorValue)
|
||||
val irNextCall = callGenerator.generateCall(ktLoopRange, nextCall, IrStatementOrigin.FOR_LOOP_NEXT)
|
||||
val irLoopParameter =
|
||||
if (ktLoopParameter != null && ktLoopDestructuringDeclaration == null)
|
||||
context.symbolTable.declareVariable(
|
||||
ktLoopParameter.startOffset, ktLoopParameter.endOffset, IrDeclarationOrigin.FOR_LOOP_VARIABLE,
|
||||
getOrFail(BindingContext.VALUE_PARAMETER, ktLoopParameter),
|
||||
irNextCall
|
||||
)
|
||||
else
|
||||
scope.createTemporaryVariable(irNextCall, "loop_parameter", origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE)
|
||||
if (ktLoopParameter != null && ktLoopDestructuringDeclaration == null)
|
||||
context.symbolTable.declareVariable(
|
||||
ktLoopParameter.startOffset, ktLoopParameter.endOffset, IrDeclarationOrigin.FOR_LOOP_VARIABLE,
|
||||
getOrFail(BindingContext.VALUE_PARAMETER, ktLoopParameter),
|
||||
irNextCall
|
||||
)
|
||||
else
|
||||
scope.createTemporaryVariable(irNextCall, "loop_parameter", origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE)
|
||||
irInnerBody.statements.add(irLoopParameter)
|
||||
|
||||
if (ktLoopDestructuringDeclaration != null) {
|
||||
statementGenerator.declareComponentVariablesInBlock(ktLoopDestructuringDeclaration, irInnerBody, VariableLValue(irLoopParameter))
|
||||
statementGenerator.declareComponentVariablesInBlock(
|
||||
ktLoopDestructuringDeclaration,
|
||||
irInnerBody,
|
||||
VariableLValue(irLoopParameter)
|
||||
)
|
||||
}
|
||||
|
||||
if (ktForBody != null) {
|
||||
|
||||
@@ -27,14 +27,14 @@ import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
|
||||
|
||||
class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
||||
fun generateModuleFragment(ktFiles: Collection<KtFile>): IrModuleFragment =
|
||||
generateModuleFragmentWithoutDependencies(ktFiles).also { irModule ->
|
||||
generateUnboundSymbolsAsDependencies(irModule)
|
||||
}
|
||||
generateModuleFragmentWithoutDependencies(ktFiles).also { irModule ->
|
||||
generateUnboundSymbolsAsDependencies(irModule)
|
||||
}
|
||||
|
||||
fun generateModuleFragmentWithoutDependencies(ktFiles: Collection<KtFile>): IrModuleFragment =
|
||||
IrModuleFragmentImpl(context.moduleDescriptor, context.irBuiltIns).also { irModule ->
|
||||
irModule.files.addAll(generateFiles(ktFiles))
|
||||
}
|
||||
IrModuleFragmentImpl(context.moduleDescriptor, context.irBuiltIns).also { irModule ->
|
||||
irModule.files.addAll(generateFiles(ktFiles))
|
||||
}
|
||||
|
||||
private fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment) {
|
||||
ExternalDependenciesGenerator(context.symbolTable, context.irBuiltIns).generateUnboundSymbolsAsDependencies(irModule)
|
||||
|
||||
+68
-59
@@ -23,86 +23,95 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
|
||||
|
||||
fun getInfixOperator(ktOperator: IElementType): IrStatementOrigin? =
|
||||
when (ktOperator) {
|
||||
KtTokens.EQ -> IrStatementOrigin.EQ
|
||||
KtTokens.PLUSEQ -> IrStatementOrigin.PLUSEQ
|
||||
KtTokens.MINUSEQ -> IrStatementOrigin.MINUSEQ
|
||||
KtTokens.MULTEQ -> IrStatementOrigin.MULTEQ
|
||||
KtTokens.DIVEQ -> IrStatementOrigin.DIVEQ
|
||||
KtTokens.PERCEQ -> IrStatementOrigin.PERCEQ
|
||||
KtTokens.PLUS -> IrStatementOrigin.PLUS
|
||||
KtTokens.MINUS -> IrStatementOrigin.MINUS
|
||||
KtTokens.MUL -> IrStatementOrigin.MUL
|
||||
KtTokens.DIV -> IrStatementOrigin.DIV
|
||||
KtTokens.PERC -> IrStatementOrigin.PERC
|
||||
KtTokens.RANGE -> IrStatementOrigin.RANGE
|
||||
KtTokens.LT -> IrStatementOrigin.LT
|
||||
KtTokens.LTEQ -> IrStatementOrigin.LTEQ
|
||||
KtTokens.GT -> IrStatementOrigin.GT
|
||||
KtTokens.GTEQ -> IrStatementOrigin.GTEQ
|
||||
KtTokens.EQEQ -> IrStatementOrigin.EQEQ
|
||||
KtTokens.EXCLEQ -> IrStatementOrigin.EXCLEQ
|
||||
KtTokens.EQEQEQ -> IrStatementOrigin.EQEQEQ
|
||||
KtTokens.EXCLEQEQEQ -> IrStatementOrigin.EXCLEQEQ
|
||||
KtTokens.IN_KEYWORD -> IrStatementOrigin.IN
|
||||
KtTokens.NOT_IN -> IrStatementOrigin.NOT_IN
|
||||
KtTokens.ANDAND -> IrStatementOrigin.ANDAND
|
||||
KtTokens.OROR -> IrStatementOrigin.OROR
|
||||
KtTokens.ELVIS -> IrStatementOrigin.ELVIS
|
||||
else -> null
|
||||
}
|
||||
when (ktOperator) {
|
||||
KtTokens.EQ -> IrStatementOrigin.EQ
|
||||
KtTokens.PLUSEQ -> IrStatementOrigin.PLUSEQ
|
||||
KtTokens.MINUSEQ -> IrStatementOrigin.MINUSEQ
|
||||
KtTokens.MULTEQ -> IrStatementOrigin.MULTEQ
|
||||
KtTokens.DIVEQ -> IrStatementOrigin.DIVEQ
|
||||
KtTokens.PERCEQ -> IrStatementOrigin.PERCEQ
|
||||
KtTokens.PLUS -> IrStatementOrigin.PLUS
|
||||
KtTokens.MINUS -> IrStatementOrigin.MINUS
|
||||
KtTokens.MUL -> IrStatementOrigin.MUL
|
||||
KtTokens.DIV -> IrStatementOrigin.DIV
|
||||
KtTokens.PERC -> IrStatementOrigin.PERC
|
||||
KtTokens.RANGE -> IrStatementOrigin.RANGE
|
||||
KtTokens.LT -> IrStatementOrigin.LT
|
||||
KtTokens.LTEQ -> IrStatementOrigin.LTEQ
|
||||
KtTokens.GT -> IrStatementOrigin.GT
|
||||
KtTokens.GTEQ -> IrStatementOrigin.GTEQ
|
||||
KtTokens.EQEQ -> IrStatementOrigin.EQEQ
|
||||
KtTokens.EXCLEQ -> IrStatementOrigin.EXCLEQ
|
||||
KtTokens.EQEQEQ -> IrStatementOrigin.EQEQEQ
|
||||
KtTokens.EXCLEQEQEQ -> IrStatementOrigin.EXCLEQEQ
|
||||
KtTokens.IN_KEYWORD -> IrStatementOrigin.IN
|
||||
KtTokens.NOT_IN -> IrStatementOrigin.NOT_IN
|
||||
KtTokens.ANDAND -> IrStatementOrigin.ANDAND
|
||||
KtTokens.OROR -> IrStatementOrigin.OROR
|
||||
KtTokens.ELVIS -> IrStatementOrigin.ELVIS
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun getPrefixOperator(ktOperator: IElementType): IrStatementOrigin? =
|
||||
when (ktOperator) {
|
||||
KtTokens.PLUSPLUS -> IrStatementOrigin.PREFIX_INCR
|
||||
KtTokens.MINUSMINUS -> IrStatementOrigin.PREFIX_DECR
|
||||
KtTokens.EXCL -> IrStatementOrigin.EXCL
|
||||
KtTokens.MINUS -> IrStatementOrigin.UMINUS
|
||||
KtTokens.PLUS -> IrStatementOrigin.UPLUS
|
||||
else -> null
|
||||
}
|
||||
when (ktOperator) {
|
||||
KtTokens.PLUSPLUS -> IrStatementOrigin.PREFIX_INCR
|
||||
KtTokens.MINUSMINUS -> IrStatementOrigin.PREFIX_DECR
|
||||
KtTokens.EXCL -> IrStatementOrigin.EXCL
|
||||
KtTokens.MINUS -> IrStatementOrigin.UMINUS
|
||||
KtTokens.PLUS -> IrStatementOrigin.UPLUS
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun getPostfixOperator(ktOperator: IElementType): IrStatementOrigin? =
|
||||
when (ktOperator) {
|
||||
KtTokens.PLUSPLUS -> IrStatementOrigin.POSTFIX_INCR
|
||||
KtTokens.MINUSMINUS -> IrStatementOrigin.POSTFIX_DECR
|
||||
KtTokens.EXCLEXCL -> IrStatementOrigin.EXCLEXCL
|
||||
else -> null
|
||||
}
|
||||
when (ktOperator) {
|
||||
KtTokens.PLUSPLUS -> IrStatementOrigin.POSTFIX_INCR
|
||||
KtTokens.MINUSMINUS -> IrStatementOrigin.POSTFIX_DECR
|
||||
KtTokens.EXCLEXCL -> IrStatementOrigin.EXCLEXCL
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun getIrTypeOperator(ktOperator: IElementType): IrTypeOperator? =
|
||||
when (ktOperator) {
|
||||
KtTokens.IS_KEYWORD -> IrTypeOperator.INSTANCEOF
|
||||
KtTokens.NOT_IS -> IrTypeOperator.NOT_INSTANCEOF
|
||||
KtTokens.AS_KEYWORD -> IrTypeOperator.CAST
|
||||
KtTokens.AS_SAFE -> IrTypeOperator.SAFE_CAST
|
||||
else -> null
|
||||
}
|
||||
when (ktOperator) {
|
||||
KtTokens.IS_KEYWORD -> IrTypeOperator.INSTANCEOF
|
||||
KtTokens.NOT_IS -> IrTypeOperator.NOT_INSTANCEOF
|
||||
KtTokens.AS_KEYWORD -> IrTypeOperator.CAST
|
||||
KtTokens.AS_SAFE -> IrTypeOperator.SAFE_CAST
|
||||
else -> null
|
||||
}
|
||||
|
||||
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 =
|
||||
setOf(IrStatementOrigin.PLUS, IrStatementOrigin.MINUS, IrStatementOrigin.MUL, IrStatementOrigin.DIV, IrStatementOrigin.PERC, IrStatementOrigin.RANGE,
|
||||
IrStatementOrigin.EXCL, IrStatementOrigin.UMINUS, IrStatementOrigin.UPLUS)
|
||||
setOf(
|
||||
IrStatementOrigin.PLUS,
|
||||
IrStatementOrigin.MINUS,
|
||||
IrStatementOrigin.MUL,
|
||||
IrStatementOrigin.DIV,
|
||||
IrStatementOrigin.PERC,
|
||||
IrStatementOrigin.RANGE,
|
||||
IrStatementOrigin.EXCL,
|
||||
IrStatementOrigin.UMINUS,
|
||||
IrStatementOrigin.UPLUS
|
||||
)
|
||||
|
||||
val COMPARISON_OPERATORS =
|
||||
setOf(IrStatementOrigin.LT, IrStatementOrigin.LTEQ, IrStatementOrigin.GT, IrStatementOrigin.GTEQ)
|
||||
setOf(IrStatementOrigin.LT, IrStatementOrigin.LTEQ, IrStatementOrigin.GT, IrStatementOrigin.GTEQ)
|
||||
|
||||
val EQUALITY_OPERATORS =
|
||||
setOf(IrStatementOrigin.EQEQ, IrStatementOrigin.EXCLEQ)
|
||||
setOf(IrStatementOrigin.EQEQ, IrStatementOrigin.EXCLEQ)
|
||||
|
||||
val IDENTITY_OPERATORS =
|
||||
setOf(IrStatementOrigin.EQEQEQ, IrStatementOrigin.EXCLEQEQ)
|
||||
setOf(IrStatementOrigin.EQEQEQ, IrStatementOrigin.EXCLEQEQ)
|
||||
|
||||
val IN_OPERATORS =
|
||||
setOf(IrStatementOrigin.IN, IrStatementOrigin.NOT_IN)
|
||||
setOf(IrStatementOrigin.IN, IrStatementOrigin.NOT_IN)
|
||||
|
||||
val BINARY_BOOLEAN_OPERATORS =
|
||||
setOf(IrStatementOrigin.ANDAND, IrStatementOrigin.OROR)
|
||||
setOf(IrStatementOrigin.ANDAND, IrStatementOrigin.OROR)
|
||||
|
||||
val INCREMENT_DECREMENT_OPERATORS =
|
||||
setOf(IrStatementOrigin.PREFIX_INCR, IrStatementOrigin.PREFIX_DECR, IrStatementOrigin.POSTFIX_INCR, IrStatementOrigin.POSTFIX_DECR)
|
||||
setOf(IrStatementOrigin.PREFIX_INCR, IrStatementOrigin.PREFIX_DECR, IrStatementOrigin.POSTFIX_INCR, IrStatementOrigin.POSTFIX_DECR)
|
||||
|
||||
val POSTFIX_INCREMENT_DECREMENT_OPERATORS =
|
||||
setOf(IrStatementOrigin.POSTFIX_INCR, IrStatementOrigin.POSTFIX_DECR)
|
||||
setOf(IrStatementOrigin.POSTFIX_INCR, IrStatementOrigin.POSTFIX_DECR)
|
||||
+46
-24
@@ -44,7 +44,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
|
||||
return when (irOperator) {
|
||||
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)
|
||||
else -> createDummyExpression(expression, ktOperator.toString())
|
||||
}
|
||||
@@ -56,7 +59,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
|
||||
return when (irOperator) {
|
||||
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)
|
||||
else -> createDummyExpression(expression, ktOperator.toString())
|
||||
}
|
||||
@@ -76,8 +82,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
throw AssertionError("Unexpected IrTypeOperator: $irOperator")
|
||||
}
|
||||
|
||||
return IrTypeOperatorCallImpl(expression.startOffset, expression.endOffset, resultType, irOperator, rhsType,
|
||||
statementGenerator.generateExpression(expression.left))
|
||||
return IrTypeOperatorCallImpl(
|
||||
expression.startOffset, expression.endOffset, resultType, irOperator, rhsType,
|
||||
statementGenerator.generateExpression(expression.left)
|
||||
)
|
||||
}
|
||||
|
||||
fun generateInstanceOfExpression(expression: KtIsExpression): IrStatement {
|
||||
@@ -85,8 +93,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
val irOperator = getIrTypeOperator(ktOperator)!!
|
||||
val againstType = getOrFail(BindingContext.TYPE, expression.typeReference)
|
||||
|
||||
return IrTypeOperatorCallImpl(expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator,
|
||||
againstType, statementGenerator.generateExpression(expression.leftHandSide))
|
||||
return IrTypeOperatorCallImpl(
|
||||
expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator,
|
||||
againstType, statementGenerator.generateExpression(expression.leftHandSide)
|
||||
)
|
||||
}
|
||||
|
||||
fun generateBinaryExpression(expression: KtBinaryExpression): IrExpression {
|
||||
@@ -140,15 +150,18 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
private fun generateInOperator(expression: KtBinaryExpression, irOperator: IrStatementOrigin): IrExpression {
|
||||
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) {
|
||||
IrStatementOrigin.IN ->
|
||||
irContainsCall
|
||||
IrStatementOrigin.NOT_IN ->
|
||||
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.NOT_IN,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
irContainsCall)
|
||||
IrUnaryPrimitiveImpl(
|
||||
expression.startOffset, expression.endOffset, IrStatementOrigin.NOT_IN,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
irContainsCall
|
||||
)
|
||||
else ->
|
||||
throw AssertionError("Unexpected in-operator $irOperator")
|
||||
}
|
||||
@@ -160,17 +173,21 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
val irArgument1 = statementGenerator.generateExpression(expression.right!!)
|
||||
|
||||
|
||||
val irIdentityEquals = IrBinaryPrimitiveImpl(expression.startOffset, expression.endOffset, irOperator,
|
||||
context.irBuiltIns.eqeqeqSymbol,
|
||||
irArgument0, irArgument1)
|
||||
val irIdentityEquals = IrBinaryPrimitiveImpl(
|
||||
expression.startOffset, expression.endOffset, irOperator,
|
||||
context.irBuiltIns.eqeqeqSymbol,
|
||||
irArgument0, irArgument1
|
||||
)
|
||||
|
||||
return when (irOperator) {
|
||||
IrStatementOrigin.EQEQEQ ->
|
||||
irIdentityEquals
|
||||
IrStatementOrigin.EXCLEQEQ ->
|
||||
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQEQ,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
irIdentityEquals)
|
||||
IrUnaryPrimitiveImpl(
|
||||
expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQEQ,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
irIdentityEquals
|
||||
)
|
||||
else ->
|
||||
throw AssertionError("Unexpected identity operator $irOperator")
|
||||
}
|
||||
@@ -181,18 +198,22 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
val irArgument0 = statementGenerator.generateExpression(expression.left!!)
|
||||
val irArgument1 = statementGenerator.generateExpression(expression.right!!)
|
||||
|
||||
val irEquals = IrBinaryPrimitiveImpl(expression.startOffset, expression.endOffset,
|
||||
irOperator,
|
||||
context.irBuiltIns.eqeqSymbol,
|
||||
irArgument0, irArgument1)
|
||||
val irEquals = IrBinaryPrimitiveImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
irOperator,
|
||||
context.irBuiltIns.eqeqSymbol,
|
||||
irArgument0, irArgument1
|
||||
)
|
||||
|
||||
return when (irOperator) {
|
||||
IrStatementOrigin.EQEQ ->
|
||||
irEquals
|
||||
IrStatementOrigin.EXCLEQ ->
|
||||
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQ,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
irEquals)
|
||||
IrUnaryPrimitiveImpl(
|
||||
expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQ,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
irEquals
|
||||
)
|
||||
else ->
|
||||
throw AssertionError("Unexpected equality operator $irOperator")
|
||||
}
|
||||
@@ -202,7 +223,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
private fun generateComparisonOperator(expression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
|
||||
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) {
|
||||
IrStatementOrigin.LT -> context.irBuiltIns.lt0Symbol
|
||||
|
||||
+48
-44
@@ -45,76 +45,80 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
val propertyDescriptor = getOrFail(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, ktParameter)
|
||||
|
||||
return IrPropertyImpl(
|
||||
ktParameter.startOffset, ktParameter.endOffset,
|
||||
IrDeclarationOrigin.DEFINED, false,
|
||||
propertyDescriptor
|
||||
ktParameter.startOffset, ktParameter.endOffset,
|
||||
IrDeclarationOrigin.DEFINED, false,
|
||||
propertyDescriptor
|
||||
).also { irProperty ->
|
||||
irProperty.backingField =
|
||||
generatePropertyBackingField(ktParameter, propertyDescriptor) {
|
||||
IrExpressionBodyImpl(IrGetValueImpl(
|
||||
IrExpressionBodyImpl(
|
||||
IrGetValueImpl(
|
||||
ktParameter.startOffset, ktParameter.endOffset,
|
||||
irValueParameter.symbol,
|
||||
IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val getter = propertyDescriptor.getter ?:
|
||||
throw AssertionError("Property declared in primary constructor has no getter: $propertyDescriptor")
|
||||
irProperty.getter = FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(getter, ktParameter)
|
||||
val getter = propertyDescriptor.getter
|
||||
?: throw AssertionError("Property declared in primary constructor has no getter: $propertyDescriptor")
|
||||
irProperty.getter =
|
||||
FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(getter, ktParameter)
|
||||
|
||||
if (propertyDescriptor.isVar) {
|
||||
val setter = propertyDescriptor.setter ?:
|
||||
throw AssertionError("Property declared in primary constructor has no setter: $propertyDescriptor")
|
||||
irProperty.setter = FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(setter, ktParameter)
|
||||
val setter = propertyDescriptor.setter
|
||||
?: throw AssertionError("Property declared in primary constructor has no setter: $propertyDescriptor")
|
||||
irProperty.setter =
|
||||
FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(setter, ktParameter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun generatePropertyBackingField(
|
||||
ktPropertyElement: KtElement,
|
||||
propertyDescriptor: PropertyDescriptor,
|
||||
generateInitializer: (IrField) -> IrExpressionBody?
|
||||
) : IrField =
|
||||
context.symbolTable.declareField(
|
||||
ktPropertyElement.startOffset, ktPropertyElement.endOffset,
|
||||
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
|
||||
propertyDescriptor
|
||||
).also {
|
||||
it.initializer = generateInitializer(it)
|
||||
}
|
||||
ktPropertyElement: KtElement,
|
||||
propertyDescriptor: PropertyDescriptor,
|
||||
generateInitializer: (IrField) -> IrExpressionBody?
|
||||
): IrField =
|
||||
context.symbolTable.declareField(
|
||||
ktPropertyElement.startOffset, ktPropertyElement.endOffset,
|
||||
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
|
||||
propertyDescriptor
|
||||
).also {
|
||||
it.initializer = generateInitializer(it)
|
||||
}
|
||||
|
||||
|
||||
private fun generateDelegatedProperty(
|
||||
ktProperty: KtProperty,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
propertyDescriptor: PropertyDescriptor
|
||||
ktProperty: KtProperty,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
propertyDescriptor: PropertyDescriptor
|
||||
): IrProperty =
|
||||
DelegatedPropertyGenerator(declarationGenerator)
|
||||
.generateDelegatedProperty(ktProperty, ktDelegate, propertyDescriptor)
|
||||
DelegatedPropertyGenerator(declarationGenerator)
|
||||
.generateDelegatedProperty(ktProperty, ktDelegate, propertyDescriptor)
|
||||
|
||||
private fun generateSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor): IrProperty =
|
||||
IrPropertyImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset,
|
||||
IrDeclarationOrigin.DEFINED, false,
|
||||
propertyDescriptor
|
||||
).buildWithScope { irProperty ->
|
||||
irProperty.backingField =
|
||||
if (propertyDescriptor.hasBackingField())
|
||||
generatePropertyBackingField(ktProperty, propertyDescriptor) { irField ->
|
||||
ktProperty.initializer?.let { ktInitializer ->
|
||||
declarationGenerator.generateInitializerBody(irField.symbol, ktInitializer)
|
||||
}
|
||||
IrPropertyImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset,
|
||||
IrDeclarationOrigin.DEFINED, false,
|
||||
propertyDescriptor
|
||||
).buildWithScope { irProperty ->
|
||||
irProperty.backingField =
|
||||
if (propertyDescriptor.hasBackingField())
|
||||
generatePropertyBackingField(ktProperty, propertyDescriptor) { irField ->
|
||||
ktProperty.initializer?.let { ktInitializer ->
|
||||
declarationGenerator.generateInitializerBody(irField.symbol, ktInitializer)
|
||||
}
|
||||
else
|
||||
null
|
||||
}
|
||||
else
|
||||
null
|
||||
|
||||
irProperty.getter = generateGetterIfRequired(ktProperty, propertyDescriptor)
|
||||
irProperty.getter = generateGetterIfRequired(ktProperty, propertyDescriptor)
|
||||
|
||||
irProperty.setter = generateSetterIfRequired(ktProperty, propertyDescriptor)
|
||||
}
|
||||
irProperty.setter = generateSetterIfRequired(ktProperty, propertyDescriptor)
|
||||
}
|
||||
|
||||
private fun PropertyDescriptor.hasBackingField(): Boolean =
|
||||
get(BindingContext.BACKING_FIELD_REQUIRED, this) ?: false
|
||||
get(BindingContext.BACKING_FIELD_REQUIRED, this) ?: false
|
||||
|
||||
private fun generateGetterIfRequired(ktProperty: KtProperty, property: PropertyDescriptor): IrFunction? {
|
||||
val getter = property.getter ?: return null
|
||||
|
||||
+75
-72
@@ -37,15 +37,18 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
val resultType = getInferredTypeWithImplicitCastsOrFail(ktClassLiteral)
|
||||
|
||||
return if (lhs is DoubleColonLHS.Expression && !lhs.isObjectQualifier) {
|
||||
IrGetClassImpl(ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
|
||||
statementGenerator.generateExpression(ktArgument))
|
||||
}
|
||||
else {
|
||||
IrGetClassImpl(
|
||||
ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
|
||||
statementGenerator.generateExpression(ktArgument)
|
||||
)
|
||||
} else {
|
||||
val typeConstructorDeclaration = lhs.type.constructor.declarationDescriptor
|
||||
val typeClass = typeConstructorDeclaration ?:
|
||||
throw AssertionError("Unexpected type constructor for ${lhs.type}: $typeConstructorDeclaration")
|
||||
IrClassReferenceImpl(ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
|
||||
context.symbolTable.referenceClassifier(typeClass), lhs.type)
|
||||
val typeClass = typeConstructorDeclaration
|
||||
?: throw AssertionError("Unexpected type constructor for ${lhs.type}: $typeConstructorDeclaration")
|
||||
IrClassReferenceImpl(
|
||||
ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
|
||||
context.symbolTable.referenceClassifier(typeClass), lhs.type
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,16 +63,16 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
val endOffset = ktCallableReference.endOffset
|
||||
|
||||
return statementGenerator.generateCallReceiver(
|
||||
ktCallableReference,
|
||||
resultingDescriptor,
|
||||
resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver,
|
||||
isSafe = false
|
||||
ktCallableReference,
|
||||
resultingDescriptor,
|
||||
resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver,
|
||||
isSafe = false
|
||||
).call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
generateCallableReference(
|
||||
startOffset, endOffset,
|
||||
getInferredTypeWithImplicitCastsOrFail(ktCallableReference),
|
||||
referencedDescriptor,
|
||||
typeArguments = null
|
||||
startOffset, endOffset,
|
||||
getInferredTypeWithImplicitCastsOrFail(ktCallableReference),
|
||||
referencedDescriptor,
|
||||
typeArguments = null
|
||||
).also { irCallableReference ->
|
||||
irCallableReference.dispatchReceiver = dispatchReceiverValue?.loadIfExists()
|
||||
irCallableReference.extensionReceiver = extensionReceiverValue?.loadIfExists()
|
||||
@@ -78,58 +81,58 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
}
|
||||
|
||||
fun generateCallableReference(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
callableDescriptor: CallableDescriptor,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
origin: IrStatementOrigin? = null
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
callableDescriptor: CallableDescriptor,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
origin: IrStatementOrigin? = null
|
||||
): IrCallableReference =
|
||||
when (callableDescriptor) {
|
||||
is FunctionDescriptor ->
|
||||
generateFunctionReference(
|
||||
startOffset, endOffset, type,
|
||||
context.symbolTable.referenceFunction(callableDescriptor.original),
|
||||
callableDescriptor,
|
||||
typeArguments,
|
||||
origin
|
||||
)
|
||||
is PropertyDescriptor ->
|
||||
generatePropertyReference(startOffset, endOffset, type, callableDescriptor, typeArguments, origin)
|
||||
else ->
|
||||
throw AssertionError("Unexpected callable reference: $callableDescriptor")
|
||||
}
|
||||
when (callableDescriptor) {
|
||||
is FunctionDescriptor ->
|
||||
generateFunctionReference(
|
||||
startOffset, endOffset, type,
|
||||
context.symbolTable.referenceFunction(callableDescriptor.original),
|
||||
callableDescriptor,
|
||||
typeArguments,
|
||||
origin
|
||||
)
|
||||
is PropertyDescriptor ->
|
||||
generatePropertyReference(startOffset, endOffset, type, callableDescriptor, typeArguments, origin)
|
||||
else ->
|
||||
throw AssertionError("Unexpected callable reference: $callableDescriptor")
|
||||
}
|
||||
|
||||
fun generateLocalDelegatedPropertyReference(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
irDelegateSymbol: IrVariableSymbol,
|
||||
origin: IrStatementOrigin?
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
irDelegateSymbol: IrVariableSymbol,
|
||||
origin: IrStatementOrigin?
|
||||
): IrLocalDelegatedPropertyReference {
|
||||
val getterDescriptor = variableDescriptor.getter ?:
|
||||
throw AssertionError("Local delegated property should have a getter: $variableDescriptor")
|
||||
val getterDescriptor =
|
||||
variableDescriptor.getter ?: throw AssertionError("Local delegated property should have a getter: $variableDescriptor")
|
||||
val setterDescriptor = variableDescriptor.setter
|
||||
|
||||
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor)
|
||||
val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it) }
|
||||
|
||||
return IrLocalDelegatedPropertyReferenceImpl(
|
||||
startOffset, endOffset, type,
|
||||
variableDescriptor,
|
||||
irDelegateSymbol, getterSymbol, setterSymbol,
|
||||
origin
|
||||
startOffset, endOffset, type,
|
||||
variableDescriptor,
|
||||
irDelegateSymbol, getterSymbol, setterSymbol,
|
||||
origin
|
||||
)
|
||||
}
|
||||
|
||||
private fun generatePropertyReference(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
propertyDescriptor: PropertyDescriptor,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
origin: IrStatementOrigin?
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
propertyDescriptor: PropertyDescriptor,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
origin: IrStatementOrigin?
|
||||
): IrPropertyReference {
|
||||
val getterDescriptor = propertyDescriptor.getter
|
||||
val setterDescriptor = propertyDescriptor.setter
|
||||
@@ -139,27 +142,27 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it.original) }
|
||||
|
||||
return IrPropertyReferenceImpl(
|
||||
startOffset, endOffset, type,
|
||||
propertyDescriptor,
|
||||
fieldSymbol, getterSymbol, setterSymbol,
|
||||
typeArguments,
|
||||
origin
|
||||
startOffset, endOffset, type,
|
||||
propertyDescriptor,
|
||||
fieldSymbol, getterSymbol, setterSymbol,
|
||||
typeArguments,
|
||||
origin
|
||||
)
|
||||
}
|
||||
|
||||
fun generateFunctionReference(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
symbol: IrFunctionSymbol,
|
||||
descriptor: FunctionDescriptor,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
origin: IrStatementOrigin?
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
symbol: IrFunctionSymbol,
|
||||
descriptor: FunctionDescriptor,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
origin: IrStatementOrigin?
|
||||
): IrFunctionReference =
|
||||
IrFunctionReferenceImpl(
|
||||
startOffset, endOffset, type,
|
||||
symbol, descriptor,
|
||||
typeArguments,
|
||||
origin
|
||||
)
|
||||
IrFunctionReferenceImpl(
|
||||
startOffset, endOffset, type,
|
||||
symbol, descriptor,
|
||||
typeArguments,
|
||||
origin
|
||||
)
|
||||
}
|
||||
+123
-98
@@ -45,61 +45,64 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||
import java.lang.AssertionError
|
||||
|
||||
class StatementGenerator(
|
||||
val bodyGenerator: BodyGenerator,
|
||||
override val scope: Scope
|
||||
val bodyGenerator: BodyGenerator,
|
||||
override val scope: Scope
|
||||
) : KtVisitor<IrStatement, Nothing?>(), GeneratorWithScope {
|
||||
override val context: GeneratorContext get() = bodyGenerator.context
|
||||
val scopeOwner: DeclarationDescriptor get() = bodyGenerator.scopeOwner
|
||||
|
||||
fun generateStatement(ktElement: KtElement): IrStatement =
|
||||
ktElement.genStmt()
|
||||
ktElement.genStmt()
|
||||
|
||||
fun generateStatements(ktStatements: List<KtExpression>, to: IrStatementContainer) =
|
||||
ktStatements.mapTo(to.statements) { generateStatement(it) }
|
||||
ktStatements.mapTo(to.statements) { generateStatement(it) }
|
||||
|
||||
fun generateExpression(ktExpression: KtExpression): IrExpression =
|
||||
ktExpression.genExpr()
|
||||
ktExpression.genExpr()
|
||||
|
||||
private fun KtElement.genStmt(): IrStatement =
|
||||
try {
|
||||
deparenthesize().accept(this@StatementGenerator, null)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(this, e)
|
||||
}
|
||||
try {
|
||||
deparenthesize().accept(this@StatementGenerator, null)
|
||||
} catch (e: Exception) {
|
||||
ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(this, e)
|
||||
}
|
||||
|
||||
private fun KtElement.genExpr(): IrExpression =
|
||||
genStmt().assertCast()
|
||||
genStmt().assertCast()
|
||||
|
||||
override fun visitExpression(expression: KtExpression, data: Nothing?): IrStatement =
|
||||
createDummyExpression(expression, expression::class.java.simpleName)
|
||||
createDummyExpression(expression, expression::class.java.simpleName)
|
||||
|
||||
override fun visitProperty(property: KtProperty, data: Nothing?): IrStatement {
|
||||
val variableDescriptor = getOrFail(BindingContext.VARIABLE, property)
|
||||
|
||||
property.delegate?.let { ktDelegate ->
|
||||
return generateLocalDelegatedProperty(property, ktDelegate, variableDescriptor as VariableDescriptorWithAccessors,
|
||||
bodyGenerator.scopeOwnerSymbol)
|
||||
return generateLocalDelegatedProperty(
|
||||
property, ktDelegate, variableDescriptor as VariableDescriptorWithAccessors,
|
||||
bodyGenerator.scopeOwnerSymbol
|
||||
)
|
||||
}
|
||||
|
||||
return context.symbolTable.declareVariable(
|
||||
property.startOffset, property.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
variableDescriptor, property.initializer?.genExpr()
|
||||
property.startOffset, property.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
variableDescriptor, property.initializer?.genExpr()
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateLocalDelegatedProperty(
|
||||
ktProperty: KtProperty,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
scopeOwnerSymbol: IrSymbol
|
||||
ktProperty: KtProperty,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
scopeOwnerSymbol: IrSymbol
|
||||
): IrStatement =
|
||||
DelegatedPropertyGenerator(context)
|
||||
.generateLocalDelegatedProperty(ktProperty, ktDelegate, variableDescriptor, scopeOwnerSymbol)
|
||||
DelegatedPropertyGenerator(context)
|
||||
.generateLocalDelegatedProperty(ktProperty, ktDelegate, variableDescriptor, scopeOwnerSymbol)
|
||||
|
||||
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement {
|
||||
val irBlock = IrCompositeImpl(multiDeclaration.startOffset, multiDeclaration.endOffset,
|
||||
context.builtIns.unitType, IrStatementOrigin.DESTRUCTURING_DECLARATION)
|
||||
val irBlock = IrCompositeImpl(
|
||||
multiDeclaration.startOffset, multiDeclaration.endOffset,
|
||||
context.builtIns.unitType, IrStatementOrigin.DESTRUCTURING_DECLARATION
|
||||
)
|
||||
val ktInitializer = multiDeclaration.initializer!!
|
||||
val containerValue = scope.createTemporaryVariableInBlock(ktInitializer.genExpr(), irBlock, "container")
|
||||
|
||||
@@ -108,7 +111,11 @@ class StatementGenerator(
|
||||
return irBlock
|
||||
}
|
||||
|
||||
fun declareComponentVariablesInBlock(multiDeclaration: KtDestructuringDeclaration, irBlock: IrStatementContainer, containerValue: IntermediateValue) {
|
||||
fun declareComponentVariablesInBlock(
|
||||
multiDeclaration: KtDestructuringDeclaration,
|
||||
irBlock: IrStatementContainer,
|
||||
containerValue: IntermediateValue
|
||||
) {
|
||||
val callGenerator = CallGenerator(this)
|
||||
for ((index, ktEntry) in multiDeclaration.entries.withIndex()) {
|
||||
val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry)
|
||||
@@ -121,11 +128,13 @@ class StatementGenerator(
|
||||
// componentN for '_' SHOULD NOT be evaluated
|
||||
if (componentVariable.name.isSpecial) continue
|
||||
|
||||
val irComponentCall = callGenerator.generateCall(ktEntry.startOffset, ktEntry.endOffset, componentSubstitutedCall,
|
||||
IrStatementOrigin.COMPONENT_N.withIndex(index + 1))
|
||||
val irComponentCall = callGenerator.generateCall(
|
||||
ktEntry.startOffset, ktEntry.endOffset, componentSubstitutedCall,
|
||||
IrStatementOrigin.COMPONENT_N.withIndex(index + 1)
|
||||
)
|
||||
val irComponentVar = context.symbolTable.declareVariable(
|
||||
ktEntry.startOffset, ktEntry.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
componentVariable, irComponentCall
|
||||
ktEntry.startOffset, ktEntry.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
componentVariable, irComponentCall
|
||||
)
|
||||
irBlock.statements.add(irComponentVar)
|
||||
}
|
||||
@@ -147,45 +156,54 @@ class StatementGenerator(
|
||||
|
||||
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrStatement {
|
||||
val returnTarget = getReturnExpressionTarget(expression)
|
||||
val irReturnedExpression = expression.returnedExpression?.genExpr() ?:
|
||||
IrGetObjectValueImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType,
|
||||
context.symbolTable.referenceClass(context.builtIns.unit))
|
||||
return IrReturnImpl(expression.startOffset, expression.endOffset, context.builtIns.nothingType,
|
||||
context.symbolTable.referenceFunction(returnTarget), irReturnedExpression)
|
||||
val irReturnedExpression = expression.returnedExpression?.genExpr() ?: IrGetObjectValueImpl(
|
||||
expression.startOffset, expression.endOffset, context.builtIns.unitType,
|
||||
context.symbolTable.referenceClass(context.builtIns.unit)
|
||||
)
|
||||
return IrReturnImpl(
|
||||
expression.startOffset, expression.endOffset, context.builtIns.nothingType,
|
||||
context.symbolTable.referenceFunction(returnTarget), irReturnedExpression
|
||||
)
|
||||
}
|
||||
|
||||
private fun scopeOwnerAsCallable() =
|
||||
(scopeOwner as? CallableDescriptor) ?: throw AssertionError("'return' in a non-callable: $scopeOwner")
|
||||
(scopeOwner as? CallableDescriptor) ?: throw AssertionError("'return' in a non-callable: $scopeOwner")
|
||||
|
||||
private fun getReturnExpressionTarget(expression: KtReturnExpression): CallableDescriptor =
|
||||
if (!ExpressionTypingUtils.isFunctionLiteral(scopeOwner) && !ExpressionTypingUtils.isFunctionExpression(scopeOwner)) {
|
||||
scopeOwnerAsCallable()
|
||||
}
|
||||
else {
|
||||
val label = expression.getTargetLabel()
|
||||
when {
|
||||
label != null -> {
|
||||
val labelTarget = getOrFail(BindingContext.LABEL_TARGET, label)
|
||||
val labelTargetDescriptor = getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, labelTarget)
|
||||
labelTargetDescriptor as CallableDescriptor
|
||||
}
|
||||
ExpressionTypingUtils.isFunctionLiteral(scopeOwner) -> {
|
||||
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(scopeOwner, true).first
|
||||
}
|
||||
else -> {
|
||||
scopeOwnerAsCallable()
|
||||
}
|
||||
if (!ExpressionTypingUtils.isFunctionLiteral(scopeOwner) && !ExpressionTypingUtils.isFunctionExpression(scopeOwner)) {
|
||||
scopeOwnerAsCallable()
|
||||
} else {
|
||||
val label = expression.getTargetLabel()
|
||||
when {
|
||||
label != null -> {
|
||||
val labelTarget = getOrFail(BindingContext.LABEL_TARGET, label)
|
||||
val labelTargetDescriptor = getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, labelTarget)
|
||||
labelTargetDescriptor as CallableDescriptor
|
||||
}
|
||||
ExpressionTypingUtils.isFunctionLiteral(scopeOwner) -> {
|
||||
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(scopeOwner, true).first
|
||||
}
|
||||
else -> {
|
||||
scopeOwnerAsCallable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 =
|
||||
generateConstantExpression(expression,
|
||||
ConstantExpressionEvaluator.getConstant(expression, context.bindingContext) ?:
|
||||
error("KtConstantExpression was not evaluated: ${expression.text}"))
|
||||
generateConstantExpression(
|
||||
expression,
|
||||
ConstantExpressionEvaluator.getConstant(expression, context.bindingContext)
|
||||
?: error("KtConstantExpression was not evaluated: ${expression.text}")
|
||||
)
|
||||
|
||||
fun generateConstantExpression(expression: KtExpression, constant: CompileTimeConstant<*>): IrExpression {
|
||||
val constantValue = constant.toConstantValue(getInferredTypeWithImplicitCastsOrFail(expression))
|
||||
@@ -236,13 +254,13 @@ class StatementGenerator(
|
||||
}
|
||||
|
||||
override fun visitLiteralStringTemplateEntry(entry: KtLiteralStringTemplateEntry, data: Nothing?): IrStatement =
|
||||
IrConstImpl.string(entry.startOffset, entry.endOffset, context.builtIns.stringType, entry.text)
|
||||
IrConstImpl.string(entry.startOffset, entry.endOffset, context.builtIns.stringType, entry.text)
|
||||
|
||||
override fun visitEscapeStringTemplateEntry(entry: KtEscapeStringTemplateEntry, data: Nothing?): IrStatement =
|
||||
IrConstImpl.string(entry.startOffset, entry.endOffset, context.builtIns.stringType, entry.unescapedValue)
|
||||
IrConstImpl.string(entry.startOffset, entry.endOffset, context.builtIns.stringType, entry.unescapedValue)
|
||||
|
||||
override fun visitStringTemplateEntryWithExpression(entry: KtStringTemplateEntryWithExpression, data: Nothing?): IrStatement =
|
||||
entry.expression!!.genExpr()
|
||||
entry.expression!!.genExpr()
|
||||
|
||||
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression, data: Nothing?): IrExpression {
|
||||
val resolvedCall = getResolvedCall(expression)
|
||||
@@ -267,18 +285,17 @@ class StatementGenerator(
|
||||
}
|
||||
|
||||
private fun generateExpressionForReferencedDescriptor(
|
||||
descriptor: DeclarationDescriptor,
|
||||
expression: KtExpression,
|
||||
resolvedCall: ResolvedCall<*>?
|
||||
descriptor: DeclarationDescriptor,
|
||||
expression: KtExpression,
|
||||
resolvedCall: ResolvedCall<*>?
|
||||
): IrExpression =
|
||||
CallGenerator(this).generateValueReference(
|
||||
expression.startOffset, expression.endOffset,
|
||||
descriptor, resolvedCall, null
|
||||
)
|
||||
CallGenerator(this).generateValueReference(
|
||||
expression.startOffset, expression.endOffset,
|
||||
descriptor, resolvedCall, null
|
||||
)
|
||||
|
||||
override fun visitCallExpression(expression: KtCallExpression, data: Nothing?): IrStatement {
|
||||
val resolvedCall = getResolvedCall(expression) ?:
|
||||
return ErrorExpressionGenerator(this).generateErrorCall(expression)
|
||||
val resolvedCall = getResolvedCall(expression) ?: return ErrorExpressionGenerator(this).generateErrorCall(expression)
|
||||
|
||||
if (resolvedCall is VariableAsFunctionResolvedCall) {
|
||||
val functionCall = pregenerateCall(resolvedCall.functionCall)
|
||||
@@ -291,26 +308,32 @@ class StatementGenerator(
|
||||
override fun visitArrayAccessExpression(expression: KtArrayAccessExpression, data: Nothing?): IrStatement {
|
||||
val indexedGetCall = getOrFail(BindingContext.INDEXED_LVALUE_GET, expression)
|
||||
|
||||
return CallGenerator(this).generateCall(expression.startOffset, expression.endOffset,
|
||||
pregenerateCall(indexedGetCall), IrStatementOrigin.GET_ARRAY_ELEMENT)
|
||||
return CallGenerator(this).generateCall(
|
||||
expression.startOffset, expression.endOffset,
|
||||
pregenerateCall(indexedGetCall), IrStatementOrigin.GET_ARRAY_ELEMENT
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression, data: Nothing?): IrStatement =
|
||||
expression.selectorExpression!!.accept(this, data)
|
||||
expression.selectorExpression!!.accept(this, data)
|
||||
|
||||
override fun visitSafeQualifiedExpression(expression: KtSafeQualifiedExpression, data: Nothing?): IrStatement =
|
||||
expression.selectorExpression!!.accept(this, data)
|
||||
expression.selectorExpression!!.accept(this, data)
|
||||
|
||||
override fun visitThisExpression(expression: KtThisExpression, data: Nothing?): IrExpression {
|
||||
val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" }
|
||||
return when (referenceTarget) {
|
||||
is ClassDescriptor ->
|
||||
IrGetValueImpl(expression.startOffset, expression.endOffset,
|
||||
context.symbolTable.referenceValueParameter(referenceTarget.thisAsReceiverParameter))
|
||||
IrGetValueImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
context.symbolTable.referenceValueParameter(referenceTarget.thisAsReceiverParameter)
|
||||
)
|
||||
is CallableDescriptor -> {
|
||||
val extensionReceiver = referenceTarget.extensionReceiverParameter ?: TODO("No extension receiver: $referenceTarget")
|
||||
IrGetValueImpl(expression.startOffset, expression.endOffset,
|
||||
context.symbolTable.referenceValueParameter(extensionReceiver))
|
||||
IrGetValueImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
context.symbolTable.referenceValueParameter(extensionReceiver)
|
||||
)
|
||||
}
|
||||
else ->
|
||||
error("Expected this or receiver: $referenceTarget")
|
||||
@@ -318,65 +341,67 @@ class StatementGenerator(
|
||||
}
|
||||
|
||||
override fun visitBinaryExpression(expression: KtBinaryExpression, data: Nothing?): IrStatement =
|
||||
OperatorExpressionGenerator(this).generateBinaryExpression(expression)
|
||||
OperatorExpressionGenerator(this).generateBinaryExpression(expression)
|
||||
|
||||
override fun visitPrefixExpression(expression: KtPrefixExpression, data: Nothing?): IrStatement =
|
||||
OperatorExpressionGenerator(this).generatePrefixExpression(expression)
|
||||
OperatorExpressionGenerator(this).generatePrefixExpression(expression)
|
||||
|
||||
override fun visitPostfixExpression(expression: KtPostfixExpression, data: Nothing?): IrStatement =
|
||||
OperatorExpressionGenerator(this).generatePostfixExpression(expression)
|
||||
OperatorExpressionGenerator(this).generatePostfixExpression(expression)
|
||||
|
||||
override fun visitBinaryWithTypeRHSExpression(expression: KtBinaryExpressionWithTypeRHS, data: Nothing?): IrStatement =
|
||||
OperatorExpressionGenerator(this).generateCastExpression(expression)
|
||||
OperatorExpressionGenerator(this).generateCastExpression(expression)
|
||||
|
||||
override fun visitIsExpression(expression: KtIsExpression, data: Nothing?): IrStatement =
|
||||
OperatorExpressionGenerator(this).generateInstanceOfExpression(expression)
|
||||
OperatorExpressionGenerator(this).generateInstanceOfExpression(expression)
|
||||
|
||||
override fun visitIfExpression(expression: KtIfExpression, data: Nothing?): IrStatement =
|
||||
BranchingExpressionGenerator(this).generateIfExpression(expression)
|
||||
BranchingExpressionGenerator(this).generateIfExpression(expression)
|
||||
|
||||
override fun visitWhenExpression(expression: KtWhenExpression, data: Nothing?): IrStatement =
|
||||
BranchingExpressionGenerator(this).generateWhenExpression(expression)
|
||||
BranchingExpressionGenerator(this).generateWhenExpression(expression)
|
||||
|
||||
override fun visitWhileExpression(expression: KtWhileExpression, data: Nothing?): IrStatement =
|
||||
LoopExpressionGenerator(this).generateWhileLoop(expression)
|
||||
LoopExpressionGenerator(this).generateWhileLoop(expression)
|
||||
|
||||
override fun visitDoWhileExpression(expression: KtDoWhileExpression, data: Nothing?): IrStatement =
|
||||
LoopExpressionGenerator(this).generateDoWhileLoop(expression)
|
||||
LoopExpressionGenerator(this).generateDoWhileLoop(expression)
|
||||
|
||||
override fun visitForExpression(expression: KtForExpression, data: Nothing?): IrStatement =
|
||||
LoopExpressionGenerator(this).generateForLoop(expression)
|
||||
LoopExpressionGenerator(this).generateForLoop(expression)
|
||||
|
||||
override fun visitBreakExpression(expression: KtBreakExpression, data: Nothing?): IrStatement =
|
||||
LoopExpressionGenerator(this).generateBreak(expression)
|
||||
LoopExpressionGenerator(this).generateBreak(expression)
|
||||
|
||||
override fun visitContinueExpression(expression: KtContinueExpression, data: Nothing?): IrStatement =
|
||||
LoopExpressionGenerator(this).generateContinue(expression)
|
||||
LoopExpressionGenerator(this).generateContinue(expression)
|
||||
|
||||
override fun visitTryExpression(expression: KtTryExpression, data: Nothing?): IrStatement =
|
||||
TryCatchExpressionGenerator(this).generateTryCatch(expression)
|
||||
TryCatchExpressionGenerator(this).generateTryCatch(expression)
|
||||
|
||||
override fun visitLambdaExpression(expression: KtLambdaExpression, data: Nothing?): IrStatement =
|
||||
LocalFunctionGenerator(this).generateLambda(expression)
|
||||
LocalFunctionGenerator(this).generateLambda(expression)
|
||||
|
||||
override fun visitNamedFunction(function: KtNamedFunction, data: Nothing?): IrStatement =
|
||||
LocalFunctionGenerator(this).generateFunction(function)
|
||||
LocalFunctionGenerator(this).generateFunction(function)
|
||||
|
||||
override fun visitObjectLiteralExpression(expression: KtObjectLiteralExpression, data: Nothing?): IrStatement =
|
||||
LocalClassGenerator(this).generateObjectLiteral(expression)
|
||||
LocalClassGenerator(this).generateObjectLiteral(expression)
|
||||
|
||||
override fun visitClassOrObject(classOrObject: KtClassOrObject, data: Nothing?): IrStatement =
|
||||
LocalClassGenerator(this).generateLocalClass(classOrObject)
|
||||
LocalClassGenerator(this).generateLocalClass(classOrObject)
|
||||
|
||||
override fun visitTypeAlias(typeAlias: KtTypeAlias, data: Nothing?): IrStatement =
|
||||
IrTypeAliasImpl(typeAlias.startOffset, typeAlias.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
getOrFail(BindingContext.TYPE_ALIAS, typeAlias))
|
||||
IrTypeAliasImpl(
|
||||
typeAlias.startOffset, typeAlias.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
getOrFail(BindingContext.TYPE_ALIAS, typeAlias)
|
||||
)
|
||||
|
||||
override fun visitClassLiteralExpression(expression: KtClassLiteralExpression, data: Nothing?): IrStatement =
|
||||
ReflectionReferencesGenerator(this).generateClassLiteral(expression)
|
||||
ReflectionReferencesGenerator(this).generateClassLiteral(expression)
|
||||
|
||||
override fun visitCallableReferenceExpression(expression: KtCallableReferenceExpression, data: Nothing?): IrStatement =
|
||||
ReflectionReferencesGenerator(this).generateCallableReference(expression)
|
||||
ReflectionReferencesGenerator(this).generateCallableReference(expression)
|
||||
}
|
||||
|
||||
abstract class StatementGeneratorExtension(val statementGenerator: StatementGenerator) : GeneratorWithScope {
|
||||
|
||||
+6
-6
@@ -56,16 +56,16 @@ class SyntheticDescriptorsFactory {
|
||||
}
|
||||
|
||||
private fun isStaticPropertyInClass(propertyDescriptor: PropertyDescriptor): Boolean =
|
||||
propertyDescriptor.containingDeclaration is ClassDescriptor &&
|
||||
propertyDescriptor.dispatchReceiverParameter == null &&
|
||||
propertyDescriptor.extensionReceiverParameter == null
|
||||
propertyDescriptor.containingDeclaration is ClassDescriptor &&
|
||||
propertyDescriptor.dispatchReceiverParameter == null &&
|
||||
propertyDescriptor.extensionReceiverParameter == null
|
||||
|
||||
private fun isPropertyInClass(propertyDescriptor: PropertyDescriptor): Boolean =
|
||||
propertyDescriptor.containingDeclaration is ClassDescriptor
|
||||
propertyDescriptor.containingDeclaration is ClassDescriptor
|
||||
|
||||
fun getOrCreatePropertyGetter(propertyDescriptor: PropertyDescriptor): PropertyGetterDescriptor =
|
||||
propertyGetters.getOrPut(propertyDescriptor) { generateGetter(propertyDescriptor) }
|
||||
propertyGetters.getOrPut(propertyDescriptor) { generateGetter(propertyDescriptor) }
|
||||
|
||||
fun getOrCreatePropertySetter(propertyDescriptor: PropertyDescriptor): PropertySetterDescriptor =
|
||||
propertySetters.getOrPut(propertyDescriptor) { generateSetter(propertyDescriptor) }
|
||||
propertySetters.getOrPut(propertyDescriptor) { generateSetter(propertyDescriptor) }
|
||||
}
|
||||
|
||||
+7
-7
@@ -38,12 +38,12 @@ class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
val catchParameterDescriptor = getOrFail(BindingContext.VALUE_PARAMETER, ktCatchParameter)
|
||||
|
||||
val irCatch = IrCatchImpl(
|
||||
ktCatchClause.startOffset, ktCatchClause.endOffset,
|
||||
context.symbolTable.declareVariable(
|
||||
ktCatchParameter.startOffset, ktCatchParameter.endOffset,
|
||||
IrDeclarationOrigin.CATCH_PARAMETER,
|
||||
catchParameterDescriptor
|
||||
)
|
||||
ktCatchClause.startOffset, ktCatchClause.endOffset,
|
||||
context.symbolTable.declareVariable(
|
||||
ktCatchParameter.startOffset, ktCatchParameter.endOffset,
|
||||
IrDeclarationOrigin.CATCH_PARAMETER,
|
||||
catchParameterDescriptor
|
||||
)
|
||||
).apply {
|
||||
result = statementGenerator.generateExpression(ktCatchBody)
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
irTryCatch.catches.add(irCatch)
|
||||
}
|
||||
|
||||
irTryCatch.finallyExpression = ktTry.finallyBlock?.let{ statementGenerator.generateExpression(it.finalExpression) }
|
||||
irTryCatch.finallyExpression = ktTry.finallyBlock?.let { statementGenerator.generateExpression(it.finalExpression) }
|
||||
|
||||
return irTryCatch
|
||||
}
|
||||
|
||||
+11
-11
@@ -26,18 +26,18 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.lang.AssertionError
|
||||
|
||||
class ArrayAccessAssignmentReceiver(
|
||||
val irArray: IrExpression,
|
||||
val irIndices: List<IrExpression>,
|
||||
val indexedGetCall: CallBuilder?,
|
||||
val indexedSetCall: CallBuilder?,
|
||||
val callGenerator: CallGenerator,
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val origin: IrStatementOrigin
|
||||
val irArray: IrExpression,
|
||||
val irIndices: List<IrExpression>,
|
||||
val indexedGetCall: CallBuilder?,
|
||||
val indexedSetCall: CallBuilder?,
|
||||
val callGenerator: CallGenerator,
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val origin: IrStatementOrigin
|
||||
) : AssignmentReceiver {
|
||||
private val type: KotlinType = indexedGetCall?.run { descriptor.returnType!! } ?:
|
||||
indexedSetCall?.run { descriptor.valueParameters.last().type } ?:
|
||||
throw AssertionError("Array access should have either indexed-get call or indexed-set call")
|
||||
private val type: KotlinType =
|
||||
indexedGetCall?.run { descriptor.returnType!! } ?: indexedSetCall?.run { descriptor.valueParameters.last().type }
|
||||
?: throw AssertionError("Array access should have either indexed-get call or indexed-set call")
|
||||
|
||||
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression {
|
||||
val hasResult = origin.isAssignmentOperatorWithResult()
|
||||
|
||||
+9
-9
@@ -24,19 +24,19 @@ import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class BackingFieldLValue(
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
override val type: KotlinType,
|
||||
val symbol: IrFieldSymbol,
|
||||
val receiver: IntermediateValue?,
|
||||
val origin: IrStatementOrigin?
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
override val type: KotlinType,
|
||||
val symbol: IrFieldSymbol,
|
||||
val receiver: IntermediateValue?,
|
||||
val origin: IrStatementOrigin?
|
||||
) : LValue, AssignmentReceiver {
|
||||
override fun store(irExpression: IrExpression): IrExpression =
|
||||
IrSetFieldImpl(startOffset, endOffset, symbol, receiver?.load(), irExpression, origin)
|
||||
IrSetFieldImpl(startOffset, endOffset, symbol, receiver?.load(), irExpression, origin)
|
||||
|
||||
override fun load(): IrExpression =
|
||||
IrGetFieldImpl(startOffset, endOffset, symbol, receiver?.load(), origin)
|
||||
IrGetFieldImpl(startOffset, endOffset, symbol, receiver?.load(), origin)
|
||||
|
||||
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression =
|
||||
withLValue(this)
|
||||
withLValue(this)
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class CallBuilder(
|
||||
val original: ResolvedCall<*>,
|
||||
val descriptor: CallableDescriptor,
|
||||
val isExtensionInvokeCall: Boolean = false
|
||||
val original: ResolvedCall<*>,
|
||||
val descriptor: CallableDescriptor,
|
||||
val isExtensionInvokeCall: Boolean = false
|
||||
) {
|
||||
var superQualifier: ClassDescriptor? = null
|
||||
|
||||
@@ -39,10 +39,11 @@ class CallBuilder(
|
||||
val irValueArgumentsByIndex = arrayOfNulls<IrExpression>(descriptor.valueParameters.size)
|
||||
|
||||
fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor) =
|
||||
irValueArgumentsByIndex[valueParameterDescriptor.index + parametersOffset]
|
||||
irValueArgumentsByIndex[valueParameterDescriptor.index + parametersOffset]
|
||||
}
|
||||
|
||||
val CallBuilder.argumentsCount: Int get() =
|
||||
val CallBuilder.argumentsCount: Int
|
||||
get() =
|
||||
irValueArgumentsByIndex.size
|
||||
|
||||
var CallBuilder.lastArgument: IrExpression?
|
||||
@@ -52,27 +53,33 @@ var CallBuilder.lastArgument: IrExpression?
|
||||
}
|
||||
|
||||
fun CallBuilder.getValueArgumentsInParameterOrder(): List<IrExpression?> =
|
||||
descriptor.valueParameters.map { irValueArgumentsByIndex[it.index] }
|
||||
descriptor.valueParameters.map { irValueArgumentsByIndex[it.index] }
|
||||
|
||||
fun CallBuilder.isValueArgumentReorderingRequired() =
|
||||
original.isValueArgumentReorderingRequired()
|
||||
original.isValueArgumentReorderingRequired()
|
||||
|
||||
val CallBuilder.hasExtensionReceiver: Boolean get() =
|
||||
val CallBuilder.hasExtensionReceiver: Boolean
|
||||
get() =
|
||||
descriptor.extensionReceiverParameter != null
|
||||
|
||||
val CallBuilder.hasDispatchReceiver: Boolean get() =
|
||||
val CallBuilder.hasDispatchReceiver: Boolean
|
||||
get() =
|
||||
descriptor.dispatchReceiverParameter != null
|
||||
|
||||
val CallBuilder.extensionReceiverType: KotlinType? get() =
|
||||
val CallBuilder.extensionReceiverType: KotlinType?
|
||||
get() =
|
||||
descriptor.extensionReceiverParameter?.type
|
||||
|
||||
val CallBuilder.dispatchReceiverType: KotlinType? get() =
|
||||
val CallBuilder.dispatchReceiverType: KotlinType?
|
||||
get() =
|
||||
descriptor.dispatchReceiverParameter?.type
|
||||
|
||||
val CallBuilder.explicitReceiverParameter: ReceiverParameterDescriptor? get() =
|
||||
val CallBuilder.explicitReceiverParameter: ReceiverParameterDescriptor?
|
||||
get() =
|
||||
descriptor.extensionReceiverParameter ?: descriptor.dispatchReceiverParameter
|
||||
|
||||
val CallBuilder.explicitReceiverType: KotlinType? get() =
|
||||
val CallBuilder.explicitReceiverType: KotlinType?
|
||||
get() =
|
||||
explicitReceiverParameter?.type
|
||||
|
||||
fun CallBuilder.setExplicitReceiverValue(explicitReceiverValue: IntermediateValue) {
|
||||
|
||||
+11
-11
@@ -23,21 +23,21 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class DelegatedLocalPropertyLValue(
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
override val type: KotlinType,
|
||||
val getterSymbol: IrSimpleFunctionSymbol?,
|
||||
val setterSymbol: IrSimpleFunctionSymbol?,
|
||||
val origin: IrStatementOrigin? = null
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
override val type: KotlinType,
|
||||
val getterSymbol: IrSimpleFunctionSymbol?,
|
||||
val setterSymbol: IrSimpleFunctionSymbol?,
|
||||
val origin: IrStatementOrigin? = null
|
||||
) : LValue, AssignmentReceiver {
|
||||
override fun load(): IrExpression =
|
||||
IrCallImpl(startOffset, endOffset, type, getterSymbol!!, getterSymbol.descriptor, null, origin)
|
||||
IrCallImpl(startOffset, endOffset, type, getterSymbol!!, getterSymbol.descriptor, null, origin)
|
||||
|
||||
override fun store(irExpression: IrExpression): IrExpression =
|
||||
IrCallImpl(startOffset, endOffset, type, setterSymbol!!, setterSymbol.descriptor, null, origin).apply {
|
||||
putValueArgument(0, irExpression)
|
||||
}
|
||||
IrCallImpl(startOffset, endOffset, type, setterSymbol!!, setterSymbol.descriptor, null, origin).apply {
|
||||
putValueArgument(0, irExpression)
|
||||
}
|
||||
|
||||
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression =
|
||||
withLValue(this)
|
||||
withLValue(this)
|
||||
}
|
||||
|
||||
+3
-3
@@ -19,9 +19,9 @@ package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
|
||||
class ExtensionInvokeCallReceiver(
|
||||
val callBuilder: CallBuilder,
|
||||
val functionReceiver: IntermediateValue,
|
||||
val extensionInvokeReceiver: IntermediateValue
|
||||
val callBuilder: CallBuilder,
|
||||
val functionReceiver: IntermediateValue,
|
||||
val extensionInvokeReceiver: IntermediateValue
|
||||
) : CallReceiver {
|
||||
override fun call(withDispatchAndExtensionReceivers: (IntermediateValue?, IntermediateValue?) -> IrExpression): IrExpression {
|
||||
// extensionInvokeReceiver is actually a first argument:
|
||||
|
||||
+9
-10
@@ -23,18 +23,17 @@ import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class LValueWithGetterAndSetterCalls(
|
||||
val callGenerator: CallGenerator,
|
||||
val getterCall: CallBuilder?,
|
||||
val setterCall: CallBuilder?,
|
||||
override val type: KotlinType,
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val origin: IrStatementOrigin? = null
|
||||
val callGenerator: CallGenerator,
|
||||
val getterCall: CallBuilder?,
|
||||
val setterCall: CallBuilder?,
|
||||
override val type: KotlinType,
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val origin: IrStatementOrigin? = null
|
||||
) : LValue {
|
||||
private val descriptor: CallableDescriptor =
|
||||
getterCall?.descriptor ?:
|
||||
setterCall?.descriptor ?:
|
||||
throw AssertionError("Call-based LValue should have either a getter or a setter call")
|
||||
getterCall?.descriptor ?: setterCall?.descriptor
|
||||
?: throw AssertionError("Call-based LValue should have either a getter or a setter call")
|
||||
|
||||
override fun load(): IrExpression {
|
||||
if (getterCall == null) throw AssertionError("No getter call for $descriptor")
|
||||
|
||||
@@ -23,12 +23,12 @@ import org.jetbrains.kotlin.psi2ir.generators.StatementGenerator
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class OnceCallValue(
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val statementGenerator: StatementGenerator,
|
||||
val call: CallBuilder,
|
||||
val origin: IrStatementOrigin? = null
|
||||
): IntermediateValue {
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val statementGenerator: StatementGenerator,
|
||||
val call: CallBuilder,
|
||||
val origin: IrStatementOrigin? = null
|
||||
) : IntermediateValue {
|
||||
private var instantiated = false
|
||||
|
||||
override fun load(): IrExpression {
|
||||
|
||||
+8
-8
@@ -23,15 +23,15 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
abstract class ExpressionValue(override val type: KotlinType) : IntermediateValue
|
||||
|
||||
inline fun generateExpressionValue(type: KotlinType, crossinline generate: () -> IrExpression) =
|
||||
object : ExpressionValue(type) {
|
||||
override fun load(): IrExpression = generate()
|
||||
}
|
||||
object : ExpressionValue(type) {
|
||||
override fun load(): IrExpression = generate()
|
||||
}
|
||||
|
||||
inline fun generateDelegatedValue(type: KotlinType, crossinline generateValue: () -> IntermediateValue) =
|
||||
object : ExpressionValue(type) {
|
||||
val lazyDelegate by lazy { generateValue() }
|
||||
override fun load(): IrExpression = lazyDelegate.load()
|
||||
}
|
||||
object : ExpressionValue(type) {
|
||||
val lazyDelegate by lazy { generateValue() }
|
||||
override fun load(): IrExpression = lazyDelegate.load()
|
||||
}
|
||||
|
||||
class OnceExpressionValue(val irExpression: IrExpression) : LValue, AssignmentReceiver {
|
||||
private var instantiated = false
|
||||
@@ -49,5 +49,5 @@ class OnceExpressionValue(val irExpression: IrExpression) : LValue, AssignmentRe
|
||||
}
|
||||
|
||||
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression =
|
||||
withLValue(this)
|
||||
withLValue(this)
|
||||
}
|
||||
+102
-102
@@ -28,131 +28,131 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
abstract class PropertyLValueBase(
|
||||
val scope: Scope,
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val origin: IrStatementOrigin?,
|
||||
override val type: KotlinType,
|
||||
val callReceiver: CallReceiver,
|
||||
val superQualifier: IrClassSymbol?
|
||||
val scope: Scope,
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val origin: IrStatementOrigin?,
|
||||
override val type: KotlinType,
|
||||
val callReceiver: CallReceiver,
|
||||
val superQualifier: IrClassSymbol?
|
||||
) : LValue, AssignmentReceiver {
|
||||
override fun assign(withLValue: (LValue) -> IrExpression) =
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
val dispatchReceiverVariable2 = dispatchReceiverValue?.let {
|
||||
scope.createTemporaryVariable(dispatchReceiverValue.load(), "this")
|
||||
}
|
||||
val dispatchReceiverValue2 = dispatchReceiverVariable2?.let { VariableLValue(it) }
|
||||
|
||||
val extensionReceiverVariable2 = extensionReceiverValue?.let {
|
||||
scope.createTemporaryVariable(extensionReceiverValue.load(), "receiver")
|
||||
}
|
||||
val extensionReceiverValue2 = extensionReceiverVariable2?.let { VariableLValue(it) }
|
||||
|
||||
val irResultExpression = withLValue(withReceiver(dispatchReceiverValue2, extensionReceiverValue2))
|
||||
|
||||
val irBlock = IrBlockImpl(startOffset, endOffset, irResultExpression.type, origin)
|
||||
irBlock.addIfNotNull(dispatchReceiverVariable2)
|
||||
irBlock.addIfNotNull(extensionReceiverVariable2)
|
||||
irBlock.statements.add(irResultExpression)
|
||||
irBlock
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
val dispatchReceiverVariable2 = dispatchReceiverValue?.let {
|
||||
scope.createTemporaryVariable(dispatchReceiverValue.load(), "this")
|
||||
}
|
||||
val dispatchReceiverValue2 = dispatchReceiverVariable2?.let { VariableLValue(it) }
|
||||
|
||||
val extensionReceiverVariable2 = extensionReceiverValue?.let {
|
||||
scope.createTemporaryVariable(extensionReceiverValue.load(), "receiver")
|
||||
}
|
||||
val extensionReceiverValue2 = extensionReceiverVariable2?.let { VariableLValue(it) }
|
||||
|
||||
val irResultExpression = withLValue(withReceiver(dispatchReceiverValue2, extensionReceiverValue2))
|
||||
|
||||
val irBlock = IrBlockImpl(startOffset, endOffset, irResultExpression.type, origin)
|
||||
irBlock.addIfNotNull(dispatchReceiverVariable2)
|
||||
irBlock.addIfNotNull(extensionReceiverVariable2)
|
||||
irBlock.statements.add(irResultExpression)
|
||||
irBlock
|
||||
}
|
||||
|
||||
override fun assign(value: IrExpression): IrExpression =
|
||||
store(value)
|
||||
store(value)
|
||||
|
||||
protected abstract fun withReceiver(dispatchReceiver: VariableLValue?, extensionReceiver: VariableLValue?): PropertyLValueBase
|
||||
}
|
||||
|
||||
class FieldPropertyLValue(
|
||||
scope: Scope,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrStatementOrigin?,
|
||||
val field: IrFieldSymbol,
|
||||
callReceiver: CallReceiver,
|
||||
superQualifier: IrClassSymbol?
|
||||
scope: Scope,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrStatementOrigin?,
|
||||
val field: IrFieldSymbol,
|
||||
callReceiver: CallReceiver,
|
||||
superQualifier: IrClassSymbol?
|
||||
) : PropertyLValueBase(scope, startOffset, endOffset, origin, field.descriptor.type, callReceiver, superQualifier) {
|
||||
override fun load(): IrExpression =
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
assert(extensionReceiverValue == null) { "Field can't have an extension receiver: ${field.descriptor}" }
|
||||
IrGetFieldImpl(
|
||||
startOffset, endOffset,
|
||||
field,
|
||||
dispatchReceiverValue?.load(),
|
||||
origin,
|
||||
superQualifier
|
||||
)
|
||||
}
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
assert(extensionReceiverValue == null) { "Field can't have an extension receiver: ${field.descriptor}" }
|
||||
IrGetFieldImpl(
|
||||
startOffset, endOffset,
|
||||
field,
|
||||
dispatchReceiverValue?.load(),
|
||||
origin,
|
||||
superQualifier
|
||||
)
|
||||
}
|
||||
|
||||
override fun store(irExpression: IrExpression) =
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
assert(extensionReceiverValue == null) { "Field can't have an extension receiver: ${field.descriptor}" }
|
||||
IrSetFieldImpl(
|
||||
startOffset, endOffset,
|
||||
field,
|
||||
dispatchReceiverValue?.load(),
|
||||
irExpression,
|
||||
origin,
|
||||
superQualifier
|
||||
)
|
||||
}
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
assert(extensionReceiverValue == null) { "Field can't have an extension receiver: ${field.descriptor}" }
|
||||
IrSetFieldImpl(
|
||||
startOffset, endOffset,
|
||||
field,
|
||||
dispatchReceiverValue?.load(),
|
||||
irExpression,
|
||||
origin,
|
||||
superQualifier
|
||||
)
|
||||
}
|
||||
|
||||
override fun withReceiver(dispatchReceiver: VariableLValue?, extensionReceiver: VariableLValue?): PropertyLValueBase =
|
||||
FieldPropertyLValue(
|
||||
scope, startOffset, endOffset, origin,
|
||||
field,
|
||||
SimpleCallReceiver(dispatchReceiver, extensionReceiver),
|
||||
superQualifier
|
||||
)
|
||||
FieldPropertyLValue(
|
||||
scope, startOffset, endOffset, origin,
|
||||
field,
|
||||
SimpleCallReceiver(dispatchReceiver, extensionReceiver),
|
||||
superQualifier
|
||||
)
|
||||
}
|
||||
|
||||
class AccessorPropertyLValue(
|
||||
scope: Scope,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrStatementOrigin?,
|
||||
type: KotlinType,
|
||||
val getter: IrFunctionSymbol?,
|
||||
val getterDescriptor: FunctionDescriptor?,
|
||||
val setter: IrFunctionSymbol?,
|
||||
val setterDescriptor: FunctionDescriptor?,
|
||||
val typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
callReceiver: CallReceiver,
|
||||
superQualifier: IrClassSymbol?
|
||||
scope: Scope,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrStatementOrigin?,
|
||||
type: KotlinType,
|
||||
val getter: IrFunctionSymbol?,
|
||||
val getterDescriptor: FunctionDescriptor?,
|
||||
val setter: IrFunctionSymbol?,
|
||||
val setterDescriptor: FunctionDescriptor?,
|
||||
val typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
callReceiver: CallReceiver,
|
||||
superQualifier: IrClassSymbol?
|
||||
) : PropertyLValueBase(scope, startOffset, endOffset, origin, type, callReceiver, superQualifier) {
|
||||
override fun load(): IrExpression =
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
IrGetterCallImpl(
|
||||
startOffset, endOffset,
|
||||
getter!!, getterDescriptor!!,
|
||||
typeArguments,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
origin,
|
||||
superQualifier
|
||||
)
|
||||
}
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
IrGetterCallImpl(
|
||||
startOffset, endOffset,
|
||||
getter!!, getterDescriptor!!,
|
||||
typeArguments,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
origin,
|
||||
superQualifier
|
||||
)
|
||||
}
|
||||
|
||||
override fun store(irExpression: IrExpression) =
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
IrSetterCallImpl(
|
||||
startOffset, endOffset,
|
||||
setter!!, setterDescriptor!!,
|
||||
typeArguments,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
irExpression,
|
||||
origin,
|
||||
superQualifier
|
||||
)
|
||||
}
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
IrSetterCallImpl(
|
||||
startOffset, endOffset,
|
||||
setter!!, setterDescriptor!!,
|
||||
typeArguments,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
irExpression,
|
||||
origin,
|
||||
superQualifier
|
||||
)
|
||||
}
|
||||
|
||||
override fun withReceiver(dispatchReceiver: VariableLValue?, extensionReceiver: VariableLValue?): PropertyLValueBase =
|
||||
AccessorPropertyLValue(
|
||||
scope, startOffset, endOffset, origin,
|
||||
type, getter, getterDescriptor, setter, setterDescriptor,
|
||||
typeArguments,
|
||||
SimpleCallReceiver(dispatchReceiver, extensionReceiver),
|
||||
superQualifier
|
||||
)
|
||||
AccessorPropertyLValue(
|
||||
scope, startOffset, endOffset, origin,
|
||||
type, getter, getterDescriptor, setter, setterDescriptor,
|
||||
typeArguments,
|
||||
SimpleCallReceiver(dispatchReceiver, extensionReceiver),
|
||||
superQualifier
|
||||
)
|
||||
}
|
||||
+5
-1
@@ -28,7 +28,11 @@ class RematerializableValue(val irExpression: IrExpressionWithCopy) : Intermedia
|
||||
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)
|
||||
block.statements.add(temporaryVariable)
|
||||
return VariableLValue(temporaryVariable)
|
||||
|
||||
+14
-13
@@ -28,12 +28,12 @@ import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
|
||||
|
||||
class SafeCallReceiver(
|
||||
val generator: GeneratorWithScope,
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val extensionReceiver: IntermediateValue?,
|
||||
val dispatchReceiver: IntermediateValue?,
|
||||
val isAssignmentReceiver: Boolean
|
||||
val generator: GeneratorWithScope,
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val extensionReceiver: IntermediateValue?,
|
||||
val dispatchReceiver: IntermediateValue?,
|
||||
val isAssignmentReceiver: Boolean
|
||||
) : CallReceiver {
|
||||
override fun call(withDispatchAndExtensionReceivers: (IntermediateValue?, IntermediateValue?) -> IrExpression): IrExpression {
|
||||
val irTmp = generator.scope.createTemporaryVariable(extensionReceiver?.load() ?: dispatchReceiver!!.load(), "safe_receiver")
|
||||
@@ -44,8 +44,7 @@ class SafeCallReceiver(
|
||||
if (extensionReceiver != null) {
|
||||
dispatchReceiverValue = dispatchReceiver
|
||||
extensionReceiverValue = safeReceiverValue
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dispatchReceiverValue = safeReceiverValue
|
||||
extensionReceiverValue = null
|
||||
}
|
||||
@@ -57,11 +56,13 @@ class SafeCallReceiver(
|
||||
|
||||
irBlock.statements.add(irTmp)
|
||||
|
||||
val irIfThenElse = IrIfThenElseImpl(startOffset, endOffset, resultType,
|
||||
generator.context.equalsNull(startOffset, endOffset, safeReceiverValue.load()),
|
||||
generator.context.constNull(startOffset, endOffset),
|
||||
irResult,
|
||||
IrStatementOrigin.SAFE_CALL)
|
||||
val irIfThenElse = IrIfThenElseImpl(
|
||||
startOffset, endOffset, resultType,
|
||||
generator.context.equalsNull(startOffset, endOffset, safeReceiverValue.load()),
|
||||
generator.context.constNull(startOffset, endOffset),
|
||||
irResult,
|
||||
IrStatementOrigin.SAFE_CALL
|
||||
)
|
||||
irBlock.statements.add(irIfThenElse)
|
||||
|
||||
return irBlock
|
||||
|
||||
+16
-16
@@ -26,12 +26,12 @@ import org.jetbrains.kotlin.psi2ir.generators.GeneratorWithScope
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
|
||||
class SafeExtensionInvokeCallReceiver(
|
||||
val generator: GeneratorWithScope,
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val callBuilder: CallBuilder,
|
||||
val functionReceiver: IntermediateValue,
|
||||
val extensionInvokeReceiver: IntermediateValue
|
||||
val generator: GeneratorWithScope,
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val callBuilder: CallBuilder,
|
||||
val functionReceiver: IntermediateValue,
|
||||
val extensionInvokeReceiver: IntermediateValue
|
||||
) : CallReceiver {
|
||||
override fun call(withDispatchAndExtensionReceivers: (IntermediateValue?, IntermediateValue?) -> IrExpression): IrExpression {
|
||||
// extensionInvokeReceiver is actually a first argument:
|
||||
@@ -54,17 +54,17 @@ class SafeExtensionInvokeCallReceiver(
|
||||
val resultType = irResult.type.makeNullable()
|
||||
|
||||
return IrBlockImpl(
|
||||
startOffset, endOffset, resultType, IrStatementOrigin.SAFE_CALL,
|
||||
arrayListOf(
|
||||
irTmp,
|
||||
IrIfThenElseImpl(
|
||||
startOffset, endOffset, resultType,
|
||||
generator.context.equalsNull(startOffset, endOffset, safeReceiverValue.load()),
|
||||
generator.context.constNull(startOffset, endOffset),
|
||||
irResult,
|
||||
IrStatementOrigin.SAFE_CALL
|
||||
)
|
||||
startOffset, endOffset, resultType, IrStatementOrigin.SAFE_CALL,
|
||||
arrayListOf(
|
||||
irTmp,
|
||||
IrIfThenElseImpl(
|
||||
startOffset, endOffset, resultType,
|
||||
generator.context.equalsNull(startOffset, endOffset, safeReceiverValue.load()),
|
||||
generator.context.constNull(startOffset, endOffset),
|
||||
irResult,
|
||||
IrStatementOrigin.SAFE_CALL
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -19,8 +19,8 @@ package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
|
||||
class SimpleCallReceiver(
|
||||
val dispatchReceiverValue: IntermediateValue?,
|
||||
val extensionReceiverValue: IntermediateValue?
|
||||
val dispatchReceiverValue: IntermediateValue?,
|
||||
val extensionReceiverValue: IntermediateValue?
|
||||
) : CallReceiver {
|
||||
override fun call(withDispatchAndExtensionReceivers: (IntermediateValue?, IntermediateValue?) -> IrExpression): IrExpression {
|
||||
return withDispatchAndExtensionReceivers(dispatchReceiverValue, extensionReceiverValue)
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class TransientReceiverValue(override val type: KotlinType): IntermediateValue {
|
||||
class TransientReceiverValue(override val type: KotlinType) : IntermediateValue {
|
||||
override fun load(): IrExpression {
|
||||
throw AssertionError("Transient receiver should not be instantiated")
|
||||
}
|
||||
|
||||
+13
-12
@@ -27,26 +27,27 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
|
||||
|
||||
class VariableLValue(
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val symbol: IrValueSymbol,
|
||||
val origin: IrStatementOrigin? = null
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val symbol: IrValueSymbol,
|
||||
val origin: IrStatementOrigin? = null
|
||||
) : LValue, AssignmentReceiver {
|
||||
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 fun load(): IrExpression =
|
||||
IrGetValueImpl(startOffset, endOffset, symbol, origin)
|
||||
IrGetValueImpl(startOffset, endOffset, symbol, origin)
|
||||
|
||||
override fun store(irExpression: IrExpression): IrExpression =
|
||||
IrSetVariableImpl(
|
||||
startOffset, endOffset,
|
||||
symbol.assertedCast<IrVariableSymbol> { "Not a variable: ${symbol.descriptor}" },
|
||||
irExpression, origin
|
||||
)
|
||||
IrSetVariableImpl(
|
||||
startOffset, endOffset,
|
||||
symbol.assertedCast<IrVariableSymbol> { "Not a variable: ${symbol.descriptor}" },
|
||||
irExpression, origin
|
||||
)
|
||||
|
||||
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression =
|
||||
withLValue(this)
|
||||
withLValue(this)
|
||||
}
|
||||
+88
-85
@@ -17,8 +17,6 @@
|
||||
package org.jetbrains.kotlin.psi2ir.transformations
|
||||
|
||||
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.IrStatement
|
||||
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.impl.IrTypeOperatorCallImpl
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.psi2ir.containsNull
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
@@ -40,7 +37,7 @@ fun insertImplicitCasts(builtIns: KotlinBuiltIns, element: IrElement) {
|
||||
element.transformChildren(InsertImplicitCasts(builtIns), null)
|
||||
}
|
||||
|
||||
class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoid() {
|
||||
class InsertImplicitCasts(val builtIns: KotlinBuiltIns) : IrElementTransformerVoid() {
|
||||
override fun visitCallableReference(expression: IrCallableReference): IrExpression =
|
||||
expression.transformPostfix {
|
||||
transformReceiverArguments()
|
||||
@@ -52,113 +49,113 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoi
|
||||
}
|
||||
|
||||
override fun visitMemberAccess(expression: IrMemberAccessExpression): IrExpression =
|
||||
expression.transformPostfix {
|
||||
transformReceiverArguments()
|
||||
for (index in descriptor.valueParameters.indices) {
|
||||
val argument = getValueArgument(index) ?: continue
|
||||
val parameterType = descriptor.valueParameters[index].type
|
||||
putValueArgument(index, argument.cast(parameterType))
|
||||
}
|
||||
expression.transformPostfix {
|
||||
transformReceiverArguments()
|
||||
for (index in descriptor.valueParameters.indices) {
|
||||
val argument = getValueArgument(index) ?: continue
|
||||
val parameterType = descriptor.valueParameters[index].type
|
||||
putValueArgument(index, argument.cast(parameterType))
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitBlockBody(body: IrBlockBody): IrBody =
|
||||
body.transformPostfix {
|
||||
statements.forEachIndexed { i, irStatement ->
|
||||
if (irStatement is IrExpression) {
|
||||
body.statements[i] = irStatement.coerceToUnit()
|
||||
}
|
||||
body.transformPostfix {
|
||||
statements.forEachIndexed { i, irStatement ->
|
||||
if (irStatement is IrExpression) {
|
||||
body.statements[i] = irStatement.coerceToUnit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitContainerExpression(expression: IrContainerExpression): IrExpression =
|
||||
expression.transformPostfix {
|
||||
if (statements.isEmpty()) return this
|
||||
expression.transformPostfix {
|
||||
if (statements.isEmpty()) return this
|
||||
|
||||
val lastIndex = statements.lastIndex
|
||||
statements.forEachIndexed { i, irStatement ->
|
||||
if (irStatement is IrExpression) {
|
||||
statements[i] =
|
||||
if (i == lastIndex)
|
||||
irStatement.cast(type)
|
||||
else
|
||||
irStatement.coerceToUnit()
|
||||
}
|
||||
val lastIndex = statements.lastIndex
|
||||
statements.forEachIndexed { i, irStatement ->
|
||||
if (irStatement is IrExpression) {
|
||||
statements[i] =
|
||||
if (i == lastIndex)
|
||||
irStatement.cast(type)
|
||||
else
|
||||
irStatement.coerceToUnit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitReturn(expression: IrReturn): IrExpression =
|
||||
expression.transformPostfix {
|
||||
value = value.cast(expression.returnTarget.returnType)
|
||||
}
|
||||
expression.transformPostfix {
|
||||
value = value.cast(expression.returnTarget.returnType)
|
||||
}
|
||||
|
||||
override fun visitSetVariable(expression: IrSetVariable): IrExpression =
|
||||
expression.transformPostfix {
|
||||
value = value.cast(expression.descriptor.type)
|
||||
}
|
||||
expression.transformPostfix {
|
||||
value = value.cast(expression.descriptor.type)
|
||||
}
|
||||
|
||||
override fun visitSetField(expression: IrSetField): IrExpression =
|
||||
expression.transformPostfix {
|
||||
value = value.cast(expression.descriptor.type)
|
||||
}
|
||||
expression.transformPostfix {
|
||||
value = value.cast(expression.descriptor.type)
|
||||
}
|
||||
|
||||
override fun visitVariable(declaration: IrVariable): IrVariable =
|
||||
declaration.transformPostfix {
|
||||
initializer = initializer?.cast(declaration.descriptor.type)
|
||||
}
|
||||
declaration.transformPostfix {
|
||||
initializer = initializer?.cast(declaration.descriptor.type)
|
||||
}
|
||||
|
||||
override fun visitField(declaration: IrField): IrStatement =
|
||||
declaration.transformPostfix {
|
||||
initializer?.coerceInnerExpression(descriptor.type)
|
||||
}
|
||||
declaration.transformPostfix {
|
||||
initializer?.coerceInnerExpression(descriptor.type)
|
||||
}
|
||||
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement =
|
||||
declaration.transformPostfix {
|
||||
valueParameters.forEach {
|
||||
it.defaultValue?.coerceInnerExpression(it.descriptor.type)
|
||||
}
|
||||
declaration.transformPostfix {
|
||||
valueParameters.forEach {
|
||||
it.defaultValue?.coerceInnerExpression(it.descriptor.type)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitWhen(expression: IrWhen): IrExpression =
|
||||
expression.transformPostfix {
|
||||
for (irBranch in branches) {
|
||||
irBranch.condition = irBranch.condition.cast(builtIns.booleanType)
|
||||
irBranch.result = irBranch.result.cast(type)
|
||||
}
|
||||
expression.transformPostfix {
|
||||
for (irBranch in branches) {
|
||||
irBranch.condition = irBranch.condition.cast(builtIns.booleanType)
|
||||
irBranch.result = irBranch.result.cast(type)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitLoop(loop: IrLoop): IrExpression =
|
||||
loop.transformPostfix {
|
||||
condition = condition.cast(builtIns.booleanType)
|
||||
body = body?.coerceToUnit()
|
||||
}
|
||||
loop.transformPostfix {
|
||||
condition = condition.cast(builtIns.booleanType)
|
||||
body = body?.coerceToUnit()
|
||||
}
|
||||
|
||||
override fun visitThrow(expression: IrThrow): IrExpression =
|
||||
expression.transformPostfix {
|
||||
value = value.cast(builtIns.throwable.defaultType)
|
||||
}
|
||||
expression.transformPostfix {
|
||||
value = value.cast(builtIns.throwable.defaultType)
|
||||
}
|
||||
|
||||
override fun visitTry(aTry: IrTry): IrExpression =
|
||||
aTry.transformPostfix {
|
||||
tryResult = tryResult.cast(type)
|
||||
aTry.transformPostfix {
|
||||
tryResult = tryResult.cast(type)
|
||||
|
||||
for (aCatch in catches) {
|
||||
aCatch.result = aCatch.result.cast(type)
|
||||
}
|
||||
|
||||
finallyExpression = finallyExpression?.coerceToUnit()
|
||||
for (aCatch in catches) {
|
||||
aCatch.result = aCatch.result.cast(type)
|
||||
}
|
||||
|
||||
finallyExpression = finallyExpression?.coerceToUnit()
|
||||
}
|
||||
|
||||
override fun visitVararg(expression: IrVararg): IrExpression =
|
||||
expression.transformPostfix {
|
||||
elements.forEachIndexed { i, element ->
|
||||
when (element) {
|
||||
is IrSpreadElement ->
|
||||
element.expression = element.expression.cast(expression.type)
|
||||
is IrExpression ->
|
||||
putElement(i, element.cast(varargElementType))
|
||||
}
|
||||
expression.transformPostfix {
|
||||
elements.forEachIndexed { i, element ->
|
||||
when (element) {
|
||||
is IrSpreadElement ->
|
||||
element.expression = element.expression.cast(expression.type)
|
||||
is IrExpression ->
|
||||
putElement(i, element.cast(varargElementType))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrExpressionBody.coerceInnerExpression(expectedType: KotlinType) {
|
||||
expression = expression.cast(expectedType)
|
||||
@@ -178,18 +175,22 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoi
|
||||
valueType.isNullabilityFlexible() && valueType.containsNull() && !expectedType.containsNull() -> {
|
||||
val nonNullValueType = valueType.upperIfFlexible().makeNotNullable()
|
||||
IrTypeOperatorCallImpl(
|
||||
startOffset, endOffset, nonNullValueType,
|
||||
IrTypeOperator.IMPLICIT_NOTNULL, nonNullValueType, this
|
||||
startOffset, endOffset, nonNullValueType,
|
||||
IrTypeOperator.IMPLICIT_NOTNULL, nonNullValueType, this
|
||||
).cast(expectedType)
|
||||
}
|
||||
KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType.makeNotNullable(), expectedType) ->
|
||||
this
|
||||
KotlinBuiltIns.isInt(valueType) && notNullableExpectedType.isBuiltInIntegerType() ->
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, notNullableExpectedType,
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION, notNullableExpectedType, this)
|
||||
IrTypeOperatorCallImpl(
|
||||
startOffset, endOffset, notNullableExpectedType,
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION, notNullableExpectedType, this
|
||||
)
|
||||
else ->
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, expectedType,
|
||||
IrTypeOperator.IMPLICIT_CAST, expectedType, this)
|
||||
IrTypeOperatorCallImpl(
|
||||
startOffset, endOffset, expectedType,
|
||||
IrTypeOperator.IMPLICIT_CAST, expectedType, this
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,14 +200,16 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoi
|
||||
return if (KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, builtIns.unitType))
|
||||
this
|
||||
else
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, builtIns.unitType,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, this)
|
||||
IrTypeOperatorCallImpl(
|
||||
startOffset, endOffset, builtIns.unitType,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, this
|
||||
)
|
||||
}
|
||||
|
||||
private fun KotlinType.isBuiltInIntegerType(): Boolean =
|
||||
KotlinBuiltIns.isByte(this) ||
|
||||
KotlinBuiltIns.isShort(this) ||
|
||||
KotlinBuiltIns.isInt(this) ||
|
||||
KotlinBuiltIns.isLong(this)
|
||||
KotlinBuiltIns.isByte(this) ||
|
||||
KotlinBuiltIns.isShort(this) ||
|
||||
KotlinBuiltIns.isInt(this) ||
|
||||
KotlinBuiltIns.isLong(this)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user