mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-26 15:51:48 +00:00
Compare commits
47 Commits
rr/stdlib/
...
pdn_ir_typ
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec29449135 | ||
|
|
6206d22660 | ||
|
|
12ef9be37a | ||
|
|
91f470755c | ||
|
|
6224608a0e | ||
|
|
f382b45e3e | ||
|
|
5572d7a37f | ||
|
|
ce95ba311d | ||
|
|
26ad8285c0 | ||
|
|
0070e90819 | ||
|
|
2e7f9de1bf | ||
|
|
0f7622e351 | ||
|
|
1ab7461e59 | ||
|
|
190f37a6ab | ||
|
|
cac670aaf0 | ||
|
|
945814f279 | ||
|
|
cc4724120f | ||
|
|
bc322e8193 | ||
|
|
ebb03237a3 | ||
|
|
807fb678ef | ||
|
|
24616aed48 | ||
|
|
f7bf83bc18 | ||
|
|
201c24d717 | ||
|
|
cc23ec7de1 | ||
|
|
8130d724ee | ||
|
|
ba5a1d3e8f | ||
|
|
aab917983c | ||
|
|
4f69d9f2c9 | ||
|
|
2e092903d5 | ||
|
|
8d82fe8aca | ||
|
|
fbb128c74c | ||
|
|
565c10af38 | ||
|
|
d0e7e57c60 | ||
|
|
20fe554d03 | ||
|
|
acf03fb2b1 | ||
|
|
a9697fa455 | ||
|
|
8595949b18 | ||
|
|
42c891db27 | ||
|
|
f8d13e92ee | ||
|
|
fc66083006 | ||
|
|
ada22d3ff1 | ||
|
|
4931ce4df8 | ||
|
|
aa995a4aa0 | ||
|
|
ab353a226e | ||
|
|
d7c8516275 | ||
|
|
d4f57703b1 | ||
|
|
38369bbeb2 |
@@ -18,7 +18,6 @@ dependencies {
|
||||
sourceSets {
|
||||
"main" {
|
||||
projectDefault()
|
||||
java.srcDir("../ir/backend.common/src")
|
||||
}
|
||||
"test" {}
|
||||
}
|
||||
|
||||
20
compiler/ir/backend.common/build.gradle.kts
Normal file
20
compiler/ir/backend.common/build.gradle.kts
Normal file
@@ -0,0 +1,20 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
jvmTarget = "1.6"
|
||||
|
||||
dependencies {
|
||||
compile(project(":compiler:util"))
|
||||
compile(project(":compiler:frontend"))
|
||||
compile(project(":compiler:backend-common"))
|
||||
compile(project(":compiler:ir.tree"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,11 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
|
||||
typealias ReportError = (element: IrElement, message: String) -> Unit
|
||||
|
||||
@@ -43,8 +44,9 @@ class CheckIrElementVisitor(val builtIns: KotlinBuiltIns, val reportError: Repor
|
||||
}
|
||||
|
||||
private fun IrExpression.ensureTypeIs(expectedType: KotlinType) {
|
||||
if (expectedType != type) {
|
||||
reportError(this, "unexpected expression.type: expected $expectedType, got ${type}")
|
||||
// TODO: compare IR types instead.
|
||||
if (expectedType != type.toKotlinType()) {
|
||||
reportError(this, "unexpected expression.type: expected $expectedType, got ${type.toKotlinType()}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,9 +156,9 @@ class CheckIrElementVisitor(val builtIns: KotlinBuiltIns, val reportError: Repor
|
||||
IrTypeOperator.IMPLICIT_CAST,
|
||||
IrTypeOperator.IMPLICIT_NOTNULL,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> typeOperand
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> typeOperand.toKotlinType()
|
||||
|
||||
IrTypeOperator.SAFE_CAST -> typeOperand.makeNullable()
|
||||
IrTypeOperator.SAFE_CAST -> typeOperand.makeNullable().toKotlinType()
|
||||
|
||||
IrTypeOperator.INSTANCEOF, IrTypeOperator.NOT_INSTANCEOF -> builtIns.booleanType
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopySymbolsRemapper
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopySymbolRemapper
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopyTypeRemapper
|
||||
import org.jetbrains.kotlin.ir.util.DescriptorsRemapper
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
|
||||
@@ -38,11 +39,13 @@ fun <T : IrElement> T.deepCopyWithVariables(): T {
|
||||
)
|
||||
}
|
||||
|
||||
val symbolsRemapper = DeepCopySymbolsRemapper(descriptorsRemapper)
|
||||
val symbolsRemapper = DeepCopySymbolRemapper(descriptorsRemapper)
|
||||
acceptVoid(symbolsRemapper)
|
||||
|
||||
val typesRemapper = DeepCopyTypeRemapper(symbolsRemapper)
|
||||
|
||||
return this.transform(
|
||||
object : DeepCopyIrTreeWithReturnableBlockSymbols(symbolsRemapper) {
|
||||
object : DeepCopyIrTreeWithReturnableBlockSymbols(symbolsRemapper, typesRemapper) {
|
||||
override fun getNonTransformedLoop(irLoop: IrLoop): IrLoop {
|
||||
return irLoop
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.renderer.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -285,7 +286,7 @@ class DumpIrTreeWithDescriptorsVisitor(out: Appendable): IrElementVisitor<Unit,
|
||||
for (typeParameter in expression.descriptor.original.typeParameters) {
|
||||
val typeArgument = expression.getTypeArgument(typeParameter) ?: continue
|
||||
val renderedParameter = DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES.render(typeParameter)
|
||||
val renderedType = DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES.renderType(typeArgument)
|
||||
val renderedType = typeArgument.render()
|
||||
printer.println("$renderedParameter: $renderedType")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,12 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrReturnableBlockImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.SymbolRemapper
|
||||
import org.jetbrains.kotlin.ir.util.TypeRemapper
|
||||
|
||||
open class DeepCopyIrTreeWithReturnableBlockSymbols(
|
||||
private val symbolRemapper: SymbolRemapper
|
||||
) : DeepCopyIrTreeWithSymbols(symbolRemapper) {
|
||||
symbolRemapper: SymbolRemapper,
|
||||
typeRemapper: TypeRemapper
|
||||
) : DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper) {
|
||||
|
||||
private inline fun <reified T : IrElement> T.transform() =
|
||||
transform(this@DeepCopyIrTreeWithReturnableBlockSymbols, null) as T
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
@@ -26,14 +25,12 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import java.io.StringWriter
|
||||
|
||||
|
||||
@@ -77,75 +74,62 @@ fun FunctionDescriptor.createOverriddenDescriptor(owner: ClassDescriptor, final:
|
||||
}
|
||||
}
|
||||
|
||||
fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(
|
||||
superConstructorDescriptor: ClassConstructorDescriptor,
|
||||
isPrimary: Boolean = false
|
||||
)
|
||||
: ClassConstructorDescriptor {
|
||||
val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
||||
/* containingDeclaration = */ this,
|
||||
/* annotations = */ Annotations.EMPTY,
|
||||
/* isPrimary = */ isPrimary,
|
||||
/* source = */ SourceElement.NO_SOURCE
|
||||
)
|
||||
val valueParameters = superConstructorDescriptor.valueParameters.map {
|
||||
it.copy(constructorDescriptor, it.name, it.index)
|
||||
}
|
||||
constructorDescriptor.initialize(valueParameters, superConstructorDescriptor.visibility)
|
||||
constructorDescriptor.returnType = superConstructorDescriptor.returnType
|
||||
return constructorDescriptor
|
||||
}
|
||||
|
||||
fun IrClass.addSimpleDelegatingConstructor(
|
||||
superConstructorSymbol: IrConstructorSymbol,
|
||||
constructorDescriptor: ClassConstructorDescriptor,
|
||||
origin: IrDeclarationOrigin
|
||||
)
|
||||
: IrConstructor {
|
||||
superConstructor: IrConstructor,
|
||||
irBuiltIns: IrBuiltIns,
|
||||
origin: IrDeclarationOrigin,
|
||||
isPrimary: Boolean = false
|
||||
): IrConstructor {
|
||||
val superConstructorDescriptor = superConstructor.descriptor
|
||||
val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
||||
/* containingDeclaration = */ this.descriptor,
|
||||
/* annotations = */ Annotations.EMPTY,
|
||||
/* isPrimary = */ isPrimary,
|
||||
/* source = */ SourceElement.NO_SOURCE
|
||||
)
|
||||
val valueParameters = superConstructor.valueParameters.map {
|
||||
val descriptor = it.descriptor as ValueParameterDescriptor
|
||||
val newDescriptor = descriptor.copy(constructorDescriptor, descriptor.name, descriptor.index)
|
||||
IrValueParameterImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
newDescriptor,
|
||||
it.type,
|
||||
it.varargElementType
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
constructorDescriptor.initialize(
|
||||
valueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||
superConstructorDescriptor.visibility
|
||||
)
|
||||
constructorDescriptor.returnType = superConstructorDescriptor.returnType
|
||||
|
||||
return IrConstructorImpl(startOffset, endOffset, origin, constructorDescriptor).also { constructor ->
|
||||
constructor.createParameterDeclarations()
|
||||
|
||||
assert(superConstructor.dispatchReceiverParameter == null) // Inner classes aren't supported.
|
||||
|
||||
constructor.valueParameters += valueParameters
|
||||
constructor.returnType = this.defaultType
|
||||
|
||||
constructor.body = IrBlockBodyImpl(
|
||||
startOffset, endOffset,
|
||||
listOf(
|
||||
IrDelegatingConstructorCallImpl(
|
||||
startOffset, endOffset,
|
||||
superConstructorSymbol, superConstructorSymbol.descriptor
|
||||
).apply {
|
||||
constructor.valueParameters.forEachIndexed { idx, parameter ->
|
||||
putValueArgument(idx, IrGetValueImpl(startOffset, endOffset, parameter.symbol))
|
||||
}
|
||||
},
|
||||
IrInstanceInitializerCallImpl(startOffset, endOffset, this.symbol)
|
||||
)
|
||||
startOffset, endOffset,
|
||||
listOf(
|
||||
IrDelegatingConstructorCallImpl(
|
||||
startOffset, endOffset, irBuiltIns.unitType,
|
||||
superConstructor.symbol, superConstructor.descriptor
|
||||
).apply {
|
||||
constructor.valueParameters.forEachIndexed { idx, parameter ->
|
||||
putValueArgument(idx, IrGetValueImpl(startOffset, endOffset, parameter.type, parameter.symbol))
|
||||
}
|
||||
},
|
||||
IrInstanceInitializerCallImpl(startOffset, endOffset, this.symbol, irBuiltIns.unitType)
|
||||
)
|
||||
)
|
||||
|
||||
constructor.parent = this
|
||||
this.declarations.add(constructor)
|
||||
}
|
||||
}
|
||||
|
||||
fun CommonBackendContext.createArrayOfExpression(
|
||||
arrayElementType: KotlinType,
|
||||
arrayElements: List<IrExpression>,
|
||||
startOffset: Int, endOffset: Int
|
||||
): IrExpression {
|
||||
|
||||
val genericArrayOfFunSymbol = ir.symbols.arrayOf
|
||||
val genericArrayOfFun = genericArrayOfFunSymbol.descriptor
|
||||
val typeParameter0 = genericArrayOfFun.typeParameters[0]
|
||||
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameter0.typeConstructor to TypeProjectionImpl(arrayElementType)))
|
||||
val substitutedArrayOfFun = genericArrayOfFun.substitute(typeSubstitutor)!!
|
||||
|
||||
val typeArguments = mapOf(typeParameter0 to arrayElementType)
|
||||
|
||||
val valueParameter0 = substitutedArrayOfFun.valueParameters[0]
|
||||
val arg0VarargType = valueParameter0.type
|
||||
val arg0VarargElementType = valueParameter0.varargElementType!!
|
||||
val arg0 = IrVarargImpl(startOffset, endOffset, arg0VarargType, arg0VarargElementType, arrayElements)
|
||||
|
||||
return IrCallImpl(startOffset, endOffset, genericArrayOfFunSymbol, substitutedArrayOfFun, typeArguments).apply {
|
||||
putValueArgument(0, arg0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
@@ -33,8 +32,8 @@ import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
@@ -42,18 +41,13 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.calls.components.isVararg
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
|
||||
open class DefaultArgumentStubGenerator constructor(val context: CommonBackendContext, private val skipInlineMethods: Boolean = true) :
|
||||
DeclarationContainerLoweringPass {
|
||||
@@ -82,34 +76,31 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
||||
log { "detected ${functionDescriptor.name.asString()} has got #${bodies.size} default expressions" }
|
||||
functionDescriptor.overriddenDescriptors.forEach { context.log { "DEFAULT-REPLACER: $it" } }
|
||||
if (bodies.isNotEmpty()) {
|
||||
val newIrFunction = functionDescriptor.generateDefaultsFunction(context)
|
||||
val newIrFunction = irFunction.generateDefaultsFunction(context)
|
||||
newIrFunction.parent = irFunction.parent
|
||||
val descriptor = newIrFunction.descriptor
|
||||
log { "$functionDescriptor -> $descriptor" }
|
||||
val builder = context.createIrBuilder(newIrFunction.symbol)
|
||||
newIrFunction.body = builder.irBlockBody(newIrFunction) {
|
||||
val params = mutableListOf<IrVariableSymbol>()
|
||||
val variables = mutableMapOf<ValueDescriptor, IrValueSymbol>()
|
||||
val params = mutableListOf<IrVariable>()
|
||||
val variables = mutableMapOf<ValueDescriptor, IrValueDeclaration>()
|
||||
|
||||
irFunction.dispatchReceiverParameter?.let {
|
||||
variables[it.descriptor] = newIrFunction.dispatchReceiverParameter!!.symbol
|
||||
variables[it.descriptor] = newIrFunction.dispatchReceiverParameter!!
|
||||
}
|
||||
|
||||
if (descriptor.extensionReceiverParameter != null) {
|
||||
variables[functionDescriptor.extensionReceiverParameter!!] =
|
||||
newIrFunction.extensionReceiverParameter!!.symbol
|
||||
newIrFunction.extensionReceiverParameter!!
|
||||
}
|
||||
|
||||
for (valueParameter in functionDescriptor.valueParameters) {
|
||||
val parameterSymbol = newIrFunction.valueParameters[valueParameter.index].symbol
|
||||
val temporaryVariableSymbol =
|
||||
IrVariableSymbolImpl(scope.createTemporaryVariableDescriptor(parameterSymbol.descriptor))
|
||||
params.add(temporaryVariableSymbol)
|
||||
variables.put(valueParameter, temporaryVariableSymbol)
|
||||
if (valueParameter.hasDefaultValue()) {
|
||||
val kIntAnd = symbols.intAnd
|
||||
val parameter = newIrFunction.valueParameters[valueParameter.index]
|
||||
|
||||
val argument = if (valueParameter.hasDefaultValue()) {
|
||||
val kIntAnd = symbols.intAnd.owner
|
||||
val condition = irNotEquals(irCall(kIntAnd).apply {
|
||||
dispatchReceiver = irGet(maskParameterSymbol(newIrFunction, valueParameter.index / 32))
|
||||
dispatchReceiver = irGet(maskParameter(newIrFunction, valueParameter.index / 32))
|
||||
putValueArgument(0, irInt(1 shl (valueParameter.index % 32)))
|
||||
}, irInt(0))
|
||||
val expressionBody = getDefaultParameterExpressionBody(irFunction, valueParameter)
|
||||
@@ -122,41 +113,40 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
||||
return irGet(valueSymbol)
|
||||
}
|
||||
})
|
||||
val variableInitialization = irIfThenElse(
|
||||
type = temporaryVariableSymbol.descriptor.type,
|
||||
irIfThenElse(
|
||||
type = parameter.type,
|
||||
condition = condition,
|
||||
thenPart = expressionBody.expression,
|
||||
elsePart = irGet(parameterSymbol)
|
||||
)
|
||||
+scope.createTemporaryVariable(
|
||||
symbol = temporaryVariableSymbol,
|
||||
initializer = variableInitialization
|
||||
elsePart = irGet(parameter)
|
||||
)
|
||||
|
||||
/* Mapping calculated values with its origin variables. */
|
||||
} else {
|
||||
+scope.createTemporaryVariable(
|
||||
symbol = temporaryVariableSymbol,
|
||||
initializer = irGet(parameterSymbol)
|
||||
)
|
||||
irGet(parameter)
|
||||
}
|
||||
val temporaryVariable = irTemporary(argument, nameHint = parameter.name.asString())
|
||||
|
||||
params.add(temporaryVariable)
|
||||
variables.put(valueParameter, temporaryVariable)
|
||||
}
|
||||
if (irFunction is IrConstructor) {
|
||||
+IrDelegatingConstructorCallImpl(
|
||||
startOffset = irFunction.startOffset,
|
||||
endOffset = irFunction.endOffset,
|
||||
type = context.irBuiltIns.unitType,
|
||||
symbol = irFunction.symbol, descriptor = irFunction.symbol.descriptor
|
||||
).apply {
|
||||
params.forEachIndexed { i, variable ->
|
||||
putValueArgument(i, irGet(variable))
|
||||
}
|
||||
if (functionDescriptor.dispatchReceiverParameter != null) {
|
||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!.symbol)
|
||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
+irReturn(irCall(irFunction.symbol).apply {
|
||||
+irReturn(irCall(irFunction).apply {
|
||||
if (functionDescriptor.dispatchReceiverParameter != null) {
|
||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!.symbol)
|
||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!)
|
||||
}
|
||||
if (functionDescriptor.extensionReceiverParameter != null) {
|
||||
extensionReceiver = irGet(variables[functionDescriptor.extensionReceiverParameter!!]!!)
|
||||
@@ -181,50 +171,29 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
||||
private fun log(msg: () -> String) = context.log { "DEFAULT-REPLACER: ${msg()}" }
|
||||
}
|
||||
|
||||
private fun Scope.createTemporaryVariableDescriptor(parameterDescriptor: ParameterDescriptor?): VariableDescriptor =
|
||||
IrTemporaryVariableDescriptorImpl(
|
||||
containingDeclaration = this.scopeOwner,
|
||||
name = parameterDescriptor!!.name.asString().synthesizedName,
|
||||
outType = parameterDescriptor.type,
|
||||
isMutable = false
|
||||
)
|
||||
|
||||
private fun Scope.createTemporaryVariable(symbol: IrVariableSymbol, initializer: IrExpression) =
|
||||
IrVariableImpl(
|
||||
startOffset = initializer.startOffset,
|
||||
endOffset = initializer.endOffset,
|
||||
origin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
||||
symbol = symbol
|
||||
).apply {
|
||||
|
||||
this.initializer = initializer
|
||||
}
|
||||
|
||||
private fun getDefaultParameterExpressionBody(irFunction: IrFunction, valueParameter: ValueParameterDescriptor): IrExpressionBody {
|
||||
return irFunction.getDefault(valueParameter) ?: TODO("FIXME!!!")
|
||||
}
|
||||
|
||||
private fun maskParameterDescriptor(function: IrFunction, number: Int) =
|
||||
maskParameterSymbol(function, number).descriptor as ValueParameterDescriptor
|
||||
maskParameter(function, number).descriptor as ValueParameterDescriptor
|
||||
|
||||
private fun maskParameterSymbol(function: IrFunction, number: Int) =
|
||||
function.valueParameters.single { it.descriptor.name == parameterMaskName(number) }.symbol
|
||||
private fun maskParameter(function: IrFunction, number: Int) =
|
||||
function.valueParameters.single { it.descriptor.name == parameterMaskName(number) }
|
||||
|
||||
private fun markerParameterDescriptor(descriptor: FunctionDescriptor) =
|
||||
descriptor.valueParameters.single { it.name == kConstructorMarkerName }
|
||||
|
||||
private fun nullConst(expression: IrElement, type: KotlinType): IrExpression? {
|
||||
when {
|
||||
KotlinBuiltIns.isFloat(type) -> return IrConstImpl.float(expression.startOffset, expression.endOffset, type, 0.0F)
|
||||
KotlinBuiltIns.isDouble(type) -> return IrConstImpl.double(expression.startOffset, expression.endOffset, type, 0.0)
|
||||
KotlinBuiltIns.isBoolean(type) -> return IrConstImpl.boolean(expression.startOffset, expression.endOffset, type, false)
|
||||
KotlinBuiltIns.isByte(type) -> return IrConstImpl.byte(expression.startOffset, expression.endOffset, type, 0)
|
||||
KotlinBuiltIns.isChar(type) -> return IrConstImpl.char(expression.startOffset, expression.endOffset, type, 0.toChar())
|
||||
KotlinBuiltIns.isShort(type) -> return IrConstImpl.short(expression.startOffset, expression.endOffset, type, 0)
|
||||
KotlinBuiltIns.isInt(type) -> return IrConstImpl.int(expression.startOffset, expression.endOffset, type, 0)
|
||||
KotlinBuiltIns.isLong(type) -> return IrConstImpl.long(expression.startOffset, expression.endOffset, type, 0)
|
||||
else -> return IrConstImpl.constNull(expression.startOffset, expression.endOffset, type.builtIns.nullableNothingType)
|
||||
}
|
||||
private fun nullConst(expression: IrElement, type: IrType, context: CommonBackendContext) = when {
|
||||
type.isFloat() -> IrConstImpl.float(expression.startOffset, expression.endOffset, type, 0.0F)
|
||||
type.isDouble() -> IrConstImpl.double(expression.startOffset, expression.endOffset, type, 0.0)
|
||||
type.isBoolean() -> IrConstImpl.boolean(expression.startOffset, expression.endOffset, type, false)
|
||||
type.isByte() -> IrConstImpl.byte(expression.startOffset, expression.endOffset, type, 0)
|
||||
type.isChar() -> IrConstImpl.char(expression.startOffset, expression.endOffset, type, 0.toChar())
|
||||
type.isShort() -> IrConstImpl.short(expression.startOffset, expression.endOffset, type, 0)
|
||||
type.isInt() -> IrConstImpl.int(expression.startOffset, expression.endOffset, type, 0)
|
||||
type.isLong() -> IrConstImpl.long(expression.startOffset, expression.endOffset, type, 0)
|
||||
else -> IrConstImpl.constNull(expression.startOffset, expression.endOffset, context.irBuiltIns.nothingNType)
|
||||
}
|
||||
|
||||
class DefaultParameterInjector constructor(val context: CommonBackendContext, private val skipInline: Boolean = true) : BodyLoweringPass {
|
||||
@@ -240,10 +209,12 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
if (argumentsCount == descriptor.valueParameters.size)
|
||||
return expression
|
||||
val (symbolForCall, params) = parametersForCall(expression)
|
||||
symbolForCall as IrConstructorSymbol
|
||||
return IrDelegatingConstructorCallImpl(
|
||||
startOffset = expression.startOffset,
|
||||
endOffset = expression.endOffset,
|
||||
symbol = symbolForCall as IrConstructorSymbol,
|
||||
type = context.irBuiltIns.unitType,
|
||||
symbol = symbolForCall,
|
||||
descriptor = symbolForCall.descriptor
|
||||
)
|
||||
.apply {
|
||||
@@ -273,13 +244,14 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
return IrCallImpl(
|
||||
startOffset = expression.startOffset,
|
||||
endOffset = expression.endOffset,
|
||||
type = symbol.owner.returnType,
|
||||
symbol = symbol,
|
||||
descriptor = descriptor,
|
||||
typeArguments = expression.descriptor.typeParameters.map {
|
||||
it to (expression.getTypeArgument(it) ?: it.defaultType)
|
||||
}.toMap()
|
||||
typeArgumentsCount = expression.typeArgumentsCount
|
||||
)
|
||||
.apply {
|
||||
this.copyTypeArgumentsFrom(expression)
|
||||
|
||||
params.forEach {
|
||||
log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}" }
|
||||
putValueArgument(it.first.index, it.second)
|
||||
@@ -310,8 +282,7 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
private fun parametersForCall(expression: IrFunctionAccessExpression): Pair<IrFunctionSymbol, List<Pair<ValueParameterDescriptor, IrExpression?>>> {
|
||||
val descriptor = expression.descriptor
|
||||
val keyFunction = expression.symbol.owner.findSuperMethodWithDefaultArguments()!!
|
||||
val keyDescriptor = keyFunction.descriptor
|
||||
val realFunction = keyDescriptor.generateDefaultsFunction(context)
|
||||
val realFunction = keyFunction.generateDefaultsFunction(context)
|
||||
realFunction.parent = keyFunction.parent
|
||||
val realDescriptor = realFunction.descriptor
|
||||
|
||||
@@ -325,15 +296,18 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
maskValues[maskIndex] = maskValues[maskIndex] or (1 shl (i % 32))
|
||||
}
|
||||
val valueParameterDescriptor = realDescriptor.valueParameters[i]
|
||||
val defaultValueArgument =
|
||||
if (valueParameterDescriptor.isVararg) null else nullConst(expression, valueParameterDescriptor.type)
|
||||
val defaultValueArgument = if (valueParameterDescriptor.isVararg) {
|
||||
null
|
||||
} else {
|
||||
nullConst(expression, realFunction.valueParameters[i].type, context)
|
||||
}
|
||||
valueParameterDescriptor to (valueArgument ?: defaultValueArgument)
|
||||
})
|
||||
maskValues.forEachIndexed { i, maskValue ->
|
||||
params += maskParameterDescriptor(realFunction, i) to IrConstImpl.int(
|
||||
startOffset = irBody.startOffset,
|
||||
endOffset = irBody.endOffset,
|
||||
type = descriptor.builtIns.intType,
|
||||
type = context.irBuiltIns.intType,
|
||||
value = maskValue
|
||||
)
|
||||
}
|
||||
@@ -347,7 +321,7 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
)
|
||||
} else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
|
||||
params += realDescriptor.valueParameters.last() to
|
||||
IrConstImpl.constNull(irBody.startOffset, irBody.endOffset, context.builtIns.any.defaultType)
|
||||
IrConstImpl.constNull(irBody.startOffset, irBody.endOffset, context.irBuiltIns.anyType)
|
||||
}
|
||||
params.forEach {
|
||||
log { "descriptor::${realDescriptor.name.asString()}#${it.first.index}: ${it.first.name.asString()}" }
|
||||
@@ -366,7 +340,7 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
private fun CallableMemberDescriptor.needsDefaultArgumentsLowering(skipInlineMethods: Boolean) =
|
||||
valueParameters.any { it.hasDefaultValue() } && !(this is FunctionDescriptor && isInline && skipInlineMethods)
|
||||
|
||||
private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendContext): IrFunction {
|
||||
private fun IrFunction.generateDefaultsFunction(context: CommonBackendContext): IrFunction = with(this.descriptor) {
|
||||
return context.ir.defaultParameterDeclarationsCache.getOrPut(this) {
|
||||
val descriptor = when (this) {
|
||||
is ClassConstructorDescriptor ->
|
||||
@@ -389,8 +363,10 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
}
|
||||
}
|
||||
|
||||
val function = this@generateDefaultsFunction
|
||||
|
||||
val syntheticParameters = MutableList((valueParameters.size + 31) / 32) { i ->
|
||||
valueParameter(descriptor, valueParameters.size + i, parameterMaskName(i), descriptor.builtIns.intType)
|
||||
valueParameter(descriptor, valueParameters.size + i, parameterMaskName(i), context.irBuiltIns.intType)
|
||||
}
|
||||
if (this is ClassConstructorDescriptor) {
|
||||
syntheticParameters += valueParameter(
|
||||
@@ -402,10 +378,29 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
syntheticParameters += valueParameter(
|
||||
descriptor, syntheticParameters.last().index + 1,
|
||||
"handler".synthesizedName,
|
||||
context.ir.symbols.any.owner.defaultType
|
||||
context.irBuiltIns.anyType
|
||||
)
|
||||
}
|
||||
|
||||
val newValueParameters = function.valueParameters.map {
|
||||
val parameterDescriptor = ValueParameterDescriptorImpl(
|
||||
containingDeclaration = descriptor,
|
||||
original = null, /* ValueParameterDescriptorImpl::copy do not save original. */
|
||||
index = it.index,
|
||||
annotations = it.descriptor.annotations,
|
||||
name = it.name,
|
||||
outType = it.descriptor.type,
|
||||
declaresDefaultValue = false,
|
||||
isCrossinline = it.isCrossinline,
|
||||
isNoinline = it.isNoinline,
|
||||
varargElementType = (it.descriptor as ValueParameterDescriptor).varargElementType,
|
||||
source = it.descriptor.source
|
||||
)
|
||||
|
||||
it.copy(parameterDescriptor)
|
||||
|
||||
} + syntheticParameters
|
||||
|
||||
descriptor.initialize(
|
||||
/* receiverParameterType = */ extensionReceiverParameter?.type,
|
||||
/* dispatchReceiverParameter = */ dispatchReceiverParameter,
|
||||
@@ -425,24 +420,11 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
setInitialized()
|
||||
}
|
||||
},
|
||||
/* unsubstitutedValueParameters = */ valueParameters.map {
|
||||
ValueParameterDescriptorImpl(
|
||||
containingDeclaration = descriptor,
|
||||
original = null, /* ValueParameterDescriptorImpl::copy do not save original. */
|
||||
index = it.index,
|
||||
annotations = it.annotations,
|
||||
name = it.name,
|
||||
outType = it.type,
|
||||
declaresDefaultValue = false,
|
||||
isCrossinline = it.isCrossinline,
|
||||
isNoinline = it.isNoinline,
|
||||
varargElementType = it.varargElementType,
|
||||
source = it.source
|
||||
)
|
||||
} + syntheticParameters,
|
||||
/* unsubstitutedValueParameters = */ newValueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||
/* unsubstitutedReturnType = */ returnType,
|
||||
/* modality = */ Modality.FINAL,
|
||||
/* visibility = */ this.visibility)
|
||||
/* visibility = */ this.visibility
|
||||
)
|
||||
descriptor.isSuspend = this.isSuspend
|
||||
context.log { "adds to cache[$this] = $descriptor" }
|
||||
|
||||
@@ -463,7 +445,29 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
)
|
||||
}
|
||||
|
||||
result.createParameterDeclarations()
|
||||
result.returnType = function.returnType
|
||||
|
||||
function.typeParameters.mapTo(result.typeParameters) {
|
||||
assert(function.descriptor.typeParameters[it.index] == it.descriptor)
|
||||
IrTypeParameterImpl(
|
||||
startOffset, endOffset, origin, descriptor.typeParameters[it.index]
|
||||
).apply { this.superTypes += it.superTypes }
|
||||
}
|
||||
result.parent = function.parent
|
||||
result.createDispatchReceiverParameter()
|
||||
|
||||
function.extensionReceiverParameter?.let {
|
||||
result.extensionReceiverParameter = IrValueParameterImpl(
|
||||
it.startOffset,
|
||||
it.endOffset,
|
||||
it.origin,
|
||||
descriptor.extensionReceiverParameter!!,
|
||||
it.type,
|
||||
it.varargElementType
|
||||
).apply { parent = result }
|
||||
}
|
||||
|
||||
result.valueParameters += newValueParameters.also { it.forEach { it.parent = result } }
|
||||
|
||||
result
|
||||
}
|
||||
@@ -472,20 +476,28 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
object DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER :
|
||||
IrDeclarationOriginImpl("DEFAULT_PARAMETER_EXTENT")
|
||||
|
||||
private fun valueParameter(descriptor: FunctionDescriptor, index: Int, name: Name, type: KotlinType): ValueParameterDescriptor {
|
||||
return ValueParameterDescriptorImpl(
|
||||
private fun IrFunction.valueParameter(descriptor: FunctionDescriptor, index: Int, name: Name, type: IrType): IrValueParameter {
|
||||
val parameterDescriptor = ValueParameterDescriptorImpl(
|
||||
containingDeclaration = descriptor,
|
||||
original = null,
|
||||
index = index,
|
||||
annotations = Annotations.EMPTY,
|
||||
name = name,
|
||||
outType = type,
|
||||
outType = type.toKotlinType(),
|
||||
declaresDefaultValue = false,
|
||||
isCrossinline = false,
|
||||
isNoinline = false,
|
||||
varargElementType = null,
|
||||
source = SourceElement.NO_SOURCE
|
||||
)
|
||||
return IrValueParameterImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
parameterDescriptor,
|
||||
type,
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
internal val kConstructorMarkerName = "marker".synthesizedName
|
||||
|
||||
@@ -68,7 +68,7 @@ class InitializersLowering(
|
||||
if (declaration.descriptor.dispatchReceiverParameter != null) // TODO isStaticField
|
||||
IrGetValueImpl(
|
||||
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
|
||||
irClass.thisReceiver!!.symbol
|
||||
irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol
|
||||
)
|
||||
else null
|
||||
val irSetField = IrSetFieldImpl(
|
||||
@@ -76,6 +76,7 @@ class InitializersLowering(
|
||||
declaration.symbol,
|
||||
receiver,
|
||||
irFieldInitializer,
|
||||
context.irBuiltIns.unitType,
|
||||
null, null
|
||||
)
|
||||
|
||||
@@ -93,7 +94,7 @@ class InitializersLowering(
|
||||
fun transformInstanceInitializerCallsInConstructors(irClass: IrClass) {
|
||||
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression {
|
||||
return IrBlockImpl(irClass.startOffset, irClass.endOffset, context.builtIns.unitType, null,
|
||||
return IrBlockImpl(irClass.startOffset, irClass.endOffset, context.irBuiltIns.unitType, null,
|
||||
instanceInitializerStatements.map { it.copy(irClass) })
|
||||
}
|
||||
})
|
||||
|
||||
@@ -29,9 +29,12 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
||||
object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
InnerClassTransformer(irClass).lowerInnerClass()
|
||||
TODO()
|
||||
// InnerClassTransformer(irClass).lowerInnerClass()
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
private inner class InnerClassTransformer(val irClass: IrClass) {
|
||||
lateinit var outerThisField: IrField
|
||||
|
||||
@@ -189,10 +192,14 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLoweringPass {
|
||||
override fun lower(irBody: IrBody) {
|
||||
TODO()
|
||||
/*
|
||||
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
@@ -240,6 +247,7 @@ class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLowe
|
||||
|
||||
// TODO callable references?
|
||||
})
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,26 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
abstract class SymbolWithIrBuilder<out S: IrSymbol, out D: IrDeclaration> {
|
||||
|
||||
@@ -62,155 +44,3 @@ abstract class SymbolWithIrBuilder<out S: IrSymbol, out D: IrDeclaration> {
|
||||
return builtIr
|
||||
}
|
||||
}
|
||||
|
||||
fun BackendContext.createPropertyGetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
||||
fieldSymbol: IrFieldSymbol, type: KotlinType)
|
||||
= object: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
|
||||
|
||||
override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
|
||||
PropertyGetterDescriptorImpl(
|
||||
/* correspondingProperty = */ fieldSymbol.descriptor,
|
||||
/* annotations = */ Annotations.EMPTY,
|
||||
/* modality = */ Modality.FINAL,
|
||||
/* visibility = */ Visibilities.PRIVATE,
|
||||
/* isDefault = */ false,
|
||||
/* isExternal = */ false,
|
||||
/* isInline = */ false,
|
||||
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
|
||||
/* original = */ null,
|
||||
/* source = */ SourceElement.NO_SOURCE
|
||||
)
|
||||
)
|
||||
|
||||
override fun doInitialize() {
|
||||
val descriptor = symbol.descriptor as PropertyGetterDescriptorImpl
|
||||
descriptor.apply {
|
||||
initialize(type)
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildIr() = IrFunctionImpl(
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
origin = origin,
|
||||
symbol = symbol).apply {
|
||||
|
||||
createParameterDeclarations()
|
||||
|
||||
body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody {
|
||||
+irReturn(irGetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), fieldSymbol))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun BackendContext.createPropertySetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
||||
fieldSymbol: IrFieldSymbol, type: KotlinType)
|
||||
= object: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
|
||||
|
||||
override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
|
||||
PropertySetterDescriptorImpl(
|
||||
/* correspondingProperty = */ fieldSymbol.descriptor,
|
||||
/* annotations = */ Annotations.EMPTY,
|
||||
/* modality = */ Modality.FINAL,
|
||||
/* visibility = */ Visibilities.PRIVATE,
|
||||
/* isDefault = */ false,
|
||||
/* isExternal = */ false,
|
||||
/* isInline = */ false,
|
||||
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
|
||||
/* original = */ null,
|
||||
/* source = */ SourceElement.NO_SOURCE
|
||||
)
|
||||
)
|
||||
|
||||
lateinit var valueParameterDescriptor: ValueParameterDescriptor
|
||||
|
||||
override fun doInitialize() {
|
||||
val descriptor = symbol.descriptor as PropertySetterDescriptorImpl
|
||||
descriptor.apply {
|
||||
valueParameterDescriptor = ValueParameterDescriptorImpl(
|
||||
containingDeclaration = this,
|
||||
original = null,
|
||||
index = 0,
|
||||
annotations = Annotations.EMPTY,
|
||||
name = Name.identifier("value"),
|
||||
outType = type,
|
||||
declaresDefaultValue = false,
|
||||
isCrossinline = false,
|
||||
isNoinline = false,
|
||||
varargElementType = null,
|
||||
source = SourceElement.NO_SOURCE
|
||||
)
|
||||
|
||||
initialize(valueParameterDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildIr() = IrFunctionImpl(
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
origin = origin,
|
||||
symbol = symbol).apply {
|
||||
|
||||
createParameterDeclarations()
|
||||
|
||||
body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody {
|
||||
+irSetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), fieldSymbol, irGet(this@apply.valueParameters.single().symbol))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun BackendContext.createPropertyWithBackingFieldBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
||||
owner: ClassDescriptor, name: Name, type: KotlinType, isMutable: Boolean)
|
||||
= object: SymbolWithIrBuilder<IrFieldSymbol, IrProperty>() {
|
||||
|
||||
private lateinit var getterBuilder: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>
|
||||
private var setterBuilder: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>? = null
|
||||
|
||||
override fun buildSymbol() = IrFieldSymbolImpl(
|
||||
PropertyDescriptorImpl.create(
|
||||
/* containingDeclaration = */ owner,
|
||||
/* annotations = */ Annotations.EMPTY,
|
||||
/* modality = */ Modality.FINAL,
|
||||
/* visibility = */ Visibilities.PRIVATE,
|
||||
/* isVar = */ isMutable,
|
||||
/* name = */ name,
|
||||
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
|
||||
/* source = */ SourceElement.NO_SOURCE,
|
||||
/* lateInit = */ false,
|
||||
/* isConst = */ false,
|
||||
/* isExpect = */ false,
|
||||
/* isActual = */ false,
|
||||
/* isExternal = */ false,
|
||||
/* isDelegated = */ false
|
||||
)
|
||||
)
|
||||
|
||||
override fun doInitialize() {
|
||||
val descriptor = symbol.descriptor as PropertyDescriptorImpl
|
||||
getterBuilder = createPropertyGetterBuilder(startOffset, endOffset, origin, symbol, type).apply { initialize() }
|
||||
if (isMutable)
|
||||
setterBuilder = createPropertySetterBuilder(startOffset, endOffset, origin, symbol, type).apply { initialize() }
|
||||
descriptor.initialize(
|
||||
/* getter = */ getterBuilder.symbol.descriptor as PropertyGetterDescriptorImpl,
|
||||
/* setter = */ setterBuilder?.symbol?.descriptor as? PropertySetterDescriptorImpl)
|
||||
val receiverType: KotlinType? = null
|
||||
descriptor.setType(type, emptyList(), owner.thisAsReceiverParameter, receiverType)
|
||||
}
|
||||
|
||||
override fun buildIr(): IrProperty {
|
||||
val backingField = IrFieldImpl(
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
origin = origin,
|
||||
symbol = symbol)
|
||||
return IrPropertyImpl(
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
origin = origin,
|
||||
isDelegated = false,
|
||||
descriptor = symbol.descriptor,
|
||||
backingField = backingField,
|
||||
getter = getterBuilder.ir,
|
||||
setter = setterBuilder?.ir)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
@@ -58,7 +58,7 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
|
||||
|
||||
return lower.context.createIrBuilder(expression.symbol, expression.startOffset, expression.endOffset).run {
|
||||
|
||||
IrCompositeImpl(startOffset, endOffset, context.builtIns.stringType).apply {
|
||||
IrCompositeImpl(startOffset, endOffset, context.irBuiltIns.stringType).apply {
|
||||
receiver?.let {
|
||||
//put receiver for bound callable reference
|
||||
statements.add(it)
|
||||
@@ -68,7 +68,7 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
|
||||
IrConstImpl.string(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
context.builtIns.stringType,
|
||||
context.irBuiltIns.stringType,
|
||||
callableReference.descriptor.name.asString()
|
||||
)
|
||||
)
|
||||
@@ -104,5 +104,5 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
|
||||
endOffset
|
||||
)
|
||||
|
||||
class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContext(backendContext.irBuiltIns)
|
||||
class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContextBase(backendContext.irBuiltIns)
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import org.jetbrains.kotlin.ir.expressions.IrBlock
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isPrimitiveType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -45,20 +47,20 @@ class LateinitLowering(
|
||||
|
||||
private fun transformGetter(backingField: IrField, getter: IrFunction) {
|
||||
val type = backingField.type
|
||||
assert(!KotlinBuiltIns.isPrimitiveType(type)) { "'lateinit' modifier is not allowed on primitive types" }
|
||||
assert(!type.isPrimitiveType()) { "'lateinit' modifier is not allowed on primitive types" }
|
||||
val startOffset = getter.startOffset
|
||||
val endOffset = getter.endOffset
|
||||
val irBuilder = context.createIrBuilder(getter.symbol, startOffset, endOffset)
|
||||
irBuilder.run {
|
||||
val block = irBlock(type)
|
||||
val resultVar = scope.createTemporaryVariable(
|
||||
irGetField(getter.dispatchReceiverParameter?.let { irGet(it.symbol) }, backingField.symbol)
|
||||
irGetField(getter.dispatchReceiverParameter?.let { irGet(it) }, backingField)
|
||||
)
|
||||
block.statements.add(resultVar)
|
||||
val throwIfNull = irIfThenElse(
|
||||
context.builtIns.nothingType,
|
||||
irNotEquals(irGet(resultVar.symbol), irNull()),
|
||||
irReturn(irGet(resultVar.symbol)),
|
||||
context.irBuiltIns.nothingType,
|
||||
irNotEquals(irGet(resultVar), irNull()),
|
||||
irReturn(irGet(resultVar)),
|
||||
throwUninitializedPropertyAccessException(backingField)
|
||||
)
|
||||
block.statements.add(throwIfNull)
|
||||
@@ -76,15 +78,15 @@ class LateinitLowering(
|
||||
IrConstImpl.string(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
context.builtIns.stringType,
|
||||
context.irBuiltIns.stringType,
|
||||
backingField.name.asString()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private val throwErrorFunction = context.ir.symbols.ThrowUninitializedPropertyAccessException
|
||||
private val throwErrorFunction = context.ir.symbols.ThrowUninitializedPropertyAccessException.owner
|
||||
|
||||
private fun IrBuilderWithScope.irBlock(type: KotlinType): IrBlock = IrBlockImpl(startOffset, endOffset, type)
|
||||
private fun IrBuilderWithScope.irBlock(type: IrType): IrBlock = IrBlockImpl(startOffset, endOffset, type)
|
||||
|
||||
}
|
||||
@@ -29,13 +29,11 @@ import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parents
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
interface LocalNameProvider {
|
||||
@@ -99,12 +97,12 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
abstract val transformedDescriptor: FunctionDescriptor
|
||||
abstract val transformedDeclaration: IrFunction
|
||||
|
||||
val capturedValueToParameter: MutableMap<ValueDescriptor, IrValueParameterSymbol> = HashMap()
|
||||
val capturedValueToParameter: MutableMap<ValueDescriptor, IrValueParameter> = HashMap()
|
||||
|
||||
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
||||
val newSymbol = capturedValueToParameter[descriptor] ?: return null
|
||||
val parameter = capturedValueToParameter[descriptor] ?: return null
|
||||
|
||||
return IrGetValueImpl(startOffset, endOffset, newSymbol)
|
||||
return IrGetValueImpl(startOffset, endOffset, parameter.type, parameter.symbol)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,9 +140,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
||||
val field = capturedValueToField[descriptor] ?: return null
|
||||
|
||||
val receiver = declaration.thisReceiver!!
|
||||
return IrGetFieldImpl(
|
||||
startOffset, endOffset, field.symbol,
|
||||
receiver = IrGetValueImpl(startOffset, endOffset, declaration.thisReceiver!!.symbol)
|
||||
startOffset, endOffset, field.symbol, field.type,
|
||||
receiver = IrGetValueImpl(startOffset, endOffset, receiver.type, receiver.symbol)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -156,9 +155,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
||||
val field = classContext.capturedValueToField[descriptor] ?: return null
|
||||
|
||||
val receiver = member.dispatchReceiverParameter!!
|
||||
return IrGetFieldImpl(
|
||||
startOffset, endOffset, field.symbol,
|
||||
receiver = IrGetValueImpl(startOffset, endOffset, member.dispatchReceiverParameter!!.symbol)
|
||||
startOffset, endOffset, field.symbol, field.type,
|
||||
receiver = IrGetValueImpl(startOffset, endOffset, receiver.type, receiver.symbol)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -169,12 +169,12 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
val localClasses: MutableMap<ClassDescriptor, LocalClassContext> = LinkedHashMap()
|
||||
val localClassConstructors: MutableMap<ClassConstructorDescriptor, LocalClassConstructorContext> = LinkedHashMap()
|
||||
|
||||
val transformedDeclarations = mutableMapOf<DeclarationDescriptor, IrSymbol>()
|
||||
val transformedDeclarations = mutableMapOf<DeclarationDescriptor, IrDeclaration>()
|
||||
|
||||
val FunctionDescriptor.transformed: IrFunctionSymbol?
|
||||
get() = transformedDeclarations[this] as IrFunctionSymbol?
|
||||
val FunctionDescriptor.transformed: IrFunction?
|
||||
get() = transformedDeclarations[this] as IrFunction?
|
||||
|
||||
val oldParameterToNew: MutableMap<ParameterDescriptor, IrValueParameterSymbol> = HashMap()
|
||||
val oldParameterToNew: MutableMap<ParameterDescriptor, IrValueParameter> = HashMap()
|
||||
val newParameterToOld: MutableMap<ParameterDescriptor, ParameterDescriptor> = HashMap()
|
||||
val newParameterToCaptured: MutableMap<ValueParameterDescriptor, IrValueSymbol> = HashMap()
|
||||
|
||||
@@ -201,7 +201,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
|
||||
original.descriptor.valueParameters.filter { it.declaresDefaultValue() }.forEach { argument ->
|
||||
val body = original.getDefault(argument)!!
|
||||
oldParameterToNew[argument]!!.owner.defaultValue = body
|
||||
oldParameterToNew[argument]!!.defaultValue = body
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,7 +219,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
override fun visitClass(declaration: IrClass): IrStatement {
|
||||
if (declaration.descriptor in localClasses) {
|
||||
// Replace local class definition with an empty composite.
|
||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.builtIns.unitType)
|
||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.irBuiltIns.unitType)
|
||||
} else {
|
||||
return super.visitClass(declaration)
|
||||
}
|
||||
@@ -228,7 +228,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||
if (declaration.descriptor in localFunctions) {
|
||||
// Replace local function definition with an empty composite.
|
||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.builtIns.unitType)
|
||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.irBuiltIns.unitType)
|
||||
} else {
|
||||
if (localContext is LocalClassContext && declaration.parent == localContext.declaration) {
|
||||
return declaration.apply {
|
||||
@@ -251,7 +251,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
|
||||
declaration.descriptor.valueParameters.filter { it.declaresDefaultValue() }.forEach { argument ->
|
||||
val body = declaration.getDefault(argument)!!
|
||||
oldParameterToNew[argument]!!.owner.defaultValue = body
|
||||
oldParameterToNew[argument]!!.defaultValue = body
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -267,7 +267,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
}
|
||||
|
||||
oldParameterToNew[descriptor]?.let {
|
||||
return IrGetValueImpl(expression.startOffset, expression.endOffset, it)
|
||||
return IrGetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol)
|
||||
}
|
||||
|
||||
return expression
|
||||
@@ -288,14 +288,17 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val oldCallee = expression.descriptor.original
|
||||
val newCallee = transformedDeclarations[oldCallee] as IrConstructorSymbol? ?: return expression
|
||||
val newCallee = transformedDeclarations[oldCallee] as IrConstructor? ?: return expression
|
||||
|
||||
return IrDelegatingConstructorCallImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
newCallee,
|
||||
newCallee.descriptor,
|
||||
remapTypeArguments(expression, newCallee.descriptor)
|
||||
).fillArguments(expression)
|
||||
context.irBuiltIns.unitType,
|
||||
newCallee.symbol,
|
||||
newCallee.descriptor
|
||||
).also {
|
||||
it.fillArguments(expression)
|
||||
it.copyTypeArgumentsFrom(expression)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T : IrMemberAccessExpression> T.fillArguments(oldExpression: IrMemberAccessExpression): T {
|
||||
@@ -311,16 +314,17 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
newParameterToCaptured[newValueParameterDescriptor]
|
||||
?: throw AssertionError("Non-mapped parameter $newValueParameterDescriptor")
|
||||
|
||||
val capturedValue = capturedValueSymbol.owner
|
||||
|
||||
val capturedValueDescriptor = capturedValueSymbol.descriptor
|
||||
localContext?.irGet(
|
||||
oldExpression.startOffset, oldExpression.endOffset,
|
||||
capturedValueDescriptor
|
||||
) ?:
|
||||
// Captured value is directly available for the caller.
|
||||
IrGetValueImpl(
|
||||
oldExpression.startOffset, oldExpression.endOffset,
|
||||
oldParameterToNew[capturedValueDescriptor] ?: capturedValueSymbol
|
||||
)
|
||||
) ?: run {
|
||||
// Captured value is directly available for the caller.
|
||||
val value = oldParameterToNew[capturedValueDescriptor] ?: capturedValue
|
||||
IrGetValueImpl(oldExpression.startOffset, oldExpression.endOffset, value.type, value.symbol)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -340,11 +344,14 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
val newCallableReference = IrFunctionReferenceImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
expression.type, // TODO functional type for transformed descriptor
|
||||
newCallee,
|
||||
newCallee.symbol,
|
||||
newCallee.descriptor,
|
||||
remapTypeArguments(expression, newCallee.descriptor),
|
||||
expression.typeArgumentsCount,
|
||||
expression.origin
|
||||
).fillArguments(expression)
|
||||
).also {
|
||||
it.fillArguments(expression)
|
||||
it.copyTypeArgumentsFrom(expression)
|
||||
}
|
||||
|
||||
return newCallableReference
|
||||
}
|
||||
@@ -355,7 +362,11 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
val oldReturnTarget = expression.returnTarget
|
||||
val newReturnTarget = oldReturnTarget.transformed ?: return expression
|
||||
|
||||
return IrReturnImpl(expression.startOffset, expression.endOffset, newReturnTarget, expression.value)
|
||||
return IrReturnImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
context.irBuiltIns.nothingType,
|
||||
newReturnTarget.symbol, expression.value
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitDeclarationReference(expression: IrDeclarationReference): IrExpression {
|
||||
@@ -399,8 +410,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
0,
|
||||
IrSetFieldImpl(
|
||||
startOffset, endOffset, field.symbol,
|
||||
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol),
|
||||
capturedValueExpression, STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE
|
||||
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol),
|
||||
capturedValueExpression,
|
||||
context.irBuiltIns.unitType,
|
||||
STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -423,31 +436,19 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
rewriteFunctionBody(memberDeclaration, null)
|
||||
}
|
||||
|
||||
private fun createNewCall(oldCall: IrCall, newCallee: IrFunctionSymbol) =
|
||||
private fun createNewCall(oldCall: IrCall, newCallee: IrFunction) =
|
||||
if (oldCall is IrCallWithShallowCopy)
|
||||
oldCall.shallowCopy(oldCall.origin, newCallee, oldCall.superQualifierSymbol)
|
||||
oldCall.shallowCopy(oldCall.origin, newCallee.symbol, oldCall.superQualifierSymbol)
|
||||
else
|
||||
IrCallImpl(
|
||||
oldCall.startOffset, oldCall.endOffset,
|
||||
newCallee,
|
||||
newCallee.returnType,
|
||||
newCallee.symbol,
|
||||
newCallee.descriptor,
|
||||
remapTypeArguments(oldCall, newCallee.descriptor),
|
||||
oldCall.origin, oldCall.superQualifierSymbol
|
||||
)
|
||||
|
||||
private fun remapTypeArguments(
|
||||
oldExpression: IrMemberAccessExpression,
|
||||
newCallee: CallableDescriptor
|
||||
): Map<TypeParameterDescriptor, KotlinType>? {
|
||||
val oldCallee = oldExpression.descriptor.original
|
||||
|
||||
return if (oldCallee.typeParameters.isEmpty())
|
||||
null
|
||||
else oldCallee.typeParameters.associateBy(
|
||||
{ newCallee.typeParameters[it.index] },
|
||||
{ oldExpression.getTypeArgumentOrDefault(it) }
|
||||
)
|
||||
}
|
||||
).also {
|
||||
it.copyTypeArgumentsFrom(oldCall)
|
||||
}
|
||||
|
||||
private fun transformDescriptors() {
|
||||
localFunctions.values.forEach {
|
||||
@@ -520,7 +521,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
oldDescriptor.extensionReceiverParameter?.type,
|
||||
newDispatchReceiverParameter,
|
||||
newTypeParameters,
|
||||
newValueParameters,
|
||||
newValueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||
oldDescriptor.returnType,
|
||||
Modality.FINAL,
|
||||
Visibilities.PRIVATE
|
||||
@@ -534,9 +535,26 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
IrFunctionImpl(startOffset, endOffset, origin, newDescriptor)
|
||||
}.apply {
|
||||
parent = memberDeclaration.parent
|
||||
createParameterDeclarations()
|
||||
returnType = localFunctionContext.declaration.returnType
|
||||
|
||||
localFunctionContext.declaration.typeParameters.mapTo(this.typeParameters) {
|
||||
IrTypeParameterImpl(it.startOffset, it.endOffset, it.origin, it.descriptor)
|
||||
.apply { superTypes += it.superTypes }
|
||||
}
|
||||
|
||||
localFunctionContext.declaration.extensionReceiverParameter?.let {
|
||||
this.extensionReceiverParameter = IrValueParameterImpl(
|
||||
it.startOffset,
|
||||
it.endOffset,
|
||||
it.origin,
|
||||
descriptor.extensionReceiverParameter!!,
|
||||
it.type,
|
||||
null
|
||||
)
|
||||
}
|
||||
this.valueParameters += newValueParameters
|
||||
recordTransformedValueParameters(localFunctionContext)
|
||||
transformedDeclarations[oldDescriptor] = this.symbol
|
||||
transformedDeclarations[oldDescriptor] = this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,7 +562,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
localContext: LocalContextWithClosureAsParameters,
|
||||
capturedValues: List<IrValueSymbol>
|
||||
)
|
||||
: List<ValueParameterDescriptor> {
|
||||
: List<IrValueParameter> {
|
||||
|
||||
val oldDescriptor = localContext.descriptor
|
||||
val newDescriptor = localContext.transformedDescriptor
|
||||
@@ -552,17 +570,23 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
val closureParametersCount = capturedValues.size
|
||||
val newValueParametersCount = closureParametersCount + oldDescriptor.valueParameters.size
|
||||
|
||||
val newValueParameters = ArrayList<ValueParameterDescriptor>(newValueParametersCount).apply {
|
||||
val newValueParameters = ArrayList<IrValueParameter>(newValueParametersCount).apply {
|
||||
capturedValues.mapIndexedTo(this) { i, capturedValue ->
|
||||
createUnsubstitutedCapturedValueParameter(newDescriptor, capturedValue.descriptor, i).apply {
|
||||
val parameterDescriptor = createUnsubstitutedCapturedValueParameter(newDescriptor, capturedValue.descriptor, i).apply {
|
||||
newParameterToCaptured[this] = capturedValue
|
||||
}
|
||||
capturedValue.owner.copy(parameterDescriptor)
|
||||
}
|
||||
|
||||
oldDescriptor.valueParameters.mapIndexedTo(this) { i, oldValueParameterDescriptor ->
|
||||
createUnsubstitutedParameter(newDescriptor, oldValueParameterDescriptor, closureParametersCount + i).apply {
|
||||
newParameterToOld.putAbsentOrSame(this, oldValueParameterDescriptor)
|
||||
localContext.declaration.valueParameters.mapIndexedTo(this) { i, oldValueParameter ->
|
||||
val parameterDescriptor = createUnsubstitutedParameter(
|
||||
newDescriptor,
|
||||
oldValueParameter.descriptor as ValueParameterDescriptor,
|
||||
closureParametersCount + i
|
||||
).apply {
|
||||
newParameterToOld.putAbsentOrSame(this, oldValueParameter.descriptor)
|
||||
}
|
||||
oldValueParameter.copy(parameterDescriptor)
|
||||
}
|
||||
}
|
||||
return newValueParameters
|
||||
@@ -573,14 +597,14 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
valueParameters.forEach {
|
||||
val capturedValue = newParameterToCaptured[it.descriptor]
|
||||
if (capturedValue != null) {
|
||||
localContext.capturedValueToParameter[capturedValue.descriptor] = it.symbol
|
||||
localContext.capturedValueToParameter[capturedValue.descriptor] = it
|
||||
}
|
||||
}
|
||||
|
||||
(listOfNotNull(dispatchReceiverParameter, extensionReceiverParameter) + valueParameters).forEach {
|
||||
val oldParameter = newParameterToOld[it.descriptor]
|
||||
if (oldParameter != null) {
|
||||
oldParameterToNew.putAbsentOrSame(oldParameter, it.symbol)
|
||||
oldParameterToNew.putAbsentOrSame(oldParameter, it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -604,7 +628,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
val newValueParameters = createTransformedValueParameters(constructorContext, capturedValues)
|
||||
|
||||
newDescriptor.initialize(
|
||||
newValueParameters,
|
||||
newValueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||
Visibilities.PRIVATE,
|
||||
newTypeParameters
|
||||
)
|
||||
@@ -619,12 +643,23 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
}
|
||||
|
||||
constructorContext.transformedDeclaration = with(constructorContext.declaration) {
|
||||
IrConstructorImpl(startOffset, endOffset, origin, newDescriptor)
|
||||
IrConstructorImpl(startOffset, endOffset, origin, newDescriptor).also { it.returnType = returnType }
|
||||
}.apply {
|
||||
parent = constructorContext.declaration.parent
|
||||
createParameterDeclarations()
|
||||
constructorContext.declaration.dispatchReceiverParameter?.let {
|
||||
this.dispatchReceiverParameter = IrValueParameterImpl(
|
||||
it.startOffset,
|
||||
it.endOffset,
|
||||
it.origin,
|
||||
descriptor.dispatchReceiverParameter!!,
|
||||
it.type,
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
this.valueParameters += newValueParameters
|
||||
recordTransformedValueParameters(constructorContext)
|
||||
transformedDeclarations[oldDescriptor] = this.symbol
|
||||
transformedDeclarations[oldDescriptor] = this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -663,7 +698,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
localClassContext.capturedValueToField[capturedValue.descriptor] = IrFieldImpl(
|
||||
localClassContext.declaration.startOffset, localClassContext.declaration.endOffset,
|
||||
DECLARATION_ORIGIN_FIELD_FOR_CAPTURED_VALUE,
|
||||
fieldDescriptor
|
||||
fieldDescriptor, capturedValue.owner.type
|
||||
).apply {
|
||||
parent = localClassContext.declaration
|
||||
}
|
||||
@@ -776,4 +811,13 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrValueDeclaration.copy(newDescriptor: ParameterDescriptor): IrValueParameter = IrValueParameterImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
newDescriptor,
|
||||
type,
|
||||
(this as? IrValueParameter)?.varargElementType
|
||||
)
|
||||
|
||||
@@ -1,372 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.AbstractClosureAnnotator
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.Closure
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
class LocalFunctionsLowering(val context: BackendContext): DeclarationContainerLoweringPass {
|
||||
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
||||
irDeclarationContainer.declarations.transformFlat { memberDeclaration ->
|
||||
if (memberDeclaration is IrFunction)
|
||||
LocalFunctionsTransformer(memberDeclaration).lowerLocalFunctions()
|
||||
else
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private class LocalFunctionContext(val declaration: IrFunction) {
|
||||
lateinit var closure: Closure
|
||||
|
||||
val closureParametersCount: Int get() = closure.capturedValues.size
|
||||
|
||||
lateinit var transformedDescriptor: FunctionDescriptor
|
||||
|
||||
val old2new: MutableMap<ValueDescriptor, ParameterDescriptor> = HashMap()
|
||||
|
||||
var index: Int = -1
|
||||
|
||||
override fun toString(): String =
|
||||
"LocalFunctionContext for ${declaration.descriptor}"
|
||||
}
|
||||
|
||||
private inner class LocalFunctionsTransformer(val memberFunction: IrFunction) {
|
||||
val localFunctions: MutableMap<FunctionDescriptor, LocalFunctionContext> = LinkedHashMap()
|
||||
val new2old: MutableMap<ParameterDescriptor, ValueDescriptor> = HashMap()
|
||||
|
||||
fun lowerLocalFunctions(): List<IrDeclaration>? {
|
||||
collectLocalFunctions()
|
||||
if (localFunctions.isEmpty()) return null
|
||||
|
||||
collectClosures()
|
||||
|
||||
transformDescriptors()
|
||||
|
||||
rewriteBodies()
|
||||
|
||||
return collectRewrittenDeclarations()
|
||||
}
|
||||
|
||||
private fun collectRewrittenDeclarations(): ArrayList<IrDeclaration> =
|
||||
ArrayList<IrDeclaration>(localFunctions.size + 1).apply {
|
||||
add(memberFunction)
|
||||
|
||||
localFunctions.values.mapTo(this) {
|
||||
val original = it.declaration
|
||||
IrFunctionImpl(
|
||||
original.startOffset, original.endOffset, original.origin,
|
||||
it.transformedDescriptor,
|
||||
original.body
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class FunctionBodiesRewriter(val localFunctionContext: LocalFunctionContext?) : IrElementTransformerVoid() {
|
||||
|
||||
override fun visitClass(declaration: IrClass): IrStatement {
|
||||
// ignore local classes for now
|
||||
return declaration
|
||||
}
|
||||
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||
// replace local function definition with an empty composite
|
||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.builtIns.unitType)
|
||||
}
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
val remapped = localFunctionContext?.let { it.old2new[expression.descriptor] }
|
||||
return if (remapped == null)
|
||||
expression
|
||||
else
|
||||
IrGetValueImpl(expression.startOffset, expression.endOffset, remapped, expression.origin)
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val oldCallee = expression.descriptor.original
|
||||
val localFunctionData = localFunctions[oldCallee] ?: return expression
|
||||
|
||||
val newCallee = localFunctionData.transformedDescriptor
|
||||
|
||||
return createNewCall(expression, newCallee).fillArguments(localFunctionData, expression)
|
||||
}
|
||||
|
||||
private fun <T : IrMemberAccessExpression> T.fillArguments(calleeContext: LocalFunctionContext, oldExpression: IrMemberAccessExpression): T {
|
||||
val closureParametersCount = calleeContext.closureParametersCount
|
||||
|
||||
mapValueParametersIndexed { index, newValueParameterDescriptor ->
|
||||
val capturedValueDescriptor = new2old[newValueParameterDescriptor] ?:
|
||||
throw AssertionError("Non-mapped parameter $newValueParameterDescriptor")
|
||||
if (index >= closureParametersCount)
|
||||
oldExpression.getValueArgument(capturedValueDescriptor as ValueParameterDescriptor)
|
||||
else {
|
||||
val remappedValueDescriptor = localFunctionContext?.let { it.old2new[capturedValueDescriptor] }
|
||||
IrGetValueImpl(oldExpression.startOffset, oldExpression.endOffset,
|
||||
remappedValueDescriptor ?: capturedValueDescriptor)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dispatchReceiver = oldExpression.dispatchReceiver
|
||||
extensionReceiver = oldExpression.extensionReceiver
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val oldCallee = expression.descriptor.original
|
||||
val localFunctionData = localFunctions[oldCallee] ?: return expression
|
||||
val newCallee = localFunctionData.transformedDescriptor
|
||||
|
||||
return IrFunctionReferenceImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
expression.type, // TODO functional type for transformed descriptor
|
||||
newCallee,
|
||||
remapTypeArguments(expression, newCallee),
|
||||
expression.origin
|
||||
).fillArguments(localFunctionData, expression)
|
||||
}
|
||||
|
||||
override fun visitReturn(expression: IrReturn): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val oldReturnTarget = expression.returnTarget
|
||||
val localFunctionData = localFunctions[oldReturnTarget] ?: return expression
|
||||
val newReturnTarget = localFunctionData.transformedDescriptor
|
||||
|
||||
return IrReturnImpl(expression.startOffset, expression.endOffset,
|
||||
newReturnTarget,
|
||||
expression.value)
|
||||
}
|
||||
}
|
||||
|
||||
private fun rewriteFunctionDeclaration(irFunction: IrFunction, localFunctionContext: LocalFunctionContext?) {
|
||||
irFunction.transformChildrenVoid(FunctionBodiesRewriter(localFunctionContext))
|
||||
}
|
||||
|
||||
private fun rewriteBodies() {
|
||||
localFunctions.values.forEach {
|
||||
rewriteFunctionDeclaration(it.declaration, it)
|
||||
}
|
||||
|
||||
rewriteFunctionDeclaration(memberFunction, null)
|
||||
}
|
||||
|
||||
private fun createNewCall(oldCall: IrCall, newCallee: FunctionDescriptor) =
|
||||
when (oldCall) {
|
||||
is IrCallWithShallowCopy ->
|
||||
oldCall.shallowCopy(oldCall.origin, newCallee, oldCall.superQualifier)
|
||||
else ->
|
||||
IrCallImpl(
|
||||
oldCall.startOffset, oldCall.endOffset,
|
||||
newCallee,
|
||||
remapTypeArguments(oldCall, newCallee),
|
||||
oldCall.origin, oldCall.superQualifier
|
||||
)
|
||||
}
|
||||
|
||||
private fun remapTypeArguments(oldExpression: IrMemberAccessExpression, newCallee: FunctionDescriptor): Map<TypeParameterDescriptor, KotlinType>? {
|
||||
val oldCallee = oldExpression.descriptor
|
||||
|
||||
return if (oldCallee.typeParameters.isEmpty())
|
||||
null
|
||||
else oldCallee.original.typeParameters.associateBy(
|
||||
{ newCallee.typeParameters[it.index] },
|
||||
{ oldExpression.getTypeArgument(it)!! }
|
||||
)
|
||||
}
|
||||
|
||||
private fun transformDescriptors() {
|
||||
localFunctions.values.forEach {
|
||||
it.transformedDescriptor = createTransformedDescriptor(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun suggestLocalName(descriptor: DeclarationDescriptor): String {
|
||||
val localFunctionContext = localFunctions[descriptor]
|
||||
return if (localFunctionContext != null && localFunctionContext.index >= 0)
|
||||
"lambda-${localFunctionContext.index}"
|
||||
else
|
||||
descriptor.name.asString()
|
||||
}
|
||||
|
||||
private fun generateNameForLiftedFunction(functionDescriptor: FunctionDescriptor): Name =
|
||||
Name.identifier(
|
||||
functionDescriptor.parentsWithSelf
|
||||
.takeWhile { it is FunctionDescriptor }
|
||||
.toList().reversed()
|
||||
.joinToString(separator = "$") { suggestLocalName(it) }
|
||||
)
|
||||
|
||||
private fun createTransformedDescriptor(localFunctionContext: LocalFunctionContext): FunctionDescriptor {
|
||||
val oldDescriptor = localFunctionContext.declaration.descriptor
|
||||
|
||||
val memberOwner = memberFunction.descriptor.containingDeclaration
|
||||
val newDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||
memberOwner,
|
||||
oldDescriptor.annotations,
|
||||
generateNameForLiftedFunction(oldDescriptor),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
oldDescriptor.source
|
||||
)
|
||||
|
||||
val closureParametersCount = localFunctionContext.closureParametersCount
|
||||
val newValueParametersCount = closureParametersCount + oldDescriptor.valueParameters.size
|
||||
|
||||
val newDispatchReceiverParameter =
|
||||
if (memberOwner is ClassDescriptor && oldDescriptor.dispatchReceiverParameter != null)
|
||||
memberOwner.thisAsReceiverParameter
|
||||
else
|
||||
null
|
||||
|
||||
// Do not substitute type parameters for now.
|
||||
val newTypeParameters = oldDescriptor.typeParameters
|
||||
|
||||
val newValueParameters = ArrayList<ValueParameterDescriptor>(newValueParametersCount).apply {
|
||||
localFunctionContext.closure.capturedValues.mapIndexedTo(this) { i, capturedValueDescriptor ->
|
||||
createUnsubstitutedCapturedValueParameter(newDescriptor, capturedValueDescriptor, i).apply {
|
||||
localFunctionContext.recordRemapped(capturedValueDescriptor, this)
|
||||
}
|
||||
}
|
||||
|
||||
oldDescriptor.valueParameters.mapIndexedTo(this) { i, oldValueParameterDescriptor ->
|
||||
createUnsubstitutedParameter(newDescriptor, oldValueParameterDescriptor, closureParametersCount + i).apply {
|
||||
localFunctionContext.recordRemapped(oldValueParameterDescriptor, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newDescriptor.initialize(
|
||||
oldDescriptor.extensionReceiverParameter?.type,
|
||||
newDispatchReceiverParameter,
|
||||
newTypeParameters,
|
||||
newValueParameters,
|
||||
oldDescriptor.returnType,
|
||||
Modality.FINAL,
|
||||
Visibilities.PRIVATE
|
||||
)
|
||||
|
||||
oldDescriptor.extensionReceiverParameter?.let {
|
||||
localFunctionContext.recordRemapped(it, newDescriptor.extensionReceiverParameter!!)
|
||||
}
|
||||
|
||||
return newDescriptor
|
||||
}
|
||||
|
||||
private fun LocalFunctionContext.recordRemapped(oldDescriptor: ValueDescriptor, newDescriptor: ParameterDescriptor): ParameterDescriptor {
|
||||
old2new[oldDescriptor] = newDescriptor
|
||||
new2old[newDescriptor] = oldDescriptor
|
||||
return newDescriptor
|
||||
}
|
||||
|
||||
private fun suggestNameForCapturedValueParameter(valueDescriptor: ValueDescriptor): Name =
|
||||
if (valueDescriptor.name.isSpecial) {
|
||||
val oldNameStr = valueDescriptor.name.asString()
|
||||
Name.identifier("$" + oldNameStr.substring(1, oldNameStr.length - 1))
|
||||
}
|
||||
else
|
||||
valueDescriptor.name
|
||||
|
||||
private fun createUnsubstitutedCapturedValueParameter(
|
||||
newParameterOwner: CallableMemberDescriptor,
|
||||
valueDescriptor: ValueDescriptor,
|
||||
index: Int
|
||||
): ValueParameterDescriptor =
|
||||
ValueParameterDescriptorImpl(
|
||||
newParameterOwner, null, index,
|
||||
valueDescriptor.annotations,
|
||||
suggestNameForCapturedValueParameter(valueDescriptor),
|
||||
valueDescriptor.type,
|
||||
false, false, false, null, valueDescriptor.source
|
||||
)
|
||||
|
||||
private fun createUnsubstitutedParameter(
|
||||
newParameterOwner: CallableMemberDescriptor,
|
||||
valueParameterDescriptor: ValueParameterDescriptor,
|
||||
newIndex: Int
|
||||
): ValueParameterDescriptor =
|
||||
valueParameterDescriptor.copy(newParameterOwner, valueParameterDescriptor.name, newIndex)
|
||||
|
||||
|
||||
private fun collectClosures() {
|
||||
memberFunction.acceptChildrenVoid(object : AbstractClosureAnnotator() {
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
// ignore local classes for now
|
||||
return
|
||||
}
|
||||
|
||||
override fun recordFunctionClosure(functionDescriptor: FunctionDescriptor, closure: Closure) {
|
||||
localFunctions[functionDescriptor]?.closure = closure
|
||||
}
|
||||
|
||||
override fun recordClassClosure(classDescriptor: ClassDescriptor, closure: Closure) {
|
||||
// ignore local classes for now
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun collectLocalFunctions() {
|
||||
memberFunction.acceptChildrenVoid(object : IrElementVisitorVoid {
|
||||
var lambdasCount = 0
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitFunction(declaration: IrFunction) {
|
||||
declaration.acceptChildrenVoid(this)
|
||||
val localFunctionContext = LocalFunctionContext(declaration)
|
||||
localFunctions[declaration.descriptor] = localFunctionContext
|
||||
if (declaration.descriptor.name.isSpecial) {
|
||||
localFunctionContext.index = lambdasCount++
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
// ignore local classes for now
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,8 +28,8 @@ import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
@@ -39,10 +39,9 @@ import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContext(backendContext.irBuiltIns)
|
||||
class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContextBase(backendContext.irBuiltIns)
|
||||
|
||||
class DeclarationIrBuilder(
|
||||
backendContext: BackendContext,
|
||||
@@ -60,7 +59,7 @@ abstract class AbstractVariableRemapper : IrElementTransformerVoid() {
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression =
|
||||
remapVariable(expression.descriptor)?.let {
|
||||
IrGetValueImpl(expression.startOffset, expression.endOffset, it.symbol, expression.origin)
|
||||
IrGetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol, expression.origin)
|
||||
} ?: expression
|
||||
}
|
||||
|
||||
@@ -84,7 +83,7 @@ fun <T : IrBuilder> T.at(element: IrElement) = this.at(element.startOffset, elem
|
||||
*/
|
||||
inline fun IrGeneratorWithScope.irBlock(
|
||||
expression: IrExpression, origin: IrStatementOrigin? = null,
|
||||
resultType: KotlinType? = expression.type,
|
||||
resultType: IrType? = expression.type,
|
||||
body: IrBlockBuilder.() -> Unit
|
||||
) =
|
||||
this.irBlock(expression.startOffset, expression.endOffset, origin, resultType, body)
|
||||
@@ -93,13 +92,15 @@ inline fun IrGeneratorWithScope.irBlockBody(irElement: IrElement, body: IrBlockB
|
||||
this.irBlockBody(irElement.startOffset, irElement.endOffset, body)
|
||||
|
||||
fun IrBuilderWithScope.irIfThen(condition: IrExpression, thenPart: IrExpression) =
|
||||
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, thenPart, null)
|
||||
IrIfThenElseImpl(startOffset, endOffset, context.irBuiltIns.unitType).apply {
|
||||
branches += IrBranchImpl(condition, thenPart)
|
||||
}
|
||||
|
||||
fun IrBuilderWithScope.irNot(arg: IrExpression) =
|
||||
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCL, arg)
|
||||
|
||||
fun IrBuilderWithScope.irThrow(arg: IrExpression) =
|
||||
IrThrowImpl(startOffset, endOffset, context.builtIns.nothingType, arg)
|
||||
IrThrowImpl(startOffset, endOffset, context.irBuiltIns.nothingType, arg)
|
||||
|
||||
fun IrBuilderWithScope.irCatch(catchParameter: IrVariable) =
|
||||
IrCatchImpl(
|
||||
@@ -107,21 +108,12 @@ fun IrBuilderWithScope.irCatch(catchParameter: IrVariable) =
|
||||
catchParameter
|
||||
)
|
||||
|
||||
fun IrBuilderWithScope.irCast(arg: IrExpression, type: KotlinType, typeOperand: KotlinType) =
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, typeOperand, arg)
|
||||
|
||||
fun IrBuilderWithScope.irImplicitCoercionToUnit(arg: IrExpression) =
|
||||
IrTypeOperatorCallImpl(
|
||||
startOffset, endOffset, context.builtIns.unitType,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, context.builtIns.unitType, arg
|
||||
startOffset, endOffset, context.irBuiltIns.unitType,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, context.irBuiltIns.unitType, context.irBuiltIns.unitClass, arg
|
||||
)
|
||||
|
||||
fun IrBuilderWithScope.irGetField(receiver: IrExpression, symbol: IrFieldSymbol) =
|
||||
IrGetFieldImpl(startOffset, endOffset, symbol, receiver)
|
||||
|
||||
fun IrBuilderWithScope.irSetField(receiver: IrExpression, symbol: IrFieldSymbol, value: IrExpression) =
|
||||
IrSetFieldImpl(startOffset, endOffset, symbol, receiver, value)
|
||||
|
||||
open class IrBuildingTransformer(private val context: BackendContext) : IrElementTransformerVoid() {
|
||||
private var currentBuilder: IrBuilderWithScope? = null
|
||||
|
||||
|
||||
@@ -27,10 +27,12 @@ import org.jetbrains.kotlin.ir.builders.irGet
|
||||
import org.jetbrains.kotlin.ir.builders.irTemporary
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSymbolDeclaration
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.isNullableAny
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
@@ -60,33 +62,33 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
|
||||
private val nameToString = Name.identifier("toString")
|
||||
private val nameAppend = Name.identifier("append")
|
||||
|
||||
private val stringBuilder = context.ir.symbols.stringBuilder
|
||||
private val stringBuilder = context.ir.symbols.stringBuilder.owner
|
||||
|
||||
//TODO: calculate and pass string length to the constructor.
|
||||
private val constructor = stringBuilder.constructors.single {
|
||||
it.owner.valueParameters.size == 0
|
||||
it.valueParameters.size == 0
|
||||
}
|
||||
|
||||
private val toStringFunction = stringBuilder.functions.single {
|
||||
it.owner.valueParameters.size == 0 && it.descriptor.name == nameToString
|
||||
it.valueParameters.size == 0 && it.name == nameToString
|
||||
}
|
||||
private val defaultAppendFunction = stringBuilder.functions.single {
|
||||
it.descriptor.name == nameAppend &&
|
||||
it.owner.valueParameters.size == 1 &&
|
||||
it.owner.valueParameters.single().type == builtIns.nullableAnyType
|
||||
it.valueParameters.size == 1 &&
|
||||
it.valueParameters.single().type.isNullableAny()
|
||||
}
|
||||
|
||||
|
||||
private val appendFunctions: Map<KotlinType, IrFunctionSymbol?> =
|
||||
private val appendFunctions: Map<KotlinType, IrSimpleFunction?> =
|
||||
typesWithSpecialAppendFunction.map { type ->
|
||||
type to stringBuilder.functions.toList().atMostOne {
|
||||
it.descriptor.name == nameAppend &&
|
||||
it.owner.valueParameters.size == 1 &&
|
||||
it.owner.valueParameters.single().type == type
|
||||
it.valueParameters.size == 1 &&
|
||||
it.valueParameters.single().type.toKotlinType() == type
|
||||
}
|
||||
}.toMap()
|
||||
|
||||
private fun typeToAppendFunction(type: KotlinType): IrFunctionSymbol {
|
||||
private fun typeToAppendFunction(type: KotlinType): IrSimpleFunction {
|
||||
return appendFunctions[type] ?: defaultAppendFunction
|
||||
}
|
||||
|
||||
@@ -96,9 +98,9 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
|
||||
expression.transformChildrenVoid(this)
|
||||
val blockBuilder = buildersStack.last()
|
||||
return blockBuilder.irBlock(expression) {
|
||||
val stringBuilderImpl = irTemporary(irCall(constructor)).symbol
|
||||
val stringBuilderImpl = irTemporary(irCall(constructor))
|
||||
expression.arguments.forEach { arg ->
|
||||
val appendFunction = typeToAppendFunction(arg.type)
|
||||
val appendFunction = typeToAppendFunction(arg.type.toKotlinType())
|
||||
+irCall(appendFunction).apply {
|
||||
dispatchReceiver = irGet(stringBuilderImpl)
|
||||
putValueArgument(0, arg)
|
||||
|
||||
@@ -18,14 +18,12 @@ package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.util.explicitParameters
|
||||
import org.jetbrains.kotlin.ir.util.getArgumentsWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.getArgumentsWithIr
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
@@ -55,7 +53,7 @@ private fun lowerTailRecursionCalls(context: BackendContext, irFunction: IrFunct
|
||||
irFunction.body = builder.irBlockBody {
|
||||
// Define variables containing current values of parameters:
|
||||
val parameterToVariable = parameters.associate {
|
||||
it to irTemporaryVar(irGet(it), nameHint = it.suggestVariableName()).symbol
|
||||
it to irTemporaryVar(irGet(it), nameHint = it.symbol.suggestVariableName())
|
||||
}
|
||||
// (these variables are to be updated on any tail call).
|
||||
|
||||
@@ -63,11 +61,11 @@ private fun lowerTailRecursionCalls(context: BackendContext, irFunction: IrFunct
|
||||
val loop = this
|
||||
condition = irTrue()
|
||||
|
||||
body = irBlock(startOffset, endOffset, resultType = context.builtIns.unitType) {
|
||||
body = irBlock(startOffset, endOffset, resultType = context.irBuiltIns.unitType) {
|
||||
// Read variables containing current values of parameters:
|
||||
val parameterToNew = parameters.associate {
|
||||
val variable = parameterToVariable[it]!!
|
||||
it to irTemporary(irGet(variable), nameHint = it.suggestVariableName()).symbol
|
||||
it to irTemporary(irGet(variable), nameHint = it.symbol.suggestVariableName())
|
||||
}
|
||||
|
||||
val transformer = BodyTransformer(
|
||||
@@ -89,8 +87,8 @@ private class BodyTransformer(
|
||||
val builder: IrBuilderWithScope,
|
||||
val irFunction: IrFunction,
|
||||
val loop: IrLoop,
|
||||
val parameterToNew: Map<IrValueParameterSymbol, IrValueSymbol>,
|
||||
val parameterToVariable: Map<IrValueParameterSymbol, IrVariableSymbol>,
|
||||
val parameterToNew: Map<IrValueParameter, IrValueDeclaration>,
|
||||
val parameterToVariable: Map<IrValueParameter, IrVariable>,
|
||||
val tailRecursionCalls: Set<IrCall>
|
||||
) : IrElementTransformerVoid() {
|
||||
|
||||
@@ -98,7 +96,7 @@ private class BodyTransformer(
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
val value = parameterToNew[expression.symbol] ?: return expression
|
||||
val value = parameterToNew[expression.symbol.owner] ?: return expression
|
||||
return builder.at(expression).irGet(value)
|
||||
}
|
||||
|
||||
@@ -113,7 +111,7 @@ private class BodyTransformer(
|
||||
|
||||
private fun IrBuilderWithScope.genTailCall(expression: IrCall) = this.irBlock(expression) {
|
||||
// Get all specified arguments:
|
||||
val parameterToArgument = expression.getArgumentsWithSymbols().map { (parameter, argument) ->
|
||||
val parameterToArgument = expression.getArgumentsWithIr().map { (parameter, argument) ->
|
||||
parameter to argument
|
||||
}
|
||||
|
||||
@@ -122,7 +120,7 @@ private class BodyTransformer(
|
||||
at(argument)
|
||||
// Note that argument can use values of parameters, so it is important that
|
||||
// references to parameters are mapped using `parameterToNew`, not `parameterToVariable`.
|
||||
+irSetVar(parameterToVariable[parameter]!!, argument)
|
||||
+irSetVar(parameterToVariable[parameter]!!.symbol, argument)
|
||||
}
|
||||
|
||||
val specifiedParameters = parameterToArgument.map { (parameter, _) -> parameter }.toSet()
|
||||
@@ -130,7 +128,7 @@ private class BodyTransformer(
|
||||
// For each unspecified argument set the corresponding variable to default:
|
||||
parameters.filter { it !in specifiedParameters }.forEach { parameter ->
|
||||
|
||||
val originalDefaultValue = parameter.owner.defaultValue?.expression ?: throw Error("no argument specified for $parameter")
|
||||
val originalDefaultValue = parameter.defaultValue?.expression ?: throw Error("no argument specified for $parameter")
|
||||
|
||||
// Copy default value, mapping parameters to variables containing freshly computed arguments:
|
||||
val defaultValue = originalDefaultValue
|
||||
@@ -140,15 +138,15 @@ private class BodyTransformer(
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val variableSymbol = parameterToVariable[expression.symbol] ?: return expression
|
||||
val variable = parameterToVariable[expression.symbol.owner] ?: return expression
|
||||
return IrGetValueImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
variableSymbol, expression.origin
|
||||
expression.startOffset, expression.endOffset, variable.type,
|
||||
variable.symbol, expression.origin
|
||||
)
|
||||
}
|
||||
}, data = null)
|
||||
|
||||
+irSetVar(parameterToVariable[parameter]!!, defaultValue)
|
||||
+irSetVar(parameterToVariable[parameter]!!.symbol, defaultValue)
|
||||
}
|
||||
|
||||
// Jump to the entry:
|
||||
|
||||
@@ -32,14 +32,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.util.getPropertyGetter
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
|
||||
@@ -68,20 +64,25 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
element?.transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||
val transformer = this
|
||||
|
||||
private fun replaceEmptyParameterWithEmptyArray(expression: IrMemberAccessExpression) {
|
||||
private fun replaceEmptyParameterWithEmptyArray(expression: IrFunctionAccessExpression) {
|
||||
log { "call of: ${expression.descriptor}" }
|
||||
context.createIrBuilder(owner, expression.startOffset, expression.endOffset).apply {
|
||||
expression.descriptor.valueParameters.forEach {
|
||||
log { "varargElementType: ${it.varargElementType} expr: ${ir2string(expression.getValueArgument(it))}" }
|
||||
}
|
||||
expression.descriptor.valueParameters.filter { it.varargElementType != null && expression.getValueArgument(it) == null }.forEach {
|
||||
expression.putValueArgument(it.index,
|
||||
IrVarargImpl(startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
type = it.type,
|
||||
varargElementType = it.varargElementType!!)
|
||||
)
|
||||
}
|
||||
expression.symbol.owner.valueParameters
|
||||
.filter { it.varargElementType != null && expression.getValueArgument(it.index) == null }
|
||||
.forEach {
|
||||
expression.putValueArgument(
|
||||
it.index,
|
||||
IrVarargImpl(
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
type = it.type,
|
||||
varargElementType = it.varargElementType!!
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
expression.transformChildrenVoid(this)
|
||||
}
|
||||
@@ -99,28 +100,27 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
override fun visitVararg(expression: IrVararg): IrExpression {
|
||||
expression.transformChildrenVoid(transformer)
|
||||
val hasSpreadElement = hasSpreadElement(expression)
|
||||
if (!hasSpreadElement && expression.elements.all { it is IrConst<*> && KotlinBuiltIns.isString(it.type) }) {
|
||||
if (!hasSpreadElement && expression.elements.all { it is IrConst<*> && it.type.isString() }) {
|
||||
log { "skipped vararg expression because it's string array literal" }
|
||||
return expression
|
||||
}
|
||||
val irBuilder = context.createIrBuilder(owner, expression.startOffset, expression.endOffset)
|
||||
irBuilder.run {
|
||||
val type = expression.varargElementType
|
||||
log { "$expression: array type:$type, is array of primitives ${!KotlinBuiltIns.isArray(expression.type)}" }
|
||||
log { "$expression: array type:$type, is array of primitives ${!expression.type.isArray()}" }
|
||||
val arrayHandle = arrayType(expression.type)
|
||||
val arrayConstructor = arrayHandle.arraySymbol.constructors.find { it.owner.valueParameters.size == 1 }!!
|
||||
val block = irBlock(arrayHandle.arraySymbol.owner.defaultType)
|
||||
val arrayConstructorCall = if (arrayConstructor.owner.typeParameters.isEmpty()) {
|
||||
irCall(arrayConstructor)
|
||||
} else {
|
||||
irCall(arrayConstructor, listOf(type))
|
||||
}
|
||||
val arrayConstructor = arrayHandle.arraySymbol.owner.constructors.find { it.valueParameters.size == 1 }!!
|
||||
val block = irBlock(expression.type)
|
||||
val arrayConstructorCall = irCall(arrayConstructor)
|
||||
|
||||
if (arrayConstructor.typeParameters.isNotEmpty()) {
|
||||
arrayConstructorCall.putTypeArgument(0, expression.varargElementType)
|
||||
}
|
||||
|
||||
val vars = expression.elements.map {
|
||||
val initVar = scope.createTemporaryVariable(
|
||||
(it as? IrSpreadElement)?.expression ?: it as IrExpression,
|
||||
"elem".synthesizedString, true)
|
||||
(it as? IrSpreadElement)?.expression ?: it as IrExpression,
|
||||
"elem".synthesizedString, true)
|
||||
block.statements.add(initVar)
|
||||
it to initVar
|
||||
}.toMap()
|
||||
@@ -138,32 +138,31 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
log { "element:$i> ${ir2string(element)}" }
|
||||
val dst = vars[element]!!
|
||||
if (element !is IrSpreadElement) {
|
||||
val setArrayElementCall = irCall(arrayHandle.setMethodSymbol)
|
||||
setArrayElementCall.dispatchReceiver = irGet(arrayTmpVariable.symbol)
|
||||
setArrayElementCall.putValueArgument(0, if (hasSpreadElement) irGet(indexTmpVariable.symbol) else irConstInt(i))
|
||||
setArrayElementCall.putValueArgument(1, irGet(dst.symbol))
|
||||
val setArrayElementCall = irCall(arrayHandle.setMethodSymbol.owner)
|
||||
setArrayElementCall.dispatchReceiver = irGet(arrayTmpVariable)
|
||||
setArrayElementCall.putValueArgument(0, if (hasSpreadElement) irGet(indexTmpVariable) else irConstInt(i))
|
||||
setArrayElementCall.putValueArgument(1, irGet(dst))
|
||||
block.statements.add(setArrayElementCall)
|
||||
if (hasSpreadElement) {
|
||||
block.statements.add(incrementVariable(indexTmpVariable.symbol, kIntOne))
|
||||
block.statements.add(incrementVariable(indexTmpVariable, kIntOne))
|
||||
}
|
||||
} else {
|
||||
val arraySizeVariable = scope.createTemporaryVariable(irArraySize(arrayHandle, irGet(dst.symbol)), "length".synthesizedString)
|
||||
val arraySizeVariable = scope.createTemporaryVariable(irArraySize(arrayHandle, irGet(dst)), "length".synthesizedString)
|
||||
block.statements.add(arraySizeVariable)
|
||||
val copyCall = irCall(arrayHandle.copyRangeToSymbol).apply {
|
||||
extensionReceiver = irGet(dst.symbol)
|
||||
putValueArgument(0, irGet(arrayTmpVariable.symbol)) /* destination */
|
||||
val copyCall = irCall(arrayHandle.copyRangeToSymbol.owner).apply {
|
||||
extensionReceiver = irGet(dst)
|
||||
putValueArgument(0, irGet(arrayTmpVariable)) /* destination */
|
||||
putValueArgument(1, kIntZero) /* fromIndex */
|
||||
putValueArgument(2, irGet(arraySizeVariable.symbol)) /* toIndex */
|
||||
putValueArgument(3, irGet(indexTmpVariable.symbol)) /* destinationIndex */
|
||||
putValueArgument(2, irGet(arraySizeVariable)) /* toIndex */
|
||||
putValueArgument(3, irGet(indexTmpVariable)) /* destinationIndex */
|
||||
}
|
||||
block.statements.add(copyCall)
|
||||
block.statements.add(incrementVariable(indexTmpVariable.symbol,
|
||||
irGet(arraySizeVariable.symbol)))
|
||||
block.statements.add(incrementVariable(indexTmpVariable, irGet(arraySizeVariable)))
|
||||
log { "element:$i:spread element> ${ir2string(element.expression)}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
block.statements.add(irGet(arrayTmpVariable.symbol))
|
||||
block.statements.add(irGet(arrayTmpVariable))
|
||||
return block
|
||||
}
|
||||
}
|
||||
@@ -171,24 +170,21 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
}
|
||||
|
||||
private val symbols = context.ir.symbols
|
||||
private val intPlusInt = symbols.intPlusInt
|
||||
private val intPlusInt = symbols.intPlusInt.owner
|
||||
|
||||
private fun arrayType(type: KotlinType): ArrayHandle = when {
|
||||
KotlinBuiltIns.isPrimitiveArray(type) -> {
|
||||
val primitiveType = KotlinBuiltIns.getPrimitiveArrayType(type.constructor.declarationDescriptor!!)
|
||||
when (primitiveType) {
|
||||
PrimitiveType.BYTE -> kByteArrayHandler
|
||||
PrimitiveType.SHORT -> kShortArrayHandler
|
||||
PrimitiveType.CHAR -> kCharArrayHandler
|
||||
PrimitiveType.INT -> kIntArrayHandler
|
||||
PrimitiveType.LONG -> kLongArrayHandler
|
||||
PrimitiveType.FLOAT -> kFloatArrayHandler
|
||||
PrimitiveType.DOUBLE -> kDoubleArrayHandler
|
||||
PrimitiveType.BOOLEAN -> kBooleanArrayHandler
|
||||
else -> TODO("unsupported type: $primitiveType")
|
||||
}
|
||||
private fun arrayType(type: IrType): ArrayHandle {
|
||||
val primitiveType = KotlinBuiltIns.getPrimitiveArrayType(type.classifierOrFail.descriptor)
|
||||
return when (primitiveType) {
|
||||
PrimitiveType.BYTE -> kByteArrayHandler
|
||||
PrimitiveType.SHORT -> kShortArrayHandler
|
||||
PrimitiveType.CHAR -> kCharArrayHandler
|
||||
PrimitiveType.INT -> kIntArrayHandler
|
||||
PrimitiveType.LONG -> kLongArrayHandler
|
||||
PrimitiveType.FLOAT -> kFloatArrayHandler
|
||||
PrimitiveType.DOUBLE -> kDoubleArrayHandler
|
||||
PrimitiveType.BOOLEAN -> kBooleanArrayHandler
|
||||
else -> kArrayHandler
|
||||
}
|
||||
else -> kArrayHandler
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.intPlus() = irCall(intPlusInt)
|
||||
@@ -199,9 +195,9 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.incrementVariable(symbol: IrVariableSymbol, value: IrExpression): IrExpression {
|
||||
return irSetVar(symbol, intPlus().apply {
|
||||
dispatchReceiver = irGet(symbol)
|
||||
private fun IrBuilderWithScope.incrementVariable(variable: IrVariable, value: IrExpression): IrExpression {
|
||||
return irSetVar(variable.symbol, intPlus().apply {
|
||||
dispatchReceiver = irGet(variable)
|
||||
putValueArgument(0, value)
|
||||
})
|
||||
}
|
||||
@@ -212,14 +208,14 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
val notSpreadElementCount = expression.elements.filter { it !is IrSpreadElement}.size
|
||||
val initialValue = irConstInt(notSpreadElementCount) as IrExpression
|
||||
return vars.filter{it.key is IrSpreadElement}.toList().fold( initial = initialValue) { result, it ->
|
||||
val arraySize = irArraySize(arrayHandle, irGet(it.second.symbol))
|
||||
val arraySize = irArraySize(arrayHandle, irGet(it.second))
|
||||
increment(result, arraySize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.irArraySize(arrayHandle: ArrayHandle, expression: IrExpression): IrExpression {
|
||||
val arraySize = irCall(arrayHandle.sizeGetterSymbol).apply {
|
||||
val arraySize = irCall(arrayHandle.sizeGetterSymbol.owner).apply {
|
||||
dispatchReceiver = expression
|
||||
}
|
||||
return arraySize
|
||||
@@ -256,7 +252,8 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.irConstInt(value: Int): IrConst<Int> = IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, value)
|
||||
private fun IrBuilderWithScope.irBlock(type: KotlinType): IrBlock = IrBlockImpl(startOffset, endOffset, type)
|
||||
private fun IrBuilderWithScope.irConstInt(value: Int): IrConst<Int> =
|
||||
IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, value)
|
||||
private fun IrBuilderWithScope.irBlock(type: IrType): IrBlock = IrBlockImpl(startOffset, endOffset, type)
|
||||
private val IrBuilderWithScope.kIntZero get() = irConstInt(0)
|
||||
private val IrBuilderWithScope.kIntOne get() = irConstInt(1)
|
||||
|
||||
@@ -16,39 +16,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.builders
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.substitute
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
|
||||
fun IrBuilderWithScope.irWhile(origin: IrStatementOrigin? = null) =
|
||||
IrWhileLoopImpl(startOffset, endOffset, context.builtIns.unitType, origin)
|
||||
IrWhileLoopImpl(startOffset, endOffset, context.irBuiltIns.unitType, origin)
|
||||
|
||||
fun IrBuilderWithScope.irBreak(loop: IrLoop) =
|
||||
IrBreakImpl(startOffset, endOffset, context.builtIns.nothingType, loop)
|
||||
IrBreakImpl(startOffset, endOffset, context.irBuiltIns.nothingType, loop)
|
||||
|
||||
fun IrBuilderWithScope.irContinue(loop: IrLoop) =
|
||||
IrContinueImpl(startOffset, endOffset, context.builtIns.nothingType, loop)
|
||||
|
||||
fun IrBuilderWithScope.irTrue() = IrConstImpl.boolean(startOffset, endOffset, context.builtIns.booleanType, true)
|
||||
|
||||
fun IrBuilderWithScope.irFalse() = IrConstImpl.boolean(startOffset, endOffset, context.builtIns.booleanType, false)
|
||||
|
||||
fun IrBuilderWithScope.irCall(symbol: IrFunctionSymbol, typeArguments: Map<TypeParameterDescriptor, KotlinType>) =
|
||||
IrCallImpl(this.startOffset, this.endOffset, symbol, symbol.descriptor.substitute(typeArguments), typeArguments)
|
||||
|
||||
fun IrBuilderWithScope.irCall(symbol: IrFunctionSymbol, typeArguments: List<KotlinType>) =
|
||||
irCall(symbol, symbol.descriptor.typeParameters.zip(typeArguments).toMap())
|
||||
IrContinueImpl(startOffset, endOffset, context.irBuiltIns.nothingType, loop)
|
||||
|
||||
fun IrBuilderWithScope.irGetObject(classSymbol: IrClassSymbol) =
|
||||
IrGetObjectValueImpl(startOffset, endOffset, classSymbol.owner.defaultType, classSymbol)
|
||||
|
||||
fun IrBuilderWithScope.irGetField(receiver: IrExpression?, symbol: IrFieldSymbol) =
|
||||
IrGetFieldImpl(startOffset, endOffset, symbol, receiver)
|
||||
IrGetObjectValueImpl(startOffset, endOffset, IrSimpleTypeImpl(classSymbol, false, emptyList(), emptyList()), classSymbol)
|
||||
|
||||
@@ -25,7 +25,7 @@ class JsIntrinsics(
|
||||
context: JsIrBackendContext
|
||||
) {
|
||||
|
||||
private val stubBuilder = DeclarationStubGenerator(context.symbolTable, JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB)
|
||||
private val stubBuilder = DeclarationStubGenerator(context.module, context.symbolTable, JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB)
|
||||
|
||||
// Equality operations:
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.resolve.calls.components.isVararg
|
||||
@@ -25,7 +26,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.util.*
|
||||
|
||||
private class IrEmptyVarargExpression(
|
||||
override val type: KotlinType,
|
||||
override val type: IrType,
|
||||
override val startOffset: Int,
|
||||
override val endOffset: Int
|
||||
) : IrExpression {
|
||||
@@ -122,13 +123,11 @@ open class IrIntrinsicFunction(
|
||||
}
|
||||
}
|
||||
|
||||
fun createWithResult(
|
||||
expression: IrMemberAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
context: JvmBackendContext,
|
||||
argsTypes: List<Type> = expression.argTypes(context),
|
||||
invokeInstruction: IrIntrinsicFunction.(InstructionAdapter) -> Type
|
||||
): IrIntrinsicFunction {
|
||||
fun createWithResult(expression: IrMemberAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
context: JvmBackendContext,
|
||||
argsTypes: List<Type> = expression.argTypes(context),
|
||||
invokeInstruction: IrIntrinsicFunction.(InstructionAdapter) -> Type): IrIntrinsicFunction {
|
||||
return object : IrIntrinsicFunction(expression, signature, context, argsTypes) {
|
||||
|
||||
override fun genInvokeInstructionWithResult(v: InstructionAdapter) = invokeInstruction(v)
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.ir2cfg.graph.ControlFlowGraph
|
||||
@@ -66,7 +67,8 @@ class FunctionGenerator(val function: IrFunction) {
|
||||
return result
|
||||
}
|
||||
|
||||
private fun IrElement?.isNothing() = this is IrExpression && KotlinBuiltIns.isNothing(type)
|
||||
private fun IrElement?.isNothing() =
|
||||
this is IrExpression && KotlinBuiltIns.isNothing(type.originalKotlinType!!) // TODO
|
||||
|
||||
override fun visitBlockBody(body: IrBlockBody, data: Boolean): IrStatement? {
|
||||
return body.process()
|
||||
@@ -81,8 +83,7 @@ class FunctionGenerator(val function: IrFunction) {
|
||||
return if (data) {
|
||||
builder.add(declaration)
|
||||
declaration
|
||||
}
|
||||
else null
|
||||
} else null
|
||||
}
|
||||
|
||||
override fun visitReturn(expression: IrReturn, data: Boolean): IrStatement? {
|
||||
@@ -121,8 +122,7 @@ class FunctionGenerator(val function: IrFunction) {
|
||||
builder.move(branch.condition)
|
||||
if (!result.process().isNothing()) {
|
||||
builder.jump(whenExit)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
builder.move(branch.condition)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,10 +20,11 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.generators.AnnotationGenerator
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
|
||||
import org.jetbrains.kotlin.psi2ir.transformations.generateAnnotationsForDeclarations
|
||||
import org.jetbrains.kotlin.psi2ir.transformations.insertImplicitCasts
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
@@ -56,11 +57,16 @@ class Psi2IrTranslator(val configuration: Psi2IrConfiguration = Psi2IrConfigurat
|
||||
}
|
||||
|
||||
private fun postprocess(context: GeneratorContext, irElement: IrElement) {
|
||||
insertImplicitCasts(context.builtIns, irElement, context.symbolTable)
|
||||
insertImplicitCasts(irElement, context)
|
||||
generateAnnotationsForDeclarations(context, irElement)
|
||||
|
||||
postprocessingSteps.forEach { it.postprocess(context, irElement) }
|
||||
|
||||
irElement.patchDeclarationParents()
|
||||
}
|
||||
|
||||
private fun generateAnnotationsForDeclarations(context: GeneratorContext, irElement: IrElement) {
|
||||
val annotationGenerator = AnnotationGenerator(context)
|
||||
irElement.acceptVoid(annotationGenerator)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
|
||||
class AnnotationGenerator(
|
||||
context: GeneratorContext
|
||||
) : IrElementVisitorVoid {
|
||||
|
||||
private val typeTranslator = context.typeTranslator
|
||||
private val constantValueGenerator = context.constantValueGenerator
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitDeclaration(declaration: IrDeclaration) {
|
||||
if (declaration is IrTypeParametersContainer) {
|
||||
typeTranslator.enterScope(declaration)
|
||||
}
|
||||
generateAnnotationsForDeclaration(declaration)
|
||||
visitElement(declaration)
|
||||
if (declaration is IrTypeParametersContainer) {
|
||||
typeTranslator.leaveScope()
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitValueParameter(declaration: IrValueParameter) {
|
||||
super.visitValueParameter(declaration)
|
||||
|
||||
val descriptor = declaration.descriptor
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
|
||||
if (containingDeclaration is PropertySetterDescriptor) {
|
||||
containingDeclaration.correspondingProperty.annotations.getUseSiteTargetedAnnotations()
|
||||
.filter { it.target == AnnotationUseSiteTarget.SETTER_PARAMETER }
|
||||
.generateAnnotationConstructorCalls(declaration)
|
||||
}
|
||||
|
||||
descriptor.type.annotations.getAllAnnotations()
|
||||
.filter { it.target == AnnotationUseSiteTarget.RECEIVER }
|
||||
.generateAnnotationConstructorCalls(declaration)
|
||||
}
|
||||
|
||||
private fun generateAnnotationsForDeclaration(declaration: IrDeclaration) {
|
||||
declaration.descriptor.annotations.getAllAnnotations()
|
||||
.filter { isAnnotationTargetMatchingDeclaration(it.target, declaration) }
|
||||
.generateAnnotationConstructorCalls(declaration)
|
||||
}
|
||||
|
||||
private fun List<AnnotationWithTarget>.generateAnnotationConstructorCalls(declaration: IrDeclaration) {
|
||||
mapTo(declaration.annotations) {
|
||||
constantValueGenerator.generateAnnotationConstructorCall(it.annotation)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isAnnotationTargetMatchingDeclaration(target: AnnotationUseSiteTarget?, element: IrElement): Boolean =
|
||||
when (element) {
|
||||
is IrProperty ->
|
||||
target == null || target == AnnotationUseSiteTarget.PROPERTY
|
||||
|
||||
is IrField ->
|
||||
target == AnnotationUseSiteTarget.FIELD || target == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
|
||||
|
||||
is IrSimpleFunction ->
|
||||
target == null || target == AnnotationUseSiteTarget.PROPERTY_GETTER || target == AnnotationUseSiteTarget.PROPERTY_SETTER
|
||||
|
||||
is IrValueParameter ->
|
||||
target == null || target == AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
|
||||
|
||||
else -> target == null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,10 @@ import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
class AnonymousInitializerGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
|
||||
class AnonymousInitializerGenerator(
|
||||
declarationGenerator: DeclarationGenerator
|
||||
) : DeclarationGeneratorExtension(declarationGenerator) {
|
||||
|
||||
fun generateAnonymousInitializerDeclaration(
|
||||
ktAnonymousInitializer: KtAnonymousInitializer,
|
||||
classDescriptor: ClassDescriptor
|
||||
|
||||
@@ -46,18 +46,20 @@ fun StatementGenerator.generateReceiverOrNull(ktDefaultElement: KtElement, recei
|
||||
fun StatementGenerator.generateReceiver(ktDefaultElement: KtElement, receiver: ReceiverValue): IntermediateValue =
|
||||
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) {
|
||||
fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffset: Int, receiver: ReceiverValue): IntermediateValue {
|
||||
val irReceiverType = receiver.type.toIrType()
|
||||
|
||||
if (receiver is TransientReceiver) return TransientReceiverValue(irReceiverType)
|
||||
|
||||
return generateDelegatedValue(irReceiverType) {
|
||||
val receiverExpression: IrExpression = when (receiver) {
|
||||
is ImplicitClassReceiver -> {
|
||||
val receiverClassDescriptor = receiver.classDescriptor
|
||||
if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor))
|
||||
generateSingletonReference(receiverClassDescriptor, defaultStartOffset, defaultEndOffset, receiver.type)
|
||||
else
|
||||
IrGetValueImpl(
|
||||
defaultStartOffset, defaultEndOffset,
|
||||
defaultStartOffset, defaultEndOffset, irReceiverType,
|
||||
context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter)
|
||||
)
|
||||
}
|
||||
@@ -69,12 +71,12 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
|
||||
generateExpression(receiver.expression)
|
||||
is ClassValueReceiver ->
|
||||
IrGetObjectValueImpl(
|
||||
receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
|
||||
receiver.expression.startOffset, receiver.expression.endOffset, irReceiverType,
|
||||
context.symbolTable.referenceClass(receiver.classQualifier.descriptor as ClassDescriptor)
|
||||
)
|
||||
is ExtensionReceiver ->
|
||||
IrGetValueImpl(
|
||||
defaultStartOffset, defaultStartOffset,
|
||||
defaultStartOffset, defaultStartOffset, irReceiverType,
|
||||
context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!)
|
||||
)
|
||||
else ->
|
||||
@@ -86,33 +88,37 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
|
||||
else
|
||||
OnceExpressionValue(receiverExpression)
|
||||
}
|
||||
}
|
||||
|
||||
fun StatementGenerator.generateSingletonReference(
|
||||
descriptor: ClassDescriptor,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType
|
||||
): IrDeclarationReference =
|
||||
when {
|
||||
): IrDeclarationReference {
|
||||
val irType = type.toIrType()
|
||||
|
||||
return when {
|
||||
DescriptorUtils.isObject(descriptor) ->
|
||||
IrGetObjectValueImpl(
|
||||
startOffset, endOffset, type,
|
||||
startOffset, endOffset, irType,
|
||||
context.symbolTable.referenceClass(descriptor)
|
||||
)
|
||||
DescriptorUtils.isEnumEntry(descriptor) ->
|
||||
IrGetEnumValueImpl(
|
||||
startOffset, endOffset, type,
|
||||
startOffset, endOffset, irType,
|
||||
context.symbolTable.referenceEnumEntry(descriptor)
|
||||
)
|
||||
else -> {
|
||||
val companionObjectDescriptor = descriptor.companionObjectDescriptor
|
||||
?: throw java.lang.AssertionError("Class value without companion object: $descriptor")
|
||||
IrGetObjectValueImpl(
|
||||
startOffset, endOffset, type,
|
||||
startOffset, endOffset, irType,
|
||||
context.symbolTable.referenceClass(companionObjectDescriptor)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun StatementGenerator.shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor: ClassDescriptor): Boolean {
|
||||
return receiverClassDescriptor.kind.isSingleton &&
|
||||
@@ -126,6 +132,7 @@ private fun StatementGenerator.generateThisOrSuperReceiver(receiver: ReceiverVal
|
||||
val ktReceiver = expressionReceiver.expression
|
||||
return IrGetValueImpl(
|
||||
ktReceiver.startOffset, ktReceiver.endOffset,
|
||||
expressionReceiver.type.toIrType(),
|
||||
context.symbolTable.referenceValueParameter(classDescriptor.thisAsReceiverParameter)
|
||||
)
|
||||
}
|
||||
@@ -192,7 +199,7 @@ private fun StatementGenerator.generateReceiverForCalleeImportedFromObject(
|
||||
calleeDescriptor: ImportedFromObjectCallableDescriptor<*>
|
||||
): ExpressionValue {
|
||||
val objectDescriptor = calleeDescriptor.containingObject
|
||||
val objectType = objectDescriptor.defaultType
|
||||
val objectType = objectDescriptor.defaultType.toIrType()
|
||||
return generateExpressionValue(objectType) {
|
||||
IrGetObjectValueImpl(
|
||||
startOffset, endOffset, objectType,
|
||||
@@ -219,7 +226,7 @@ fun StatementGenerator.generateVarargExpression(
|
||||
val varargElementType =
|
||||
valueParameter.varargElementType ?: throw AssertionError("Vararg argument for non-vararg parameter $valueParameter")
|
||||
|
||||
val irVararg = IrVarargImpl(varargStartOffset, varargEndOffset, valueParameter.type, varargElementType)
|
||||
val irVararg = IrVarargImpl(varargStartOffset, varargEndOffset, valueParameter.type.toIrType(), varargElementType.toIrType())
|
||||
|
||||
for (argument in varargArgument.arguments) {
|
||||
val ktArgumentExpression = argument.getArgumentExpression()
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi2ir.generators
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
|
||||
import org.jetbrains.kotlin.ir.builders.irBlock
|
||||
import org.jetbrains.kotlin.ir.builders.irGet
|
||||
import org.jetbrains.kotlin.ir.builders.irTemporary
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
@@ -35,25 +36,26 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ThisClassReceiver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
fun generateAssignment(expression: KtBinaryExpression): IrExpression {
|
||||
val ktLeft = expression.left!!
|
||||
val irRhs = expression.right!!.genExpr()
|
||||
|
||||
fun generateAssignment(ktExpression: KtBinaryExpression): IrExpression {
|
||||
val ktLeft = ktExpression.left!!
|
||||
val irRhs = ktExpression.right!!.genExpr()
|
||||
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, IrStatementOrigin.EQ)
|
||||
return irAssignmentReceiver.assign(irRhs)
|
||||
}
|
||||
|
||||
fun generateAugmentedAssignment(expression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
|
||||
val opResolvedCall = getResolvedCall(expression)!!
|
||||
val isSimpleAssignment = get(BindingContext.VARIABLE_REASSIGNMENT, expression) ?: false
|
||||
val ktLeft = expression.left!!
|
||||
val ktRight = expression.right!!
|
||||
fun generateAugmentedAssignment(ktExpression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
|
||||
val opResolvedCall = getResolvedCall(ktExpression)!!
|
||||
val isSimpleAssignment = get(BindingContext.VARIABLE_REASSIGNMENT, ktExpression) ?: false
|
||||
val ktLeft = ktExpression.left!!
|
||||
val ktRight = ktExpression.right!!
|
||||
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, origin)
|
||||
|
||||
return irAssignmentReceiver.assign { irLValue ->
|
||||
val opCall = statementGenerator.pregenerateCallReceivers(opResolvedCall)
|
||||
opCall.setExplicitReceiverValue(irLValue)
|
||||
opCall.irValueArgumentsByIndex[0] = ktRight.genExpr()
|
||||
val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, origin)
|
||||
val irOpCall = CallGenerator(statementGenerator).generateCall(ktExpression, opCall, origin)
|
||||
|
||||
if (isSimpleAssignment) {
|
||||
// Set( Op( Get(), RHS ) )
|
||||
@@ -65,35 +67,37 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
||||
}
|
||||
}
|
||||
|
||||
fun generatePrefixIncrementDecrement(expression: KtPrefixExpression, origin: IrStatementOrigin): IrExpression {
|
||||
val opResolvedCall = getResolvedCall(expression)!!
|
||||
val ktBaseExpression = expression.baseExpression!!
|
||||
fun generatePrefixIncrementDecrement(ktExpression: KtPrefixExpression, origin: IrStatementOrigin): IrExpression {
|
||||
val opResolvedCall = getResolvedCall(ktExpression)!!
|
||||
val ktBaseExpression = ktExpression.baseExpression!!
|
||||
val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, origin)
|
||||
|
||||
return irAssignmentReceiver.assign { irLValue ->
|
||||
irBlock(expression, origin, irLValue.type) {
|
||||
irBlock(ktExpression.startOffset, ktExpression.endOffset, origin, irLValue.type) {
|
||||
val opCall = statementGenerator.pregenerateCall(opResolvedCall)
|
||||
opCall.setExplicitReceiverValue(irLValue)
|
||||
val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, origin)
|
||||
val irOpCall = CallGenerator(statementGenerator).generateCall(ktExpression, opCall, origin)
|
||||
+irLValue.store(irOpCall)
|
||||
+irLValue.load()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun generatePostfixIncrementDecrement(expression: KtPostfixExpression, origin: IrStatementOrigin): IrExpression {
|
||||
val opResolvedCall = getResolvedCall(expression)!!
|
||||
val ktBaseExpression = expression.baseExpression!!
|
||||
fun generatePostfixIncrementDecrement(ktExpression: KtPostfixExpression, origin: IrStatementOrigin): IrExpression {
|
||||
val opResolvedCall = getResolvedCall(ktExpression)!!
|
||||
val ktBaseExpression = ktExpression.baseExpression!!
|
||||
val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, origin)
|
||||
|
||||
return irAssignmentReceiver.assign { irLValue ->
|
||||
irBlock(expression, origin, irLValue.type) {
|
||||
irBlock(ktExpression.startOffset, ktExpression.endOffset, origin, irLValue.type) {
|
||||
val temporary = irTemporary(irLValue.load())
|
||||
val opCall = statementGenerator.pregenerateCall(opResolvedCall)
|
||||
opCall.setExplicitReceiverValue(VariableLValue(startOffset, endOffset, temporary.symbol))
|
||||
val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, origin)
|
||||
opCall.setExplicitReceiverValue(
|
||||
VariableLValue(context, startOffset, endOffset, temporary.symbol, temporary.type)
|
||||
)
|
||||
val irOpCall = CallGenerator(statementGenerator).generateCall(ktExpression, opCall, origin)
|
||||
+irLValue.store(irOpCall)
|
||||
+irGet(temporary.symbol)
|
||||
+irGet(temporary.type, temporary.symbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,31 +120,37 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
||||
@Suppress("DEPRECATION")
|
||||
if (descriptor.isDelegated)
|
||||
DelegatedLocalPropertyLValue(
|
||||
context,
|
||||
ktLeft.startOffset, ktLeft.endOffset,
|
||||
descriptor.type,
|
||||
descriptor.type.toIrType(),
|
||||
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
|
||||
)
|
||||
createVariableValue(ktLeft, descriptor, origin)
|
||||
is PropertyDescriptor ->
|
||||
generateAssignmentReceiverForProperty(descriptor, origin, ktLeft, resolvedCall)
|
||||
is ValueDescriptor ->
|
||||
VariableLValue(
|
||||
ktLeft.startOffset, ktLeft.endOffset,
|
||||
context.symbolTable.referenceValue(descriptor),
|
||||
origin
|
||||
)
|
||||
createVariableValue(ktLeft, descriptor, origin)
|
||||
else ->
|
||||
OnceExpressionValue(ktLeft.genExpr())
|
||||
}
|
||||
}
|
||||
|
||||
private fun createVariableValue(
|
||||
ktExpression: KtExpression,
|
||||
descriptor: ValueDescriptor,
|
||||
origin: IrStatementOrigin
|
||||
) =
|
||||
VariableLValue(
|
||||
context,
|
||||
ktExpression.startOffset, ktExpression.endOffset,
|
||||
context.symbolTable.referenceValue(descriptor),
|
||||
descriptor.type.toIrType(),
|
||||
origin
|
||||
)
|
||||
|
||||
private fun createBackingFieldLValue(
|
||||
ktExpression: KtExpression,
|
||||
descriptor: PropertyDescriptor,
|
||||
@@ -148,8 +158,9 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
||||
origin: IrStatementOrigin?
|
||||
): BackingFieldLValue =
|
||||
BackingFieldLValue(
|
||||
context,
|
||||
ktExpression.startOffset, ktExpression.endOffset,
|
||||
descriptor.type,
|
||||
descriptor.type.toIrType(),
|
||||
context.symbolTable.referenceField(descriptor),
|
||||
receiverValue, origin
|
||||
)
|
||||
@@ -162,9 +173,12 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
||||
): AssignmentReceiver =
|
||||
if (isValInitializationInConstructor(descriptor, resolvedCall)) {
|
||||
val thisClass = getThisClass()
|
||||
val thisAsReceiverParameter = thisClass.thisAsReceiverParameter
|
||||
val thisType = thisAsReceiverParameter.type.toIrType()
|
||||
val irThis = IrGetValueImpl(
|
||||
ktLeft.startOffset, ktLeft.endOffset,
|
||||
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter)
|
||||
thisType,
|
||||
context.symbolTable.referenceValueParameter(thisAsReceiverParameter)
|
||||
)
|
||||
createBackingFieldLValue(ktLeft, descriptor, RematerializableValue(irThis), null)
|
||||
} else {
|
||||
@@ -184,7 +198,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
||||
ktExpression: KtExpression,
|
||||
descriptor: PropertyDescriptor,
|
||||
propertyReceiver: CallReceiver,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
typeArgumentsMap: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
origin: IrStatementOrigin?,
|
||||
superQualifier: ClassDescriptor?
|
||||
): PropertyLValueBase {
|
||||
@@ -196,24 +210,32 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
||||
val setterDescriptor = descriptor.setter
|
||||
val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it.original) }
|
||||
|
||||
val propertyIrType = descriptor.type.toIrType()
|
||||
return if (getterSymbol != null || setterSymbol != null) {
|
||||
val typeArgumentsList =
|
||||
typeArgumentsMap?.let { typeArguments ->
|
||||
descriptor.original.typeParameters.map { typeArguments[it]!!.toIrType() }
|
||||
}
|
||||
AccessorPropertyLValue(
|
||||
context,
|
||||
scope,
|
||||
ktExpression.startOffset, ktExpression.endOffset, origin,
|
||||
descriptor.type,
|
||||
propertyIrType,
|
||||
getterSymbol,
|
||||
getterDescriptor,
|
||||
setterSymbol,
|
||||
setterDescriptor,
|
||||
typeArguments,
|
||||
typeArgumentsList,
|
||||
propertyReceiver,
|
||||
superQualifierSymbol
|
||||
)
|
||||
} else
|
||||
FieldPropertyLValue(
|
||||
context,
|
||||
scope,
|
||||
ktExpression.startOffset, ktExpression.endOffset, origin,
|
||||
context.symbolTable.referenceField(descriptor),
|
||||
propertyIrType,
|
||||
propertyReceiver,
|
||||
superQualifierSymbol
|
||||
)
|
||||
|
||||
@@ -29,14 +29,19 @@ import org.jetbrains.kotlin.psi2ir.intermediate.VariableLValue
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
class BodyGenerator(
|
||||
val scopeOwnerSymbol: IrSymbol,
|
||||
override val context: GeneratorContext
|
||||
) : GeneratorWithScope {
|
||||
|
||||
val scopeOwner: DeclarationDescriptor get() = scopeOwnerSymbol.descriptor
|
||||
|
||||
private val typeTranslator = context.typeTranslator
|
||||
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||
|
||||
override val scope = Scope(scopeOwnerSymbol)
|
||||
private val loopTable = HashMap<KtLoopExpression, IrLoop>()
|
||||
|
||||
@@ -66,8 +71,10 @@ class BodyGenerator(
|
||||
val ktDestructuringDeclaration = ktParameter.destructuringDeclaration ?: continue
|
||||
val valueParameter = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter)
|
||||
val parameterValue = VariableLValue(
|
||||
context,
|
||||
ktDestructuringDeclaration.startOffset, ktDestructuringDeclaration.endOffset,
|
||||
context.symbolTable.referenceValue(valueParameter),
|
||||
valueParameter.type.toIrType(),
|
||||
IrStatementOrigin.DESTRUCTURING_DECLARATION
|
||||
)
|
||||
statementGenerator.declareComponentVariablesInBlock(ktDestructuringDeclaration, irBlockBody, parameterValue)
|
||||
@@ -85,7 +92,7 @@ class BodyGenerator(
|
||||
generateReturnExpression(
|
||||
ktBody.startOffset, ktBody.endOffset,
|
||||
IrGetObjectValueImpl(
|
||||
ktBody.startOffset, ktBody.endOffset, context.builtIns.unitType,
|
||||
ktBody.startOffset, ktBody.endOffset, context.irBuiltIns.unitType,
|
||||
context.symbolTable.referenceClass(context.builtIns.unit)
|
||||
)
|
||||
)
|
||||
@@ -115,7 +122,7 @@ class BodyGenerator(
|
||||
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,
|
||||
startOffset, endOffset, context.irBuiltIns.nothingType,
|
||||
context.symbolTable.referenceFunction(returnTarget),
|
||||
returnValue
|
||||
)
|
||||
@@ -177,7 +184,8 @@ class BodyGenerator(
|
||||
irBlockBody.statements.add(
|
||||
IrInstanceInitializerCallImpl(
|
||||
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
|
||||
context.symbolTable.referenceClass(classDescriptor)
|
||||
context.symbolTable.referenceClass(classDescriptor),
|
||||
context.irBuiltIns.unitType
|
||||
)
|
||||
)
|
||||
|
||||
@@ -193,7 +201,8 @@ class BodyGenerator(
|
||||
irBlockBody.statements.add(
|
||||
IrInstanceInitializerCallImpl(
|
||||
ktConstructor.startOffset, ktConstructor.endOffset,
|
||||
context.symbolTable.referenceClass(classDescriptor)
|
||||
context.symbolTable.referenceClass(classDescriptor),
|
||||
context.irBuiltIns.unitType
|
||||
)
|
||||
)
|
||||
|
||||
@@ -248,9 +257,9 @@ class BodyGenerator(
|
||||
irBlockBody.statements.add(
|
||||
IrDelegatingConstructorCallImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
context.irBuiltIns.unitType,
|
||||
context.symbolTable.referenceConstructor(anyConstructor),
|
||||
anyConstructor,
|
||||
null
|
||||
anyConstructor
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -264,9 +273,12 @@ class BodyGenerator(
|
||||
irBlockBody.statements.add(
|
||||
IrEnumConstructorCallImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
context.irBuiltIns.unitType,
|
||||
context.symbolTable.referenceConstructor(enumConstructor),
|
||||
mapOf(enumConstructor.typeParameters.single() to classDescriptor.defaultType)
|
||||
)
|
||||
1 // kotlin.Enum<T> has a single type parameter
|
||||
).apply {
|
||||
putTypeArgument(0, classDescriptor.defaultType.toIrType())
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -279,8 +291,9 @@ class BodyGenerator(
|
||||
val enumEntryConstructor = enumEntryDescriptor.unsubstitutedPrimaryConstructor!!
|
||||
return IrEnumConstructorCallImpl(
|
||||
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
||||
context.irBuiltIns.unitType,
|
||||
context.symbolTable.referenceConstructor(enumEntryConstructor),
|
||||
null // enums can't be generic (so far)
|
||||
0 // enums can't be generic
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,22 +18,26 @@ package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.buildStatement
|
||||
import org.jetbrains.kotlin.ir.builders.irIfThenMaybeElse
|
||||
import org.jetbrains.kotlin.ir.builders.whenComma
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.defaultLoad
|
||||
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.defaultLoad
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
|
||||
fun generateIfExpression(expression: KtIfExpression): IrExpression {
|
||||
val resultType = getInferredTypeWithImplicitCastsOrFail(expression)
|
||||
val resultType = getInferredTypeWithImplicitCastsOrFail(expression).toIrType()
|
||||
|
||||
var ktLastIf: KtIfExpression = expression
|
||||
val irBranches = SmartList<IrBranch>()
|
||||
@@ -63,13 +67,13 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
ktIf: KtIfExpression,
|
||||
irBranches: List<IrBranch>,
|
||||
irElseResult: IrExpression?,
|
||||
resultType: KotlinType
|
||||
resultType: IrType
|
||||
): IrWhen {
|
||||
if (irBranches.size == 1) {
|
||||
return IrIfThenElseImpl(
|
||||
ktIf.startOffset, ktIf.endOffset, resultType,
|
||||
irBranches[0].condition, irBranches[0].result, irElseResult
|
||||
)
|
||||
val irBranch0 = irBranches[0]
|
||||
return buildStatement(ktIf.startOffset, ktIf.endOffset) {
|
||||
irIfThenMaybeElse(resultType, irBranch0.condition, irBranch0.result, irElseResult)
|
||||
}
|
||||
}
|
||||
|
||||
val irWhen = IrWhenImpl(ktIf.startOffset, ktIf.endOffset, resultType, IrStatementOrigin.WHEN)
|
||||
@@ -77,12 +81,18 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
irWhen.branches.addAll(irBranches)
|
||||
|
||||
irElseResult?.let {
|
||||
irWhen.branches.add(IrBranchImpl.elseBranch(it))
|
||||
irWhen.branches.add(elseBranch(it))
|
||||
}
|
||||
|
||||
return irWhen
|
||||
}
|
||||
|
||||
private fun elseBranch(result: IrExpression) =
|
||||
IrElseBranchImpl(
|
||||
IrConstImpl.boolean(result.startOffset, result.endOffset, context.irBuiltIns.booleanType, true),
|
||||
result
|
||||
)
|
||||
|
||||
fun generateWhenExpression(expression: KtWhenExpression): IrExpression {
|
||||
val irSubject = generateWhenSubject(expression)
|
||||
|
||||
@@ -93,9 +103,9 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
val isExhaustive = expression.isExhaustiveWhen()
|
||||
|
||||
val resultType = when {
|
||||
isUsedAsExpression -> inferredType
|
||||
isExhaustive && KotlinBuiltIns.isNothing(inferredType) -> inferredType
|
||||
else -> context.builtIns.unitType
|
||||
isUsedAsExpression -> inferredType.toIrType()
|
||||
KotlinBuiltIns.isNothing(inferredType) -> inferredType.toIrType()
|
||||
else -> context.irBuiltIns.unitType
|
||||
}
|
||||
|
||||
val irWhen = IrWhenImpl(expression.startOffset, expression.endOffset, resultType, IrStatementOrigin.WHEN)
|
||||
@@ -103,7 +113,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
for (ktEntry in expression.entries) {
|
||||
if (ktEntry.isElse) {
|
||||
val irElseResult = ktEntry.expression!!.genExpr()
|
||||
irWhen.branches.add(IrBranchImpl.elseBranch(irElseResult))
|
||||
irWhen.branches.add(elseBranch(irElseResult))
|
||||
break
|
||||
}
|
||||
|
||||
@@ -141,8 +151,12 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
val isExhaustive = whenExpression.isExhaustiveWhen()
|
||||
|
||||
if (isExhaustive) {
|
||||
val call = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.noWhenBranchMatchedExceptionSymbol)
|
||||
irWhen.branches.add(IrBranchImpl.elseBranch(call))
|
||||
val call = IrCallImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
context.irBuiltIns.nothingType,
|
||||
context.irBuiltIns.noWhenBranchMatchedExceptionSymbol
|
||||
)
|
||||
irWhen.branches.add(elseBranch(call))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,12 +169,12 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
private fun generateWhenBody(expression: KtWhenExpression, irSubject: IrVariable?, irWhen: IrWhen): IrExpression =
|
||||
if (irSubject == null) {
|
||||
if (irWhen.branches.isEmpty())
|
||||
IrBlockImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType, IrStatementOrigin.WHEN)
|
||||
IrBlockImpl(expression.startOffset, expression.endOffset, context.irBuiltIns.unitType, IrStatementOrigin.WHEN)
|
||||
else
|
||||
irWhen
|
||||
} else {
|
||||
if (irWhen.branches.isEmpty()) {
|
||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType, IrStatementOrigin.WHEN)
|
||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, context.irBuiltIns.unitType, IrStatementOrigin.WHEN)
|
||||
irBlock.statements.add(irSubject)
|
||||
irBlock
|
||||
} else {
|
||||
@@ -189,13 +203,13 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
|
||||
private fun generateIsPatternCondition(irSubject: IrVariable, ktCondition: KtWhenConditionIsPattern): IrExpression {
|
||||
val typeOperand = getOrFail(BindingContext.TYPE, ktCondition.typeReference)
|
||||
val typeOperandDescriptor = typeOperand.constructor.declarationDescriptor
|
||||
?: throw AssertionError("No declaration descriptor for type $typeOperand")
|
||||
val typeOperandSymbol = context.symbolTable.referenceClassifier(typeOperandDescriptor)
|
||||
|
||||
val irTypeOperand = typeOperand.toIrType()
|
||||
val typeSymbol = irTypeOperand.classifierOrNull ?: throw AssertionError("Not a classifier type: $typeOperand")
|
||||
return IrTypeOperatorCallImpl(
|
||||
ktCondition.startOffset, ktCondition.endOffset, context.builtIns.booleanType,
|
||||
IrTypeOperator.INSTANCEOF, typeOperand, irSubject.defaultLoad(), typeOperandSymbol
|
||||
ktCondition.startOffset, ktCondition.endOffset,
|
||||
context.irBuiltIns.booleanType,
|
||||
IrTypeOperator.INSTANCEOF, irTypeOperand, typeSymbol,
|
||||
irSubject.defaultLoad()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -210,6 +224,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
||||
IrStatementOrigin.NOT_IN ->
|
||||
IrUnaryPrimitiveImpl(
|
||||
ktCondition.startOffset, ktCondition.endOffset,
|
||||
context.irBuiltIns.booleanType,
|
||||
IrStatementOrigin.EXCL, context.irBuiltIns.booleanNotSymbol,
|
||||
irInCall
|
||||
)
|
||||
|
||||
@@ -19,9 +19,7 @@ package org.jetbrains.kotlin.psi2ir.generators
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
@@ -73,7 +71,8 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
is SyntheticFieldDescriptor -> {
|
||||
val receiver = statementGenerator.generateBackingFieldReceiver(startOffset, endOffset, resolvedCall, descriptor)
|
||||
val field = statementGenerator.context.symbolTable.referenceField(descriptor.propertyDescriptor)
|
||||
IrGetFieldImpl(startOffset, endOffset, field, receiver?.load())
|
||||
val fieldType = descriptor.propertyDescriptor.type.toIrType()
|
||||
IrGetFieldImpl(startOffset, endOffset, field, fieldType, receiver?.load())
|
||||
}
|
||||
is VariableDescriptor ->
|
||||
generateGetVariable(startOffset, endOffset, descriptor, getTypeArguments(resolvedCall), origin)
|
||||
@@ -93,21 +92,29 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
val getterDescriptor = descriptor.getter!!
|
||||
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
|
||||
IrCallImpl(
|
||||
startOffset, endOffset, descriptor.type, getterSymbol, getterDescriptor,
|
||||
typeArguments, origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY
|
||||
)
|
||||
startOffset, endOffset, descriptor.type.toIrType(), getterSymbol, getterDescriptor,
|
||||
origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY
|
||||
).apply {
|
||||
putTypeArguments(typeArguments) { it.toIrType() }
|
||||
}
|
||||
} else
|
||||
IrGetValueImpl(startOffset, endOffset, context.symbolTable.referenceValue(descriptor), origin)
|
||||
IrGetValueImpl(startOffset, endOffset, descriptor.type.toIrType(), 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, call.typeArguments)
|
||||
irCall.dispatchReceiver = dispatchReceiver?.load()
|
||||
irCall.extensionReceiver = extensionReceiver?.load()
|
||||
val irCall = IrDelegatingConstructorCallImpl(
|
||||
startOffset, endOffset,
|
||||
context.irBuiltIns.unitType,
|
||||
constructorSymbol,
|
||||
descriptor
|
||||
).apply {
|
||||
putTypeArguments(call.typeArguments) { it.toIrType() }
|
||||
this.dispatchReceiver = dispatchReceiver?.load()
|
||||
this.extensionReceiver = extensionReceiver?.load()
|
||||
}
|
||||
addParametersToCall(startOffset, endOffset, call, irCall, descriptor.builtIns.unitType)
|
||||
}
|
||||
|
||||
@@ -121,11 +128,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
if (dispatchReceiver != null) throw AssertionError("Dispatch receiver should be null: $dispatchReceiver")
|
||||
if (extensionReceiver != null) throw AssertionError("Extension receiver should be null: $extensionReceiver")
|
||||
val constructorSymbol = context.symbolTable.referenceConstructor(constructorDescriptor.original)
|
||||
val irCall = IrEnumConstructorCallImpl(
|
||||
startOffset, endOffset,
|
||||
constructorSymbol,
|
||||
call.typeArguments
|
||||
)
|
||||
val irCall = IrEnumConstructorCallImpl(startOffset, endOffset, constructorDescriptor.returnType.toIrType(), constructorSymbol)
|
||||
addParametersToCall(startOffset, endOffset, call, irCall, constructorDescriptor.returnType)
|
||||
}
|
||||
}
|
||||
@@ -144,19 +147,24 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
|
||||
IrGetterCallImpl(
|
||||
startOffset, endOffset,
|
||||
descriptor.type.toIrType(),
|
||||
getterSymbol,
|
||||
getterDescriptor,
|
||||
call.typeArguments,
|
||||
descriptor.typeParametersCount,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
IrStatementOrigin.GET_PROPERTY,
|
||||
superQualifierSymbol
|
||||
)
|
||||
).apply {
|
||||
putTypeArguments(call.typeArguments) { it.toIrType() }
|
||||
}
|
||||
|
||||
} else {
|
||||
val fieldSymbol = context.symbolTable.referenceField(descriptor.original)
|
||||
IrGetFieldImpl(
|
||||
startOffset, endOffset,
|
||||
fieldSymbol,
|
||||
descriptor.type.toIrType(),
|
||||
dispatchReceiverValue?.load(),
|
||||
IrStatementOrigin.GET_PROPERTY,
|
||||
superQualifierSymbol
|
||||
@@ -178,16 +186,16 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
val superQualifierSymbol = call.superQualifier?.let { context.symbolTable.referenceClass(it) }
|
||||
val irCall = IrCallImpl(
|
||||
startOffset, endOffset,
|
||||
returnType,
|
||||
returnType.toIrType(),
|
||||
functionSymbol,
|
||||
functionDescriptor,
|
||||
call.typeArguments,
|
||||
origin,
|
||||
superQualifierSymbol
|
||||
)
|
||||
irCall.dispatchReceiver = dispatchReceiverValue?.load()
|
||||
irCall.extensionReceiver = extensionReceiverValue?.load()
|
||||
|
||||
).apply {
|
||||
putTypeArguments(call.typeArguments) { it.toIrType() }
|
||||
this.dispatchReceiver = dispatchReceiverValue?.load()
|
||||
this.extensionReceiver = extensionReceiverValue?.load()
|
||||
}
|
||||
addParametersToCall(startOffset, endOffset, call, irCall, returnType)
|
||||
}
|
||||
|
||||
@@ -220,7 +228,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
val valueArgumentsInEvaluationOrder = resolvedCall.valueArguments.values
|
||||
val valueParameters = resolvedCall.resultingDescriptor.valueParameters
|
||||
|
||||
val irBlock = IrBlockImpl(startOffset, endOffset, resultType, IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL)
|
||||
val irBlock = IrBlockImpl(startOffset, endOffset, resultType.toIrType(), IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL)
|
||||
|
||||
val valueArgumentsToValueParameters = HashMap<ResolvedValueArgument, ValueParameterDescriptor>()
|
||||
for ((index, valueArgument) in resolvedCall.valueArgumentsByIndex!!.withIndex()) {
|
||||
@@ -233,7 +241,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
for (valueArgument in valueArgumentsInEvaluationOrder) {
|
||||
val valueParameter = valueArgumentsToValueParameters[valueArgument]!!
|
||||
val irArgument = call.getValueArgument(valueParameter) ?: continue
|
||||
val irArgumentValue = scope.createTemporaryVariableInBlock(irArgument, irBlock, valueParameter.name.asString())
|
||||
val irArgumentValue = scope.createTemporaryVariableInBlock(context, irArgument, irBlock, valueParameter.name.asString())
|
||||
irArgumentValues[valueParameter] = irArgumentValue
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.substitute
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -24,44 +23,50 @@ 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.expressions.putTypeArguments
|
||||
import org.jetbrains.kotlin.ir.expressions.typeParametersCount
|
||||
import org.jetbrains.kotlin.ir.util.StableDescriptorsComparator
|
||||
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
|
||||
import org.jetbrains.kotlin.ir.util.isEnumClass
|
||||
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.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize
|
||||
import java.lang.AssertionError
|
||||
|
||||
class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
|
||||
class ClassGenerator(
|
||||
declarationGenerator: DeclarationGenerator
|
||||
) : DeclarationGeneratorExtension(declarationGenerator) {
|
||||
|
||||
fun generateClass(ktClassOrObject: KtClassOrObject): IrClass {
|
||||
val descriptor = getOrFail(BindingContext.CLASS, ktClassOrObject)
|
||||
val classDescriptor = getOrFail(BindingContext.CLASS, ktClassOrObject)
|
||||
val startOffset = ktClassOrObject.startOffset
|
||||
val endOffset = ktClassOrObject.endOffset
|
||||
|
||||
return context.symbolTable.declareClass(
|
||||
startOffset, endOffset, IrDeclarationOrigin.DEFINED, descriptor
|
||||
startOffset, endOffset, IrDeclarationOrigin.DEFINED, classDescriptor
|
||||
).buildWithScope { irClass ->
|
||||
descriptor.typeConstructor.supertypes.mapNotNullTo(irClass.superClasses) {
|
||||
it.constructor.declarationDescriptor?.safeAs<ClassDescriptor>()?.let {
|
||||
context.symbolTable.referenceClass(it)
|
||||
}
|
||||
declarationGenerator.generateGlobalTypeParametersDeclarations(irClass, classDescriptor.declaredTypeParameters)
|
||||
|
||||
classDescriptor.typeConstructor.supertypes.mapTo(irClass.superTypes) {
|
||||
it.toIrType()
|
||||
}
|
||||
|
||||
irClass.thisReceiver = context.symbolTable.declareValueParameter(
|
||||
startOffset, endOffset,
|
||||
IrDeclarationOrigin.INSTANCE_RECEIVER,
|
||||
irClass.descriptor.thisAsReceiverParameter
|
||||
classDescriptor.thisAsReceiverParameter,
|
||||
classDescriptor.thisAsReceiverParameter.type.toIrType()
|
||||
)
|
||||
|
||||
declarationGenerator.generateGlobalTypeParametersDeclarations(irClass, descriptor.declaredTypeParameters)
|
||||
|
||||
val irPrimaryConstructor = generatePrimaryConstructor(irClass, ktClassOrObject)
|
||||
if (irPrimaryConstructor != null) {
|
||||
generateDeclarationsForPrimaryConstructorParameters(irClass, irPrimaryConstructor, ktClassOrObject)
|
||||
@@ -77,7 +82,7 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
generateAdditionalMembersForDataClass(irClass, ktClassOrObject)
|
||||
}
|
||||
|
||||
if (irClass.isEnumClass) {
|
||||
if (DescriptorUtils.isEnumClass(classDescriptor)) {
|
||||
generateAdditionalMembersForEnumClass(irClass)
|
||||
}
|
||||
}
|
||||
@@ -127,7 +132,7 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
val irDelegateField = context.symbolTable.declareField(
|
||||
ktDelegateExpression.startOffset, ktDelegateExpression.endOffset,
|
||||
IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor,
|
||||
delegateDescriptor, delegateDescriptor.type.toIrType(),
|
||||
createBodyGenerator(irClass.symbol).generateExpressionBody(ktDelegateExpression)
|
||||
)
|
||||
irClass.addMember(irDelegateField)
|
||||
@@ -166,18 +171,21 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
|
||||
private fun generateDelegatedProperty(
|
||||
irDelegate: IrField,
|
||||
delegated: PropertyDescriptor,
|
||||
overridden: PropertyDescriptor
|
||||
delegatedDescriptor: PropertyDescriptor,
|
||||
overriddenDescriptor: PropertyDescriptor
|
||||
): IrPropertyImpl {
|
||||
val startOffset = irDelegate.startOffset
|
||||
val endOffset = irDelegate.endOffset
|
||||
|
||||
val irProperty = IrPropertyImpl(startOffset, endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, false, delegated)
|
||||
val irProperty = IrPropertyImpl(
|
||||
startOffset, endOffset, IrDeclarationOrigin.DELEGATED_MEMBER,
|
||||
false, delegatedDescriptor
|
||||
)
|
||||
|
||||
irProperty.getter = generateDelegatedFunction(irDelegate, delegated.getter!!, overridden.getter!!)
|
||||
irProperty.getter = generateDelegatedFunction(irDelegate, delegatedDescriptor.getter!!, overriddenDescriptor.getter!!)
|
||||
|
||||
if (delegated.isVar) {
|
||||
irProperty.setter = generateDelegatedFunction(irDelegate, delegated.setter!!, overridden.setter!!)
|
||||
if (delegatedDescriptor.isVar) {
|
||||
irProperty.setter = generateDelegatedFunction(irDelegate, delegatedDescriptor.setter!!, overriddenDescriptor.setter!!)
|
||||
}
|
||||
return irProperty
|
||||
}
|
||||
@@ -202,6 +210,10 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
delegated
|
||||
).buildWithScope { irFunction ->
|
||||
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irFunction)
|
||||
|
||||
// TODO could possibly refer to scoped type parameters for property accessors
|
||||
irFunction.returnType = delegated.returnType!!.toIrType()
|
||||
|
||||
irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden, irFunction)
|
||||
}
|
||||
|
||||
@@ -216,30 +228,42 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
val irBlockBody = IrBlockBodyImpl(startOffset, endOffset)
|
||||
val substitutedOverridden = substituteOverriddenDescriptorForDelegate(delegated, overridden)
|
||||
val returnType = substitutedOverridden.returnType!!
|
||||
val irReturnType = returnType.toIrType()
|
||||
val irCall = IrCallImpl(
|
||||
startOffset, endOffset, returnType,
|
||||
startOffset, endOffset, irReturnType,
|
||||
context.symbolTable.referenceFunction(overridden.original),
|
||||
substitutedOverridden,
|
||||
getTypeArgumentsForOverriddenDescriptorDelegatingCall(delegated, overridden)
|
||||
)
|
||||
substitutedOverridden.typeParametersCount
|
||||
).apply {
|
||||
val typeArguments = getTypeArgumentsForOverriddenDescriptorDelegatingCall(delegated, overridden)
|
||||
putTypeArguments(typeArguments) { it.toIrType() }
|
||||
}
|
||||
val dispatchReceiverParameter = irDelegatedFunction.dispatchReceiverParameter!!
|
||||
val dispatchReceiverType = dispatchReceiverParameter.type
|
||||
irCall.dispatchReceiver =
|
||||
IrGetFieldImpl(
|
||||
startOffset, endOffset, irDelegate.symbol,
|
||||
IrGetValueImpl(startOffset, endOffset, irDelegatedFunction.dispatchReceiverParameter!!.symbol)
|
||||
startOffset, endOffset,
|
||||
irDelegate.symbol,
|
||||
irDelegate.type,
|
||||
IrGetValueImpl(
|
||||
startOffset, endOffset,
|
||||
dispatchReceiverType,
|
||||
dispatchReceiverParameter.symbol
|
||||
)
|
||||
)
|
||||
irCall.extensionReceiver =
|
||||
irDelegatedFunction.extensionReceiverParameter?.let { extensionReceiver ->
|
||||
IrGetValueImpl(startOffset, endOffset, extensionReceiver.symbol)
|
||||
IrGetValueImpl(startOffset, endOffset, extensionReceiver.type, extensionReceiver.symbol)
|
||||
}
|
||||
irCall.mapValueParameters { overriddenValueParameter ->
|
||||
val delegatedValueParameter = delegated.valueParameters[overriddenValueParameter.index]
|
||||
val irDelegatedValueParameter = irDelegatedFunction.getIrValueParameter(delegatedValueParameter)
|
||||
IrGetValueImpl(startOffset, endOffset, irDelegatedValueParameter.symbol)
|
||||
IrGetValueImpl(startOffset, endOffset, irDelegatedValueParameter.type, irDelegatedValueParameter.symbol)
|
||||
}
|
||||
if (KotlinBuiltIns.isUnit(returnType) || KotlinBuiltIns.isNothing(returnType)) {
|
||||
irBlockBody.statements.add(irCall)
|
||||
} else {
|
||||
val irReturn = IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, irDelegatedFunction.symbol, irCall)
|
||||
val irReturn = IrReturnImpl(startOffset, endOffset, context.irBuiltIns.nothingType, irDelegatedFunction.symbol, irCall)
|
||||
irBlockBody.statements.add(irReturn)
|
||||
}
|
||||
return irBlockBody
|
||||
@@ -253,8 +277,14 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
return if (overridden is PropertyAccessorDescriptor)
|
||||
overridden
|
||||
else {
|
||||
val typeArguments = zipTypeParametersToDefaultTypes(overridden, delegated)
|
||||
overridden.substitute(typeArguments)
|
||||
val substitutor =
|
||||
TypeSubstitutor.create(
|
||||
overridden.original.typeParameters.associate {
|
||||
val delegatedDefaultType = delegated.typeParameters[it.index].defaultType
|
||||
it.typeConstructor to TypeProjectionImpl(delegatedDefaultType)
|
||||
}
|
||||
)
|
||||
overridden.substitute(substitutor)!!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.putDefault
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.mapTypeParameters
|
||||
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
|
||||
@@ -43,13 +44,21 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import java.lang.AssertionError
|
||||
|
||||
class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
|
||||
class DataClassMembersGenerator(
|
||||
declarationGenerator: DeclarationGenerator
|
||||
) : DeclarationGeneratorExtension(declarationGenerator) {
|
||||
|
||||
fun generate(ktClassOrObject: KtClassOrObject, irClass: IrClass) {
|
||||
MyDataClassMethodGenerator(ktClassOrObject, irClass).generate()
|
||||
}
|
||||
|
||||
private fun declareSimpleFunction(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, function: FunctionDescriptor) =
|
||||
context.symbolTable.declareSimpleFunctionWithOverrides(startOffset, endOffset, origin, function)
|
||||
context.symbolTable.declareSimpleFunctionWithOverrides(
|
||||
startOffset, endOffset, origin,
|
||||
function
|
||||
).apply {
|
||||
returnType = function.returnType!!.toIrType()
|
||||
}
|
||||
|
||||
private inner class MemberFunctionBuilder(
|
||||
val irClass: IrClass,
|
||||
@@ -73,11 +82,23 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
irFunction.putDefault(parameter, irExprBody(value))
|
||||
}
|
||||
|
||||
fun irThis(): IrExpression =
|
||||
IrGetValueImpl(startOffset, endOffset, irFunction.dispatchReceiverParameter!!.symbol)
|
||||
fun irThis(): IrExpression {
|
||||
val irDispatchReceiverParameter = irFunction.dispatchReceiverParameter!!
|
||||
return IrGetValueImpl(
|
||||
startOffset, endOffset,
|
||||
irDispatchReceiverParameter.type,
|
||||
irDispatchReceiverParameter.symbol
|
||||
)
|
||||
}
|
||||
|
||||
fun irOther(): IrExpression =
|
||||
IrGetValueImpl(startOffset, endOffset, irFunction.valueParameters[0].symbol)
|
||||
fun irOther(): IrExpression {
|
||||
val irFirstParameter = irFunction.valueParameters[0]
|
||||
return IrGetValueImpl(
|
||||
startOffset, endOffset,
|
||||
irFirstParameter.type,
|
||||
irFirstParameter.symbol
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class MyDataClassMethodGenerator(
|
||||
@@ -105,7 +126,7 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
?: throw AssertionError("No definition for data class constructor parameter $parameter")
|
||||
|
||||
buildMember(function, ktParameter) {
|
||||
+irReturn(irGet(irThis(), getPropertyGetterSymbol(parameter)))
|
||||
+irReturn(irGet(function.returnType!!.toIrType(), irThis(), getPropertyGetterSymbol(parameter)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,15 +145,18 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
|
||||
buildMember(function, declaration) { irFunction ->
|
||||
function.valueParameters.forEach { parameter ->
|
||||
putDefault(parameter, irGet(irThis(), getPropertyGetterSymbol(parameter)))
|
||||
putDefault(parameter, irGet(parameter.type.toIrType(), irThis(), getPropertyGetterSymbol(parameter)))
|
||||
}
|
||||
+irReturn(
|
||||
irCall(
|
||||
constructorSymbol,
|
||||
dataClassConstructor.returnType,
|
||||
dataClassConstructor.typeParameters.associate { it to it.defaultType }
|
||||
).mapValueParameters {
|
||||
irGet(irFunction.valueParameters[it.index].symbol)
|
||||
dataClassConstructor.returnType.toIrType()
|
||||
).apply {
|
||||
mapTypeParameters { it.defaultType.toIrType() }
|
||||
mapValueParameters {
|
||||
val irValueParameter = irFunction.valueParameters[it.index]
|
||||
irGet(irValueParameter.type, irValueParameter.symbol)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -140,12 +164,15 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
|
||||
override fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||
buildMember(function, declaration) {
|
||||
val irType = classDescriptor.defaultType.toIrType()
|
||||
|
||||
+irIfThenReturnTrue(irEqeqeq(irThis(), irOther()))
|
||||
+irIfThenReturnFalse(irNotIs(irOther(), classDescriptor.defaultType, irClass.symbol))
|
||||
val otherWithCast = irTemporary(irImplicitCast(irOther(), classDescriptor.defaultType, irClass.symbol), "other_with_cast")
|
||||
+irIfThenReturnFalse(irNotIs(irOther(), irType))
|
||||
val otherWithCast = irTemporary(irAs(irOther(), irType), "other_with_cast")
|
||||
for (property in properties) {
|
||||
val arg1 = irGet(irThis(), getPropertyGetterSymbol(property))
|
||||
val arg2 = irGet(irGet(otherWithCast.symbol), getPropertyGetterSymbol(property))
|
||||
val irPropertyType = property.type.toIrType()
|
||||
val arg1 = irGet(irPropertyType, irThis(), getPropertyGetterSymbol(property))
|
||||
val arg2 = irGet(irPropertyType, irGet(irType, otherWithCast.symbol), getPropertyGetterSymbol(property))
|
||||
+irIfThenReturnFalse(irNotEquals(arg1, arg2))
|
||||
}
|
||||
+irReturnTrue()
|
||||
@@ -184,36 +211,60 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
|
||||
override fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||
buildMember(function, declaration) {
|
||||
val irIntType = context.irBuiltIns.intType
|
||||
val result = irTemporaryVar(irInt(0), "result").symbol
|
||||
var first = true
|
||||
for (property in properties) {
|
||||
val hashCodeOfProperty = getHashCodeOfProperty(irThis(), property)
|
||||
val irNewValue =
|
||||
if (first) hashCodeOfProperty
|
||||
else irCallOp(intPlus, irCallOp(intTimes, irGet(result), irInt(31)), hashCodeOfProperty)
|
||||
else
|
||||
irCallOp(
|
||||
intPlus,
|
||||
irIntType,
|
||||
irCallOp(
|
||||
intTimes, irIntType, irGet(irIntType, result), irInt(31)
|
||||
),
|
||||
hashCodeOfProperty
|
||||
)
|
||||
+irSetVar(result, irNewValue)
|
||||
first = false
|
||||
}
|
||||
+irReturn(irGet(result))
|
||||
+irReturn(irGet(irIntType, result))
|
||||
}
|
||||
}
|
||||
|
||||
private fun MemberFunctionBuilder.getHashCodeOfProperty(receiver: IrExpression, property: PropertyDescriptor): IrExpression {
|
||||
val getterSymbol = getPropertyGetterSymbol(property)
|
||||
val propertyType = property.type
|
||||
val irPropertyType = propertyType.toIrType()
|
||||
return when {
|
||||
property.type.containsNull() ->
|
||||
irLetS(irGet(receiver, getterSymbol)) { variable ->
|
||||
irIfNull(context.builtIns.intType, irGet(variable), irInt(0), getHashCodeOf(irGet(variable)))
|
||||
propertyType.containsNull() ->
|
||||
irLetS(
|
||||
irGet(irPropertyType, receiver, getterSymbol)
|
||||
) { variable ->
|
||||
irIfNull(
|
||||
context.irBuiltIns.intType,
|
||||
irGet(irPropertyType, variable),
|
||||
irInt(0),
|
||||
getHashCodeOf(
|
||||
propertyType,
|
||||
irGet(irPropertyType, variable)
|
||||
)
|
||||
)
|
||||
}
|
||||
else ->
|
||||
getHashCodeOf(irGet(receiver, getterSymbol))
|
||||
getHashCodeOf(
|
||||
propertyType,
|
||||
irGet(irPropertyType, receiver, getterSymbol)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MemberFunctionBuilder.getHashCodeOf(irValue: IrExpression): IrExpression {
|
||||
val hashCodeFunctionDescriptor = getHashCodeFunction(irValue.type)
|
||||
private fun MemberFunctionBuilder.getHashCodeOf(kotlinType: KotlinType, irValue: IrExpression): IrExpression {
|
||||
val hashCodeFunctionDescriptor = getHashCodeFunction(kotlinType)
|
||||
val hashCodeFunctionSymbol = declarationGenerator.context.symbolTable.referenceFunction(hashCodeFunctionDescriptor.original)
|
||||
return irCall(hashCodeFunctionSymbol, hashCodeFunctionDescriptor).apply {
|
||||
return irCall(hashCodeFunctionSymbol, hashCodeFunctionDescriptor, context.irBuiltIns.intType).apply {
|
||||
if (descriptor.dispatchReceiverParameter != null) {
|
||||
dispatchReceiver = irValue
|
||||
} else {
|
||||
@@ -228,19 +279,25 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
irConcat.addArgument(irString(classDescriptor.name.asString() + "("))
|
||||
var first = true
|
||||
for (property in properties) {
|
||||
val irPropertyType = property.type.toIrType()
|
||||
|
||||
if (!first) irConcat.addArgument(irString(", "))
|
||||
|
||||
irConcat.addArgument(irString(property.name.asString() + "="))
|
||||
val irPropertyValue = irGet(irThis(), getPropertyGetterSymbol(property))
|
||||
|
||||
val irPropertyValue = irGet(irPropertyType, irThis(), getPropertyGetterSymbol(property))
|
||||
|
||||
val typeConstructorDescriptor = property.type.constructor.declarationDescriptor
|
||||
val irPropertyStringValue =
|
||||
if (typeConstructorDescriptor is ClassDescriptor &&
|
||||
KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor)
|
||||
)
|
||||
irCall(context.irBuiltIns.dataClassArrayMemberToStringSymbol).apply {
|
||||
irCall(context.irBuiltIns.dataClassArrayMemberToStringSymbol, context.irBuiltIns.stringType).apply {
|
||||
putValueArgument(0, irPropertyValue)
|
||||
}
|
||||
else
|
||||
irPropertyValue
|
||||
|
||||
irConcat.addArgument(irPropertyStringValue)
|
||||
first = false
|
||||
}
|
||||
|
||||
@@ -31,8 +31,14 @@ import org.jetbrains.kotlin.psi2ir.endOffsetOrUndefined
|
||||
import org.jetbrains.kotlin.psi2ir.startOffsetOrUndefined
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
|
||||
private val typeTranslator = context.typeTranslator
|
||||
|
||||
fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||
|
||||
fun generateMemberDeclaration(ktDeclaration: KtDeclaration): IrDeclaration =
|
||||
when (ktDeclaration) {
|
||||
is KtNamedFunction ->
|
||||
@@ -108,7 +114,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
from: List<TypeParameterDescriptor>,
|
||||
declareTypeParameter: (Int, Int, TypeParameterDescriptor) -> IrTypeParameter
|
||||
) {
|
||||
val irTypeParameters = from.map { typeParameterDescriptor ->
|
||||
from.mapTo(irTypeParametersOwner.typeParameters) { typeParameterDescriptor ->
|
||||
val ktTypeParameterDeclaration = DescriptorToSourceUtils.getSourceFromDescriptor(typeParameterDescriptor)
|
||||
val startOffset = ktTypeParameterDeclaration.startOffsetOrUndefined
|
||||
val endOffset = ktTypeParameterDeclaration.endOffsetOrUndefined
|
||||
@@ -119,20 +125,9 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
)
|
||||
}
|
||||
|
||||
irTypeParameters.forEach {
|
||||
mapSuperClassifiers(it.descriptor, it)
|
||||
}
|
||||
|
||||
irTypeParametersOwner.typeParameters.addAll(irTypeParameters)
|
||||
}
|
||||
|
||||
private fun mapSuperClassifiers(
|
||||
descriptor: TypeParameterDescriptor,
|
||||
irTypeParameter: IrTypeParameter
|
||||
) {
|
||||
descriptor.typeConstructor.supertypes.mapNotNullTo(irTypeParameter.superClassifiers) {
|
||||
it.constructor.declarationDescriptor?.let {
|
||||
context.symbolTable.referenceClassifier(it)
|
||||
for (irTypeParameter in irTypeParametersOwner.typeParameters) {
|
||||
irTypeParameter.descriptor.upperBounds.mapTo(irTypeParameter.superTypes) {
|
||||
it.toIrType()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,21 +149,29 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateFakeOverrideProperty(propertyDescriptor: PropertyDescriptor, ktElement: KtElement): IrProperty =
|
||||
IrPropertyImpl(
|
||||
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined,
|
||||
private fun generateFakeOverrideProperty(propertyDescriptor: PropertyDescriptor, ktElement: KtElement): IrProperty {
|
||||
val startOffset = ktElement.startOffset
|
||||
val endOffset = ktElement.endOffset
|
||||
|
||||
val backingField =
|
||||
if (propertyDescriptor.getter == null)
|
||||
context.symbolTable.declareField(
|
||||
startOffset, endOffset, IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
propertyDescriptor, propertyDescriptor.type.toIrType()
|
||||
)
|
||||
else
|
||||
null
|
||||
|
||||
return IrPropertyImpl(
|
||||
startOffset, endOffset,
|
||||
IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
false,
|
||||
propertyDescriptor,
|
||||
if (propertyDescriptor.getter == null)
|
||||
context.symbolTable.declareField(
|
||||
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
propertyDescriptor
|
||||
)
|
||||
else null,
|
||||
backingField,
|
||||
propertyDescriptor.getter?.let { generateFakeOverrideFunction(it, ktElement) },
|
||||
propertyDescriptor.setter?.let { generateFakeOverrideFunction(it, ktElement) }
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtElement): IrSimpleFunction =
|
||||
FunctionGenerator(this).generateFakeOverrideFunction(functionDescriptor, ktElement)
|
||||
@@ -183,6 +186,8 @@ abstract class DeclarationGeneratorExtension(val declarationGenerator: Declarati
|
||||
builder(irDeclaration)
|
||||
}
|
||||
}
|
||||
|
||||
fun KotlinType.toIrType() = with(declarationGenerator) { toIrType() }
|
||||
}
|
||||
|
||||
fun Generator.createBodyGenerator(scopeOwnerSymbol: IrSymbol) =
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.ir.builders.irBlockBody
|
||||
import org.jetbrains.kotlin.ir.builders.irGet
|
||||
import org.jetbrains.kotlin.ir.builders.irReturn
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -55,8 +56,9 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
val kPropertyType = getKPropertyTypeForDelegatedProperty(propertyDescriptor)
|
||||
|
||||
val irProperty = IrPropertyImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED, true,
|
||||
propertyDescriptor
|
||||
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
isDelegated = true,
|
||||
descriptor = propertyDescriptor
|
||||
).apply {
|
||||
backingField = generateDelegateFieldForProperty(propertyDescriptor, kPropertyType, ktDelegate)
|
||||
}
|
||||
@@ -99,7 +101,7 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
|
||||
accessorDescriptor
|
||||
).buildWithScope { irAccessor ->
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irAccessor, ktProperty, null)
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarationsAndReturnType(irAccessor, ktProperty, null)
|
||||
irAccessor.body = generateBody(irAccessor)
|
||||
}
|
||||
|
||||
@@ -124,7 +126,7 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
|
||||
return context.symbolTable.declareField(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor
|
||||
delegateDescriptor, delegateDescriptor.type.toIrType()
|
||||
).also { irDelegate ->
|
||||
irDelegate.initializer = generateInitializerBodyForPropertyDelegate(
|
||||
propertyDescriptor, kPropertyType, ktDelegate,
|
||||
@@ -161,8 +163,9 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
): IntermediateValue {
|
||||
val thisValue = createThisValueForDelegate(thisClass, ktDelegate)
|
||||
return BackingFieldLValue(
|
||||
context,
|
||||
ktDelegate.startOffset, ktDelegate.endOffset,
|
||||
irDelegateField.descriptor.type,
|
||||
irDelegateField.descriptor.type.toIrType(),
|
||||
irDelegateField,
|
||||
thisValue,
|
||||
null
|
||||
@@ -171,10 +174,12 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
|
||||
private fun createThisValueForDelegate(thisClass: ClassDescriptor?, ktDelegate: KtPropertyDelegate): IntermediateValue? =
|
||||
thisClass?.let {
|
||||
generateExpressionValue(it.thisAsReceiverParameter.type) {
|
||||
generateExpressionValue(it.thisAsReceiverParameter.type.toIrType()) {
|
||||
val thisAsReceiverParameter = thisClass.thisAsReceiverParameter
|
||||
IrGetValueImpl(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset,
|
||||
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter)
|
||||
thisAsReceiverParameter.type.toIrType(),
|
||||
context.symbolTable.referenceValueParameter(thisAsReceiverParameter)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -225,7 +230,8 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
|
||||
val irLocalDelegatedProperty = IrLocalDelegatedPropertyImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
variableDescriptor
|
||||
variableDescriptor,
|
||||
variableDescriptor.type.toIrType()
|
||||
).apply {
|
||||
delegate = generateDelegateVariableForLocalDelegatedProperty(ktDelegate, variableDescriptor, kPropertyType, scopeOwnerSymbol)
|
||||
}
|
||||
@@ -275,7 +281,7 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
|
||||
return context.symbolTable.declareVariable(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor
|
||||
delegateDescriptor, delegateDescriptor.type.toIrType()
|
||||
).also { irVariable ->
|
||||
irVariable.initializer = generateInitializerForLocalDelegatedPropertyDelegate(
|
||||
variableDescriptor, kPropertyType, ktDelegate,
|
||||
@@ -321,7 +327,7 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
}
|
||||
|
||||
private fun createVariableValueForDelegate(irDelegate: IrVariableSymbol, ktDelegate: KtPropertyDelegate) =
|
||||
VariableLValue(ktDelegate.startOffset, ktDelegate.endOffset, irDelegate)
|
||||
VariableLValue(context, ktDelegate.startOffset, ktDelegate.endOffset, irDelegate, irDelegate.descriptor.type.toIrType())
|
||||
|
||||
private inline fun createLocalPropertyAccessor(
|
||||
getterDescriptor: VariableAccessorDescriptor,
|
||||
@@ -333,7 +339,7 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
|
||||
getterDescriptor
|
||||
).buildWithScope { irAccessor ->
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irAccessor, ktDelegate, null)
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarationsAndReturnType(irAccessor, ktDelegate, null)
|
||||
irAccessor.body = generateBody(irAccessor)
|
||||
}
|
||||
|
||||
@@ -363,7 +369,9 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
irPropertyReference: IrCallableReference
|
||||
): IrBody =
|
||||
with(createBodyGenerator(irGetter.symbol)) {
|
||||
irBlockBody(ktDelegate) {
|
||||
val startOffset = ktDelegate.startOffset
|
||||
val endOffset = ktDelegate.endOffset
|
||||
irBlockBody(startOffset, endOffset) {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor)
|
||||
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
||||
@@ -371,8 +379,8 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
|
||||
+irReturn(
|
||||
CallGenerator(statementGenerator).generateCall(
|
||||
ktDelegate.startOffset,
|
||||
ktDelegate.endOffset,
|
||||
startOffset,
|
||||
endOffset,
|
||||
conventionMethodCall
|
||||
)
|
||||
)
|
||||
@@ -386,14 +394,17 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
||||
delegateReceiverValue: IntermediateValue,
|
||||
irPropertyReference: IrCallableReference
|
||||
): IrBody = with(createBodyGenerator(irSetter.symbol)) {
|
||||
irBlockBody(ktDelegate) {
|
||||
val startOffset = ktDelegate.startOffset
|
||||
val endOffset = ktDelegate.endOffset
|
||||
irBlockBody(startOffset, endOffset) {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, setterDescriptor)
|
||||
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
||||
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
|
||||
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
|
||||
conventionMethodCall.irValueArgumentsByIndex[2] = irGet(irSetter.valueParameters[0].symbol)
|
||||
+irReturn(CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, conventionMethodCall))
|
||||
val irSetterParameter = irSetter.valueParameters[0]
|
||||
conventionMethodCall.irValueArgumentsByIndex[2] = irGet(irSetterParameter.type, irSetterParameter.symbol)
|
||||
+irReturn(CallGenerator(statementGenerator).generateCall(startOffset, endOffset, conventionMethodCall))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ class EnumClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER,
|
||||
valuesFunction
|
||||
).also { irFunction ->
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irFunction, null, null)
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarationsAndReturnType(irFunction, null, null)
|
||||
irFunction.body = IrSyntheticBodyImpl(irClass.startOffset, irClass.endOffset, IrSyntheticBodyKind.ENUM_VALUES)
|
||||
}
|
||||
)
|
||||
@@ -63,7 +63,7 @@ class EnumClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER,
|
||||
valueOfFunction
|
||||
).also { irFunction ->
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irFunction, null, null)
|
||||
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarationsAndReturnType(irFunction, null, null)
|
||||
irFunction.body = IrSyntheticBodyImpl(irClass.startOffset, irClass.endOffset, IrSyntheticBodyKind.ENUM_VALUEOF)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -35,15 +35,20 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
|
||||
|
||||
fun generateErrorExpression(ktElement: KtElement, e: Exception): IrExpression =
|
||||
generateErrorExpression(ktElement, e) {
|
||||
val errorExpressionType =
|
||||
if (ktElement is KtExpression)
|
||||
getErrorExpressionType(ktElement)
|
||||
else
|
||||
ErrorUtils.createErrorType("")
|
||||
IrErrorExpressionImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
if (ktElement is KtExpression) getErrorExpressionType(ktElement) else ErrorUtils.createErrorType(""),
|
||||
errorExpressionType.toIrType(),
|
||||
e.message ?: ""
|
||||
)
|
||||
}
|
||||
|
||||
fun generateErrorCall(ktCall: KtCallExpression): IrExpression = generateErrorExpression(ktCall) {
|
||||
val type = getErrorExpressionType(ktCall)
|
||||
val type = getErrorExpressionType(ktCall).toIrType()
|
||||
|
||||
val irErrorCall = IrErrorCallExpressionImpl(ktCall.startOffset, ktCall.endOffset, type, "") // TODO problem description?
|
||||
irErrorCall.explicitReceiver = (ktCall.parent as? KtDotQualifiedExpression)?.run {
|
||||
@@ -64,7 +69,7 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
|
||||
getInferredTypeWithImplicitCasts(ktExpression) ?: ErrorUtils.createErrorType("")
|
||||
|
||||
fun generateErrorSimpleName(ktName: KtSimpleNameExpression): IrExpression = generateErrorExpression(ktName) {
|
||||
val type = getErrorExpressionType(ktName)
|
||||
val type = getErrorExpressionType(ktName).toIrType()
|
||||
|
||||
val irErrorCall = IrErrorCallExpressionImpl(ktName.startOffset, ktName.endOffset, type, "") // TODO problem description?
|
||||
irErrorCall.explicitReceiver = (ktName.parent as? KtDotQualifiedExpression)?.let { ktParent ->
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.psi2ir.startOffsetOrUndefined
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor
|
||||
|
||||
class FunctionGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
|
||||
|
||||
@@ -58,12 +59,8 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
}
|
||||
|
||||
fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtElement): IrSimpleFunction =
|
||||
context.symbolTable.declareSimpleFunctionWithOverrides(
|
||||
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
functionDescriptor
|
||||
).buildWithScope { irFunction ->
|
||||
generateFunctionParameterDeclarations(irFunction, ktElement, null)
|
||||
declareSimpleFunctionInner(functionDescriptor, ktElement, IrDeclarationOrigin.FAKE_OVERRIDE).buildWithScope { irFunction ->
|
||||
generateFunctionParameterDeclarationsAndReturnType(irFunction, ktElement, null)
|
||||
}
|
||||
|
||||
private inline fun declareSimpleFunction(
|
||||
@@ -73,19 +70,28 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
descriptor: FunctionDescriptor,
|
||||
generateBody: BodyGenerator.() -> IrBody?
|
||||
): IrSimpleFunction =
|
||||
context.symbolTable.declareSimpleFunctionWithOverrides(
|
||||
ktFunction.startOffset, ktFunction.endOffset, origin, descriptor
|
||||
).buildWithScope { irFunction ->
|
||||
generateFunctionParameterDeclarations(irFunction, ktFunction, ktReceiver)
|
||||
declareSimpleFunctionInner(descriptor, ktFunction, origin).buildWithScope { irFunction ->
|
||||
generateFunctionParameterDeclarationsAndReturnType(irFunction, ktFunction, ktReceiver)
|
||||
irFunction.body = createBodyGenerator(irFunction.symbol).generateBody()
|
||||
}
|
||||
|
||||
fun generateFunctionParameterDeclarations(
|
||||
private fun declareSimpleFunctionInner(
|
||||
descriptor: FunctionDescriptor,
|
||||
ktElement: KtElement,
|
||||
origin: IrDeclarationOrigin
|
||||
): IrSimpleFunction =
|
||||
context.symbolTable.declareSimpleFunctionWithOverrides(
|
||||
ktElement.startOffset, ktElement.endOffset, origin,
|
||||
descriptor
|
||||
)
|
||||
|
||||
fun generateFunctionParameterDeclarationsAndReturnType(
|
||||
irFunction: IrFunction,
|
||||
ktParameterOwner: KtElement?,
|
||||
ktReceiverParameterElement: KtElement?
|
||||
) {
|
||||
declarationGenerator.generateScopedTypeParameterDeclarations(irFunction, irFunction.descriptor.typeParameters)
|
||||
declarationGenerator.generateScopedTypeParameterDeclarations(irFunction, irFunction.descriptor.propertyIfAccessor.typeParameters)
|
||||
irFunction.returnType = irFunction.descriptor.returnType!!.toIrType()
|
||||
generateValueParameterDeclarations(irFunction, ktParameterOwner, ktReceiverParameterElement)
|
||||
}
|
||||
|
||||
@@ -94,14 +100,14 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
ktProperty: KtProperty,
|
||||
ktAccessor: KtPropertyAccessor?
|
||||
): IrSimpleFunction =
|
||||
context.symbolTable.declareSimpleFunctionWithOverrides(
|
||||
ktAccessor?.startOffset ?: ktProperty.startOffset,
|
||||
ktAccessor?.endOffset ?: ktProperty.endOffset,
|
||||
if (ktAccessor != null) IrDeclarationOrigin.DEFINED else IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
|
||||
descriptor
|
||||
declareSimpleFunctionInner(
|
||||
descriptor,
|
||||
ktAccessor ?: ktProperty,
|
||||
if (ktAccessor != null) IrDeclarationOrigin.DEFINED else IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
|
||||
).buildWithScope { irAccessor ->
|
||||
declarationGenerator.generateScopedTypeParameterDeclarations(irAccessor, descriptor.correspondingProperty.typeParameters)
|
||||
generateFunctionParameterDeclarations(irAccessor, ktAccessor ?: ktProperty, ktProperty.receiverTypeReference)
|
||||
irAccessor.returnType = irAccessor.descriptor.returnType!!.toIrType()
|
||||
generateValueParameterDeclarations(irAccessor, ktAccessor ?: ktProperty, ktProperty.receiverTypeReference)
|
||||
val ktBodyExpression = ktAccessor?.bodyExpression
|
||||
irAccessor.body =
|
||||
if (ktBodyExpression != null)
|
||||
@@ -114,13 +120,9 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
descriptor: PropertyAccessorDescriptor,
|
||||
ktParameter: KtParameter
|
||||
): IrSimpleFunction =
|
||||
context.symbolTable.declareSimpleFunctionWithOverrides(
|
||||
ktParameter.startOffsetOrUndefined,
|
||||
ktParameter.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
|
||||
descriptor
|
||||
).buildWithScope { irAccessor ->
|
||||
declareSimpleFunctionInner(descriptor, ktParameter, IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR).buildWithScope { irAccessor ->
|
||||
declarationGenerator.generateScopedTypeParameterDeclarations(irAccessor, descriptor.typeParameters)
|
||||
irAccessor.returnType = descriptor.returnType!!.toIrType()
|
||||
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irAccessor)
|
||||
irAccessor.body = generateDefaultAccessorBody(ktParameter, descriptor, irAccessor)
|
||||
}
|
||||
@@ -142,17 +144,20 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
): IrBlockBody {
|
||||
val property = getter.correspondingProperty
|
||||
|
||||
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
|
||||
val startOffset = ktProperty.startOffset
|
||||
val endOffset = ktProperty.endOffset
|
||||
val irBody = IrBlockBodyImpl(startOffset, endOffset)
|
||||
|
||||
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
|
||||
|
||||
irBody.statements.add(
|
||||
IrReturnImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset, context.builtIns.nothingType,
|
||||
startOffset, endOffset, context.irBuiltIns.nothingType,
|
||||
irAccessor.symbol,
|
||||
IrGetFieldImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset,
|
||||
startOffset, endOffset,
|
||||
context.symbolTable.referenceField(property),
|
||||
property.type.toIrType(),
|
||||
receiver
|
||||
)
|
||||
)
|
||||
@@ -167,17 +172,20 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
): IrBlockBody {
|
||||
val property = setter.correspondingProperty
|
||||
|
||||
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
|
||||
val startOffset = ktProperty.startOffset
|
||||
val endOffset = ktProperty.endOffset
|
||||
val irBody = IrBlockBodyImpl(startOffset, endOffset)
|
||||
|
||||
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
|
||||
|
||||
val setterParameter = irAccessor.valueParameters.single().symbol
|
||||
val irValueParameter = irAccessor.valueParameters.single()
|
||||
irBody.statements.add(
|
||||
IrSetFieldImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset,
|
||||
startOffset, endOffset,
|
||||
context.symbolTable.referenceField(property),
|
||||
receiver,
|
||||
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset, setterParameter)
|
||||
IrGetValueImpl(startOffset, endOffset, irValueParameter.type, irValueParameter.symbol),
|
||||
context.irBuiltIns.unitType
|
||||
)
|
||||
)
|
||||
return irBody
|
||||
@@ -186,11 +194,14 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
private fun generateReceiverExpressionForDefaultPropertyAccessor(ktProperty: KtElement, property: PropertyDescriptor): IrExpression? {
|
||||
val containingDeclaration = property.containingDeclaration
|
||||
return when (containingDeclaration) {
|
||||
is ClassDescriptor ->
|
||||
is ClassDescriptor -> {
|
||||
val thisAsReceiverParameter = containingDeclaration.thisAsReceiverParameter
|
||||
IrGetValueImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset,
|
||||
context.symbolTable.referenceValue(containingDeclaration.thisAsReceiverParameter)
|
||||
thisAsReceiverParameter.type.toIrType(),
|
||||
context.symbolTable.referenceValue(thisAsReceiverParameter)
|
||||
)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -228,10 +239,12 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
generateBody: BodyGenerator.() -> IrBody?
|
||||
): IrConstructor =
|
||||
context.symbolTable.declareConstructor(
|
||||
ktConstructorElement.startOffset, ktConstructorElement.endOffset, IrDeclarationOrigin.DEFINED, constructorDescriptor
|
||||
ktConstructorElement.startOffset, ktConstructorElement.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
constructorDescriptor
|
||||
).buildWithScope { irConstructor ->
|
||||
generateValueParameterDeclarations(irConstructor, ktParametersElement, null)
|
||||
irConstructor.body = createBodyGenerator(irConstructor.symbol).generateBody()
|
||||
irConstructor.returnType = constructorDescriptor.returnType.toIrType()
|
||||
}
|
||||
|
||||
fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction) {
|
||||
@@ -268,12 +281,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
bodyGenerator: BodyGenerator,
|
||||
withDefaultValues: Boolean
|
||||
): IrValueParameter =
|
||||
context.symbolTable.declareValueParameter(
|
||||
ktParameter.startOffsetOrUndefined,
|
||||
ktParameter.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
valueParameterDescriptor
|
||||
).also {
|
||||
declareParameter(valueParameterDescriptor, ktParameter).also {
|
||||
if (withDefaultValues) {
|
||||
it.defaultValue = ktParameter?.defaultValue?.let {
|
||||
bodyGenerator.generateExpressionBody(it)
|
||||
@@ -285,11 +293,13 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
receiverParameterDescriptor: ReceiverParameterDescriptor,
|
||||
ktElement: KtElement?
|
||||
): IrValueParameter =
|
||||
context.symbolTable.declareValueParameter(
|
||||
ktElement.startOffsetOrUndefined,
|
||||
ktElement.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
receiverParameterDescriptor
|
||||
)
|
||||
declareParameter(receiverParameterDescriptor, ktElement)
|
||||
|
||||
private fun declareParameter(descriptor: ParameterDescriptor, ktElement: KtElement?) =
|
||||
context.symbolTable.declareValueParameter(
|
||||
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
descriptor, descriptor.type.toIrType(),
|
||||
(descriptor as? ValueParameterDescriptor)?.varargElementType?.toIrType()
|
||||
)
|
||||
}
|
||||
@@ -17,17 +17,10 @@
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
||||
import org.jetbrains.kotlin.ir.builders.IrGenerator
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorWithScope
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.endOffsetOrUndefined
|
||||
import org.jetbrains.kotlin.psi2ir.startOffsetOrUndefined
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -39,8 +32,7 @@ interface Generator : IrGenerator {
|
||||
override val context: GeneratorContext
|
||||
}
|
||||
|
||||
interface GeneratorWithScope : Generator, IrGeneratorWithScope {
|
||||
}
|
||||
interface GeneratorWithScope : Generator, IrGeneratorWithScope
|
||||
|
||||
|
||||
fun <K, V : Any> Generator.get(slice: ReadOnlySlice<K, V>, key: K): V? =
|
||||
@@ -61,22 +53,3 @@ fun Generator.getInferredTypeWithImplicitCastsOrFail(key: KtExpression): KotlinT
|
||||
fun Generator.getResolvedCall(key: KtElement): ResolvedCall<out CallableDescriptor>? =
|
||||
key.getResolvedCall(context.bindingContext)
|
||||
|
||||
fun Generator.createDummyExpression(ktExpression: KtExpression, description: String): IrErrorExpressionImpl =
|
||||
IrErrorExpressionImpl(
|
||||
ktExpression.startOffset,
|
||||
ktExpression.endOffset,
|
||||
getInferredTypeWithImplicitCastsOrFail(ktExpression),
|
||||
description
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
inline fun GeneratorWithScope.irBlockBody(ktElement: KtElement?, body: IrBlockBodyBuilder.() -> Unit): IrBlockBody =
|
||||
this.irBlockBody(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, body)
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.NotFoundClasses
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.util.ConstantValueGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -30,11 +32,21 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
class GeneratorContext(
|
||||
val configuration: Psi2IrConfiguration,
|
||||
val moduleDescriptor: ModuleDescriptor,
|
||||
val bindingContext: BindingContext
|
||||
) : IrGeneratorContext(IrBuiltIns(moduleDescriptor.builtIns)) {
|
||||
val sourceManager = PsiSourceManager()
|
||||
val bindingContext: BindingContext,
|
||||
val symbolTable: SymbolTable = SymbolTable()
|
||||
) : IrGeneratorContext() {
|
||||
|
||||
val symbolTable = SymbolTable()
|
||||
val constantValueGenerator: ConstantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable)
|
||||
val typeTranslator: TypeTranslator = TypeTranslator(symbolTable)
|
||||
|
||||
init {
|
||||
typeTranslator.constantValueGenerator = constantValueGenerator
|
||||
constantValueGenerator.typeTranslator = typeTranslator
|
||||
}
|
||||
|
||||
override val irBuiltIns: IrBuiltIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, symbolTable)
|
||||
|
||||
val sourceManager = PsiSourceManager()
|
||||
|
||||
// TODO: inject a correct StorageManager instance, or store NotFoundClasses inside ModuleDescriptor
|
||||
val reflectionTypes = ReflectionTypes(moduleDescriptor, NotFoundClasses(LockBasedStorageManager.NO_LOCKS, moduleDescriptor))
|
||||
|
||||
@@ -27,9 +27,10 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
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 startOffset = ktObjectLiteral.startOffset
|
||||
val endOffset = ktObjectLiteral.endOffset
|
||||
val objectLiteralType = getInferredTypeWithImplicitCastsOrFail(ktObjectLiteral).toIrType()
|
||||
val irBlock = IrBlockImpl(startOffset, endOffset, objectLiteralType, IrStatementOrigin.OBJECT_LITERAL)
|
||||
|
||||
val irClass = DeclarationGenerator(statementGenerator.context).generateClassOrObjectDeclaration(ktObjectLiteral.objectDeclaration)
|
||||
irBlock.statements.add(irClass)
|
||||
@@ -48,10 +49,9 @@ class LocalClassGenerator(statementGenerator: StatementGenerator) : StatementGen
|
||||
|
||||
irBlock.statements.add(
|
||||
IrCallImpl(
|
||||
ktObjectLiteral.startOffset, ktObjectLiteral.endOffset, objectLiteralType,
|
||||
startOffset, endOffset, objectLiteralType,
|
||||
context.symbolTable.referenceConstructor(objectConstructor),
|
||||
objectConstructor,
|
||||
null,
|
||||
IrStatementOrigin.OBJECT_LITERAL
|
||||
)
|
||||
)
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
class LocalFunctionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
fun generateLambda(ktLambda: KtLambdaExpression): IrStatement {
|
||||
val ktFun = ktLambda.functionLiteral
|
||||
val lambdaExpressionType = getInferredTypeWithImplicitCastsOrFail(ktLambda)
|
||||
val lambdaExpressionType = getInferredTypeWithImplicitCastsOrFail(ktLambda).toIrType()
|
||||
val irLambdaFunction = FunctionGenerator(context).generateLambdaFunctionDeclaration(ktFun)
|
||||
|
||||
val irBlock = IrBlockImpl(ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, IrStatementOrigin.LAMBDA)
|
||||
@@ -37,8 +37,8 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
|
||||
irBlock.statements.add(
|
||||
IrFunctionReferenceImpl(
|
||||
ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType,
|
||||
irLambdaFunction.symbol, irLambdaFunction.symbol.descriptor,
|
||||
null, IrStatementOrigin.LAMBDA
|
||||
irLambdaFunction.symbol, irLambdaFunction.symbol.descriptor, 0,
|
||||
IrStatementOrigin.LAMBDA
|
||||
)
|
||||
)
|
||||
return irBlock
|
||||
@@ -49,7 +49,7 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
|
||||
generateFunctionDeclaration(ktFun)
|
||||
} else {
|
||||
// anonymous function expression
|
||||
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun)
|
||||
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun).toIrType()
|
||||
val irBlock = IrBlockImpl(ktFun.startOffset, ktFun.endOffset, funExpressionType, IrStatementOrigin.ANONYMOUS_FUNCTION)
|
||||
|
||||
val irFun = generateFunctionDeclaration(ktFun)
|
||||
@@ -58,8 +58,8 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
|
||||
irBlock.statements.add(
|
||||
IrFunctionReferenceImpl(
|
||||
ktFun.startOffset, ktFun.endOffset, funExpressionType,
|
||||
irFun.symbol, irFun.symbol.descriptor,
|
||||
null, IrStatementOrigin.ANONYMOUS_FUNCTION
|
||||
irFun.symbol, irFun.symbol.descriptor, 0,
|
||||
IrStatementOrigin.ANONYMOUS_FUNCTION
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
fun generateWhileLoop(ktWhile: KtWhileExpression): IrExpression {
|
||||
val irLoop = IrWhileLoopImpl(
|
||||
ktWhile.startOffset, ktWhile.endOffset,
|
||||
context.builtIns.unitType, IrStatementOrigin.WHILE_LOOP
|
||||
context.irBuiltIns.unitType, IrStatementOrigin.WHILE_LOOP
|
||||
)
|
||||
|
||||
irLoop.condition = ktWhile.condition!!.genExpr()
|
||||
@@ -55,7 +55,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
fun generateDoWhileLoop(ktDoWhile: KtDoWhileExpression): IrExpression {
|
||||
val irLoop = IrDoWhileLoopImpl(
|
||||
ktDoWhile.startOffset, ktDoWhile.endOffset,
|
||||
context.builtIns.unitType, IrStatementOrigin.DO_WHILE_LOOP
|
||||
context.irBuiltIns.unitType, IrStatementOrigin.DO_WHILE_LOOP
|
||||
)
|
||||
|
||||
statementGenerator.bodyGenerator.putLoop(ktDoWhile, irLoop)
|
||||
@@ -71,21 +71,21 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
|
||||
irLoop.label = getLoopLabel(ktDoWhile)
|
||||
|
||||
return IrBlockImpl(ktDoWhile.startOffset, ktDoWhile.endOffset, context.builtIns.unitType).apply {
|
||||
return IrBlockImpl(ktDoWhile.startOffset, ktDoWhile.endOffset, context.irBuiltIns.unitType).apply {
|
||||
statements.add(irLoop)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateWhileLoopBody(ktLoopBody: KtBlockExpression): IrExpression =
|
||||
IrBlockImpl(
|
||||
ktLoopBody.startOffset, ktLoopBody.endOffset, context.builtIns.unitType, null,
|
||||
ktLoopBody.startOffset, ktLoopBody.endOffset, context.irBuiltIns.unitType, null,
|
||||
ktLoopBody.statements.map { it.genStmt() }
|
||||
)
|
||||
|
||||
|
||||
private fun generateDoWhileLoopBody(ktLoopBody: KtBlockExpression): IrExpression =
|
||||
IrCompositeImpl(
|
||||
ktLoopBody.startOffset, ktLoopBody.endOffset, context.builtIns.unitType, null,
|
||||
ktLoopBody.startOffset, ktLoopBody.endOffset, context.irBuiltIns.unitType, null,
|
||||
ktLoopBody.statements.map { it.genStmt() }
|
||||
)
|
||||
|
||||
@@ -93,7 +93,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
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 {
|
||||
return IrBreakImpl(ktBreak.startOffset, ktBreak.endOffset, context.irBuiltIns.nothingType, parentLoop).apply {
|
||||
label = ktBreak.getLabelName()
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
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 {
|
||||
return IrContinueImpl(ktContinue.startOffset, ktContinue.endOffset, context.irBuiltIns.nothingType, parentLoop).apply {
|
||||
label = ktContinue.getLabelName()
|
||||
}
|
||||
}
|
||||
@@ -154,16 +154,18 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
|
||||
val callGenerator = CallGenerator(statementGenerator)
|
||||
|
||||
val irForBlock = IrBlockImpl(ktFor.startOffset, ktFor.endOffset, context.builtIns.unitType, IrStatementOrigin.FOR_LOOP)
|
||||
val startOffset = ktFor.startOffset
|
||||
val endOffset = ktFor.endOffset
|
||||
|
||||
val irForBlock = IrBlockImpl(startOffset, endOffset, context.irBuiltIns.unitType, IrStatementOrigin.FOR_LOOP)
|
||||
|
||||
val iteratorCall = statementGenerator.pregenerateCall(iteratorResolvedCall)
|
||||
val irIteratorCall = callGenerator.generateCall(ktLoopRange, iteratorCall, IrStatementOrigin.FOR_LOOP_ITERATOR)
|
||||
val irIterator = scope.createTemporaryVariable(irIteratorCall, "iterator", origin = IrDeclarationOrigin.FOR_LOOP_ITERATOR)
|
||||
val iteratorValue = VariableLValue(irIterator)
|
||||
val iteratorValue = VariableLValue(context, irIterator)
|
||||
irForBlock.statements.add(irIterator)
|
||||
|
||||
val irInnerWhile =
|
||||
IrWhileLoopImpl(ktFor.startOffset, ktFor.endOffset, context.builtIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE)
|
||||
val irInnerWhile = IrWhileLoopImpl(startOffset, endOffset, context.irBuiltIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE)
|
||||
irInnerWhile.label = getLoopLabel(ktFor)
|
||||
statementGenerator.bodyGenerator.putLoop(ktFor, irInnerWhile)
|
||||
irForBlock.statements.add(irInnerWhile)
|
||||
@@ -173,28 +175,30 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
val irHasNextCall = callGenerator.generateCall(ktLoopRange, hasNextCall, IrStatementOrigin.FOR_LOOP_HAS_NEXT)
|
||||
irInnerWhile.condition = irHasNextCall
|
||||
|
||||
val irInnerBody = IrBlockImpl(ktFor.startOffset, ktFor.endOffset, context.builtIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE)
|
||||
val irInnerBody = IrBlockImpl(startOffset, endOffset, context.irBuiltIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE)
|
||||
irInnerWhile.body = irInnerBody
|
||||
|
||||
val nextCall = statementGenerator.pregenerateCall(nextResolvedCall)
|
||||
nextCall.setExplicitReceiverValue(iteratorValue)
|
||||
val irNextCall = callGenerator.generateCall(ktLoopRange, nextCall, IrStatementOrigin.FOR_LOOP_NEXT)
|
||||
val irLoopParameter =
|
||||
if (ktLoopParameter != null && ktLoopDestructuringDeclaration == null)
|
||||
if (ktLoopParameter != null && ktLoopDestructuringDeclaration == null) {
|
||||
val loopParameter = getOrFail(BindingContext.VALUE_PARAMETER, ktLoopParameter)
|
||||
context.symbolTable.declareVariable(
|
||||
ktLoopParameter.startOffset, ktLoopParameter.endOffset, IrDeclarationOrigin.FOR_LOOP_VARIABLE,
|
||||
getOrFail(BindingContext.VALUE_PARAMETER, ktLoopParameter),
|
||||
loopParameter, loopParameter.type.toIrType(),
|
||||
irNextCall
|
||||
)
|
||||
else
|
||||
} 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)
|
||||
VariableLValue(context, irLoopParameter)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -22,13 +22,12 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.transformations.AnnotationGenerator
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
|
||||
|
||||
class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
||||
|
||||
private val annotationGenerator = AnnotationGenerator(context)
|
||||
private val constantValueGenerator = context.constantValueGenerator
|
||||
|
||||
fun generateModuleFragment(ktFiles: Collection<KtFile>): IrModuleFragment =
|
||||
generateModuleFragmentWithoutDependencies(ktFiles).also { irModule ->
|
||||
@@ -41,7 +40,9 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
||||
}
|
||||
|
||||
fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment) {
|
||||
ExternalDependenciesGenerator(context.symbolTable, context.irBuiltIns).generateUnboundSymbolsAsDependencies(irModule)
|
||||
ExternalDependenciesGenerator(
|
||||
irModule.descriptor, context.symbolTable, context.irBuiltIns
|
||||
).generateUnboundSymbolsAsDependencies(irModule)
|
||||
}
|
||||
|
||||
private fun generateFiles(ktFiles: Collection<KtFile>): List<IrFile> {
|
||||
@@ -58,7 +59,7 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
||||
for (ktAnnotationEntry in ktFile.annotationEntries) {
|
||||
val annotationDescriptor = getOrFail(BindingContext.ANNOTATION, ktAnnotationEntry)
|
||||
irFile.fileAnnotations.add(annotationDescriptor)
|
||||
irFile.annotations.add(annotationGenerator.generateAnnotationConstructorCall(annotationDescriptor))
|
||||
irFile.annotations.add(constantValueGenerator.generateAnnotationConstructorCall(annotationDescriptor))
|
||||
}
|
||||
|
||||
for (ktDeclaration in ktFile.declarations) {
|
||||
|
||||
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||
import org.jetbrains.kotlin.ir.types.makeNotNull
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -46,6 +48,14 @@ import java.lang.AssertionError
|
||||
|
||||
class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
|
||||
private fun createErrorExpression(ktExpression: KtExpression, text: String) =
|
||||
IrErrorExpressionImpl(
|
||||
ktExpression.startOffset,
|
||||
ktExpression.endOffset,
|
||||
context.irBuiltIns.nothingType,
|
||||
text
|
||||
)
|
||||
|
||||
fun generatePrefixExpression(expression: KtPrefixExpression): IrExpression {
|
||||
val ktOperator = expression.operationReference.getReferencedNameElementType()
|
||||
val irOperator = getPrefixOperator(ktOperator)
|
||||
@@ -57,7 +67,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
irOperator
|
||||
)
|
||||
in OPERATORS_DESUGARED_TO_CALLS -> generatePrefixOperatorAsCall(expression, irOperator)
|
||||
else -> createDummyExpression(expression, ktOperator.toString())
|
||||
else -> createErrorExpression(expression, ktOperator.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +82,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
irOperator
|
||||
)
|
||||
IrStatementOrigin.EXCLEXCL -> generateExclExclOperator(expression, irOperator)
|
||||
else -> createDummyExpression(expression, ktOperator.toString())
|
||||
else -> createErrorExpression(expression, ktOperator.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,9 +101,9 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
}
|
||||
|
||||
return IrTypeOperatorCallImpl(
|
||||
expression.startOffset, expression.endOffset, resultType, irOperator, rhsType,
|
||||
expression.left.genExpr(),
|
||||
context.symbolTable.referenceClassifier(rhsType.constructor.declarationDescriptor!!)
|
||||
expression.startOffset, expression.endOffset, resultType.toIrType(), irOperator, rhsType.toIrType(),
|
||||
context.symbolTable.referenceClassifier(rhsType.constructor.declarationDescriptor!!),
|
||||
expression.left.genExpr()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -103,9 +113,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
val againstType = getOrFail(BindingContext.TYPE, expression.typeReference)
|
||||
|
||||
return IrTypeOperatorCallImpl(
|
||||
expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator,
|
||||
againstType, expression.leftHandSide.genExpr(),
|
||||
context.symbolTable.referenceClassifier(againstType.constructor.declarationDescriptor!!)
|
||||
expression.startOffset, expression.endOffset, context.irBuiltIns.booleanType, irOperator,
|
||||
againstType.toIrType(),
|
||||
context.symbolTable.referenceClassifier(againstType.constructor.declarationDescriptor!!),
|
||||
expression.leftHandSide.genExpr()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -128,19 +139,24 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
in IDENTITY_OPERATORS -> generateIdentityOperator(expression, irOperator)
|
||||
in IN_OPERATORS -> generateInOperator(expression, irOperator)
|
||||
in BINARY_BOOLEAN_OPERATORS -> generateBinaryBooleanOperator(expression, irOperator)
|
||||
else -> createDummyExpression(expression, ktOperator.toString())
|
||||
else -> createErrorExpression(expression, ktOperator.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateElvis(expression: KtBinaryExpression): IrExpression {
|
||||
val specialCallForElvis = getResolvedCall(expression)!!
|
||||
val resultType = specialCallForElvis.resultingDescriptor.returnType!!
|
||||
val resultType = specialCallForElvis.resultingDescriptor.returnType!!.toIrType()
|
||||
val irArgument0 = expression.left!!.genExpr()
|
||||
val irArgument1 = expression.right!!.genExpr()
|
||||
|
||||
return irBlock(expression, IrStatementOrigin.ELVIS, resultType) {
|
||||
return irBlock(expression.startOffset, expression.endOffset, IrStatementOrigin.ELVIS, resultType) {
|
||||
val temporary = irTemporary(irArgument0, "elvis_lhs")
|
||||
+irIfNull(resultType, irGet(temporary.symbol), irArgument1, irGet(temporary.symbol))
|
||||
+irIfNull(
|
||||
resultType,
|
||||
irGet(temporary.type, temporary.symbol),
|
||||
irArgument1,
|
||||
irGet(temporary.type, temporary.symbol)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +183,9 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
irContainsCall
|
||||
IrStatementOrigin.NOT_IN ->
|
||||
IrUnaryPrimitiveImpl(
|
||||
expression.startOffset, expression.endOffset, IrStatementOrigin.NOT_IN,
|
||||
expression.startOffset, expression.endOffset,
|
||||
context.irBuiltIns.booleanType,
|
||||
IrStatementOrigin.NOT_IN,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
irContainsCall
|
||||
)
|
||||
@@ -182,7 +200,9 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
val irArgument1 = expression.right!!.genExpr()
|
||||
|
||||
val irIdentityEquals = IrBinaryPrimitiveImpl(
|
||||
expression.startOffset, expression.endOffset, irOperator,
|
||||
expression.startOffset, expression.endOffset,
|
||||
context.irBuiltIns.booleanType,
|
||||
irOperator,
|
||||
context.irBuiltIns.eqeqeqSymbol,
|
||||
irArgument0, irArgument1
|
||||
)
|
||||
@@ -192,7 +212,9 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
irIdentityEquals
|
||||
IrStatementOrigin.EXCLEQEQ ->
|
||||
IrUnaryPrimitiveImpl(
|
||||
expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQEQ,
|
||||
expression.startOffset, expression.endOffset,
|
||||
context.irBuiltIns.booleanType,
|
||||
IrStatementOrigin.EXCLEQEQ,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
irIdentityEquals
|
||||
)
|
||||
@@ -218,6 +240,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
|
||||
val irEquals = IrBinaryPrimitiveImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
context.irBuiltIns.booleanType,
|
||||
irOperator,
|
||||
eqeqSymbol,
|
||||
expression.left!!.generateAsPrimitiveNumericComparisonOperand(comparisonInfo?.leftType, comparisonType),
|
||||
@@ -230,6 +253,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
IrStatementOrigin.EXCLEQ ->
|
||||
IrUnaryPrimitiveImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
context.irBuiltIns.booleanType,
|
||||
IrStatementOrigin.EXCLEQ,
|
||||
context.irBuiltIns.booleanNotSymbol,
|
||||
irEquals
|
||||
@@ -253,14 +277,18 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
context.irBuiltIns.ieee754equalsFunByOperandType[comparisonType]?.symbol
|
||||
?: context.irBuiltIns.eqeqSymbol
|
||||
IrBinaryPrimitiveImpl(
|
||||
startOffset, endOffset, irOperator,
|
||||
startOffset, endOffset,
|
||||
context.irBuiltIns.booleanType,
|
||||
irOperator,
|
||||
eqeqSymbol,
|
||||
arg1.promoteToPrimitiveNumericType(comparisonInfo.leftType, comparisonType),
|
||||
arg2.promoteToPrimitiveNumericType(comparisonInfo.rightType, comparisonType)
|
||||
)
|
||||
} else {
|
||||
IrBinaryPrimitiveImpl(
|
||||
startOffset, endOffset, irOperator,
|
||||
startOffset, endOffset,
|
||||
context.irBuiltIns.booleanType,
|
||||
irOperator,
|
||||
context.irBuiltIns.eqeqSymbol,
|
||||
arg1, arg2
|
||||
)
|
||||
@@ -281,7 +309,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
operandType == targetType || operandNNType == targetType ->
|
||||
this
|
||||
|
||||
type.containsNull() ->
|
||||
// TODO: don't rely on originalKotlinType.
|
||||
type.originalKotlinType!!.containsNull() ->
|
||||
safeCallOnDispatchReceiver(this@OperatorExpressionGenerator, startOffset, endOffset) { dispatchReceiver ->
|
||||
invokeConversionFunction(
|
||||
startOffset, endOffset,
|
||||
@@ -308,10 +337,9 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
IrCallImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
functionDescriptor.returnType!!,
|
||||
functionDescriptor.returnType!!.toIrType(),
|
||||
context.symbolTable.referenceFunction(functionDescriptor.original),
|
||||
functionDescriptor,
|
||||
typeArguments = null,
|
||||
origin = null, // TODO origin for widening conversions?
|
||||
superQualifierSymbol = null
|
||||
).apply {
|
||||
@@ -331,17 +359,21 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
|
||||
return if (comparisonInfo != null) {
|
||||
IrBinaryPrimitiveImpl(
|
||||
startOffset, endOffset, origin,
|
||||
startOffset, endOffset,
|
||||
context.irBuiltIns.booleanType,
|
||||
origin,
|
||||
getComparisonOperatorSymbol(origin, comparisonInfo.comparisonType),
|
||||
expression.left!!.generateAsPrimitiveNumericComparisonOperand(comparisonInfo.leftType, comparisonInfo.comparisonType),
|
||||
expression.right!!.generateAsPrimitiveNumericComparisonOperand(comparisonInfo.rightType, comparisonInfo.comparisonType)
|
||||
)
|
||||
} else {
|
||||
IrBinaryPrimitiveImpl(
|
||||
startOffset, endOffset, origin,
|
||||
startOffset, endOffset,
|
||||
context.irBuiltIns.booleanType,
|
||||
origin,
|
||||
getComparisonOperatorSymbol(origin, context.irBuiltIns.int),
|
||||
generateCall(getResolvedCall(expression)!!, expression, origin),
|
||||
IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, 0)
|
||||
IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, 0)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -367,11 +399,16 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
val irArgument = ktArgument.genExpr()
|
||||
val ktOperator = expression.operationReference
|
||||
|
||||
val resultType = irArgument.type.makeNotNullable()
|
||||
val resultType = irArgument.type.makeNotNull()
|
||||
|
||||
return irBlock(ktOperator, origin, resultType) {
|
||||
return irBlock(ktOperator.startOffset, ktOperator.endOffset, origin, resultType) {
|
||||
val temporary = irTemporary(irArgument, "notnull")
|
||||
+irIfNull(resultType, irGet(temporary.symbol), irThrowNpe(origin), irGet(temporary.symbol))
|
||||
+irIfNull(
|
||||
resultType,
|
||||
irGet(temporary.type, temporary.symbol),
|
||||
irThrowNpe(origin),
|
||||
irGet(temporary.type, temporary.symbol)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
fun generatePropertyForPrimaryConstructorParameter(ktParameter: KtParameter, irValueParameter: IrValueParameter): IrDeclaration {
|
||||
val propertyDescriptor = getOrFail(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, ktParameter)
|
||||
|
||||
val irPropertyType = propertyDescriptor.type.toIrType()
|
||||
return IrPropertyImpl(
|
||||
ktParameter.startOffset, ktParameter.endOffset,
|
||||
IrDeclarationOrigin.DEFINED, false,
|
||||
@@ -54,6 +55,7 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
IrExpressionBodyImpl(
|
||||
IrGetValueImpl(
|
||||
ktParameter.startOffset, ktParameter.endOffset,
|
||||
irPropertyType,
|
||||
irValueParameter.symbol,
|
||||
IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
)
|
||||
@@ -82,7 +84,7 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
context.symbolTable.declareField(
|
||||
ktPropertyElement.startOffset, ktPropertyElement.endOffset,
|
||||
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
|
||||
propertyDescriptor
|
||||
propertyDescriptor, propertyDescriptor.type.toIrType()
|
||||
).also {
|
||||
it.initializer = generateInitializer(it)
|
||||
}
|
||||
@@ -99,7 +101,8 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
private fun generateSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor): IrProperty =
|
||||
IrPropertyImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset,
|
||||
IrDeclarationOrigin.DEFINED, false,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
false,
|
||||
propertyDescriptor
|
||||
).buildWithScope { irProperty ->
|
||||
irProperty.backingField =
|
||||
|
||||
@@ -31,10 +31,11 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
||||
|
||||
class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
|
||||
fun generateClassLiteral(ktClassLiteral: KtClassLiteralExpression): IrExpression {
|
||||
val ktArgument = ktClassLiteral.receiverExpression!!
|
||||
val lhs = getOrFail(BindingContext.DOUBLE_COLON_LHS, ktArgument)
|
||||
val resultType = getInferredTypeWithImplicitCastsOrFail(ktClassLiteral)
|
||||
val resultType = getInferredTypeWithImplicitCastsOrFail(ktClassLiteral).toIrType()
|
||||
|
||||
return if (lhs is DoubleColonLHS.Expression && !lhs.isObjectQualifier) {
|
||||
IrGetClassImpl(
|
||||
@@ -47,7 +48,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
?: throw AssertionError("Unexpected type constructor for ${lhs.type}: $typeConstructorDeclaration")
|
||||
IrClassReferenceImpl(
|
||||
ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
|
||||
context.symbolTable.referenceClassifier(typeClass), lhs.type
|
||||
context.symbolTable.referenceClassifier(typeClass), lhs.type.toIrType()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -119,7 +120,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it) }
|
||||
|
||||
return IrLocalDelegatedPropertyReferenceImpl(
|
||||
startOffset, endOffset, type,
|
||||
startOffset, endOffset, type.toIrType(),
|
||||
variableDescriptor,
|
||||
irDelegateSymbol, getterSymbol, setterSymbol,
|
||||
origin
|
||||
@@ -142,12 +143,13 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it.original) }
|
||||
|
||||
return IrPropertyReferenceImpl(
|
||||
startOffset, endOffset, type,
|
||||
propertyDescriptor,
|
||||
startOffset, endOffset, type.toIrType(),
|
||||
propertyDescriptor, propertyDescriptor.typeParametersCount,
|
||||
fieldSymbol, getterSymbol, setterSymbol,
|
||||
typeArguments,
|
||||
origin
|
||||
)
|
||||
).apply {
|
||||
putTypeArguments(typeArguments) { it.toIrType()}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateFunctionReference(
|
||||
@@ -160,9 +162,10 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
origin: IrStatementOrigin?
|
||||
): IrFunctionReference =
|
||||
IrFunctionReferenceImpl(
|
||||
startOffset, endOffset, type,
|
||||
symbol, descriptor,
|
||||
typeArguments,
|
||||
startOffset, endOffset, type.toIrType(),
|
||||
symbol, descriptor, descriptor.typeParametersCount,
|
||||
origin
|
||||
)
|
||||
).apply {
|
||||
putTypeArguments(typeArguments) { it.toIrType() }
|
||||
}
|
||||
}
|
||||
@@ -41,16 +41,23 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||
import java.lang.AssertionError
|
||||
|
||||
class StatementGenerator(
|
||||
val bodyGenerator: BodyGenerator,
|
||||
override val scope: Scope
|
||||
) : KtVisitor<IrStatement, Nothing?>(), GeneratorWithScope {
|
||||
) : KtVisitor<IrStatement, Nothing?>(),
|
||||
GeneratorWithScope {
|
||||
|
||||
override val context: GeneratorContext get() = bodyGenerator.context
|
||||
|
||||
val scopeOwner: DeclarationDescriptor get() = bodyGenerator.scopeOwner
|
||||
|
||||
private val typeTranslator = context.typeTranslator
|
||||
|
||||
fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||
|
||||
fun generateStatement(ktElement: KtElement): IrStatement =
|
||||
ktElement.genStmt()
|
||||
|
||||
@@ -71,7 +78,12 @@ class StatementGenerator(
|
||||
genStmt().assertCast()
|
||||
|
||||
override fun visitExpression(expression: KtExpression, data: Nothing?): IrStatement =
|
||||
createDummyExpression(expression, expression::class.java.simpleName)
|
||||
IrErrorExpressionImpl(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
context.irBuiltIns.nothingType,
|
||||
expression::class.java.simpleName
|
||||
)
|
||||
|
||||
override fun visitProperty(property: KtProperty, data: Nothing?): IrStatement {
|
||||
val variableDescriptor = getOrFail(BindingContext.VARIABLE, property)
|
||||
@@ -85,7 +97,9 @@ class StatementGenerator(
|
||||
|
||||
return context.symbolTable.declareVariable(
|
||||
property.startOffset, property.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
variableDescriptor, property.initializer?.genExpr()
|
||||
variableDescriptor,
|
||||
variableDescriptor.type.toIrType(),
|
||||
property.initializer?.genExpr()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -101,10 +115,10 @@ class StatementGenerator(
|
||||
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement {
|
||||
val irBlock = IrCompositeImpl(
|
||||
multiDeclaration.startOffset, multiDeclaration.endOffset,
|
||||
context.builtIns.unitType, IrStatementOrigin.DESTRUCTURING_DECLARATION
|
||||
context.irBuiltIns.unitType, IrStatementOrigin.DESTRUCTURING_DECLARATION
|
||||
)
|
||||
val ktInitializer = multiDeclaration.initializer!!
|
||||
val containerValue = scope.createTemporaryVariableInBlock(ktInitializer.genExpr(), irBlock, "container")
|
||||
val containerValue = scope.createTemporaryVariableInBlock(context, ktInitializer.genExpr(), irBlock, "container")
|
||||
|
||||
declareComponentVariablesInBlock(multiDeclaration, irBlock, containerValue)
|
||||
|
||||
@@ -134,7 +148,7 @@ class StatementGenerator(
|
||||
)
|
||||
val irComponentVar = context.symbolTable.declareVariable(
|
||||
ktEntry.startOffset, ktEntry.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
componentVariable, irComponentCall
|
||||
componentVariable, componentVariable.type.toIrType(), irComponentCall
|
||||
)
|
||||
irBlock.statements.add(irComponentVar)
|
||||
}
|
||||
@@ -145,7 +159,7 @@ class StatementGenerator(
|
||||
if (isBlockBody) throw AssertionError("Use IrBlockBody and corresponding body generator to generate blocks as function bodies")
|
||||
|
||||
val returnType = getInferredTypeWithImplicitCasts(expression) ?: context.builtIns.unitType
|
||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, returnType)
|
||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, returnType.toIrType())
|
||||
|
||||
expression.statements.forEach {
|
||||
irBlock.statements.add(it.genStmt())
|
||||
@@ -157,11 +171,11 @@ 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,
|
||||
expression.startOffset, expression.endOffset, context.irBuiltIns.unitType,
|
||||
context.symbolTable.referenceClass(context.builtIns.unit)
|
||||
)
|
||||
return IrReturnImpl(
|
||||
expression.startOffset, expression.endOffset, context.builtIns.nothingType,
|
||||
expression.startOffset, expression.endOffset, context.irBuiltIns.nothingType,
|
||||
context.symbolTable.referenceFunction(returnTarget), irReturnedExpression
|
||||
)
|
||||
}
|
||||
@@ -193,7 +207,7 @@ class StatementGenerator(
|
||||
return IrThrowImpl(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
context.builtIns.nothingType,
|
||||
context.irBuiltIns.nothingType,
|
||||
expression.thrownExpression!!.genExpr()
|
||||
)
|
||||
}
|
||||
@@ -206,7 +220,7 @@ class StatementGenerator(
|
||||
)
|
||||
|
||||
fun generateConstantExpression(expression: KtExpression, constant: CompileTimeConstant<*>): IrExpression =
|
||||
ConstantValueGenerator(context).generateConstantValueAsExpression(
|
||||
context.constantValueGenerator.generateConstantValueAsExpression(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
constant.toConstantValue(getInferredTypeWithImplicitCastsOrFail(expression))
|
||||
@@ -214,7 +228,7 @@ class StatementGenerator(
|
||||
|
||||
override fun visitStringTemplateExpression(expression: KtStringTemplateExpression, data: Nothing?): IrStatement {
|
||||
val entries = expression.entries
|
||||
val resultType = getInferredTypeWithImplicitCastsOrFail(expression)
|
||||
val resultType = getInferredTypeWithImplicitCastsOrFail(expression).toIrType()
|
||||
return when (entries.size) {
|
||||
1 -> {
|
||||
val irArg = entries[0].genExpr()
|
||||
@@ -231,10 +245,10 @@ 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.irBuiltIns.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.irBuiltIns.stringType, entry.unescapedValue)
|
||||
|
||||
override fun visitStringTemplateEntryWithExpression(entry: KtStringTemplateEntryWithExpression, data: Nothing?): IrStatement =
|
||||
entry.expression!!.genExpr()
|
||||
@@ -300,15 +314,22 @@ class StatementGenerator(
|
||||
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 ->
|
||||
is ClassDescriptor -> {
|
||||
val thisAsReceiverParameter = referenceTarget.thisAsReceiverParameter
|
||||
val thisType = thisAsReceiverParameter.type.toIrType()
|
||||
IrGetValueImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
context.symbolTable.referenceValueParameter(referenceTarget.thisAsReceiverParameter)
|
||||
thisType,
|
||||
context.symbolTable.referenceValueParameter(thisAsReceiverParameter)
|
||||
)
|
||||
}
|
||||
|
||||
is CallableDescriptor -> {
|
||||
val extensionReceiver = referenceTarget.extensionReceiverParameter ?: TODO("No extension receiver: $referenceTarget")
|
||||
val extensionReceiverType = extensionReceiver.type.toIrType()
|
||||
IrGetValueImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
extensionReceiverType,
|
||||
context.symbolTable.referenceValueParameter(extensionReceiver)
|
||||
)
|
||||
}
|
||||
@@ -387,4 +408,6 @@ abstract class StatementGeneratorExtension(val statementGenerator: StatementGene
|
||||
|
||||
fun KtExpression.genExpr() = statementGenerator.generateExpression(this)
|
||||
fun KtExpression.genStmt() = statementGenerator.generateStatement(this)
|
||||
fun KotlinType.toIrType() = with(statementGenerator) { toIrType() }
|
||||
fun translateType(kotlinType: KotlinType) = kotlinType.toIrType()
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
fun generateTryCatch(ktTry: KtTryExpression): IrExpression {
|
||||
val resultType = getInferredTypeWithImplicitCastsOrFail(ktTry)
|
||||
val resultType = getInferredTypeWithImplicitCastsOrFail(ktTry).toIrType()
|
||||
val irTryCatch = IrTryImpl(ktTry.startOffset, ktTry.endOffset, resultType)
|
||||
|
||||
irTryCatch.tryResult = ktTry.tryBlock.genExpr()
|
||||
@@ -42,7 +42,7 @@ class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
context.symbolTable.declareVariable(
|
||||
ktCatchParameter.startOffset, ktCatchParameter.endOffset,
|
||||
IrDeclarationOrigin.CATCH_PARAMETER,
|
||||
catchParameterDescriptor
|
||||
catchParameterDescriptor, catchParameterDescriptor.type.toIrType()
|
||||
)
|
||||
).apply {
|
||||
result = ktCatchBody.genExpr()
|
||||
|
||||
@@ -26,33 +26,40 @@ 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
|
||||
private val irArray: IrExpression,
|
||||
private val irIndices: List<IrExpression>,
|
||||
private val indexedGetCall: CallBuilder?,
|
||||
private val indexedSetCall: CallBuilder?,
|
||||
private val callGenerator: CallGenerator,
|
||||
private val startOffset: Int,
|
||||
private val endOffset: Int,
|
||||
private val origin: IrStatementOrigin
|
||||
) : AssignmentReceiver {
|
||||
private val type: KotlinType =
|
||||
|
||||
private val kotlinType: 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()
|
||||
val resultType = if (hasResult) type else callGenerator.context.builtIns.unitType
|
||||
val irBlock = IrBlockImpl(startOffset, endOffset, resultType, origin)
|
||||
val resultType = if (hasResult) kotlinType else callGenerator.context.builtIns.unitType
|
||||
val irResultType = callGenerator.translateType(resultType)
|
||||
val irBlock = IrBlockImpl(startOffset, endOffset, irResultType, origin)
|
||||
|
||||
val irArrayValue = callGenerator.scope.createTemporaryVariableInBlock(irArray, irBlock, "array")
|
||||
val irArrayValue = callGenerator.scope.createTemporaryVariableInBlock(callGenerator.context, irArray, irBlock, "array")
|
||||
|
||||
val irIndexValues = irIndices.mapIndexed { i, irIndex ->
|
||||
callGenerator.scope.createTemporaryVariableInBlock(irIndex, irBlock, "index$i")
|
||||
callGenerator.scope.createTemporaryVariableInBlock(callGenerator.context, irIndex, irBlock, "index$i")
|
||||
}
|
||||
|
||||
indexedGetCall?.fillArrayAndIndexArguments(irArrayValue, irIndexValues)
|
||||
indexedSetCall?.fillArrayAndIndexArguments(irArrayValue, irIndexValues)
|
||||
val irLValue = LValueWithGetterAndSetterCalls(callGenerator, indexedGetCall, indexedSetCall, type, startOffset, endOffset, origin)
|
||||
val irLValue = LValueWithGetterAndSetterCalls(
|
||||
callGenerator,
|
||||
indexedGetCall, indexedSetCall,
|
||||
callGenerator.translateType(kotlinType),
|
||||
startOffset, endOffset, origin
|
||||
)
|
||||
irBlock.inlineStatement(withLValue(irLValue))
|
||||
|
||||
return irBlock
|
||||
|
||||
@@ -16,26 +16,30 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
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?
|
||||
private val context: IrGeneratorContext,
|
||||
private val startOffset: Int,
|
||||
private val endOffset: Int,
|
||||
override val type: IrType,
|
||||
private val symbol: IrFieldSymbol,
|
||||
private val receiver: IntermediateValue?,
|
||||
private 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, context.irBuiltIns.unitType, origin)
|
||||
|
||||
override fun load(): IrExpression =
|
||||
IrGetFieldImpl(startOffset, endOffset, symbol, receiver?.load(), origin)
|
||||
IrGetFieldImpl(startOffset, endOffset, symbol, type, receiver?.load(), origin)
|
||||
|
||||
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression =
|
||||
withLValue(this)
|
||||
|
||||
@@ -16,25 +16,31 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class DelegatedLocalPropertyLValue(
|
||||
private val context: IrGeneratorContext,
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
override val type: KotlinType,
|
||||
val getterSymbol: IrSimpleFunctionSymbol?,
|
||||
val setterSymbol: IrSimpleFunctionSymbol?,
|
||||
override val type: IrType,
|
||||
private val getterSymbol: IrSimpleFunctionSymbol?,
|
||||
private val setterSymbol: IrSimpleFunctionSymbol?,
|
||||
val origin: IrStatementOrigin? = null
|
||||
) : LValue, AssignmentReceiver {
|
||||
) :
|
||||
LValue,
|
||||
AssignmentReceiver {
|
||||
|
||||
override fun load(): IrExpression =
|
||||
IrCallImpl(startOffset, endOffset, type, getterSymbol!!, getterSymbol.descriptor, null, origin)
|
||||
IrCallImpl(startOffset, endOffset, type, getterSymbol!!, getterSymbol.descriptor, origin)
|
||||
|
||||
override fun store(irExpression: IrExpression): IrExpression =
|
||||
IrCallImpl(startOffset, endOffset, type, setterSymbol!!, setterSymbol.descriptor, null, origin).apply {
|
||||
IrCallImpl(startOffset, endOffset, context.irBuiltIns.unitType, setterSymbol!!, setterSymbol.descriptor, origin).apply {
|
||||
putValueArgument(0, irExpression)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,11 @@ package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
|
||||
class ExtensionInvokeCallReceiver(
|
||||
val callBuilder: CallBuilder,
|
||||
val functionReceiver: IntermediateValue,
|
||||
val extensionInvokeReceiver: IntermediateValue
|
||||
private val callBuilder: CallBuilder,
|
||||
private val functionReceiver: IntermediateValue,
|
||||
private val extensionInvokeReceiver: IntermediateValue
|
||||
) : CallReceiver {
|
||||
|
||||
override fun call(withDispatchAndExtensionReceivers: (IntermediateValue?, IntermediateValue?) -> IrExpression): IrExpression {
|
||||
// extensionInvokeReceiver is actually a first argument:
|
||||
// receiver.extFun(p1, ..., pN)
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
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, type, symbol)
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
@@ -26,11 +27,12 @@ class LValueWithGetterAndSetterCalls(
|
||||
val callGenerator: CallGenerator,
|
||||
val getterCall: CallBuilder?,
|
||||
val setterCall: CallBuilder?,
|
||||
override val type: KotlinType,
|
||||
override val type: IrType,
|
||||
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")
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
|
||||
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 {
|
||||
private var instantiated = false
|
||||
|
||||
override fun load(): IrExpression {
|
||||
if (instantiated) throw AssertionError("Value for call ${call.descriptor} has already been instantiated")
|
||||
instantiated = true
|
||||
return CallGenerator(statementGenerator).generateCall(startOffset, endOffset, call, origin)
|
||||
}
|
||||
|
||||
override val type: KotlinType get() = call.descriptor.returnType!!
|
||||
}
|
||||
@@ -17,17 +17,18 @@
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
abstract class ExpressionValue(override val type: KotlinType) : IntermediateValue
|
||||
abstract class ExpressionValue(override val type: IrType) : IntermediateValue
|
||||
|
||||
inline fun generateExpressionValue(type: KotlinType, crossinline generate: () -> IrExpression) =
|
||||
inline fun generateExpressionValue(type: IrType, crossinline generate: () -> IrExpression) =
|
||||
object : ExpressionValue(type) {
|
||||
override fun load(): IrExpression = generate()
|
||||
}
|
||||
|
||||
inline fun generateDelegatedValue(type: KotlinType, crossinline generateValue: () -> IntermediateValue) =
|
||||
inline fun generateDelegatedValue(type: IrType, crossinline generateValue: () -> IntermediateValue) =
|
||||
object : ExpressionValue(type) {
|
||||
val lazyDelegate by lazy { generateValue() }
|
||||
override fun load(): IrExpression = lazyDelegate.load()
|
||||
@@ -42,7 +43,7 @@ class OnceExpressionValue(val irExpression: IrExpression) : LValue, AssignmentRe
|
||||
return irExpression
|
||||
}
|
||||
|
||||
override val type: KotlinType get() = irExpression.type
|
||||
override val type: IrType get() = irExpression.type
|
||||
|
||||
override fun store(irExpression: IrExpression): IrExpression {
|
||||
throw AssertionError("Expression value ${irExpression.render()} can't be used in store operation")
|
||||
|
||||
@@ -17,22 +17,24 @@
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
|
||||
abstract class PropertyLValueBase(
|
||||
protected val context: IrGeneratorContext,
|
||||
val scope: Scope,
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val origin: IrStatementOrigin?,
|
||||
override val type: KotlinType,
|
||||
override val type: IrType,
|
||||
val callReceiver: CallReceiver,
|
||||
val superQualifier: IrClassSymbol?
|
||||
) : LValue, AssignmentReceiver {
|
||||
@@ -41,12 +43,12 @@ abstract class PropertyLValueBase(
|
||||
val dispatchReceiverVariable2 = dispatchReceiverValue?.let {
|
||||
scope.createTemporaryVariable(dispatchReceiverValue.load(), "this")
|
||||
}
|
||||
val dispatchReceiverValue2 = dispatchReceiverVariable2?.let { VariableLValue(it) }
|
||||
val dispatchReceiverValue2 = dispatchReceiverVariable2?.let { VariableLValue(context, it) }
|
||||
|
||||
val extensionReceiverVariable2 = extensionReceiverValue?.let {
|
||||
scope.createTemporaryVariable(extensionReceiverValue.load(), "receiver")
|
||||
}
|
||||
val extensionReceiverValue2 = extensionReceiverVariable2?.let { VariableLValue(it) }
|
||||
val extensionReceiverValue2 = extensionReceiverVariable2?.let { VariableLValue(context, it) }
|
||||
|
||||
val irResultExpression = withLValue(withReceiver(dispatchReceiverValue2, extensionReceiverValue2))
|
||||
|
||||
@@ -64,20 +66,25 @@ abstract class PropertyLValueBase(
|
||||
}
|
||||
|
||||
class FieldPropertyLValue(
|
||||
context: IrGeneratorContext,
|
||||
scope: Scope,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrStatementOrigin?,
|
||||
val field: IrFieldSymbol,
|
||||
type: IrType,
|
||||
callReceiver: CallReceiver,
|
||||
superQualifier: IrClassSymbol?
|
||||
) : PropertyLValueBase(scope, startOffset, endOffset, origin, field.descriptor.type, callReceiver, superQualifier) {
|
||||
) :
|
||||
PropertyLValueBase(context, scope, startOffset, endOffset, origin, 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,
|
||||
type,
|
||||
dispatchReceiverValue?.load(),
|
||||
origin,
|
||||
superQualifier
|
||||
@@ -92,6 +99,7 @@ class FieldPropertyLValue(
|
||||
field,
|
||||
dispatchReceiverValue?.load(),
|
||||
irExpression,
|
||||
context.irBuiltIns.unitType,
|
||||
origin,
|
||||
superQualifier
|
||||
)
|
||||
@@ -99,57 +107,76 @@ class FieldPropertyLValue(
|
||||
|
||||
override fun withReceiver(dispatchReceiver: VariableLValue?, extensionReceiver: VariableLValue?): PropertyLValueBase =
|
||||
FieldPropertyLValue(
|
||||
context,
|
||||
scope, startOffset, endOffset, origin,
|
||||
field,
|
||||
type,
|
||||
SimpleCallReceiver(dispatchReceiver, extensionReceiver),
|
||||
superQualifier
|
||||
)
|
||||
}
|
||||
|
||||
class AccessorPropertyLValue(
|
||||
context: IrGeneratorContext,
|
||||
scope: Scope,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrStatementOrigin?,
|
||||
type: KotlinType,
|
||||
type: IrType,
|
||||
val getter: IrFunctionSymbol?,
|
||||
val getterDescriptor: FunctionDescriptor?,
|
||||
val setter: IrFunctionSymbol?,
|
||||
val setterDescriptor: FunctionDescriptor?,
|
||||
val typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
val typeArguments: List<IrType>?,
|
||||
callReceiver: CallReceiver,
|
||||
superQualifier: IrClassSymbol?
|
||||
) : PropertyLValueBase(scope, startOffset, endOffset, origin, type, callReceiver, superQualifier) {
|
||||
) : PropertyLValueBase(context, scope, startOffset, endOffset, origin, type, callReceiver, superQualifier) {
|
||||
|
||||
private val typeArgumentsCount = typeArguments?.size ?: 0
|
||||
|
||||
private fun IrMemberAccessExpression.putTypeArguments() {
|
||||
typeArguments?.forEachIndexed { index, irType ->
|
||||
putTypeArgument(index, irType)
|
||||
}
|
||||
}
|
||||
|
||||
override fun load(): IrExpression =
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
IrGetterCallImpl(
|
||||
startOffset, endOffset,
|
||||
type,
|
||||
getter!!, getterDescriptor!!,
|
||||
typeArguments,
|
||||
typeArgumentsCount,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
origin,
|
||||
superQualifier
|
||||
)
|
||||
).apply {
|
||||
putTypeArguments()
|
||||
}
|
||||
}
|
||||
|
||||
override fun store(irExpression: IrExpression) =
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
IrSetterCallImpl(
|
||||
startOffset, endOffset,
|
||||
context.irBuiltIns.unitType,
|
||||
setter!!, setterDescriptor!!,
|
||||
typeArguments,
|
||||
typeArgumentsCount,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
irExpression,
|
||||
origin,
|
||||
superQualifier
|
||||
)
|
||||
).apply {
|
||||
putTypeArguments()
|
||||
}
|
||||
}
|
||||
|
||||
override fun withReceiver(dispatchReceiver: VariableLValue?, extensionReceiver: VariableLValue?): PropertyLValueBase =
|
||||
AccessorPropertyLValue(
|
||||
scope, startOffset, endOffset, origin,
|
||||
context, scope,
|
||||
startOffset, endOffset, origin,
|
||||
type, getter, getterDescriptor, setter, setterDescriptor,
|
||||
typeArguments,
|
||||
SimpleCallReceiver(dispatchReceiver, extensionReceiver),
|
||||
|
||||
@@ -16,24 +16,28 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class RematerializableValue(val irExpression: IrExpressionWithCopy) : IntermediateValue {
|
||||
override val type: KotlinType get() = irExpression.type
|
||||
|
||||
override val type: IrType get() = irExpression.type
|
||||
|
||||
override fun load(): IrExpression = irExpression.copy()
|
||||
}
|
||||
|
||||
fun Scope.createTemporaryVariableInBlock(
|
||||
context: IrGeneratorContext,
|
||||
irExpression: IrExpression,
|
||||
block: IrContainerExpressionBase,
|
||||
nameHint: String? = null
|
||||
): IntermediateValue {
|
||||
val temporaryVariable = createTemporaryVariable(irExpression, nameHint)
|
||||
block.statements.add(temporaryVariable)
|
||||
return VariableLValue(temporaryVariable)
|
||||
return VariableLValue(context, temporaryVariable)
|
||||
}
|
||||
@@ -16,12 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.ir.builders.constNull
|
||||
import org.jetbrains.kotlin.ir.builders.equalsNull
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrIfThenElseImpl
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorWithScope
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
@@ -35,9 +35,10 @@ class SafeCallReceiver(
|
||||
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")
|
||||
val safeReceiverValue = VariableLValue(irTmp)
|
||||
val safeReceiverValue = VariableLValue(generator.context, irTmp)
|
||||
|
||||
val dispatchReceiverValue: IntermediateValue?
|
||||
val extensionReceiverValue: IntermediateValue?
|
||||
@@ -50,19 +51,17 @@ class SafeCallReceiver(
|
||||
}
|
||||
|
||||
val irResult = withDispatchAndExtensionReceivers(dispatchReceiverValue, extensionReceiverValue)
|
||||
val resultType = if (isAssignmentReceiver) irResult.type.builtIns.unitType else irResult.type.makeNullable()
|
||||
|
||||
val resultType = if (isAssignmentReceiver) generator.context.irBuiltIns.unitType else irResult.type.makeNullable()
|
||||
|
||||
val irBlock = IrBlockImpl(startOffset, endOffset, resultType, IrStatementOrigin.SAFE_CALL)
|
||||
|
||||
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 =
|
||||
generator.buildStatement(startOffset, endOffset, IrStatementOrigin.SAFE_CALL) {
|
||||
irIfNull(resultType, safeReceiverValue.load(), irNull(), irResult)
|
||||
}
|
||||
irBlock.statements.add(irIfThenElse)
|
||||
|
||||
return irBlock
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.ir.builders.constNull
|
||||
import org.jetbrains.kotlin.ir.builders.equalsNull
|
||||
import org.jetbrains.kotlin.ir.builders.irBlock
|
||||
import org.jetbrains.kotlin.ir.builders.irIfNull
|
||||
import org.jetbrains.kotlin.ir.builders.irNull
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrIfThenElseImpl
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorWithScope
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
|
||||
class SafeExtensionInvokeCallReceiver(
|
||||
val generator: GeneratorWithScope,
|
||||
@@ -33,6 +32,7 @@ class SafeExtensionInvokeCallReceiver(
|
||||
val functionReceiver: IntermediateValue,
|
||||
val extensionInvokeReceiver: IntermediateValue
|
||||
) : CallReceiver {
|
||||
|
||||
override fun call(withDispatchAndExtensionReceivers: (IntermediateValue?, IntermediateValue?) -> IrExpression): IrExpression {
|
||||
// extensionInvokeReceiver is actually a first argument:
|
||||
// receiver?.extFun(p1, ..., pN)
|
||||
@@ -42,7 +42,7 @@ class SafeExtensionInvokeCallReceiver(
|
||||
|
||||
val irTmp = generator.scope.createTemporaryVariable(extensionInvokeReceiver.load(), "safe_receiver")
|
||||
|
||||
val safeReceiverValue = VariableLValue(irTmp)
|
||||
val safeReceiverValue = VariableLValue(generator.context, irTmp)
|
||||
|
||||
// Patch call and generate it
|
||||
assert(callBuilder.irValueArgumentsByIndex[0] == null) {
|
||||
@@ -53,19 +53,14 @@ 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
|
||||
)
|
||||
return generator.irBlock(startOffset, endOffset, IrStatementOrigin.SAFE_CALL, resultType) {
|
||||
+irTmp
|
||||
+irIfNull(
|
||||
resultType,
|
||||
safeReceiverValue.load(), irNull(),
|
||||
irResult
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,10 @@ package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
|
||||
class SimpleCallReceiver(
|
||||
val dispatchReceiverValue: IntermediateValue?,
|
||||
val extensionReceiverValue: IntermediateValue?
|
||||
private val dispatchReceiverValue: IntermediateValue?,
|
||||
private val extensionReceiverValue: IntermediateValue?
|
||||
) : CallReceiver {
|
||||
|
||||
override fun call(withDispatchAndExtensionReceivers: (IntermediateValue?, IntermediateValue?) -> IrExpression): IrExpression {
|
||||
return withDispatchAndExtensionReceivers(dispatchReceiverValue, extensionReceiverValue)
|
||||
}
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class TransientReceiverValue(override val type: KotlinType) : IntermediateValue {
|
||||
class TransientReceiverValue(override val type: IrType) : IntermediateValue {
|
||||
|
||||
override fun load(): IrExpression {
|
||||
throw AssertionError("Transient receiver should not be instantiated")
|
||||
}
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
interface IntermediateValue {
|
||||
fun load(): IrExpression
|
||||
fun loadIfExists(): IrExpression? = load()
|
||||
val type: KotlinType
|
||||
val type: IrType
|
||||
}
|
||||
|
||||
interface LValue : IntermediateValue {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
@@ -23,27 +24,31 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSetVariableImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
|
||||
|
||||
class VariableLValue(
|
||||
private val context: IrGeneratorContext,
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val symbol: IrValueSymbol,
|
||||
override val type: IrType,
|
||||
val origin: IrStatementOrigin? = null
|
||||
) : LValue, AssignmentReceiver {
|
||||
constructor(irVariable: IrVariable, origin: IrStatementOrigin? = null) : this(
|
||||
irVariable.startOffset, irVariable.endOffset, irVariable.symbol, origin
|
||||
)
|
||||
) :
|
||||
LValue,
|
||||
AssignmentReceiver {
|
||||
|
||||
override val type: KotlinType get() = symbol.descriptor.type
|
||||
constructor(context: IrGeneratorContext, irVariable: IrVariable, origin: IrStatementOrigin? = null) :
|
||||
this(context, irVariable.startOffset, irVariable.endOffset, irVariable.symbol, irVariable.type, origin)
|
||||
|
||||
override fun load(): IrExpression =
|
||||
IrGetValueImpl(startOffset, endOffset, symbol, origin)
|
||||
IrGetValueImpl(startOffset, endOffset, type, symbol, origin)
|
||||
|
||||
override fun store(irExpression: IrExpression): IrExpression =
|
||||
IrSetVariableImpl(
|
||||
startOffset, endOffset,
|
||||
context.irBuiltIns.unitType,
|
||||
symbol.assertedCast<IrVariableSymbol> { "Not a variable: ${symbol.descriptor}" },
|
||||
irExpression, origin
|
||||
)
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.transformations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.generators.ConstantValueGenerator
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
fun generateAnnotationsForDeclarations(context: GeneratorContext, irElement: IrElement) {
|
||||
val annotationGenerator = AnnotationGenerator(context.moduleDescriptor, context.symbolTable)
|
||||
irElement.acceptVoid(annotationGenerator)
|
||||
}
|
||||
|
||||
class AnnotationGenerator(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
private val symbolTable: SymbolTable
|
||||
) : IrElementVisitorVoid {
|
||||
|
||||
constructor(context: GeneratorContext) : this(context.moduleDescriptor, context.symbolTable)
|
||||
|
||||
private val scopedTypeParameterResolver = ScopedTypeParametersResolver()
|
||||
private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable, this, scopedTypeParameterResolver)
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitDeclaration(declaration: IrDeclaration) {
|
||||
if (declaration is IrTypeParametersContainer) {
|
||||
scopedTypeParameterResolver.enterTypeParameterScope(declaration)
|
||||
}
|
||||
generateAnnotationsForDeclaration(declaration)
|
||||
visitElement(declaration)
|
||||
if (declaration is IrTypeParametersContainer) {
|
||||
scopedTypeParameterResolver.leaveTypeParameterScope()
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitValueParameter(declaration: IrValueParameter) {
|
||||
super.visitValueParameter(declaration)
|
||||
|
||||
val descriptor = declaration.descriptor
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
|
||||
if (containingDeclaration is PropertySetterDescriptor) {
|
||||
containingDeclaration.correspondingProperty.annotations.getUseSiteTargetedAnnotations()
|
||||
.filter { it.target == AnnotationUseSiteTarget.SETTER_PARAMETER }
|
||||
.generateAnnotationConstructorCalls(declaration)
|
||||
}
|
||||
|
||||
descriptor.type.annotations.getAllAnnotations()
|
||||
.filter { it.target == AnnotationUseSiteTarget.RECEIVER }
|
||||
.generateAnnotationConstructorCalls(declaration)
|
||||
}
|
||||
|
||||
private fun generateAnnotationsForDeclaration(declaration: IrDeclaration) {
|
||||
declaration.descriptor.annotations.getAllAnnotations()
|
||||
.filter { isAnnotationTargetMatchingDeclaration(it.target, declaration) }
|
||||
.generateAnnotationConstructorCalls(declaration)
|
||||
}
|
||||
|
||||
private fun List<AnnotationWithTarget>.generateAnnotationConstructorCalls(declaration: IrDeclaration) {
|
||||
mapTo(declaration.annotations) {
|
||||
generateAnnotationConstructorCall(it.annotation)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateAnnotationConstructorCall(annotationDescriptor: AnnotationDescriptor): IrCall {
|
||||
val annotationType = annotationDescriptor.type
|
||||
val annotationClassDescriptor = annotationType.constructor.declarationDescriptor as? ClassDescriptor
|
||||
?: throw AssertionError("No declaration descriptor for annotation $annotationDescriptor")
|
||||
assert(DescriptorUtils.isAnnotationClass(annotationClassDescriptor)) {
|
||||
"Annotation class expected: $annotationClassDescriptor"
|
||||
}
|
||||
|
||||
val primaryConstructorDescriptor =
|
||||
annotationClassDescriptor.unsubstitutedPrimaryConstructor
|
||||
?: annotationClassDescriptor.constructors.singleOrNull()
|
||||
?: throw AssertionError("No constructor for annotation class $annotationClassDescriptor")
|
||||
|
||||
val primaryConstructorSymbol = symbolTable.referenceConstructor(primaryConstructorDescriptor)
|
||||
|
||||
val psi = annotationDescriptor.source.safeAs<PsiSourceElement>()?.psi
|
||||
val startOffset = psi?.startOffset ?: UNDEFINED_OFFSET
|
||||
val endOffset = psi?.startOffset ?: UNDEFINED_OFFSET
|
||||
|
||||
val irCall = IrCallImpl(
|
||||
startOffset, endOffset, annotationType,
|
||||
primaryConstructorSymbol, primaryConstructorDescriptor,
|
||||
typeArgumentsCount = 0
|
||||
)
|
||||
|
||||
for (valueParameter in primaryConstructorDescriptor.valueParameters) {
|
||||
val argumentIndex = valueParameter.index
|
||||
val argumentValue = annotationDescriptor.allValueArguments[valueParameter.name] ?: continue
|
||||
val irArgument =
|
||||
constantValueGenerator.generateConstantValueAsExpression(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
argumentValue,
|
||||
valueParameter.varargElementType
|
||||
)
|
||||
irCall.putValueArgument(argumentIndex, irArgument)
|
||||
}
|
||||
|
||||
return irCall
|
||||
}
|
||||
|
||||
private fun isAnnotationTargetMatchingDeclaration(target: AnnotationUseSiteTarget?, element: IrElement): Boolean =
|
||||
when (element) {
|
||||
is IrProperty ->
|
||||
target == null || target == AnnotationUseSiteTarget.PROPERTY
|
||||
|
||||
is IrField ->
|
||||
target == AnnotationUseSiteTarget.FIELD || target == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
|
||||
|
||||
is IrSimpleFunction ->
|
||||
target == null || target == AnnotationUseSiteTarget.PROPERTY_GETTER || target == AnnotationUseSiteTarget.PROPERTY_SETTER
|
||||
|
||||
is IrValueParameter ->
|
||||
target == null || target == AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
|
||||
|
||||
else -> target == null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,17 +17,20 @@
|
||||
package org.jetbrains.kotlin.psi2ir.transformations
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
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.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.psi2ir.containsNull
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.isError
|
||||
@@ -36,26 +39,17 @@ import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
import org.jetbrains.kotlin.types.upperIfFlexible
|
||||
|
||||
fun insertImplicitCasts(builtIns: KotlinBuiltIns, element: IrElement, symbolTable: SymbolTable) {
|
||||
element.transformChildren(InsertImplicitCasts(builtIns, symbolTable), null)
|
||||
fun insertImplicitCasts(element: IrElement, context: GeneratorContext) {
|
||||
element.transformChildren(InsertImplicitCasts(context), null)
|
||||
}
|
||||
|
||||
class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symbolTable: SymbolTable) : IrElementTransformerVoid() {
|
||||
class InsertImplicitCasts(context: GeneratorContext) : IrElementTransformerVoid() {
|
||||
|
||||
private val typeParameterResolver = ScopedTypeParametersResolver()
|
||||
private val builtIns = context.builtIns
|
||||
private val irBuiltIns = context.irBuiltIns
|
||||
|
||||
private inline fun <T> runInTypeParameterScope(typeParametersContainer: IrTypeParametersContainer, fn: () -> T): T {
|
||||
typeParameterResolver.enterTypeParameterScope(typeParametersContainer)
|
||||
val result = fn()
|
||||
typeParameterResolver.leaveTypeParameterScope()
|
||||
return result
|
||||
}
|
||||
|
||||
private fun resolveScopedTypeParameter(classifier: ClassifierDescriptor): IrTypeParameterSymbol? =
|
||||
if (classifier is TypeParameterDescriptor)
|
||||
typeParameterResolver.resolveScopedTypeParameter(classifier)
|
||||
else
|
||||
null
|
||||
private val typeTranslator = context.typeTranslator
|
||||
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||
|
||||
override fun visitCallableReference(expression: IrCallableReference): IrExpression =
|
||||
expression.transformPostfix {
|
||||
@@ -128,7 +122,7 @@ class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symb
|
||||
}
|
||||
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement =
|
||||
runInTypeParameterScope(declaration) {
|
||||
typeTranslator.buildWithScope(declaration) {
|
||||
declaration.transformPostfix {
|
||||
valueParameters.forEach {
|
||||
it.defaultValue?.coerceInnerExpression(it.descriptor.type)
|
||||
@@ -137,7 +131,7 @@ class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symb
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass): IrStatement =
|
||||
runInTypeParameterScope(declaration) {
|
||||
typeTranslator.buildWithScope(declaration) {
|
||||
super.visitClass(declaration)
|
||||
}
|
||||
|
||||
@@ -187,13 +181,16 @@ class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symb
|
||||
expression = expression.cast(expectedType)
|
||||
}
|
||||
|
||||
private fun IrExpression.cast(irType: IrType): IrExpression =
|
||||
cast(irType.originalKotlinType)
|
||||
|
||||
private fun IrExpression.cast(expectedType: KotlinType?): IrExpression {
|
||||
if (expectedType == null) return this
|
||||
if (expectedType.isError) return this
|
||||
|
||||
val notNullableExpectedType = expectedType.makeNotNullable()
|
||||
|
||||
val valueType = this.type
|
||||
val valueType = this.type.originalKotlinType!!
|
||||
|
||||
return when {
|
||||
KotlinBuiltIns.isUnit(expectedType) ->
|
||||
@@ -224,26 +221,29 @@ class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symb
|
||||
targetType: KotlinType,
|
||||
typeOperator: IrTypeOperator
|
||||
): IrExpression {
|
||||
val typeDescriptor = targetType.constructor.declarationDescriptor
|
||||
?: throw AssertionError("No declaration for target type: $targetType")
|
||||
|
||||
val irType = targetType.toIrType()
|
||||
return IrTypeOperatorCallImpl(
|
||||
startOffset, endOffset,
|
||||
targetType, typeOperator, targetType, this,
|
||||
resolveScopedTypeParameter(typeDescriptor) ?: symbolTable.referenceClassifier(typeDescriptor)
|
||||
startOffset,
|
||||
endOffset,
|
||||
irType,
|
||||
typeOperator,
|
||||
irType, irType.classifierOrFail,
|
||||
this
|
||||
)
|
||||
}
|
||||
|
||||
private fun IrExpression.coerceToUnit(): IrExpression {
|
||||
val valueType = this.type
|
||||
val valueType = this.type.originalKotlinType!!
|
||||
|
||||
return if (KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, builtIns.unitType))
|
||||
this
|
||||
else
|
||||
IrTypeOperatorCallImpl(
|
||||
startOffset, endOffset, builtIns.unitType,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, this,
|
||||
symbolTable.referenceClass(builtIns.unit)
|
||||
startOffset, endOffset,
|
||||
irBuiltIns.unitType,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
|
||||
irBuiltIns.unitType, irBuiltIns.unitType.classifierOrFail,
|
||||
this
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.types
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrTypeImpl
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||
import org.jetbrains.kotlin.psi2ir.transformations.AnnotationGenerator
|
||||
import org.jetbrains.kotlin.psi2ir.transformations.ScopedTypeParametersResolver
|
||||
import org.jetbrains.kotlin.types.*
|
||||
|
||||
class TypeTranslator(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
private val symbolTable: SymbolTable
|
||||
) {
|
||||
|
||||
constructor(context: GeneratorContext) : this(context.moduleDescriptor, context.symbolTable)
|
||||
|
||||
private val annotationGenerator = AnnotationGenerator(moduleDescriptor, symbolTable)
|
||||
private val typeParametersResolver = ScopedTypeParametersResolver()
|
||||
|
||||
fun enterScope(irElement: IrTypeParametersContainer) {
|
||||
typeParametersResolver.enterTypeParameterScope(irElement)
|
||||
}
|
||||
|
||||
fun leaveScope() {
|
||||
typeParametersResolver.leaveTypeParameterScope()
|
||||
}
|
||||
|
||||
private fun resolveTypeParameter(typeParameterDescriptor: TypeParameterDescriptor) =
|
||||
typeParametersResolver.resolveScopedTypeParameter(typeParameterDescriptor)
|
||||
?: symbolTable.referenceTypeParameter(typeParameterDescriptor)
|
||||
|
||||
fun translateType(ktType: KotlinType): IrTypeImpl =
|
||||
translateType(ktType, Variance.INVARIANT)
|
||||
|
||||
private fun translateType(ktType: KotlinType, variance: Variance): IrTypeImpl {
|
||||
if (ktType.isFlexible()) {
|
||||
return translateType(ktType.upperIfFlexible(), variance)
|
||||
}
|
||||
|
||||
val ktTypeConstructor = ktType.constructor
|
||||
val ktTypeDescriptor = ktTypeConstructor.declarationDescriptor
|
||||
|
||||
return when (ktTypeDescriptor) {
|
||||
is TypeParameterDescriptor ->
|
||||
IrTypeImpl(
|
||||
resolveTypeParameter(ktTypeDescriptor),
|
||||
ktType.isMarkedNullable,
|
||||
emptyList(),
|
||||
translateTypeAnnotations(ktType.annotations),
|
||||
variance
|
||||
)
|
||||
|
||||
is ClassDescriptor ->
|
||||
IrTypeImpl(
|
||||
symbolTable.referenceClass(ktTypeDescriptor),
|
||||
ktType.isMarkedNullable,
|
||||
translateTypeArguments(ktType.arguments),
|
||||
translateTypeAnnotations(ktType.annotations),
|
||||
variance
|
||||
)
|
||||
|
||||
else ->
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateTypeAnnotations(annotations: Annotations): List<IrCall> =
|
||||
annotations.getAllAnnotations().map {
|
||||
// TODO filter out annotation targets
|
||||
annotationGenerator.generateAnnotationConstructorCall(it.annotation)
|
||||
}
|
||||
|
||||
private fun translateTypeArguments(arguments: List<TypeProjection>) =
|
||||
arguments.map {
|
||||
// TODO starProjection
|
||||
translateType(it.type, it.projectionKind)
|
||||
}
|
||||
|
||||
private inner class SimpleTranslationVisitor : IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitDeclaration(declaration: IrDeclaration) {
|
||||
if (declaration is IrTypeParametersContainer) {
|
||||
enterScope(declaration)
|
||||
}
|
||||
declaration.acceptChildrenVoid(this)
|
||||
if (declaration is IrTypeParametersContainer) {
|
||||
leaveScope()
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitExpression(expression: IrExpression) {
|
||||
translateType(expression.type)
|
||||
expression.acceptChildrenVoid(this)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun tryTranslateAllExpressionTypes(
|
||||
element: IrElement,
|
||||
context: GeneratorContext
|
||||
) {
|
||||
element.acceptVoid(TypeTranslator(context).SimpleTranslationVisitor())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ plugins {
|
||||
jvmTarget = "1.6"
|
||||
|
||||
dependencies {
|
||||
compile(intellijDep())
|
||||
compile(project(":compiler:util"))
|
||||
compile(project(":compiler:frontend"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.builders
|
||||
@@ -20,11 +9,15 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
|
||||
|
||||
|
||||
@@ -87,45 +80,70 @@ fun IrBuilderWithScope.irExprBody(value: IrExpression) =
|
||||
|
||||
fun IrBuilderWithScope.irReturn(value: IrExpression) =
|
||||
IrReturnImpl(
|
||||
startOffset, endOffset, context.builtIns.nothingType,
|
||||
startOffset, endOffset,
|
||||
context.irBuiltIns.nothingType,
|
||||
scope.scopeOwnerSymbol.assertedCast<IrReturnTargetSymbol> {
|
||||
"Function scope expected: ${scope.scopeOwner}"
|
||||
},
|
||||
value
|
||||
)
|
||||
|
||||
fun IrBuilderWithScope.irReturnTrue() =
|
||||
irReturn(IrConstImpl(startOffset, endOffset, context.builtIns.booleanType, IrConstKind.Boolean, true))
|
||||
fun IrBuilderWithScope.irBoolean(value: Boolean) =
|
||||
IrConstImpl(startOffset, endOffset, context.irBuiltIns.booleanType, IrConstKind.Boolean, value)
|
||||
|
||||
fun IrBuilderWithScope.irReturnFalse() =
|
||||
irReturn(IrConstImpl(startOffset, endOffset, context.builtIns.booleanType, IrConstKind.Boolean, false))
|
||||
fun IrBuilderWithScope.irTrue() = irBoolean(true)
|
||||
fun IrBuilderWithScope.irFalse() = irBoolean(false)
|
||||
fun IrBuilderWithScope.irReturnTrue() = irReturn(irTrue())
|
||||
fun IrBuilderWithScope.irReturnFalse() = irReturn(irFalse())
|
||||
|
||||
fun IrBuilderWithScope.irIfThenElse(type: KotlinType, condition: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
|
||||
IrIfThenElseImpl(startOffset, endOffset, type, condition, thenPart, elsePart)
|
||||
fun IrBuilderWithScope.irElseBranch(expression: IrExpression) =
|
||||
IrElseBranchImpl(startOffset, endOffset, irTrue(), expression)
|
||||
|
||||
fun IrBuilderWithScope.irIfNull(type: KotlinType, subject: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
|
||||
fun IrBuilderWithScope.irIfThen(type: IrType, condition: IrExpression, thenPart: IrExpression) =
|
||||
IrIfThenElseImpl(startOffset, endOffset, type).apply {
|
||||
branches.add(IrBranchImpl(startOffset, endOffset, condition, thenPart))
|
||||
}
|
||||
|
||||
fun IrBuilderWithScope.irIfThenElse(type: IrType, condition: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
|
||||
IrIfThenElseImpl(startOffset, endOffset, type).apply {
|
||||
branches.add(IrBranchImpl(startOffset, endOffset, condition, thenPart))
|
||||
branches.add(irElseBranch(elsePart))
|
||||
}
|
||||
|
||||
fun IrBuilderWithScope.irIfThenMaybeElse(type: IrType, condition: IrExpression, thenPart: IrExpression, elsePart: IrExpression?) =
|
||||
if (elsePart != null)
|
||||
irIfThenElse(type, condition, thenPart, elsePart)
|
||||
else
|
||||
irIfThen(type, condition, thenPart)
|
||||
|
||||
fun IrBuilderWithScope.irIfNull(type: IrType, subject: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
|
||||
irIfThenElse(type, irEqualsNull(subject), thenPart, elsePart)
|
||||
|
||||
fun IrBuilderWithScope.irThrowNpe(origin: IrStatementOrigin) =
|
||||
IrNullaryPrimitiveImpl(startOffset, endOffset, origin, context.irBuiltIns.throwNpeSymbol)
|
||||
IrNullaryPrimitiveImpl(startOffset, endOffset, context.irBuiltIns.nothingType, origin, context.irBuiltIns.throwNpeSymbol)
|
||||
|
||||
fun IrBuilderWithScope.irIfThenReturnTrue(condition: IrExpression) =
|
||||
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, irReturnTrue())
|
||||
irIfThen(context.irBuiltIns.unitType, condition, irReturnTrue())
|
||||
|
||||
fun IrBuilderWithScope.irIfThenReturnFalse(condition: IrExpression) =
|
||||
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, irReturnFalse())
|
||||
irIfThen(context.irBuiltIns.unitType, condition, irReturnFalse())
|
||||
|
||||
fun IrBuilderWithScope.irGet(variable: IrValueSymbol) =
|
||||
IrGetValueImpl(startOffset, endOffset, variable)
|
||||
fun IrBuilderWithScope.irGet(type: IrType, variable: IrValueSymbol) =
|
||||
IrGetValueImpl(startOffset, endOffset, type, variable)
|
||||
|
||||
fun IrBuilderWithScope.irGet(variable: IrValueDeclaration) = irGet(variable.type, variable.symbol)
|
||||
|
||||
fun IrBuilderWithScope.irSetVar(variable: IrVariableSymbol, value: IrExpression) =
|
||||
IrSetVariableImpl(startOffset, endOffset, variable, value, IrStatementOrigin.EQ)
|
||||
IrSetVariableImpl(startOffset, endOffset, context.irBuiltIns.unitType, variable, value, IrStatementOrigin.EQ)
|
||||
|
||||
fun IrBuilderWithScope.irGetField(receiver: IrExpression?, field: IrField) =
|
||||
IrGetFieldImpl(startOffset, endOffset, field.symbol, field.type, receiver)
|
||||
|
||||
fun IrBuilderWithScope.irEqeqeq(arg1: IrExpression, arg2: IrExpression) =
|
||||
context.eqeqeq(startOffset, endOffset, arg1, arg2)
|
||||
|
||||
fun IrBuilderWithScope.irNull() =
|
||||
IrConstImpl.constNull(startOffset, endOffset, context.builtIns.nullableNothingType)
|
||||
IrConstImpl.constNull(startOffset, endOffset, context.irBuiltIns.nothingNType)
|
||||
|
||||
fun IrBuilderWithScope.irEqualsNull(argument: IrExpression) =
|
||||
primitiveOp2(
|
||||
@@ -142,35 +160,30 @@ fun IrBuilderWithScope.irNotEquals(arg1: IrExpression, arg2: IrExpression) =
|
||||
)
|
||||
)
|
||||
|
||||
fun IrBuilderWithScope.irGet(receiver: IrExpression, getterSymbol: IrFunctionSymbol): IrCall =
|
||||
IrGetterCallImpl(startOffset, endOffset, getterSymbol, getterSymbol.descriptor, null, receiver, null, IrStatementOrigin.GET_PROPERTY)
|
||||
fun IrBuilderWithScope.irGet(type: IrType, receiver: IrExpression, getterSymbol: IrFunctionSymbol): IrCall =
|
||||
IrGetterCallImpl(
|
||||
startOffset, endOffset,
|
||||
type,
|
||||
getterSymbol, getterSymbol.descriptor,
|
||||
typeArgumentsCount = 0,
|
||||
dispatchReceiver = receiver,
|
||||
extensionReceiver = null,
|
||||
origin = IrStatementOrigin.GET_PROPERTY
|
||||
)
|
||||
|
||||
fun IrBuilderWithScope.irCall(
|
||||
callee: IrFunctionSymbol,
|
||||
type: KotlinType,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
|
||||
): IrCall =
|
||||
IrCallImpl(startOffset, endOffset, type, callee, callee.descriptor, typeArguments)
|
||||
fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol, type: IrType): IrCall =
|
||||
IrCallImpl(startOffset, endOffset, type, callee, callee.descriptor)
|
||||
|
||||
fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol): IrCall =
|
||||
irCall(callee, callee.descriptor.returnType!!)
|
||||
fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol, descriptor: FunctionDescriptor, type: IrType): IrCall =
|
||||
IrCallImpl(startOffset, endOffset, type, callee, descriptor)
|
||||
|
||||
fun IrBuilderWithScope.irCall(
|
||||
calleeSymbol: IrFunctionSymbol,
|
||||
calleeDescriptor: FunctionDescriptor,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
|
||||
): IrCall =
|
||||
IrCallImpl(startOffset, endOffset, calleeDescriptor.returnType!!, calleeSymbol, calleeDescriptor, typeArguments)
|
||||
fun IrBuilderWithScope.irCall(callee: IrFunction): IrCall =
|
||||
irCall(callee.symbol, callee.descriptor, callee.returnType)
|
||||
|
||||
fun IrBuilderWithScope.irCallOp(callee: IrFunctionSymbol, dispatchReceiver: IrExpression, argument: IrExpression): IrCall =
|
||||
irCall(callee, callee.descriptor.returnType!!).apply {
|
||||
this.dispatchReceiver = dispatchReceiver
|
||||
putValueArgument(0, argument)
|
||||
}
|
||||
|
||||
fun IrBuilderWithScope.irCallOp(
|
||||
callee: IrFunctionSymbol,
|
||||
type: KotlinType,
|
||||
type: IrType,
|
||||
dispatchReceiver: IrExpression,
|
||||
argument: IrExpression
|
||||
): IrCall =
|
||||
@@ -179,47 +192,31 @@ fun IrBuilderWithScope.irCallOp(
|
||||
putValueArgument(0, argument)
|
||||
}
|
||||
|
||||
@Deprecated("Creates unbound symbol")
|
||||
fun IrBuilderWithScope.irIs(argument: IrExpression, type: KotlinType) =
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.INSTANCEOF, type, argument)
|
||||
fun IrBuilderWithScope.typeOperator(
|
||||
resultType: IrType,
|
||||
argument: IrExpression,
|
||||
typeOperator: IrTypeOperator,
|
||||
typeOperand: IrType
|
||||
) =
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, resultType, typeOperator, typeOperand, typeOperand.classifierOrFail, argument)
|
||||
|
||||
fun IrBuilderWithScope.irIs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.INSTANCEOF, type, argument, typeClassifier)
|
||||
fun IrBuilderWithScope.irIs(argument: IrExpression, type: IrType) =
|
||||
typeOperator(context.irBuiltIns.booleanType, argument, IrTypeOperator.INSTANCEOF, type)
|
||||
|
||||
fun IrBuilderWithScope.irNotIs(argument: IrExpression, type: IrType) =
|
||||
typeOperator(context.irBuiltIns.booleanType, argument, IrTypeOperator.NOT_INSTANCEOF, type)
|
||||
|
||||
@Deprecated("Creates unbound symbol")
|
||||
fun IrBuilderWithScope.irNotIs(argument: IrExpression, type: KotlinType) =
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.NOT_INSTANCEOF, type, argument)
|
||||
|
||||
fun IrBuilderWithScope.irNotIs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
|
||||
IrTypeOperatorCallImpl(
|
||||
startOffset, endOffset,
|
||||
context.builtIns.booleanType,
|
||||
IrTypeOperator.NOT_INSTANCEOF,
|
||||
type, argument, typeClassifier
|
||||
)
|
||||
|
||||
|
||||
@Deprecated("Creates unbound symbol")
|
||||
fun IrBuilderWithScope.irAs(argument: IrExpression, type: KotlinType) =
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, type, argument)
|
||||
|
||||
fun IrBuilderWithScope.irAs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, type, argument, typeClassifier)
|
||||
|
||||
@Deprecated("Creates unbound symbol")
|
||||
fun IrBuilderWithScope.irImplicitCast(argument: IrExpression, type: KotlinType) =
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, argument)
|
||||
|
||||
fun IrBuilderWithScope.irImplicitCast(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, argument, typeClassifier)
|
||||
fun IrBuilderWithScope.irAs(argument: IrExpression, type: IrType) =
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, type, type.classifierOrFail, argument)
|
||||
|
||||
fun IrBuilderWithScope.irImplicitCast(argument: IrExpression, type: IrType) =
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, type.classifierOrFail, argument)
|
||||
|
||||
fun IrBuilderWithScope.irInt(value: Int) =
|
||||
IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, value)
|
||||
IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, value)
|
||||
|
||||
fun IrBuilderWithScope.irString(value: String) =
|
||||
IrConstImpl.string(startOffset, endOffset, context.builtIns.stringType, value)
|
||||
IrConstImpl.string(startOffset, endOffset, context.irBuiltIns.stringType, value)
|
||||
|
||||
fun IrBuilderWithScope.irConcat() =
|
||||
IrStringConcatenationImpl(startOffset, endOffset, context.builtIns.stringType)
|
||||
IrStringConcatenationImpl(startOffset, endOffset, context.irBuiltIns.stringType)
|
||||
|
||||
@@ -25,7 +25,8 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import java.util.*
|
||||
|
||||
abstract class IrBuilder(
|
||||
@@ -78,11 +79,14 @@ open class IrBlockBodyBuilder(
|
||||
}
|
||||
|
||||
class IrBlockBuilder(
|
||||
context: IrGeneratorContext, scope: Scope,
|
||||
startOffset: Int, endOffset: Int,
|
||||
context: IrGeneratorContext,
|
||||
scope: Scope,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
val origin: IrStatementOrigin? = null,
|
||||
var resultType: KotlinType? = null
|
||||
var resultType: IrType? = null
|
||||
) : IrStatementsBuilder<IrBlock>(context, scope, startOffset, endOffset) {
|
||||
|
||||
private val statements = ArrayList<IrStatement>()
|
||||
|
||||
inline fun block(body: IrBlockBuilder.() -> Unit): IrBlock {
|
||||
@@ -95,22 +99,52 @@ class IrBlockBuilder(
|
||||
}
|
||||
|
||||
override fun doBuild(): IrBlock {
|
||||
val resultType = this.resultType ?: (statements.lastOrNull() as? IrExpression)?.type ?: context.builtIns.unitType
|
||||
val resultType = this.resultType
|
||||
?: statements.lastOrNull().safeAs<IrExpression>()?.type
|
||||
?: context.irBuiltIns.unitType
|
||||
val irBlock = IrBlockImpl(startOffset, endOffset, resultType, origin)
|
||||
irBlock.statements.addAll(statements)
|
||||
return irBlock
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : IrBuilder> T.at(startOffset: Int, endOffset: Int): T {
|
||||
class IrSingleStatementBuilder(
|
||||
context: IrGeneratorContext,
|
||||
scope: Scope,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
val origin: IrStatementOrigin? = null
|
||||
) : IrBuilderWithScope(context, scope, startOffset, endOffset) {
|
||||
|
||||
inline fun <T : IrElement> build(statementBuilder: IrSingleStatementBuilder.() -> T): T =
|
||||
statementBuilder()
|
||||
}
|
||||
|
||||
inline fun <T : IrElement> IrGeneratorWithScope.buildStatement(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrStatementOrigin?,
|
||||
builder: IrSingleStatementBuilder.() -> T
|
||||
) =
|
||||
IrSingleStatementBuilder(context, scope, startOffset, endOffset, origin).builder()
|
||||
|
||||
inline fun <T : IrElement> IrGeneratorWithScope.buildStatement(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
builder: IrSingleStatementBuilder.() -> T
|
||||
) =
|
||||
IrSingleStatementBuilder(context, scope, startOffset, endOffset).builder()
|
||||
|
||||
fun <T : IrBuilder> T.at(startOffset: Int, endOffset: Int) = apply {
|
||||
this.startOffset = startOffset
|
||||
this.endOffset = endOffset
|
||||
return this
|
||||
}
|
||||
|
||||
inline fun IrGeneratorWithScope.irBlock(
|
||||
startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET,
|
||||
origin: IrStatementOrigin? = null, resultType: KotlinType? = null,
|
||||
startOffset: Int = UNDEFINED_OFFSET,
|
||||
endOffset: Int = UNDEFINED_OFFSET,
|
||||
origin: IrStatementOrigin? = null,
|
||||
resultType: IrType? = null,
|
||||
body: IrBlockBuilder.() -> Unit
|
||||
): IrExpression =
|
||||
IrBlockBuilder(
|
||||
@@ -129,3 +163,4 @@ inline fun IrGeneratorWithScope.irBlockBody(
|
||||
startOffset,
|
||||
endOffset
|
||||
).blockBody(body)
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@ interface IrGeneratorWithScope : IrGenerator {
|
||||
val scope: Scope
|
||||
}
|
||||
|
||||
open class IrGeneratorContext(val irBuiltIns: IrBuiltIns) {
|
||||
abstract class IrGeneratorContext {
|
||||
abstract val irBuiltIns: IrBuiltIns
|
||||
|
||||
val builtIns: KotlinBuiltIns get() = irBuiltIns.builtIns
|
||||
}
|
||||
}
|
||||
|
||||
open class IrGeneratorContextBase(override val irBuiltIns: IrBuiltIns) : IrGeneratorContext()
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.putDefault
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
|
||||
// This class can be used by kotlin-native.
|
||||
@Suppress("unused")
|
||||
@@ -33,6 +34,7 @@ class IrMemberFunctionBuilder(
|
||||
context: IrGeneratorContext,
|
||||
val irClass: IrClass,
|
||||
val function: FunctionDescriptor,
|
||||
val returnType: IrType,
|
||||
val origin: IrDeclarationOrigin,
|
||||
startOffset: Int = UNDEFINED_OFFSET,
|
||||
endOffset: Int = UNDEFINED_OFFSET
|
||||
@@ -43,6 +45,7 @@ class IrMemberFunctionBuilder(
|
||||
irFunction = IrFunctionImpl(startOffset, endOffset, origin, function)
|
||||
body(irFunction)
|
||||
irFunction.body = doBuild()
|
||||
irFunction.returnType = returnType
|
||||
irClass.declarations.add(irFunction)
|
||||
return irFunction
|
||||
}
|
||||
|
||||
@@ -16,19 +16,22 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.builders
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrElseBranch
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.IrWhen
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
|
||||
// TODO rewrite using IR Builders
|
||||
|
||||
fun primitiveOp1(
|
||||
startOffset: Int, endOffset: Int,
|
||||
primitiveOpSymbol: IrSimpleFunctionSymbol,
|
||||
origin: IrStatementOrigin,
|
||||
argument: IrExpression
|
||||
): IrExpression =
|
||||
IrUnaryPrimitiveImpl(startOffset, endOffset, origin, primitiveOpSymbol, argument)
|
||||
IrUnaryPrimitiveImpl(startOffset, endOffset, primitiveOpSymbol.owner.returnType, origin, primitiveOpSymbol, argument)
|
||||
|
||||
fun primitiveOp2(
|
||||
startOffset: Int, endOffset: Int,
|
||||
@@ -36,10 +39,10 @@ fun primitiveOp2(
|
||||
origin: IrStatementOrigin,
|
||||
argument1: IrExpression, argument2: IrExpression
|
||||
): IrExpression =
|
||||
IrBinaryPrimitiveImpl(startOffset, endOffset, origin, primitiveOpSymbol, argument1, argument2)
|
||||
IrBinaryPrimitiveImpl(startOffset, endOffset, primitiveOpSymbol.owner.returnType, origin, primitiveOpSymbol, argument1, argument2)
|
||||
|
||||
fun IrGeneratorContext.constNull(startOffset: Int, endOffset: Int): IrExpression =
|
||||
IrConstImpl.constNull(startOffset, endOffset, builtIns.nullableNothingType)
|
||||
IrConstImpl.constNull(startOffset, endOffset, irBuiltIns.nothingNType)
|
||||
|
||||
fun IrGeneratorContext.equalsNull(startOffset: Int, endOffset: Int, argument: IrExpression): IrExpression =
|
||||
primitiveOp2(
|
||||
@@ -51,7 +54,19 @@ fun IrGeneratorContext.eqeqeq(startOffset: Int, endOffset: Int, argument1: IrExp
|
||||
primitiveOp2(startOffset, endOffset, irBuiltIns.eqeqeqSymbol, IrStatementOrigin.EQEQEQ, argument1, argument2)
|
||||
|
||||
fun IrGeneratorContext.throwNpe(startOffset: Int, endOffset: Int, origin: IrStatementOrigin): IrExpression =
|
||||
IrNullaryPrimitiveImpl(startOffset, endOffset, origin, irBuiltIns.throwNpeSymbol)
|
||||
IrNullaryPrimitiveImpl(startOffset, endOffset, irBuiltIns.nothingType, origin, irBuiltIns.throwNpeSymbol)
|
||||
|
||||
fun IrGeneratorContext.constTrue(startOffset: Int, endOffset: Int) =
|
||||
IrConstImpl.constTrue(startOffset, endOffset, irBuiltIns.booleanType)
|
||||
|
||||
fun IrGeneratorContext.constFalse(startOffset: Int, endOffset: Int) =
|
||||
IrConstImpl.constFalse(startOffset, endOffset, irBuiltIns.booleanType)
|
||||
|
||||
fun IrGeneratorContext.elseBranch(elseExpr: IrExpression): IrElseBranch {
|
||||
val startOffset = elseExpr.startOffset
|
||||
val endOffset = elseExpr.endOffset
|
||||
return IrElseBranchImpl(startOffset, endOffset, constTrue(startOffset, endOffset), elseExpr)
|
||||
}
|
||||
|
||||
// a || b == if (a) true else b
|
||||
fun IrGeneratorContext.oror(
|
||||
@@ -61,11 +76,10 @@ fun IrGeneratorContext.oror(
|
||||
b: IrExpression,
|
||||
origin: IrStatementOrigin = IrStatementOrigin.OROR
|
||||
): IrWhen =
|
||||
IrIfThenElseImpl(
|
||||
startOffset, endOffset, builtIns.booleanType,
|
||||
a, IrConstImpl.constTrue(b.startOffset, b.endOffset, builtIns.booleanType), b,
|
||||
origin
|
||||
)
|
||||
IrIfThenElseImpl(startOffset, endOffset, irBuiltIns.booleanType, origin).apply {
|
||||
branches.add(IrBranchImpl(a, constTrue(a.startOffset, a.endOffset)))
|
||||
branches.add(elseBranch(b))
|
||||
}
|
||||
|
||||
fun IrGeneratorContext.oror(a: IrExpression, b: IrExpression, origin: IrStatementOrigin = IrStatementOrigin.OROR): IrWhen =
|
||||
oror(b.startOffset, b.endOffset, a, b, origin)
|
||||
@@ -81,11 +95,10 @@ fun IrGeneratorContext.andand(
|
||||
b: IrExpression,
|
||||
origin: IrStatementOrigin = IrStatementOrigin.ANDAND
|
||||
): IrWhen =
|
||||
IrIfThenElseImpl(
|
||||
startOffset, endOffset, builtIns.booleanType,
|
||||
a, b, IrConstImpl.constFalse(b.startOffset, b.endOffset, builtIns.booleanType),
|
||||
origin
|
||||
)
|
||||
IrIfThenElseImpl(startOffset, endOffset, irBuiltIns.booleanType, origin).apply {
|
||||
branches.add(IrBranchImpl(a, b))
|
||||
branches.add(elseBranch(constFalse(b.startOffset, b.endOffset)))
|
||||
}
|
||||
|
||||
fun IrGeneratorContext.andand(a: IrExpression, b: IrExpression, origin: IrStatementOrigin = IrStatementOrigin.ANDAND): IrWhen =
|
||||
andand(b.startOffset, b.endOffset, a, b, origin)
|
||||
@@ -30,6 +30,8 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
@@ -42,7 +44,7 @@ class Scope(val scopeOwnerSymbol: IrSymbol) {
|
||||
private var lastTemporaryIndex: Int = 0
|
||||
private fun nextTemporaryIndex(): Int = lastTemporaryIndex++
|
||||
|
||||
fun createDescriptorForTemporaryVariable(
|
||||
private fun createDescriptorForTemporaryVariable(
|
||||
type: KotlinType,
|
||||
nameHint: String? = null,
|
||||
isMutable: Boolean = false
|
||||
@@ -59,12 +61,18 @@ class Scope(val scopeOwnerSymbol: IrSymbol) {
|
||||
nameHint: String? = null,
|
||||
isMutable: Boolean = false,
|
||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE
|
||||
): IrVariable =
|
||||
IrVariableImpl(
|
||||
): IrVariable {
|
||||
val originalKotlinType = irExpression.type.originalKotlinType ?: irExpression.type.toKotlinType()
|
||||
return IrVariableImpl(
|
||||
irExpression.startOffset, irExpression.endOffset, origin,
|
||||
createDescriptorForTemporaryVariable(irExpression.type, nameHint, isMutable),
|
||||
createDescriptorForTemporaryVariable(
|
||||
originalKotlinType,
|
||||
nameHint, isMutable
|
||||
),
|
||||
irExpression.type,
|
||||
irExpression
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DeprecatedCallableAddReplaceWith")
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
interface IrClass : IrSymbolDeclaration<IrClassSymbol>, IrDeclarationContainer, IrTypeParametersContainer {
|
||||
@@ -35,8 +36,7 @@ interface IrClass : IrSymbolDeclaration<IrClassSymbol>, IrDeclarationContainer,
|
||||
val isData: Boolean
|
||||
val isExternal: Boolean
|
||||
|
||||
// NB type parameters can't be top-level classifiers in supetypes of a class
|
||||
val superClasses: MutableList<IrClassSymbol>
|
||||
val superTypes: MutableList<IrType>
|
||||
|
||||
var thisReceiver: IrValueParameter?
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
interface IrField : IrSymbolDeclaration<IrFieldSymbol> {
|
||||
override val descriptor: PropertyDescriptor
|
||||
|
||||
val name: Name
|
||||
val type: KotlinType
|
||||
val type: IrType
|
||||
val visibility: Visibility
|
||||
val isFinal: Boolean
|
||||
val isExternal: Boolean
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
|
||||
interface IrFunction : IrDeclaration, IrTypeParametersContainer, IrSymbolOwner, IrDeclarationParent, IrReturnTarget {
|
||||
override val descriptor: FunctionDescriptor
|
||||
@@ -33,7 +33,7 @@ interface IrFunction : IrDeclaration, IrTypeParametersContainer, IrSymbolOwner,
|
||||
val visibility: Visibility
|
||||
val isInline: Boolean // NB: there's an inline constructor for Array and each primitive array class
|
||||
val isExternal: Boolean
|
||||
val returnType: KotlinType
|
||||
var returnType: IrType
|
||||
|
||||
var dispatchReceiverParameter: IrValueParameter?
|
||||
var extensionReceiverParameter: IrValueParameter?
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
interface IrLocalDelegatedProperty : IrDeclaration {
|
||||
override val descriptor: VariableDescriptorWithAccessors
|
||||
|
||||
val name: Name
|
||||
val type: KotlinType
|
||||
val type: IrType
|
||||
val isVar: Boolean
|
||||
|
||||
var delegate: IrVariable
|
||||
|
||||
@@ -19,14 +19,13 @@ package org.jetbrains.kotlin.ir.declarations
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
interface IrProperty : IrDeclaration {
|
||||
override val descriptor: PropertyDescriptor
|
||||
|
||||
val name: Name
|
||||
val type: KotlinType
|
||||
val modality: Modality
|
||||
val visibility: Visibility
|
||||
val isVar: Boolean
|
||||
|
||||
@@ -19,9 +19,9 @@ package org.jetbrains.kotlin.ir.declarations
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
interface IrTypeParameter : IrSymbolDeclaration<IrTypeParameterSymbol> {
|
||||
@@ -30,9 +30,7 @@ interface IrTypeParameter : IrSymbolDeclaration<IrTypeParameterSymbol> {
|
||||
val name: Name
|
||||
val variance: Variance
|
||||
val index: Int
|
||||
val upperBounds: List<KotlinType>
|
||||
|
||||
val superClassifiers: MutableList<IrClassifierSymbol>
|
||||
val superTypes: MutableList<IrType>
|
||||
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrTypeParameter
|
||||
}
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
@@ -15,5 +16,5 @@ interface IrValueDeclaration : IrDeclaration, IrSymbolOwner {
|
||||
override val symbol: IrValueSymbol
|
||||
|
||||
val name: Name
|
||||
val type: KotlinType
|
||||
val type: IrType
|
||||
}
|
||||
@@ -19,14 +19,14 @@ package org.jetbrains.kotlin.ir.declarations
|
||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
interface IrValueParameter : IrValueDeclaration, IrSymbolDeclaration<IrValueParameterSymbol> {
|
||||
override val descriptor: ParameterDescriptor
|
||||
|
||||
val index: Int
|
||||
val varargElementType: KotlinType?
|
||||
val varargElementType: IrType?
|
||||
val isCrossinline: Boolean
|
||||
val isNoinline: Boolean
|
||||
|
||||
|
||||
@@ -30,12 +30,22 @@ class IrAnonymousInitializerImpl(
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
override val symbol: IrAnonymousInitializerSymbol
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin), IrAnonymousInitializer {
|
||||
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor) :
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin),
|
||||
IrAnonymousInitializer {
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: ClassDescriptor
|
||||
) :
|
||||
this(startOffset, endOffset, origin, IrAnonymousInitializerSymbolImpl(descriptor))
|
||||
|
||||
constructor(
|
||||
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: ClassDescriptor,
|
||||
body: IrBlockBody
|
||||
) : this(startOffset, endOffset, origin, descriptor) {
|
||||
this.body = body
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.transform
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
@@ -43,10 +44,16 @@ class IrClassImpl(
|
||||
override val isInner: Boolean,
|
||||
override val isData: Boolean,
|
||||
override val isExternal: Boolean
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin),
|
||||
) :
|
||||
IrDeclarationBase(startOffset, endOffset, origin),
|
||||
IrClass {
|
||||
|
||||
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, symbol: IrClassSymbol) :
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
symbol: IrClassSymbol
|
||||
) :
|
||||
this(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
symbol.descriptor.name, symbol.descriptor.kind,
|
||||
@@ -57,11 +64,19 @@ class IrClassImpl(
|
||||
isExternal = symbol.descriptor.isEffectivelyExternal()
|
||||
)
|
||||
|
||||
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor) :
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: ClassDescriptor
|
||||
) :
|
||||
this(startOffset, endOffset, origin, IrClassSymbolImpl(descriptor))
|
||||
|
||||
constructor(
|
||||
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: ClassDescriptor,
|
||||
members: List<IrDeclaration>
|
||||
) : this(startOffset, endOffset, origin, descriptor) {
|
||||
addAll(members)
|
||||
@@ -79,7 +94,7 @@ class IrClassImpl(
|
||||
|
||||
override val typeParameters: MutableList<IrTypeParameter> = SmartList()
|
||||
|
||||
override val superClasses: MutableList<IrClassSymbol> = SmartList()
|
||||
override val superTypes: MutableList<IrType> = SmartList()
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitClass(this, data)
|
||||
|
||||
@@ -23,10 +23,10 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class IrConstructorImpl(
|
||||
startOffset: Int,
|
||||
@@ -35,14 +35,13 @@ class IrConstructorImpl(
|
||||
override val symbol: IrConstructorSymbol,
|
||||
name: Name,
|
||||
visibility: Visibility,
|
||||
returnType: KotlinType,
|
||||
isInline: Boolean,
|
||||
isExternal: Boolean,
|
||||
override val isPrimary: Boolean
|
||||
) :
|
||||
IrFunctionBase(
|
||||
startOffset, endOffset, origin, name,
|
||||
visibility, isInline, isExternal, returnType
|
||||
visibility, isInline, isExternal
|
||||
),
|
||||
IrConstructor {
|
||||
|
||||
@@ -56,7 +55,6 @@ class IrConstructorImpl(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
symbol.descriptor.name,
|
||||
symbol.descriptor.visibility,
|
||||
symbol.descriptor.returnType,
|
||||
symbol.descriptor.isInline,
|
||||
symbol.descriptor.isEffectivelyExternal(),
|
||||
symbol.descriptor.isPrimary
|
||||
@@ -71,7 +69,7 @@ class IrConstructorImpl(
|
||||
descriptor: ClassConstructorDescriptor
|
||||
) : this(startOffset, endOffset, origin, IrConstructorSymbolImpl(descriptor))
|
||||
|
||||
@Deprecated("Let use constructor which takes symbol instead of descriptor")
|
||||
@Deprecated("Use constructor which takes symbol instead of descriptor")
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
|
||||
@@ -36,15 +36,29 @@ class IrEnumEntryImpl(
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin),
|
||||
IrEnumEntry {
|
||||
|
||||
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, symbol: IrEnumEntrySymbol) :
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
symbol: IrEnumEntrySymbol
|
||||
) :
|
||||
this(startOffset, endOffset, origin, symbol, symbol.descriptor.name)
|
||||
|
||||
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor) :
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: ClassDescriptor
|
||||
) :
|
||||
this(startOffset, endOffset, origin, IrEnumEntrySymbolImpl(descriptor))
|
||||
|
||||
constructor(
|
||||
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
|
||||
correspondingClass: IrClass?, initializerExpression: IrExpression?
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: ClassDescriptor,
|
||||
correspondingClass: IrClass?,
|
||||
initializerExpression: IrExpression?
|
||||
) : this(startOffset, endOffset, origin, descriptor) {
|
||||
this.correspondingClass = correspondingClass
|
||||
this.initializerExpression = initializerExpression
|
||||
|
||||
@@ -29,7 +29,8 @@ import org.jetbrains.kotlin.name.FqName
|
||||
class IrExternalPackageFragmentImpl(
|
||||
override val symbol: IrExternalPackageFragmentSymbol,
|
||||
override val fqName: FqName
|
||||
) : IrExternalPackageFragment, IrElementBase(UNDEFINED_OFFSET, UNDEFINED_OFFSET) {
|
||||
) : IrElementBase(UNDEFINED_OFFSET, UNDEFINED_OFFSET),
|
||||
IrExternalPackageFragment {
|
||||
|
||||
constructor(symbol: IrExternalPackageFragmentSymbol) : this(symbol, symbol.descriptor.fqName)
|
||||
|
||||
|
||||
@@ -23,11 +23,11 @@ import org.jetbrains.kotlin.ir.declarations.IrField
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
|
||||
class IrFieldImpl(
|
||||
@@ -36,34 +36,44 @@ class IrFieldImpl(
|
||||
origin: IrDeclarationOrigin,
|
||||
override val symbol: IrFieldSymbol,
|
||||
override val name: Name,
|
||||
override val type: KotlinType,
|
||||
override val type: IrType,
|
||||
override val visibility: Visibility,
|
||||
override val isFinal: Boolean,
|
||||
override val isExternal: Boolean
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin), IrField {
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin),
|
||||
IrField {
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
symbol: IrFieldSymbol,
|
||||
initializer: IrExpressionBody? = null
|
||||
) : this(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
symbol.descriptor.name, symbol.descriptor.type, symbol.descriptor.visibility,
|
||||
!symbol.descriptor.isVar,
|
||||
symbol.descriptor.isEffectivelyExternal()
|
||||
) {
|
||||
this.initializer = initializer
|
||||
}
|
||||
|
||||
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: PropertyDescriptor) :
|
||||
this(startOffset, endOffset, origin, IrFieldSymbolImpl(descriptor))
|
||||
type: IrType
|
||||
) :
|
||||
this(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
symbol.descriptor.name, type, symbol.descriptor.visibility,
|
||||
isFinal = !symbol.descriptor.isVar,
|
||||
isExternal = symbol.descriptor.isEffectivelyExternal()
|
||||
)
|
||||
|
||||
constructor(
|
||||
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: PropertyDescriptor,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: PropertyDescriptor,
|
||||
type: IrType
|
||||
) :
|
||||
this(startOffset, endOffset, origin, IrFieldSymbolImpl(descriptor), type)
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: PropertyDescriptor,
|
||||
type: IrType,
|
||||
initializer: IrExpressionBody?
|
||||
) : this(startOffset, endOffset, origin, descriptor) {
|
||||
) : this(startOffset, endOffset, origin, descriptor, type) {
|
||||
this.initializer = initializer
|
||||
}
|
||||
|
||||
|
||||
@@ -34,12 +34,20 @@ class IrFileImpl(
|
||||
override val fileEntry: SourceManager.FileEntry,
|
||||
override val symbol: IrFileSymbol,
|
||||
override val fqName: FqName
|
||||
) : IrElementBase(0, fileEntry.maxOffset), IrFile {
|
||||
) :
|
||||
IrElementBase(0, fileEntry.maxOffset),
|
||||
IrFile {
|
||||
|
||||
constructor(fileEntry: SourceManager.FileEntry, symbol: IrFileSymbol) :
|
||||
constructor(
|
||||
fileEntry: SourceManager.FileEntry,
|
||||
symbol: IrFileSymbol
|
||||
) :
|
||||
this(fileEntry, symbol, symbol.descriptor.fqName)
|
||||
|
||||
constructor(fileEntry: SourceManager.FileEntry, packageFragmentDescriptor: PackageFragmentDescriptor) :
|
||||
constructor(
|
||||
fileEntry: SourceManager.FileEntry,
|
||||
packageFragmentDescriptor: PackageFragmentDescriptor
|
||||
) :
|
||||
this(fileEntry, IrFileSymbolImpl(packageFragmentDescriptor), packageFragmentDescriptor.fqName)
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -22,11 +22,11 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.transform
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
abstract class IrFunctionBase(
|
||||
@@ -36,9 +36,11 @@ abstract class IrFunctionBase(
|
||||
override val name: Name,
|
||||
override val visibility: Visibility,
|
||||
override val isInline: Boolean,
|
||||
override val isExternal: Boolean,
|
||||
override val returnType: KotlinType
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin), IrFunction {
|
||||
override val isExternal: Boolean
|
||||
) :
|
||||
IrDeclarationBase(startOffset, endOffset, origin),
|
||||
IrFunction {
|
||||
|
||||
override val typeParameters: MutableList<IrTypeParameter> = SmartList()
|
||||
|
||||
override var dispatchReceiverParameter: IrValueParameter? = null
|
||||
@@ -47,6 +49,8 @@ abstract class IrFunctionBase(
|
||||
|
||||
final override var body: IrBody? = null
|
||||
|
||||
final override lateinit var returnType: IrType
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
typeParameters.forEach { it.accept(visitor, data) }
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
class IrFunctionImpl(
|
||||
@@ -35,18 +35,33 @@ class IrFunctionImpl(
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
override val symbol: IrSimpleFunctionSymbol,
|
||||
name: Name = symbol.descriptor.name,
|
||||
visibility: Visibility = symbol.descriptor.visibility,
|
||||
override val modality: Modality = symbol.descriptor.modality,
|
||||
returnType: KotlinType = symbol.descriptor.returnType!!,
|
||||
isInline: Boolean = symbol.descriptor.isInline,
|
||||
isExternal: Boolean = symbol.descriptor.isExternal,
|
||||
override val isTailrec: Boolean = symbol.descriptor.isTailrec,
|
||||
override val isSuspend: Boolean = symbol.descriptor.isSuspend
|
||||
name: Name,
|
||||
visibility: Visibility,
|
||||
override val modality: Modality,
|
||||
isInline: Boolean,
|
||||
isExternal: Boolean,
|
||||
override val isTailrec: Boolean,
|
||||
override val isSuspend: Boolean
|
||||
) :
|
||||
IrFunctionBase(startOffset, endOffset, origin, name, visibility, isInline, isExternal, returnType),
|
||||
IrFunctionBase(startOffset, endOffset, origin, name, visibility, isInline, isExternal),
|
||||
IrSimpleFunction {
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
symbol: IrSimpleFunctionSymbol
|
||||
) : this(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
symbol.descriptor.name,
|
||||
symbol.descriptor.visibility,
|
||||
symbol.descriptor.modality,
|
||||
symbol.descriptor.isInline,
|
||||
symbol.descriptor.isExternal,
|
||||
symbol.descriptor.isTailrec,
|
||||
symbol.descriptor.isSuspend
|
||||
)
|
||||
|
||||
override val descriptor: FunctionDescriptor = symbol.descriptor
|
||||
|
||||
override val overriddenSymbols: MutableList<IrSimpleFunctionSymbol> = SmartList()
|
||||
|
||||
@@ -21,10 +21,10 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrLocalDelegatedProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class IrLocalDelegatedPropertyImpl(
|
||||
startOffset: Int,
|
||||
@@ -32,19 +32,21 @@ class IrLocalDelegatedPropertyImpl(
|
||||
origin: IrDeclarationOrigin,
|
||||
override val descriptor: VariableDescriptorWithAccessors,
|
||||
override val name: Name,
|
||||
override val type: KotlinType,
|
||||
override val type: IrType,
|
||||
override val isVar: Boolean
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin),
|
||||
) :
|
||||
IrDeclarationBase(startOffset, endOffset, origin),
|
||||
IrLocalDelegatedProperty {
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: VariableDescriptorWithAccessors
|
||||
descriptor: VariableDescriptorWithAccessors,
|
||||
type: IrType
|
||||
) : this(
|
||||
startOffset, endOffset, origin, descriptor,
|
||||
descriptor.name, descriptor.type, descriptor.isVar
|
||||
descriptor.name, type, descriptor.isVar
|
||||
)
|
||||
|
||||
constructor(
|
||||
@@ -52,8 +54,9 @@ class IrLocalDelegatedPropertyImpl(
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: VariableDescriptorWithAccessors,
|
||||
type: IrType,
|
||||
delegate: IrVariable
|
||||
) : this(startOffset, endOffset, origin, descriptor) {
|
||||
) : this(startOffset, endOffset, origin, descriptor, type) {
|
||||
this.delegate = delegate
|
||||
}
|
||||
|
||||
@@ -62,10 +65,11 @@ class IrLocalDelegatedPropertyImpl(
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: VariableDescriptorWithAccessors,
|
||||
type: IrType,
|
||||
delegate: IrVariable,
|
||||
getter: IrFunction,
|
||||
setter: IrFunction?
|
||||
) : this(startOffset, endOffset, origin, descriptor) {
|
||||
) : this(startOffset, endOffset, origin, descriptor, type) {
|
||||
this.delegate = delegate
|
||||
this.getter = getter
|
||||
this.setter = setter
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
class IrPropertyImpl(
|
||||
@@ -34,7 +33,6 @@ class IrPropertyImpl(
|
||||
origin: IrDeclarationOrigin,
|
||||
override val descriptor: PropertyDescriptor,
|
||||
override val name: Name,
|
||||
override val type: KotlinType,
|
||||
override val visibility: Visibility,
|
||||
override val modality: Modality,
|
||||
override val isVar: Boolean,
|
||||
@@ -53,7 +51,7 @@ class IrPropertyImpl(
|
||||
descriptor: PropertyDescriptor
|
||||
) : this(
|
||||
startOffset, endOffset, origin, descriptor,
|
||||
descriptor.name, descriptor.type, descriptor.visibility, descriptor.modality,
|
||||
descriptor.name, descriptor.visibility, descriptor.modality,
|
||||
isVar = descriptor.isVar,
|
||||
isConst = descriptor.isConst,
|
||||
isLateinit = descriptor.isLateInit,
|
||||
|
||||
@@ -27,7 +27,10 @@ class IrTypeAliasImpl(
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
override val descriptor: TypeAliasDescriptor
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin), IrTypeAlias {
|
||||
) :
|
||||
IrDeclarationBase(startOffset, endOffset, origin),
|
||||
IrTypeAlias {
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitTypeAlias(this, data)
|
||||
}
|
||||
|
||||
@@ -19,13 +19,12 @@ package org.jetbrains.kotlin.ir.declarations.impl
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
@@ -36,20 +35,30 @@ class IrTypeParameterImpl(
|
||||
override val symbol: IrTypeParameterSymbol,
|
||||
override val name: Name,
|
||||
override val index: Int,
|
||||
override val variance: Variance,
|
||||
override val upperBounds: List<KotlinType>
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin), IrTypeParameter {
|
||||
override val variance: Variance
|
||||
) :
|
||||
IrDeclarationBase(startOffset, endOffset, origin),
|
||||
IrTypeParameter {
|
||||
|
||||
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, symbol: IrTypeParameterSymbol) :
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
symbol: IrTypeParameterSymbol
|
||||
) :
|
||||
this(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
symbol.descriptor.name,
|
||||
symbol.descriptor.index,
|
||||
symbol.descriptor.variance,
|
||||
symbol.descriptor.upperBounds.toMutableList()
|
||||
symbol.descriptor.variance
|
||||
)
|
||||
|
||||
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: TypeParameterDescriptor) :
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: TypeParameterDescriptor
|
||||
) :
|
||||
this(startOffset, endOffset, origin, IrTypeParameterSymbolImpl(descriptor))
|
||||
|
||||
init {
|
||||
@@ -58,7 +67,7 @@ class IrTypeParameterImpl(
|
||||
|
||||
override val descriptor: TypeParameterDescriptor get() = symbol.descriptor
|
||||
|
||||
override val superClassifiers: MutableList<IrClassifierSymbol> = SmartList<IrClassifierSymbol>()
|
||||
override val superTypes: MutableList<IrType> = SmartList()
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitTypeParameter(this, data)
|
||||
|
||||
@@ -23,10 +23,10 @@ import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class IrValueParameterImpl(
|
||||
@@ -36,34 +36,52 @@ class IrValueParameterImpl(
|
||||
override val symbol: IrValueParameterSymbol,
|
||||
override val name: Name,
|
||||
override val index: Int,
|
||||
override val type: KotlinType,
|
||||
override val varargElementType: KotlinType?,
|
||||
override val type: IrType,
|
||||
override val varargElementType: IrType?,
|
||||
override val isCrossinline: Boolean,
|
||||
override val isNoinline: Boolean
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin), IrValueParameter {
|
||||
) :
|
||||
IrDeclarationBase(startOffset, endOffset, origin),
|
||||
IrValueParameter {
|
||||
|
||||
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, symbol: IrValueParameterSymbol) :
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
symbol: IrValueParameterSymbol,
|
||||
type: IrType,
|
||||
varargElementType: IrType?
|
||||
) :
|
||||
this(
|
||||
startOffset, endOffset, origin,
|
||||
symbol,
|
||||
symbol.descriptor.name,
|
||||
symbol.descriptor.safeAs<ValueParameterDescriptor>()?.index ?: -1,
|
||||
symbol.descriptor.type,
|
||||
symbol.descriptor.safeAs<ValueParameterDescriptor>()?.varargElementType,
|
||||
type,
|
||||
varargElementType,
|
||||
symbol.descriptor.safeAs<ValueParameterDescriptor>()?.isCrossinline ?: false,
|
||||
symbol.descriptor.safeAs<ValueParameterDescriptor>()?.isNoinline ?: false
|
||||
)
|
||||
|
||||
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ParameterDescriptor) :
|
||||
this(startOffset, endOffset, origin, IrValueParameterSymbolImpl(descriptor))
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: ParameterDescriptor,
|
||||
type: IrType,
|
||||
varargElementType: IrType?
|
||||
) :
|
||||
this(startOffset, endOffset, origin, IrValueParameterSymbolImpl(descriptor), type, varargElementType)
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: ParameterDescriptor,
|
||||
type: IrType,
|
||||
varargElementType: IrType?,
|
||||
defaultValue: IrExpressionBody?
|
||||
) : this(startOffset, endOffset, origin, descriptor) {
|
||||
) : this(startOffset, endOffset, origin, descriptor, type, varargElementType) {
|
||||
this.defaultValue = defaultValue
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class IrVariableImpl(
|
||||
startOffset: Int,
|
||||
@@ -33,21 +33,23 @@ class IrVariableImpl(
|
||||
origin: IrDeclarationOrigin,
|
||||
override val symbol: IrVariableSymbol,
|
||||
override val name: Name,
|
||||
override val type: KotlinType,
|
||||
override val type: IrType,
|
||||
override val isVar: Boolean,
|
||||
override val isConst: Boolean,
|
||||
override val isLateinit: Boolean
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin),
|
||||
) :
|
||||
IrDeclarationBase(startOffset, endOffset, origin),
|
||||
IrVariable {
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
symbol: IrVariableSymbol
|
||||
symbol: IrVariableSymbol,
|
||||
type: IrType
|
||||
) : this(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
symbol.descriptor.name, symbol.descriptor.type,
|
||||
symbol.descriptor.name, type,
|
||||
isVar = symbol.descriptor.isVar,
|
||||
isConst = symbol.descriptor.isConst,
|
||||
isLateinit = symbol.descriptor.isLateInit
|
||||
@@ -57,16 +59,18 @@ class IrVariableImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: VariableDescriptor
|
||||
) : this(startOffset, endOffset, origin, IrVariableSymbolImpl(descriptor))
|
||||
descriptor: VariableDescriptor,
|
||||
type: IrType
|
||||
) : this(startOffset, endOffset, origin, IrVariableSymbolImpl(descriptor), type)
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: VariableDescriptor,
|
||||
type: IrType,
|
||||
initializer: IrExpression?
|
||||
) : this(startOffset, endOffset, origin, descriptor) {
|
||||
) : this(startOffset, endOffset, origin, descriptor, type) {
|
||||
this.initializer = initializer
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,10 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.withHasQuestionMark
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -36,11 +38,22 @@ import org.jetbrains.kotlin.types.SimpleType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
|
||||
class IrBuiltIns(val builtIns: KotlinBuiltIns) {
|
||||
private val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtIns.builtInsModule, KOTLIN_INTERNAL_IR_FQN)
|
||||
class IrBuiltIns(
|
||||
val builtIns: KotlinBuiltIns,
|
||||
private val typeTranslator: TypeTranslator,
|
||||
outerSymbolTable: SymbolTable? = null
|
||||
) {
|
||||
|
||||
private val builtInsModule = builtIns.builtInsModule
|
||||
|
||||
private val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtInsModule, KOTLIN_INTERNAL_IR_FQN)
|
||||
val irBuiltInsExternalPackageFragment = IrExternalPackageFragmentImpl(IrExternalPackageFragmentSymbolImpl(packageFragment))
|
||||
|
||||
private val stubBuilder = DeclarationStubGenerator(SymbolTable(), IrDeclarationOrigin.IR_BUILTINS_STUB)
|
||||
private val symbolTable = outerSymbolTable ?: SymbolTable()
|
||||
private val stubBuilder = DeclarationStubGenerator(builtInsModule, symbolTable, IrDeclarationOrigin.IR_BUILTINS_STUB)
|
||||
|
||||
private fun ClassDescriptor.toIrSymbol() = symbolTable.referenceClass(this)
|
||||
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||
|
||||
fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List<KotlinType>): IrSimpleFunction {
|
||||
val operatorDescriptor = IrSimpleBuiltinOperatorDescriptorImpl(packageFragment, Name.identifier(name), returnType)
|
||||
@@ -68,19 +81,57 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns) {
|
||||
private fun List<SimpleType>.defineComparisonOperatorForEachType(name: String) =
|
||||
associate { it to defineComparisonOperator(name, it) }
|
||||
|
||||
val bool = builtIns.booleanType
|
||||
val any = builtIns.anyType
|
||||
val anyN = builtIns.nullableAnyType
|
||||
val anyType = any.toIrType()
|
||||
val anyClass = builtIns.any.toIrSymbol()
|
||||
val anyNType = anyType.withHasQuestionMark(true)
|
||||
|
||||
val bool = builtIns.booleanType
|
||||
val booleanType = bool.toIrType()
|
||||
val booleanClass = builtIns.boolean.toIrSymbol()
|
||||
|
||||
val char = builtIns.charType
|
||||
val charType = char.toIrType()
|
||||
val charClass = builtIns.char.toIrSymbol()
|
||||
|
||||
val byte = builtIns.byteType
|
||||
val byteType = byte.toIrType()
|
||||
val byteClass = builtIns.byte.toIrSymbol()
|
||||
|
||||
val short = builtIns.shortType
|
||||
val shortType = short.toIrType()
|
||||
val shortClass = builtIns.short.toIrSymbol()
|
||||
|
||||
val int = builtIns.intType
|
||||
val intType = int.toIrType()
|
||||
val intClass = builtIns.int.toIrSymbol()
|
||||
|
||||
val long = builtIns.longType
|
||||
val longType = long.toIrType()
|
||||
val longClass = builtIns.long.toIrSymbol()
|
||||
|
||||
val float = builtIns.floatType
|
||||
val floatType = float.toIrType()
|
||||
val floatClass = builtIns.float.toIrSymbol()
|
||||
|
||||
val double = builtIns.doubleType
|
||||
val doubleType = double.toIrType()
|
||||
val doubleClass = builtIns.double.toIrSymbol()
|
||||
|
||||
val nothing = builtIns.nothingType
|
||||
val nothingN = builtIns.nullableNothingType
|
||||
val nothingType = nothing.toIrType()
|
||||
val nothingClass = builtIns.nothing.toIrSymbol()
|
||||
val nothingNType = nothingType.withHasQuestionMark(true)
|
||||
|
||||
val unit = builtIns.unitType
|
||||
val unitType = unit.toIrType()
|
||||
val unitClass = builtIns.unit.toIrSymbol()
|
||||
|
||||
val string = builtIns.stringType
|
||||
val stringType = string.toIrType()
|
||||
val stringClass = builtIns.string.toIrSymbol()
|
||||
|
||||
val primitiveTypes = listOf(bool, char, byte, short, int, long, float, double)
|
||||
val primitiveTypesWithComparisons = listOf(int, long, float, double)
|
||||
@@ -101,7 +152,7 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns) {
|
||||
val throwNpeFun = defineOperator("THROW_NPE", nothing, listOf())
|
||||
val throwCceFun = defineOperator("THROW_CCE", nothing, listOf())
|
||||
val booleanNotFun = defineOperator("NOT", bool, listOf(bool))
|
||||
val noWhenBranchMatchedExceptionFun = defineOperator("noWhenBranchMatchedException", unit, listOf())
|
||||
val noWhenBranchMatchedExceptionFun = defineOperator("noWhenBranchMatchedException", nothing, listOf())
|
||||
|
||||
val eqeqeq = eqeqeqFun.descriptor
|
||||
val eqeq = eqeqFun.descriptor
|
||||
|
||||
@@ -18,12 +18,12 @@ package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
|
||||
|
||||
interface IrClassReference : IrDeclarationReference {
|
||||
override val descriptor: ClassifierDescriptor
|
||||
override val symbol: IrClassifierSymbol
|
||||
val classType: KotlinType
|
||||
val classType: IrType
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user