Refactoring: Consistently use Symbols in JvmSymbols

This commit is contained in:
Steven Schäfer
2019-08-15 11:48:45 +02:00
committed by max-kammerer
parent c77fa1ecd6
commit 2be4abe9a6
10 changed files with 93 additions and 95 deletions
@@ -18,17 +18,12 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.types.isNullableAny
import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.fields
import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -55,7 +50,7 @@ class JvmSymbols(
klass.addConstructor().apply {
addValueParameter("message", irBuiltIns.stringType)
}
}.symbol
}
override val ThrowNullPointerException: IrFunctionSymbol =
nullPointerExceptionClass.constructors.single()
@@ -68,7 +63,7 @@ class JvmSymbols(
klass.addConstructor().apply {
addValueParameter("message", irBuiltIns.stringType)
}
}.symbol
}
override val ThrowTypeCastException: IrFunctionSymbol =
typeCastExceptionClass.constructors.single()
@@ -76,7 +71,7 @@ class JvmSymbols(
private fun createPackage(fqName: FqName): IrPackageFragment =
IrExternalPackageFragmentImpl(IrExternalPackageFragmentSymbolImpl(EmptyPackageFragmentDescriptor(context.state.module, fqName)))
private fun createClass(fqName: FqName, classKind: ClassKind = ClassKind.CLASS, block: (IrClass) -> Unit): IrClass =
private fun createClass(fqName: FqName, classKind: ClassKind = ClassKind.CLASS, block: (IrClass) -> Unit = {}): IrClassSymbol =
buildClass {
name = fqName.shortName()
kind = classKind
@@ -90,7 +85,7 @@ class JvmSymbols(
}
createImplicitParameterDeclarationWithWrappedDescriptor()
block(this)
}
}.symbol
private val intrinsicsClass: IrClassSymbol = createClass(
JvmClassName.byInternalName(IrIntrinsicMethods.INTRINSICS_CLASS_NAME).fqNameForTopLevelClassMaybeWithDollars
@@ -106,7 +101,7 @@ class JvmSymbols(
addValueParameter("value", irBuiltIns.anyNType)
addValueParameter("expression", irBuiltIns.stringType)
}
}.symbol
}
val checkExpressionValueIsNotNull: IrSimpleFunctionSymbol =
intrinsicsClass.functions.single { it.owner.name.asString() == "checkExpressionValueIsNotNull" }
@@ -121,7 +116,7 @@ class JvmSymbols(
get() = context.getTopLevelClass(FqName("java.lang.StringBuilder"))
override val defaultConstructorMarker: IrClassSymbol =
createClass(FqName("kotlin.jvm.internal.DefaultConstructorMarker")) { }.symbol
createClass(FqName("kotlin.jvm.internal.DefaultConstructorMarker"))
override val copyRangeTo: Map<ClassDescriptor, IrSimpleFunctionSymbol>
get() = error("Unused in JVM IR")
@@ -148,13 +143,13 @@ class JvmSymbols(
get() = TODO("not implemented")
val javaLangClass: IrClassSymbol =
if (firMode) createClass(FqName("java.lang.Class")) {}.symbol else context.getTopLevelClass(FqName("java.lang.Class"))
if (firMode) createClass(FqName("java.lang.Class")) else context.getTopLevelClass(FqName("java.lang.Class"))
val javaLangAssertionError: IrClassSymbol =
if (firMode) createClass(FqName("java.lang.AssertionError")) {}.symbol else context.getTopLevelClass(FqName("java.lang.AssertionError"))
private val javaLangAssertionError: IrClassSymbol =
if (firMode) createClass(FqName("java.lang.AssertionError")) else context.getTopLevelClass(FqName("java.lang.AssertionError"))
val assertionErrorConstructor by lazy {
context.ir.symbols.javaLangAssertionError.constructors.single {
val assertionErrorConstructor by lazy<IrConstructorSymbol> {
javaLangAssertionError.constructors.single {
it.owner.valueParameters.size == 1 && it.owner.valueParameters[0].type.isNullableAny()
}
}
@@ -163,7 +158,7 @@ class JvmSymbols(
klass.addConstructor().apply {
addValueParameter("arity", irBuiltIns.intType)
}
}.symbol
}
private fun generateCallableReferenceMethods(klass: IrClass) {
klass.addFunction("getSignature", irBuiltIns.stringType, Modality.OPEN)
@@ -184,7 +179,12 @@ class JvmSymbols(
klass.addField("receiver", irBuiltIns.anyNType, Visibilities.PROTECTED)
generateCallableReferenceMethods(klass)
}.symbol
}
val functionReferenceReceiverField: IrFieldSymbol = functionReference.fieldByName("receiver")
val functionReferenceGetSignature: IrSimpleFunctionSymbol = functionReference.functionByName("getSignature")
val functionReferenceGetName: IrSimpleFunctionSymbol = functionReference.functionByName("getName")
val functionReferenceGetOwner: IrSimpleFunctionSymbol = functionReference.functionByName("getOwner")
fun getFunction(parameterCount: Int): IrClassSymbol =
symbolTable.referenceClass(builtIns.getFunction(parameterCount))
@@ -201,7 +201,7 @@ class JvmSymbols(
addValueParameter("p$i", klass.typeParameters[i - 1].defaultType)
}
}
}.symbol
}
}
fun getJvmFunctionClass(parameterCount: Int): IrClassSymbol =
@@ -218,7 +218,7 @@ class JvmSymbols(
varargElementType = irBuiltIns.anyNType
}
}
}.symbol
}
private data class PropertyReferenceKey(
val mutable: Boolean,
@@ -280,7 +280,7 @@ class JvmSymbols(
addValueParameter("value", irBuiltIns.anyNType)
}
}
}.symbol
}
}
fun getPropertyReferenceClass(mutable: Boolean, parameterCount: Int, impl: Boolean): IrClassSymbol =
@@ -313,10 +313,7 @@ class JvmSymbols(
}
}
}
}.symbol
private fun IrClassSymbol.functionByName(name: String): IrSimpleFunctionSymbol =
functions.single { it.owner.name.asString() == name }
}
val getOrCreateKotlinPackage: IrSimpleFunctionSymbol =
reflection.functionByName("getOrCreateKotlinPackage")
@@ -325,7 +322,7 @@ class JvmSymbols(
javaLangClass.functionByName("desiredAssertionStatus")
}
private val unsafeCoerceIntrinsic =
val unsafeCoerceIntrinsic: IrSimpleFunctionSymbol =
buildFun {
name = Name.special("<unsafe-coerce>")
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
@@ -335,8 +332,7 @@ class JvmSymbols(
val dst = addTypeParameter("R", irBuiltIns.anyNType)
addValueParameter("v", src.defaultType)
returnType = dst.defaultType
}
val unsafeCoerceIntrinsicSymbol = unsafeCoerceIntrinsic.symbol
}.symbol
private val collectionToArrayClass: IrClassSymbol = createClass(FqName("kotlin.jvm.internal.CollectionToArray")) { klass ->
klass.origin = JvmLoweredDeclarationOrigin.TO_ARRAY
@@ -351,7 +347,7 @@ class JvmSymbols(
addValueParameter("collection", irBuiltIns.collectionClass.owner.typeWith(), JvmLoweredDeclarationOrigin.TO_ARRAY)
addValueParameter("array", arrayType, JvmLoweredDeclarationOrigin.TO_ARRAY)
}
}.symbol
}
val nonGenericToArray: IrSimpleFunctionSymbol =
collectionToArrayClass.functions.single { it.owner.name.asString() == "toArray" && it.owner.valueParameters.size == 1 }
@@ -370,7 +366,7 @@ class JvmSymbols(
}
}.symbol
val spreadBuilder = createClass(FqName("kotlin.jvm.internal.SpreadBuilder")) { klass ->
val spreadBuilder: IrClassSymbol = createClass(FqName("kotlin.jvm.internal.SpreadBuilder")) { klass ->
klass.addConstructor().apply {
addValueParameter("size", irBuiltIns.intType)
}
@@ -390,7 +386,7 @@ class JvmSymbols(
}
}
val primitiveSpreadBuilders = irBuiltIns.primitiveIrTypes.associateWith { irType ->
val primitiveSpreadBuilders: Map<IrType, IrClassSymbol> = irBuiltIns.primitiveIrTypes.associateWith { irType ->
val name = irType.classOrNull!!.owner.name
createClass(FqName("kotlin.jvm.internal.${name}SpreadBuilder")) { klass ->
klass.addConstructor().apply {
@@ -412,7 +408,7 @@ class JvmSymbols(
}
}
val systemClass = createClass(FqName("java.lang.System")) { klass ->
private val systemClass: IrClassSymbol = createClass(FqName("java.lang.System")) { klass ->
klass.addFunction("arraycopy", irBuiltIns.unitType, isStatic = true).apply {
addValueParameter("src", irBuiltIns.anyNType)
addValueParameter("srcPos", irBuiltIns.intType)
@@ -421,5 +417,11 @@ class JvmSymbols(
addValueParameter("length", irBuiltIns.intType)
}
}
val systemArraycopy = systemClass.functions.single { it.name.asString() == "arraycopy" }
val systemArraycopy: IrSimpleFunctionSymbol = systemClass.functionByName("arraycopy")
}
private fun IrClassSymbol.functionByName(name: String): IrSimpleFunctionSymbol =
functions.single { it.owner.name.asString() == name }
private fun IrClassSymbol.fieldByName(name: String): IrFieldSymbol =
fields.single { it.owner.name.asString() == name }
@@ -96,7 +96,7 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
irBuiltIns.checkNotNullSymbol.toKey()!! to IrCheckNotNull,
irBuiltIns.andandSymbol.toKey()!! to AndAnd,
irBuiltIns.ororSymbol.toKey()!! to OrOr,
symbols.unsafeCoerceIntrinsicSymbol.toKey()!! to UnsafeCoerce
symbols.unsafeCoerceIntrinsic.toKey()!! to UnsafeCoerce
) +
numberConversionMethods() +
unaryFunForPrimitives("plus", UnaryPlus) +
@@ -63,7 +63,7 @@ class IrArrayBuilder(val builder: JvmIrBuilder, val arrayType: IrType) {
private fun newArray(size: IrExpression): IrExpression {
val arrayConstructor = if (unwrappedArrayType.isBoxedArray)
builder.backendContext.ir.symbols.arrayOfNulls
builder.irSymbols.arrayOfNulls
else
unwrappedArrayType.classOrNull!!.constructors.single { it.owner.valueParameters.size == 1 }
@@ -97,7 +97,7 @@ class IrArrayBuilder(val builder: JvmIrBuilder, val arrayType: IrType) {
// Copy a single spread expression, unless it refers to a newly constructed array.
private fun copyArray(spread: IrExpression): IrExpression {
if (spread is IrConstructorCall ||
(spread is IrFunctionAccessExpression && spread.symbol == builder.backendContext.ir.symbols.arrayOfNulls))
(spread is IrFunctionAccessExpression && spread.symbol == builder.irSymbols.arrayOfNulls))
return spread
return builder.irBlock {
@@ -105,7 +105,7 @@ class IrArrayBuilder(val builder: JvmIrBuilder, val arrayType: IrType) {
val size = unwrappedArrayType.classOrNull!!.getPropertyGetter("size")!!
fun getSize() = irCall(size).apply { dispatchReceiver = irGet(spreadVar) }
val result = irTemporary(newArray(getSize()))
+irCall(builder.backendContext.ir.symbols.systemArraycopy).apply {
+irCall(builder.irSymbols.systemArraycopy).apply {
putValueArgument(0, irGet(spreadVar))
putValueArgument(1, irInt(0))
putValueArgument(2, irGet(result))
@@ -119,16 +119,16 @@ class IrArrayBuilder(val builder: JvmIrBuilder, val arrayType: IrType) {
// Build an array containing spread expressions.
private fun buildComplexArray(): IrExpression {
val spreadBuilder = if (unwrappedArrayType.isBoxedArray)
builder.backendContext.ir.symbols.spreadBuilder
builder.irSymbols.spreadBuilder
else
builder.backendContext.ir.symbols.primitiveSpreadBuilders.getValue(elementType)
builder.irSymbols.primitiveSpreadBuilders.getValue(elementType)
val addElement = spreadBuilder.functions.single { it.name.asString() == "add" }
val addSpread = spreadBuilder.functions.single { it.name.asString() == "addSpread" }
val toArray = spreadBuilder.functions.single { it.name.asString() == "toArray" }
val addElement = spreadBuilder.functions.single { it.owner.name.asString() == "add" }
val addSpread = spreadBuilder.functions.single { it.owner.name.asString() == "addSpread" }
val toArray = spreadBuilder.functions.single { it.owner.name.asString() == "toArray" }
return builder.irBlock {
val spreadBuilderVar = irTemporary(irCallConstructor(spreadBuilder.constructors.single().symbol, listOf()).apply {
val spreadBuilderVar = irTemporary(irCallConstructor(spreadBuilder.constructors.single(), listOf()).apply {
putValueArgument(0, irInt(elements.size))
})
@@ -142,8 +142,8 @@ class IrArrayBuilder(val builder: JvmIrBuilder, val arrayType: IrType) {
val toArrayCall = irCall(toArray).apply {
dispatchReceiver = irGet(spreadBuilderVar)
if (unwrappedArrayType.isBoxedArray) {
val size = spreadBuilder.functions.single { it.name.asString() == "size" }
putValueArgument(0, irCall(builder.backendContext.ir.symbols.arrayOfNulls, arrayType).apply {
val size = spreadBuilder.functions.single { it.owner.name.asString() == "size" }
putValueArgument(0, irCall(builder.irSymbols.arrayOfNulls, arrayType).apply {
putTypeArgument(0, elementType)
putValueArgument(0, irCall(size).apply {
dispatchReceiver = irGet(spreadBuilderVar)
@@ -162,7 +162,7 @@ class IrArrayBuilder(val builder: JvmIrBuilder, val arrayType: IrType) {
// Coerce expression to irType if we are working with an inline class array type
private fun coerce(expression: IrExpression, irType: IrType): IrExpression =
if (isUnboxedInlineClassArray)
builder.irCall(builder.backendContext.ir.symbols.unsafeCoerceIntrinsicSymbol, irType).apply {
builder.irCall(builder.irSymbols.unsafeCoerceIntrinsic, irType).apply {
putTypeArgument(0, expression.type)
putTypeArgument(1, irType)
putValueArgument(0, expression)
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.ir
import org.jetbrains.kotlin.backend.common.lower.IrLoweringContext
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmSymbols
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -109,7 +110,10 @@ class JvmIrBuilder(
Scope(symbol),
startOffset,
endOffset
)
) {
val irSymbols: JvmSymbols
get() = backendContext.ir.symbols
}
fun JvmBackendContext.createJvmIrBuilder(
symbol: IrSymbol,
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
@@ -159,23 +158,25 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
copyAttributes(irFunctionReference)
}
fun build(): IrExpression = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol).irBlock {
val constructor = createConstructor()
createInvokeMethod(
if (samSuperType != null && boundReceiver != null) {
irTemporary(boundReceiver.second)
} else null
)
fun build(): IrExpression = context.createJvmIrBuilder(currentScope!!.scope.scopeOwnerSymbol).run {
irBlock {
val constructor = createConstructor()
createInvokeMethod(
if (samSuperType != null && boundReceiver != null) {
irTemporary(boundReceiver.second)
} else null
)
if (!isLambda && samSuperType == null) {
createGetSignatureMethod(functionGetSignature)
createGetNameMethod(functionGetName)
createGetOwnerMethod(functionGetOwner)
}
if (!isLambda && samSuperType == null) {
createGetSignatureMethod(this@run.irSymbols.functionReferenceGetSignature.owner)
createGetNameMethod(this@run.irSymbols.functionReferenceGetName.owner)
createGetOwnerMethod(this@run.irSymbols.functionReferenceGetOwner.owner)
}
+functionReferenceClass
+irCall(constructor.symbol).apply {
if (valueArgumentsCount > 0) putValueArgument(0, boundReceiver!!.second)
+functionReferenceClass
+irCall(constructor.symbol).apply {
if (valueArgumentsCount > 0) putValueArgument(0, boundReceiver!!.second)
}
}
}
@@ -292,7 +293,7 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
// will put it into a field.
if (samSuperType == null)
irImplicitCast(
irGetField(irGet(dispatchReceiverParameter!!), functionReferenceReceiverField),
irGetField(irGet(dispatchReceiverParameter!!), irSymbols.functionReferenceReceiverField.owner),
boundReceiver.second.type
)
else
@@ -318,9 +319,8 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
}
unboundIndex >= argumentTypes.size ->
// Default value argument
// TODO For suspend functions the last argument is continuation and it is implicit:
// irCall(getContinuationSymbol, listOf(ourSymbol.descriptor.returnType!!))
// Default value argument (this pass doesn't handle suspend functions, otherwise
// it could also be the continuation argument)
null
else ->
@@ -405,18 +405,4 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
private val currentDeclarationParent
get() = allScopes.last { it.irElement is IrDeclarationParent }.irElement as IrDeclarationParent
private fun IrClassSymbol.functionByName(name: String) = owner.functions.single { it.name.asString() == name }
private val functionReferenceReceiverField =
context.ir.symbols.functionReference.owner.declarations.single { it is IrField && it.name.toString() == "receiver" } as IrField
private val functionGetSignature =
context.ir.symbols.functionReference.functionByName("getSignature")
private val functionGetName =
context.ir.symbols.functionReference.functionByName("getName")
private val functionGetOwner =
context.ir.symbols.functionReference.functionByName("getOwner")
}
@@ -249,7 +249,7 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
private fun createSyntheticValuesFieldInitializerExpression(): IrExpression =
context.createJvmIrBuilder(irClass.symbol).irArray(context.irBuiltIns.arrayClass.typeWith(irClass.defaultType)) {
enumEntryFields.forEach { irField ->
+IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irField.symbol, irField.symbol.owner.type)
+IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irField.symbol, irField.type)
}
}
@@ -56,7 +56,7 @@ private class FunctionNVarargBridgeLowering(val context: JvmBackendContext) :
at(expression)
irCall(functionNInvokeFun).apply {
dispatchReceiver = expression.dispatchReceiver
putValueArgument(0, irArray(backendContext.ir.symbols.array.typeWith(context.irBuiltIns.anyNType)) {
putValueArgument(0, irArray(irSymbols.array.typeWith(context.irBuiltIns.anyNType)) {
(0 until expression.valueArgumentsCount).forEach { +expression.getValueArgument(it)!! }
})
}
@@ -28,7 +28,7 @@ class JvmDefaultParameterInjector(context: JvmBackendContext) :
return super.nullConst(startOffset, endOffset, type)
val underlyingType = type.unboxInlineClass()
return IrCallImpl(startOffset, endOffset, type, context.ir.symbols.unsafeCoerceIntrinsicSymbol).apply {
return IrCallImpl(startOffset, endOffset, type, context.ir.symbols.unsafeCoerceIntrinsic).apply {
putTypeArgument(0, underlyingType) // from
putTypeArgument(1, type) // to
putValueArgument(0, super.nullConst(startOffset, endOffset, underlyingType))
@@ -237,7 +237,7 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F
}
private fun coerceInlineClasses(argument: IrExpression, from: IrType, to: IrType) =
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, to, context.ir.symbols.unsafeCoerceIntrinsicSymbol).apply {
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, to, context.ir.symbols.unsafeCoerceIntrinsic).apply {
putTypeArgument(0, from)
putTypeArgument(1, to)
putValueArgument(0, argument)
@@ -178,17 +178,23 @@ fun IrMemberAccessExpression.usesDefaultArguments(): Boolean =
val DeclarationDescriptorWithSource.startOffset: Int? get() = (this.source as? PsiSourceElement)?.psi?.startOffset
val DeclarationDescriptorWithSource.endOffset: Int? get() = (this.source as? PsiSourceElement)?.psi?.endOffset
val IrClassSymbol.functions: Sequence<IrSimpleFunctionSymbol>
get() = this.owner.declarations.asSequence().filterIsInstance<IrSimpleFunction>().map { it.symbol }
val IrClass.functions: Sequence<IrSimpleFunction>
get() = this.declarations.asSequence().filterIsInstance<IrSimpleFunction>()
get() = declarations.asSequence().filterIsInstance<IrSimpleFunction>()
val IrClassSymbol.constructors: Sequence<IrConstructorSymbol>
get() = this.owner.declarations.asSequence().filterIsInstance<IrConstructor>().map { it.symbol }
val IrClassSymbol.functions: Sequence<IrSimpleFunctionSymbol>
get() = owner.functions.map { it.symbol }
val IrClass.constructors: Sequence<IrConstructor>
get() = this.declarations.asSequence().filterIsInstance<IrConstructor>()
get() = declarations.asSequence().filterIsInstance<IrConstructor>()
val IrClassSymbol.constructors: Sequence<IrConstructorSymbol>
get() = owner.constructors.map { it.symbol }
val IrClass.fields: Sequence<IrField>
get() = declarations.asSequence().filterIsInstance<IrField>()
val IrClassSymbol.fields: Sequence<IrFieldSymbol>
get() = owner.fields.map { it.symbol }
val IrClass.primaryConstructor: IrConstructor?
get() = this.declarations.singleOrNull { it is IrConstructor && it.isPrimary } as IrConstructor?