Compare commits

...

47 Commits

Author SHA1 Message Date
Dmitry Petrov
ec29449135 Fix circular dependency: TypeTranslator <-> ConstantValueGenerator
TODO proper DI?
2018-06-26 16:29:14 +03:00
Dmitry Petrov
6206d22660 Temporary fix for IR2CFG: use originalKotlinType 2018-06-26 14:58:42 +03:00
Dmitry Petrov
12ef9be37a IrTypes: IrSuspensionPoint, IrSuspendableExpression update 2018-06-26 14:58:42 +03:00
Svyatoslav Scherbina
91f470755c IrTypes: migrate some code from backend.common
(cherry picked from commit 3788130)
2018-06-26 14:58:42 +03:00
Svyatoslav Scherbina
6224608a0e IrTypes: comment backend.common code to be migrated by someone else
(cherry picked from commit 0491fc4)
2018-06-26 14:58:42 +03:00
Svyatoslav Scherbina
f382b45e3e backend.common: remove obsolete lowerings
(cherry picked from commit 5d6b9c7)
2018-06-26 14:58:42 +03:00
Svyatoslav Scherbina
5572d7a37f psi2ir: fix type for IrGetField(delegate) when generating delegation
(cherry picked from commit 7601cc2)
2018-06-26 14:58:42 +03:00
Svyatoslav Scherbina
ce95ba311d psi2ir: fix null support in 'promoteToPrimitiveNumericType'
(cherry picked from commit 9b2a637)
2018-06-26 14:58:42 +03:00
Svyatoslav Scherbina
26ad8285c0 psi2ir: fix generating fake override for property with type parameters
(cherry picked from commit 2051177)
2018-06-26 14:58:42 +03:00
Svyatoslav Scherbina
0070e90819 psi2ir: don't generate accessor type parameter supertypes twice
(cherry picked from commit 22e6d5f)
2018-06-26 14:58:42 +03:00
Dmitry Petrov
2e7f9de1bf IrTypes: generateAnnotationConstructorCall -> ConstantValueGenerator 2018-06-26 14:58:42 +03:00
Dmitry Petrov
0f7622e351 IrTypes: use proper scope for type parameters in stub generation 2018-06-26 14:58:42 +03:00
Svyatoslav Scherbina
1ab7461e59 IrTypes: fix multiple issues in psi2ir 2018-06-26 14:58:42 +03:00
Svyatoslav Scherbina
190f37a6ab Expose transformAnnotations from DeepCopyIrTree 2018-06-26 14:58:42 +03:00
Dmitry Petrov
cac670aaf0 Minor: IrTypes: fix after rebase 2018-06-26 14:58:42 +03:00
Dmitry Petrov
945814f279 IrTypes: approximate only non-denotable Kotlin types 2018-06-26 14:58:42 +03:00
Dmitry Petrov
cc4724120f IrTypes: star projections
Initial implementation, mostly to avoid infinite recursion in cases such
as 'Enum<*>'.
2018-06-26 14:58:42 +03:00
Dmitry Petrov
bc322e8193 IrTypes: Fix type arguments mapping for properties 2018-06-26 14:58:42 +03:00
Dmitry Petrov
ebb03237a3 IrTypes: IrProperty has no type of its own
Within the current scheme, type parameters for IrProperty become type
parameters for getter and setter (and, since only extension properties
can have type parameters, backing field's type can't depend on type
parameters; see also KT-24643). Either properties themselves can have
type parameters of their own (for the sake of representing the property
type), or properties don't have types and don't have type parameters.
2018-06-26 14:58:42 +03:00
Dmitry Petrov
807fb678ef IrTypes: IrTypeParameter.superTypes can depend on type parameters
IrTypeParameter.superTypes can depend on type parameters and thus should
be initialized with type parameters in scope.
2018-06-26 14:58:42 +03:00
Dmitry Petrov
24616aed48 IrTypes: IrClass.superTypes can depend on type parameters
IrClass.superTypes can depend on type parameters of a class and thus
should be initialized after type parameters are in put in scope.
2018-06-26 14:58:42 +03:00
Dmitry Petrov
f7bf83bc18 IrTypes: IrFunction.returnType can depend on type parameters
Function return type can depend on function type parameters and should
be initialized with type parameters in scope.
2018-06-26 14:58:42 +03:00
Dmitry Petrov
201c24d717 Minor: IrTypes: fix after rebase 2018-06-26 14:58:42 +03:00
Dmitry Petrov
cc23ec7de1 IrTypes: IrClass.superTypes, IrTypeParameter.superTypes 2018-06-26 14:58:42 +03:00
Dmitry Petrov
8130d724ee compiler/ir/backend.common is NOT a part of compiler/backend-common 2018-06-26 14:58:42 +03:00
Dmitry Petrov
ba5a1d3e8f IrTypes: minor: pass generator context where required 2018-06-26 14:58:42 +03:00
Dmitry Petrov
aab917983c IrTypes required to declare symbol 2018-06-26 14:58:42 +03:00
Dmitry Petrov
4f69d9f2c9 IrTypes: dummy implementation of IrType.render 2018-06-26 14:58:42 +03:00
Dmitry Petrov
2e092903d5 IrTypes: deep copy with symbols
Preliminary implementation of type remapper (does nothing).
2018-06-26 14:58:42 +03:00
Dmitry Petrov
8d82fe8aca IrTypes: make old DeepCopy compile
Lots of TODOs, should figure out proper type mapping strategy
(or simply drop this frankenstein code, finally).
2018-06-26 14:58:42 +03:00
Dmitry Petrov
fbb128c74c Add dependency: ir.tree -> intellij
AnnotationGenerator looks into PsiElement
2018-06-26 14:58:42 +03:00
Dmitry Petrov
565c10af38 IrTypes: update minor utilities 2018-06-26 14:58:42 +03:00
Dmitry Petrov
d0e7e57c60 IrTypes: Implicit casts, take 1
Keep KotlinType along with IrTypes created by psi2ir.
2018-06-26 14:58:42 +03:00
Dmitry Petrov
20fe554d03 IrTypes in psi2ir: generators (seem to be) complete 2018-06-26 14:58:42 +03:00
Dmitry Petrov
acf03fb2b1 IrTypes in psi2ir (work in progress) 2018-06-26 14:58:42 +03:00
Dmitry Petrov
a9697fa455 Rebase + reformat 2018-06-26 14:58:42 +03:00
Dmitry Petrov
8595949b18 IrTypes: Fix up some back-end code 2018-06-26 14:58:42 +03:00
Dmitry Petrov
42c891db27 IrTypes in psi2ir (work in progress) 2018-06-26 14:58:42 +03:00
Dmitry Petrov
f8d13e92ee IrTypes: basic built-in types 2018-06-26 14:58:42 +03:00
Dmitry Petrov
fc66083006 psi2ir: translate types in StatementGenerator
TODO: DI
2018-06-26 14:58:42 +03:00
Dmitry Petrov
ada22d3ff1 DeclarationStubGenerator uses IrTypes 2018-06-26 14:58:42 +03:00
Dmitry Petrov
4931ce4df8 IR: Drop obsolete builders (should be rewritten) 2018-06-26 14:58:42 +03:00
Dmitry Petrov
aa995a4aa0 psi2ir: cleanup TypeTranslator 2018-06-26 14:58:42 +03:00
Dmitry Petrov
ab353a226e IR declarations: KotlinType -> IrType 2018-06-26 14:58:42 +03:00
Dmitry Petrov
d7c8516275 IR expressions: KotlinType -> IrType 2018-06-26 14:58:42 +03:00
Dmitry Petrov
d4f57703b1 psi2ir: approximate types in TypeTranslator 2018-06-26 14:58:42 +03:00
Dmitry Petrov
38369bbeb2 IrType -> IrDynamicType, IrErrorType, IrSimpleType 2018-06-26 14:58:42 +03:00
177 changed files with 3334 additions and 2907 deletions

View File

@@ -18,7 +18,6 @@ dependencies {
sourceSets {
"main" {
projectDefault()
java.srcDir("../ir/backend.common/src")
}
"test" {}
}

View 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" {}
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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")
}
}

View File

@@ -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

View File

@@ -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)
}
}

View File

@@ -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

View File

@@ -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) })
}
})

View File

@@ -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?
})
*/
}
}

View File

@@ -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)
}
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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
)

View File

@@ -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
}
})
}
}
}

View File

@@ -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

View File

@@ -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)

View File

@@ -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:

View File

@@ -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)

View File

@@ -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)

View File

@@ -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:

View File

@@ -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)

View File

@@ -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)
}
}

View File

@@ -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)
}
}

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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()

View File

@@ -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
)

View File

@@ -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
)
}

View File

@@ -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
)

View File

@@ -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
}

View File

@@ -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)!!
}
}

View File

@@ -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
}

View File

@@ -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) =

View File

@@ -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))
}
}
}

View File

@@ -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)
}
)

View File

@@ -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 ->

View File

@@ -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()
)
}

View File

@@ -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)

View File

@@ -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))

View File

@@ -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
)
)

View File

@@ -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
)
)

View File

@@ -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)
)
}

View File

@@ -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) {

View File

@@ -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)
)
}
}

View File

@@ -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 =

View File

@@ -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() }
}
}

View File

@@ -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()
}

View File

@@ -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()

View File

@@ -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

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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")

View File

@@ -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!!
}

View File

@@ -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")

View File

@@ -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),

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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
)
)
}
}
}

View File

@@ -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)
}

View File

@@ -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")
}

View File

@@ -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 {

View File

@@ -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
)

View File

@@ -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
}
}

View File

@@ -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
)
}

View File

@@ -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())
}
}
}

View File

@@ -7,6 +7,7 @@ plugins {
jvmTarget = "1.6"
dependencies {
compile(intellijDep())
compile(project(":compiler:util"))
compile(project(":compiler:frontend"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }

View File

@@ -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)

View File

@@ -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)

View File

@@ -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()

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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")

View File

@@ -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?
}

View File

@@ -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

View File

@@ -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?

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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,

View File

@@ -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

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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(

View File

@@ -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) }

View File

@@ -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()

View File

@@ -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

View File

@@ -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,

View File

@@ -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)
}

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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