[JS IR BE] Add basic support for external declarations
This commit is contained in:
@@ -59,8 +59,8 @@ object JsIrBuilder {
|
||||
fun buildSetVariable(symbol: IrVariableSymbol, value: IrExpression, type: IrType) =
|
||||
IrSetVariableImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, symbol, value, SYNTHESIZED_STATEMENT)
|
||||
|
||||
fun buildGetField(symbol: IrFieldSymbol, receiver: IrExpression?, superQualifierSymbol: IrClassSymbol? = null) =
|
||||
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, symbol.owner.type, receiver, SYNTHESIZED_STATEMENT, superQualifierSymbol)
|
||||
fun buildGetField(symbol: IrFieldSymbol, receiver: IrExpression?, superQualifierSymbol: IrClassSymbol? = null, type: IrType? = null) =
|
||||
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, type ?: symbol.owner.type, receiver, SYNTHESIZED_STATEMENT, superQualifierSymbol)
|
||||
|
||||
fun buildSetField(symbol: IrFieldSymbol, receiver: IrExpression?, value: IrExpression, type: IrType, superQualifierSymbol: IrClassSymbol? = null) =
|
||||
IrSetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, receiver, value, type, SYNTHESIZED_STATEMENT, superQualifierSymbol)
|
||||
|
||||
+27
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
@@ -64,6 +65,9 @@ class EnumClassTransformer(val context: JsIrBackendContext, private val irClass:
|
||||
// Pass these parameters to delegating constructor calls
|
||||
lowerEnumConstructorsBody()
|
||||
|
||||
// The first step creates a new `IrConstructor` with new `IrValueParameter`s so references to old `IrValueParameter`s must be replaced with new ones.
|
||||
fixReferencesToConstructorParameters()
|
||||
|
||||
// Create instance variable for each enum entry initialized with `null`
|
||||
val entryInstances = createEnumEntryInstanceVariables()
|
||||
|
||||
@@ -95,6 +99,29 @@ class EnumClassTransformer(val context: JsIrBackendContext, private val irClass:
|
||||
return listOf(irClass) + entryInstances + listOf(entryInstancesInitializedVar, initEntryInstancesFun) + entryGetInstanceFuns
|
||||
}
|
||||
|
||||
private fun fixReferencesToConstructorParameters() {
|
||||
val fromOldToNewParameter = mutableMapOf<IrValueParameterSymbol, IrValueParameter>()
|
||||
|
||||
loweredEnumConstructors.forEach { (oldCtorSymbol, newCtor) ->
|
||||
val oldParameters = oldCtorSymbol.owner.valueParameters
|
||||
val newParameters = newCtor.valueParameters
|
||||
|
||||
oldParameters.forEach { old ->
|
||||
fromOldToNewParameter[old.symbol] = newParameters.single { it.name == old.name }
|
||||
}
|
||||
}
|
||||
|
||||
irClass.transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
fromOldToNewParameter[expression.symbol]?.let {
|
||||
return builder.irGet(it)
|
||||
}
|
||||
|
||||
return super.visitGetValue(expression)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun createEnumValueOfBody(): IrBody {
|
||||
val valueOfFun = findFunctionDescriptorForMemberWithSyntheticBodyKind(IrSyntheticBodyKind.ENUM_VALUEOF)
|
||||
val nameParameter = valueOfFun.valueParameters[0]
|
||||
|
||||
+19
-4
@@ -9,12 +9,10 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.utils.isNullable
|
||||
import org.jetbrains.kotlin.backend.common.utils.isSubtypeOf
|
||||
import org.jetbrains.kotlin.backend.common.utils.isSubtypeOfClass
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.ConversionNames
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isFakeOverriddenFromAny
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
@@ -23,6 +21,7 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.isNullConst
|
||||
@@ -262,6 +261,22 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
||||
if (call is IrCall) {
|
||||
val symbol = call.symbol
|
||||
|
||||
if (symbol.isEffectivelyExternal()) {
|
||||
when (call.origin) {
|
||||
IrStatementOrigin.GET_PROPERTY -> {
|
||||
val fieldSymbol = IrFieldSymbolImpl((symbol.descriptor as PropertyAccessorDescriptor).correspondingProperty)
|
||||
return JsIrBuilder.buildGetField(fieldSymbol, call.dispatchReceiver, type = call.type)
|
||||
}
|
||||
|
||||
// assignment to a property
|
||||
IrStatementOrigin.EQ -> {
|
||||
val fieldSymbol = IrFieldSymbolImpl((symbol.descriptor as PropertyAccessorDescriptor).correspondingProperty)
|
||||
return JsIrBuilder.buildSetField(fieldSymbol, call.dispatchReceiver, call.getValueArgument(0)!!, call.type)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
symbolToTransformer[symbol]?.let {
|
||||
return it(call)
|
||||
}
|
||||
|
||||
+4
-2
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
@@ -84,7 +85,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
if (!irClass.isInterface) {
|
||||
declaration.resolveFakeOverride()?.let {
|
||||
val implClassDesc = it.descriptor.containingDeclaration as ClassDescriptor
|
||||
if (!KotlinBuiltIns.isAny(implClassDesc)) {
|
||||
if (!KotlinBuiltIns.isAny(implClassDesc) && !it.isEffectivelyExternal()) {
|
||||
val implMethodName = context.getNameForSymbol(it.symbol)
|
||||
val implClassName = context.getNameForSymbol(IrClassSymbolImpl(implClassDesc))
|
||||
|
||||
@@ -164,7 +165,8 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
JsArrayLiteral(
|
||||
irClass.superTypes.mapNotNull {
|
||||
val symbol = it.classifierOrFail
|
||||
if (symbol.isInterface) JsNameRef(context.getNameForSymbol(symbol)) else null
|
||||
// TODO: make sure that there is a test which breaks when isExternal is used here instead of isEffectivelyExternal
|
||||
if (symbol.isInterface && !symbol.isEffectivelyExternal()) JsNameRef(context.getNameForSymbol(symbol)) else null
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
+12
-5
@@ -6,13 +6,13 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.utils
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsName
|
||||
import org.jetbrains.kotlin.js.naming.isES5IdentifierPart
|
||||
import org.jetbrains.kotlin.js.naming.isES5IdentifierStart
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||
|
||||
@@ -30,6 +30,16 @@ class SimpleNameGenerator : NameGenerator {
|
||||
private fun getNameForDescriptor(descriptor: DeclarationDescriptor, context: JsGenerationContext): JsName =
|
||||
nameCache.getOrPut(descriptor) {
|
||||
var nameDeclarator: (String) -> JsName = context.currentScope::declareName
|
||||
|
||||
if (descriptor is MemberDescriptor && descriptor.isEffectivelyExternal()) {
|
||||
val descriptorForName = when (descriptor) {
|
||||
is ConstructorDescriptor -> descriptor.constructedClass
|
||||
is PropertyAccessorDescriptor -> descriptor.correspondingProperty
|
||||
else -> descriptor
|
||||
}
|
||||
return@getOrPut nameDeclarator(descriptorForName.name.asString())
|
||||
}
|
||||
|
||||
val nameBuilder = StringBuilder()
|
||||
when (descriptor) {
|
||||
is ReceiverParameterDescriptor -> {
|
||||
@@ -42,10 +52,7 @@ class SimpleNameGenerator : NameGenerator {
|
||||
is ValueParameterDescriptor -> {
|
||||
val declaredName = descriptor.name.asString()
|
||||
nameBuilder.append(declaredName)
|
||||
if (declaredName.startsWith("\$")) {
|
||||
nameBuilder.append('_')
|
||||
nameBuilder.append(descriptor.index)
|
||||
}
|
||||
nameDeclarator = context.currentScope::declareFreshName
|
||||
}
|
||||
is PropertyDescriptor -> {
|
||||
nameBuilder.append(descriptor.name.identifier)
|
||||
|
||||
+3
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -50,3 +51,5 @@ fun CallableMemberDescriptor.isFakeOverriddenFromAny(): Boolean {
|
||||
}
|
||||
|
||||
fun IrDeclaration.isEffectivelyExternal() = descriptor.isEffectivelyExternal()
|
||||
|
||||
fun IrSymbol.isEffectivelyExternal() = descriptor.isEffectivelyExternal()
|
||||
|
||||
Reference in New Issue
Block a user