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 1b1e448ad2a..9d95d13fdf2 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 @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescr import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.js.JsDescriptorsFactory +import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor @@ -107,6 +108,18 @@ class JsIrBackendContext( (0..22).map { symbolTable.referenceClass(reflectionTypes.getKFunction(it)) } } + val primitiveCompanionObjects = PrimitiveType.NUMBER_TYPES + .filter { it.name != "LONG" && it.name != "CHAR" } // skip due to they have own explicit companions + .map { + it.typeName to symbolTable.lazyWrapper.referenceClass( + getClass( + internalPackageName + .child(Name.identifier("internal")) + .child(Name.identifier("${it.typeName.identifier}CompanionObject")) + ) + ) + }.toMap() + val suspendFunctions = (0..22).map { symbolTable.referenceClass(builtIns.getSuspendFunction(it)) } val dynamicType = IrDynamicTypeImpl(createDynamicType(builtIns), emptyList(), Variance.INVARIANT) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt index c6a3ba4b5d7..e2472dd1be3 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt @@ -116,6 +116,7 @@ private fun JsIrBackendContext.lower(moduleFragment: IrModuleFragment) { moduleFragment.files.forEach(clble.getClosureBuilder()) moduleFragment.files.forEach(clble.getReferenceReplacer()) moduleFragment.files.forEach(ClassReferenceLowering(this)::lower) + moduleFragment.files.forEach(PrimitiveCompanionLowering(this)::lower) moduleFragment.files.forEach(IntrinsicifyCallsLowering(this)::lower) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PrimitiveCompanionLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PrimitiveCompanionLowering.kt new file mode 100644 index 00000000000..b8a53e95556 --- /dev/null +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PrimitiveCompanionLowering.kt @@ -0,0 +1,35 @@ +/* + * 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.backend.js.lower + +import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrGetObjectValue +import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl +import org.jetbrains.kotlin.ir.types.isPrimitiveType +import org.jetbrains.kotlin.ir.util.defaultType +import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid +import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid + +class PrimitiveCompanionLowering(val context: JsIrBackendContext) : FileLoweringPass { + override fun lower(irFile: IrFile) { + irFile.transformChildrenVoid(object : IrElementTransformerVoid() { + override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression { + val symbol = expression.symbol + if (!symbol.isBound) return expression + val declaration = symbol.owner + if (!declaration.isCompanion) return expression + val parent = declaration.parent as IrClass + if (!parent.defaultType.isPrimitiveType()) return expression + val actualCompanion = context.primitiveCompanionObjects[parent.name] ?: return expression + return expression.run { IrGetObjectValueImpl(startOffset, endOffset, actualCompanion.owner.defaultType, actualCompanion) } + } + }) + } +} \ No newline at end of file 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 b979b08f1d3..92990b9ca4b 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 @@ -24,6 +24,8 @@ private val runtimeSources = listOfKtFilesFrom( "libraries/stdlib/js/src/kotlin/reflect", "libraries/stdlib/js/src/kotlin/annotationsJVM.kt", + "libraries/stdlib/js/runtime/primitiveCompanionObjects.kt", + "libraries/stdlib/src/kotlin/internal", "libraries/stdlib/src/kotlin/util/Standard.kt", "core/builtins/native/kotlin/Annotation.kt",