From 6863f9e4f373e27a8b611c95032ab5785a6fa882 Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Thu, 14 Feb 2019 20:01:48 +0300 Subject: [PATCH] [JS IR BE] Make backend be able work with unbound symbols * Fix array type deserialization * Prepare to compilation against klibs --- .../ir/backend/js/JsIrBackendContext.kt | 6 +- .../js/lower/ThrowableSuccessorsLowering.kt | 73 ++++++++++--------- .../coroutines/CoroutineIntrinsicLowering.kt | 2 +- .../kotlin/ir/descriptors/IrBuiltIns.kt | 4 +- .../ir/util/ExternalDependenciesGenerator.kt | 2 +- .../kotlin/js/test/BasicIrBoxTest.kt | 2 +- 6 files changed, 47 insertions(+), 42 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt index d368014f2fb..ddf434d8bfc 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt @@ -263,11 +263,11 @@ class JsIrBackendContext( val throwableClass by lazy { symbolTable.referenceClass( getClass(JsIrBackendContext.KOTLIN_PACKAGE_FQN.child(Name.identifier("Throwable"))) - ).owner + ) } - val throwableConstructors by lazy { throwableClass.declarations.filterIsInstance() } + val throwableConstructors by lazy { throwableClass.owner.declarations.filterIsInstance().map { it.symbol } } - val defaultThrowableCtor by lazy { throwableConstructors.single { it.valueParameters.size == 0 } } + val defaultThrowableCtor by lazy { throwableConstructors.single { it.owner.valueParameters.size == 0 } } private fun referenceOperators() = OperatorNames.ALL.map { name -> // TODO to replace KotlinType with IrType we need right equals on IrType diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ThrowableSuccessorsLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ThrowableSuccessorsLowering.kt index 87adffd9f93..577f612bbcf 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ThrowableSuccessorsLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ThrowableSuccessorsLowering.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* +import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.makeNotNull @@ -29,40 +30,44 @@ import org.jetbrains.kotlin.ir.util.isThrowableTypeOrSubtype import org.jetbrains.kotlin.ir.visitors.* import org.jetbrains.kotlin.name.Name -class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPass { - private val unitType = context.irBuiltIns.unitType - private val nothingNType = context.irBuiltIns.nothingNType - private val nothingType = context.irBuiltIns.nothingType - private val stringType = context.irBuiltIns.stringType - private val booleanType = context.irBuiltIns.booleanType +class ThrowableSuccessorsLowering(val context: JsIrBackendContext) : FileLoweringPass { + private val unitType get() = context.irBuiltIns.unitType + private val nothingNType get() = context.irBuiltIns.nothingNType + private val nothingType get() = context.irBuiltIns.nothingType + private val stringType get() = context.irBuiltIns.stringType + private val booleanType get() = context.irBuiltIns.booleanType + private val throwableType get() = context.irBuiltIns.throwableType - private val propertyGetter = context.intrinsics.jsGetJSField.symbol - private val propertySetter = context.intrinsics.jsSetJSField.symbol - private val eqeqeqSymbol = context.irBuiltIns.eqeqSymbol + private val propertyGetter get() = context.intrinsics.jsGetJSField.symbol + private val propertySetter get() = context.intrinsics.jsSetJSField.symbol + private val eqeqeqSymbol get() = context.irBuiltIns.eqeqSymbol private val messageName get() = JsIrBuilder.buildString(stringType, "message") private val causeName get() = JsIrBuilder.buildString(stringType, "cause") private val nameName get() = JsIrBuilder.buildString(stringType, "name") - private val throwableClass = context.throwableClass - private val throwableConstructors = context.throwableConstructors + private val throwableClass by lazy { context.throwableClass } + private val throwableConstructors by lazy { context.throwableConstructors } - private val defaultCtor = context.defaultThrowableCtor - private val toString = - throwableClass.declarations.filterIsInstance().single { it.name == Name.identifier("toString") } + private val defaultCtor by lazy { context.defaultThrowableCtor } + private val toString by lazy { + throwableClass.owner.declarations.filterIsInstance().single { it.name == Name.identifier("toString") }.symbol + } private val messagePropertyName = Name.identifier("message") private val causePropertyName = Name.identifier("cause") - private val messageGetter = - throwableClass.declarations.filterIsInstance().atMostOne { it.name == Name.special("") } - ?: throwableClass.declarations.filterIsInstance().atMostOne { it.name == messagePropertyName }?.getter!! - private val causeGetter = - throwableClass.declarations.filterIsInstance().atMostOne { it.name == Name.special("") } - ?: throwableClass.declarations.filterIsInstance().atMostOne { it.name == causePropertyName }?.getter!! + private val messageGetter by lazy { + throwableClass.owner.declarations.filterIsInstance().atMostOne { it.name == Name.special("") }?.symbol + ?: throwableClass.owner.declarations.filterIsInstance().atMostOne { it.name == messagePropertyName }?.getter?.symbol!! + } + private val causeGetter by lazy { + throwableClass.owner.declarations.filterIsInstance().atMostOne { it.name == Name.special("") }?.symbol + ?: throwableClass.owner.declarations.filterIsInstance().atMostOne { it.name == causePropertyName }?.getter?.symbol!! + } - private val captureStackFunction = context.symbolTable.referenceSimpleFunction(context.getInternalFunctions("captureStack").single()) - private val newThrowableFunction = context.symbolTable.referenceSimpleFunction(context.getInternalFunctions("newThrowable").single()) + private val captureStackFunction by lazy { context.symbolTable.referenceSimpleFunction(context.getInternalFunctions("captureStack").single()) } + private val newThrowableFunction by lazy { context.symbolTable.referenceSimpleFunction(context.getInternalFunctions("newThrowable").single()) } private val pendingSuperUsages = mutableListOf() private data class DirectThrowableSuccessors(val klass: IrClass, val message: IrField, val cause: IrField) @@ -104,7 +109,7 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas inner class ThrowableInstanceCreationLowering : IrElementTransformerVoid() { override fun visitCall(expression: IrCall): IrExpression { - if (expression.symbol.owner !in throwableConstructors) return super.visitCall(expression) + if (expression.symbol !in throwableConstructors) return super.visitCall(expression) expression.transformChildrenVoid(this) @@ -141,8 +146,8 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas override fun visitClass(declaration: IrClass) { if (isDirectChildOfThrowable(declaration)) { - val messageField = createBackingField(declaration, messagePropertyName, messageGetter.returnType) - val causeField = createBackingField(declaration, causePropertyName, causeGetter.returnType) + val messageField = createBackingField(declaration, messagePropertyName, stringType) + val causeField = createBackingField(declaration, causePropertyName, throwableType) val existedMessageAccessor = ownPropertyAccessor(declaration, messageGetter) if (existedMessageAccessor.origin == IrDeclarationOrigin.FAKE_OVERRIDE) createPropertyAccessor(existedMessageAccessor, messageField) @@ -202,13 +207,13 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas override fun visitFunction(declaration: IrFunction, data: IrDeclarationParent) = super.visitFunction(declaration, declaration) override fun visitCall(expression: IrCall, data: IrDeclarationParent): IrElement { - if (expression.superQualifierSymbol?.owner != throwableClass) return super.visitCall(expression, data) + if (expression.superQualifierSymbol != throwableClass) return super.visitCall(expression, data) expression.transformChildren(this, data) val superField = when { - expression.symbol.owner == messageGetter -> successor.message - expression.symbol.owner == causeGetter -> successor.cause + expression.symbol == messageGetter -> successor.message + expression.symbol == causeGetter -> successor.cause else -> error("Unknown accessor") } @@ -216,14 +221,14 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas } override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: IrDeclarationParent): IrElement { - if (expression.symbol.owner !in throwableConstructors) return super.visitDelegatingConstructorCall(expression, data) + if (expression.symbol !in throwableConstructors) return super.visitDelegatingConstructorCall(expression, data) expression.transformChildren(this, data) val (messageArg, causeArg, paramStatements) = extractConstructorParameters(expression, data) val newDelegation = expression.run { - IrDelegatingConstructorCallImpl(startOffset, endOffset, type, defaultCtor.symbol, defaultCtor.descriptor) + IrDelegatingConstructorCallImpl(startOffset, endOffset, type, defaultCtor, defaultCtor.descriptor) } val klass = successor.klass @@ -304,14 +309,14 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas putValueArgument(1, JsIrBuilder.buildNull(value.type)) } val value2 = JsIrBuilder.buildGetValue(receiver.symbol) - val call = JsIrBuilder.buildCall(toString.symbol, stringType).apply { dispatchReceiver = value2 } + val call = JsIrBuilder.buildCall(toString, stringType).apply { dispatchReceiver = value2 } return JsIrBuilder.buildIfElse(stringType.makeNullable(), check, JsIrBuilder.buildNull(stringType), call) } private fun isDirectChildOfThrowable(irClass: IrClass) = irClass.superTypes.any { it.isThrowable() } - private fun ownPropertyAccessor(irClass: IrClass, irBase: IrFunction) = + private fun ownPropertyAccessor(irClass: IrClass, irBase: IrFunctionSymbol) = irClass.declarations.filterIsInstance().mapNotNull { it.getter } - .single { it.overriddenSymbols.any { s -> s.owner == irBase } } + .single { it.overriddenSymbols.any { s -> s == irBase } } inner class ThrowablePropertiesUsageTransformer : IrElementTransformerVoid() { override fun visitCall(expression: IrCall): IrExpression { @@ -321,7 +326,7 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas expression.transformChildrenVoid(this) - val owner = expression.symbol.owner + val owner = expression.symbol return when (owner) { messageGetter -> { IrCallImpl(expression.startOffset, expression.endOffset, expression.type, propertyGetter).apply { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/CoroutineIntrinsicLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/CoroutineIntrinsicLowering.kt index b538eebe0fc..a7e1127fe7f 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/CoroutineIntrinsicLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/CoroutineIntrinsicLowering.kt @@ -28,7 +28,7 @@ class CoroutineIntrinsicLowering(val context: JsIrBackendContext): FileLoweringP irCall(expression, context.coroutineSuspendOrReturn) expression.descriptor.isBuiltInIntercepted(languageVersion) -> error("Intercepted should not be used with release coroutines") - expression.symbol.owner == context.intrinsics.jsCoroutineContext.owner -> + expression.symbol == context.intrinsics.jsCoroutineContext -> irCall(expression, context.coroutineGetContextJs) else -> call } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt index 0134209acf0..68d81a15659 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt @@ -96,8 +96,8 @@ class IrBuiltIns( builtIns.nothing to IrTypeMapper({ nothingType }, { nothingNType }), builtIns.unit to IrTypeMapper({ unitType }, { buildNullableType(unitType) }), builtIns.string to IrTypeMapper({ stringType }, { buildNullableType(stringType) }), - builtIns.throwable to IrTypeMapper({ throwableType }, { buildNullableType(throwableType) }), - builtIns.array to IrTypeMapper({ arrayType }, { buildNullableType(arrayType) }) + builtIns.throwable to IrTypeMapper({ throwableType }, { buildNullableType(throwableType) })//, +// builtIns.array to IrTypeMapper({ arrayType }, { buildNullableType(arrayType) }) ) fun getPrimitiveTypeOrNullByDescriptor(descriptor: ClassifierDescriptor, isNullable: Boolean) = diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt index 5312a4c6167..8cab0220afe 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt @@ -61,7 +61,7 @@ class ExternalDependenciesGenerator( deserializer?.declareForwardDeclarations() - assert(symbolTable.unboundClasses.isEmpty()) +// assert(symbolTable.unboundClasses.isEmpty()) assert(symbolTable.unboundConstructors.isEmpty()) assert(symbolTable.unboundEnumEntries.isEmpty()) assert(symbolTable.unboundFields.isEmpty()) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt index 4fa0ccec2ac..6f9b8b589c1 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt @@ -118,7 +118,7 @@ abstract class BasicIrBoxTest( filesToCompile, config.configuration, listOf(FqName((testPackage?.let { "$it." } ?: "") + testFunction)), - CompilationMode.TEST_AGAINST_CACHE, + CompilationMode.TEST_AGAINST_CACHE,//CompilationMode.TEST_AGAINST_KLIB, dependencies, runtimeResult, moduleType = if (isMainModule) ModuleType.MAIN else ModuleType.SECONDARY