feat: add polyfills insertion for ES Next used features

This commit is contained in:
Artem Kobzar
2022-02-16 10:49:11 +00:00
committed by Space
parent 76ff717091
commit 804eb61bf0
80 changed files with 8769 additions and 6552 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.backend.js.lower.JsInnerClassesSupport
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsPolyfills
import org.jetbrains.kotlin.ir.backend.js.utils.JsInlineClassesUtils
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
@@ -65,7 +66,7 @@ class JsIrBackendContext(
val granularity: JsGenerationGranularity = JsGenerationGranularity.WHOLE_PROGRAM,
val icCompatibleIr2Js: Boolean = false,
) : JsCommonBackendContext {
val polyfills = JsPolyfills()
val fieldToInitializer: MutableMap<IrField, IrExpression> = mutableMapOf()
val localClassNames: MutableMap<IrClass, String> = mutableMapOf()
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
import org.jetbrains.kotlin.ir.backend.js.lower.collectNativeImplementations
import org.jetbrains.kotlin.ir.backend.js.lower.generateJsTests
import org.jetbrains.kotlin.ir.backend.js.lower.moveBodilessDeclarationsToSeparatePlace
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
@@ -140,6 +141,7 @@ fun compileIr(
}
allModules.forEach { module ->
collectNativeImplementations(context, module)
moveBodilessDeclarationsToSeparatePlace(context, module)
}
@@ -158,6 +160,7 @@ fun generateJsCode(
moduleFragment: IrModuleFragment,
nameTables: NameTables
): String {
collectNativeImplementations(context, moduleFragment)
moveBodilessDeclarationsToSeparatePlace(context, moduleFragment)
jsPhases.invokeToplevel(PhaseConfig(jsPhases), context, listOf(moduleFragment))
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.backend.js.ic.ModuleCache
import org.jetbrains.kotlin.ir.backend.js.ic.PersistentCacheConsumer
import org.jetbrains.kotlin.ir.backend.js.lower.collectNativeImplementations
import org.jetbrains.kotlin.ir.backend.js.lower.generateJsTests
import org.jetbrains.kotlin.ir.backend.js.lower.moveBodilessDeclarationsToSeparatePlace
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
@@ -80,6 +81,7 @@ fun compileWithIC(
symbolTable.noUnboundLeft("Unbound symbols at the end of linker")
allModules.forEach {
collectNativeImplementations(context, module)
moveBodilessDeclarationsToSeparatePlace(context, it)
}
@@ -34,9 +34,11 @@ fun eliminateDeadDeclarations(
val uselessDeclarationsProcessor =
UselessDeclarationsRemover(removeUnusedAssociatedObjects, usefulDeclarations, context, context.dceRuntimeDiagnostic)
modules.forEach { module ->
module.files.forEach {
it.acceptVoid(uselessDeclarationsProcessor)
context.polyfills.saveOnlyIntersectionOfNextDeclarationsFor(it, usefulDeclarations)
}
}
}
@@ -55,7 +57,15 @@ private fun IrDeclaration.addRootsTo(
setter?.addRootsTo(nestedVisitor, context)
}
isEffectivelyExternal() -> {
acceptVoid(nestedVisitor)
val correspondingProperty = when (this) {
is IrField -> correspondingPropertySymbol?.owner
is IrSimpleFunction -> correspondingPropertySymbol?.owner
else -> null
}
if (!hasJsPolyfill() && correspondingProperty?.hasJsPolyfill() != true) {
acceptVoid(nestedVisitor)
}
}
isExported(context) -> {
acceptVoid(nestedVisitor)
@@ -55,9 +55,24 @@ abstract class UsefulDeclarationProcessor(
expression.symbol.owner.enqueue(data, "raw function access")
}
override fun visitBlock(expression: IrBlock, data: IrDeclaration) {
super.visitBlock(expression, data)
if (expression !is IrReturnableBlock) return
expression.inlineFunctionSymbol?.owner?.enqueue(data, "inline function usage")
}
override fun visitFieldAccess(expression: IrFieldAccessExpression, data: IrDeclaration) {
super.visitFieldAccess(expression, data)
expression.symbol.owner.enqueue(data, "field access")
val field = expression.symbol.owner.apply { enqueue(data, "field access") }
val correspondingProperty = field.correspondingPropertySymbol?.owner ?: return
if (
field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD &&
correspondingProperty.hasJsPolyfill()
) {
correspondingProperty.enqueue(field, "property backing field")
}
}
override fun visitStringConcatenation(expression: IrStringConcatenation, data: IrDeclaration) {
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.DeclarationTransformer
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
fun collectNativeImplementations(context: JsIrBackendContext, moduleFragment: IrModuleFragment) =
CollectNativeImplementationsVisitor(context).let { collector ->
moduleFragment.files.forEach { it.accept(collector, null) }
}
class CollectNativeImplementationsVisitor(private val context: JsIrBackendContext) : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {}
override fun visitFile(declaration: IrFile) {
declaration.declarations.forEach {
context.polyfills.registerDeclarationNativeImplementation(declaration, it)
}
super.visitFile(declaration)
}
}
@@ -114,7 +114,6 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
expression
)
return JsNameRef(field.getJsNameOrKotlinName().identifier, receiver).withSource(expression, context)
.also { context.staticContext.polyfills.visitDeclaration(field) }
}
if (fieldParent is IrClass && context.isClassInlineLike(fieldParent)) {
@@ -129,7 +128,6 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
if (owner.isThisReceiver()) return JsThisRef().withSource(expression, context)
return context.getNameForValueDeclaration(owner).makeRef().withSource(expression, context)
.also { context.staticContext.polyfills.visitDeclaration(owner) }
}
override fun visitGetObjectValue(expression: IrGetObjectValue, context: JsGenerationContext): JsExpression {
@@ -146,7 +144,6 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
val dest = jsElementAccess(fieldName.ident, expression.receiver?.accept(this, context))
val source = expression.value.accept(this, context)
return jsAssignment(dest, source).withSource(expression, context)
.also { context.staticContext.polyfills.visitDeclaration(field) }
}
override fun visitSetValue(expression: IrSetValue, context: JsGenerationContext): JsExpression {
@@ -154,7 +151,6 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
val ref = JsNameRef(context.getNameForValueDeclaration(field))
val value = expression.value.accept(this, context)
return JsBinaryOperation(JsBinaryOperator.ASG, ref, value).withSource(expression, context)
.also { context.staticContext.polyfills.visitDeclaration(field) }
}
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, context: JsGenerationContext): JsExpression {
@@ -225,10 +221,6 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
return JsCallTransformer(expression, context).generateExpression()
}
return translateCall(expression, context, this).withSource(expression, context)
.also {
val function = expression.symbol.owner
context.staticContext.polyfills.visitDeclaration(function.correspondingPropertySymbol?.owner ?: function)
}
}
override fun visitWhen(expression: IrWhen, context: JsGenerationContext): JsExpression {
@@ -86,9 +86,7 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
override fun visitSetValue(expression: IrSetValue, context: JsGenerationContext): JsStatement {
val owner = expression.symbol.owner
val ref = JsNameRef(context.getNameForValueDeclaration(owner))
return expression.value
.maybeOptimizeIntoSwitch(context) { jsAssignment(ref, it).withSource(expression, context).makeStmt() }
.also { context.staticContext.polyfills.visitDeclaration(owner) }
return expression.value.maybeOptimizeIntoSwitch(context) { jsAssignment(ref, it).withSource(expression, context).makeStmt() }
}
override fun visitReturn(expression: IrReturn, context: JsGenerationContext): JsStatement {
@@ -139,7 +137,6 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
return JsCallTransformer(expression, data).generateStatement()
}
return translateCall(expression, data, IrElementToJsExpressionTransformer()).withSource(expression, data).makeStmt()
.also { data.staticContext.polyfills.visitDeclaration(expression.symbol.owner) }
}
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, context: JsGenerationContext): JsStatement {
@@ -98,7 +98,7 @@ class IrModuleToJsTransformer(
exportedModule,
namer,
refInfo,
generateMainCall = true
generateMainCall = true,
)
val dependencies = others.mapIndexed { index, module ->
@@ -112,7 +112,7 @@ class IrModuleToJsTransformer(
ExportedModule(moduleName, exportedModule.moduleKind, exportedDeclarations),
namer,
refInfo,
generateMainCall = false
generateMainCall = false,
)
}.reversed()
@@ -123,7 +123,8 @@ class IrModuleToJsTransformer(
emptyList(),
exportedModule,
namer,
EmptyCrossModuleReferenceInfo
EmptyCrossModuleReferenceInfo,
generateMainCall = true,
)
}
}
@@ -134,7 +135,7 @@ class IrModuleToJsTransformer(
exportedModule: ExportedModule,
namer: NameTables,
refInfo: CrossModuleReferenceInfo,
generateMainCall: Boolean = true
generateMainCall: Boolean = true,
): CompilationOutputs {
val nameGenerator = refInfo.withReferenceTracking(
@@ -147,6 +148,7 @@ class IrModuleToJsTransformer(
globalNameScope = namer.globalNames
)
val polyfillStatements = generatePolyfillStatements(modules)
val (importStatements, importedJsModules) =
generateImportStatements(
getNameForExternalDeclaration = { staticContext.getNameForStaticDeclaration(it) },
@@ -163,8 +165,10 @@ class IrModuleToJsTransformer(
val crossModuleExports = generateCrossModuleExports(modules, refInfo, internalModuleName)
val program = JsProgram()
if (generateScriptModule) {
with(program.globalBlock) {
statements.addWithComment("block: polyfills", polyfillStatements)
statements.addWithComment("block: imports", importStatements + crossModuleImports)
statements += moduleBody
statements.addWithComment("block: exports", exportStatements + crossModuleExports)
@@ -185,6 +189,7 @@ class IrModuleToJsTransformer(
}
}
program.globalBlock.statements.addWithComment("block: polyfills", polyfillStatements)
program.globalBlock.statements += ModuleWrapperTranslation.wrap(
exportedModule.name,
rootFunction,
@@ -223,7 +228,6 @@ class IrModuleToJsTransformer(
null
}
staticContext.polyfills.addAllNeededPolyfillsTo(jsCode)
program.accept(JsToStringGenerationVisitor(jsCode, sourceMapBuilderConsumer ?: NoOpSourceLocationConsumer))
return CompilationOutputs(
@@ -290,7 +294,6 @@ class IrModuleToJsTransformer(
val statements = mutableListOf<JsStatement>()
val preDeclarationBlock = JsGlobalBlock()
val postDeclarationBlock = JsGlobalBlock()
statements.addWithComment("block: pre-declaration", preDeclarationBlock)
@@ -394,6 +397,13 @@ class IrModuleToJsTransformer(
} ?: emptyList()
}
private fun generatePolyfillStatements(modules: Iterable<IrModuleFragment>): List<JsStatement> {
return modules.asSequence()
.flatMap { it.files }
.flatMap { backendContext.polyfills.getAllPolyfillsFor(it) }
.toList()
}
private fun generateImportStatements(
getNameForExternalDeclaration: (IrDeclarationWithName) -> JsName,
declareFreshGlobal: (String) -> JsName
@@ -147,13 +147,16 @@ class IrModuleToJsTransformerTmp(
modules: Iterable<IrModuleFragment>,
exportData: Map<IrModuleFragment, Map<IrFile, List<ExportedDeclaration>>>,
): JsIrProgram {
return JsIrProgram(
modules.map { m ->
JsIrModule(m.safeName, m.externalModuleName(), m.files.map { f ->
val exports = exportData[m]!![f]!!
generateProgramFragment(f, exports)
})
JsIrModule(
m.safeName,
m.externalModuleName(),
m.files.map {
val exports = exportData[m]!![it]!!
generateProgramFragment(it, exports)
},
)
}
)
}
@@ -172,7 +175,9 @@ class IrModuleToJsTransformerTmp(
globalNameScope = globalNameScope
)
val result = JsIrProgramFragment(file.fqName.asString())
val result = JsIrProgramFragment(file.fqName.asString()).apply {
polyfills.statements += backendContext.polyfills.getAllPolyfillsFor(file)
}
val internalModuleName = ReservedJsNames.makeInternalModuleName()
val globalNames = NameTable<String>(globalNameScope)
@@ -364,7 +369,7 @@ private fun generateSingleWrappedModuleBody(
sourceMapsInfo: SourceMapsInfo?,
generateScriptModule: Boolean,
generateCallToMain: Boolean,
crossModuleReferences: CrossModuleReferences = CrossModuleReferences.Empty
crossModuleReferences: CrossModuleReferences = CrossModuleReferences.Empty,
): CompilationOutputs {
val program = Merger(
moduleName,
@@ -21,9 +21,14 @@ class JsIrProgramFragment(val packageFqn: String) {
var testFunInvocation: JsStatement? = null
var suiteFn: JsName? = null
val definitions = mutableSetOf<String>()
val polyfills = JsGlobalBlock()
}
class JsIrModule(val moduleName: String, val externalModuleName: String, val fragments: List<JsIrProgramFragment>)
class JsIrModule(
val moduleName: String,
val externalModuleName: String,
val fragments: List<JsIrProgramFragment>,
)
class JsIrProgram(val modules: List<JsIrModule>) {
val mainModule = modules.last()
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.transformers.irToJs
import org.jetbrains.kotlin.ir.backend.js.utils.getJsPolyfill
import org.jetbrains.kotlin.ir.backend.js.utils.hasJsPolyfill
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.js.backend.ast.JsStatement
class JsPolyfills {
private val polyfillsPerFile = hashMapOf<IrFile, HashSet<IrDeclaration>>()
fun registerDeclarationNativeImplementation(file: IrFile, declaration: IrDeclaration) {
if (!declaration.hasJsPolyfill()) return
val declarations = polyfillsPerFile[file] ?: hashSetOf()
declarations.add(declaration)
polyfillsPerFile[file] = declarations
}
fun saveOnlyIntersectionOfNextDeclarationsFor(file: IrFile, declarations: Set<IrDeclaration>) {
val polyfills = polyfillsPerFile[file] ?: return
polyfillsPerFile[file] = polyfills.intersect(declarations).toHashSet()
}
fun getAllPolyfillsFor(file: IrFile): List<JsStatement> =
polyfillsPerFile[file].orEmpty().asImplementationList()
private fun Iterable<IrDeclaration>.asImplementationList() =
asSequence().asImplementationList()
private fun Sequence<IrDeclaration>.asImplementationList(): List<JsStatement> =
map { it.getJsPolyfill()!! }
.distinct()
.flatMap { parseJsCode(it).orEmpty() }
.toList()
}
@@ -1,28 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.transformers.irToJs
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.backend.js.utils.getJsNativeImplementation
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
import org.jetbrains.kotlin.js.util.TextOutput
class JsPolyfillsVisitor {
private val polyfills = mutableSetOf<String>()
fun visitDeclaration(declaration: IrDeclaration) {
if (!declaration.isEffectivelyExternal()) return
val implementation = declaration.getJsNativeImplementation() ?: return
polyfills.add(implementation)
}
fun addAllNeededPolyfillsTo(output: TextOutput) {
if (polyfills.isEmpty()) return
output.print("// region block: polyfills")
output.print(polyfills.joinToString("\n"))
output.print("// endregion\n")
}
}
@@ -159,21 +159,22 @@ class Merger(
linkJsNames()
val moduleBody = mutableListOf<JsStatement>().also {
if (!generateScriptModule) it += JsStringLiteral("use strict").makeStmt()
}
val moduleBody = mutableListOf<JsStatement>()
val preDeclarationBlock = JsGlobalBlock()
val postDeclarationBlock = JsGlobalBlock()
val polyfillDeclarationBlock = JsGlobalBlock()
moduleBody.addWithComment("block: pre-declaration", preDeclarationBlock)
val classModels = mutableMapOf<JsName, JsIrIcClassModel>()
val initializerBlock = JsGlobalBlock()
fragments.forEach {
moduleBody += it.declarations.statements
classModels += it.classes
initializerBlock.statements += it.initializers.statements
polyfillDeclarationBlock.statements += it.polyfills.statements
}
// sort member forwarding code
@@ -213,9 +214,13 @@ class Merger(
if (generateScriptModule) {
with(program.globalBlock) {
this.statements.addWithComment("block: imports", importStatements)
this.statements += moduleBody
this.statements.addWithComment("block: exports", exportStatements)
if (!generateScriptModule) {
statements += JsStringLiteral("use strict").makeStmt()
}
statements.addWithComment("block: polyfills", polyfillDeclarationBlock.statements)
statements.addWithComment("block: imports", importStatements)
statements += moduleBody
statements.addWithComment("block: exports", exportStatements)
}
} else {
val internalModuleName = ReservedJsNames.makeInternalModuleName()
@@ -223,9 +228,12 @@ class Merger(
parameters += JsParameter(internalModuleName)
parameters += (importedJsModules).map { JsParameter(it.internalName) }
with(body) {
this.statements.addWithComment("block: imports", importStatements)
this.statements += moduleBody
this.statements.addWithComment("block: exports", exportStatements)
if (!generateScriptModule) {
statements += JsStringLiteral("use strict").makeStmt()
}
statements.addWithComment("block: imports", importStatements)
statements += moduleBody
statements.addWithComment("block: exports", exportStatements)
if (generateCallToMain) {
callToMain?.let { this.statements += it }
}
@@ -233,6 +241,7 @@ class Merger(
}
}
program.globalBlock.statements.addWithComment("block: polyfills", polyfillDeclarationBlock.statements)
program.globalBlock.statements += ModuleWrapperTranslation.wrap(
moduleName,
rootFunction,
@@ -27,7 +27,7 @@ object JsAnnotations {
val jsNativeSetter = FqName("kotlin.js.nativeSetter")
val jsNativeInvoke = FqName("kotlin.js.nativeInvoke")
val jsFunFqn = FqName("kotlin.js.JsFun")
val jsNativeImplementationFqn = FqName("kotlin.js.JsNativeImplementation")
val JsPolyfillFqn = FqName("kotlin.js.JsPolyfill")
}
@Suppress("UNCHECKED_CAST")
@@ -46,8 +46,11 @@ fun IrAnnotationContainer.getJsQualifier(): String? =
fun IrAnnotationContainer.getJsName(): String? =
getAnnotation(JsAnnotations.jsNameFqn)?.getSingleConstStringArgument()
fun IrAnnotationContainer.getJsNativeImplementation(): String? =
getAnnotation(JsAnnotations.jsNativeImplementationFqn)?.getSingleConstStringArgument()
fun IrAnnotationContainer.getJsPolyfill(): String? =
getAnnotation(JsAnnotations.JsPolyfillFqn)?.getSingleConstStringArgument()
fun IrAnnotationContainer.hasJsPolyfill(): Boolean =
hasAnnotation(JsAnnotations.JsPolyfillFqn)
fun IrAnnotationContainer.getJsFunAnnotation(): String? =
getAnnotation(JsAnnotations.jsFunFqn)?.getSingleConstStringArgument()
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.ir.backend.js.utils
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIntrinsicTransformers
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrClassModel
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsPolyfillsVisitor
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
@@ -20,7 +19,6 @@ class JsStaticContext(
private val irNamer: IrNamer,
val globalNameScope: NameTable<IrDeclaration>,
) : IrNamer by irNamer {
val polyfills = JsPolyfillsVisitor()
val intrinsics = JsIntrinsicTransformers(backendContext)
val classModels = mutableMapOf<IrClassSymbol, JsIrClassModel>()
val coroutineImplDeclaration = backendContext.ir.symbols.coroutineImpl.owner
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.ir.backend.js.utils.serialization
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrClassModel
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrIcClassModel
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrProgramFragment
import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope
@@ -60,6 +59,9 @@ class JsIrAstDeserializer : JsAstDeserializerBase() {
if (proto.hasExportBlock()) {
fragment.exports.statements += deserializeGlobalBlock(proto.exportBlock).statements
}
if (proto.hasPolyfills()) {
fragment.polyfills.statements += deserializeGlobalBlock(proto.polyfills).statements
}
proto.nameBindingList.associateTo(fragment.nameBindings) { nameBindingProto ->
deserializeString(nameBindingProto.signatureId) to deserializeName(nameBindingProto.nameId)
@@ -80,7 +82,6 @@ class JsIrAstDeserializer : JsAstDeserializerBase() {
}
fragment.dts = proto.dts
fragment.definitions += proto.definitionsList.map { deserializeString(it) }
return fragment
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrProgramFragmen
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.*
import org.jetbrains.kotlin.serialization.js.ast.JsAstSerializerBase
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.io.OutputStream
@@ -60,6 +61,7 @@ class JsIrAstSerializer: JsAstSerializerBase() {
fragmentBuilder.declarationBlock = serializeBlock(fragment.declarations)
fragmentBuilder.initializerBlock = serializeBlock(fragment.initializers)
fragmentBuilder.exportBlock = serializeBlock(fragment.exports)
fragmentBuilder.polyfills = serializeBlock(fragment.polyfills)
for ((key, name) in fragment.nameBindings.entries) {
val nameBindingBuilder = NameBinding.newBuilder()
@@ -1248,7 +1248,6 @@ public class JsToStringGenerationVisitor extends JsVisitor {
p.print(javaScriptString(jsImport.getModule()));
}
private void newline() {
p.newline();
sourceLocationConsumer.newLine();
+5
View File
@@ -373,6 +373,10 @@ message Catch {
message Empty {
}
message Code {
required string value = 1;
}
message SingleLineComment {
required string message = 1;
}
@@ -404,6 +408,7 @@ message Fragment {
optional string dts = 15;
optional int32 suite_function = 16;
repeated int32 definitions = 17;
optional GlobalBlock polyfills = 18;
}
message InlinedLocalDeclarations {
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -333,7 +333,8 @@ val runMocha by task<NpmTask> {
environment.set(mapOf(
"KOTLIN_JS_LOCATION" to rootDir.resolve("dist/js/kotlin.js").toString(),
"KOTLIN_JS_TEST_LOCATION" to rootDir.resolve("dist/js/kotlin-test.js").toString()
"KOTLIN_JS_TEST_LOCATION" to rootDir.resolve("dist/js/kotlin-test.js").toString(),
"BOX_FLAG_LOCATION" to rootDir.resolve("compiler/testData/jsBoxFlag.js").toString()
))
}
@@ -132,7 +132,7 @@ fun getAllFilesForRunner(
val dceOutputDir = JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices, TranslationMode.FULL_DCE)
val artifactsPaths = modulesToArtifact.values.map { it.outputFile.absolutePath }.filter { !File(it).isDirectory }
val allJsFiles = additionalFiles + inputJsFilesBefore + artifactsPaths + commonFiles + additionalMainFiles + inputJsFilesAfter
val allJsFiles = additionalFiles + inputJsFilesBefore +artifactsPaths + commonFiles + additionalMainFiles + inputJsFilesAfter
val result = mutableMapOf(TranslationMode.FULL to allJsFiles)
@@ -8137,6 +8137,206 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills")
@TestDataPath("$PROJECT_ROOT")
public class Polyfills {
@Test
public void testAllFilesPresentInPolyfills() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/acosh")
@TestDataPath("$PROJECT_ROOT")
public class Acosh {
@Test
public void testAllFilesPresentInAcosh() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/acosh"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/asinh")
@TestDataPath("$PROJECT_ROOT")
public class Asinh {
@Test
public void testAllFilesPresentInAsinh() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/asinh"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/atanh")
@TestDataPath("$PROJECT_ROOT")
public class Atanh {
@Test
public void testAllFilesPresentInAtanh() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/atanh"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/clz32")
@TestDataPath("$PROJECT_ROOT")
public class Clz32 {
@Test
public void testAllFilesPresentInClz32() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/clz32"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/cosh")
@TestDataPath("$PROJECT_ROOT")
public class Cosh {
@Test
public void testAllFilesPresentInCosh() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/cosh"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/expm1")
@TestDataPath("$PROJECT_ROOT")
public class Expm1 {
@Test
public void testAllFilesPresentInExpm1() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/expm1"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/fill")
@TestDataPath("$PROJECT_ROOT")
public class Fill {
@Test
public void testAllFilesPresentInFill() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/fill"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/globalThis")
@TestDataPath("$PROJECT_ROOT")
public class GlobalThis {
@Test
public void testAllFilesPresentInGlobalThis() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/globalThis"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/hypot")
@TestDataPath("$PROJECT_ROOT")
public class Hypot {
@Test
public void testAllFilesPresentInHypot() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/hypot"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/imul")
@TestDataPath("$PROJECT_ROOT")
public class Imul {
@Test
public void testAllFilesPresentInImul() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/imul"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/isView")
@TestDataPath("$PROJECT_ROOT")
public class IsView {
@Test
public void testAllFilesPresentInIsView() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/isView"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/log10")
@TestDataPath("$PROJECT_ROOT")
public class Log10 {
@Test
public void testAllFilesPresentInLog10() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/log10"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/log1p")
@TestDataPath("$PROJECT_ROOT")
public class Log1p {
@Test
public void testAllFilesPresentInLog1p() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/log1p"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/log2")
@TestDataPath("$PROJECT_ROOT")
public class Log2 {
@Test
public void testAllFilesPresentInLog2() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/log2"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/sign")
@TestDataPath("$PROJECT_ROOT")
public class Sign {
@Test
public void testAllFilesPresentInSign() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/sign"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/sinh")
@TestDataPath("$PROJECT_ROOT")
public class Sinh {
@Test
public void testAllFilesPresentInSinh() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/sinh"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/sort")
@TestDataPath("$PROJECT_ROOT")
public class Sort {
@Test
public void testAllFilesPresentInSort() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/sort"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/tanh")
@TestDataPath("$PROJECT_ROOT")
public class Tanh {
@Test
public void testAllFilesPresentInTanh() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/tanh"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/trunc")
@TestDataPath("$PROJECT_ROOT")
public class Trunc {
@Test
public void testAllFilesPresentInTrunc() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/trunc"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/propertyAccess")
@TestDataPath("$PROJECT_ROOT")
@@ -8533,6 +8533,434 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills")
@TestDataPath("$PROJECT_ROOT")
public class Polyfills {
@Test
public void testAllFilesPresentInPolyfills() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/acosh")
@TestDataPath("$PROJECT_ROOT")
public class Acosh {
@Test
@TestMetadata("acoshWithExistedIntrinsic.kt")
public void testAcoshWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/acosh/acoshWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("acoshWithoutExistedIntrinsic.kt")
public void testAcoshWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/acosh/acoshWithoutExistedIntrinsic.kt");
}
@Test
public void testAllFilesPresentInAcosh() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/acosh"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/asinh")
@TestDataPath("$PROJECT_ROOT")
public class Asinh {
@Test
public void testAllFilesPresentInAsinh() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/asinh"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("asinhWithExistedIntrinsic.kt")
public void testAsinhWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/asinh/asinhWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("asinhWithoutExistedIntrinsic.kt")
public void testAsinhWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/asinh/asinhWithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/atanh")
@TestDataPath("$PROJECT_ROOT")
public class Atanh {
@Test
public void testAllFilesPresentInAtanh() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/atanh"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("atanhWithExistedIntrinsic.kt")
public void testAtanhWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/atanh/atanhWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("atanhWithoutExistedIntrinsic.kt")
public void testAtanhWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/atanh/atanhWithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/clz32")
@TestDataPath("$PROJECT_ROOT")
public class Clz32 {
@Test
public void testAllFilesPresentInClz32() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/clz32"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("clz32WithExistedIntrinsic.kt")
public void testClz32WithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/clz32/clz32WithExistedIntrinsic.kt");
}
@Test
@TestMetadata("clz32WithoutExistedIntrinsic.kt")
public void testClz32WithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/clz32/clz32WithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/cosh")
@TestDataPath("$PROJECT_ROOT")
public class Cosh {
@Test
public void testAllFilesPresentInCosh() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/cosh"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("coshWithExistedIntrinsic.kt")
public void testCoshWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/cosh/coshWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("coshWithoutExistedIntrinsic.kt")
public void testCoshWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/cosh/coshWithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/expm1")
@TestDataPath("$PROJECT_ROOT")
public class Expm1 {
@Test
public void testAllFilesPresentInExpm1() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/expm1"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("expm1WithExistedIntrinsic.kt")
public void testExpm1WithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/expm1/expm1WithExistedIntrinsic.kt");
}
@Test
@TestMetadata("expm1WithoutExistedIntrinsic.kt")
public void testExpm1WithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/expm1/expm1WithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/fill")
@TestDataPath("$PROJECT_ROOT")
public class Fill {
@Test
public void testAllFilesPresentInFill() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/fill"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("arrayFillWithExistedIntrinsic.kt")
public void testArrayFillWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/fill/arrayFillWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("arrayFillWithoutExistedIntrinsic.kt")
public void testArrayFillWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/fill/arrayFillWithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/globalThis")
@TestDataPath("$PROJECT_ROOT")
public class GlobalThis {
@Test
public void testAllFilesPresentInGlobalThis() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/globalThis"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("globalThisWithExistedIntrinsic.kt")
public void testGlobalThisWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/globalThis/globalThisWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("globalThisWithoutExistedIntrinsic.kt")
public void testGlobalThisWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/globalThis/globalThisWithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/hypot")
@TestDataPath("$PROJECT_ROOT")
public class Hypot {
@Test
public void testAllFilesPresentInHypot() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/hypot"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("hypotWithExistedIntrinsic.kt")
public void testHypotWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/hypot/hypotWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("hypotWithoutExistedIntrinsic.kt")
public void testHypotWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/hypot/hypotWithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/imul")
@TestDataPath("$PROJECT_ROOT")
public class Imul {
@Test
public void testAllFilesPresentInImul() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/imul"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("imulWithExistedIntrinsic.kt")
public void testImulWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/imul/imulWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("imulWithoutExistedIntrinsic.kt")
public void testImulWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/imul/imulWithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/isView")
@TestDataPath("$PROJECT_ROOT")
public class IsView {
@Test
public void testAllFilesPresentInIsView() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/isView"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("isViewWithExistedIntrinsic.kt")
public void testIsViewWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/isView/isViewWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("isViewWithoutExistedIntrinsic.kt")
public void testIsViewWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/isView/isViewWithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/log10")
@TestDataPath("$PROJECT_ROOT")
public class Log10 {
@Test
public void testAllFilesPresentInLog10() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/log10"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("log10WithExistedIntrinsic.kt")
public void testLog10WithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/log10/log10WithExistedIntrinsic.kt");
}
@Test
@TestMetadata("log10WithoutExistedIntrinsic.kt")
public void testLog10WithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/log10/log10WithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/log1p")
@TestDataPath("$PROJECT_ROOT")
public class Log1p {
@Test
public void testAllFilesPresentInLog1p() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/log1p"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("log1pWithExistedIntrinsic.kt")
public void testLog1pWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/log1p/log1pWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("log1pWithoutExistedIntrinsic.kt")
public void testLog1pWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/log1p/log1pWithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/log2")
@TestDataPath("$PROJECT_ROOT")
public class Log2 {
@Test
public void testAllFilesPresentInLog2() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/log2"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("log2WithExistedIntrinsic.kt")
public void testLog2WithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/log2/log2WithExistedIntrinsic.kt");
}
@Test
@TestMetadata("log2WithoutExistedIntrinsic.kt")
public void testLog2WithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/log2/log2WithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/sign")
@TestDataPath("$PROJECT_ROOT")
public class Sign {
@Test
public void testAllFilesPresentInSign() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/sign"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("signWithExistedIntrinsic.kt")
public void testSignWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/sign/signWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("signWithoutExistedIntrinsic.kt")
public void testSignWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/sign/signWithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/sinh")
@TestDataPath("$PROJECT_ROOT")
public class Sinh {
@Test
public void testAllFilesPresentInSinh() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/sinh"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("sinhWithExistedIntrinsic.kt")
public void testSinhWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/sinh/sinhWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("sinhWithoutExistedIntrinsic.kt")
public void testSinhWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/sinh/sinhWithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/sort")
@TestDataPath("$PROJECT_ROOT")
public class Sort {
@Test
public void testAllFilesPresentInSort() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/sort"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("sortWithExistedIntrinsic.kt")
public void testSortWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/sort/sortWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("sortWithoutExistedIntrinsic.kt")
public void testSortWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/sort/sortWithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/tanh")
@TestDataPath("$PROJECT_ROOT")
public class Tanh {
@Test
public void testAllFilesPresentInTanh() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/tanh"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("tanhWithExistedIntrinsic.kt")
public void testTanhWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/tanh/tanhWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("tanhWithoutExistedIntrinsic.kt")
public void testTanhWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/tanh/tanhWithoutExistedIntrinsic.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/polyfills/trunc")
@TestDataPath("$PROJECT_ROOT")
public class Trunc {
@Test
public void testAllFilesPresentInTrunc() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/polyfills/trunc"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("truncWithExistedIntrinsic.kt")
public void testTruncWithExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/trunc/truncWithExistedIntrinsic.kt");
}
@Test
@TestMetadata("truncWithoutExistedIntrinsic.kt")
public void testTruncWithoutExistedIntrinsic() throws Exception {
runTest("js/js.translator/testData/box/polyfills/trunc/truncWithoutExistedIntrinsic.kt");
}
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/propertyAccess")
@TestDataPath("$PROJECT_ROOT")
@@ -0,0 +1,27 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.acosh = function acosh(x) {
acosh.called = true;
if (x <= 0.5) {
return NaN
} else if (x === 1) {
return 0
}
return 1.3169578969248166
}
// FILE: main.kt
import kotlin.math.acosh
fun box(): String {
assertEquals(acosh(-1.0), Double.NaN)
assertEquals(acosh(0.0), Double.NaN)
assertEquals(acosh(0.5), Double.NaN)
assertEquals(acosh(1.0), 0.0)
assertEquals(acosh(2.0), 1.3169578969248166)
assertEquals(js("Math.acosh.called"), true)
return "OK"
}
@@ -0,0 +1,19 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.acosh = undefined;
// FILE: main.kt
import kotlin.math.acosh
fun box(): String {
assertEquals(acosh(-1.0), Double.NaN)
assertEquals(acosh(0.0), Double.NaN)
assertEquals(acosh(0.5), Double.NaN)
assertEquals(acosh(1.0), 0.0)
assertEquals(acosh(2.0), 1.3169578969248166)
assertEquals(js("Math.acosh.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,26 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.asinh = function asinh(x) {
asinh.called = true;
switch (x) {
case -1: return -0.8813735870195429
case 0: return 0.0
case 1: return 0.8813735870195429
case 2: return 1.4436354751788103
}
}
// FILE: main.kt
import kotlin.math.asinh
fun box(): String {
assertEquals(asinh(-1.0), -0.8813735870195429)
assertEquals(asinh(0.0), 0.0)
assertEquals(asinh(1.0), 0.8813735870195429)
assertEquals(asinh(2.0), 1.4436354751788103)
assertEquals(js("Math.asinh.called"), true)
return "OK"
}
@@ -0,0 +1,18 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.asinh = undefined;
// FILE: main.kt
import kotlin.math.asinh
fun box(): String {
assertEquals(asinh(-1.0), -0.8813735870195429)
assertEquals(asinh(0.0), 0.0)
assertEquals(asinh(1.0), 0.8813735870195429)
assertEquals(asinh(2.0), 1.4436354751788103)
assertEquals(js("Math.asinh.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,26 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.atanh = function atanh(x) {
atanh.called = true;
switch (x) {
case -1: return -Infinity
case 0: return 0.0
case 0.5: return 0.5493061443340548
case 1: return Infinity
}
}
// FILE: main.kt
import kotlin.math.atanh
fun box(): String {
assertEquals(atanh(-1.0), Double.NEGATIVE_INFINITY)
assertEquals(atanh(0.0), 0.0)
assertEquals(atanh(0.5), 0.5493061443340548)
assertEquals(atanh(1.0), Double.POSITIVE_INFINITY)
assertEquals(js("Math.atanh.called"), true)
return "OK"
}
@@ -0,0 +1,18 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.atanh = undefined;
// FILE: main.kt
import kotlin.math.atanh
fun box(): String {
assertEquals(atanh(-1.0), Double.NEGATIVE_INFINITY)
assertEquals(atanh(0.0), 0.0)
assertEquals(atanh(0.5), 0.5493061443340548)
assertEquals(atanh(1.0), Double.POSITIVE_INFINITY)
assertEquals(js("Math.atanh.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,21 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.clz32 = function clz32(x) {
clz32.called = true;
var asUint = x >>> 0;
if (asUint === 0) {
return 32;
}
return 31 - (Math.log(asUint) / Math.LN2 | 0) | 0; // the "| 0" acts like math.floor
}
// FILE: main.kt
fun box(): String {
val result = 4.countLeadingZeroBits()
assertEquals(result, 29)
assertEquals(js("Math.clz32.called"), true)
return "OK"
}
@@ -0,0 +1,14 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.clz32 = undefined;
// FILE: main.kt
fun box(): String {
val result = 4.countLeadingZeroBits()
assertEquals(result, 29)
assertEquals(js("Math.clz32.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,26 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.cosh = function cosh(x) {
cosh.called = true;
switch (x) {
case -1: return 1.5430806348152437
case 0: return 1.0
case 1: return 1.5430806348152437
case 2: return 3.7621956910836314
}
}
// FILE: main.kt
import kotlin.math.cosh
fun box(): String {
assertEquals(cosh(-1.0), 1.5430806348152437)
assertEquals(cosh(0.0), 1.0)
assertEquals(cosh(1.0), 1.5430806348152437)
assertEquals(cosh(2.0), 3.7621956910836314)
assertEquals(js("Math.cosh.called"), true)
return "OK"
}
@@ -0,0 +1,18 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.cosh = undefined;
// FILE: main.kt
import kotlin.math.cosh
fun box(): String {
assertEquals(cosh(-1.0), 1.5430806348152437)
assertEquals(cosh(0.0), 1.0)
assertEquals(cosh(1.0), 1.5430806348152437)
assertEquals(cosh(2.0), 3.7621956910836314)
assertEquals(js("Math.cosh.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,26 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.expm1 = function expm1(x) {
expm1.called = true;
switch (x) {
case -1: return -0.6321205588285577
case 0: return 0.0
case 1: return 1.718281828459045
case 2: return 6.38905609893065
}
}
// FILE: main.kt
import kotlin.math.expm1
fun box(): String {
assertEquals(expm1(-1.0), -0.6321205588285577)
assertEquals(expm1(0.0), 0.0)
assertEquals(expm1(1.0), 1.718281828459045)
assertEquals(expm1(2.0), 6.38905609893065)
assertEquals(js("Math.expm1.called"), true)
return "OK"
}
@@ -0,0 +1,18 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.expm1 = undefined;
// FILE: main.kt
import kotlin.math.expm1
fun box(): String {
assertEquals(expm1(-1.0), -0.6321205588285577)
assertEquals(expm1(0.0), 0.0)
assertEquals(expm1(1.0), 1.718281828459045)
assertEquals(expm1(2.0), 6.38905609893065)
assertEquals(js("Math.expm1.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,20 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Int32Array.prototype.fill = function fill(value) {
fill.called = true;
for (var i = 0; i < this.length; i++) {
this[i] = value;
}
return this
}
// FILE: main.kt
fun box(): String {
val int = IntArray(4).apply { fill(42) }
assertEquals(int.joinToString(", "), "42, 42, 42, 42")
assertEquals(js("Int32Array.prototype.fill.called"), true)
return "OK"
}
@@ -0,0 +1,14 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Int32Array.prototype.fill = undefined;
// FILE: main.kt
fun box(): String {
val int = IntArray(4).apply { fill(42) }
assertEquals(int.joinToString(", "), "42, 42, 42, 42")
assertEquals(js("Int32Array.prototype.fill.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,12 @@
// !LANGUAGE: +JsAllowInvalidCharsIdentifiersEscaping
// TARGET_BACKEND: JS_IR
// FILE: main.js
this.globalThis = { "Is Just Created Global This": true }
// FILE: main.kt
external val `Is Just Created Global This`: Boolean
fun box(): String {
assertEquals(`Is Just Created Global This`, true)
return "OK"
}
@@ -0,0 +1,13 @@
// !LANGUAGE: +JsAllowInvalidCharsIdentifiersEscaping
// TARGET_BACKEND: JS_IR
// FILE: main.js
this.globalThis = undefined
this["Is Just Created Global This"] = true
// FILE: main.kt
external val `Is Just Created Global This`: Boolean
fun box(): String {
assertEquals(`Is Just Created Global This`, true)
return "OK"
}
@@ -0,0 +1,19 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.hypot = function hypot(a, b) {
hypot.called = true;
return Math.sqrt(a*a + b*b)
}
// FILE: main.kt
import kotlin.math.hypot
fun box(): String {
assertEquals(hypot(3.0, 4.0), 5.0)
assertEquals(hypot(5.0, 12.0), 13.0)
assertEquals(hypot(-5.0, 0.0), 5.0)
assertEquals(js("Math.hypot.called"), true)
return "OK"
}
@@ -0,0 +1,16 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.hypot = undefined;
// FILE: main.kt
import kotlin.math.hypot
fun box(): String {
assertEquals(hypot(3.0, 4.0), 5.0)
assertEquals(hypot(5.0, 12.0), 13.0)
assertEquals(hypot(-5.0, 0.0), 5.0)
assertEquals(js("Math.hypot.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,18 @@
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.imul = function imul(a, b) {
imul.called = true;
return a * b
}
// FILE: main.kt
fun box(): String {
val a: Int = 2
val b: Int = 42
val c: Int = a * b
assertEquals(c, 84)
assertEquals(js("Math.imul.called"), true)
return "OK"
}
@@ -0,0 +1,18 @@
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.imul = undefined;
// FILE: main.kt
fun box(): String {
val a: Int = 2
val b: Int = 42
val c: Int = 44
val d: Int = -2
assertEquals(a * b, 84)
assertEquals(a * c, 88)
assertEquals(a * d, -4)
assertEquals(js("Math.imul.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,18 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
ArrayBuffer.isView = function isView(a) {
isView.called = true;
return a != null && a.__proto__ != null && a.__proto__.__proto__ === Int8Array.prototype.__proto__;
}
// FILE: main.kt
fun box(): String {
val intArr = intArrayOf(5, 4, 3, 2, 1)
val result = IntArray(5).apply { intArr.copyInto(this) }
assertEquals(result.joinToString(","), intArr.joinToString(","))
assertEquals(js("ArrayBuffer.isView.called"), true)
return "OK"
}
@@ -0,0 +1,15 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
ArrayBuffer.isView = undefined;
// FILE: main.kt
fun box(): String {
val intArr = intArrayOf(5, 4, 3, 2, 1)
val result = IntArray(5).apply { intArr.copyInto(this) }
assertEquals(result.joinToString(","), intArr.joinToString(","))
assertEquals(js("ArrayBuffer.isView.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,19 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.log10 = function log10(x) {
log10.called = true;
return Math.log(x) * Math.LOG10E;
}
// FILE: main.kt
import kotlin.math.log10
fun box(): String {
assertEquals(log10(1.0), 0)
assertEquals(log10(10.0), 1)
assertEquals(log10(100.0), 2)
assertEquals(js("Math.log10.called"), true)
return "OK"
}
@@ -0,0 +1,16 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.log10 = undefined;
// FILE: main.kt
import kotlin.math.log10
fun box(): String {
assertEquals(log10(1.0), 0)
assertEquals(log10(10.0), 1)
assertEquals(log10(100.0), 2)
assertEquals(js("Math.log10.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,25 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.log1p = function log1p(x) {
log1p.called = true;
switch (x) {
case -2: return NaN
case -1: return -Infinity
case 0: return 0
case 1: return 0.6931471805599453
}
}
// FILE: main.kt
import kotlin.math.ln1p
fun box(): String {
assertEquals(ln1p(-2.0), Double.NaN)
assertEquals(ln1p(-1.0), Double.NEGATIVE_INFINITY)
assertEquals(ln1p(0.0), 0.0)
assertEquals(ln1p(1.0), 0.6931471805599453)
assertEquals(js("Math.log1p.called"), true)
return "OK"
}
@@ -0,0 +1,17 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.log1p = undefined;
// FILE: main.kt
import kotlin.math.ln1p
fun box(): String {
assertEquals(ln1p(-2.0), Double.NaN)
assertEquals(ln1p(-1.0), Double.NEGATIVE_INFINITY)
assertEquals(ln1p(0.0), 0.0)
assertEquals(ln1p(1.0), 0.6931471805599453)
assertEquals(js("Math.log1p.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,19 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.log2 = function log2(x) {
log2.called = true;
return Math.log(x) * Math.LOG2E;
}
// FILE: main.kt
import kotlin.math.log2
fun box(): String {
assertEquals(log2(1.0), 0)
assertEquals(log2(2.0), 1)
assertEquals(log2(4.0), 2)
assertEquals(js("Math.log2.called"), true)
return "OK"
}
@@ -0,0 +1,16 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.log2 = undefined;
// FILE: main.kt
import kotlin.math.log2
fun box(): String {
assertEquals(log2(1.0), 0)
assertEquals(log2(2.0), 1)
assertEquals(log2(4.0), 2)
assertEquals(js("Math.log2.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,19 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.sign = function sign(x) {
sign.called = true;
return x > 0 ? 1 : -1;
}
// FILE: main.kt
import kotlin.math.sign
fun box(): String {
val result = 44.0.sign
assertEquals(result, 1)
assertEquals(js("Math.sign.called"), true)
return "OK"
}
@@ -0,0 +1,16 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.sign = undefined;
// FILE: main.kt
import kotlin.math.sign
fun box(): String {
val result = 44.0.sign
assertEquals(result, 1)
assertEquals(js("Math.sign.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,26 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.sinh = function sinh(x) {
sinh.called = true;
switch (x) {
case -1: return -1.1752011936438014
case 0: return 0
case 1: return 1.1752011936438014
case 2: return 3.626860407847019
}
}
// FILE: main.kt
import kotlin.math.sinh
fun box(): String {
assertEquals(sinh(-1.0), -1.1752011936438014)
assertEquals(sinh(0.0), 0.0)
assertEquals(sinh(1.0), 1.1752011936438014)
assertEquals(sinh(2.0), 3.626860407847019)
assertEquals(js("Math.sinh.called"), true)
return "OK"
}
@@ -0,0 +1,18 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.sinh = undefined;
// FILE: main.kt
import kotlin.math.sinh
fun box(): String {
assertEquals(sinh(-1.0), -1.1752011936438014)
assertEquals(sinh(0.0), 0.0)
assertEquals(sinh(1.0), 1.1752011936438014)
assertEquals(sinh(2.0), 3.626860407847019)
assertEquals(js("Math.sinh.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,18 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Int32Array.prototype.sort = function sort(compareFunction) {
sort.called = true;
return Array.prototype.sort.call(this, compareFunction);
}
// FILE: main.kt
fun box(): String {
val intArr = intArrayOf(5, 4, 3, 2, 1)
.apply { sort { a, b -> a - b } }
assertEquals(intArr.joinToString(","), "1,2,3,4,5")
assertEquals(js("Int32Array.prototype.sort.called"), true)
return "OK"
}
@@ -0,0 +1,15 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Int32Array.prototype.sort = undefined;
// FILE: main.kt
fun box(): String {
val intArr = intArrayOf(5, 4, 3, 2, 1)
.apply { sort { a, b -> a - b } }
assertEquals(intArr.joinToString(","), "1,2,3,4,5")
assertEquals(js("Int32Array.prototype.sort.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,26 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.tanh = function tanh(x) {
tanh.called = true;
switch (x) {
case -1: return -0.7615941559557649
case 0: return 0
case 1: return 0.7615941559557649
case Infinity: return 1
}
}
// FILE: main.kt
import kotlin.math.tanh
fun box(): String {
assertEquals(tanh(-1.0), -0.7615941559557649)
assertEquals(tanh(0.0), 0.0)
assertEquals(tanh(1.0), 0.7615941559557649)
assertEquals(tanh(Double.POSITIVE_INFINITY), 1.0)
assertEquals(js("Math.tanh.called"), true)
return "OK"
}
@@ -0,0 +1,17 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.tanh = undefined;
// FILE: main.kt
import kotlin.math.tanh
fun box(): String {
assertEquals(tanh(-1.0), -0.7615941559557649)
assertEquals(tanh(0.0), 0.0)
assertEquals(tanh(1.0), 0.7615941559557649)
assertEquals(tanh(Double.POSITIVE_INFINITY), 1.0)
assertEquals(js("Math.tanh.called"), js("undefined"))
return "OK"
}
@@ -0,0 +1,25 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.trunc = function trunc(x) {
trunc.called = true;
if (isNaN(x)) {
return NaN;
}
if (x > 0) {
return Math.floor(x);
}
return Math.ceil(x);
}
// FILE: main.kt
import kotlin.math.truncate
fun box(): String {
val result = truncate(1.188)
assertEquals(result, 1)
assertEquals(js("Math.trunc.called"), true)
return "OK"
}
@@ -0,0 +1,16 @@
// WITH_STDLIB
// TARGET_BACKEND: JS_IR
// FILE: main.js
Math.trunc = undefined;
// FILE: main.kt
import kotlin.math.truncate
fun box(): String {
val result = truncate(1.188)
assertEquals(result, 1)
assertEquals(js("Math.trunc.called"), js("undefined"))
return "OK"
}
+1 -1
View File
@@ -5,7 +5,7 @@
package kotlin.js
@JsNativeImplementation("""
@JsPolyfill("""
(function() {
if (typeof globalThis === 'object') return;
Object.defineProperty(Object.prototype, '__magic__', {
+2 -2
View File
@@ -5,8 +5,8 @@
@file:JsQualifier("Math")
package kotlin.js
@JsNativeImplementation("""
if (typeof Math == "object" && Math !== null & typeof Math.imul === "undefined") {
@JsPolyfill("""
if (typeof Math.imul === "undefined") {
Math.imul = function imul(a, b) {
return ((a & 0xffff0000) * (b & 0xffff) + (a & 0xffff) * (b | 0)) | 0;
}
@@ -142,9 +142,7 @@ internal fun isArray(obj: Any): Boolean {
return isJsArray(obj) && !(obj.asDynamic().`$type$`)
}
internal fun isArrayish(o: dynamic) =
isJsArray(o) || js("ArrayBuffer").isView(o).unsafeCast<Boolean>()
internal fun isArrayish(o: dynamic) = isJsArray(o) || arrayBufferIsView(o)
internal fun isChar(@Suppress("UNUSED_PARAMETER") c: Any): Boolean {
error("isChar is not implemented")
@@ -1434,7 +1434,7 @@ public actual fun CharArray.copyOfRange(fromIndex: Int, toIndex: Int): CharArray
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun <T> Array<T>.fill(element: T, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1450,7 +1450,7 @@ public actual fun <T> Array<T>.fill(element: T, fromIndex: Int = 0, toIndex: Int
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun ByteArray.fill(element: Byte, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1466,7 +1466,7 @@ public actual fun ByteArray.fill(element: Byte, fromIndex: Int = 0, toIndex: Int
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun ShortArray.fill(element: Short, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1482,7 +1482,7 @@ public actual fun ShortArray.fill(element: Short, fromIndex: Int = 0, toIndex: I
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun IntArray.fill(element: Int, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1498,7 +1498,7 @@ public actual fun IntArray.fill(element: Int, fromIndex: Int = 0, toIndex: Int =
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun LongArray.fill(element: Long, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1514,7 +1514,7 @@ public actual fun LongArray.fill(element: Long, fromIndex: Int = 0, toIndex: Int
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun FloatArray.fill(element: Float, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1530,7 +1530,7 @@ public actual fun FloatArray.fill(element: Float, fromIndex: Int = 0, toIndex: I
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun DoubleArray.fill(element: Double, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1546,7 +1546,7 @@ public actual fun DoubleArray.fill(element: Double, fromIndex: Int = 0, toIndex:
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun BooleanArray.fill(element: Boolean, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1562,7 +1562,7 @@ public actual fun BooleanArray.fill(element: Boolean, fromIndex: Int = 0, toInde
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun CharArray.fill(element: Char, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1805,7 +1805,7 @@ public actual inline fun <T> Array<out T>.plusElement(element: T): Array<T> {
* @sample samples.collections.Arrays.Sorting.sortArray
*/
public actual fun IntArray.sort(): Unit {
this.asDynamic().sort()
nativeSort()
}
/**
@@ -1824,7 +1824,7 @@ public actual fun LongArray.sort(): Unit {
* @sample samples.collections.Arrays.Sorting.sortArray
*/
public actual fun ByteArray.sort(): Unit {
this.asDynamic().sort()
nativeSort()
}
/**
@@ -1833,7 +1833,7 @@ public actual fun ByteArray.sort(): Unit {
* @sample samples.collections.Arrays.Sorting.sortArray
*/
public actual fun ShortArray.sort(): Unit {
this.asDynamic().sort()
nativeSort()
}
/**
@@ -1842,7 +1842,7 @@ public actual fun ShortArray.sort(): Unit {
* @sample samples.collections.Arrays.Sorting.sortArray
*/
public actual fun DoubleArray.sort(): Unit {
this.asDynamic().sort()
nativeSort()
}
/**
@@ -1851,7 +1851,7 @@ public actual fun DoubleArray.sort(): Unit {
* @sample samples.collections.Arrays.Sorting.sortArray
*/
public actual fun FloatArray.sort(): Unit {
this.asDynamic().sort()
nativeSort()
}
/**
@@ -1860,7 +1860,7 @@ public actual fun FloatArray.sort(): Unit {
* @sample samples.collections.Arrays.Sorting.sortArray
*/
public actual fun CharArray.sort(): Unit {
this.asDynamic().sort(::primitiveCompareTo)
nativeSort(::primitiveCompareTo)
}
/**
@@ -2043,7 +2043,7 @@ public actual fun CharArray.sort(fromIndex: Int = 0, toIndex: Int = size): Unit
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun ByteArray.sort(noinline comparison: (a: Byte, b: Byte) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
@@ -2053,7 +2053,7 @@ public inline fun ByteArray.sort(noinline comparison: (a: Byte, b: Byte) -> Int)
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun ShortArray.sort(noinline comparison: (a: Short, b: Short) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
@@ -2063,7 +2063,7 @@ public inline fun ShortArray.sort(noinline comparison: (a: Short, b: Short) -> I
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun IntArray.sort(noinline comparison: (a: Int, b: Int) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
@@ -2073,7 +2073,7 @@ public inline fun IntArray.sort(noinline comparison: (a: Int, b: Int) -> Int): U
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun LongArray.sort(noinline comparison: (a: Long, b: Long) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
@@ -2083,7 +2083,7 @@ public inline fun LongArray.sort(noinline comparison: (a: Long, b: Long) -> Int)
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun FloatArray.sort(noinline comparison: (a: Float, b: Float) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
@@ -2093,7 +2093,7 @@ public inline fun FloatArray.sort(noinline comparison: (a: Float, b: Float) -> I
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun DoubleArray.sort(noinline comparison: (a: Double, b: Double) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
@@ -2103,7 +2103,7 @@ public inline fun DoubleArray.sort(noinline comparison: (a: Double, b: Double) -
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun CharArray.sort(noinline comparison: (a: Char, b: Char) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
+16 -16
View File
@@ -1464,7 +1464,7 @@ public actual fun CharArray.copyOfRange(fromIndex: Int, toIndex: Int): CharArray
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun <T> Array<T>.fill(element: T, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1480,7 +1480,7 @@ public actual fun <T> Array<T>.fill(element: T, fromIndex: Int = 0, toIndex: Int
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun ByteArray.fill(element: Byte, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1496,7 +1496,7 @@ public actual fun ByteArray.fill(element: Byte, fromIndex: Int = 0, toIndex: Int
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun ShortArray.fill(element: Short, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1512,7 +1512,7 @@ public actual fun ShortArray.fill(element: Short, fromIndex: Int = 0, toIndex: I
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun IntArray.fill(element: Int, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1528,7 +1528,7 @@ public actual fun IntArray.fill(element: Int, fromIndex: Int = 0, toIndex: Int =
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun LongArray.fill(element: Long, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1544,7 +1544,7 @@ public actual fun LongArray.fill(element: Long, fromIndex: Int = 0, toIndex: Int
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun FloatArray.fill(element: Float, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1560,7 +1560,7 @@ public actual fun FloatArray.fill(element: Float, fromIndex: Int = 0, toIndex: I
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun DoubleArray.fill(element: Double, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1576,7 +1576,7 @@ public actual fun DoubleArray.fill(element: Double, fromIndex: Int = 0, toIndex:
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun BooleanArray.fill(element: Boolean, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -1592,7 +1592,7 @@ public actual fun BooleanArray.fill(element: Boolean, fromIndex: Int = 0, toInde
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun CharArray.fill(element: Char, fromIndex: Int = 0, toIndex: Int = size): Unit {
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
}
/**
@@ -2062,7 +2062,7 @@ public actual fun CharArray.sort(fromIndex: Int = 0, toIndex: Int = size): Unit
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun ByteArray.sort(noinline comparison: (a: Byte, b: Byte) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
@@ -2072,7 +2072,7 @@ public inline fun ByteArray.sort(noinline comparison: (a: Byte, b: Byte) -> Int)
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun ShortArray.sort(noinline comparison: (a: Short, b: Short) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
@@ -2082,7 +2082,7 @@ public inline fun ShortArray.sort(noinline comparison: (a: Short, b: Short) -> I
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun IntArray.sort(noinline comparison: (a: Int, b: Int) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
@@ -2092,7 +2092,7 @@ public inline fun IntArray.sort(noinline comparison: (a: Int, b: Int) -> Int): U
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun LongArray.sort(noinline comparison: (a: Long, b: Long) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
@@ -2102,7 +2102,7 @@ public inline fun LongArray.sort(noinline comparison: (a: Long, b: Long) -> Int)
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun FloatArray.sort(noinline comparison: (a: Float, b: Float) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
@@ -2112,7 +2112,7 @@ public inline fun FloatArray.sort(noinline comparison: (a: Float, b: Float) -> I
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun DoubleArray.sort(noinline comparison: (a: Double, b: Double) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
@@ -2122,7 +2122,7 @@ public inline fun DoubleArray.sort(noinline comparison: (a: Double, b: Double) -
@DeprecatedSinceKotlin(warningSince = "1.6")
@kotlin.internal.InlineOnly
public inline fun CharArray.sort(noinline comparison: (a: Char, b: Char) -> Int): Unit {
asDynamic().sort(comparison)
nativeSort(comparison)
}
/**
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:JsQualifier("ArrayBuffer")
package kotlin.js
@JsName("isView")
@JsPolyfill("""
if (typeof ArrayBuffer.isView === "undefined") {
ArrayBuffer.isView = function(a) {
return a != null && a.__proto__ != null && a.__proto__.__proto__ === Int8Array.prototype.__proto__;
};
}
""")
internal external fun arrayBufferIsView(value: Any?): Boolean
@@ -7,6 +7,7 @@ package kotlin.collections
import kotlin.comparisons.naturalOrder
import kotlin.random.Random
import kotlin.js.arrayBufferIsView
/**
* Returns the array if it's not `null`, or an empty array otherwise.
@@ -193,7 +194,7 @@ internal fun <T> arrayCopy(source: Array<out T>, destination: Array<in T>, desti
val rangeSize = endIndex - startIndex
AbstractList.checkRangeIndexes(destinationOffset, destinationOffset + rangeSize, destination.size)
if (js("ArrayBuffer").isView(destination) && js("ArrayBuffer").isView(source)) {
if (arrayBufferIsView(destination) && arrayBufferIsView(source)) {
val subrange = source.asDynamic().subarray(startIndex, endIndex)
destination.asDynamic().set(subrange, destinationOffset)
} else {
@@ -7,4 +7,4 @@ package kotlin.js
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
internal annotation class JsNativeImplementation(val implementation: String)
internal annotation class JsPolyfill(val implementation: String)
@@ -0,0 +1,66 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.js
@PublishedApi
@Suppress("NOTHING_TO_INLINE")
@JsPolyfill("""
if (typeof Array.prototype.fill === "undefined") {
// Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill#Polyfill
Object.defineProperty(Array.prototype, 'fill', {
value: function (value) {
// Steps 1-2.
if (this == null) {
throw new TypeError('this is null or not defined');
}
var O = Object(this);
// Steps 3-5.
var len = O.length >>> 0;
// Steps 6-7.
var start = arguments[1];
var relativeStart = start >> 0;
// Step 8.
var k = relativeStart < 0 ?
Math.max(len + relativeStart, 0) :
Math.min(relativeStart, len);
// Steps 9-10.
var end = arguments[2];
var relativeEnd = end === undefined ?
len : end >> 0;
// Step 11.
var finalValue = relativeEnd < 0 ?
Math.max(len + relativeEnd, 0) :
Math.min(relativeEnd, len);
// Step 12.
while (k < finalValue) {
O[k] = value;
k++;
}
// Step 13.
return O;
}
});
}
[Int8Array, Int16Array, Uint16Array, Int32Array, Float32Array, Float64Array].forEach(function (TypedArray) {
if (typeof TypedArray.prototype.fill === "undefined") {
Object.defineProperty(TypedArray.prototype, 'fill', {
value: Array.prototype.fill
});
}
})
""")
internal inline fun Any.nativeFill(element: Any?, fromIndex: Int, toIndex: Int): Unit {
asDynamic().fill(element, fromIndex, toIndex)
}
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.js
@PublishedApi
@Suppress("NOTHING_TO_INLINE")
@JsPolyfill("""
[Int8Array, Int16Array, Uint16Array, Int32Array, Float32Array, Float64Array].forEach(function (TypedArray) {
if (typeof TypedArray.prototype.sort === "undefined") {
Object.defineProperty(TypedArray.prototype, 'sort', {
value: function(compareFunction) {
compareFunction = compareFunction || function (a, b) {
if (a < b) return -1;
if (a > b) return 1;
if (a === b) {
if (a !== 0) return 0;
var ia = 1 / a;
return ia === 1 / b ? 0 : (ia < 0 ? -1 : 1);
}
return a !== a ? (b !== b ? 0 : 1) : -1
}
return Array.prototype.sort.call(this, compareFunction || totalOrderComparator);
}
});
}
})
""")
internal inline fun Any.nativeSort(noinline comparison: (a: dynamic, b: dynamic) -> Int = js("undefined")): Unit {
asDynamic().sort(comparison)
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -33,24 +33,20 @@ internal external object JsMath {
fun round(value: Number): Double
fun floor(value: Number): Double
fun ceil(value: Number): Double
fun trunc(value: Number): Double
fun sign(value: Number): Double
fun sinh(value: Double): Double
fun cosh(value: Double): Double
fun tanh(value: Double): Double
fun asinh(value: Double): Double
fun acosh(value: Double): Double
fun atanh(value: Double): Double
fun hypot(x: Double, y: Double): Double
fun expm1(value: Double): Double
fun log10(value: Double): Double
fun log2(value: Double): Double
fun log1p(value: Double): Double
fun clz32(value: Int): Int
}
internal const val defineTaylorNBound = """
var epsilon = 2.220446049250313E-16;
var taylor_2_bound = Math.sqrt(epsilon);
var taylor_n_bound = Math.sqrt(taylor_2_bound);
"""
internal const val defineUpperTaylor2Bound = """
$defineTaylorNBound
var upper_taylor_2_bound = 1/taylor_2_bound;
"""
internal const val defineUpperTaylorNBound = """
$defineUpperTaylor2Bound
var upper_taylor_n_bound = 1/taylor_n_bound;
"""
@@ -0,0 +1,308 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:JsQualifier("Math")
package kotlin.js
// ES6 Math polyfills
// Inverse hyperbolic function implementations derived from boost special math functions,
// Copyright Eric Ford & Hubert Holin 2001.
@PublishedApi
@JsName("sign")
@JsPolyfill("""
if (typeof Math.sign === "undefined") {
Math.sign = function(x) {
x = +x; // convert to a number
if (x === 0 || isNaN(x)) {
return Number(x);
}
return x > 0 ? 1 : -1;
};
}
""")
internal external fun nativeSign(value: Number): Double
@PublishedApi
@JsName("trunc")
@JsPolyfill("""
if (typeof Math.trunc === "undefined") {
Math.trunc = function(x) {
if (isNaN(x)) {
return NaN;
}
if (x > 0) {
return Math.floor(x);
}
return Math.ceil(x);
};
}
""")
internal external fun nativeTrunc(value: Number): Double
@PublishedApi
@JsName("sinh")
@JsPolyfill("""
if (typeof Math.sinh === "undefined") {
$defineTaylorNBound
Math.sinh = function(x) {
if (Math.abs(x) < taylor_n_bound) {
var result = x;
if (Math.abs(x) > taylor_2_bound) {
result += (x * x * x) / 6;
}
return result;
} else {
var y = Math.exp(x);
var y1 = 1 / y;
if (!isFinite(y)) return Math.exp(x - Math.LN2);
if (!isFinite(y1)) return -Math.exp(-x - Math.LN2);
return (y - y1) / 2;
}
};
}
""")
internal external fun nativeSinh(value: Double): Double
@PublishedApi
@JsName("cosh")
@JsPolyfill("""
if (typeof Math.cosh === "undefined") {
Math.cosh = function(x) {
var y = Math.exp(x);
var y1 = 1 / y;
if (!isFinite(y) || !isFinite(y1)) return Math.exp(Math.abs(x) - Math.LN2);
return (y + y1) / 2;
};
}
""")
internal external fun nativeCosh(value: Double): Double
@PublishedApi
@JsName("tanh")
@JsPolyfill("""
if (typeof Math.tanh === "undefined") {
$defineTaylorNBound
Math.tanh = function(x){
if (Math.abs(x) < taylor_n_bound) {
var result = x;
if (Math.abs(x) > taylor_2_bound) {
result -= (x * x * x) / 3;
}
return result;
}
else {
var a = Math.exp(+x), b = Math.exp(-x);
return a === Infinity ? 1 : b === Infinity ? -1 : (a - b) / (a + b);
}
};
}
""")
internal external fun nativeTanh(value: Double): Double
@PublishedApi
@JsName("asinh")
@JsPolyfill("""
if (typeof Math.asinh === "undefined") {
$defineUpperTaylorNBound
var asinh = function(x) {
if (x >= +taylor_n_bound)
{
if (x > upper_taylor_n_bound)
{
if (x > upper_taylor_2_bound)
{
// approximation by laurent series in 1/x at 0+ order from -1 to 0
return Math.log(x) + Math.LN2;
}
else
{
// approximation by laurent series in 1/x at 0+ order from -1 to 1
return Math.log(x * 2 + (1 / (x * 2)));
}
}
else
{
return Math.log(x + Math.sqrt(x * x + 1));
}
}
else if (x <= -taylor_n_bound)
{
return -asinh(-x);
}
else
{
// approximation by taylor series in x at 0 up to order 2
var result = x;
if (Math.abs(x) >= taylor_2_bound)
{
var x3 = x * x * x;
// approximation by taylor series in x at 0 up to order 4
result -= x3 / 6;
}
return result;
}
};
Math.asinh = asinh;
}
""")
internal external fun nativeAsinh(value: Double): Double
@PublishedApi
@JsName("acosh")
@JsPolyfill("""
if (typeof Math.acosh === "undefined") {
$defineUpperTaylor2Bound
Math.acosh = function(x) {
if (x < 1)
{
return NaN;
}
else if (x - 1 >= taylor_n_bound)
{
if (x > upper_taylor_2_bound)
{
// approximation by laurent series in 1/x at 0+ order from -1 to 0
return Math.log(x) + Math.LN2;
}
else
{
return Math.log(x + Math.sqrt(x * x - 1));
}
}
else
{
var y = Math.sqrt(x - 1);
// approximation by taylor series in y at 0 up to order 2
var result = y;
if (y >= taylor_2_bound)
{
var y3 = y * y * y;
// approximation by taylor series in y at 0 up to order 4
result -= y3 / 12;
}
return Math.sqrt(2) * result;
}
};
}
""")
internal external fun nativeAcosh(value: Double): Double
@PublishedApi
@JsName("atanh")
@JsPolyfill("""
if (typeof Math.atanh === "undefined") {
$defineTaylorNBound
Math.atanh = function(x) {
if (Math.abs(x) < taylor_n_bound) {
var result = x;
if (Math.abs(x) > taylor_2_bound) {
result += (x * x * x) / 3;
}
return result;
}
return Math.log((1 + x) / (1 - x)) / 2;
};
}
""")
internal external fun nativeAtanh(value: Double): Double
@PublishedApi
@JsName("log1p")
@JsPolyfill("""
if (typeof Math.log1p === "undefined") {
$defineTaylorNBound
Math.log1p = function(x) {
if (Math.abs(x) < taylor_n_bound) {
var x2 = x * x;
var x3 = x2 * x;
var x4 = x3 * x;
// approximation by taylor series in x at 0 up to order 4
return (-x4 / 4 + x3 / 3 - x2 / 2 + x);
}
return Math.log(x + 1);
};
}
""")
internal external fun nativeLog1p(value: Double): Double
@PublishedApi
@JsName("expm1")
@JsPolyfill("""
if (typeof Math.expm1 === "undefined") {
$defineTaylorNBound
Math.expm1 = function(x) {
if (Math.abs(x) < taylor_n_bound) {
var x2 = x * x;
var x3 = x2 * x;
var x4 = x3 * x;
// approximation by taylor series in x at 0 up to order 4
return (x4 / 24 + x3 / 6 + x2 / 2 + x);
}
return Math.exp(x) - 1;
};
}
""")
internal external fun nativeExpm1(value: Double): Double
@PublishedApi
@JsName("hypot")
@JsPolyfill("""
if (typeof Math.hypot === "undefined") {
Math.hypot = function() {
var y = 0;
var length = arguments.length;
for (var i = 0; i < length; i++) {
if (arguments[i] === Infinity || arguments[i] === -Infinity) {
return Infinity;
}
y += arguments[i] * arguments[i];
}
return Math.sqrt(y);
};
}
""")
internal external fun nativeHypot(x: Double, y: Double): Double
@PublishedApi
@JsName("log10")
@JsPolyfill("""
if (typeof Math.log10 === "undefined") {
Math.log10 = function(x) {
return Math.log(x) * Math.LOG10E;
};
}
""")
internal external fun nativeLog10(value: Double): Double
@PublishedApi
@JsName("log2")
@JsPolyfill("""
if (typeof Math.log2 === "undefined") {
Math.log2 = function(x) {
return Math.log(x) * Math.LOG2E;
};
}
""")
internal external fun nativeLog2(value: Double): Double
@PublishedApi
@JsName("clz32")
@JsPolyfill("""
if (typeof Math.clz32 === "undefined") {
Math.clz32 = (function(log, LN2) {
return function(x) {
var asUint = x >>> 0;
if (asUint === 0) {
return 32;
}
return 31 - (log(asUint) / LN2 | 0) | 0; // the "| 0" acts like math.floor
};
})(Math.log, Math.LN2);
}
""")
internal external fun nativeClz32(value: Int): Int
+27 -27
View File
@@ -101,7 +101,7 @@ public actual inline fun atan2(y: Double, x: Double): Double = nativeMath.atan2(
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun sinh(x: Double): Double = nativeMath.sinh(x)
public actual inline fun sinh(x: Double): Double = nativeSinh(x)
/**
* Computes the hyperbolic cosine of the value [x].
@@ -112,7 +112,7 @@ public actual inline fun sinh(x: Double): Double = nativeMath.sinh(x)
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun cosh(x: Double): Double = nativeMath.cosh(x)
public actual inline fun cosh(x: Double): Double = nativeCosh(x)
/**
* Computes the hyperbolic tangent of the value [x].
@@ -124,7 +124,7 @@ public actual inline fun cosh(x: Double): Double = nativeMath.cosh(x)
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun tanh(x: Double): Double = nativeMath.tanh(x)
public actual inline fun tanh(x: Double): Double = nativeTanh(x)
/**
* Computes the inverse hyperbolic sine of the value [x].
@@ -138,7 +138,7 @@ public actual inline fun tanh(x: Double): Double = nativeMath.tanh(x)
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun asinh(x: Double): Double = nativeMath.asinh(x)
public actual inline fun asinh(x: Double): Double = nativeAsinh(x)
/**
* Computes the inverse hyperbolic cosine of the value [x].
@@ -152,7 +152,7 @@ public actual inline fun asinh(x: Double): Double = nativeMath.asinh(x)
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun acosh(x: Double): Double = nativeMath.acosh(x)
public actual inline fun acosh(x: Double): Double = nativeAcosh(x)
/**
* Computes the inverse hyperbolic tangent of the value [x].
@@ -167,7 +167,7 @@ public actual inline fun acosh(x: Double): Double = nativeMath.acosh(x)
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun atanh(x: Double): Double = nativeMath.atanh(x)
public actual inline fun atanh(x: Double): Double = nativeAtanh(x)
/**
* Computes `sqrt(x^2 + y^2)` without intermediate overflow or underflow.
@@ -178,7 +178,7 @@ public actual inline fun atanh(x: Double): Double = nativeMath.atanh(x)
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun hypot(x: Double, y: Double): Double = nativeMath.hypot(x, y)
public actual inline fun hypot(x: Double, y: Double): Double = nativeHypot(x, y)
/**
* Computes the positive square root of the value [x].
@@ -216,7 +216,7 @@ public actual inline fun exp(x: Double): Double = nativeMath.exp(x)
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun expm1(x: Double): Double = nativeMath.expm1(x)
public actual inline fun expm1(x: Double): Double = nativeExpm1(x)
/**
* Computes the logarithm of the value [x] to the given [base].
@@ -256,7 +256,7 @@ public actual inline fun ln(x: Double): Double = nativeMath.log(x)
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun log10(x: Double): Double = nativeMath.log10(x)
public actual inline fun log10(x: Double): Double = nativeLog10(x)
/**
* Computes the binary logarithm (base 2) of the value [x].
@@ -265,7 +265,7 @@ public actual inline fun log10(x: Double): Double = nativeMath.log10(x)
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun log2(x: Double): Double = nativeMath.log2(x)
public actual inline fun log2(x: Double): Double = nativeLog2(x)
/**
* Computes `ln(x + 1)`.
@@ -283,7 +283,7 @@ public actual inline fun log2(x: Double): Double = nativeMath.log2(x)
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun ln1p(x: Double): Double = nativeMath.log1p(x)
public actual inline fun ln1p(x: Double): Double = nativeLog1p(x)
/**
* Rounds the given value [x] to an integer towards positive infinity.
@@ -319,7 +319,7 @@ public actual inline fun floor(x: Double): Double = nativeMath.floor(x)
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun truncate(x: Double): Double = nativeMath.trunc(x)
public actual inline fun truncate(x: Double): Double = nativeTrunc(x)
/**
* Rounds the given value [x] towards the closest integer with ties rounded towards even integer.
@@ -359,7 +359,7 @@ public actual inline fun abs(x: Double): Double = nativeMath.abs(x)
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun sign(x: Double): Double = nativeMath.sign(x)
public actual inline fun sign(x: Double): Double = nativeSign(x)
/**
@@ -429,7 +429,7 @@ public actual inline val Double.absoluteValue: Double get() = nativeMath.abs(thi
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline val Double.sign: Double get() = nativeMath.sign(this)
public actual inline val Double.sign: Double get() = nativeSign(this)
/**
* Returns this value with the sign bit same as of the [sign] value.
@@ -626,7 +626,7 @@ public actual inline fun atan2(y: Float, x: Float): Float = nativeMath.atan2(y.t
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun sinh(x: Float): Float = nativeMath.sinh(x.toDouble()).toFloat()
public actual inline fun sinh(x: Float): Float = nativeSinh(x.toDouble()).toFloat()
/**
* Computes the hyperbolic cosine of the value [x].
@@ -637,7 +637,7 @@ public actual inline fun sinh(x: Float): Float = nativeMath.sinh(x.toDouble()).t
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun cosh(x: Float): Float = nativeMath.cosh(x.toDouble()).toFloat()
public actual inline fun cosh(x: Float): Float = nativeCosh(x.toDouble()).toFloat()
/**
* Computes the hyperbolic tangent of the value [x].
@@ -649,7 +649,7 @@ public actual inline fun cosh(x: Float): Float = nativeMath.cosh(x.toDouble()).t
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun tanh(x: Float): Float = nativeMath.tanh(x.toDouble()).toFloat()
public actual inline fun tanh(x: Float): Float = nativeTanh(x.toDouble()).toFloat()
/**
* Computes the inverse hyperbolic sine of the value [x].
@@ -663,7 +663,7 @@ public actual inline fun tanh(x: Float): Float = nativeMath.tanh(x.toDouble()).t
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun asinh(x: Float): Float = nativeMath.asinh(x.toDouble()).toFloat()
public actual inline fun asinh(x: Float): Float = nativeAsinh(x.toDouble()).toFloat()
/**
* Computes the inverse hyperbolic cosine of the value [x].
@@ -677,7 +677,7 @@ public actual inline fun asinh(x: Float): Float = nativeMath.asinh(x.toDouble())
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun acosh(x: Float): Float = nativeMath.acosh(x.toDouble()).toFloat()
public actual inline fun acosh(x: Float): Float = nativeAcosh(x.toDouble()).toFloat()
/**
* Computes the inverse hyperbolic tangent of the value [x].
@@ -692,7 +692,7 @@ public actual inline fun acosh(x: Float): Float = nativeMath.acosh(x.toDouble())
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun atanh(x: Float): Float = nativeMath.atanh(x.toDouble()).toFloat()
public actual inline fun atanh(x: Float): Float = nativeAtanh(x.toDouble()).toFloat()
/**
* Computes `sqrt(x^2 + y^2)` without intermediate overflow or underflow.
@@ -703,7 +703,7 @@ public actual inline fun atanh(x: Float): Float = nativeMath.atanh(x.toDouble())
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun hypot(x: Float, y: Float): Float = nativeMath.hypot(x.toDouble(), y.toDouble()).toFloat()
public actual inline fun hypot(x: Float, y: Float): Float = nativeHypot(x.toDouble(), y.toDouble()).toFloat()
/**
* Computes the positive square root of the value [x].
@@ -741,7 +741,7 @@ public actual inline fun exp(x: Float): Float = nativeMath.exp(x.toDouble()).toF
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun expm1(x: Float): Float = nativeMath.expm1(x.toDouble()).toFloat()
public actual inline fun expm1(x: Float): Float = nativeExpm1(x.toDouble()).toFloat()
/**
* Computes the logarithm of the value [x] to the given [base].
@@ -779,7 +779,7 @@ public actual inline fun ln(x: Float): Float = nativeMath.log(x.toDouble()).toFl
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun log10(x: Float): Float = nativeMath.log10(x.toDouble()).toFloat()
public actual inline fun log10(x: Float): Float = nativeLog10(x.toDouble()).toFloat()
/**
* Computes the binary logarithm (base 2) of the value [x].
@@ -788,7 +788,7 @@ public actual inline fun log10(x: Float): Float = nativeMath.log10(x.toDouble())
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun log2(x: Float): Float = nativeMath.log2(x.toDouble()).toFloat()
public actual inline fun log2(x: Float): Float = nativeLog2(x.toDouble()).toFloat()
/**
* Computes `ln(a + 1)`.
@@ -806,7 +806,7 @@ public actual inline fun log2(x: Float): Float = nativeMath.log2(x.toDouble()).t
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun ln1p(x: Float): Float = nativeMath.log1p(x.toDouble()).toFloat()
public actual inline fun ln1p(x: Float): Float = nativeLog1p(x.toDouble()).toFloat()
/**
* Rounds the given value [x] to an integer towards positive infinity.
@@ -878,7 +878,7 @@ public actual inline fun abs(x: Float): Float = nativeMath.abs(x.toDouble()).toF
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline fun sign(x: Float): Float = nativeMath.sign(x.toDouble()).toFloat()
public actual inline fun sign(x: Float): Float = nativeSign(x.toDouble()).toFloat()
@@ -950,7 +950,7 @@ public actual inline val Float.absoluteValue: Float get() = nativeMath.abs(this.
*/
@SinceKotlin("1.2")
@InlineOnly
public actual inline val Float.sign: Float get() = nativeMath.sign(this.toDouble()).toFloat()
public actual inline val Float.sign: Float get() = nativeSign(this.toDouble()).toFloat()
/**
* Returns this value with the sign bit same as of the [sign] value.
+1 -1
View File
@@ -60,7 +60,7 @@ public actual fun Int.countOneBits(): Int {
@SinceKotlin("1.4")
@WasExperimental(ExperimentalStdlibApi::class)
@kotlin.internal.InlineOnly
public actual inline fun Int.countLeadingZeroBits(): Int = JsMath.clz32(this)
public actual inline fun Int.countLeadingZeroBits(): Int = nativeClz32(this)
/**
* Counts the number of consecutive least significant bits that are zero in the binary representation of this [Int] number.
@@ -217,9 +217,34 @@ internal actual inline fun String.nativeIndexOf(str: String, fromIndex: Int): In
internal actual inline fun String.nativeLastIndexOf(str: String, fromIndex: Int): Int = asDynamic().lastIndexOf(str, fromIndex)
@kotlin.internal.InlineOnly
@kotlin.js.JsPolyfill("""
if (typeof String.prototype.startsWith === "undefined") {
Object.defineProperty(String.prototype, "startsWith", {
value: function (searchString, position) {
position = position || 0;
return this.lastIndexOf(searchString, position) === position;
}
});
}
""")
internal inline fun String.nativeStartsWith(s: String, position: Int): Boolean = asDynamic().startsWith(s, position)
@kotlin.internal.InlineOnly
@kotlin.js.JsPolyfill("""
if (typeof String.prototype.endsWith === "undefined") {
Object.defineProperty(String.prototype, "endsWith", {
value: function (searchString, position) {
var subjectString = this.toString();
if (position === undefined || position > subjectString.length) {
position = subjectString.length;
}
position -= searchString.length;
var lastIndex = subjectString.indexOf(searchString, position);
return lastIndex !== -1 && lastIndex === position;
}
});
}
""")
internal inline fun String.nativeEndsWith(s: String): Boolean = asDynamic().endsWith(s)
@kotlin.internal.InlineOnly
@@ -1223,9 +1223,9 @@ object ArrayOps : TemplateGroupBase() {
if (primitive == PrimitiveType.Char) {
// Requires comparator because default comparator of 'Array.prototype.sort' compares
// string representation of values
body { "this.asDynamic().sort(::primitiveCompareTo)" }
body { "nativeSort(::primitiveCompareTo)" }
} else {
body { "this.asDynamic().sort()" }
body { "nativeSort()" }
}
}
} else {
@@ -1292,7 +1292,7 @@ object ArrayOps : TemplateGroupBase() {
deprecate(Deprecation("Use other sorting functions from the Standard Library", warningSince = "1.6"))
inlineOnly()
signature("sort(noinline comparison: (a: T, b: T) -> Int)")
body { "asDynamic().sort(comparison)" }
body { "nativeSort(comparison)" }
}
specialFor(ArraysOfObjects) {
deprecate(
@@ -1641,7 +1641,7 @@ object ArrayOps : TemplateGroupBase() {
body {
"""
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
this.asDynamic().fill(element, fromIndex, toIndex);
nativeFill(element, fromIndex, toIndex);
"""
}
}
+4
View File
@@ -93,6 +93,10 @@ the Kotlin IntelliJ IDEA plugin:
- License: Boost Software License 1.0 ([license/third_party/boost_LICENSE.txt][boost])
- Origin: Derived from boost special math functions, Copyright Eric Ford & Hubert Holin 2001.
- Path: libraries/stdlib/js/src/kotlin/js/math.polyfills.kt
- License: Boost Software License 1.0 ([license/third_party/boost_LICENSE.txt][boost])
- Origin: Derived from boost special math functions, Copyright Eric Ford & Hubert Holin 2001.
- Path: libraries/stdlib/wasm/internal/kotlin/wasm/internal/Number2String.kt
- License: Apache 2 ([third_party/assemblyscript_license.txt][assemblyscript])
- Origin: Derived from assemblyscript standard library