JS IR: support kotlin.test
This commit is contained in:
+11
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.common.ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
|
|
||||||
|
val IrDeclaration.isExpect get() = descriptor.let { it is MemberDescriptor && it.isExpect }
|
||||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
|||||||
import org.jetbrains.kotlin.ir.SourceManager
|
import org.jetbrains.kotlin.ir.SourceManager
|
||||||
import org.jetbrains.kotlin.ir.SourceRangeInfo
|
import org.jetbrains.kotlin.ir.SourceRangeInfo
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.CallableReferenceKey
|
import org.jetbrains.kotlin.ir.backend.js.lower.CallableReferenceKey
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.ConstructorPair
|
import org.jetbrains.kotlin.ir.backend.js.lower.ConstructorPair
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
||||||
@@ -81,6 +82,17 @@ class JsIrBackendContext(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var testContainerField: IrSimpleFunction? = null
|
||||||
|
|
||||||
|
val hasTests get() = testContainerField != null
|
||||||
|
|
||||||
|
val testContainer
|
||||||
|
get() = testContainerField ?: JsIrBuilder.buildFunction("test fun", irBuiltIns.unitType, implicitDeclarationFile).apply {
|
||||||
|
body = JsIrBuilder.buildBlockBody(emptyList())
|
||||||
|
testContainerField = this
|
||||||
|
implicitDeclarationFile.declarations += this
|
||||||
|
}
|
||||||
|
|
||||||
override val sharedVariablesManager = JsSharedVariablesManager(irBuiltIns, implicitDeclarationFile)
|
override val sharedVariablesManager = JsSharedVariablesManager(irBuiltIns, implicitDeclarationFile)
|
||||||
override val declarationFactory = JsDeclarationFactory()
|
override val declarationFactory = JsDeclarationFactory()
|
||||||
|
|
||||||
@@ -224,6 +236,9 @@ class JsIrBackendContext(
|
|||||||
|
|
||||||
val throwISEymbol = symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("THROW_ISE"))).single())
|
val throwISEymbol = symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("THROW_ISE"))).single())
|
||||||
|
|
||||||
|
val suiteFun = getFunctions(FqName("kotlin.test.suite")).singleOrNull()?.let { symbolTable.referenceSimpleFunction(it) }
|
||||||
|
val testFun = getFunctions(FqName("kotlin.test.test")).singleOrNull()?.let { symbolTable.referenceSimpleFunction(it) }
|
||||||
|
|
||||||
val coroutineImplLabelPropertyGetter by lazy { ir.symbols.coroutineImpl.getPropertyGetter("state")!!.owner }
|
val coroutineImplLabelPropertyGetter by lazy { ir.symbols.coroutineImpl.getPropertyGetter("state")!!.owner }
|
||||||
val coroutineImplLabelPropertySetter by lazy { ir.symbols.coroutineImpl.getPropertySetter("state")!!.owner }
|
val coroutineImplLabelPropertySetter by lazy { ir.symbols.coroutineImpl.getPropertySetter("state")!!.owner }
|
||||||
val coroutineImplResultSymbolGetter by lazy { ir.symbols.coroutineImpl.getPropertyGetter("result")!!.owner }
|
val coroutineImplResultSymbolGetter by lazy { ir.symbols.coroutineImpl.getPropertyGetter("result")!!.owner }
|
||||||
|
|||||||
@@ -333,10 +333,17 @@ private val callsLoweringPhase = makeJsModulePhase(
|
|||||||
description = "Handle intrinsics"
|
description = "Handle intrinsics"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val testGenerationPhase = makeJsModulePhase(
|
||||||
|
::TestGenerator,
|
||||||
|
name = "TestGenerationLowering",
|
||||||
|
description = "Generate invocations to kotlin.test suite and test functions"
|
||||||
|
)
|
||||||
|
|
||||||
val jsPhases = namedIrModulePhase(
|
val jsPhases = namedIrModulePhase(
|
||||||
name = "IrModuleLowering",
|
name = "IrModuleLowering",
|
||||||
description = "IR module lowering",
|
description = "IR module lowering",
|
||||||
lower = expectDeclarationsRemovingPhase then
|
lower = testGenerationPhase then
|
||||||
|
expectDeclarationsRemovingPhase then
|
||||||
functionInliningPhase then
|
functionInliningPhase then
|
||||||
lateinitLoweringPhase then
|
lateinitLoweringPhase then
|
||||||
tailrecLoweringPhase then
|
tailrecLoweringPhase then
|
||||||
|
|||||||
@@ -5,27 +5,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.ir
|
package org.jetbrains.kotlin.ir.backend.js.ir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
import org.jetbrains.kotlin.backend.common.descriptors.*
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedTypeParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -149,6 +140,9 @@ object JsIrBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun buildAnonymousInitializer() =
|
||||||
|
IrAnonymousInitializerImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SYNTHESIZED_DECLARATION, IrAnonymousInitializerSymbolImpl(WrappedClassDescriptor()))
|
||||||
|
|
||||||
fun buildGetObjectValue(type: IrType, classSymbol: IrClassSymbol) =
|
fun buildGetObjectValue(type: IrType, classSymbol: IrClassSymbol) =
|
||||||
IrGetObjectValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, classSymbol)
|
IrGetObjectValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, classSymbol)
|
||||||
|
|
||||||
@@ -257,6 +251,7 @@ object JsIrBuilder {
|
|||||||
fun buildBoolean(type: IrType, v: Boolean) = IrConstImpl.boolean(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, v)
|
fun buildBoolean(type: IrType, v: Boolean) = IrConstImpl.boolean(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, v)
|
||||||
fun buildInt(type: IrType, v: Int) = IrConstImpl.int(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, v)
|
fun buildInt(type: IrType, v: Int) = IrConstImpl.int(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, v)
|
||||||
fun buildString(type: IrType, s: String) = IrConstImpl.string(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, s)
|
fun buildString(type: IrType, s: String) = IrConstImpl.string(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, s)
|
||||||
|
fun buildTry(type: IrType) = IrTryImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type)
|
||||||
fun buildCatch(ex: IrVariable, block: IrBlockImpl) = IrCatchImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, ex, block)
|
fun buildCatch(ex: IrVariable, block: IrBlockImpl) = IrCatchImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, ex, block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.ir.isExpect
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
|
import org.jetbrains.kotlin.ir.util.defaultType
|
||||||
|
import org.jetbrains.kotlin.ir.util.fqNameSafe
|
||||||
|
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
|
class TestGenerator(val context: JsIrBackendContext) : FileLoweringPass {
|
||||||
|
|
||||||
|
override fun lower(irFile: IrFile) {
|
||||||
|
irFile.declarations.forEach {
|
||||||
|
if (it is IrClass) {
|
||||||
|
generateTestCalls(it) { suiteForPackage(irFile.fqName).body }
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO top-level functions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val packageSuites = mutableMapOf<FqName, FunctionWithBody>()
|
||||||
|
|
||||||
|
private fun suiteForPackage(fqName: FqName) = packageSuites.getOrPut(fqName) {
|
||||||
|
context.suiteFun!!.createInvocation(fqName.asString(), context.testContainer.body as IrBlockBody)
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class FunctionWithBody(val function: IrSimpleFunction, val body: IrBlockBody)
|
||||||
|
|
||||||
|
private fun IrSimpleFunctionSymbol.createInvocation(
|
||||||
|
name: String,
|
||||||
|
parentBody: IrBlockBody,
|
||||||
|
ignored: Boolean = false
|
||||||
|
): FunctionWithBody {
|
||||||
|
val body = JsIrBuilder.buildBlockBody(emptyList())
|
||||||
|
|
||||||
|
val function = JsIrBuilder.buildFunction(
|
||||||
|
"$name test fun",
|
||||||
|
context.irBuiltIns.unitType,
|
||||||
|
context.implicitDeclarationFile
|
||||||
|
).also {
|
||||||
|
it.body = body
|
||||||
|
context.implicitDeclarationFile.declarations += it
|
||||||
|
}
|
||||||
|
|
||||||
|
parentBody.statements += JsIrBuilder.buildCall(this).apply {
|
||||||
|
putValueArgument(0, JsIrBuilder.buildString(context.irBuiltIns.stringType, name))
|
||||||
|
putValueArgument(1, JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, ignored))
|
||||||
|
|
||||||
|
val refType = IrSimpleTypeImpl(context.functionN(0), false, emptyList(), emptyList())
|
||||||
|
putValueArgument(2, JsIrBuilder.buildFunctionReference(refType, function.symbol))
|
||||||
|
}
|
||||||
|
|
||||||
|
return FunctionWithBody(function, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateTestCalls(irClass: IrClass, parentBody: () -> IrBlockBody) {
|
||||||
|
if (irClass.modality == Modality.ABSTRACT || irClass.isEffectivelyExternal() || irClass.isExpect) return
|
||||||
|
|
||||||
|
val suiteFunBody by lazy { context.suiteFun!!.createInvocation(irClass.name.asString(), parentBody(), irClass.isIgnored) }
|
||||||
|
|
||||||
|
val beforeFunctions = irClass.declarations.filterIsInstance<IrSimpleFunction>().filter { it.isBefore }
|
||||||
|
val afterFunctions = irClass.declarations.filterIsInstance<IrSimpleFunction>().filter { it.isAfter }
|
||||||
|
|
||||||
|
irClass.declarations.forEach {
|
||||||
|
when {
|
||||||
|
it is IrClass ->
|
||||||
|
generateTestCalls(it) { suiteFunBody.body }
|
||||||
|
|
||||||
|
it is IrSimpleFunction && it.isTest ->
|
||||||
|
generateCodeForTestMethod(it, beforeFunctions, afterFunctions, irClass, suiteFunBody.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateCodeForTestMethod(
|
||||||
|
testFun: IrSimpleFunction,
|
||||||
|
beforeFuns: List<IrSimpleFunction>,
|
||||||
|
afterFuns: List<IrSimpleFunction>,
|
||||||
|
irClass: IrClass,
|
||||||
|
parentBody: IrBlockBody
|
||||||
|
) {
|
||||||
|
val (fn, body) = context.testFun!!.createInvocation(testFun.name.asString(), parentBody, testFun.isIgnored)
|
||||||
|
|
||||||
|
val classVal = JsIrBuilder.buildVar(irClass.defaultType, fn, initializer = irClass.instance())
|
||||||
|
|
||||||
|
body.statements += classVal
|
||||||
|
|
||||||
|
body.statements += beforeFuns.map {
|
||||||
|
JsIrBuilder.buildCall(it.symbol).apply {
|
||||||
|
dispatchReceiver = JsIrBuilder.buildGetValue(classVal.symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val returnStatement = JsIrBuilder.buildReturn(
|
||||||
|
fn.symbol,
|
||||||
|
JsIrBuilder.buildCall(testFun.symbol).apply {
|
||||||
|
dispatchReceiver = JsIrBuilder.buildGetValue(classVal.symbol)
|
||||||
|
},
|
||||||
|
context.irBuiltIns.unitType
|
||||||
|
)
|
||||||
|
|
||||||
|
if (afterFuns.isEmpty()) {
|
||||||
|
body.statements += returnStatement
|
||||||
|
} else {
|
||||||
|
body.statements += JsIrBuilder.buildTry(context.irBuiltIns.unitType).apply {
|
||||||
|
tryResult = returnStatement
|
||||||
|
finallyExpression = JsIrBuilder.buildComposite(context.irBuiltIns.unitType).apply {
|
||||||
|
statements += afterFuns.map {
|
||||||
|
JsIrBuilder.buildCall(it.symbol).apply {
|
||||||
|
dispatchReceiver = JsIrBuilder.buildGetValue(classVal.symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrClass.instance(): IrExpression {
|
||||||
|
return if (kind == ClassKind.OBJECT) {
|
||||||
|
JsIrBuilder.buildGetObjectValue(defaultType, symbol)
|
||||||
|
} else {
|
||||||
|
declarations.asSequence().filterIsInstance<IrConstructor>().single { it.isPrimary }.let { constructor ->
|
||||||
|
JsIrBuilder.buildCall(constructor.symbol).also {
|
||||||
|
if (isInner) {
|
||||||
|
it.dispatchReceiver = (parent as IrClass).instance()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val IrAnnotationContainer.isTest
|
||||||
|
get() = hasAnnotation("kotlin.test.Test")
|
||||||
|
|
||||||
|
private val IrAnnotationContainer.isIgnored
|
||||||
|
get() = hasAnnotation("kotlin.test.Ignore")
|
||||||
|
|
||||||
|
private val IrAnnotationContainer.isBefore
|
||||||
|
get() = hasAnnotation("kotlin.test.BeforeTest")
|
||||||
|
|
||||||
|
private val IrAnnotationContainer.isAfter
|
||||||
|
get() = hasAnnotation("kotlin.test.AfterTest")
|
||||||
|
|
||||||
|
private fun IrAnnotationContainer.hasAnnotation(fqName: String) =
|
||||||
|
annotations.any { it.symbol.owner.parent.fqNameSafe == FqName(fqName) }
|
||||||
|
}
|
||||||
+1
-4
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsDeclarationScope
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsEmpty
|
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsStatement
|
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsVars
|
|
||||||
|
|
||||||
class IrDeclarationToJsTransformer : BaseIrElementToJsNodeTransformer<JsStatement, JsGenerationContext> {
|
class IrDeclarationToJsTransformer : BaseIrElementToJsNodeTransformer<JsStatement, JsGenerationContext> {
|
||||||
|
|
||||||
|
|||||||
+4
@@ -49,6 +49,10 @@ class IrModuleToJsTransformer(private val backendContext: JsIrBackendContext) :
|
|||||||
statements += postDeclarationBlock
|
statements += postDeclarationBlock
|
||||||
statements += context.staticContext.initializerBlock
|
statements += context.staticContext.initializerBlock
|
||||||
|
|
||||||
|
if (backendContext.hasTests) {
|
||||||
|
statements += JsInvocation(context.getNameForSymbol(backendContext.testContainer.symbol).makeRef()).makeStmt()
|
||||||
|
}
|
||||||
|
|
||||||
return statements
|
return statements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,25 +21,214 @@ sourceSets {
|
|||||||
"test" { projectDefault() }
|
"test" { projectDefault() }
|
||||||
}
|
}
|
||||||
|
|
||||||
val generateIrRuntimeKlib by task<NoDebugJavaExec> {
|
val unimplementedNativeBuiltIns =
|
||||||
val inDirs = arrayOf(fileFrom(rootDir, "core", "builtins", "src"),
|
(file("$rootDir/core/builtins/native/kotlin/").list().toSet() - file("$rootDir/libraries/stdlib/js/irRuntime/builtins/").list())
|
||||||
fileFrom(rootDir, "core", "builtins", "native"),
|
.map { "core/builtins/native/kotlin/$it" }
|
||||||
fileFrom(rootDir, "libraries", "stdlib", "common", "src"),
|
|
||||||
fileFrom(rootDir, "libraries", "stdlib", "src", "kotlin"),
|
|
||||||
fileFrom(rootDir, "libraries", "stdlib", "js", "src", "generated"),
|
|
||||||
fileFrom(rootDir, "libraries", "stdlib", "js", "irRuntime"),
|
|
||||||
fileFrom(rootDir, "libraries", "stdlib", "unsigned"),
|
|
||||||
fileFrom(rootDir, "js", "js.translator", "testData", "_commonFiles"))
|
|
||||||
inDirs.forEach { inputs.dir(it) }
|
|
||||||
|
|
||||||
val outDir = "$rootDir/js/js.translator/testData/out/klibs/"
|
// Required to compile native builtins with the rest of runtime
|
||||||
outputs.dir(outDir)
|
val builtInsHeader = """@file:Suppress(
|
||||||
|
"NON_ABSTRACT_FUNCTION_WITH_NO_BODY",
|
||||||
|
"MUST_BE_INITIALIZED_OR_BE_ABSTRACT",
|
||||||
|
"EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE",
|
||||||
|
"PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED",
|
||||||
|
"WRONG_MODIFIER_TARGET"
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
val fullRuntimeSources by task<Copy> {
|
||||||
|
val sources = listOf(
|
||||||
|
"core/builtins/src/kotlin/",
|
||||||
|
"libraries/stdlib/common/src/",
|
||||||
|
"libraries/stdlib/src/kotlin/",
|
||||||
|
"libraries/stdlib/js/src/kotlin/",
|
||||||
|
"libraries/stdlib/js/src/generated/",
|
||||||
|
"libraries/stdlib/js/irRuntime/",
|
||||||
|
"libraries/stdlib/js/runtime/",
|
||||||
|
"libraries/stdlib/unsigned/",
|
||||||
|
|
||||||
|
// TODO get rid - move to test module
|
||||||
|
"js/js.translator/testData/_commonFiles/"
|
||||||
|
) + unimplementedNativeBuiltIns
|
||||||
|
|
||||||
|
val excluded = listOf(
|
||||||
|
"libraries/stdlib/common/src/kotlin/JvmAnnotationsH.kt",
|
||||||
|
"libraries/stdlib/src/kotlin/annotations/Multiplatform.kt",
|
||||||
|
"libraries/stdlib/common/src/kotlin/NativeAnnotationsH.kt",
|
||||||
|
|
||||||
|
// TODO: Support Int.pow
|
||||||
|
"libraries/stdlib/js/src/kotlin/random/PlatformRandom.kt",
|
||||||
|
|
||||||
|
// Fails with: EXPERIMENTAL_IS_NOT_ENABLED
|
||||||
|
"libraries/stdlib/common/src/kotlin/annotations/Annotations.kt",
|
||||||
|
|
||||||
|
// Conflicts with libraries/stdlib/js/src/kotlin/annotations.kt
|
||||||
|
"libraries/stdlib/js/runtime/hacks.kt",
|
||||||
|
|
||||||
|
// TODO: Reuse in IR BE
|
||||||
|
"libraries/stdlib/js/runtime/Enum.kt",
|
||||||
|
|
||||||
|
// JS-specific optimized version of emptyArray() already defined
|
||||||
|
"core/builtins/src/kotlin/ArrayIntrinsics.kt",
|
||||||
|
|
||||||
|
// Unnecessary for now
|
||||||
|
"libraries/stdlib/js/src/kotlin/dom/**",
|
||||||
|
"libraries/stdlib/js/src/kotlin/browser/**",
|
||||||
|
|
||||||
|
// TODO: fix compilation issues in arrayPlusCollection
|
||||||
|
// Replaced with irRuntime/kotlinHacks.kt
|
||||||
|
"libraries/stdlib/js/src/kotlin/kotlin.kt",
|
||||||
|
|
||||||
|
"libraries/stdlib/js/src/kotlin/currentBeMisc.kt",
|
||||||
|
|
||||||
|
// IR BE has its own generated sources
|
||||||
|
"libraries/stdlib/js/src/generated/**",
|
||||||
|
"libraries/stdlib/js/src/kotlin/collectionsExternal.kt",
|
||||||
|
|
||||||
|
// Full version is defined in stdlib
|
||||||
|
// This file is useful for smaller subset of runtime sources
|
||||||
|
"libraries/stdlib/js/irRuntime/smallRuntimeMissingDeclarations.kt",
|
||||||
|
|
||||||
|
// Mostly array-specific stuff
|
||||||
|
"libraries/stdlib/js/src/kotlin/builtins.kt",
|
||||||
|
|
||||||
|
// coroutines
|
||||||
|
// TODO: merge coroutines_13 with JS BE coroutines
|
||||||
|
"libraries/stdlib/js/src/kotlin/coroutines/intrinsics/IntrinsicsJs.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/coroutines/CoroutineImpl.kt",
|
||||||
|
|
||||||
|
// Inlining of js fun doesn't update the variables inside
|
||||||
|
"libraries/stdlib/js/src/kotlin/jsTypeOf.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/collections/utils.kt",
|
||||||
|
|
||||||
|
// TODO: Remove stub
|
||||||
|
"libraries/stdlib/js/src/kotlin/builtins.kt",
|
||||||
|
|
||||||
|
// Expect declarations get thrown away and libraries/kotlin.test/common/src/main/kotlin/kotlin/test/Assertions.kt doesn't compile
|
||||||
|
"libraries/stdlib/common/src/kotlin/NativeAnnotationsH.kt"
|
||||||
|
)
|
||||||
|
|
||||||
|
sources.forEach { path ->
|
||||||
|
from("$rootDir/$path") {
|
||||||
|
into(path.dropLastWhile { it != '/' })
|
||||||
|
excluded.filter { it.startsWith(path) }.forEach {
|
||||||
|
exclude(it.substring(path.length))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
into("$buildDir/fullRuntime/src")
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
unimplementedNativeBuiltIns.forEach { path ->
|
||||||
|
val file = File("$buildDir/fullRuntime/src/$path")
|
||||||
|
val sourceCode = builtInsHeader + file.readText()
|
||||||
|
file.writeText(sourceCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val reducedRuntimeSources by task<Copy> {
|
||||||
|
dependsOn(fullRuntimeSources)
|
||||||
|
|
||||||
|
from(fullRuntimeSources.outputs.files.singleFile) {
|
||||||
|
exclude(
|
||||||
|
listOf(
|
||||||
|
"libraries/stdlib/unsigned/**",
|
||||||
|
"libraries/stdlib/common/src/generated/_Arrays.kt",
|
||||||
|
"libraries/stdlib/common/src/generated/_Collections.kt",
|
||||||
|
"libraries/stdlib/common/src/generated/_Comparisons.kt",
|
||||||
|
"libraries/stdlib/common/src/generated/_Maps.kt",
|
||||||
|
"libraries/stdlib/common/src/generated/_Sequences.kt",
|
||||||
|
"libraries/stdlib/common/src/generated/_Sets.kt",
|
||||||
|
"libraries/stdlib/common/src/generated/_Strings.kt",
|
||||||
|
"libraries/stdlib/common/src/generated/_UArrays.kt",
|
||||||
|
"libraries/stdlib/common/src/generated/_URanges.kt",
|
||||||
|
"libraries/stdlib/common/src/generated/_UCollections.kt",
|
||||||
|
"libraries/stdlib/common/src/generated/_UComparisons.kt",
|
||||||
|
"libraries/stdlib/common/src/generated/_USequences.kt",
|
||||||
|
"libraries/stdlib/common/src/kotlin/SequencesH.kt",
|
||||||
|
"libraries/stdlib/common/src/kotlin/TextH.kt",
|
||||||
|
"libraries/stdlib/common/src/kotlin/UMath.kt",
|
||||||
|
"libraries/stdlib/common/src/kotlin/collections/**",
|
||||||
|
"libraries/stdlib/common/src/kotlin/ioH.kt",
|
||||||
|
"libraries/stdlib/js/irRuntime/collectionsHacks.kt",
|
||||||
|
"libraries/stdlib/js/irRuntime/generated/**",
|
||||||
|
"libraries/stdlib/js/src/kotlin/char.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/collections.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/collections/**",
|
||||||
|
"libraries/stdlib/js/src/kotlin/console.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/coreDeprecated.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/date.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/debug.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/grouping.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/json.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/numberConversions.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/promise.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/regex.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/regexp.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/sequence.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/string.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/stringsCode.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/text.kt",
|
||||||
|
"libraries/stdlib/src/kotlin/collections/**",
|
||||||
|
"libraries/stdlib/src/kotlin/experimental/bitwiseOperations.kt",
|
||||||
|
"libraries/stdlib/src/kotlin/properties/Delegates.kt",
|
||||||
|
"libraries/stdlib/src/kotlin/random/URandom.kt",
|
||||||
|
"libraries/stdlib/src/kotlin/text/**",
|
||||||
|
"libraries/stdlib/src/kotlin/util/KotlinVersion.kt",
|
||||||
|
"libraries/stdlib/src/kotlin/util/Tuples.kt"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
from("$rootDir/libraries/stdlib/js/irRuntime/smallRuntimeMissingDeclarations.kt") {
|
||||||
|
into("libraries/stdlib/js/irRuntime/")
|
||||||
|
}
|
||||||
|
|
||||||
|
into("$buildDir/reducedRuntime/src")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun JavaExec.buildKLib(sources: List<String>, dependencies: List<String>, outPath: String) {
|
||||||
|
inputs.files(sources)
|
||||||
|
outputs.dir(file(outPath).parent)
|
||||||
|
|
||||||
classpath = sourceSets.test.get().runtimeClasspath
|
classpath = sourceSets.test.get().runtimeClasspath
|
||||||
main = "org.jetbrains.kotlin.ir.backend.js.GenerateIrRuntimeKt"
|
main = "org.jetbrains.kotlin.ir.backend.js.GenerateIrRuntimeKt"
|
||||||
workingDir = rootDir
|
workingDir = rootDir
|
||||||
|
args = sources.toList() + listOf("-o", outPath) + dependencies.flatMap { listOf("-d", it) }
|
||||||
|
|
||||||
passClasspathInJar()
|
passClasspathInJar()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val generateFullRuntimeKLib by task<NoDebugJavaExec> {
|
||||||
|
dependsOn(fullRuntimeSources)
|
||||||
|
|
||||||
|
buildKLib(sources = listOf(fullRuntimeSources.outputs.files.singleFile.path),
|
||||||
|
dependencies = emptyList(),
|
||||||
|
outPath = "$buildDir/fullRuntime/klib/JS_IR_RUNTIME.klm")
|
||||||
|
}
|
||||||
|
|
||||||
|
val generateReducedRuntimeKLib by task<NoDebugJavaExec> {
|
||||||
|
dependsOn(reducedRuntimeSources)
|
||||||
|
|
||||||
|
buildKLib(sources = listOf(reducedRuntimeSources.outputs.files.singleFile.path),
|
||||||
|
dependencies = emptyList(),
|
||||||
|
outPath = "$buildDir/reducedRuntime/klib/JS_IR_RUNTIME.klm")
|
||||||
|
}
|
||||||
|
|
||||||
|
val generateKotlinTestKLib by task<NoDebugJavaExec> {
|
||||||
|
dependsOn(generateFullRuntimeKLib)
|
||||||
|
|
||||||
|
buildKLib(
|
||||||
|
sources = listOf(
|
||||||
|
"$rootDir/libraries/kotlin.test/annotations-common/src/main",
|
||||||
|
"$rootDir/libraries/kotlin.test/common/src/main",
|
||||||
|
"$rootDir/libraries/kotlin.test/js/src/main"
|
||||||
|
),
|
||||||
|
dependencies = listOf("${generateFullRuntimeKLib.outputs.files.singleFile.path}/JS_IR_RUNTIME.klm"),
|
||||||
|
outPath = "$buildDir/kotlin.test/klib/kotlin.test.klm"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
testsJar {}
|
testsJar {}
|
||||||
@@ -5,21 +5,21 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js
|
package org.jetbrains.kotlin.ir.backend.js
|
||||||
|
|
||||||
|
import com.intellij.openapi.Disposable
|
||||||
import com.intellij.openapi.vfs.StandardFileSystems
|
import com.intellij.openapi.vfs.StandardFileSystems
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager
|
import com.intellij.openapi.vfs.VirtualFileManager
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.config.*
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
import com.intellij.openapi.Disposable
|
fun buildConfiguration(environment: KotlinCoreEnvironment, moduleName: String): CompilerConfiguration {
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|
||||||
|
|
||||||
fun buildConfiguration(environment: KotlinCoreEnvironment): CompilerConfiguration {
|
|
||||||
val runtimeConfiguration = environment.configuration.copy()
|
val runtimeConfiguration = environment.configuration.copy()
|
||||||
runtimeConfiguration.put(CommonConfigurationKeys.MODULE_NAME, "JS_IR_RUNTIME")
|
runtimeConfiguration.put(CommonConfigurationKeys.MODULE_NAME, moduleName)
|
||||||
runtimeConfiguration.put(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN)
|
runtimeConfiguration.put(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN)
|
||||||
|
|
||||||
runtimeConfiguration.languageVersionSettings = LanguageVersionSettingsImpl(
|
runtimeConfiguration.languageVersionSettings = LanguageVersionSettingsImpl(
|
||||||
@@ -37,34 +37,69 @@ fun buildConfiguration(environment: KotlinCoreEnvironment): CompilerConfiguratio
|
|||||||
return runtimeConfiguration
|
return runtimeConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
private val fullRuntimeKlibPath = "js/js.translator/testData/out/klibs/runtimeFull/"
|
val environment = KotlinCoreEnvironment.createForTests(Disposable { }, CompilerConfiguration(), EnvironmentConfigFiles.JS_CONFIG_FILES)
|
||||||
private val defaultRuntimeKlibPath = "js/js.translator/testData/out/klibs/runtimeDefault/"
|
|
||||||
|
|
||||||
fun main() {
|
fun createPsiFile(fileName: String): KtFile {
|
||||||
|
val psiManager = PsiManager.getInstance(environment.project)
|
||||||
|
val fileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL)
|
||||||
|
|
||||||
val environment = KotlinCoreEnvironment.createForTests(Disposable { }, CompilerConfiguration(), EnvironmentConfigFiles.JS_CONFIG_FILES)
|
val file = fileSystem.findFileByPath(fileName) ?: error("File not found: $fileName")
|
||||||
|
|
||||||
fun createPsiFile(fileName: String): KtFile {
|
return psiManager.findFile(file) as KtFile
|
||||||
val psiManager = PsiManager.getInstance(environment.project)
|
}
|
||||||
val fileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL)
|
|
||||||
|
|
||||||
val file = fileSystem.findFileByPath(fileName) ?: error("File not found: $fileName")
|
fun buildKLib(moduleName: String, sources: List<String>, outputPath: String, dependencies: List<KlibModuleRef>): KlibModuleRef {
|
||||||
|
return generateKLib(
|
||||||
return psiManager.findFile(file) as KtFile
|
project = environment.project,
|
||||||
}
|
files = sources.map(::createPsiFile),
|
||||||
|
configuration = buildConfiguration(environment, moduleName),
|
||||||
|
immediateDependencies = dependencies,
|
||||||
fun buildKlib(sources: List<String>, outputPath: String) {
|
allDependencies = dependencies,
|
||||||
generateKLib(
|
outputKlibPath = outputPath
|
||||||
project = environment.project,
|
)
|
||||||
files = sources.map(::createPsiFile),
|
}
|
||||||
configuration = buildConfiguration(environment),
|
|
||||||
immediateDependencies = emptyList(),
|
private fun listOfKtFilesFrom(paths: List<String>): List<String> {
|
||||||
allDependencies = emptyList(),
|
val currentDir = File("")
|
||||||
outputKlibPath = outputPath
|
return paths.flatMap { path ->
|
||||||
)
|
File(path)
|
||||||
}
|
.walkTopDown()
|
||||||
|
.filter { it.extension == "kt" }
|
||||||
buildKlib(JsIrTestRuntime.FULL.sources, fullRuntimeKlibPath)
|
.map { it.relativeToOrSelf(currentDir).path }
|
||||||
buildKlib(JsIrTestRuntime.DEFAULT.sources, defaultRuntimeKlibPath)
|
.asIterable()
|
||||||
|
}.distinct()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
|
val inputFiles = mutableListOf<String>()
|
||||||
|
var outputPath: String? = null
|
||||||
|
val dependencies = mutableListOf<String>()
|
||||||
|
|
||||||
|
var index = 0
|
||||||
|
while (index < args.size) {
|
||||||
|
val arg = args[index++]
|
||||||
|
|
||||||
|
when (arg) {
|
||||||
|
"-o" -> outputPath = args[index++]
|
||||||
|
"-d" -> dependencies += args[index++]
|
||||||
|
else -> inputFiles += arg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputPath == null) {
|
||||||
|
error("Please set path to .klm file: `-o some/dir/module-name.klm`")
|
||||||
|
}
|
||||||
|
|
||||||
|
val name = outputPath.takeLastWhile { it != '/' }
|
||||||
|
|
||||||
|
if (!name.endsWith(".klm")) error("invalid output file name")
|
||||||
|
|
||||||
|
val dependencyKLibs = dependencies.map {
|
||||||
|
val file = File(it)
|
||||||
|
KlibModuleRef(file.name.dropLast(4), file.parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
buildKLib(name.dropLast(4), listOfKtFilesFrom(inputFiles), File(outputPath).parent, dependencyKLibs)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,178 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
private const val runtimeDir = "js/js.translator/testData/out/irBox"
|
|
||||||
|
|
||||||
enum class JsIrTestRuntime(
|
|
||||||
val sources: List<String>,
|
|
||||||
val path: String
|
|
||||||
) {
|
|
||||||
// Includes all built-ins and reduced subset of stdlib
|
|
||||||
DEFAULT(
|
|
||||||
sources = reducedRuntimeSources,
|
|
||||||
path = "$runtimeDir/testRuntime.js"
|
|
||||||
),
|
|
||||||
|
|
||||||
// Includes almost full stdlib
|
|
||||||
FULL(
|
|
||||||
sources = fullRuntimeSources,
|
|
||||||
path = "$runtimeDir/testRuntimeFull.js"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Required to compile native builtins with the rest of runtime
|
|
||||||
private const val builtInsHeader = """@file:Suppress(
|
|
||||||
"NON_ABSTRACT_FUNCTION_WITH_NO_BODY",
|
|
||||||
"MUST_BE_INITIALIZED_OR_BE_ABSTRACT",
|
|
||||||
"EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE",
|
|
||||||
"PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED",
|
|
||||||
"WRONG_MODIFIER_TARGET"
|
|
||||||
)
|
|
||||||
"""
|
|
||||||
|
|
||||||
// Native builtins that were not implemented in JS IR runtime
|
|
||||||
private val unimplementedNativeBuiltInsDir = KotlinTestUtils.tmpDir("unimplementedBuiltins").also { tmpDir ->
|
|
||||||
val allBuiltins = listOfKtFilesFrom("core/builtins/native/kotlin").map { File(it).name }
|
|
||||||
val implementedBuiltIns = listOfKtFilesFrom("libraries/stdlib/js/irRuntime/builtins/").map { File(it).name }
|
|
||||||
val unimplementedBuiltIns = allBuiltins - implementedBuiltIns
|
|
||||||
for (filename in unimplementedBuiltIns) {
|
|
||||||
val originalFile = File("core/builtins/native/kotlin", filename)
|
|
||||||
val newFile = File(tmpDir, filename)
|
|
||||||
val sourceCode = builtInsHeader + originalFile.readText()
|
|
||||||
newFile.writeText(sourceCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val fullRuntimeSources = listOfKtFilesFrom(
|
|
||||||
"core/builtins/src/kotlin",
|
|
||||||
"libraries/stdlib/common/src",
|
|
||||||
"libraries/stdlib/src/kotlin/",
|
|
||||||
"libraries/stdlib/js/src/kotlin",
|
|
||||||
"libraries/stdlib/js/src/generated",
|
|
||||||
"libraries/stdlib/js/irRuntime",
|
|
||||||
"libraries/stdlib/js/runtime",
|
|
||||||
"libraries/stdlib/unsigned",
|
|
||||||
|
|
||||||
"core/builtins/src/kotlin/Unit.kt",
|
|
||||||
unimplementedNativeBuiltInsDir.path,
|
|
||||||
"js/js.translator/testData/_commonFiles"
|
|
||||||
) - listOfKtFilesFrom(
|
|
||||||
"libraries/stdlib/common/src/kotlin/JvmAnnotationsH.kt",
|
|
||||||
"libraries/stdlib/src/kotlin/annotations/Multiplatform.kt",
|
|
||||||
"libraries/stdlib/common/src/kotlin/NativeAnnotationsH.kt",
|
|
||||||
|
|
||||||
// TODO: Support Int.pow
|
|
||||||
"libraries/stdlib/js/src/kotlin/random/PlatformRandom.kt",
|
|
||||||
|
|
||||||
// Fails with: EXPERIMENTAL_IS_NOT_ENABLED
|
|
||||||
"libraries/stdlib/common/src/kotlin/annotations/Annotations.kt",
|
|
||||||
|
|
||||||
// Conflicts with libraries/stdlib/js/src/kotlin/annotations.kt
|
|
||||||
"libraries/stdlib/js/runtime/hacks.kt",
|
|
||||||
|
|
||||||
// TODO: Reuse in IR BE
|
|
||||||
"libraries/stdlib/js/runtime/Enum.kt",
|
|
||||||
|
|
||||||
// JS-specific optimized version of emptyArray() already defined
|
|
||||||
"core/builtins/src/kotlin/ArrayIntrinsics.kt",
|
|
||||||
|
|
||||||
// Unnecessary for now
|
|
||||||
"libraries/stdlib/js/src/kotlin/dom",
|
|
||||||
"libraries/stdlib/js/src/kotlin/browser",
|
|
||||||
|
|
||||||
// TODO: fix compilation issues in arrayPlusCollection
|
|
||||||
// Replaced with irRuntime/kotlinHacks.kt
|
|
||||||
"libraries/stdlib/js/src/kotlin/kotlin.kt",
|
|
||||||
|
|
||||||
"libraries/stdlib/js/src/kotlin/currentBeMisc.kt",
|
|
||||||
|
|
||||||
// IR BE has its own generated sources
|
|
||||||
"libraries/stdlib/js/src/generated",
|
|
||||||
"libraries/stdlib/js/src/kotlin/collectionsExternal.kt",
|
|
||||||
|
|
||||||
// Full version is defined in stdlib
|
|
||||||
// This file is useful for smaller subset of runtime sources
|
|
||||||
"libraries/stdlib/js/irRuntime/smallRuntimeMissingDeclarations.kt",
|
|
||||||
|
|
||||||
// Mostly array-specific stuff
|
|
||||||
"libraries/stdlib/js/src/kotlin/builtins.kt",
|
|
||||||
|
|
||||||
// coroutines
|
|
||||||
// TODO: merge coroutines_13 with JS BE coroutines
|
|
||||||
"libraries/stdlib/js/src/kotlin/coroutines/intrinsics/IntrinsicsJs.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/coroutines/CoroutineImpl.kt",
|
|
||||||
|
|
||||||
// Inlining of js fun doesn't update the variables inside
|
|
||||||
"libraries/stdlib/js/src/kotlin/jsTypeOf.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/collections/utils.kt",
|
|
||||||
|
|
||||||
// TODO: Remove stub
|
|
||||||
"libraries/stdlib/js/src/kotlin/builtins.kt"
|
|
||||||
)
|
|
||||||
|
|
||||||
private val reducedRuntimeSources = fullRuntimeSources - listOfKtFilesFrom(
|
|
||||||
"libraries/stdlib/unsigned",
|
|
||||||
"libraries/stdlib/common/src/generated/_Arrays.kt",
|
|
||||||
"libraries/stdlib/common/src/generated/_Collections.kt",
|
|
||||||
"libraries/stdlib/common/src/generated/_Comparisons.kt",
|
|
||||||
"libraries/stdlib/common/src/generated/_Maps.kt",
|
|
||||||
"libraries/stdlib/common/src/generated/_Sequences.kt",
|
|
||||||
"libraries/stdlib/common/src/generated/_Sets.kt",
|
|
||||||
"libraries/stdlib/common/src/generated/_Strings.kt",
|
|
||||||
"libraries/stdlib/common/src/generated/_UArrays.kt",
|
|
||||||
"libraries/stdlib/common/src/generated/_URanges.kt",
|
|
||||||
"libraries/stdlib/common/src/generated/_UCollections.kt",
|
|
||||||
"libraries/stdlib/common/src/generated/_UComparisons.kt",
|
|
||||||
"libraries/stdlib/common/src/generated/_USequences.kt",
|
|
||||||
"libraries/stdlib/common/src/kotlin/SequencesH.kt",
|
|
||||||
"libraries/stdlib/common/src/kotlin/TextH.kt",
|
|
||||||
"libraries/stdlib/common/src/kotlin/UMath.kt",
|
|
||||||
"libraries/stdlib/common/src/kotlin/collections/",
|
|
||||||
"libraries/stdlib/common/src/kotlin/ioH.kt",
|
|
||||||
"libraries/stdlib/js/irRuntime/collectionsHacks.kt",
|
|
||||||
"libraries/stdlib/js/irRuntime/generated/",
|
|
||||||
"libraries/stdlib/js/src/kotlin/char.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/collections.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/collections/",
|
|
||||||
"libraries/stdlib/js/src/kotlin/console.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/coreDeprecated.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/date.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/debug.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/grouping.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/json.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/numberConversions.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/promise.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/regex.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/regexp.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/sequence.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/string.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/stringsCode.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/text.kt",
|
|
||||||
"libraries/stdlib/src/kotlin/collections/",
|
|
||||||
"libraries/stdlib/src/kotlin/experimental/bitwiseOperations.kt",
|
|
||||||
"libraries/stdlib/src/kotlin/properties/Delegates.kt",
|
|
||||||
"libraries/stdlib/src/kotlin/random/URandom.kt",
|
|
||||||
"libraries/stdlib/src/kotlin/text/",
|
|
||||||
"libraries/stdlib/src/kotlin/util/KotlinVersion.kt",
|
|
||||||
"libraries/stdlib/src/kotlin/util/Tuples.kt"
|
|
||||||
) + listOfKtFilesFrom(
|
|
||||||
"libraries/stdlib/js/irRuntime/smallRuntimeMissingDeclarations.kt"
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun listOfKtFilesFrom(vararg paths: String): List<String> {
|
|
||||||
val currentDir = File("")
|
|
||||||
return paths.flatMap { path ->
|
|
||||||
File(path)
|
|
||||||
.walkTopDown()
|
|
||||||
.filter { it.extension == "kt" }
|
|
||||||
.map { it.relativeToOrSelf(currentDir).path }
|
|
||||||
.asIterable()
|
|
||||||
}.distinct()
|
|
||||||
}
|
|
||||||
@@ -76,7 +76,8 @@ class CodeConformanceTest : TestCase() {
|
|||||||
"libraries/tools/kotlin-gradle-plugin-integration-tests/build",
|
"libraries/tools/kotlin-gradle-plugin-integration-tests/build",
|
||||||
"libraries/tools/kotlin-test-nodejs-runner/node_modules",
|
"libraries/tools/kotlin-test-nodejs-runner/node_modules",
|
||||||
"libraries/tools/kotlin-test-nodejs-runner/.gradle",
|
"libraries/tools/kotlin-test-nodejs-runner/.gradle",
|
||||||
"buildSrc/prepare-deps/build"
|
"buildSrc/prepare-deps/build",
|
||||||
|
"compiler/ir/serialization.js/build"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,11 @@ sourceSets {
|
|||||||
fun Test.setUpBoxTests(jsEnabled: Boolean, jsIrEnabled: Boolean) {
|
fun Test.setUpBoxTests(jsEnabled: Boolean, jsIrEnabled: Boolean) {
|
||||||
dependsOn(":dist")
|
dependsOn(":dist")
|
||||||
if (jsEnabled) dependsOn(testJsRuntime)
|
if (jsEnabled) dependsOn(testJsRuntime)
|
||||||
if (jsIrEnabled) dependsOn(":compiler:ir.serialization.js:generateIrRuntimeKlib")
|
if (jsIrEnabled) {
|
||||||
|
dependsOn(":compiler:ir.serialization.js:generateFullRuntimeKLib")
|
||||||
|
dependsOn(":compiler:ir.serialization.js:generateReducedRuntimeKLib")
|
||||||
|
dependsOn(":compiler:ir.serialization.js:generateKotlinTestKLib")
|
||||||
|
}
|
||||||
|
|
||||||
if (jsEnabled && !jsIrEnabled) exclude("org/jetbrains/kotlin/js/test/ir/semantics/*")
|
if (jsEnabled && !jsIrEnabled) exclude("org/jetbrains/kotlin/js/test/ir/semantics/*")
|
||||||
if (!jsEnabled && jsIrEnabled) include("org/jetbrains/kotlin/js/test/ir/semantics/*")
|
if (!jsEnabled && jsIrEnabled) include("org/jetbrains/kotlin/js/test/ir/semantics/*")
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.idea.KotlinFileType
|
|||||||
import org.jetbrains.kotlin.incremental.js.IncrementalDataProviderImpl
|
import org.jetbrains.kotlin.incremental.js.IncrementalDataProviderImpl
|
||||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
|
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
|
||||||
import org.jetbrains.kotlin.incremental.js.TranslationResultValue
|
import org.jetbrains.kotlin.incremental.js.TranslationResultValue
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrTestRuntime
|
|
||||||
import org.jetbrains.kotlin.js.JavaScript
|
import org.jetbrains.kotlin.js.JavaScript
|
||||||
import org.jetbrains.kotlin.js.backend.JsToStringGenerationVisitor
|
import org.jetbrains.kotlin.js.backend.JsToStringGenerationVisitor
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
@@ -110,11 +109,7 @@ abstract class BasicBoxTest(
|
|||||||
fileContent = fileContent.replace("COROUTINES_PACKAGE", coroutinesPackage)
|
fileContent = fileContent.replace("COROUTINES_PACKAGE", coroutinesPackage)
|
||||||
}
|
}
|
||||||
|
|
||||||
val runtimeType =
|
val needsFullIrRuntime = KJS_WITH_FULL_RUNTIME.matcher(fileContent).find()
|
||||||
if (KJS_WITH_FULL_RUNTIME.matcher(fileContent).find())
|
|
||||||
JsIrTestRuntime.FULL
|
|
||||||
else
|
|
||||||
JsIrTestRuntime.DEFAULT
|
|
||||||
|
|
||||||
val actualMainCallParameters = if (CALL_MAIN_PATTERN.matcher(fileContent).find()) MainCallParameters.mainWithArguments(listOf("testArg")) else mainCallParameters
|
val actualMainCallParameters = if (CALL_MAIN_PATTERN.matcher(fileContent).find()) MainCallParameters.mainWithArguments(listOf("testArg")) else mainCallParameters
|
||||||
|
|
||||||
@@ -150,7 +145,7 @@ abstract class BasicBoxTest(
|
|||||||
file.parent, module, outputFileName, dependencies, allDependencies, friends, modules.size > 1,
|
file.parent, module, outputFileName, dependencies, allDependencies, friends, modules.size > 1,
|
||||||
!SKIP_SOURCEMAP_REMAPPING.matcher(fileContent).find(),
|
!SKIP_SOURCEMAP_REMAPPING.matcher(fileContent).find(),
|
||||||
outputPrefixFile, outputPostfixFile, actualMainCallParameters, testPackage, testFunction,
|
outputPrefixFile, outputPostfixFile, actualMainCallParameters, testPackage, testFunction,
|
||||||
runtimeType, isMainModule
|
needsFullIrRuntime, isMainModule
|
||||||
)
|
)
|
||||||
|
|
||||||
when {
|
when {
|
||||||
@@ -333,7 +328,7 @@ abstract class BasicBoxTest(
|
|||||||
mainCallParameters: MainCallParameters,
|
mainCallParameters: MainCallParameters,
|
||||||
testPackage: String?,
|
testPackage: String?,
|
||||||
testFunction: String,
|
testFunction: String,
|
||||||
runtime: JsIrTestRuntime,
|
needsFullIrRuntime: Boolean,
|
||||||
isMainModule: Boolean
|
isMainModule: Boolean
|
||||||
) {
|
) {
|
||||||
val kotlinFiles = module.files.filter { it.fileName.endsWith(".kt") }
|
val kotlinFiles = module.files.filter { it.fileName.endsWith(".kt") }
|
||||||
@@ -356,13 +351,13 @@ abstract class BasicBoxTest(
|
|||||||
val incrementalData = IncrementalData()
|
val incrementalData = IncrementalData()
|
||||||
translateFiles(
|
translateFiles(
|
||||||
psiFiles.map(TranslationUnit::SourceFile), outputFile, config, outputPrefixFile, outputPostfixFile,
|
psiFiles.map(TranslationUnit::SourceFile), outputFile, config, outputPrefixFile, outputPostfixFile,
|
||||||
mainCallParameters, incrementalData, remap, testPackage, testFunction, runtime, isMainModule
|
mainCallParameters, incrementalData, remap, testPackage, testFunction, needsFullIrRuntime, isMainModule
|
||||||
)
|
)
|
||||||
|
|
||||||
if (incrementalCompilationChecksEnabled && module.hasFilesToRecompile) {
|
if (incrementalCompilationChecksEnabled && module.hasFilesToRecompile) {
|
||||||
checkIncrementalCompilation(
|
checkIncrementalCompilation(
|
||||||
sourceDirs, module, kotlinFiles, dependencies, allDependencies, friends, multiModule, remap,
|
sourceDirs, module, kotlinFiles, dependencies, allDependencies, friends, multiModule, remap,
|
||||||
outputFile, outputPrefixFile, outputPostfixFile, mainCallParameters, incrementalData, testPackage, testFunction, runtime
|
outputFile, outputPrefixFile, outputPostfixFile, mainCallParameters, incrementalData, testPackage, testFunction, needsFullIrRuntime
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -383,7 +378,7 @@ abstract class BasicBoxTest(
|
|||||||
incrementalData: IncrementalData,
|
incrementalData: IncrementalData,
|
||||||
testPackage: String?,
|
testPackage: String?,
|
||||||
testFunction: String,
|
testFunction: String,
|
||||||
runtime: JsIrTestRuntime
|
needsFullIrRuntime: Boolean
|
||||||
) {
|
) {
|
||||||
val sourceToTranslationUnit = hashMapOf<File, TranslationUnit>()
|
val sourceToTranslationUnit = hashMapOf<File, TranslationUnit>()
|
||||||
for (testFile in kotlinFiles) {
|
for (testFile in kotlinFiles) {
|
||||||
@@ -405,7 +400,7 @@ abstract class BasicBoxTest(
|
|||||||
|
|
||||||
translateFiles(
|
translateFiles(
|
||||||
translationUnits, recompiledOutputFile, recompiledConfig, outputPrefixFile, outputPostfixFile,
|
translationUnits, recompiledOutputFile, recompiledConfig, outputPrefixFile, outputPostfixFile,
|
||||||
mainCallParameters, incrementalData, remap, testPackage, testFunction, runtime, false
|
mainCallParameters, incrementalData, remap, testPackage, testFunction, needsFullIrRuntime, false
|
||||||
)
|
)
|
||||||
|
|
||||||
val originalOutput = FileUtil.loadFile(outputFile)
|
val originalOutput = FileUtil.loadFile(outputFile)
|
||||||
@@ -470,7 +465,7 @@ abstract class BasicBoxTest(
|
|||||||
remap: Boolean,
|
remap: Boolean,
|
||||||
testPackage: String?,
|
testPackage: String?,
|
||||||
testFunction: String,
|
testFunction: String,
|
||||||
runtime: JsIrTestRuntime,
|
needsFullIrRuntime: Boolean,
|
||||||
isMainModule: Boolean
|
isMainModule: Boolean
|
||||||
) {
|
) {
|
||||||
val translator = K2JSTranslator(config, false)
|
val translator = K2JSTranslator(config, false)
|
||||||
|
|||||||
@@ -7,7 +7,10 @@ package org.jetbrains.kotlin.js.test
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||||
import org.jetbrains.kotlin.ir.backend.js.*
|
import org.jetbrains.kotlin.ir.backend.js.KlibModuleRef
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.compile
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.generateKLib
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.jsPhases
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
import org.jetbrains.kotlin.js.config.JsConfig
|
import org.jetbrains.kotlin.js.config.JsConfig
|
||||||
import org.jetbrains.kotlin.js.facade.MainCallParameters
|
import org.jetbrains.kotlin.js.facade.MainCallParameters
|
||||||
@@ -15,13 +18,9 @@ import org.jetbrains.kotlin.js.facade.TranslationUnit
|
|||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
private val fullRuntimeKlibPath = "js/js.translator/testData/out/klibs/runtimeFull/"
|
private val fullRuntimeKlib = KlibModuleRef("JS_IR_RUNTIME", "compiler/ir/serialization.js/build/fullRuntime/klib")
|
||||||
private val defaultRuntimeKlibPath = "js/js.translator/testData/out/klibs/runtimeDefault/"
|
private val defaultRuntimeKlib = KlibModuleRef("JS_IR_RUNTIME", "compiler/ir/serialization.js/build/reducedRuntime/klib")
|
||||||
|
private val kotlinTestKLib = KlibModuleRef("kotlin.test", "compiler/ir/serialization.js/build/kotlin.test/klib")
|
||||||
private val JS_IR_RUNTIME_MODULE_NAME = "JS_IR_RUNTIME"
|
|
||||||
|
|
||||||
private val fullRuntimeKlib = KlibModuleRef(JS_IR_RUNTIME_MODULE_NAME, fullRuntimeKlibPath)
|
|
||||||
private val defaultRuntimeKlib = KlibModuleRef(JS_IR_RUNTIME_MODULE_NAME, defaultRuntimeKlibPath)
|
|
||||||
|
|
||||||
abstract class BasicIrBoxTest(
|
abstract class BasicIrBoxTest(
|
||||||
pathToTestDir: String,
|
pathToTestDir: String,
|
||||||
@@ -53,10 +52,6 @@ abstract class BasicIrBoxTest(
|
|||||||
|
|
||||||
override val testChecker get() = if (runTestInNashorn) NashornIrJsTestChecker() else V8IrJsTestChecker
|
override val testChecker get() = if (runTestInNashorn) NashornIrJsTestChecker() else V8IrJsTestChecker
|
||||||
|
|
||||||
private val runtimes = mapOf(
|
|
||||||
JsIrTestRuntime.DEFAULT to defaultRuntimeKlib,
|
|
||||||
JsIrTestRuntime.FULL to fullRuntimeKlib)
|
|
||||||
|
|
||||||
override fun translateFiles(
|
override fun translateFiles(
|
||||||
units: List<TranslationUnit>,
|
units: List<TranslationUnit>,
|
||||||
outputFile: File,
|
outputFile: File,
|
||||||
@@ -68,7 +63,7 @@ abstract class BasicIrBoxTest(
|
|||||||
remap: Boolean,
|
remap: Boolean,
|
||||||
testPackage: String?,
|
testPackage: String?,
|
||||||
testFunction: String,
|
testFunction: String,
|
||||||
runtime: JsIrTestRuntime,
|
needsFullIrRuntime: Boolean,
|
||||||
isMainModule: Boolean
|
isMainModule: Boolean
|
||||||
) {
|
) {
|
||||||
val filesToCompile = units
|
val filesToCompile = units
|
||||||
@@ -76,35 +71,20 @@ abstract class BasicIrBoxTest(
|
|||||||
// TODO: split input files to some parts (global common, local common, test)
|
// TODO: split input files to some parts (global common, local common, test)
|
||||||
.filterNot { it.virtualFilePath.contains(BasicBoxTest.COMMON_FILES_DIR_PATH) }
|
.filterNot { it.virtualFilePath.contains(BasicBoxTest.COMMON_FILES_DIR_PATH) }
|
||||||
|
|
||||||
// config.configuration.put(CommonConfigurationKeys.EXCLUDED_ELEMENTS_FROM_DUMPING, setOf("<JS_IR_RUNTIME>"))
|
val runtimeKlibs = if (needsFullIrRuntime) listOf(fullRuntimeKlib, kotlinTestKLib) else listOf(defaultRuntimeKlib)
|
||||||
// config.configuration.put(
|
|
||||||
// CommonConfigurationKeys.PHASES_TO_VALIDATE_AFTER,
|
|
||||||
// setOf(
|
|
||||||
// "RemoveInlineFunctionsWithReifiedTypeParametersLowering",
|
|
||||||
// "InnerClassConstructorCallsLowering",
|
|
||||||
// "InlineClassLowering", "ConstLowering"
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
|
|
||||||
val runtimeKlib = runtimes[runtime]!!
|
|
||||||
|
|
||||||
val libraries = config.configuration[JSConfigurationKeys.LIBRARIES]!!.map { File(it).name }
|
val libraries = config.configuration[JSConfigurationKeys.LIBRARIES]!!.map { File(it).name }
|
||||||
val transitiveLibraries = config.configuration[JSConfigurationKeys.TRANSITIVE_LIBRARIES]!!.map { File(it).name }
|
val transitiveLibraries = config.configuration[JSConfigurationKeys.TRANSITIVE_LIBRARIES]!!.map { File(it).name }
|
||||||
|
|
||||||
// TODO: Add proper depencencies
|
// TODO: Add proper depencencies
|
||||||
val dependencies = listOf(runtimeKlib) + libraries.map {
|
val dependencies = runtimeKlibs + libraries.map {
|
||||||
compilationCache[it] ?: error("Can't find compiled module for dependency $it")
|
compilationCache[it] ?: error("Can't find compiled module for dependency $it")
|
||||||
}
|
}
|
||||||
|
|
||||||
val allDependencies = listOf(runtimeKlib) + transitiveLibraries.map {
|
val allDependencies = runtimeKlibs + transitiveLibraries.map {
|
||||||
compilationCache[it] ?: error("Can't find compiled module for dependency $it")
|
compilationCache[it] ?: error("Can't find compiled module for dependency $it")
|
||||||
}
|
}
|
||||||
|
|
||||||
// config.configuration.put(CommonConfigurationKeys.PHASES_TO_DUMP_STATE, setOf("UnitMaterializationLowering"))
|
|
||||||
// config.configuration.put(CommonConfigurationKeys.PHASES_TO_DUMP_STATE_BEFORE, setOf("ReturnableBlockLowering"))
|
|
||||||
// config.configuration.put(CommonConfigurationKeys.PHASES_TO_DUMP_STATE_AFTER, setOf("MultipleCatchesLowering"))
|
|
||||||
// config.configuration.put(CommonConfigurationKeys.PHASES_TO_VALIDATE, setOf("ALL"))
|
|
||||||
|
|
||||||
val actualOutputFile = outputFile.absolutePath.let {
|
val actualOutputFile = outputFile.absolutePath.let {
|
||||||
if (!isMainModule) it.replace("_v5.js", "/") else it
|
if (!isMainModule) it.replace("_v5.js", "/") else it
|
||||||
}
|
}
|
||||||
|
|||||||
+90
-23
@@ -1,44 +1,107 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
import kotlin.test.FrameworkAdapter
|
import kotlin.test.FrameworkAdapter
|
||||||
|
import kotlin.collections.*
|
||||||
|
|
||||||
private val context = TestContext()
|
private var sortingContext = SortingContext()
|
||||||
|
|
||||||
fun call(name: String) = context.call(name)
|
private var bodyContext: TestBodyContext? = null
|
||||||
|
|
||||||
|
fun call(name: String) = bodyContext!!.call(name)
|
||||||
|
|
||||||
fun raise(name: String): Nothing {
|
fun raise(name: String): Nothing {
|
||||||
context.raised(name)
|
bodyContext!!.raised(name)
|
||||||
throw Exception(name)
|
throw Exception(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("INVISIBLE_MEMBER")
|
@Suppress("INVISIBLE_MEMBER")
|
||||||
val underscore = kotlin.test.setAdapter(object : FrameworkAdapter {
|
private val underscore = kotlin.test.setAdapter(object : FrameworkAdapter {
|
||||||
override fun suite(name: String, ignored: Boolean, suiteFn: () -> Unit) {
|
override fun suite(name: String, ignored: Boolean, suiteFn: () -> Unit) {
|
||||||
context.suite(name, ignored) { suiteFn() }
|
sortingContext.suite(name, ignored) { suiteFn() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun test(name: String, ignored: Boolean, testFn: () -> dynamic) {
|
override fun test(name: String, ignored: Boolean, testFn: () -> dynamic) {
|
||||||
context.test(name, ignored) { returned(testFn()) }
|
sortingContext.test(name, ignored) { returned(testFn()) }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class TestContext {
|
interface SuiteContext {
|
||||||
|
fun suite(name: String, ignored: Boolean = false, body: SuiteContext.() -> Unit)
|
||||||
|
|
||||||
|
fun test(name: String, ignored: Boolean = false, body: TestBodyContext.() -> Unit = {})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface TestBodyContext {
|
||||||
|
fun call(name: String)
|
||||||
|
|
||||||
|
fun raised(msg: String)
|
||||||
|
|
||||||
|
fun caught(msg: String)
|
||||||
|
|
||||||
|
fun returned(msg: dynamic)
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class Entity(val name: String,
|
||||||
|
val ignored: Boolean)
|
||||||
|
|
||||||
|
private class Suite(name: String, ignored: Boolean, val body: SuiteContext.() -> Unit): Entity(name, ignored)
|
||||||
|
|
||||||
|
private class Test(name: String, ignored: Boolean, val body: TestBodyContext.() -> Unit): Entity(name, ignored)
|
||||||
|
|
||||||
|
|
||||||
|
private class SortingContext: SuiteContext {
|
||||||
|
|
||||||
|
val structure = mutableListOf<Entity>()
|
||||||
|
|
||||||
|
override fun suite(name: String, ignored: Boolean, body: SuiteContext.() -> Unit) {
|
||||||
|
structure += Suite(name, ignored, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun test(name: String, ignored: Boolean, body: TestBodyContext.() -> Unit) {
|
||||||
|
structure += Test(name, ignored, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T: SuiteContext> replayInto(context: T): T {
|
||||||
|
structure.sortedBy { it.name }.forEach {
|
||||||
|
when (it) {
|
||||||
|
is Suite -> context.suite(it.name, it.ignored) {
|
||||||
|
val oldSorter = sortingContext
|
||||||
|
|
||||||
|
sortingContext = SortingContext()
|
||||||
|
it.body(sortingContext)
|
||||||
|
sortingContext.replayInto(this)
|
||||||
|
|
||||||
|
sortingContext = oldSorter
|
||||||
|
}
|
||||||
|
is Test -> context.test(it.name, it.ignored) {
|
||||||
|
bodyContext = this
|
||||||
|
it.body(this)
|
||||||
|
bodyContext = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LoggingContext : SuiteContext, TestBodyContext{
|
||||||
val log: String
|
val log: String
|
||||||
get() = logHead + (lastRecord ?: "")
|
get() = logHead + (lastRecord ?: "")
|
||||||
|
|
||||||
var indentation = ""
|
private var indentation = ""
|
||||||
|
|
||||||
fun suite(name: String, ignored: Boolean = false, body: TestContext.() -> Unit) = indent {
|
override fun suite(name: String, ignored: Boolean, body: SuiteContext.() -> Unit) = indent {
|
||||||
record("suite(\"$name\"${optionalIgnore(ignored)}) {")
|
record("suite(\"$name\"${optionalIgnore(ignored)}) {")
|
||||||
body.runSafely()
|
runSafely { this.body() }
|
||||||
record("}")
|
record("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun test(name: String, ignored: Boolean, body: TestBodyContext.() -> Unit) = indent {
|
||||||
fun test(name: String, ignored: Boolean = false, body: TestContext.() -> Unit = {}) = indent {
|
|
||||||
val num = record("test(\"$name\"${optionalIgnore(ignored)}) {")
|
val num = record("test(\"$name\"${optionalIgnore(ignored)}) {")
|
||||||
|
|
||||||
body.runSafely()
|
runSafely { this.body() }
|
||||||
|
|
||||||
if (!writtenSince(num)) {
|
if (!writtenSince(num)) {
|
||||||
record("test(\"$name\"${optionalIgnore(ignored)})", replaceLast = true)
|
record("test(\"$name\"${optionalIgnore(ignored)})", replaceLast = true)
|
||||||
@@ -48,25 +111,25 @@ class TestContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun call(name: String) = indent {
|
override fun call(name: String) = indent {
|
||||||
record("call(\"$name\")")
|
record("call(\"$name\")")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun raised(msg: String) = indent {
|
override fun raised(msg: String) = indent {
|
||||||
record("raised(\"$msg\")")
|
record("raised(\"$msg\")")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun caught(msg: String) = indent {
|
override fun caught(msg: String) = indent {
|
||||||
record("caught(\"$msg\")")
|
record("caught(\"$msg\")")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun returned(msg: dynamic) = indent {
|
override fun returned(msg: dynamic) = indent {
|
||||||
if (msg is String) record("returned(\"$msg\")")
|
if (msg is String) record("returned(\"$msg\")")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun (TestContext.() -> Unit).runSafely() {
|
private fun runSafely(body: () -> Unit) {
|
||||||
try {
|
try {
|
||||||
this()
|
body()
|
||||||
}
|
}
|
||||||
catch (t: Throwable) {
|
catch (t: Throwable) {
|
||||||
caught(t.message ?: "")
|
caught(t.message ?: "")
|
||||||
@@ -100,8 +163,8 @@ class TestContext {
|
|||||||
private fun optionalIgnore(ignored: Boolean) = if (ignored) ", true" else ""
|
private fun optionalIgnore(ignored: Boolean) = if (ignored) ", true" else ""
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkLog(wrapInEmptySuite: Boolean = true, body: TestContext.() -> Unit): String {
|
fun checkLog(wrapInEmptySuite: Boolean = true, body: SuiteContext.() -> Unit): String {
|
||||||
val expectedContext = TestContext()
|
val expectedContext = SortingContext()
|
||||||
if (wrapInEmptySuite) {
|
if (wrapInEmptySuite) {
|
||||||
expectedContext.suite("") {
|
expectedContext.suite("") {
|
||||||
body()
|
body()
|
||||||
@@ -109,8 +172,12 @@ fun checkLog(wrapInEmptySuite: Boolean = true, body: TestContext.() -> Unit): St
|
|||||||
} else {
|
} else {
|
||||||
expectedContext.body()
|
expectedContext.body()
|
||||||
}
|
}
|
||||||
if (context.log != expectedContext.log) {
|
|
||||||
return "Failed test structure check. Expected: ${expectedContext.log}; actual: ${context.log}."
|
val expectedLog = expectedContext.replayInto(LoggingContext()).log
|
||||||
|
val actualLog = sortingContext.replayInto(LoggingContext()).log
|
||||||
|
|
||||||
|
if (actualLog != expectedLog) {
|
||||||
|
return "Failed test structure check. Expected: ${expectedLog}; actual: ${actualLog}."
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return "OK"
|
return "OK"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// EXPECTED_REACHABLE_NODES: 1706
|
||||||
// EXPECTED_REACHABLE_NODES: 1339
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|
||||||
import common.*
|
import common.*
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.BeforeTest
|
import kotlin.test.BeforeTest
|
||||||
|
|||||||
+3
-2
@@ -1,5 +1,6 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// EXPECTED_REACHABLE_NODES: 1709
|
||||||
// EXPECTED_REACHABLE_NODES: 1340
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|
||||||
import common.*
|
import common.*
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.Ignore
|
import kotlin.test.Ignore
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// EXPECTED_REACHABLE_NODES: 1829
|
||||||
// EXPECTED_REACHABLE_NODES: 1330
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|
||||||
// FILE: a.kt
|
// FILE: a.kt
|
||||||
package a
|
package a
|
||||||
|
|||||||
+3
-2
@@ -1,5 +1,6 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// EXPECTED_REACHABLE_NODES: 1719
|
||||||
// EXPECTED_REACHABLE_NODES: 1351
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|
||||||
import common.*
|
import common.*
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.BeforeTest
|
import kotlin.test.BeforeTest
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
|
// EXPECTED_REACHABLE_NODES: 1697
|
||||||
// !LANGUAGE: +MultiPlatformProjects
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
// EXPECTED_REACHABLE_NODES: 1328
|
// KJS_WITH_FULL_RUNTIME
|
||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
|
|
||||||
// FILE: lib.kt
|
// FILE: lib.kt
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
|
|||||||
+3
-2
@@ -1,5 +1,6 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// EXPECTED_REACHABLE_NODES: 1735
|
||||||
// EXPECTED_REACHABLE_NODES: 1367
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|
||||||
import common.*
|
import common.*
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// EXPECTED_REACHABLE_NODES: 1737
|
||||||
// EXPECTED_REACHABLE_NODES: 1297
|
// KJS_WITH_FULL_RUNTIME
|
||||||
import common.*
|
import common.*
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.BeforeTest
|
import kotlin.test.BeforeTest
|
||||||
|
|||||||
+3
-2
@@ -1,5 +1,6 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// EXPECTED_REACHABLE_NODES: 1698
|
||||||
// EXPECTED_REACHABLE_NODES: 1330
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|
||||||
import common.*
|
import common.*
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.native.concurrent
|
||||||
|
|
||||||
|
// Current serialization removes expect declarations, so some dummy annotations are needed
|
||||||
|
// Expect declarations: libraries/stdlib/common/src/kotlin/NativeAnnotationsH.kt
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
@OptionalExpectation
|
||||||
|
public annotation class ThreadLocal()
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.PROPERTY)
|
||||||
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
@OptionalExpectation
|
||||||
|
public annotation class SharedImmutable()
|
||||||
Reference in New Issue
Block a user