[JS IR] Support per-file mode and ES modules
This commit is contained in:
+3
@@ -170,6 +170,9 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
|||||||
@Argument(value = "-Xir-per-module-output-name", description = "Adds a custom output name to the splitted js files")
|
@Argument(value = "-Xir-per-module-output-name", description = "Adds a custom output name to the splitted js files")
|
||||||
var irPerModuleOutputName: String? by NullableStringFreezableVar(null)
|
var irPerModuleOutputName: String? by NullableStringFreezableVar(null)
|
||||||
|
|
||||||
|
@Argument(value = "-Xir-per-file", description = "Splits generated .js per-file")
|
||||||
|
var irPerFile: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
@Argument(
|
@Argument(
|
||||||
value = "-Xinclude",
|
value = "-Xinclude",
|
||||||
valueDescription = "<path>",
|
valueDescription = "<path>",
|
||||||
|
|||||||
+1
@@ -24,6 +24,7 @@ public interface K2JsArgumentConstants {
|
|||||||
String MODULE_AMD = "amd";
|
String MODULE_AMD = "amd";
|
||||||
String MODULE_COMMONJS = "commonjs";
|
String MODULE_COMMONJS = "commonjs";
|
||||||
String MODULE_UMD = "umd";
|
String MODULE_UMD = "umd";
|
||||||
|
String MODULE_ES = "es";
|
||||||
|
|
||||||
String SOURCE_MAP_SOURCE_CONTENT_ALWAYS = "always";
|
String SOURCE_MAP_SOURCE_CONTENT_ALWAYS = "always";
|
||||||
String SOURCE_MAP_SOURCE_CONTENT_NEVER = "never";
|
String SOURCE_MAP_SOURCE_CONTENT_NEVER = "never";
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ import org.jetbrains.kotlin.ir.backend.js.ic.checkCaches
|
|||||||
import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName
|
import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ic.*
|
import org.jetbrains.kotlin.ir.backend.js.ic.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
|
||||||
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
|
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
|
||||||
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
|
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
|
||||||
import org.jetbrains.kotlin.js.config.*
|
import org.jetbrains.kotlin.js.config.*
|
||||||
@@ -332,20 +334,21 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
|
|
||||||
val start = System.currentTimeMillis()
|
val start = System.currentTimeMillis()
|
||||||
|
|
||||||
val compiledModule = compile(
|
val granularity = when {
|
||||||
|
arguments.irPerModule -> JsGenerationGranularity.PER_MODULE
|
||||||
|
arguments.irPerFile -> JsGenerationGranularity.PER_FILE
|
||||||
|
else -> JsGenerationGranularity.WHOLE_PROGRAM
|
||||||
|
}
|
||||||
|
|
||||||
|
val ir = compile(
|
||||||
module,
|
module,
|
||||||
phaseConfig,
|
phaseConfig,
|
||||||
if (arguments.irDceDriven) PersistentIrFactory() else IrFactoryImpl,
|
if (arguments.irDceDriven) PersistentIrFactory() else IrFactoryImpl,
|
||||||
mainArguments = mainCallArguments,
|
|
||||||
generateFullJs = !arguments.irDce,
|
|
||||||
generateDceJs = arguments.irDce,
|
|
||||||
dceRuntimeDiagnostic = RuntimeDiagnostic.resolve(
|
dceRuntimeDiagnostic = RuntimeDiagnostic.resolve(
|
||||||
arguments.irDceRuntimeDiagnostic,
|
arguments.irDceRuntimeDiagnostic,
|
||||||
messageCollector
|
messageCollector
|
||||||
),
|
),
|
||||||
dceDriven = arguments.irDceDriven,
|
dceDriven = arguments.irDceDriven,
|
||||||
multiModule = arguments.irPerModule,
|
|
||||||
relativeRequirePath = true,
|
|
||||||
propertyLazyInitialization = arguments.irPropertyLazyInitialization,
|
propertyLazyInitialization = arguments.irPropertyLazyInitialization,
|
||||||
baseClassIntoMetadata = arguments.irBaseClassInMetadata,
|
baseClassIntoMetadata = arguments.irBaseClassInMetadata,
|
||||||
safeExternalBoolean = arguments.irSafeExternalBoolean,
|
safeExternalBoolean = arguments.irSafeExternalBoolean,
|
||||||
@@ -354,11 +357,28 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
messageCollector
|
messageCollector
|
||||||
),
|
),
|
||||||
lowerPerModule = icCaches.isNotEmpty(),
|
lowerPerModule = icCaches.isNotEmpty(),
|
||||||
|
granularity = granularity
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val transformer = IrModuleToJsTransformer(
|
||||||
|
ir.context,
|
||||||
|
mainCallArguments,
|
||||||
|
fullJs = true,
|
||||||
|
dceJs = arguments.irDce,
|
||||||
|
multiModule = arguments.irPerModule,
|
||||||
|
relativeRequirePath = false
|
||||||
|
)
|
||||||
|
val compiledModule: CompilerResult = transformer.generateModule(ir.allModules)
|
||||||
|
|
||||||
messageCollector.report(INFO, "Executable production duration: ${System.currentTimeMillis() - start}ms")
|
messageCollector.report(INFO, "Executable production duration: ${System.currentTimeMillis() - start}ms")
|
||||||
|
|
||||||
val outputs = if (arguments.irDce && !arguments.irDceDriven) compiledModule.outputsAfterDce!! else compiledModule.outputs!!
|
|
||||||
|
|
||||||
|
val outputs = if (arguments.irDce && !arguments.irDceDriven)
|
||||||
|
compiledModule.outputsAfterDce!!
|
||||||
|
else
|
||||||
|
compiledModule.outputs!!
|
||||||
|
|
||||||
outputFile.write(outputs)
|
outputFile.write(outputs)
|
||||||
outputs.dependencies.forEach { (name, content) ->
|
outputs.dependencies.forEach { (name, content) ->
|
||||||
outputFile.resolveSibling("$name.js").write(content)
|
outputFile.resolveSibling("$name.js").write(content)
|
||||||
@@ -495,7 +515,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
K2JsArgumentConstants.MODULE_PLAIN to ModuleKind.PLAIN,
|
K2JsArgumentConstants.MODULE_PLAIN to ModuleKind.PLAIN,
|
||||||
K2JsArgumentConstants.MODULE_COMMONJS to ModuleKind.COMMON_JS,
|
K2JsArgumentConstants.MODULE_COMMONJS to ModuleKind.COMMON_JS,
|
||||||
K2JsArgumentConstants.MODULE_AMD to ModuleKind.AMD,
|
K2JsArgumentConstants.MODULE_AMD to ModuleKind.AMD,
|
||||||
K2JsArgumentConstants.MODULE_UMD to ModuleKind.UMD
|
K2JsArgumentConstants.MODULE_UMD to ModuleKind.UMD,
|
||||||
|
K2JsArgumentConstants.MODULE_ES to ModuleKind.ES,
|
||||||
)
|
)
|
||||||
private val sourceMapContentEmbeddingMap = mapOf(
|
private val sourceMapContentEmbeddingMap = mapOf(
|
||||||
K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_ALWAYS to SourceMapSourceEmbedding.ALWAYS,
|
K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_ALWAYS to SourceMapSourceEmbedding.ALWAYS,
|
||||||
|
|||||||
+11
-5
@@ -25,12 +25,18 @@ import org.jetbrains.kotlin.ir.types.isUnit
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
|
||||||
class PropertyAccessorInlineLowering(private val context: CommonBackendContext) : BodyLoweringPass {
|
open class PropertyAccessorInlineLowering(
|
||||||
|
private val context: CommonBackendContext,
|
||||||
|
) : BodyLoweringPass {
|
||||||
|
|
||||||
private val IrProperty.isSafeToInline: Boolean get() = isTopLevel || (modality === Modality.FINAL || visibility == DescriptorVisibilities.PRIVATE) || (parent as IrClass).modality === Modality.FINAL
|
fun IrProperty.isSafeToInlineInClosedWorld() =
|
||||||
|
isTopLevel || (modality === Modality.FINAL || visibility == DescriptorVisibilities.PRIVATE) || (parent as IrClass).modality === Modality.FINAL
|
||||||
|
|
||||||
|
open fun IrProperty.isSafeToInline(accessContainer: IrDeclaration): Boolean =
|
||||||
|
isSafeToInlineInClosedWorld()
|
||||||
|
|
||||||
// TODO: implement general function inlining optimization and replace it with
|
// TODO: implement general function inlining optimization and replace it with
|
||||||
private inner class AccessorInliner : IrElementTransformerVoid() {
|
private inner class AccessorInliner(val container: IrDeclaration) : IrElementTransformerVoid() {
|
||||||
|
|
||||||
private val unitType = context.irBuiltIns.unitType
|
private val unitType = context.irBuiltIns.unitType
|
||||||
|
|
||||||
@@ -38,7 +44,7 @@ class PropertyAccessorInlineLowering(private val context: CommonBackendContext)
|
|||||||
val property = callee.correspondingPropertySymbol?.owner ?: return false
|
val property = callee.correspondingPropertySymbol?.owner ?: return false
|
||||||
|
|
||||||
// Some devirtualization required here
|
// Some devirtualization required here
|
||||||
if (!property.isSafeToInline) return false
|
if (!property.isSafeToInline(container)) return false
|
||||||
|
|
||||||
val parent = property.parent
|
val parent = property.parent
|
||||||
if (parent is IrClass) {
|
if (parent is IrClass) {
|
||||||
@@ -176,6 +182,6 @@ class PropertyAccessorInlineLowering(private val context: CommonBackendContext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
||||||
irBody.transformChildrenVoid(AccessorInliner())
|
irBody.transformChildrenVoid(AccessorInliner(container))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.ir.*
|
import org.jetbrains.kotlin.ir.*
|
||||||
|
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.ir.JsIrBuilder
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.JsInnerClassesSupport
|
import org.jetbrains.kotlin.ir.backend.js.lower.JsInnerClassesSupport
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsInlineClassesUtils
|
import org.jetbrains.kotlin.ir.backend.js.utils.JsInlineClassesUtils
|
||||||
@@ -58,7 +59,8 @@ class JsIrBackendContext(
|
|||||||
val baseClassIntoMetadata: Boolean = false,
|
val baseClassIntoMetadata: Boolean = false,
|
||||||
val safeExternalBoolean: Boolean = false,
|
val safeExternalBoolean: Boolean = false,
|
||||||
val safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null,
|
val safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null,
|
||||||
override val mapping: JsMapping = JsMapping(symbolTable.irFactory)
|
override val mapping: JsMapping = JsMapping(symbolTable.irFactory),
|
||||||
|
val granularity: JsGenerationGranularity = JsGenerationGranularity.WHOLE_PROGRAM,
|
||||||
) : JsCommonBackendContext {
|
) : JsCommonBackendContext {
|
||||||
val fileToInitializationFuns: MutableMap<IrFile, IrSimpleFunction?> = mutableMapOf()
|
val fileToInitializationFuns: MutableMap<IrFile, IrSimpleFunction?> = mutableMapOf()
|
||||||
val fileToInitializerPureness: MutableMap<IrFile, Boolean> = mutableMapOf()
|
val fileToInitializerPureness: MutableMap<IrFile, Boolean> = mutableMapOf()
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.backend.common.lower.optimizations.FoldConstantLower
|
|||||||
import org.jetbrains.kotlin.backend.common.lower.optimizations.PropertyAccessorInlineLowering
|
import org.jetbrains.kotlin.backend.common.lower.optimizations.PropertyAccessorInlineLowering
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.*
|
import org.jetbrains.kotlin.ir.backend.js.lower.*
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.calls.CallsLowering
|
import org.jetbrains.kotlin.ir.backend.js.lower.calls.CallsLowering
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.cleanup.CleanupLowering
|
import org.jetbrains.kotlin.ir.backend.js.lower.cleanup.CleanupLowering
|
||||||
@@ -397,7 +398,7 @@ private val removeInitializersForLazyProperties = makeDeclarationTransformerPhas
|
|||||||
)
|
)
|
||||||
|
|
||||||
private val propertyAccessorInlinerLoweringPhase = makeBodyLoweringPhase(
|
private val propertyAccessorInlinerLoweringPhase = makeBodyLoweringPhase(
|
||||||
::PropertyAccessorInlineLowering,
|
::JsPropertyAccessorInlineLowering,
|
||||||
name = "PropertyAccessorInlineLowering",
|
name = "PropertyAccessorInlineLowering",
|
||||||
description = "[Optimization] Inline property accessors"
|
description = "[Optimization] Inline property accessors"
|
||||||
)
|
)
|
||||||
@@ -775,6 +776,14 @@ private val cleanupLoweringPhase = makeBodyLoweringPhase(
|
|||||||
name = "CleanupLowering",
|
name = "CleanupLowering",
|
||||||
description = "Clean up IR before codegen"
|
description = "Clean up IR before codegen"
|
||||||
)
|
)
|
||||||
|
private val moveOpenClassesToSeparatePlaceLowering = makeCustomJsModulePhase(
|
||||||
|
{ context, module ->
|
||||||
|
if (context.granularity == JsGenerationGranularity.PER_FILE)
|
||||||
|
moveOpenClassesToSeparateFiles(module)
|
||||||
|
},
|
||||||
|
name = "MoveOpenClassesToSeparateFiles",
|
||||||
|
description = "Move open classes to separate files"
|
||||||
|
).toModuleLowering()
|
||||||
|
|
||||||
private val jsSuspendArityStorePhase = makeDeclarationTransformerPhase(
|
private val jsSuspendArityStorePhase = makeDeclarationTransformerPhase(
|
||||||
::JsSuspendArityStoreLowering,
|
::JsSuspendArityStoreLowering,
|
||||||
@@ -880,6 +889,9 @@ private val loweringList = listOf<Lowering>(
|
|||||||
captureStackTraceInThrowablesPhase,
|
captureStackTraceInThrowablesPhase,
|
||||||
callsLoweringPhase,
|
callsLoweringPhase,
|
||||||
cleanupLoweringPhase,
|
cleanupLoweringPhase,
|
||||||
|
// Currently broken due to static members lowering making single-open-class
|
||||||
|
// files non-recognizable as single-class files
|
||||||
|
// moveOpenClassesToSeparatePlaceLowering,
|
||||||
validateIrAfterLowering,
|
validateIrAfterLowering,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,457 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.codegen
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.LoweredIr
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity.*
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.export.*
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.lower.StaticMembersLowering
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrFileToJsTransformer
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.processClassModels
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||||
|
import org.jetbrains.kotlin.ir.util.file
|
||||||
|
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||||
|
import org.jetbrains.kotlin.ir.util.hasInterfaceParent
|
||||||
|
import org.jetbrains.kotlin.ir.util.isInterface
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
interface CompilerOutputSink {
|
||||||
|
fun write(module: String, path: String, content: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
class JsGenerationOptions(
|
||||||
|
val jsExtension: String = "js",
|
||||||
|
val generatePackageJson: Boolean = false,
|
||||||
|
val generateTypeScriptDefinitions: Boolean = false,
|
||||||
|
)
|
||||||
|
|
||||||
|
class IrToJs(
|
||||||
|
private val backendContext: JsIrBackendContext,
|
||||||
|
private val guid: (IrDeclaration) -> String,
|
||||||
|
private val outputSink: CompilerOutputSink,
|
||||||
|
private val mainArguments: List<String>?,
|
||||||
|
private val granularity: JsGenerationGranularity,
|
||||||
|
private val mainModuleName: String,
|
||||||
|
private val options: JsGenerationOptions,
|
||||||
|
) {
|
||||||
|
val indexFileName = "index.${options.jsExtension}"
|
||||||
|
|
||||||
|
val FileUnit.initFunctionName
|
||||||
|
get() = "KotlinInit$" + sanitizeName(pathToJsModule(file))
|
||||||
|
|
||||||
|
sealed class CodegenUnitReference
|
||||||
|
object ThisUnitReference : CodegenUnitReference()
|
||||||
|
inner class OtherUnitReference(
|
||||||
|
module: IrModuleFragment,
|
||||||
|
) : CodegenUnitReference() {
|
||||||
|
// Path to entry point of other module from "top-level", e.g. directory which contains all other modules
|
||||||
|
val importPath = "./" + module.jsModuleName + "/" + indexFileName
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CodegenUnit {
|
||||||
|
abstract val packageFragments: Iterable<IrPackageFragment>
|
||||||
|
abstract val externalPackageFragments: Iterable<IrPackageFragment>
|
||||||
|
abstract fun referenceCodegenUnitOfDeclaration(declaration: IrDeclaration): CodegenUnitReference
|
||||||
|
abstract val pathToKotlinModulesRoot: String
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class FileUnit(val file: IrFile, val externalFile: IrFile?) : CodegenUnit() {
|
||||||
|
override val packageFragments =
|
||||||
|
listOf(file)
|
||||||
|
|
||||||
|
override val externalPackageFragments =
|
||||||
|
listOfNotNull(externalFile)
|
||||||
|
|
||||||
|
override fun referenceCodegenUnitOfDeclaration(declaration: IrDeclaration): CodegenUnitReference =
|
||||||
|
when (val declarationFile = declaration.file) {
|
||||||
|
file -> ThisUnitReference
|
||||||
|
else -> OtherUnitReference(declarationFile.module)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val pathToKotlinModulesRoot: String by lazy {
|
||||||
|
"../".repeat(file.fqName.pathSegments().size + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class ModuleUnit(val module: IrModuleFragment) : CodegenUnit() {
|
||||||
|
override val packageFragments: Iterable<IrPackageFragment> =
|
||||||
|
module.files
|
||||||
|
|
||||||
|
override val externalPackageFragments: Iterable<IrPackageFragment> =
|
||||||
|
packageFragments.mapNotNull { backendContext.externalPackageFragment[it.symbol] }
|
||||||
|
|
||||||
|
override fun referenceCodegenUnitOfDeclaration(declaration: IrDeclaration): CodegenUnitReference =
|
||||||
|
when (val declarationModule = declaration.file.module) {
|
||||||
|
module -> ThisUnitReference
|
||||||
|
else -> OtherUnitReference(declarationModule)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val pathToKotlinModulesRoot: String = "../"
|
||||||
|
}
|
||||||
|
|
||||||
|
class WholeProgramUnit(
|
||||||
|
val modules: Iterable<IrModuleFragment>,
|
||||||
|
val externalModules: Iterable<IrPackageFragment>
|
||||||
|
) : CodegenUnit() {
|
||||||
|
override val packageFragments: Iterable<IrPackageFragment> =
|
||||||
|
modules.flatMap { it.files }
|
||||||
|
|
||||||
|
override val externalPackageFragments: Iterable<IrPackageFragment>
|
||||||
|
get() = externalModules
|
||||||
|
|
||||||
|
override fun referenceCodegenUnitOfDeclaration(declaration: IrDeclaration): CodegenUnitReference =
|
||||||
|
ThisUnitReference
|
||||||
|
|
||||||
|
override val pathToKotlinModulesRoot: String
|
||||||
|
get() = "../"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pathToJsModule(file: IrFile): String =
|
||||||
|
"${fileJsRootModuleName(file)}/${fileJsSubModulePath(file)}"
|
||||||
|
|
||||||
|
private fun fileJsRootModuleName(file: IrFile): String =
|
||||||
|
when (granularity) {
|
||||||
|
WHOLE_PROGRAM -> mainModuleName
|
||||||
|
PER_MODULE, PER_FILE -> file.module.jsModuleName
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fileJsSubModulePath(file: IrFile): String =
|
||||||
|
when (granularity) {
|
||||||
|
WHOLE_PROGRAM, PER_MODULE -> indexFileName
|
||||||
|
|
||||||
|
PER_FILE -> {
|
||||||
|
val maybeSingleOpenClass = (file.declarations.singleOrNull() as? IrClass)?.takeIf {
|
||||||
|
it.modality == Modality.ABSTRACT || it.modality == Modality.OPEN
|
||||||
|
}
|
||||||
|
|
||||||
|
val hash = abs((maybeSingleOpenClass?.let { guid(it) } ?: file.path).hashCode())
|
||||||
|
val filePrefix = maybeSingleOpenClass?.name?.asString()?.let { sanitizeName(it) + ".class" } ?: file.name
|
||||||
|
val fileName = "${filePrefix}_$hash.${options.jsExtension}"
|
||||||
|
val packagePath = file.fqName.pathSegments().joinToString("") { it.identifier + "/" }
|
||||||
|
"$packagePath$fileName"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GeneratedUnit(
|
||||||
|
val jsStatements: List<JsStatement>,
|
||||||
|
val exportedDeclarations: List<ExportedDeclaration>,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun generateUnit(unit: CodegenUnit): GeneratedUnit {
|
||||||
|
val exportedDeclarations: List<ExportedDeclaration> =
|
||||||
|
with(ExportModelGenerator(backendContext, generateNamespacesForPackages = false)) {
|
||||||
|
(unit.externalPackageFragments + unit.packageFragments).flatMap { packageFragment ->
|
||||||
|
generateExport(packageFragment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val stableNames: Set<String> = collectStableNames(unit)
|
||||||
|
val nameGenerator = NewNamerImpl(backendContext, unit, guid, stableNames)
|
||||||
|
|
||||||
|
val staticContext = JsStaticContext(
|
||||||
|
backendContext = backendContext,
|
||||||
|
irNamer = nameGenerator,
|
||||||
|
globalNameScope = nameGenerator.staticNames
|
||||||
|
)
|
||||||
|
|
||||||
|
val rootContext = JsGenerationContext(
|
||||||
|
currentFunction = null,
|
||||||
|
currentFile = null,
|
||||||
|
staticContext = staticContext,
|
||||||
|
localNames = LocalNameGenerator(NameTable())
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val declarationStatements: List<JsStatement> = unit.packageFragments.flatMap {
|
||||||
|
StaticMembersLowering(backendContext).lower(it as IrFile)
|
||||||
|
it.accept(IrFileToJsTransformer(), rootContext).statements
|
||||||
|
}
|
||||||
|
|
||||||
|
val preDeclarationBlock = JsGlobalBlock()
|
||||||
|
val postDeclarationBlock = JsGlobalBlock()
|
||||||
|
processClassModels(rootContext.staticContext.classModels, preDeclarationBlock, postDeclarationBlock)
|
||||||
|
|
||||||
|
val statements = mutableListOf<JsStatement>()
|
||||||
|
statements += nameGenerator.internalImports.values
|
||||||
|
statements += preDeclarationBlock
|
||||||
|
statements += declarationStatements
|
||||||
|
statements += postDeclarationBlock
|
||||||
|
|
||||||
|
// Generate module initialization
|
||||||
|
|
||||||
|
val initializerBlock = rootContext.staticContext.initializerBlock
|
||||||
|
when (unit) {
|
||||||
|
is WholeProgramUnit, is ModuleUnit -> {
|
||||||
|
// Run initialization during ES module initialization
|
||||||
|
statements += initializerBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
is FileUnit -> {
|
||||||
|
// Postpone initialization by putting it into a separate function
|
||||||
|
// Will be called later in proper order after class model is initialized
|
||||||
|
val initFunction = JsFunction(emptyScope, JsBlock(initializerBlock.statements), "init fun")
|
||||||
|
initFunction.name = JsName(unit.initFunctionName)
|
||||||
|
statements += initFunction.makeStmt()
|
||||||
|
statements += JsExport(initFunction.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate internal export
|
||||||
|
|
||||||
|
val internalExports = mutableListOf<JsExport.Element>()
|
||||||
|
fun export(declaration: IrDeclarationWithName) {
|
||||||
|
internalExports += JsExport.Element(nameGenerator.getNameForStaticDeclaration(declaration), JsName(guid(declaration)))
|
||||||
|
}
|
||||||
|
|
||||||
|
for (fragment in unit.packageFragments) {
|
||||||
|
for (declaration in fragment.declarations) {
|
||||||
|
if (declaration is IrDeclarationWithName) {
|
||||||
|
export(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default implementations of interface methods are nested under interface declarations in IR at this point,
|
||||||
|
// but they are effectively used as a static declaration and can be directly referenced by other codegen unit,
|
||||||
|
// thus requiring internal export
|
||||||
|
declaration.acceptChildrenVoid(object : IrElementVisitorVoid {
|
||||||
|
override fun visitElement(element: IrElement) {
|
||||||
|
element.acceptChildrenVoid(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSimpleFunction(declaration: IrSimpleFunction) {
|
||||||
|
if (declaration.hasInterfaceParent() && declaration.body != null) {
|
||||||
|
export(declaration)
|
||||||
|
}
|
||||||
|
super.visitSimpleFunction(declaration)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statements += JsExport(JsExport.Subject.Elements(internalExports), null)
|
||||||
|
|
||||||
|
// Generate external export
|
||||||
|
|
||||||
|
val globalNames = NameTable<String>(nameGenerator.staticNames)
|
||||||
|
val exporter = ExportModelToJsStatements(
|
||||||
|
nameGenerator,
|
||||||
|
declareNewNamespace = { globalNames.declareFreshName(it, it) }
|
||||||
|
)
|
||||||
|
exportedDeclarations.forEach {
|
||||||
|
statements += exporter.generateDeclarationExport(it, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
return GeneratedUnit(statements, exportedDeclarations)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectStableNames(unit: CodegenUnit): Set<String> {
|
||||||
|
val newStableStaticNamesCollectorVisitor =
|
||||||
|
NewStableStaticNamesCollectorVisitor(needToCollectReferences = granularity != WHOLE_PROGRAM)
|
||||||
|
unit.packageFragments.forEach { it.acceptVoid(newStableStaticNamesCollectorVisitor) }
|
||||||
|
unit.externalPackageFragments.forEach { it.acceptVoid(newStableStaticNamesCollectorVisitor) }
|
||||||
|
|
||||||
|
return newStableStaticNamesCollectorVisitor.collectedStableNames
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns import statement and call expression
|
||||||
|
private fun invokeFunctionFromEntryJsFile(
|
||||||
|
function: IrFunction,
|
||||||
|
args: List<JsExpression> = emptyList()
|
||||||
|
): Pair<JsStatement, JsExpression> {
|
||||||
|
val name = guid(function)
|
||||||
|
val importPath = if (granularity == WHOLE_PROGRAM) "./$indexFileName" else "../" + pathToJsModule(function.file)
|
||||||
|
return Pair(
|
||||||
|
JsImport(importPath, mutableListOf(JsImport.Element(name, null))),
|
||||||
|
JsInvocation(JsNameRef(name), args)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun invokeFunctionFromEntryJsFileAsStatements(
|
||||||
|
function: IrFunction,
|
||||||
|
args: List<JsExpression> = emptyList()
|
||||||
|
): List<JsStatement> =
|
||||||
|
invokeFunctionFromEntryJsFile(function, args)
|
||||||
|
.let { listOf(it.first, it.second.makeStmt()) }
|
||||||
|
|
||||||
|
fun generateModules(
|
||||||
|
mainModule: IrModuleFragment,
|
||||||
|
allModules: List<IrModuleFragment>
|
||||||
|
) {
|
||||||
|
when (granularity) {
|
||||||
|
WHOLE_PROGRAM ->
|
||||||
|
generateModule(mainModule, allModules)
|
||||||
|
|
||||||
|
PER_MODULE,
|
||||||
|
PER_FILE ->
|
||||||
|
allModules.forEach { module ->
|
||||||
|
generateModule(mainModule = module, allModules = emptyList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateModuleLevelCode(module: IrModuleFragment, statements: MutableList<JsStatement>) {
|
||||||
|
if (mainArguments != null) {
|
||||||
|
val mainFunction = JsMainFunctionDetector(backendContext).getMainFunctionOrNull(module)
|
||||||
|
if (mainFunction != null) {
|
||||||
|
val generateArgv = mainFunction.valueParameters.firstOrNull()?.isStringArrayParameter() ?: false
|
||||||
|
val generateContinuation = mainFunction.isLoweredSuspendFunction(backendContext)
|
||||||
|
|
||||||
|
val mainArgumentsArray =
|
||||||
|
if (generateArgv)
|
||||||
|
JsArrayLiteral(mainArguments.map { JsStringLiteral(it) })
|
||||||
|
else
|
||||||
|
null
|
||||||
|
|
||||||
|
val continuation =
|
||||||
|
if (generateContinuation) {
|
||||||
|
val (import, invoke) = invokeFunctionFromEntryJsFile(backendContext.coroutineEmptyContinuation.owner.getter!!)
|
||||||
|
statements += import
|
||||||
|
invoke
|
||||||
|
} else
|
||||||
|
null
|
||||||
|
|
||||||
|
statements += invokeFunctionFromEntryJsFileAsStatements(
|
||||||
|
mainFunction, listOfNotNull(mainArgumentsArray, continuation)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backendContext.testRoots[module]?.let { testContainer ->
|
||||||
|
statements += invokeFunctionFromEntryJsFileAsStatements(testContainer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateModule(
|
||||||
|
mainModule: IrModuleFragment,
|
||||||
|
allModules: List<IrModuleFragment>,
|
||||||
|
) {
|
||||||
|
val moduleName = mainModule.jsModuleName
|
||||||
|
val indexJsStatements = mutableListOf<JsStatement>()
|
||||||
|
val exportedDeclarations = mutableListOf<ExportedDeclaration>()
|
||||||
|
|
||||||
|
when (granularity) {
|
||||||
|
PER_FILE -> {
|
||||||
|
for (file in mainModule.files.sortedBy(::fileInitOrder)) {
|
||||||
|
if (file.declarations.isEmpty()) continue
|
||||||
|
|
||||||
|
val pathToSubModule = fileJsSubModulePath(file)
|
||||||
|
indexJsStatements += JsExport(JsExport.Subject.All, fromModule = "./$pathToSubModule")
|
||||||
|
|
||||||
|
val unit = FileUnit(file, backendContext.externalPackageFragment[file.symbol])
|
||||||
|
val generatedUnit = generateUnit(unit)
|
||||||
|
|
||||||
|
val importElements = JsImport.Element(unit.initFunctionName, null)
|
||||||
|
indexJsStatements += JsImport("./$pathToSubModule", mutableListOf(importElements))
|
||||||
|
indexJsStatements += JsInvocation(JsNameRef(JsName(unit.initFunctionName))).makeStmt()
|
||||||
|
|
||||||
|
exportedDeclarations += generatedUnit.exportedDeclarations
|
||||||
|
|
||||||
|
outputSink.write(
|
||||||
|
file.module.jsModuleName,
|
||||||
|
pathToSubModule,
|
||||||
|
"// Kotlin file: ${file.path}\n" + generatedUnit.jsStatements.toJsCodeString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
generateModuleLevelCode(mainModule, indexJsStatements)
|
||||||
|
}
|
||||||
|
|
||||||
|
PER_MODULE -> {
|
||||||
|
val generatedUnit = generateUnit(ModuleUnit(mainModule))
|
||||||
|
indexJsStatements += generatedUnit.jsStatements
|
||||||
|
generateModuleLevelCode(mainModule, indexJsStatements)
|
||||||
|
exportedDeclarations += generatedUnit.exportedDeclarations
|
||||||
|
}
|
||||||
|
|
||||||
|
WHOLE_PROGRAM -> {
|
||||||
|
val generatedUnit = generateUnit(WholeProgramUnit(allModules, backendContext.externalPackageFragment.values))
|
||||||
|
indexJsStatements += generatedUnit.jsStatements
|
||||||
|
allModules.forEach {
|
||||||
|
generateModuleLevelCode(it, indexJsStatements)
|
||||||
|
}
|
||||||
|
exportedDeclarations += generatedUnit.exportedDeclarations
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outputSink.write(moduleName, indexFileName, indexJsStatements.toJsCodeString())
|
||||||
|
|
||||||
|
if (options.generatePackageJson) {
|
||||||
|
outputSink.write(moduleName, "package.json", """{ "main": "$indexFileName", "type": "module" }""")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.generateTypeScriptDefinitions && exportedDeclarations.isNotEmpty()) {
|
||||||
|
val dts = ExportedModule(moduleName, moduleKind = ModuleKind.ES, exportedDeclarations).toTypeScript()
|
||||||
|
outputSink.write(moduleName, "index.d.ts", dts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fileInitOrder(file: IrFile): Int =
|
||||||
|
when (val singleDeclaration = file.declarations.singleOrNull()) {
|
||||||
|
// Initialize parent classes before child classes
|
||||||
|
// TODO: Comment about open classes in separate files
|
||||||
|
is IrClass -> singleDeclaration.getInheritanceChainLength()
|
||||||
|
// Initialize regular files after all open classes
|
||||||
|
else -> Int.MAX_VALUE
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrClass.getInheritanceChainLength(): Int {
|
||||||
|
if (symbol == backendContext.irBuiltIns.anyClass)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
// FIXME: Filter out interfaces
|
||||||
|
superTypes.forEach { superType ->
|
||||||
|
val superClass: IrClass? = superType.classOrNull?.owner
|
||||||
|
if (superClass != null && /* !!! */ !superClass.isInterface)
|
||||||
|
return superClass.getInheritanceChainLength() + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val IrModuleFragment.jsModuleName: String
|
||||||
|
get() = name.asString().dropWhile { it == '<' }.dropLastWhile { it == '>' }
|
||||||
|
|
||||||
|
private fun List<JsStatement>.toJsCodeString(): String =
|
||||||
|
JsGlobalBlock().also { it.statements += this }.toString()
|
||||||
|
|
||||||
|
enum class JsGenerationGranularity {
|
||||||
|
WHOLE_PROGRAM,
|
||||||
|
PER_MODULE,
|
||||||
|
PER_FILE
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateEsModules(
|
||||||
|
ir: LoweredIr,
|
||||||
|
outputSink: CompilerOutputSink,
|
||||||
|
mainArguments: List<String>?,
|
||||||
|
granularity: JsGenerationGranularity,
|
||||||
|
options: JsGenerationOptions,
|
||||||
|
) {
|
||||||
|
// Declaration numeration to create temporary GUID
|
||||||
|
// TODO: Replace with an actual GUID
|
||||||
|
val numerator = StaticDeclarationNumerator()
|
||||||
|
ir.allModules.forEach { numerator.add(it) }
|
||||||
|
|
||||||
|
fun guid(declaration: IrDeclaration): String {
|
||||||
|
val name = sanitizeName((declaration as IrDeclarationWithName).name.toString())
|
||||||
|
val number = numerator.numeration[declaration]
|
||||||
|
?: error("Can't find number for declaration ${declaration.fqNameWhenAvailable}")
|
||||||
|
// TODO: Use shorter names in release mode
|
||||||
|
return "${name}_GUID_${number}"
|
||||||
|
}
|
||||||
|
|
||||||
|
val ir2js = IrToJs(ir.context, ::guid, outputSink, mainArguments, granularity, ir.mainModule.jsModuleName, options)
|
||||||
|
ir2js.generateModules(ir.mainModule, ir.allModules)
|
||||||
|
}
|
||||||
@@ -8,6 +8,9 @@ package org.jetbrains.kotlin.ir.backend.js
|
|||||||
import org.jetbrains.kotlin.backend.common.lower
|
import org.jetbrains.kotlin.backend.common.lower
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||||
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.ic.SerializedIcData
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ic.ModuleCache
|
import org.jetbrains.kotlin.ir.backend.js.ic.ModuleCache
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ic.icCompile
|
import org.jetbrains.kotlin.ir.backend.js.ic.icCompile
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.generateTests
|
import org.jetbrains.kotlin.ir.backend.js.lower.generateTests
|
||||||
@@ -37,39 +40,36 @@ class CompilationOutputs(
|
|||||||
val dependencies: Iterable<Pair<String, CompilationOutputs>> = emptyList()
|
val dependencies: Iterable<Pair<String, CompilationOutputs>> = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class LoweredIr(
|
||||||
|
val context: JsIrBackendContext,
|
||||||
|
val mainModule: IrModuleFragment,
|
||||||
|
val allModules: List<IrModuleFragment>
|
||||||
|
)
|
||||||
|
|
||||||
fun compile(
|
fun compile(
|
||||||
depsDescriptors: ModulesStructure,
|
depsDescriptors: ModulesStructure,
|
||||||
phaseConfig: PhaseConfig,
|
phaseConfig: PhaseConfig,
|
||||||
irFactory: IrFactory,
|
irFactory: IrFactory,
|
||||||
mainArguments: List<String>?,
|
|
||||||
exportedDeclarations: Set<FqName> = emptySet(),
|
exportedDeclarations: Set<FqName> = emptySet(),
|
||||||
generateFullJs: Boolean = true,
|
|
||||||
generateDceJs: Boolean = false,
|
|
||||||
dceDriven: Boolean = false,
|
dceDriven: Boolean = false,
|
||||||
dceRuntimeDiagnostic: RuntimeDiagnostic? = null,
|
dceRuntimeDiagnostic: RuntimeDiagnostic? = null,
|
||||||
es6mode: Boolean = false,
|
es6mode: Boolean = false,
|
||||||
multiModule: Boolean = false,
|
|
||||||
relativeRequirePath: Boolean = false,
|
|
||||||
propertyLazyInitialization: Boolean,
|
propertyLazyInitialization: Boolean,
|
||||||
verifySignatures: Boolean = true,
|
verifySignatures: Boolean = true,
|
||||||
baseClassIntoMetadata: Boolean = false,
|
baseClassIntoMetadata: Boolean = false,
|
||||||
lowerPerModule: Boolean = false,
|
lowerPerModule: Boolean = false,
|
||||||
safeExternalBoolean: Boolean = false,
|
safeExternalBoolean: Boolean = false,
|
||||||
safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null,
|
safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null,
|
||||||
filesToLower: Set<String>? = null
|
filesToLower: Set<String>? = null,
|
||||||
): CompilerResult {
|
granularity: JsGenerationGranularity = JsGenerationGranularity.WHOLE_PROGRAM,
|
||||||
|
): LoweredIr {
|
||||||
|
|
||||||
if (lowerPerModule) {
|
if (lowerPerModule) {
|
||||||
return icCompile(
|
return icCompile(
|
||||||
depsDescriptors,
|
depsDescriptors,
|
||||||
mainArguments,
|
|
||||||
exportedDeclarations,
|
exportedDeclarations,
|
||||||
generateFullJs,
|
|
||||||
generateDceJs,
|
|
||||||
dceRuntimeDiagnostic,
|
dceRuntimeDiagnostic,
|
||||||
es6mode,
|
es6mode,
|
||||||
multiModule,
|
|
||||||
relativeRequirePath,
|
|
||||||
propertyLazyInitialization,
|
propertyLazyInitialization,
|
||||||
baseClassIntoMetadata,
|
baseClassIntoMetadata,
|
||||||
safeExternalBoolean,
|
safeExternalBoolean,
|
||||||
@@ -77,7 +77,7 @@ fun compile(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val (moduleFragment: IrModuleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer, moduleToName) =
|
val (moduleFragment: IrModuleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer, _) =
|
||||||
loadIr(depsDescriptors, irFactory, verifySignatures, filesToLower, loadFunctionInterfacesIntoStdlib = true)
|
loadIr(depsDescriptors, irFactory, verifySignatures, filesToLower, loadFunctionInterfacesIntoStdlib = true)
|
||||||
|
|
||||||
val mainModule = depsDescriptors.mainModule
|
val mainModule = depsDescriptors.mainModule
|
||||||
@@ -102,7 +102,8 @@ fun compile(
|
|||||||
propertyLazyInitialization = propertyLazyInitialization,
|
propertyLazyInitialization = propertyLazyInitialization,
|
||||||
baseClassIntoMetadata = baseClassIntoMetadata,
|
baseClassIntoMetadata = baseClassIntoMetadata,
|
||||||
safeExternalBoolean = safeExternalBoolean,
|
safeExternalBoolean = safeExternalBoolean,
|
||||||
safeExternalBooleanDiagnostic = safeExternalBooleanDiagnostic
|
safeExternalBooleanDiagnostic = safeExternalBooleanDiagnostic,
|
||||||
|
granularity = granularity
|
||||||
)
|
)
|
||||||
|
|
||||||
// Load declarations referenced during `context` initialization
|
// Load declarations referenced during `context` initialization
|
||||||
@@ -130,17 +131,6 @@ fun compile(
|
|||||||
eliminateDeadDeclarations(allModules, context)
|
eliminateDeadDeclarations(allModules, context)
|
||||||
|
|
||||||
irFactory.stageController = StageController(controller.currentStage)
|
irFactory.stageController = StageController(controller.currentStage)
|
||||||
|
|
||||||
val transformer = IrModuleToJsTransformer(
|
|
||||||
context,
|
|
||||||
mainArguments,
|
|
||||||
fullJs = true,
|
|
||||||
dceJs = false,
|
|
||||||
multiModule = multiModule,
|
|
||||||
relativeRequirePath = relativeRequirePath,
|
|
||||||
moduleToName = moduleToName,
|
|
||||||
)
|
|
||||||
return transformer.generateModule(allModules)
|
|
||||||
} else {
|
} else {
|
||||||
// TODO is this reachable when lowerPerModule == true?
|
// TODO is this reachable when lowerPerModule == true?
|
||||||
if (lowerPerModule) {
|
if (lowerPerModule) {
|
||||||
@@ -154,18 +144,9 @@ fun compile(
|
|||||||
} else {
|
} else {
|
||||||
jsPhases.invokeToplevel(phaseConfig, context, allModules)
|
jsPhases.invokeToplevel(phaseConfig, context, allModules)
|
||||||
}
|
}
|
||||||
|
|
||||||
val transformer = IrModuleToJsTransformer(
|
|
||||||
context,
|
|
||||||
mainArguments,
|
|
||||||
fullJs = generateFullJs,
|
|
||||||
dceJs = generateDceJs,
|
|
||||||
multiModule = multiModule,
|
|
||||||
relativeRequirePath = relativeRequirePath,
|
|
||||||
moduleToName = moduleToName,
|
|
||||||
)
|
|
||||||
return transformer.generateModule(allModules)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return LoweredIr(context, moduleFragment, allModules)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun lowerPreservingIcData(module: IrModuleFragment, context: JsIrBackendContext, controller: WholeWorldStageController) {
|
fun lowerPreservingIcData(module: IrModuleFragment, context: JsIrBackendContext, controller: WholeWorldStageController) {
|
||||||
|
|||||||
+9
-5
@@ -26,24 +26,28 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
|||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
class ExportModelGenerator(val context: JsIrBackendContext) {
|
class ExportModelGenerator(
|
||||||
|
val context: JsIrBackendContext,
|
||||||
|
val generateNamespacesForPackages: Boolean
|
||||||
|
) {
|
||||||
|
|
||||||
fun generateExport(file: IrPackageFragment): List<ExportedDeclaration> {
|
fun generateExport(file: IrPackageFragment): List<ExportedDeclaration> {
|
||||||
val namespaceFqName = file.fqName
|
val namespaceFqName = file.fqName
|
||||||
val exports = file.declarations.flatMap { declaration -> listOfNotNull(exportDeclaration(declaration)) }
|
val exports = file.declarations.flatMap { declaration -> listOfNotNull(exportDeclaration(declaration)) }
|
||||||
return when {
|
return when {
|
||||||
exports.isEmpty() -> emptyList()
|
exports.isEmpty() -> emptyList()
|
||||||
namespaceFqName.isRoot -> exports
|
!generateNamespacesForPackages || namespaceFqName.isRoot -> exports
|
||||||
else -> listOf(ExportedNamespace(namespaceFqName.toString(), exports))
|
else -> listOf(ExportedNamespace(namespaceFqName.toString(), exports))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateExport(modules: Iterable<IrModuleFragment>): ExportedModule =
|
fun generateExport(modules: Iterable<IrModuleFragment>, moduleKind: ModuleKind = ModuleKind.PLAIN): ExportedModule =
|
||||||
ExportedModule(
|
ExportedModule(
|
||||||
context.configuration[CommonConfigurationKeys.MODULE_NAME]!!,
|
context.configuration[CommonConfigurationKeys.MODULE_NAME]!!,
|
||||||
context.configuration[JSConfigurationKeys.MODULE_KIND]!!,
|
moduleKind,
|
||||||
(context.externalPackageFragment.values + modules.flatMap { it.files }).flatMap {
|
(context.externalPackageFragment.values + modules.flatMap { it.files }).flatMap {
|
||||||
generateExport(it)
|
generateExport(it)
|
||||||
}
|
}
|
||||||
@@ -296,7 +300,7 @@ class ExportModelGenerator(val context: JsIrBackendContext) {
|
|||||||
|
|
||||||
classifier is IrClassSymbol -> {
|
classifier is IrClassSymbol -> {
|
||||||
val klass = classifier.owner
|
val klass = classifier.owner
|
||||||
val name = klass.fqNameWhenAvailable!!.asString()
|
val name = if (generateNamespacesForPackages) klass.fqNameWhenAvailable!!.asString() else klass.name.asString()
|
||||||
|
|
||||||
when (klass.kind) {
|
when (klass.kind) {
|
||||||
ClassKind.ANNOTATION_CLASS,
|
ClassKind.ANNOTATION_CLASS,
|
||||||
|
|||||||
+35
-27
@@ -11,25 +11,24 @@ import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.jsAssignment
|
|||||||
import org.jetbrains.kotlin.ir.backend.js.utils.IrNamer
|
import org.jetbrains.kotlin.ir.backend.js.utils.IrNamer
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
|
|
||||||
|
|
||||||
class ExportModelToJsStatements(
|
class ExportModelToJsStatements(
|
||||||
private val internalModuleName: JsName,
|
|
||||||
private val namer: IrNamer,
|
private val namer: IrNamer,
|
||||||
private val declareNewNamespace: (String) -> String
|
private val declareNewNamespace: (String) -> String
|
||||||
) {
|
) {
|
||||||
private val namespaceToRefMap = mutableMapOf<String, JsNameRef>()
|
private val namespaceToRefMap = mutableMapOf<String, JsNameRef>()
|
||||||
|
|
||||||
fun generateModuleExport(module: ExportedModule): List<JsStatement> {
|
fun generateModuleExport(module: ExportedModule, internalModuleName: JsName): List<JsStatement> {
|
||||||
return module.declarations.flatMap { generateDeclarationExport(it, JsNameRef(internalModuleName)) }
|
return module.declarations.flatMap { generateDeclarationExport(it, JsNameRef(internalModuleName)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateDeclarationExport(declaration: ExportedDeclaration, namespace: JsNameRef): List<JsStatement> {
|
fun generateDeclarationExport(declaration: ExportedDeclaration, namespace: JsNameRef?): List<JsStatement> {
|
||||||
return when (declaration) {
|
return when (declaration) {
|
||||||
is ExportedNamespace -> {
|
is ExportedNamespace -> {
|
||||||
|
require(namespace != null) { "Only namespaced namespaces are allowed" }
|
||||||
val statements = mutableListOf<JsStatement>()
|
val statements = mutableListOf<JsStatement>()
|
||||||
val elements = declaration.name.split(".")
|
val elements = declaration.name.split(".")
|
||||||
var currentNamespace = ""
|
var currentNamespace = ""
|
||||||
var currentRef = namespace
|
var currentRef: JsNameRef = namespace
|
||||||
for (element in elements) {
|
for (element in elements) {
|
||||||
val newNamespace = "$currentNamespace$$element"
|
val newNamespace = "$currentNamespace$$element"
|
||||||
val newNameSpaceRef = namespaceToRefMap.getOrPut(newNamespace) {
|
val newNameSpaceRef = namespaceToRefMap.getOrPut(newNamespace) {
|
||||||
@@ -37,14 +36,15 @@ class ExportModelToJsStatements(
|
|||||||
val varRef = JsNameRef(varName)
|
val varRef = JsNameRef(varName)
|
||||||
val namespaceRef = JsNameRef(element, currentRef)
|
val namespaceRef = JsNameRef(element, currentRef)
|
||||||
statements += JsVars(
|
statements += JsVars(
|
||||||
JsVars.JsVar(JsName(varName),
|
JsVars.JsVar(
|
||||||
JsAstUtils.or(
|
JsName(varName),
|
||||||
namespaceRef,
|
JsAstUtils.or(
|
||||||
jsAssignment(
|
namespaceRef,
|
||||||
namespaceRef,
|
jsAssignment(
|
||||||
JsObjectLiteral()
|
namespaceRef,
|
||||||
)
|
JsObjectLiteral()
|
||||||
)
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
varRef
|
varRef
|
||||||
@@ -56,17 +56,23 @@ class ExportModelToJsStatements(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is ExportedFunction -> {
|
is ExportedFunction -> {
|
||||||
listOf(
|
val name = namer.getNameForStaticDeclaration(declaration.ir)
|
||||||
jsAssignment(
|
if (namespace == null) {
|
||||||
JsNameRef(declaration.name, namespace),
|
listOf(JsExport(name, alias = JsName(declaration.name)))
|
||||||
JsNameRef(namer.getNameForStaticDeclaration(declaration.ir))
|
} else {
|
||||||
).makeStmt()
|
listOf(
|
||||||
)
|
jsAssignment(
|
||||||
|
JsNameRef(declaration.name, namespace),
|
||||||
|
JsNameRef(name)
|
||||||
|
).makeStmt()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is ExportedConstructor -> emptyList()
|
is ExportedConstructor -> emptyList()
|
||||||
|
|
||||||
is ExportedProperty -> {
|
is ExportedProperty -> {
|
||||||
|
require(namespace != null) { "Only namespaced properties are allowed" }
|
||||||
val getter = declaration.irGetter?.let { JsNameRef(namer.getNameForStaticDeclaration(it)) }
|
val getter = declaration.irGetter?.let { JsNameRef(namer.getNameForStaticDeclaration(it)) }
|
||||||
val setter = declaration.irSetter?.let { JsNameRef(namer.getNameForStaticDeclaration(it)) }
|
val setter = declaration.irSetter?.let { JsNameRef(namer.getNameForStaticDeclaration(it)) }
|
||||||
listOf(defineProperty(namespace, declaration.name, getter, setter).makeStmt())
|
listOf(defineProperty(namespace, declaration.name, getter, setter).makeStmt())
|
||||||
@@ -77,14 +83,16 @@ class ExportModelToJsStatements(
|
|||||||
is ExportedClass -> {
|
is ExportedClass -> {
|
||||||
if (declaration.isInterface) return emptyList()
|
if (declaration.isInterface) return emptyList()
|
||||||
val newNameSpace = JsNameRef(declaration.name, namespace)
|
val newNameSpace = JsNameRef(declaration.name, namespace)
|
||||||
val klassExport = jsAssignment(
|
val name = namer.getNameForStaticDeclaration(declaration.ir)
|
||||||
newNameSpace,
|
val klassExport =
|
||||||
JsNameRef(
|
if (namespace == null) {
|
||||||
namer.getNameForStaticDeclaration(
|
JsExport(name, alias = JsName(declaration.name))
|
||||||
declaration.ir
|
} else {
|
||||||
)
|
jsAssignment(
|
||||||
)
|
newNameSpace,
|
||||||
).makeStmt()
|
JsNameRef(name)
|
||||||
|
).makeStmt()
|
||||||
|
}
|
||||||
|
|
||||||
// These are only used when exporting secondary constructors annotated with @JsName
|
// These are only used when exporting secondary constructors annotated with @JsName
|
||||||
val staticFunctions = declaration.members.filter { it is ExportedFunction && it.isStatic }
|
val staticFunctions = declaration.members.filter { it is ExportedFunction && it.isStatic }
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ fun ExportedModule.toTypeScript(): String {
|
|||||||
|
|
||||||
return when (moduleKind) {
|
return when (moduleKind) {
|
||||||
ModuleKind.PLAIN -> "declare namespace $namespaceName {\n$declarationsDts\n}\n"
|
ModuleKind.PLAIN -> "declare namespace $namespaceName {\n$declarationsDts\n}\n"
|
||||||
ModuleKind.AMD, ModuleKind.COMMON_JS -> declarationsDts
|
ModuleKind.AMD, ModuleKind.COMMON_JS, ModuleKind.ES -> declarationsDts
|
||||||
ModuleKind.UMD -> "$declarationsDts\nexport as namespace $namespaceName;"
|
ModuleKind.UMD -> "$declarationsDts\nexport as namespace $namespaceName;"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,25 +123,20 @@ private fun dumpIr(module: IrModuleFragment, fileName: String) {
|
|||||||
|
|
||||||
fun icCompile(
|
fun icCompile(
|
||||||
depsDescriptor: ModulesStructure,
|
depsDescriptor: ModulesStructure,
|
||||||
mainArguments: List<String>?,
|
|
||||||
exportedDeclarations: Set<FqName> = emptySet(),
|
exportedDeclarations: Set<FqName> = emptySet(),
|
||||||
generateFullJs: Boolean = true,
|
|
||||||
generateDceJs: Boolean = false,
|
|
||||||
dceRuntimeDiagnostic: RuntimeDiagnostic? = null,
|
dceRuntimeDiagnostic: RuntimeDiagnostic? = null,
|
||||||
es6mode: Boolean = false,
|
es6mode: Boolean = false,
|
||||||
multiModule: Boolean = false,
|
|
||||||
relativeRequirePath: Boolean = false,
|
|
||||||
propertyLazyInitialization: Boolean,
|
propertyLazyInitialization: Boolean,
|
||||||
baseClassIntoMetadata: Boolean = false,
|
baseClassIntoMetadata: Boolean = false,
|
||||||
safeExternalBoolean: Boolean = false,
|
safeExternalBoolean: Boolean = false,
|
||||||
safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null,
|
safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null,
|
||||||
): CompilerResult {
|
): LoweredIr {
|
||||||
|
|
||||||
val irFactory = PersistentIrFactory()
|
val irFactory = PersistentIrFactory()
|
||||||
val controller = WholeWorldStageController()
|
val controller = WholeWorldStageController()
|
||||||
irFactory.stageController = controller
|
irFactory.stageController = controller
|
||||||
|
|
||||||
val (context, _, allModules, moduleToName, loweredIrLoaded) = prepareIr(
|
val (context, _, allModules, _, loweredIrLoaded) = prepareIr(
|
||||||
depsDescriptor,
|
depsDescriptor,
|
||||||
exportedDeclarations,
|
exportedDeclarations,
|
||||||
dceRuntimeDiagnostic,
|
dceRuntimeDiagnostic,
|
||||||
@@ -155,8 +150,6 @@ fun icCompile(
|
|||||||
|
|
||||||
val modulesToLower = allModules.filter { it !in loweredIrLoaded }
|
val modulesToLower = allModules.filter { it !in loweredIrLoaded }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!modulesToLower.isEmpty()) {
|
if (!modulesToLower.isEmpty()) {
|
||||||
// This won't work incrementally
|
// This won't work incrementally
|
||||||
modulesToLower.forEach { module ->
|
modulesToLower.forEach { module ->
|
||||||
@@ -172,20 +165,7 @@ fun icCompile(
|
|||||||
|
|
||||||
// dumpIr(allModules.first(), "simple-dump${if (useStdlibCache) "-actual" else ""}")
|
// dumpIr(allModules.first(), "simple-dump${if (useStdlibCache) "-actual" else ""}")
|
||||||
|
|
||||||
val transformer = IrModuleToJsTransformer(
|
return LoweredIr(context, allModules.last(), allModules)
|
||||||
context,
|
|
||||||
mainArguments,
|
|
||||||
fullJs = generateFullJs,
|
|
||||||
dceJs = generateDceJs,
|
|
||||||
multiModule = multiModule,
|
|
||||||
relativeRequirePath = relativeRequirePath,
|
|
||||||
moduleToName = moduleToName,
|
|
||||||
removeUnusedAssociatedObjects = false,
|
|
||||||
)
|
|
||||||
|
|
||||||
irFactory.stageController = object : StageController(999) {}
|
|
||||||
|
|
||||||
return transformer.generateModule(allModules)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun lowerPreservingIcData(module: IrModuleFragment, context: JsIrBackendContext, controller: WholeWorldStageController) {
|
fun lowerPreservingIcData(module: IrModuleFragment, context: JsIrBackendContext, controller: WholeWorldStageController) {
|
||||||
|
|||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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.lower.optimizations.PropertyAccessorInlineLowering
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||||
|
import org.jetbrains.kotlin.ir.util.fileOrNull
|
||||||
|
|
||||||
|
class JsPropertyAccessorInlineLowering(
|
||||||
|
val context: JsIrBackendContext
|
||||||
|
) : PropertyAccessorInlineLowering(context) {
|
||||||
|
override fun IrProperty.isSafeToInline(accessContainer: IrDeclaration): Boolean {
|
||||||
|
if (!isSafeToInlineInClosedWorld())
|
||||||
|
return false
|
||||||
|
|
||||||
|
if (isConst)
|
||||||
|
return true
|
||||||
|
|
||||||
|
return when (context.granularity) {
|
||||||
|
JsGenerationGranularity.WHOLE_PROGRAM ->
|
||||||
|
true
|
||||||
|
JsGenerationGranularity.PER_MODULE -> {
|
||||||
|
val accessModule = accessContainer.fileOrNull?.module ?: return false
|
||||||
|
val module = fileOrNull?.module ?: return false
|
||||||
|
accessModule == module
|
||||||
|
}
|
||||||
|
JsGenerationGranularity.PER_FILE ->
|
||||||
|
// Not inlining because
|
||||||
|
// 1. we need a way to distinguish per-file generation units
|
||||||
|
// 2. per-file mode intended for debug builds only at the moment
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.descriptors.ClassKind
|
||||||
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.util.transformDeclarationsFlat
|
||||||
|
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||||
|
|
||||||
|
fun moveOpenClassesToSeparateFiles(moduleFragment: IrModuleFragment) {
|
||||||
|
fun createFile(file: IrFile, klass: IrClass): IrFile =
|
||||||
|
IrFileImpl(fileEntry = file.fileEntry, fqName = file.fqName, symbol = IrFileSymbolImpl(), module = file.module).also {
|
||||||
|
it.annotations += file.annotations
|
||||||
|
it.declarations += klass
|
||||||
|
klass.parent = it
|
||||||
|
}
|
||||||
|
|
||||||
|
moduleFragment.files.transformFlat { file ->
|
||||||
|
// We don't have to split declarations with a single class
|
||||||
|
if (file.declarations.size <= 1)
|
||||||
|
return@transformFlat null
|
||||||
|
|
||||||
|
val openClasses = mutableListOf<IrClass>()
|
||||||
|
fun removeAndCollectOpenClasses(container: IrDeclarationContainer) {
|
||||||
|
container.transformDeclarationsFlat { declaration ->
|
||||||
|
if (declaration is IrDeclarationContainer) {
|
||||||
|
removeAndCollectOpenClasses(declaration)
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
declaration is IrClass &&
|
||||||
|
(declaration.modality == Modality.OPEN || declaration.modality == Modality.ABSTRACT) &&
|
||||||
|
declaration.kind == ClassKind.CLASS &&
|
||||||
|
declaration.visibility != DescriptorVisibilities.PRIVATE &&
|
||||||
|
declaration.visibility != DescriptorVisibilities.LOCAL
|
||||||
|
) {
|
||||||
|
openClasses += declaration
|
||||||
|
emptyList()
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeAndCollectOpenClasses(file)
|
||||||
|
|
||||||
|
return@transformFlat if (openClasses.isEmpty())
|
||||||
|
null
|
||||||
|
else
|
||||||
|
listOf(file) + openClasses.map { createFile(file, it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+1
@@ -7,6 +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.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsBlock
|
import org.jetbrains.kotlin.js.backend.ast.JsBlock
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
|
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -6,15 +6,19 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
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.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.ir.util.isInterface
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsFunction
|
import org.jetbrains.kotlin.js.backend.ast.JsFunction
|
||||||
|
|
||||||
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
||||||
class IrFunctionToJsTransformer : BaseIrElementToJsNodeTransformer<JsFunction, JsGenerationContext> {
|
class IrFunctionToJsTransformer : BaseIrElementToJsNodeTransformer<JsFunction, JsGenerationContext> {
|
||||||
override fun visitSimpleFunction(declaration: IrSimpleFunction, context: JsGenerationContext): JsFunction {
|
override fun visitSimpleFunction(declaration: IrSimpleFunction, context: JsGenerationContext): JsFunction {
|
||||||
val funcName = if (declaration.dispatchReceiverParameter == null) {
|
val parentClass = declaration.parent as? IrClass
|
||||||
|
val isInterfaceDefaultImpl = parentClass?.isInterface ?: false
|
||||||
|
val funcName = if (declaration.dispatchReceiverParameter == null || isInterfaceDefaultImpl) {
|
||||||
if (declaration.parent is IrFunction) {
|
if (declaration.parent is IrFunction) {
|
||||||
context.getNameForValueDeclaration(declaration)
|
context.getNameForValueDeclaration(declaration)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+30
-29
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.js.backend.JsToStringGenerationVisitor
|
|||||||
import org.jetbrains.kotlin.js.backend.NoOpSourceLocationConsumer
|
import org.jetbrains.kotlin.js.backend.NoOpSourceLocationConsumer
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding
|
import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding
|
||||||
import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver
|
import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver
|
||||||
import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder
|
import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder
|
||||||
@@ -52,17 +53,14 @@ class IrModuleToJsTransformer(
|
|||||||
) + packageLevelJsModules
|
) + packageLevelJsModules
|
||||||
}
|
}
|
||||||
|
|
||||||
val exportedModule = ExportModelGenerator(backendContext).generateExport(modules)
|
val moduleKind: ModuleKind = backendContext.configuration[JSConfigurationKeys.MODULE_KIND]!!
|
||||||
|
val exportedModule = ExportModelGenerator(backendContext, generateNamespacesForPackages = true).generateExport(modules, moduleKind = moduleKind)
|
||||||
val dts = exportedModule.toTypeScript()
|
val dts = exportedModule.toTypeScript()
|
||||||
|
|
||||||
modules.forEach { module ->
|
modules.forEach { module ->
|
||||||
module.files.forEach { StaticMembersLowering(backendContext).lower(it) }
|
module.files.forEach { StaticMembersLowering(backendContext).lower(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (multiModule) {
|
|
||||||
breakCrossModuleFieldAccess(backendContext, modules)
|
|
||||||
}
|
|
||||||
|
|
||||||
modules.forEach { module ->
|
modules.forEach { module ->
|
||||||
namer.merge(module.files, additionalPackages)
|
namer.merge(module.files, additionalPackages)
|
||||||
}
|
}
|
||||||
@@ -103,7 +101,7 @@ class IrModuleToJsTransformer(
|
|||||||
val dependencies = others.mapIndexed { index, module ->
|
val dependencies = others.mapIndexed { index, module ->
|
||||||
val moduleName = module.externalModuleName()
|
val moduleName = module.externalModuleName()
|
||||||
|
|
||||||
val exportedDeclarations = ExportModelGenerator(backendContext).let { module.files.flatMap { file -> it.generateExport(file) } }
|
val exportedDeclarations = ExportModelGenerator(backendContext, generateNamespacesForPackages = true).let { module.files.flatMap { file -> it.generateExport(file) } }
|
||||||
|
|
||||||
moduleName to generateWrappedModuleBody2(
|
moduleName to generateWrappedModuleBody2(
|
||||||
listOf(module),
|
listOf(module),
|
||||||
@@ -149,7 +147,7 @@ class IrModuleToJsTransformer(
|
|||||||
currentFile = null,
|
currentFile = null,
|
||||||
currentFunction = null,
|
currentFunction = null,
|
||||||
staticContext = staticContext,
|
staticContext = staticContext,
|
||||||
localNames = LocalNameGenerator(NameScope.EmptyScope)
|
localNames = LocalNameGenerator(NameTable())
|
||||||
)
|
)
|
||||||
|
|
||||||
val (importStatements, importedJsModules) =
|
val (importStatements, importedJsModules) =
|
||||||
@@ -162,7 +160,8 @@ class IrModuleToJsTransformer(
|
|||||||
|
|
||||||
val internalModuleName = JsName("_")
|
val internalModuleName = JsName("_")
|
||||||
val globalNames = NameTable<String>(namer.globalNames)
|
val globalNames = NameTable<String>(namer.globalNames)
|
||||||
val exportStatements = ExportModelToJsStatements(internalModuleName, nameGenerator, { globalNames.declareFreshName(it, it)}).generateModuleExport(exportedModule)
|
val exportStatements = ExportModelToJsStatements(nameGenerator) { globalNames.declareFreshName(it, it) }
|
||||||
|
.generateModuleExport(exportedModule, internalModuleName)
|
||||||
|
|
||||||
val (crossModuleImports, importedKotlinModules) = generateCrossModuleImports(nameGenerator, modules, dependencies, { JsName(sanitizeName(it)) })
|
val (crossModuleImports, importedKotlinModules) = generateCrossModuleImports(nameGenerator, modules, dependencies, { JsName(sanitizeName(it)) })
|
||||||
val crossModuleExports = generateCrossModuleExports(modules, refInfo, internalModuleName)
|
val crossModuleExports = generateCrossModuleExports(modules, refInfo, internalModuleName)
|
||||||
@@ -431,27 +430,6 @@ class IrModuleToJsTransformer(
|
|||||||
return Pair(importStatements, importedJsModules)
|
return Pair(importStatements, importedJsModules)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processClassModels(
|
|
||||||
classModelMap: Map<IrClassSymbol, JsIrClassModel>,
|
|
||||||
preDeclarationBlock: JsBlock,
|
|
||||||
postDeclarationBlock: JsBlock
|
|
||||||
) {
|
|
||||||
val declarationHandler = object : DFS.AbstractNodeHandler<IrClassSymbol, Unit>() {
|
|
||||||
override fun result() {}
|
|
||||||
override fun afterChildren(current: IrClassSymbol) {
|
|
||||||
classModelMap[current]?.let {
|
|
||||||
preDeclarationBlock.statements += it.preDeclarationBlock.statements
|
|
||||||
postDeclarationBlock.statements += it.postDeclarationBlock.statements
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DFS.dfs(
|
|
||||||
classModelMap.keys,
|
|
||||||
{ klass -> classModelMap[klass]?.superClasses ?: emptyList() },
|
|
||||||
declarationHandler
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun MutableList<JsStatement>.startRegion(description: String = "") {
|
private fun MutableList<JsStatement>.startRegion(description: String = "") {
|
||||||
if (generateRegionComments) {
|
if (generateRegionComments) {
|
||||||
@@ -479,3 +457,26 @@ class IrModuleToJsTransformer(
|
|||||||
endRegion()
|
endRegion()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun processClassModels(
|
||||||
|
classModelMap: Map<IrClassSymbol, JsIrClassModel>,
|
||||||
|
preDeclarationBlock: JsBlock,
|
||||||
|
postDeclarationBlock: JsBlock
|
||||||
|
) {
|
||||||
|
val declarationHandler = object : DFS.AbstractNodeHandler<IrClassSymbol, Unit>() {
|
||||||
|
override fun result() {}
|
||||||
|
override fun afterChildren(current: IrClassSymbol) {
|
||||||
|
classModelMap[current]?.let {
|
||||||
|
preDeclarationBlock.statements += it.preDeclarationBlock.statements
|
||||||
|
postDeclarationBlock.statements += it.postDeclarationBlock.statements
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DFS.dfs(
|
||||||
|
classModelMap.keys,
|
||||||
|
{ klass -> classModelMap[klass]?.superClasses ?: emptyList() },
|
||||||
|
declarationHandler
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-9
@@ -85,7 +85,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is IrClass -> {
|
is IrClass -> {
|
||||||
classBlock.statements += JsClassGenerator(declaration, context).generate()
|
// classBlock.statements += JsClassGenerator(declaration, context).generate()
|
||||||
}
|
}
|
||||||
is IrField -> {
|
is IrField -> {
|
||||||
}
|
}
|
||||||
@@ -208,9 +208,14 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
val memberRef = JsNameRef(memberName, classPrototypeRef)
|
val memberRef = JsNameRef(memberName, classPrototypeRef)
|
||||||
|
|
||||||
if (declaration.isReal && declaration.body != null) {
|
if (declaration.isReal && declaration.body != null) {
|
||||||
val translatedFunction = declaration.accept(IrFunctionToJsTransformer(), context)
|
val translatedFunction: JsFunction = declaration.accept(IrFunctionToJsTransformer(), context)
|
||||||
assert(!declaration.isStaticMethodOfClass)
|
assert(!declaration.isStaticMethodOfClass)
|
||||||
|
|
||||||
|
if (irClass.isInterface) {
|
||||||
|
classModel.preDeclarationBlock.statements += translatedFunction.makeStmt()
|
||||||
|
return Pair(memberRef, null)
|
||||||
|
}
|
||||||
|
|
||||||
return Pair(memberRef, translatedFunction)
|
return Pair(memberRef, translatedFunction)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,14 +229,19 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
?.let {
|
?.let {
|
||||||
val implClassDeclaration = it.parent as IrClass
|
val implClassDeclaration = it.parent as IrClass
|
||||||
|
|
||||||
if (implClassDeclaration.shouldCopyFrom()) {
|
if (implClassDeclaration.shouldCopyFrom() && it.body != null) {
|
||||||
val implMethodName = context.getNameForMemberFunction(it)
|
val reference = context.getNameForStaticDeclaration(it).makeRef()
|
||||||
val implClassName = context.getNameForClass(implClassDeclaration)
|
classModel.postDeclarationBlock.statements += jsAssignment(memberRef, reference).makeStmt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
declaration.collectRealOverrides()
|
||||||
|
.find { it.modality != Modality.ABSTRACT }
|
||||||
|
?.let {
|
||||||
|
val implClassDeclaration = it.parent as IrClass
|
||||||
|
|
||||||
val implClassPrototype = prototypeOf(implClassName.makeRef())
|
if (implClassDeclaration.shouldCopyFrom() && it.body != null) {
|
||||||
val implMemberRef = JsNameRef(implMethodName, implClassPrototype)
|
val reference = context.getNameForStaticDeclaration(it).makeRef()
|
||||||
|
classModel.postDeclarationBlock.statements += jsAssignment(memberRef, reference).makeStmt()
|
||||||
classModel.postDeclarationBlock.statements += jsAssignment(memberRef, implMemberRef).makeStmt()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -25,6 +25,7 @@ object ModuleWrapperTranslation {
|
|||||||
ModuleKind.COMMON_JS -> wrapCommonJs(function, importedModules, program)
|
ModuleKind.COMMON_JS -> wrapCommonJs(function, importedModules, program)
|
||||||
ModuleKind.UMD -> wrapUmd(moduleId, function, importedModules, program)
|
ModuleKind.UMD -> wrapUmd(moduleId, function, importedModules, program)
|
||||||
ModuleKind.PLAIN -> wrapPlain(moduleId, function, importedModules, program)
|
ModuleKind.PLAIN -> wrapPlain(moduleId, function, importedModules, program)
|
||||||
|
ModuleKind.ES -> error("ES modules are not supported in legacy wrapper")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-88
@@ -116,94 +116,6 @@ fun buildCrossModuleReferenceInfo(modules: Iterable<IrModuleFragment>): CrossMod
|
|||||||
return CrossModuleReferenceInfoImpl(map)
|
return CrossModuleReferenceInfoImpl(map)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun breakCrossModuleFieldAccess(
|
|
||||||
context: JsIrBackendContext,
|
|
||||||
modules: Iterable<IrModuleFragment>
|
|
||||||
) {
|
|
||||||
val fieldToGetter = mutableMapOf<IrField, IrSimpleFunction>()
|
|
||||||
|
|
||||||
fun IrField.getter(): IrSimpleFunction {
|
|
||||||
return fieldToGetter.getOrPut(this) {
|
|
||||||
val fieldName = name
|
|
||||||
val getter = context.irFactory.buildFun {
|
|
||||||
name = Name.identifier("get-$fieldName")
|
|
||||||
returnType = type
|
|
||||||
}
|
|
||||||
getter.body = factory.createBlockBody(
|
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf(
|
|
||||||
IrReturnImpl(
|
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, getter.symbol,
|
|
||||||
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, type)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
getter.parent = parent
|
|
||||||
(parent as IrDeclarationContainer).declarations += getter
|
|
||||||
|
|
||||||
getter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val fieldToSetter = mutableMapOf<IrField, IrSimpleFunction>()
|
|
||||||
|
|
||||||
fun IrField.setter(): IrSimpleFunction {
|
|
||||||
return fieldToSetter.getOrPut(this) {
|
|
||||||
val fieldName = name
|
|
||||||
val setter = context.irFactory.buildFun {
|
|
||||||
name = Name.identifier("set-$fieldName")
|
|
||||||
returnType = context.irBuiltIns.unitType
|
|
||||||
}
|
|
||||||
|
|
||||||
val param = setter.addValueParameter("value", type)
|
|
||||||
|
|
||||||
setter.body = factory.createBlockBody(
|
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf(
|
|
||||||
IrSetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, type).apply {
|
|
||||||
value = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, param.symbol)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
setter.parent = parent
|
|
||||||
(parent as IrDeclarationContainer).declarations += setter
|
|
||||||
|
|
||||||
setter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
modules.reversed().forEach { module ->
|
|
||||||
|
|
||||||
val moduleFields = module.files.flatMap { it.declarations.filterIsInstance<IrField>() }.toSet()
|
|
||||||
|
|
||||||
fun IrField.transformAccess(fn: IrField.() -> IrCall): IrCall? {
|
|
||||||
if (parent !is IrPackageFragment || isEffectivelyExternal() || this in moduleFields) return null
|
|
||||||
return fn()
|
|
||||||
}
|
|
||||||
|
|
||||||
module.transformChildrenVoid(object : IrElementTransformerVoid() {
|
|
||||||
|
|
||||||
override fun visitGetField(expression: IrGetField): IrExpression {
|
|
||||||
expression.transformChildrenVoid(this)
|
|
||||||
|
|
||||||
return expression.symbol.owner.transformAccess {
|
|
||||||
val getter = getter()
|
|
||||||
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, getter.returnType, getter.symbol, getter.typeParameters.size, getter.valueParameters.size)
|
|
||||||
} ?: expression
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSetField(expression: IrSetField): IrExpression {
|
|
||||||
expression.transformChildrenVoid(this)
|
|
||||||
|
|
||||||
return expression.symbol.owner.transformAccess {
|
|
||||||
val setter = setter()
|
|
||||||
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, setter.returnType, setter.symbol, setter.typeParameters.size, setter.valueParameters.size).apply {
|
|
||||||
putValueArgument(0, expression.value)
|
|
||||||
}
|
|
||||||
} ?: expression
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val IrModuleFragment.safeName: String
|
val IrModuleFragment.safeName: String
|
||||||
get() {
|
get() {
|
||||||
var result = name.asString()
|
var result = name.asString()
|
||||||
|
|||||||
+20
-19
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
|||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsStatementOrigins
|
import org.jetbrains.kotlin.ir.backend.js.JsStatementOrigins
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
@@ -127,17 +128,22 @@ fun translateCall(
|
|||||||
}
|
}
|
||||||
|
|
||||||
expression.superQualifierSymbol?.let { superQualifier ->
|
expression.superQualifierSymbol?.let { superQualifier ->
|
||||||
val (target, klass) = if (superQualifier.owner.isInterface) {
|
val (target: IrSimpleFunction, klass: IrClass) = if (superQualifier.owner.isInterface) {
|
||||||
val impl = function.resolveFakeOverride()!!
|
val impl = function.resolveFakeOverride()!!
|
||||||
Pair(impl, impl.parentAsClass)
|
Pair(impl, impl.parentAsClass)
|
||||||
} else {
|
} else {
|
||||||
Pair(function, superQualifier.owner)
|
Pair(function, superQualifier.owner)
|
||||||
}
|
}
|
||||||
|
|
||||||
val qualifierName = context.getNameForClass(klass).makeRef()
|
val callRef = if (klass.isInterface && target.body != null) {
|
||||||
val targetName = context.getNameForMemberFunction(target)
|
JsNameRef(Namer.CALL_FUNCTION, JsNameRef(context.getNameForStaticDeclaration(target)))
|
||||||
val qPrototype = JsNameRef(targetName, prototypeOf(qualifierName))
|
} else {
|
||||||
val callRef = JsNameRef(Namer.CALL_FUNCTION, qPrototype)
|
val qualifierName = context.getNameForClass(klass).makeRef()
|
||||||
|
val targetName = context.getNameForMemberFunction(target)
|
||||||
|
val qPrototype = JsNameRef(targetName, prototypeOf(qualifierName))
|
||||||
|
JsNameRef(Namer.CALL_FUNCTION, qPrototype)
|
||||||
|
}
|
||||||
|
|
||||||
return JsInvocation(callRef, jsDispatchReceiver?.let { receiver -> listOf(receiver) + arguments } ?: arguments)
|
return JsInvocation(callRef, jsDispatchReceiver?.let { receiver -> listOf(receiver) + arguments } ?: arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,20 +199,15 @@ fun translateCall(
|
|||||||
"VarargIIFE"
|
"VarargIIFE"
|
||||||
)
|
)
|
||||||
|
|
||||||
val iifeFunHasContext = (jsDispatchReceiver as? JsNameRef)?.qualifier is JsThisRef
|
JsInvocation(
|
||||||
if (iifeFunHasContext) {
|
// Create scope for temporary variable holding dispatch receiver
|
||||||
JsInvocation(
|
// It is used both during method reference and passing `this` value to `apply` function.
|
||||||
// Create scope for temporary variable holding dispatch receiver
|
JsNameRef(
|
||||||
// It is used both during method reference and passing `this` value to `apply` function.
|
"call",
|
||||||
JsNameRef(
|
iifeFun
|
||||||
"call",
|
),
|
||||||
iifeFun
|
JsThisRef()
|
||||||
),
|
)
|
||||||
JsThisRef()
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
JsInvocation(iifeFun)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (argumentsAsSingleArray is JsArrayLiteral) {
|
if (argumentsAsSingleArray is JsArrayLiteral) {
|
||||||
|
|||||||
+2
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.backend.js.utils
|
|||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
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.JsIntrinsicTransformers
|
||||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrClassModel
|
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrClassModel
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
|
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
@@ -16,7 +17,7 @@ import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
|||||||
class JsStaticContext(
|
class JsStaticContext(
|
||||||
val backendContext: JsIrBackendContext,
|
val backendContext: JsIrBackendContext,
|
||||||
private val irNamer: IrNamer,
|
private val irNamer: IrNamer,
|
||||||
val globalNameScope: NameScope,
|
val globalNameScope: NameTable<IrDeclaration>,
|
||||||
) : IrNamer by irNamer {
|
) : IrNamer by irNamer {
|
||||||
val intrinsics = JsIntrinsicTransformers(backendContext)
|
val intrinsics = JsIntrinsicTransformers(backendContext)
|
||||||
val classModels = mutableMapOf<IrClassSymbol, JsIrClassModel>()
|
val classModels = mutableMapOf<IrClassSymbol, JsIrClassModel>()
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.types.isUnit
|
|||||||
import org.jetbrains.kotlin.ir.util.file
|
import org.jetbrains.kotlin.ir.util.file
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||||
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
||||||
|
import org.jetbrains.kotlin.ir.util.isInterface
|
||||||
import org.jetbrains.kotlin.ir.util.render
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
@@ -32,7 +33,12 @@ import kotlin.math.abs
|
|||||||
private fun <T> mapToKey(declaration: T): String {
|
private fun <T> mapToKey(declaration: T): String {
|
||||||
return with(JsManglerIr) {
|
return with(JsManglerIr) {
|
||||||
if (declaration is IrDeclaration) {
|
if (declaration is IrDeclaration) {
|
||||||
declaration.hashedMangle(compatibleMode = false).toString()
|
try {
|
||||||
|
declaration.hashedMangle(compatibleMode = false).toString()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
// FIXME: We can't mangle some local declarations. But
|
||||||
|
"wrong_key"
|
||||||
|
}
|
||||||
} else if (declaration is String) {
|
} else if (declaration is String) {
|
||||||
declaration.hashMangle.toString()
|
declaration.hashMangle.toString()
|
||||||
} else {
|
} else {
|
||||||
@@ -118,6 +124,7 @@ fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext?):
|
|||||||
}
|
}
|
||||||
|
|
||||||
val nameBuilder = StringBuilder()
|
val nameBuilder = StringBuilder()
|
||||||
|
nameBuilder.append(declarationName)
|
||||||
|
|
||||||
// TODO should we skip type parameters and use upper bound of type parameter when print type of value parameters?
|
// TODO should we skip type parameters and use upper bound of type parameter when print type of value parameters?
|
||||||
declaration.typeParameters.ifNotEmpty {
|
declaration.typeParameters.ifNotEmpty {
|
||||||
@@ -202,6 +209,11 @@ class NameTables(
|
|||||||
when (memberDecl) {
|
when (memberDecl) {
|
||||||
is IrField ->
|
is IrField ->
|
||||||
generateNameForMemberField(memberDecl)
|
generateNameForMemberField(memberDecl)
|
||||||
|
is IrSimpleFunction -> {
|
||||||
|
if (declaration.isInterface && memberDecl.body != null) {
|
||||||
|
globalNames.declareFreshName(memberDecl, memberDecl.name.asString())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,8 +311,7 @@ class NameTables(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class LocalNameGenerator(parentScope: NameScope) : IrElementVisitorVoid {
|
class LocalNameGenerator(val variableNames: NameTable<IrDeclaration>) : IrElementVisitorVoid {
|
||||||
val variableNames = NameTable<IrDeclarationWithName>(parentScope)
|
|
||||||
val localLoopNames = NameTable<IrLoop>()
|
val localLoopNames = NameTable<IrLoop>()
|
||||||
val localReturnableBlockNames = NameTable<IrReturnableBlock>()
|
val localReturnableBlockNames = NameTable<IrReturnableBlock>()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.utils
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.codegen.IrToJs
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrDeclarationReference
|
||||||
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.JsImport
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.JsName
|
||||||
|
|
||||||
|
class StaticDeclarationNumerator {
|
||||||
|
var currentNumber = 0
|
||||||
|
val numeration = mutableMapOf<IrDeclaration, Int>()
|
||||||
|
|
||||||
|
fun add(moduleFragment: IrModuleFragment) {
|
||||||
|
moduleFragment.files.forEach { add(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(declaration: IrDeclaration) {
|
||||||
|
// TODO: We should not visit declarations multiple times.
|
||||||
|
// Investigate enum tests in dce-driven mode.
|
||||||
|
if (declaration !in numeration) {
|
||||||
|
numeration[declaration] = currentNumber
|
||||||
|
currentNumber++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(packageFragment: IrPackageFragment) {
|
||||||
|
packageFragment.acceptChildrenVoid(object : IrElementVisitorVoid {
|
||||||
|
override fun visitElement(element: IrElement) {
|
||||||
|
element.acceptChildrenVoid(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitDeclaration(declaration: IrDeclarationBase) {
|
||||||
|
if (declaration !is IrVariable) {
|
||||||
|
add(declaration)
|
||||||
|
}
|
||||||
|
super.visitDeclaration(declaration)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NewStableStaticNamesCollectorVisitor(val needToCollectReferences: Boolean) : IrElementVisitorVoid {
|
||||||
|
val collectedStableNames = mutableSetOf<String>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
collectedStableNames.addAll(RESERVED_IDENTIFIERS)
|
||||||
|
collectedStableNames.add(Namer.IMPLICIT_RECEIVER_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrDeclaration.collectStableName() {
|
||||||
|
collectedStableNames += stableNameForExternalDeclaration(this) ?: return
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitElement(element: IrElement) {
|
||||||
|
element.acceptChildrenVoid(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitDeclaration(declaration: IrDeclarationBase) {
|
||||||
|
super.visitDeclaration(declaration)
|
||||||
|
declaration.collectStableName()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitDeclarationReference(expression: IrDeclarationReference) {
|
||||||
|
super.visitDeclarationReference(expression)
|
||||||
|
if (needToCollectReferences) {
|
||||||
|
val declaration = expression.symbol.owner as? IrDeclaration
|
||||||
|
declaration?.collectStableName()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NewNamerImpl(
|
||||||
|
val context: JsIrBackendContext,
|
||||||
|
val unit: IrToJs.CodegenUnit,
|
||||||
|
val exportId: (IrDeclarationWithName) -> String,
|
||||||
|
val stableNames: Set<String>,
|
||||||
|
) : IrNamerBase() {
|
||||||
|
val staticNames = NameTable<IrDeclaration>(
|
||||||
|
reserved = stableNames.toMutableSet()
|
||||||
|
)
|
||||||
|
val internalImports = mutableMapOf<String, JsImport>()
|
||||||
|
|
||||||
|
override fun getNameForMemberFunction(function: IrSimpleFunction): JsName {
|
||||||
|
require(function.dispatchReceiverParameter != null)
|
||||||
|
val name = jsFunctionSignature(function, context)
|
||||||
|
return name.toJsName()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getNameForMemberField(field: IrField): JsName {
|
||||||
|
val fieldName = sanitizeName(
|
||||||
|
try {
|
||||||
|
exportId(field)
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
// TODO: Fix DCE with inline classes and remove this hack
|
||||||
|
field.name.asString() + "_LIKELY_ELIMINATED_BY_DCE"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// TODO: Webpack not minimize member names, it is long name, which is not minimized, so it affects final JS bundle size
|
||||||
|
// Use shorter names
|
||||||
|
return JsName("f_$fieldName")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getNameForStaticDeclaration(declaration: IrDeclarationWithName): JsName {
|
||||||
|
staticNames.names[declaration]?.let { return JsName(it) }
|
||||||
|
|
||||||
|
fun registerImport(moduleId: String, importedName: String) {
|
||||||
|
val fullModuleId = if (moduleId.startsWith(".")) {
|
||||||
|
unit.pathToKotlinModulesRoot + moduleId
|
||||||
|
} else {
|
||||||
|
// TODO: Do we cover this path in tests?
|
||||||
|
moduleId
|
||||||
|
}
|
||||||
|
|
||||||
|
val import = internalImports.getOrPut(fullModuleId) {
|
||||||
|
JsImport(fullModuleId)
|
||||||
|
}
|
||||||
|
import.elements += JsImport.Element(importedName, staticNames.names[declaration]!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration.isEffectivelyExternal()) {
|
||||||
|
val jsModule: String? = declaration.getJsModule()
|
||||||
|
val maybeParentFile: IrFile? = declaration.parent as? IrFile
|
||||||
|
val fileJsModule: String? = maybeParentFile?.getJsModule()
|
||||||
|
val jsQualifier: String? = maybeParentFile?.getJsQualifier()
|
||||||
|
|
||||||
|
when {
|
||||||
|
jsModule != null -> {
|
||||||
|
// TODO: Support jsQualifier
|
||||||
|
staticNames.declareFreshName(declaration, declaration.name.asString())
|
||||||
|
registerImport(jsModule, "default")
|
||||||
|
}
|
||||||
|
|
||||||
|
fileJsModule != null -> {
|
||||||
|
// TODO: Support jsQualifier
|
||||||
|
staticNames.declareFreshName(declaration, declaration.name.asString())
|
||||||
|
registerImport(fileJsModule, declaration.getJsNameOrKotlinName().identifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
var name = declaration.getJsNameOrKotlinName().identifier
|
||||||
|
if (jsQualifier != null)
|
||||||
|
name = "$jsQualifier.$name"
|
||||||
|
|
||||||
|
staticNames.declareStableName(declaration, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else { // Non-external declaration
|
||||||
|
staticNames.declareFreshName(declaration, declaration.name.asString())
|
||||||
|
val unitReference = unit.referenceCodegenUnitOfDeclaration(declaration)
|
||||||
|
if (unitReference is IrToJs.OtherUnitReference) {
|
||||||
|
registerImport(unitReference.importPath, exportId(declaration))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return JsName(staticNames.names[declaration]!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Cache?
|
||||||
|
private fun stableNameForExternalDeclaration(declaration: IrDeclaration): String? {
|
||||||
|
if (declaration !is IrDeclarationWithName ||
|
||||||
|
!declaration.hasStaticDispatch() ||
|
||||||
|
!declaration.isEffectivelyExternal() ||
|
||||||
|
declaration.isPropertyAccessor ||
|
||||||
|
declaration.isPropertyField
|
||||||
|
) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration is IrConstructor) {
|
||||||
|
return stableNameForExternalDeclaration(declaration.parentAsClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
val importedFromModuleOnly =
|
||||||
|
declaration.getJsModule() != null && !declaration.isJsNonModule()
|
||||||
|
|
||||||
|
val jsName = declaration.getJsName()
|
||||||
|
|
||||||
|
val jsQualifier = declaration.fileOrNull?.getJsQualifier()
|
||||||
|
|
||||||
|
return when {
|
||||||
|
importedFromModuleOnly ->
|
||||||
|
null
|
||||||
|
|
||||||
|
jsQualifier != null ->
|
||||||
|
jsQualifier.split('1')[0]
|
||||||
|
|
||||||
|
jsName != null ->
|
||||||
|
jsName
|
||||||
|
|
||||||
|
else ->
|
||||||
|
declaration.name.identifier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+1
@@ -20,6 +20,7 @@ where advanced options include:
|
|||||||
Enable runtime diagnostics when performing DCE instead of removing declarations
|
Enable runtime diagnostics when performing DCE instead of removing declarations
|
||||||
-Xir-module-name=<name> Specify a compilation module name for IR backend
|
-Xir-module-name=<name> Specify a compilation module name for IR backend
|
||||||
-Xir-only Disables pre-IR backend
|
-Xir-only Disables pre-IR backend
|
||||||
|
-Xir-per-file Splits generated .js per-file
|
||||||
-Xir-per-module Splits generated .js per-module
|
-Xir-per-module Splits generated .js per-module
|
||||||
-Xir-per-module-output-name Adds a custom output name to the splitted js files
|
-Xir-per-module-output-name Adds a custom output name to the splitted js files
|
||||||
-Xir-produce-js Generates JS file using IR backend. Also disables pre-IR backend
|
-Xir-produce-js Generates JS file using IR backend. Also disables pre-IR backend
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SKIP_DCE_DRIVEN
|
||||||
|
|
||||||
enum class Bar {
|
enum class Bar {
|
||||||
ONE {
|
ONE {
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
// TARGET_BACKEND: JS_IR
|
|
||||||
// PROPERTY_LAZY_INITIALIZATION
|
|
||||||
|
|
||||||
// FILE: A.kt
|
|
||||||
|
|
||||||
val a = "A"
|
|
||||||
|
|
||||||
// FILE: B.kt
|
|
||||||
val b = "B".let {
|
|
||||||
it + "B"
|
|
||||||
}
|
|
||||||
|
|
||||||
val c = b
|
|
||||||
|
|
||||||
// FILE: C.kt
|
|
||||||
val d = "D".let {
|
|
||||||
it + "D"
|
|
||||||
}
|
|
||||||
|
|
||||||
val e = d
|
|
||||||
|
|
||||||
// FILE: main.kt
|
|
||||||
|
|
||||||
fun box(): String {
|
|
||||||
// Get only e to initialize all properties in file
|
|
||||||
e
|
|
||||||
return if (
|
|
||||||
js("a") === "A" &&
|
|
||||||
js("typeof b") == "undefined" &&
|
|
||||||
js("typeof c") == "undefined" &&
|
|
||||||
js("d") === "DD" &&
|
|
||||||
js("e") === "DD"
|
|
||||||
)
|
|
||||||
"OK"
|
|
||||||
else "a = ${js("a")}; typeof b = ${js("typeof b")}; typeof c = ${js("typeof c")}; d = ${js("d")}; e = ${js("e")}"
|
|
||||||
}
|
|
||||||
+4
-1
@@ -3,7 +3,10 @@
|
|||||||
// PROPERTY_LAZY_INITIALIZATION
|
// PROPERTY_LAZY_INITIALIZATION
|
||||||
|
|
||||||
// FILE: A.kt
|
// FILE: A.kt
|
||||||
|
var result: String? = null
|
||||||
|
|
||||||
val a = "a".let {
|
val a = "a".let {
|
||||||
|
result = "OK"
|
||||||
it + "a"
|
it + "a"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,5 +16,5 @@ fun foo() =
|
|||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val foo = foo()
|
val foo = foo()
|
||||||
return if (js("typeof a") == "string" && js("a") == "aa") "OK" else "fail"
|
return result!!
|
||||||
}
|
}
|
||||||
+2
-1
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
// FILE: A.kt
|
// FILE: A.kt
|
||||||
val a1 = "a".let {
|
val a1 = "a".let {
|
||||||
|
throw Error()
|
||||||
it + "a"
|
it + "a"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,5 +40,5 @@ fun box(): String {
|
|||||||
C.values()
|
C.values()
|
||||||
C.valueOf("OK")
|
C.valueOf("OK")
|
||||||
val baz = b
|
val baz = b
|
||||||
return if (js("typeof a1") == "undefined") "OK" else "fail"
|
return "OK"
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// TODO: Investigate ES modules issue
|
||||||
|
|
||||||
// FILE: Outer.kt
|
// FILE: Outer.kt
|
||||||
|
|
||||||
package another
|
package another
|
||||||
|
|||||||
@@ -1173,6 +1173,69 @@ public class JsToStringGenerationVisitor extends JsVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitExport(@NotNull JsExport export) {
|
||||||
|
p.print("export");
|
||||||
|
space();
|
||||||
|
JsExport.Subject subject = export.getSubject();
|
||||||
|
|
||||||
|
if (subject instanceof JsExport.Subject.All) {
|
||||||
|
p.print("*");
|
||||||
|
} else if (subject instanceof JsExport.Subject.Elements) {
|
||||||
|
blockOpen();
|
||||||
|
List<JsExport.Element> elements = ((JsExport.Subject.Elements) subject).getElements();
|
||||||
|
for (JsExport.Element element : elements) {
|
||||||
|
nameDef(element.getName());
|
||||||
|
JsName alias = element.getAlias();
|
||||||
|
if (alias != null) {
|
||||||
|
p.print(" as ");
|
||||||
|
nameDef(alias);
|
||||||
|
}
|
||||||
|
p.print(',');
|
||||||
|
p.newline();
|
||||||
|
}
|
||||||
|
p.indentOut();
|
||||||
|
p.print('}');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (export.getFromModule() != null) {
|
||||||
|
p.print(" from ");
|
||||||
|
p.print(javaScriptString(export.getFromModule()));
|
||||||
|
}
|
||||||
|
needSemi = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitImport(@NotNull JsImport jsImport) {
|
||||||
|
p.print("import {");
|
||||||
|
boolean isMultiline = jsImport.getElements().size() > 1;
|
||||||
|
p.indentIn();
|
||||||
|
if (isMultiline)
|
||||||
|
newlineOpt();
|
||||||
|
else
|
||||||
|
space();
|
||||||
|
|
||||||
|
for (JsImport.Element element : jsImport.getElements()) {
|
||||||
|
nameDef(element.getName());
|
||||||
|
JsName alias = element.getAlias();
|
||||||
|
if (alias != null) {
|
||||||
|
p.print(" as ");
|
||||||
|
nameDef(alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isMultiline) {
|
||||||
|
p.print(',');
|
||||||
|
newlineOpt();
|
||||||
|
} else {
|
||||||
|
space();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.indentOut();
|
||||||
|
p.print("} from ");
|
||||||
|
p.print(javaScriptString(jsImport.getModule()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void newline() {
|
private void newline() {
|
||||||
p.newline();
|
p.newline();
|
||||||
sourceLocationConsumer.newLine();
|
sourceLocationConsumer.newLine();
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.js.backend.ast
|
||||||
|
|
||||||
|
class JsExport(
|
||||||
|
val subject: Subject,
|
||||||
|
val fromModule: String? = null,
|
||||||
|
) : SourceInfoAwareJsNode(), JsStatement {
|
||||||
|
|
||||||
|
constructor(element: Element) : this(Subject.Elements(listOf(element)))
|
||||||
|
constructor(name: JsName, alias: JsName? = null) : this(Element(name, alias))
|
||||||
|
|
||||||
|
sealed class Subject {
|
||||||
|
class Elements(val elements: List<Element>) : Subject()
|
||||||
|
object All : Subject()
|
||||||
|
}
|
||||||
|
|
||||||
|
class Element(
|
||||||
|
val name: JsName,
|
||||||
|
val alias: JsName?
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun accept(visitor: JsVisitor) {
|
||||||
|
visitor.visitExport(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun acceptChildren(visitor: JsVisitor) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deepCopy(): JsStatement =
|
||||||
|
JsExport(subject, fromModule)
|
||||||
|
|
||||||
|
override fun traverse(v: JsVisitorWithContext, ctx: JsContext<*>) {
|
||||||
|
v.visit(this, ctx)
|
||||||
|
v.endVisit(this, ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.js.backend.ast
|
||||||
|
|
||||||
|
class JsImport(
|
||||||
|
val module: String,
|
||||||
|
val elements: MutableList<Element> = mutableListOf(),
|
||||||
|
) : SourceInfoAwareJsNode(), JsStatement {
|
||||||
|
|
||||||
|
class Element(
|
||||||
|
val name: JsName,
|
||||||
|
val alias: JsName?
|
||||||
|
) {
|
||||||
|
constructor(name: String, alias: String?) : this(JsName(name), alias?.let { JsName(it) })
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun accept(visitor: JsVisitor) {
|
||||||
|
visitor.visitImport(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun acceptChildren(visitor: JsVisitor) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deepCopy(): JsStatement =
|
||||||
|
JsImport(module, elements.map { it }.toMutableList())
|
||||||
|
|
||||||
|
override fun traverse(v: JsVisitorWithContext, ctx: JsContext<*>) {
|
||||||
|
v.visit(this, ctx)
|
||||||
|
v.endVisit(this, ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -165,6 +165,12 @@ abstract class JsVisitor {
|
|||||||
open fun visitSingleLineComment(comment: JsSingleLineComment): Unit =
|
open fun visitSingleLineComment(comment: JsSingleLineComment): Unit =
|
||||||
visitElement(comment)
|
visitElement(comment)
|
||||||
|
|
||||||
|
open fun visitExport(export: JsExport): Unit =
|
||||||
|
visitElement(export)
|
||||||
|
|
||||||
|
open fun visitImport(import: JsImport): Unit =
|
||||||
|
visitElement(import)
|
||||||
|
|
||||||
protected open fun visitElement(node: JsNode) {
|
protected open fun visitElement(node: JsNode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,6 +214,12 @@ public abstract class JsVisitorWithContext {
|
|||||||
public void endVisit(@NotNull JsSingleLineComment x, @NotNull JsContext ctx) {
|
public void endVisit(@NotNull JsSingleLineComment x, @NotNull JsContext ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void endVisit(@NotNull JsExport x, @NotNull JsContext ctx) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endVisit(@NotNull JsImport x, @NotNull JsContext ctx) {
|
||||||
|
}
|
||||||
|
|
||||||
public void endVisit(@NotNull JsWhile x, @NotNull JsContext ctx) {
|
public void endVisit(@NotNull JsWhile x, @NotNull JsContext ctx) {
|
||||||
endVisit((JsLoop) x, ctx);
|
endVisit((JsLoop) x, ctx);
|
||||||
}
|
}
|
||||||
@@ -398,6 +404,14 @@ public abstract class JsVisitorWithContext {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean visit(@NotNull JsExport x, @NotNull JsContext ctx) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean visit(@NotNull JsImport x, @NotNull JsContext ctx) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract <T extends JsNode> T doAccept(T node);
|
protected abstract <T extends JsNode> T doAccept(T node);
|
||||||
|
|
||||||
protected abstract JsExpression doAcceptLvalue(JsExpression expr);
|
protected abstract JsExpression doAcceptLvalue(JsExpression expr);
|
||||||
|
|||||||
+1
@@ -124,6 +124,7 @@ object KotlinJavascriptSerializationUtil {
|
|||||||
ModuleKind.AMD -> JsProtoBuf.Library.Kind.AMD
|
ModuleKind.AMD -> JsProtoBuf.Library.Kind.AMD
|
||||||
ModuleKind.COMMON_JS -> JsProtoBuf.Library.Kind.COMMON_JS
|
ModuleKind.COMMON_JS -> JsProtoBuf.Library.Kind.COMMON_JS
|
||||||
ModuleKind.UMD -> JsProtoBuf.Library.Kind.UMD
|
ModuleKind.UMD -> JsProtoBuf.Library.Kind.UMD
|
||||||
|
ModuleKind.ES -> error("Es modules serialization")
|
||||||
}
|
}
|
||||||
if (builder.kind != moduleProtoKind) {
|
if (builder.kind != moduleProtoKind) {
|
||||||
builder.kind = moduleProtoKind
|
builder.kind = moduleProtoKind
|
||||||
|
|||||||
@@ -22,5 +22,6 @@ public enum ModuleKind {
|
|||||||
PLAIN,
|
PLAIN,
|
||||||
AMD,
|
AMD,
|
||||||
COMMON_JS,
|
COMMON_JS,
|
||||||
UMD
|
UMD,
|
||||||
|
ES
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -257,6 +257,8 @@ projectTest(parallel = true) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
projectTest("jsTest", true) {
|
projectTest("jsTest", true) {
|
||||||
|
// PIR temporary disabled
|
||||||
|
systemProperty("kotlin.js.ir.pir", "false")
|
||||||
setUpJsBoxTests(jsEnabled = true, jsIrEnabled = false)
|
setUpJsBoxTests(jsEnabled = true, jsIrEnabled = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,11 +47,6 @@ fun main(args: Array<String>) {
|
|||||||
model("typescript-export/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR_ES6)
|
model("typescript-export/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR_ES6)
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractLegacyJsTypeScriptExportTest> {
|
|
||||||
model("typescript-export/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
testClass<AbstractSourceMapGenerationSmokeTest> {
|
testClass<AbstractSourceMapGenerationSmokeTest> {
|
||||||
model("sourcemap/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
|
model("sourcemap/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ 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.codegen.JsGenerationGranularity
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ic.ICCache
|
import org.jetbrains.kotlin.ir.backend.js.ic.ICCache
|
||||||
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
|
||||||
@@ -46,6 +47,7 @@ import org.jetbrains.kotlin.js.parser.sourcemaps.SourceMapParser
|
|||||||
import org.jetbrains.kotlin.js.parser.sourcemaps.SourceMapSuccess
|
import org.jetbrains.kotlin.js.parser.sourcemaps.SourceMapSuccess
|
||||||
import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver
|
import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver
|
||||||
import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder
|
import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder
|
||||||
|
import org.jetbrains.kotlin.js.test.engines.ExternalTool
|
||||||
import org.jetbrains.kotlin.js.sourceMap.SourceMapBuilderConsumer
|
import org.jetbrains.kotlin.js.sourceMap.SourceMapBuilderConsumer
|
||||||
import org.jetbrains.kotlin.js.test.utils.*
|
import org.jetbrains.kotlin.js.test.utils.*
|
||||||
import org.jetbrains.kotlin.js.util.TextOutputImpl
|
import org.jetbrains.kotlin.js.util.TextOutputImpl
|
||||||
@@ -153,7 +155,17 @@ abstract class BasicBoxTest(
|
|||||||
if (errorPolicyMatcher.find()) ErrorTolerancePolicy.resolvePolicy(errorPolicyMatcher.group(1)) else ErrorTolerancePolicy.DEFAULT
|
if (errorPolicyMatcher.find()) ErrorTolerancePolicy.resolvePolicy(errorPolicyMatcher.group(1)) else ErrorTolerancePolicy.DEFAULT
|
||||||
|
|
||||||
val skipDceDriven = SKIP_DCE_DRIVEN.matcher(fileContent).find()
|
val skipDceDriven = SKIP_DCE_DRIVEN.matcher(fileContent).find()
|
||||||
|
val esModules = ES_MODULES.matcher(fileContent).find()
|
||||||
|
|
||||||
val splitPerModule = SPLIT_PER_MODULE.matcher(fileContent).find()
|
val splitPerModule = SPLIT_PER_MODULE.matcher(fileContent).find()
|
||||||
|
val splitPerFile = SPLIT_PER_FILE.matcher(fileContent).find()
|
||||||
|
|
||||||
|
val granularity = when {
|
||||||
|
splitPerModule -> JsGenerationGranularity.PER_MODULE
|
||||||
|
splitPerFile -> JsGenerationGranularity.PER_FILE
|
||||||
|
else -> JsGenerationGranularity.WHOLE_PROGRAM
|
||||||
|
}
|
||||||
|
|
||||||
val skipMangleVerification = SKIP_MANGLE_VERIFICATION.matcher(fileContent).find()
|
val skipMangleVerification = SKIP_MANGLE_VERIFICATION.matcher(fileContent).find()
|
||||||
|
|
||||||
val safeExternalBoolean = SAFE_EXTERNAL_BOOLEAN.matcher(fileContent).find()
|
val safeExternalBoolean = SAFE_EXTERNAL_BOOLEAN.matcher(fileContent).find()
|
||||||
@@ -196,6 +208,12 @@ abstract class BasicBoxTest(
|
|||||||
val mainModule = modules[mainModuleName] ?: error("No module with name \"$mainModuleName\"")
|
val mainModule = modules[mainModuleName] ?: error("No module with name \"$mainModuleName\"")
|
||||||
val icCache = mutableMapOf<String, TestModuleCache>()
|
val icCache = mutableMapOf<String, TestModuleCache>()
|
||||||
|
|
||||||
|
if (esModules) {
|
||||||
|
modules.forEach { _, m -> m.moduleKind = ModuleKind.ES }
|
||||||
|
}
|
||||||
|
|
||||||
|
val customTestModule: String? = inputFiles.find { it.testEntryEsModule }?.let { File(it.fileName).readText() }
|
||||||
|
|
||||||
val generatedJsFiles = orderedModules.asReversed().mapNotNull { module ->
|
val generatedJsFiles = orderedModules.asReversed().mapNotNull { module ->
|
||||||
val dependencies = module.dependenciesSymbols.map { modules[it]?.outputFileName(outputDir) + ".meta.js" }
|
val dependencies = module.dependenciesSymbols.map { modules[it]?.outputFileName(outputDir) + ".meta.js" }
|
||||||
val allDependencies = module.allTransitiveDependencies().map { modules[it]?.outputFileName(outputDir) + ".meta.js" }
|
val allDependencies = module.allTransitiveDependencies().map { modules[it]?.outputFileName(outputDir) + ".meta.js" }
|
||||||
@@ -229,7 +247,8 @@ abstract class BasicBoxTest(
|
|||||||
isMainModule,
|
isMainModule,
|
||||||
expectActualLinker,
|
expectActualLinker,
|
||||||
skipDceDriven,
|
skipDceDriven,
|
||||||
splitPerModule,
|
esModules,
|
||||||
|
granularity,
|
||||||
errorPolicy,
|
errorPolicy,
|
||||||
propertyLazyInitialization = true,
|
propertyLazyInitialization = true,
|
||||||
safeExternalBoolean,
|
safeExternalBoolean,
|
||||||
@@ -237,7 +256,8 @@ abstract class BasicBoxTest(
|
|||||||
skipMangleVerification,
|
skipMangleVerification,
|
||||||
abiVersion,
|
abiVersion,
|
||||||
checkIC,
|
checkIC,
|
||||||
icCache
|
icCache,
|
||||||
|
customTestModule,
|
||||||
)
|
)
|
||||||
|
|
||||||
when {
|
when {
|
||||||
@@ -279,6 +299,7 @@ abstract class BasicBoxTest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val additionalFiles = mutableListOf<String>()
|
val additionalFiles = mutableListOf<String>()
|
||||||
|
val moduleEmulationFiles = mutableListOf<String>()
|
||||||
|
|
||||||
val moduleKindMatcher = MODULE_KIND_PATTERN.matcher(fileContent)
|
val moduleKindMatcher = MODULE_KIND_PATTERN.matcher(fileContent)
|
||||||
val moduleKind = if (moduleKindMatcher.find()) ModuleKind.valueOf(moduleKindMatcher.group(1)) else ModuleKind.PLAIN
|
val moduleKind = if (moduleKindMatcher.find()) ModuleKind.valueOf(moduleKindMatcher.group(1)) else ModuleKind.PLAIN
|
||||||
@@ -286,7 +307,7 @@ abstract class BasicBoxTest(
|
|||||||
val withModuleSystem = moduleKind != ModuleKind.PLAIN && !NO_MODULE_SYSTEM_PATTERN.matcher(fileContent).find()
|
val withModuleSystem = moduleKind != ModuleKind.PLAIN && !NO_MODULE_SYSTEM_PATTERN.matcher(fileContent).find()
|
||||||
|
|
||||||
if (withModuleSystem) {
|
if (withModuleSystem) {
|
||||||
additionalFiles += MODULE_EMULATION_FILE
|
moduleEmulationFiles += MODULE_EMULATION_FILE
|
||||||
}
|
}
|
||||||
|
|
||||||
val additionalJsFile = filePath.removeSuffix("." + KotlinFileType.EXTENSION) + JavaScript.DOT_EXTENSION
|
val additionalJsFile = filePath.removeSuffix("." + KotlinFileType.EXTENSION) + JavaScript.DOT_EXTENSION
|
||||||
@@ -294,6 +315,63 @@ abstract class BasicBoxTest(
|
|||||||
additionalFiles += additionalJsFile
|
additionalFiles += additionalJsFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (esModules) {
|
||||||
|
val additionalMainJsFile =
|
||||||
|
(filePath.removeSuffix("." + KotlinFileType.EXTENSION) + "__main.js").takeIf { File(it).exists() }
|
||||||
|
|
||||||
|
val maybeAdditionalMjsFile: String? =
|
||||||
|
(filePath.removeSuffix("." + KotlinFileType.EXTENSION) + ".mjs")
|
||||||
|
.takeIf { File(it).exists() }
|
||||||
|
|
||||||
|
val allMjsFiles: List<String> =
|
||||||
|
inputFiles.filter { it.fileName.endsWith(".mjs") }.map { it.fileName } + listOfNotNull(maybeAdditionalMjsFile)
|
||||||
|
|
||||||
|
val allNonEsModuleFiles: List<String> =
|
||||||
|
additionalFiles + inputJsFilesBefore + globalCommonFiles + localCommonFiles + additionalCommonFiles
|
||||||
|
|
||||||
|
fun runIrEsmTests(testOutputDir: File) {
|
||||||
|
val esmOutputDir = testOutputDir.esModulesSubDir
|
||||||
|
|
||||||
|
// Copy __main file if present
|
||||||
|
if (additionalMainJsFile != null) {
|
||||||
|
val newFileName = File(esmOutputDir, "test.mjs")
|
||||||
|
newFileName.delete()
|
||||||
|
File(additionalMainJsFile).copyTo(newFileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy all .mjs files into generated directory
|
||||||
|
allMjsFiles.forEach { mjsFile ->
|
||||||
|
val outFile = File(esmOutputDir, File(mjsFile).name)
|
||||||
|
File(mjsFile).copyTo(outFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
val perFileEsModuleFile = "$esmOutputDir/test.mjs"
|
||||||
|
v8tool.run(*allNonEsModuleFiles.toTypedArray(), perFileEsModuleFile, *inputJsFilesAfter.toTypedArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun File.getTestDir(): File =
|
||||||
|
File(generatedJsFiles.single().first.replace(outputDir.absolutePath, this.absolutePath))
|
||||||
|
|
||||||
|
if (!skipRegularMode) {
|
||||||
|
runIrEsmTests(outputDir.getTestDir())
|
||||||
|
|
||||||
|
if (runIrDce) {
|
||||||
|
runIrEsmTests(dceOutputDir.getTestDir())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runIrPir && !skipDceDriven) {
|
||||||
|
runIrEsmTests(pirOutputDir.getTestDir())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esModules)
|
||||||
|
return
|
||||||
|
|
||||||
|
// Old systems tests
|
||||||
|
|
||||||
|
additionalFiles.addAll(0, moduleEmulationFiles)
|
||||||
|
|
||||||
val additionalMainFiles = mutableListOf<String>()
|
val additionalMainFiles = mutableListOf<String>()
|
||||||
val additionalMainJsFile = filePath.removeSuffix("." + KotlinFileType.EXTENSION) + "__main.js"
|
val additionalMainJsFile = filePath.removeSuffix("." + KotlinFileType.EXTENSION) + "__main.js"
|
||||||
if (File(additionalMainJsFile).exists()) {
|
if (File(additionalMainJsFile).exists()) {
|
||||||
@@ -318,7 +396,6 @@ abstract class BasicBoxTest(
|
|||||||
} +
|
} +
|
||||||
globalCommonFiles + localCommonFiles + additionalCommonFiles + additionalMainFiles + inputJsFilesAfter
|
globalCommonFiles + localCommonFiles + additionalCommonFiles + additionalMainFiles + inputJsFilesAfter
|
||||||
|
|
||||||
|
|
||||||
val dontRunGeneratedCode =
|
val dontRunGeneratedCode =
|
||||||
InTextDirectivesUtils.dontRunGeneratedCode(targetBackend, file)
|
InTextDirectivesUtils.dontRunGeneratedCode(targetBackend, file)
|
||||||
|
|
||||||
@@ -501,7 +578,8 @@ abstract class BasicBoxTest(
|
|||||||
isMainModule: Boolean,
|
isMainModule: Boolean,
|
||||||
expectActualLinker: Boolean,
|
expectActualLinker: Boolean,
|
||||||
skipDceDriven: Boolean,
|
skipDceDriven: Boolean,
|
||||||
splitPerModule: Boolean,
|
esModules: Boolean,
|
||||||
|
granularity: JsGenerationGranularity,
|
||||||
errorIgnorancePolicy: ErrorTolerancePolicy,
|
errorIgnorancePolicy: ErrorTolerancePolicy,
|
||||||
propertyLazyInitialization: Boolean,
|
propertyLazyInitialization: Boolean,
|
||||||
safeExternalBoolean: Boolean,
|
safeExternalBoolean: Boolean,
|
||||||
@@ -509,7 +587,8 @@ abstract class BasicBoxTest(
|
|||||||
skipMangleVerification: Boolean,
|
skipMangleVerification: Boolean,
|
||||||
abiVersion: KotlinAbiVersion,
|
abiVersion: KotlinAbiVersion,
|
||||||
checkIC: Boolean,
|
checkIC: Boolean,
|
||||||
icCache: MutableMap<String, TestModuleCache>
|
icCache: MutableMap<String, TestModuleCache>,
|
||||||
|
customTestModule: String?,
|
||||||
) {
|
) {
|
||||||
val kotlinFiles = module.files.filter { it.fileName.endsWith(".kt") }
|
val kotlinFiles = module.files.filter { it.fileName.endsWith(".kt") }
|
||||||
val testFiles = kotlinFiles.map { it.fileName }
|
val testFiles = kotlinFiles.map { it.fileName }
|
||||||
@@ -558,7 +637,8 @@ abstract class BasicBoxTest(
|
|||||||
needsFullIrRuntime,
|
needsFullIrRuntime,
|
||||||
isMainModule,
|
isMainModule,
|
||||||
skipDceDriven,
|
skipDceDriven,
|
||||||
splitPerModule,
|
esModules,
|
||||||
|
granularity,
|
||||||
propertyLazyInitialization,
|
propertyLazyInitialization,
|
||||||
safeExternalBoolean,
|
safeExternalBoolean,
|
||||||
safeExternalBooleanDiagnostic,
|
safeExternalBooleanDiagnostic,
|
||||||
@@ -566,7 +646,8 @@ abstract class BasicBoxTest(
|
|||||||
abiVersion,
|
abiVersion,
|
||||||
checkIC,
|
checkIC,
|
||||||
recompile = false,
|
recompile = false,
|
||||||
icCache
|
icCache,
|
||||||
|
customTestModule,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (incrementalCompilationChecksEnabled && module.hasFilesToRecompile) {
|
if (incrementalCompilationChecksEnabled && module.hasFilesToRecompile) {
|
||||||
@@ -661,7 +742,8 @@ abstract class BasicBoxTest(
|
|||||||
needsFullIrRuntime,
|
needsFullIrRuntime,
|
||||||
isMainModule = false,
|
isMainModule = false,
|
||||||
skipDceDriven = true,
|
skipDceDriven = true,
|
||||||
splitPerModule = false,
|
esModules = false,
|
||||||
|
granularity = JsGenerationGranularity.WHOLE_PROGRAM,
|
||||||
propertyLazyInitialization = true,
|
propertyLazyInitialization = true,
|
||||||
safeExternalBoolean = false,
|
safeExternalBoolean = false,
|
||||||
safeExternalBooleanDiagnostic = null,
|
safeExternalBooleanDiagnostic = null,
|
||||||
@@ -669,7 +751,8 @@ abstract class BasicBoxTest(
|
|||||||
abiVersion = KotlinAbiVersion.CURRENT,
|
abiVersion = KotlinAbiVersion.CURRENT,
|
||||||
incrementalCompilation = true,
|
incrementalCompilation = true,
|
||||||
recompile = true,
|
recompile = true,
|
||||||
mutableMapOf()
|
mutableMapOf(),
|
||||||
|
customTestModule = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
val originalOutput = FileUtil.loadFile(outputFile)
|
val originalOutput = FileUtil.loadFile(outputFile)
|
||||||
@@ -747,7 +830,8 @@ abstract class BasicBoxTest(
|
|||||||
needsFullIrRuntime: Boolean,
|
needsFullIrRuntime: Boolean,
|
||||||
isMainModule: Boolean,
|
isMainModule: Boolean,
|
||||||
skipDceDriven: Boolean,
|
skipDceDriven: Boolean,
|
||||||
splitPerModule: Boolean,
|
esModules: Boolean,
|
||||||
|
granularity: JsGenerationGranularity,
|
||||||
propertyLazyInitialization: Boolean,
|
propertyLazyInitialization: Boolean,
|
||||||
safeExternalBoolean: Boolean,
|
safeExternalBoolean: Boolean,
|
||||||
safeExternalBooleanDiagnostic: RuntimeDiagnostic?,
|
safeExternalBooleanDiagnostic: RuntimeDiagnostic?,
|
||||||
@@ -755,7 +839,8 @@ abstract class BasicBoxTest(
|
|||||||
abiVersion: KotlinAbiVersion,
|
abiVersion: KotlinAbiVersion,
|
||||||
incrementalCompilation: Boolean,
|
incrementalCompilation: Boolean,
|
||||||
recompile: Boolean,
|
recompile: Boolean,
|
||||||
icCache: MutableMap<String, TestModuleCache>
|
icCache: MutableMap<String, TestModuleCache>,
|
||||||
|
customTestModule: String?,
|
||||||
) {
|
) {
|
||||||
val translator = K2JSTranslator(config, false)
|
val translator = K2JSTranslator(config, false)
|
||||||
val translationResult = translator.translateUnits(ExceptionThrowingReporter, units, mainCallParameters)
|
val translationResult = translator.translateUnits(ExceptionThrowingReporter, units, mainCallParameters)
|
||||||
@@ -813,6 +898,8 @@ abstract class BasicBoxTest(
|
|||||||
"$content\n"
|
"$content\n"
|
||||||
|
|
||||||
ModuleKind.PLAIN -> content
|
ModuleKind.PLAIN -> content
|
||||||
|
|
||||||
|
ModuleKind.ES -> error("Module emulation markers are not supported for ES modules")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1082,7 +1169,8 @@ abstract class BasicBoxTest(
|
|||||||
temporaryFile.absolutePath,
|
temporaryFile.absolutePath,
|
||||||
currentModule,
|
currentModule,
|
||||||
recompile = RECOMPILE_PATTERN.matcher(text).find(),
|
recompile = RECOMPILE_PATTERN.matcher(text).find(),
|
||||||
packageName = ktFile.packageFqName.asString()
|
packageName = ktFile.packageFqName.asString(),
|
||||||
|
testEntryEsModule = ENTRY_ES_MODULE.matcher(text).find(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1099,7 +1187,7 @@ abstract class BasicBoxTest(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class TestFile(val fileName: String, val module: TestModule, val recompile: Boolean, val packageName: String) {
|
protected class TestFile(val fileName: String, val module: TestModule, val recompile: Boolean, val packageName: String, val testEntryEsModule: Boolean) {
|
||||||
init {
|
init {
|
||||||
module.files += this
|
module.files += this
|
||||||
}
|
}
|
||||||
@@ -1149,6 +1237,8 @@ abstract class BasicBoxTest(
|
|||||||
// Run top level box function
|
// Run top level box function
|
||||||
private val RUN_PLAIN_BOX_FUNCTION = Pattern.compile("^// *RUN_PLAIN_BOX_FUNCTION", Pattern.MULTILINE)
|
private val RUN_PLAIN_BOX_FUNCTION = Pattern.compile("^// *RUN_PLAIN_BOX_FUNCTION", Pattern.MULTILINE)
|
||||||
|
|
||||||
|
private val ENTRY_ES_MODULE = Pattern.compile("^// *ENTRY_ES_MODULE", Pattern.MULTILINE)
|
||||||
|
|
||||||
private val NO_INLINE_PATTERN = Pattern.compile("^// *NO_INLINE *$", Pattern.MULTILINE)
|
private val NO_INLINE_PATTERN = Pattern.compile("^// *NO_INLINE *$", Pattern.MULTILINE)
|
||||||
private val SKIP_NODE_JS = Pattern.compile("^// *SKIP_NODE_JS *$", Pattern.MULTILINE)
|
private val SKIP_NODE_JS = Pattern.compile("^// *SKIP_NODE_JS *$", Pattern.MULTILINE)
|
||||||
private val SKIP_MINIFICATION = Pattern.compile("^// *SKIP_MINIFICATION *$", Pattern.MULTILINE)
|
private val SKIP_MINIFICATION = Pattern.compile("^// *SKIP_MINIFICATION *$", Pattern.MULTILINE)
|
||||||
@@ -1163,7 +1253,10 @@ abstract class BasicBoxTest(
|
|||||||
private val WITH_STDLIB = Pattern.compile("^// *WITH_STDLIB *\$", Pattern.MULTILINE)
|
private val WITH_STDLIB = Pattern.compile("^// *WITH_STDLIB *\$", Pattern.MULTILINE)
|
||||||
private val EXPECT_ACTUAL_LINKER = Pattern.compile("^// EXPECT_ACTUAL_LINKER *$", Pattern.MULTILINE)
|
private val EXPECT_ACTUAL_LINKER = Pattern.compile("^// EXPECT_ACTUAL_LINKER *$", Pattern.MULTILINE)
|
||||||
private val SKIP_DCE_DRIVEN = Pattern.compile("^// *SKIP_DCE_DRIVEN *$", Pattern.MULTILINE)
|
private val SKIP_DCE_DRIVEN = Pattern.compile("^// *SKIP_DCE_DRIVEN *$", Pattern.MULTILINE)
|
||||||
|
private val ES_MODULES = Pattern.compile("^// *ES_MODULES *$", Pattern.MULTILINE)
|
||||||
|
|
||||||
private val SPLIT_PER_MODULE = Pattern.compile("^// *SPLIT_PER_MODULE *$", Pattern.MULTILINE)
|
private val SPLIT_PER_MODULE = Pattern.compile("^// *SPLIT_PER_MODULE *$", Pattern.MULTILINE)
|
||||||
|
private val SPLIT_PER_FILE = Pattern.compile("^// *SPLIT_PER_FILE *$", Pattern.MULTILINE)
|
||||||
private val SKIP_MANGLE_VERIFICATION = Pattern.compile("^// *SKIP_MANGLE_VERIFICATION *$", Pattern.MULTILINE)
|
private val SKIP_MANGLE_VERIFICATION = Pattern.compile("^// *SKIP_MANGLE_VERIFICATION *$", Pattern.MULTILINE)
|
||||||
|
|
||||||
private val ERROR_POLICY_PATTERN = Pattern.compile("^// *ERROR_POLICY: *(.+)$", Pattern.MULTILINE)
|
private val ERROR_POLICY_PATTERN = Pattern.compile("^// *ERROR_POLICY: *(.+)$", Pattern.MULTILINE)
|
||||||
@@ -1216,4 +1309,6 @@ fun RuntimeDiagnostic.Companion.resolve(
|
|||||||
else -> {
|
else -> {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val v8tool by lazy { ExternalTool(System.getProperty("javascript.engine.path.V8")) }
|
||||||
@@ -10,7 +10,14 @@ import org.jetbrains.kotlin.backend.common.phaser.AnyNamedPhase
|
|||||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.toPhaseMap
|
import org.jetbrains.kotlin.backend.common.phaser.toPhaseMap
|
||||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||||
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.ir.backend.js.*
|
import org.jetbrains.kotlin.ir.backend.js.*
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.codegen.CompilerOutputSink
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity.*
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationOptions
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.codegen.generateEsModules
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ic.*
|
import org.jetbrains.kotlin.ir.backend.js.ic.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
|
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
|
||||||
@@ -205,7 +212,8 @@ abstract class BasicIrBoxTest(
|
|||||||
needsFullIrRuntime: Boolean,
|
needsFullIrRuntime: Boolean,
|
||||||
isMainModule: Boolean,
|
isMainModule: Boolean,
|
||||||
skipDceDriven: Boolean,
|
skipDceDriven: Boolean,
|
||||||
splitPerModule: Boolean,
|
esModules: Boolean,
|
||||||
|
granularity: JsGenerationGranularity,
|
||||||
propertyLazyInitialization: Boolean,
|
propertyLazyInitialization: Boolean,
|
||||||
safeExternalBoolean: Boolean,
|
safeExternalBoolean: Boolean,
|
||||||
safeExternalBooleanDiagnostic: RuntimeDiagnostic?,
|
safeExternalBooleanDiagnostic: RuntimeDiagnostic?,
|
||||||
@@ -213,7 +221,8 @@ abstract class BasicIrBoxTest(
|
|||||||
abiVersion: KotlinAbiVersion,
|
abiVersion: KotlinAbiVersion,
|
||||||
incrementalCompilation: Boolean,
|
incrementalCompilation: Boolean,
|
||||||
recompile: Boolean,
|
recompile: Boolean,
|
||||||
icCache: MutableMap<String, TestModuleCache>
|
icCache: MutableMap<String, TestModuleCache>,
|
||||||
|
customTestModule: String?,
|
||||||
) {
|
) {
|
||||||
val filesToCompile = units.mapNotNull { (it as? TranslationUnit.SourceFile)?.file }
|
val filesToCompile = units.mapNotNull { (it as? TranslationUnit.SourceFile)?.file }
|
||||||
|
|
||||||
@@ -299,38 +308,73 @@ abstract class BasicIrBoxTest(
|
|||||||
icCache = emptyMap()
|
icCache = emptyMap()
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!skipRegularMode) {
|
|
||||||
// val dirtyFilesToRecompile = if (recompile) {
|
|
||||||
// units.map { (it as TranslationUnit.SourceFile).file.virtualFilePath }.toSet()
|
|
||||||
// } else null
|
|
||||||
val dirtyFilesToRecompile: Set<String>? = null
|
|
||||||
|
|
||||||
val compiledModule = compile(
|
val mainArguments = mainCallParameters.run { if (shouldBeGenerated()) arguments() else null }
|
||||||
|
fun compileToLoweredIr(
|
||||||
|
dceDriven: Boolean,
|
||||||
|
granularity: JsGenerationGranularity,
|
||||||
|
dirtyFilesToRecompile: Set<String>? = null
|
||||||
|
): LoweredIr =
|
||||||
|
compile(
|
||||||
module,
|
module,
|
||||||
phaseConfig = phaseConfig,
|
phaseConfig = phaseConfig,
|
||||||
irFactory = IrFactoryImpl,
|
irFactory = IrFactoryImpl,
|
||||||
mainArguments = mainCallParameters.run { if (shouldBeGenerated()) arguments() else null },
|
|
||||||
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, testFunction))),
|
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, testFunction))),
|
||||||
generateFullJs = true,
|
dceDriven = dceDriven,
|
||||||
generateDceJs = runIrDce,
|
|
||||||
dceDriven = false,
|
|
||||||
es6mode = runEs6Mode,
|
es6mode = runEs6Mode,
|
||||||
multiModule = splitPerModule || perModule,
|
|
||||||
propertyLazyInitialization = propertyLazyInitialization,
|
propertyLazyInitialization = propertyLazyInitialization,
|
||||||
|
verifySignatures = !skipMangleVerification,
|
||||||
lowerPerModule = lowerPerModule,
|
lowerPerModule = lowerPerModule,
|
||||||
safeExternalBoolean = safeExternalBoolean,
|
safeExternalBoolean = safeExternalBoolean,
|
||||||
safeExternalBooleanDiagnostic = safeExternalBooleanDiagnostic,
|
safeExternalBooleanDiagnostic = safeExternalBooleanDiagnostic,
|
||||||
verifySignatures = !skipMangleVerification,
|
granularity = granularity,
|
||||||
filesToLower = dirtyFilesToRecompile
|
filesToLower = dirtyFilesToRecompile
|
||||||
)
|
)
|
||||||
|
|
||||||
// if (incrementalCompilation) {
|
fun generateTestFile(outputDir: File) {
|
||||||
// // TODO: enable once incremental js generation is done
|
val moduleName = config.configuration[CommonConfigurationKeys.MODULE_NAME]
|
||||||
// generateJsFromAst(klibPath, icCache.map { it.key to it.value.createModuleCache() }.toMap())
|
val esmTestFile = File(outputDir, "test.mjs")
|
||||||
// }
|
logger.logFile("ES module test file", esmTestFile)
|
||||||
|
val defaultTestModule =
|
||||||
|
"""
|
||||||
|
import { box } from './${moduleName}/index.js';
|
||||||
|
let res = box();
|
||||||
|
if (res !== "OK") {
|
||||||
|
throw "Wrong result: " + String(res);
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
val jsOutputFile = if (recompile) File(outputFile.parentFile, outputFile.nameWithoutExtension + "-recompiled.js")
|
esmTestFile.writeText(customTestModule ?: defaultTestModule)
|
||||||
else outputFile
|
}
|
||||||
|
|
||||||
|
val options = JsGenerationOptions(generatePackageJson = true, generateTypeScriptDefinitions = generateDts)
|
||||||
|
|
||||||
|
fun generateEsModules(ir: LoweredIr, outputDir: File, granularity: JsGenerationGranularity) {
|
||||||
|
outputDir.deleteRecursively()
|
||||||
|
generateEsModules(ir, jsOutputSink(outputDir), mainArguments = mainArguments, granularity = granularity, options = options)
|
||||||
|
generateTestFile(outputDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateOldModuleSystems(
|
||||||
|
ir: LoweredIr,
|
||||||
|
outputFile: File,
|
||||||
|
outputDceFile: File,
|
||||||
|
granularity: JsGenerationGranularity,
|
||||||
|
runDce: Boolean,
|
||||||
|
dirtyFilesToRecompile: Set<String>? = null
|
||||||
|
) {
|
||||||
|
outputFile.deleteRecursively()
|
||||||
|
|
||||||
|
check(granularity != PER_FILE) { "Per file granularity is not supported for old module systems" }
|
||||||
|
val transformer = IrModuleToJsTransformer(
|
||||||
|
ir.context,
|
||||||
|
mainArguments,
|
||||||
|
fullJs = true,
|
||||||
|
dceJs = runDce,
|
||||||
|
multiModule = granularity == PER_MODULE,
|
||||||
|
relativeRequirePath = false
|
||||||
|
)
|
||||||
|
val compiledModule: CompilerResult = transformer.generateModule(ir.allModules)
|
||||||
|
|
||||||
val compiledOutput = if (dirtyFilesToRecompile != null) CompilationOutputs(
|
val compiledOutput = if (dirtyFilesToRecompile != null) CompilationOutputs(
|
||||||
"""
|
"""
|
||||||
@@ -343,9 +387,9 @@ abstract class BasicIrBoxTest(
|
|||||||
) else compiledModule.outputs!!
|
) else compiledModule.outputs!!
|
||||||
val compiledDCEOutput = if (dirtyFilesToRecompile != null) null else compiledModule.outputsAfterDce
|
val compiledDCEOutput = if (dirtyFilesToRecompile != null) null else compiledModule.outputsAfterDce
|
||||||
|
|
||||||
compiledOutput.writeTo(jsOutputFile, config)
|
compiledOutput.writeTo(outputFile, config)
|
||||||
|
|
||||||
compiledDCEOutput?.writeTo(dceOutputFile, config)
|
compiledDCEOutput?.writeTo(outputDceFile, config)
|
||||||
|
|
||||||
if (generateDts) {
|
if (generateDts) {
|
||||||
val dtsFile = outputFile.withReplacedExtensionOrNull("_v5.js", ".d.ts")!!
|
val dtsFile = outputFile.withReplacedExtensionOrNull("_v5.js", ".d.ts")!!
|
||||||
@@ -356,26 +400,31 @@ abstract class BasicIrBoxTest(
|
|||||||
compiledOutput.jsProgram?.let { processJsProgram(it, units) }
|
compiledOutput.jsProgram?.let { processJsProgram(it, units) }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runIrPir) {
|
@Suppress("NAME_SHADOWING")
|
||||||
val compiledModule = compile(
|
val granularity = if (perModule) PER_MODULE else granularity
|
||||||
module,
|
|
||||||
phaseConfig = phaseConfig,
|
if (!skipRegularMode) {
|
||||||
irFactory = PersistentIrFactory(),
|
val ir = compileToLoweredIr(dceDriven = false, granularity)
|
||||||
mainArguments = mainCallParameters.run { if (shouldBeGenerated()) arguments() else null },
|
if (esModules) {
|
||||||
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, testFunction))),
|
generateEsModules(ir, outputFile.esModulesSubDir, granularity)
|
||||||
generateFullJs = true,
|
if (runIrDce) {
|
||||||
generateDceJs = runIrDce,
|
eliminateDeadDeclarations(ir.allModules, ir.context)
|
||||||
dceDriven = true,
|
generateEsModules(ir, dceOutputFile.esModulesSubDir, granularity)
|
||||||
es6mode = runEs6Mode,
|
}
|
||||||
multiModule = splitPerModule || perModule,
|
} else {
|
||||||
propertyLazyInitialization = propertyLazyInitialization,
|
val jsOutputFile = if (recompile) File(outputFile.parentFile, outputFile.nameWithoutExtension + "-recompiled.js")
|
||||||
lowerPerModule = lowerPerModule,
|
else outputFile
|
||||||
safeExternalBoolean = safeExternalBoolean,
|
generateOldModuleSystems(ir, jsOutputFile, dceOutputFile, granularity, runIrDce)
|
||||||
safeExternalBooleanDiagnostic = safeExternalBooleanDiagnostic,
|
}
|
||||||
verifySignatures = !skipMangleVerification,
|
}
|
||||||
)
|
|
||||||
compiledModule.outputs!!.writeTo(pirOutputFile, config)
|
if (runIrPir && !skipDceDriven) {
|
||||||
processJsProgram(compiledModule.outputs!!.jsProgram!!, units)
|
val ir = compileToLoweredIr(dceDriven = true, granularity)
|
||||||
|
if (esModules) {
|
||||||
|
generateEsModules(ir, pirOutputFile.esModulesSubDir, granularity)
|
||||||
|
} else {
|
||||||
|
generateOldModuleSystems(ir, pirOutputFile, pirOutputFile, granularity, false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -453,15 +502,19 @@ abstract class BasicIrBoxTest(
|
|||||||
needsFullIrRuntime,
|
needsFullIrRuntime,
|
||||||
isMainModule,
|
isMainModule,
|
||||||
skipDceDriven = true,
|
skipDceDriven = true,
|
||||||
splitPerModule = false, // TODO??
|
granularity = WHOLE_PROGRAM, // TODO??
|
||||||
propertyLazyInitialization = true,
|
propertyLazyInitialization = true,
|
||||||
safeExternalBoolean = false,
|
safeExternalBoolean = false,
|
||||||
safeExternalBooleanDiagnostic = null,
|
safeExternalBooleanDiagnostic = null,
|
||||||
skipMangleVerification = false,
|
skipMangleVerification = false,
|
||||||
KotlinAbiVersion.CURRENT,
|
abiVersion = KotlinAbiVersion.CURRENT,
|
||||||
incrementalCompilation = true,
|
incrementalCompilation = true,
|
||||||
recompile = true,
|
recompile = true,
|
||||||
icCaches
|
icCache = icCaches,
|
||||||
|
|
||||||
|
// TODO??
|
||||||
|
customTestModule = null,
|
||||||
|
esModules = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
val cacheProvider = icCache.cacheProvider()
|
val cacheProvider = icCache.cacheProvider()
|
||||||
@@ -481,6 +534,19 @@ abstract class BasicIrBoxTest(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun jsOutputSink(perFileOutputDir: File): CompilerOutputSink {
|
||||||
|
perFileOutputDir.deleteRecursively()
|
||||||
|
perFileOutputDir.mkdirs()
|
||||||
|
|
||||||
|
return object : CompilerOutputSink {
|
||||||
|
override fun write(module: String, path: String, content: String) {
|
||||||
|
val file = File(File(perFileOutputDir, module), path)
|
||||||
|
file.parentFile.mkdirs()
|
||||||
|
file.writeText(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun createIcCache(
|
private fun createIcCache(
|
||||||
path: String,
|
path: String,
|
||||||
dirtyFiles: Collection<String>?,
|
dirtyFiles: Collection<String>?,
|
||||||
@@ -561,8 +627,10 @@ abstract class BasicIrBoxTest(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun File.write(text: String) {
|
private fun File.write(text: String) {
|
||||||
parentFile.mkdirs()
|
parentFile.mkdirs()
|
||||||
writeText(text)
|
writeText(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val File.esModulesSubDir: File
|
||||||
|
get() = File(absolutePath + "_esm")
|
||||||
|
|||||||
@@ -7,8 +7,12 @@ package org.jetbrains.kotlin.js.test.engines
|
|||||||
|
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
|
import java.lang.Boolean.getBoolean
|
||||||
import kotlin.test.fail
|
import kotlin.test.fail
|
||||||
|
|
||||||
|
|
||||||
|
val toolLogsEnabled: Boolean = getBoolean("kotlin.js.test.verbose")
|
||||||
|
|
||||||
class ExternalTool(val path: String) {
|
class ExternalTool(val path: String) {
|
||||||
fun run(vararg arguments: String) {
|
fun run(vararg arguments: String) {
|
||||||
val command = arrayOf(path, *arguments)
|
val command = arrayOf(path, *arguments)
|
||||||
@@ -17,7 +21,9 @@ class ExternalTool(val path: String) {
|
|||||||
.start()
|
.start()
|
||||||
|
|
||||||
val commandString = command.joinToString(" ") { escapeShellArgument(it) }
|
val commandString = command.joinToString(" ") { escapeShellArgument(it) }
|
||||||
println(commandString)
|
if (toolLogsEnabled) {
|
||||||
|
println(commandString)
|
||||||
|
}
|
||||||
|
|
||||||
// Print process output
|
// Print process output
|
||||||
val input = BufferedReader(InputStreamReader(process.inputStream))
|
val input = BufferedReader(InputStreamReader(process.inputStream))
|
||||||
|
|||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2020 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.js.test.semantics
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.js.test.BasicBoxTest
|
|
||||||
|
|
||||||
abstract class AbstractLegacyJsTypeScriptExportTest : BasicBoxTest(
|
|
||||||
pathToTestDir = TEST_DATA_DIR_PATH + "typescript-export/",
|
|
||||||
testGroupOutputDirPrefix = "legacy-typescript-export/"
|
|
||||||
)
|
|
||||||
Generated
+488
-10
@@ -1587,6 +1587,494 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class EsModules extends AbstractIrBoxJsES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInEsModules() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/crossModuleRef")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class CrossModuleRef extends AbstractIrBoxJsES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInCrossModuleRef() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/crossModuleRef"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("callableObjectRef.kt")
|
||||||
|
public void testCallableObjectRef() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/callableObjectRef.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("constructor.kt")
|
||||||
|
public void testConstructor() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/constructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inheritance.kt")
|
||||||
|
public void testInheritance() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/inheritance.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineJsModule.kt")
|
||||||
|
public void testInlineJsModule() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/inlineJsModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineJsModuleNonIdentifier.kt")
|
||||||
|
public void testInlineJsModuleNonIdentifier() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/inlineJsModuleNonIdentifier.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineJsModulePackage.kt")
|
||||||
|
public void testInlineJsModulePackage() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/inlineJsModulePackage.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineModule.kt")
|
||||||
|
public void testInlineModule() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/inlineModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineModuleNonIndentifier.kt")
|
||||||
|
public void testInlineModuleNonIndentifier() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/inlineModuleNonIndentifier.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambda.kt")
|
||||||
|
public void testLambda() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/lambda.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("object.kt")
|
||||||
|
public void testObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/object.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("objectInInlineClosure.kt")
|
||||||
|
public void testObjectInInlineClosure() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/objectInInlineClosure.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("objectIsObject.kt")
|
||||||
|
public void testObjectIsObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/objectIsObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelExtension.kt")
|
||||||
|
public void testTopLevelExtension() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/topLevelExtension.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelMutableProperty.kt")
|
||||||
|
public void testTopLevelMutableProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/topLevelMutableProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelProperty.kt")
|
||||||
|
public void testTopLevelProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/topLevelProperty.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/crossModuleRefPerFile")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class CrossModuleRefPerFile extends AbstractIrBoxJsES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInCrossModuleRefPerFile() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/crossModuleRefPerFile"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("callableObjectRef.kt")
|
||||||
|
public void testCallableObjectRef() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/callableObjectRef.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("constructor.kt")
|
||||||
|
public void testConstructor() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/constructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inheritance.kt")
|
||||||
|
public void testInheritance() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/inheritance.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineModule.kt")
|
||||||
|
public void testInlineModule() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/inlineModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineModuleNonIndentifier.kt")
|
||||||
|
public void testInlineModuleNonIndentifier() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/inlineModuleNonIndentifier.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambda.kt")
|
||||||
|
public void testLambda() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/lambda.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("object.kt")
|
||||||
|
public void testObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/object.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("objectInInlineClosure.kt")
|
||||||
|
public void testObjectInInlineClosure() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/objectInInlineClosure.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("objectIsObject.kt")
|
||||||
|
public void testObjectIsObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/objectIsObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelExtension.kt")
|
||||||
|
public void testTopLevelExtension() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/topLevelExtension.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelMutableProperty.kt")
|
||||||
|
public void testTopLevelMutableProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/topLevelMutableProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelProperty.kt")
|
||||||
|
public void testTopLevelProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/topLevelProperty.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/crossModuleRefPerModule")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class CrossModuleRefPerModule extends AbstractIrBoxJsES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInCrossModuleRefPerModule() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/crossModuleRefPerModule"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("callableObjectRef.kt")
|
||||||
|
public void testCallableObjectRef() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/callableObjectRef.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("constructor.kt")
|
||||||
|
public void testConstructor() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/constructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inheritance.kt")
|
||||||
|
public void testInheritance() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/inheritance.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineModule.kt")
|
||||||
|
public void testInlineModule() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/inlineModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineModuleNonIndentifier.kt")
|
||||||
|
public void testInlineModuleNonIndentifier() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/inlineModuleNonIndentifier.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambda.kt")
|
||||||
|
public void testLambda() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/lambda.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("object.kt")
|
||||||
|
public void testObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/object.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("objectInInlineClosure.kt")
|
||||||
|
public void testObjectInInlineClosure() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/objectInInlineClosure.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("objectIsObject.kt")
|
||||||
|
public void testObjectIsObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/objectIsObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelExtension.kt")
|
||||||
|
public void testTopLevelExtension() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/topLevelExtension.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelMutableProperty.kt")
|
||||||
|
public void testTopLevelMutableProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/topLevelMutableProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelProperty.kt")
|
||||||
|
public void testTopLevelProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/topLevelProperty.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/export")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Export extends AbstractIrBoxJsES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInExport() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/export"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("exportAllFile.kt")
|
||||||
|
public void testExportAllFile() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/exportAllFile.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nonIndetifierModuleName.kt")
|
||||||
|
public void testNonIndetifierModuleName() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/nonIndetifierModuleName.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overriddenChainNonExportIntermediate.kt")
|
||||||
|
public void testOverriddenChainNonExportIntermediate() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/overriddenChainNonExportIntermediate.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overriddenExternalMethodWithSameNameMethod.kt")
|
||||||
|
public void testOverriddenExternalMethodWithSameNameMethod() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/overriddenExternalMethodWithSameNameMethod.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overriddenExternalMethodWithSameStableNameMethod.kt")
|
||||||
|
public void testOverriddenExternalMethodWithSameStableNameMethod() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/overriddenExternalMethodWithSameStableNameMethod.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reservedModuleName.kt")
|
||||||
|
public void testReservedModuleName() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/reservedModuleName.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/incremental")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Incremental extends AbstractIrBoxJsES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInIncremental() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/incremental"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jsModule.kt")
|
||||||
|
public void testJsModule() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/incremental/jsModule.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/inline")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Inline extends AbstractIrBoxJsES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInInline() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/inline"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlinedObjectLiteralIsCheck.kt")
|
||||||
|
public void testInlinedObjectLiteralIsCheck() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/inline/inlinedObjectLiteralIsCheck.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/jsExport")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JsExport extends AbstractIrBoxJsES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJsExport() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/jsExport"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("dataClass.kt")
|
||||||
|
public void testDataClass() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsExport/dataClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("exportedDefaultStub.kt")
|
||||||
|
public void testExportedDefaultStub() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsExport/exportedDefaultStub.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jsExportInClass.kt")
|
||||||
|
public void testJsExportInClass() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsExport/jsExportInClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("recursiveExport.kt")
|
||||||
|
public void testRecursiveExport() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsExport/recursiveExport.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/jsModule")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JsModule extends AbstractIrBoxJsES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJsModule() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/jsModule"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalClass.kt")
|
||||||
|
public void testExternalClass() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalClassNameClash.kt")
|
||||||
|
public void testExternalClassNameClash() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalClassNameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalClassWithDefaults.kt")
|
||||||
|
public void testExternalClassWithDefaults() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalClassWithDefaults.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalConstructor.kt")
|
||||||
|
public void testExternalConstructor() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalFunction.kt")
|
||||||
|
public void testExternalFunction() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalFunctionNameClash.kt")
|
||||||
|
public void testExternalFunctionNameClash() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalFunctionNameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalObject.kt")
|
||||||
|
public void testExternalObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalPackage.kt")
|
||||||
|
public void testExternalPackage() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalPackage.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalPackageInDifferentFile.kt")
|
||||||
|
public void testExternalPackageInDifferentFile() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalPackageInDifferentFile.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalProperty.kt")
|
||||||
|
public void testExternalProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("interfaces.kt")
|
||||||
|
public void testInterfaces() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/interfaces.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelVarargFun.kt")
|
||||||
|
public void testTopLevelVarargFun() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/topLevelVarargFun.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/jsName")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JsName extends AbstractIrBoxJsES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJsName() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/jsName"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultJsName.kt")
|
||||||
|
public void testDefaultJsName() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsName/defaultJsName.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jsTopLevelClashes.kt")
|
||||||
|
public void testJsTopLevelClashes() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsName/jsTopLevelClashes.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/native")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Native extends AbstractIrBoxJsES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNative() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/native"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inheritanceInNativeClass.kt")
|
||||||
|
public void testInheritanceInNativeClass() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/native/inheritanceInNativeClass.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("js/js.translator/testData/box/examples")
|
@TestMetadata("js/js.translator/testData/box/examples")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
@@ -2385,21 +2873,11 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
|
|||||||
runTest("js/js.translator/testData/box/expression/function/manglingClashFunctionsAndClasses.kt");
|
runTest("js/js.translator/testData/box/expression/function/manglingClashFunctionsAndClasses.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("manglingClashWithFunctionsWithoutParameters.kt")
|
|
||||||
public void testManglingClashWithFunctionsWithoutParameters() throws Exception {
|
|
||||||
runTest("js/js.translator/testData/box/expression/function/manglingClashWithFunctionsWithoutParameters.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("manglingImportedFromObjectWithNI.kt")
|
@TestMetadata("manglingImportedFromObjectWithNI.kt")
|
||||||
public void testManglingImportedFromObjectWithNI() throws Exception {
|
public void testManglingImportedFromObjectWithNI() throws Exception {
|
||||||
runTest("js/js.translator/testData/box/expression/function/manglingImportedFromObjectWithNI.kt");
|
runTest("js/js.translator/testData/box/expression/function/manglingImportedFromObjectWithNI.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("manglingStability.kt")
|
|
||||||
public void testManglingStability() throws Exception {
|
|
||||||
runTest("js/js.translator/testData/box/expression/function/manglingStability.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("namedArguments.kt")
|
@TestMetadata("namedArguments.kt")
|
||||||
public void testNamedArguments() throws Exception {
|
public void testNamedArguments() throws Exception {
|
||||||
runTest("js/js.translator/testData/box/expression/function/namedArguments.kt");
|
runTest("js/js.translator/testData/box/expression/function/namedArguments.kt");
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
-5
@@ -20145,11 +20145,6 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
|||||||
runTest("compiler/testData/codegen/box/properties/lazyInitializationOrder.kt");
|
runTest("compiler/testData/codegen/box/properties/lazyInitializationOrder.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("lazyInitializationPure.kt")
|
|
||||||
public void testLazyInitializationPure() throws Exception {
|
|
||||||
runTest("compiler/testData/codegen/box/properties/lazyInitializationPure.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("lazyInitializationSplitPerModule.kt")
|
@TestMetadata("lazyInitializationSplitPerModule.kt")
|
||||||
public void testLazyInitializationSplitPerModule() throws Exception {
|
public void testLazyInitializationSplitPerModule() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/properties/lazyInitializationSplitPerModule.kt");
|
runTest("compiler/testData/codegen/box/properties/lazyInitializationSplitPerModule.kt");
|
||||||
|
|||||||
+488
-10
@@ -1587,6 +1587,494 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class EsModules extends AbstractIrBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInEsModules() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/crossModuleRef")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class CrossModuleRef extends AbstractIrBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInCrossModuleRef() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/crossModuleRef"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("callableObjectRef.kt")
|
||||||
|
public void testCallableObjectRef() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/callableObjectRef.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("constructor.kt")
|
||||||
|
public void testConstructor() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/constructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inheritance.kt")
|
||||||
|
public void testInheritance() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/inheritance.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineJsModule.kt")
|
||||||
|
public void testInlineJsModule() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/inlineJsModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineJsModuleNonIdentifier.kt")
|
||||||
|
public void testInlineJsModuleNonIdentifier() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/inlineJsModuleNonIdentifier.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineJsModulePackage.kt")
|
||||||
|
public void testInlineJsModulePackage() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/inlineJsModulePackage.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineModule.kt")
|
||||||
|
public void testInlineModule() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/inlineModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineModuleNonIndentifier.kt")
|
||||||
|
public void testInlineModuleNonIndentifier() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/inlineModuleNonIndentifier.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambda.kt")
|
||||||
|
public void testLambda() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/lambda.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("object.kt")
|
||||||
|
public void testObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/object.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("objectInInlineClosure.kt")
|
||||||
|
public void testObjectInInlineClosure() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/objectInInlineClosure.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("objectIsObject.kt")
|
||||||
|
public void testObjectIsObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/objectIsObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelExtension.kt")
|
||||||
|
public void testTopLevelExtension() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/topLevelExtension.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelMutableProperty.kt")
|
||||||
|
public void testTopLevelMutableProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/topLevelMutableProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelProperty.kt")
|
||||||
|
public void testTopLevelProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRef/topLevelProperty.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/crossModuleRefPerFile")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class CrossModuleRefPerFile extends AbstractIrBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInCrossModuleRefPerFile() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/crossModuleRefPerFile"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("callableObjectRef.kt")
|
||||||
|
public void testCallableObjectRef() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/callableObjectRef.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("constructor.kt")
|
||||||
|
public void testConstructor() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/constructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inheritance.kt")
|
||||||
|
public void testInheritance() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/inheritance.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineModule.kt")
|
||||||
|
public void testInlineModule() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/inlineModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineModuleNonIndentifier.kt")
|
||||||
|
public void testInlineModuleNonIndentifier() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/inlineModuleNonIndentifier.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambda.kt")
|
||||||
|
public void testLambda() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/lambda.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("object.kt")
|
||||||
|
public void testObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/object.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("objectInInlineClosure.kt")
|
||||||
|
public void testObjectInInlineClosure() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/objectInInlineClosure.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("objectIsObject.kt")
|
||||||
|
public void testObjectIsObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/objectIsObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelExtension.kt")
|
||||||
|
public void testTopLevelExtension() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/topLevelExtension.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelMutableProperty.kt")
|
||||||
|
public void testTopLevelMutableProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/topLevelMutableProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelProperty.kt")
|
||||||
|
public void testTopLevelProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerFile/topLevelProperty.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/crossModuleRefPerModule")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class CrossModuleRefPerModule extends AbstractIrBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInCrossModuleRefPerModule() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/crossModuleRefPerModule"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("callableObjectRef.kt")
|
||||||
|
public void testCallableObjectRef() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/callableObjectRef.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("constructor.kt")
|
||||||
|
public void testConstructor() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/constructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inheritance.kt")
|
||||||
|
public void testInheritance() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/inheritance.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineModule.kt")
|
||||||
|
public void testInlineModule() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/inlineModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineModuleNonIndentifier.kt")
|
||||||
|
public void testInlineModuleNonIndentifier() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/inlineModuleNonIndentifier.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambda.kt")
|
||||||
|
public void testLambda() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/lambda.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("object.kt")
|
||||||
|
public void testObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/object.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("objectInInlineClosure.kt")
|
||||||
|
public void testObjectInInlineClosure() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/objectInInlineClosure.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("objectIsObject.kt")
|
||||||
|
public void testObjectIsObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/objectIsObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelExtension.kt")
|
||||||
|
public void testTopLevelExtension() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/topLevelExtension.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelMutableProperty.kt")
|
||||||
|
public void testTopLevelMutableProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/topLevelMutableProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelProperty.kt")
|
||||||
|
public void testTopLevelProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/crossModuleRefPerModule/topLevelProperty.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/export")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Export extends AbstractIrBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInExport() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/export"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("exportAllFile.kt")
|
||||||
|
public void testExportAllFile() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/exportAllFile.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nonIndetifierModuleName.kt")
|
||||||
|
public void testNonIndetifierModuleName() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/nonIndetifierModuleName.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overriddenChainNonExportIntermediate.kt")
|
||||||
|
public void testOverriddenChainNonExportIntermediate() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/overriddenChainNonExportIntermediate.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overriddenExternalMethodWithSameNameMethod.kt")
|
||||||
|
public void testOverriddenExternalMethodWithSameNameMethod() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/overriddenExternalMethodWithSameNameMethod.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overriddenExternalMethodWithSameStableNameMethod.kt")
|
||||||
|
public void testOverriddenExternalMethodWithSameStableNameMethod() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/overriddenExternalMethodWithSameStableNameMethod.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reservedModuleName.kt")
|
||||||
|
public void testReservedModuleName() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/reservedModuleName.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/incremental")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Incremental extends AbstractIrBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInIncremental() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/incremental"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jsModule.kt")
|
||||||
|
public void testJsModule() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/incremental/jsModule.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/inline")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Inline extends AbstractIrBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInInline() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/inline"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlinedObjectLiteralIsCheck.kt")
|
||||||
|
public void testInlinedObjectLiteralIsCheck() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/inline/inlinedObjectLiteralIsCheck.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/jsExport")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JsExport extends AbstractIrBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJsExport() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/jsExport"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("dataClass.kt")
|
||||||
|
public void testDataClass() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsExport/dataClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("exportedDefaultStub.kt")
|
||||||
|
public void testExportedDefaultStub() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsExport/exportedDefaultStub.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jsExportInClass.kt")
|
||||||
|
public void testJsExportInClass() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsExport/jsExportInClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("recursiveExport.kt")
|
||||||
|
public void testRecursiveExport() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsExport/recursiveExport.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/jsModule")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JsModule extends AbstractIrBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJsModule() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/jsModule"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalClass.kt")
|
||||||
|
public void testExternalClass() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalClassNameClash.kt")
|
||||||
|
public void testExternalClassNameClash() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalClassNameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalClassWithDefaults.kt")
|
||||||
|
public void testExternalClassWithDefaults() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalClassWithDefaults.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalConstructor.kt")
|
||||||
|
public void testExternalConstructor() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalFunction.kt")
|
||||||
|
public void testExternalFunction() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalFunctionNameClash.kt")
|
||||||
|
public void testExternalFunctionNameClash() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalFunctionNameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalObject.kt")
|
||||||
|
public void testExternalObject() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalPackage.kt")
|
||||||
|
public void testExternalPackage() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalPackage.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalPackageInDifferentFile.kt")
|
||||||
|
public void testExternalPackageInDifferentFile() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalPackageInDifferentFile.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("externalProperty.kt")
|
||||||
|
public void testExternalProperty() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/externalProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("interfaces.kt")
|
||||||
|
public void testInterfaces() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/interfaces.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevelVarargFun.kt")
|
||||||
|
public void testTopLevelVarargFun() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/topLevelVarargFun.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/jsName")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JsName extends AbstractIrBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJsName() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/jsName"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultJsName.kt")
|
||||||
|
public void testDefaultJsName() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsName/defaultJsName.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jsTopLevelClashes.kt")
|
||||||
|
public void testJsTopLevelClashes() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsName/jsTopLevelClashes.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/native")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Native extends AbstractIrBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNative() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/native"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inheritanceInNativeClass.kt")
|
||||||
|
public void testInheritanceInNativeClass() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/native/inheritanceInNativeClass.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("js/js.translator/testData/box/examples")
|
@TestMetadata("js/js.translator/testData/box/examples")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
@@ -2385,21 +2873,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
runTest("js/js.translator/testData/box/expression/function/manglingClashFunctionsAndClasses.kt");
|
runTest("js/js.translator/testData/box/expression/function/manglingClashFunctionsAndClasses.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("manglingClashWithFunctionsWithoutParameters.kt")
|
|
||||||
public void testManglingClashWithFunctionsWithoutParameters() throws Exception {
|
|
||||||
runTest("js/js.translator/testData/box/expression/function/manglingClashWithFunctionsWithoutParameters.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("manglingImportedFromObjectWithNI.kt")
|
@TestMetadata("manglingImportedFromObjectWithNI.kt")
|
||||||
public void testManglingImportedFromObjectWithNI() throws Exception {
|
public void testManglingImportedFromObjectWithNI() throws Exception {
|
||||||
runTest("js/js.translator/testData/box/expression/function/manglingImportedFromObjectWithNI.kt");
|
runTest("js/js.translator/testData/box/expression/function/manglingImportedFromObjectWithNI.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("manglingStability.kt")
|
|
||||||
public void testManglingStability() throws Exception {
|
|
||||||
runTest("js/js.translator/testData/box/expression/function/manglingStability.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("namedArguments.kt")
|
@TestMetadata("namedArguments.kt")
|
||||||
public void testNamedArguments() throws Exception {
|
public void testNamedArguments() throws Exception {
|
||||||
runTest("js/js.translator/testData/box/expression/function/namedArguments.kt");
|
runTest("js/js.translator/testData/box/expression/function/namedArguments.kt");
|
||||||
|
|||||||
Generated
-5
@@ -19551,11 +19551,6 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/properties/lazyInitializationOrder.kt");
|
runTest("compiler/testData/codegen/box/properties/lazyInitializationOrder.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("lazyInitializationPure.kt")
|
|
||||||
public void testLazyInitializationPure() throws Exception {
|
|
||||||
runTest("compiler/testData/codegen/box/properties/lazyInitializationPure.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("lazyInitializationSplitPerModule.kt")
|
@TestMetadata("lazyInitializationSplitPerModule.kt")
|
||||||
public void testLazyInitializationSplitPerModule() throws Exception {
|
public void testLazyInitializationSplitPerModule() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/properties/lazyInitializationSplitPerModule.kt");
|
runTest("compiler/testData/codegen/box/properties/lazyInitializationSplitPerModule.kt");
|
||||||
|
|||||||
+153
@@ -1592,6 +1592,159 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class EsModules extends AbstractBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInEsModules() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/crossModuleRef")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class CrossModuleRef extends AbstractBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInCrossModuleRef() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/crossModuleRef"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/crossModuleRefPerFile")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class CrossModuleRefPerFile extends AbstractBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInCrossModuleRefPerFile() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/crossModuleRefPerFile"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/crossModuleRefPerModule")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class CrossModuleRefPerModule extends AbstractBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInCrossModuleRefPerModule() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/crossModuleRefPerModule"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/export")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Export extends AbstractBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInExport() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/export"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overriddenExternalMethodWithSameStableNameMethod.kt")
|
||||||
|
public void testOverriddenExternalMethodWithSameStableNameMethod() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/overriddenExternalMethodWithSameStableNameMethod.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reservedModuleName.kt")
|
||||||
|
public void testReservedModuleName() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/export/reservedModuleName.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/incremental")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Incremental extends AbstractBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInIncremental() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/incremental"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/inline")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Inline extends AbstractBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInInline() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/inline"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/jsExport")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JsExport extends AbstractBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJsExport() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/jsExport"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/jsModule")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JsModule extends AbstractBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJsModule() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/jsModule"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/jsName")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JsName extends AbstractBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJsName() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/jsName"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/box/esModules/native")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Native extends AbstractBoxJsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNative() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/native"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("js/js.translator/testData/box/examples")
|
@TestMetadata("js/js.translator/testData/box/examples")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
-181
@@ -1,181 +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.js.test.semantics;
|
|
||||||
|
|
||||||
import com.intellij.testFramework.TestDataPath;
|
|
||||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
|
||||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
|
||||||
import org.jetbrains.kotlin.test.TargetBackend;
|
|
||||||
import org.jetbrains.kotlin.test.TestMetadata;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
@TestMetadata("js/js.translator/testData/typescript-export")
|
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
|
||||||
public class LegacyJsTypeScriptExportTestGenerated extends AbstractLegacyJsTypeScriptExportTest {
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInTypescript_export() throws Exception {
|
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("js/js.translator/testData/typescript-export/constructors")
|
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
|
||||||
public static class Constructors extends AbstractLegacyJsTypeScriptExportTest {
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInConstructors() throws Exception {
|
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/constructors"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("js/js.translator/testData/typescript-export/declarations")
|
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
|
||||||
public static class Declarations extends AbstractLegacyJsTypeScriptExportTest {
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInDeclarations() throws Exception {
|
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/declarations"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("declarations.kt")
|
|
||||||
public void testDeclarations() throws Exception {
|
|
||||||
runTest("js/js.translator/testData/typescript-export/declarations/declarations.kt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("js/js.translator/testData/typescript-export/inheritance")
|
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
|
||||||
public static class Inheritance extends AbstractLegacyJsTypeScriptExportTest {
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInInheritance() throws Exception {
|
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/inheritance"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("inheritance.kt")
|
|
||||||
public void testInheritance() throws Exception {
|
|
||||||
runTest("js/js.translator/testData/typescript-export/inheritance/inheritance.kt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("js/js.translator/testData/typescript-export/moduleSystems")
|
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
|
||||||
public static class ModuleSystems extends AbstractLegacyJsTypeScriptExportTest {
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInModuleSystems() throws Exception {
|
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/moduleSystems"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("commonjs.kt")
|
|
||||||
public void testCommonjs() throws Exception {
|
|
||||||
runTest("js/js.translator/testData/typescript-export/moduleSystems/commonjs.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("plain.kt")
|
|
||||||
public void testPlain() throws Exception {
|
|
||||||
runTest("js/js.translator/testData/typescript-export/moduleSystems/plain.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("umd.kt")
|
|
||||||
public void testUmd() throws Exception {
|
|
||||||
runTest("js/js.translator/testData/typescript-export/moduleSystems/umd.kt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("js/js.translator/testData/typescript-export/namespaces")
|
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
|
||||||
public static class Namespaces extends AbstractLegacyJsTypeScriptExportTest {
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInNamespaces() throws Exception {
|
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/namespaces"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("namespaces.kt")
|
|
||||||
public void testNamespaces() throws Exception {
|
|
||||||
runTest("js/js.translator/testData/typescript-export/namespaces/namespaces.kt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("js/js.translator/testData/typescript-export/primitives")
|
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
|
||||||
public static class Primitives extends AbstractLegacyJsTypeScriptExportTest {
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInPrimitives() throws Exception {
|
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/primitives"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("primitives.kt")
|
|
||||||
public void testPrimitives() throws Exception {
|
|
||||||
runTest("js/js.translator/testData/typescript-export/primitives/primitives.kt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("js/js.translator/testData/typescript-export/selectiveExport")
|
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
|
||||||
public static class SelectiveExport extends AbstractLegacyJsTypeScriptExportTest {
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInSelectiveExport() throws Exception {
|
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/selectiveExport"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("selectiveExport.kt")
|
|
||||||
public void testSelectiveExport() throws Exception {
|
|
||||||
runTest("js/js.translator/testData/typescript-export/selectiveExport/selectiveExport.kt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("js/js.translator/testData/typescript-export/visibility")
|
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
|
||||||
public static class Visibility extends AbstractLegacyJsTypeScriptExportTest {
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInVisibility() throws Exception {
|
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/visibility"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("visibility.kt")
|
|
||||||
public void testVisibility() throws Exception {
|
|
||||||
runTest("js/js.translator/testData/typescript-export/visibility/visibility.kt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
@@ -31,6 +31,7 @@ object ModuleWrapperTranslation {
|
|||||||
ModuleKind.COMMON_JS -> wrapCommonJs(function, importedModules, program)
|
ModuleKind.COMMON_JS -> wrapCommonJs(function, importedModules, program)
|
||||||
ModuleKind.UMD -> wrapUmd(moduleId, function, importedModules, program)
|
ModuleKind.UMD -> wrapUmd(moduleId, function, importedModules, program)
|
||||||
ModuleKind.PLAIN -> wrapPlain(moduleId, function, importedModules, program)
|
ModuleKind.PLAIN -> wrapPlain(moduleId, function, importedModules, program)
|
||||||
|
ModuleKind.ES -> error("ES modules are not supported in legacy wrapper")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
object O {
|
||||||
|
operator fun invoke() = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun callO() = O()
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = O()
|
||||||
|
if (a != "OK") return "fail: simple: $a"
|
||||||
|
|
||||||
|
val b = callO()
|
||||||
|
if (b != "OK") return "fail: inline: $a"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
class A(val x: Int) {
|
||||||
|
constructor(a: Int, b: Int) : this(a + b)
|
||||||
|
}
|
||||||
|
|
||||||
|
external class B(x: Int) {
|
||||||
|
constructor(a: Int, b: Int)
|
||||||
|
|
||||||
|
val x: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: may be useful after implementing local classes in inline functions
|
||||||
|
/*
|
||||||
|
inline fun foo(p: Int, q: Int, r: Int): Pair<Int, Int> {
|
||||||
|
class C(val x : Int) {
|
||||||
|
constructor(a: Int, b: Int) : this(a + b)
|
||||||
|
}
|
||||||
|
return Pair(C(p).x, C(q, r).x)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline fun callPrimaryConstructor(x: Int) = A(x).x
|
||||||
|
|
||||||
|
inline fun callSecondaryConstructor(x: Int, y: Int) = A(x, y).x
|
||||||
|
|
||||||
|
// FILE: lib.js
|
||||||
|
|
||||||
|
function B(x, y) {
|
||||||
|
this.x = x;
|
||||||
|
if (typeof y !== 'undefined') {
|
||||||
|
this.x += y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = A(23).x
|
||||||
|
if (a != 23) return "fail: primary constructor: $a"
|
||||||
|
|
||||||
|
val b = A(40, 2).x
|
||||||
|
if (b != 42) return "fail: secondary constructor: $b"
|
||||||
|
|
||||||
|
val c = B(99).x
|
||||||
|
if (c != 99) return "fail: native primary constructor: $c"
|
||||||
|
|
||||||
|
val d = B(100, 11).x
|
||||||
|
if (d != 111) return "fail: native secondary constructor: $d"
|
||||||
|
|
||||||
|
/*
|
||||||
|
val (e, f) = foo(123, 320, 1)
|
||||||
|
if (e != 123) return "fail: local primary constructor: $e"
|
||||||
|
if (f != 321) return "fail: local secondary constructor: $f"
|
||||||
|
*/
|
||||||
|
|
||||||
|
val g = callPrimaryConstructor(55)
|
||||||
|
if (g != 55) return "fail: primary constructor from inline function: $g"
|
||||||
|
|
||||||
|
val h = callSecondaryConstructor(990, 9)
|
||||||
|
if (h != 999) return "fail: secondary constructor from inline function: $h"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
fun foo() = 23
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.A
|
||||||
|
|
||||||
|
class B : A() {
|
||||||
|
fun bar() = foo() + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val result = B().bar()
|
||||||
|
if (result != 24) return "fail: $result"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// FILE: lib1.mjs
|
||||||
|
export default function() {
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: lib2
|
||||||
|
// FILE: lib2.kt
|
||||||
|
@JsModule("./lib1.mjs")
|
||||||
|
external fun foo(): String
|
||||||
|
|
||||||
|
// MODULE: lib3(lib2)
|
||||||
|
// FILE: lib3.kt
|
||||||
|
inline fun bar() = foo()
|
||||||
|
|
||||||
|
// MODULE: main(lib3)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun box() = bar()
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// FILE: lib-1.mjs
|
||||||
|
export default function foo() {
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: lib2
|
||||||
|
// FILE: lib2.kt
|
||||||
|
@JsModule("./lib-1.mjs")
|
||||||
|
external fun foo(): String
|
||||||
|
|
||||||
|
// MODULE: lib3(lib2)
|
||||||
|
// FILE: lib3.kt
|
||||||
|
inline fun bar() = foo()
|
||||||
|
|
||||||
|
// MODULE: main(lib3)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun box() = bar()
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// FILE: lib1.mjs
|
||||||
|
export function foo() {
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: lib2
|
||||||
|
// FILE: lib2.kt
|
||||||
|
@file:JsModule("./lib1.mjs")
|
||||||
|
|
||||||
|
external fun foo(): String
|
||||||
|
|
||||||
|
// MODULE: lib3(lib2)
|
||||||
|
// FILE: lib3.kt
|
||||||
|
inline fun bar() = foo()
|
||||||
|
|
||||||
|
// MODULE: main(lib3)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun box() = bar()
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: lib1
|
||||||
|
// FILE: lib1.kt
|
||||||
|
|
||||||
|
fun foo() = "OK"
|
||||||
|
|
||||||
|
// MODULE: lib2(lib1)
|
||||||
|
// FILE: lib2.kt
|
||||||
|
|
||||||
|
inline fun bar() = foo()
|
||||||
|
|
||||||
|
// MODULE: main(lib1, lib2)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun box() = bar()
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: 1
|
||||||
|
// FILE: lib1.kt
|
||||||
|
|
||||||
|
fun foo() = "OK"
|
||||||
|
|
||||||
|
// MODULE: 2(1)
|
||||||
|
// FILE: lib2.kt
|
||||||
|
|
||||||
|
inline fun bar() = foo()
|
||||||
|
|
||||||
|
// MODULE: main(2)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun box() = bar()
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
fun bar(f: () -> String) = f()
|
||||||
|
|
||||||
|
inline fun foo(): String {
|
||||||
|
return bar { "OK" }
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box() = foo()
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
var log = ""
|
||||||
|
|
||||||
|
object O {
|
||||||
|
init {
|
||||||
|
log += "O.init;"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun result() = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getResult(): String {
|
||||||
|
log += "before;"
|
||||||
|
val result = O.result()
|
||||||
|
log += "after;"
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val result = getResult()
|
||||||
|
if (result != "OK") return "fail: unexpected result: $result"
|
||||||
|
|
||||||
|
if (log != "before;O.init;after;") return "fail: wrong evaluation order: $log"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
object O {
|
||||||
|
val result = "OK"
|
||||||
|
|
||||||
|
inline fun foo(): String {
|
||||||
|
val o = object {
|
||||||
|
fun bar() = O
|
||||||
|
}
|
||||||
|
return fetch(o.bar())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fetch(o: O) = o.result
|
||||||
|
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box() = O.foo()
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
object O
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var o: Any = O
|
||||||
|
if (o !is O) return "fail1"
|
||||||
|
if (!(o is O)) return "fail2"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
class A(val x: Int)
|
||||||
|
|
||||||
|
fun A.foo() = 23 + x
|
||||||
|
|
||||||
|
inline fun A.baz() = 99 + x
|
||||||
|
|
||||||
|
inline fun A.callFoo() = foo()
|
||||||
|
|
||||||
|
inline fun A.buzz(): Int {
|
||||||
|
val o = object {
|
||||||
|
fun f() = 111 + x
|
||||||
|
}
|
||||||
|
return o.f()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = A(1).foo()
|
||||||
|
if (a != 24) return "fail: simple function: $a"
|
||||||
|
|
||||||
|
val c = A(1).baz()
|
||||||
|
if (c != 100) return "fail: inline function: $c"
|
||||||
|
|
||||||
|
val d = A(1).buzz()
|
||||||
|
if (d != 112) return "fail: inline function with object expression: $d"
|
||||||
|
|
||||||
|
val e = A(2).callFoo()
|
||||||
|
if (e != 25) return "fail: inline function calling another function: $e"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
fun foo() = 23
|
||||||
|
|
||||||
|
external fun bar(): Int = definedExternally
|
||||||
|
|
||||||
|
inline fun baz() = 99
|
||||||
|
|
||||||
|
inline fun callFoo() = foo()
|
||||||
|
|
||||||
|
inline fun buzz(): Int {
|
||||||
|
val o = object {
|
||||||
|
fun f() = 111
|
||||||
|
}
|
||||||
|
return o.f()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: lib.js
|
||||||
|
|
||||||
|
function bar() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = lib.foo()
|
||||||
|
if (a != 23) return "fail: simple function: $a"
|
||||||
|
|
||||||
|
val b = lib.bar()
|
||||||
|
if (b != 42) return "fail: native function: $b"
|
||||||
|
|
||||||
|
val c = lib.baz()
|
||||||
|
if (c != 99) return "fail: inline function: $c"
|
||||||
|
|
||||||
|
val d = lib.buzz()
|
||||||
|
if (d != 111) return "fail: inline function with object expression: $d"
|
||||||
|
|
||||||
|
val e = lib.callFoo()
|
||||||
|
if (e != 23) return "fail: inline function calling another function: $e"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
var foo = 23
|
||||||
|
|
||||||
|
var bar: Int = 42
|
||||||
|
get() = field
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsName("faz") var baz = 99
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: lib.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (foo != 23) return "fail: simple property initial value: $foo"
|
||||||
|
foo = 24
|
||||||
|
if (foo != 24) return "fail: simple property new value: $foo"
|
||||||
|
|
||||||
|
if (bar != 42) return "fail: property with accessor initial value: $bar"
|
||||||
|
bar = 43
|
||||||
|
if (bar != 43) return "fail: property with accessor new value: $bar"
|
||||||
|
|
||||||
|
if (baz != 99) return "fail: renamed property initial value: $baz"
|
||||||
|
baz = 100
|
||||||
|
if (baz != 100) return "fail: renamed property new value: $baz"
|
||||||
|
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
val foo = 23
|
||||||
|
|
||||||
|
val boo: Int
|
||||||
|
get() = 42
|
||||||
|
|
||||||
|
external val bar: Int = definedExternally
|
||||||
|
|
||||||
|
external val far: Int
|
||||||
|
get() = definedExternally
|
||||||
|
|
||||||
|
// TODO: annotations like this are not serialized properly. Uncomment after KT-14529 gets fixed
|
||||||
|
/*
|
||||||
|
val fuzz: Int
|
||||||
|
@JsName("getBuzz") get() = 55
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline fun fetchFoo() = foo
|
||||||
|
|
||||||
|
@JsName("fee")
|
||||||
|
val tee = 2525
|
||||||
|
|
||||||
|
// FILE: lib.js
|
||||||
|
|
||||||
|
var bar = 99
|
||||||
|
var far = 111
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: lib.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (foo != 23) return "fail: simple property: $foo"
|
||||||
|
if (boo != 42) return "fail: property with accessor: $boo"
|
||||||
|
if (bar != 99) return "fail: native property: $bar"
|
||||||
|
if (far != 111) return "fail: native property with accessor: $far"
|
||||||
|
//if (fuzz != 55) return "fail: property with JsName on accessor: $fuzz"
|
||||||
|
if (tee != 2525) return "fail: native property with JsName: $tee"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_FILE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1289
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
object O {
|
||||||
|
operator fun invoke() = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun callO() = O()
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = O()
|
||||||
|
if (a != "OK") return "fail: simple: $a"
|
||||||
|
|
||||||
|
val b = callO()
|
||||||
|
if (b != "OK") return "fail: inline: $a"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_FILE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1291
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
class A(val x: Int) {
|
||||||
|
constructor(a: Int, b: Int) : this(a + b)
|
||||||
|
}
|
||||||
|
|
||||||
|
external class B(x: Int) {
|
||||||
|
constructor(a: Int, b: Int)
|
||||||
|
|
||||||
|
val x: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: may be useful after implementing local classes in inline functions
|
||||||
|
/*
|
||||||
|
inline fun foo(p: Int, q: Int, r: Int): Pair<Int, Int> {
|
||||||
|
class C(val x : Int) {
|
||||||
|
constructor(a: Int, b: Int) : this(a + b)
|
||||||
|
}
|
||||||
|
return Pair(C(p).x, C(q, r).x)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline fun callPrimaryConstructor(x: Int) = A(x).x
|
||||||
|
|
||||||
|
inline fun callSecondaryConstructor(x: Int, y: Int) = A(x, y).x
|
||||||
|
|
||||||
|
// FILE: lib.js
|
||||||
|
|
||||||
|
function B(x, y) {
|
||||||
|
this.x = x;
|
||||||
|
if (typeof y !== 'undefined') {
|
||||||
|
this.x += y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = A(23).x
|
||||||
|
if (a != 23) return "fail: primary constructor: $a"
|
||||||
|
|
||||||
|
val b = A(40, 2).x
|
||||||
|
if (b != 42) return "fail: secondary constructor: $b"
|
||||||
|
|
||||||
|
val c = B(99).x
|
||||||
|
if (c != 99) return "fail: native primary constructor: $c"
|
||||||
|
|
||||||
|
val d = B(100, 11).x
|
||||||
|
if (d != 111) return "fail: native secondary constructor: $d"
|
||||||
|
|
||||||
|
/*
|
||||||
|
val (e, f) = foo(123, 320, 1)
|
||||||
|
if (e != 123) return "fail: local primary constructor: $e"
|
||||||
|
if (f != 321) return "fail: local secondary constructor: $f"
|
||||||
|
*/
|
||||||
|
|
||||||
|
val g = callPrimaryConstructor(55)
|
||||||
|
if (g != 55) return "fail: primary constructor from inline function: $g"
|
||||||
|
|
||||||
|
val h = callSecondaryConstructor(990, 9)
|
||||||
|
if (h != 999) return "fail: secondary constructor from inline function: $h"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_FILE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1292
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
fun foo() = 23
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.A
|
||||||
|
|
||||||
|
class B : A() {
|
||||||
|
fun bar() = foo() + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val result = B().bar()
|
||||||
|
if (result != 24) return "fail: $result"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_FILE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1283
|
||||||
|
// MODULE: lib1
|
||||||
|
// FILE: lib1.kt
|
||||||
|
|
||||||
|
fun foo() = "OK"
|
||||||
|
|
||||||
|
// MODULE: lib2(lib1)
|
||||||
|
// FILE: lib2.kt
|
||||||
|
|
||||||
|
inline fun bar() = foo()
|
||||||
|
|
||||||
|
// MODULE: main(lib1, lib2)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun box() = bar()
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_FILE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1283
|
||||||
|
// MODULE: 1
|
||||||
|
// FILE: lib1.kt
|
||||||
|
|
||||||
|
fun foo() = "OK"
|
||||||
|
|
||||||
|
// MODULE: 2(1)
|
||||||
|
// FILE: lib2.kt
|
||||||
|
|
||||||
|
inline fun bar() = foo()
|
||||||
|
|
||||||
|
// MODULE: main(2)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun box() = bar()
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_FILE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1283
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
fun bar(f: () -> String) = f()
|
||||||
|
|
||||||
|
inline fun foo(): String {
|
||||||
|
return bar { "OK" }
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box() = foo()
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_FILE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1289
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
var log = ""
|
||||||
|
|
||||||
|
object O {
|
||||||
|
init {
|
||||||
|
log += "O.init;"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun result() = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getResult(): String {
|
||||||
|
log += "before;"
|
||||||
|
val result = O.result()
|
||||||
|
log += "after;"
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val result = getResult()
|
||||||
|
if (result != "OK") return "fail: unexpected result: $result"
|
||||||
|
|
||||||
|
if (log != "before;O.init;after;") return "fail: wrong evaluation order: $log"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_FILE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1382
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
object O {
|
||||||
|
val result = "OK"
|
||||||
|
|
||||||
|
inline fun foo(): String {
|
||||||
|
val o = object {
|
||||||
|
fun bar() = O
|
||||||
|
}
|
||||||
|
return fetch(o.bar())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fetch(o: O) = o.result
|
||||||
|
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box() = O.foo()
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_FILE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1284
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
object O
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var o: Any = O
|
||||||
|
if (o !is O) return "fail1"
|
||||||
|
if (!(o is O)) return "fail2"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_FILE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1290
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
class A(val x: Int)
|
||||||
|
|
||||||
|
fun A.foo() = 23 + x
|
||||||
|
|
||||||
|
inline fun A.baz() = 99 + x
|
||||||
|
|
||||||
|
inline fun A.callFoo() = foo()
|
||||||
|
|
||||||
|
inline fun A.buzz(): Int {
|
||||||
|
val o = object {
|
||||||
|
fun f() = 111 + x
|
||||||
|
}
|
||||||
|
return o.f()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = A(1).foo()
|
||||||
|
if (a != 24) return "fail: simple function: $a"
|
||||||
|
|
||||||
|
val c = A(1).baz()
|
||||||
|
if (c != 100) return "fail: inline function: $c"
|
||||||
|
|
||||||
|
val d = A(1).buzz()
|
||||||
|
if (d != 112) return "fail: inline function with object expression: $d"
|
||||||
|
|
||||||
|
val e = A(2).callFoo()
|
||||||
|
if (e != 25) return "fail: inline function calling another function: $e"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_FILE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1287
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
fun foo() = 23
|
||||||
|
|
||||||
|
external fun bar(): Int = definedExternally
|
||||||
|
|
||||||
|
inline fun baz() = 99
|
||||||
|
|
||||||
|
inline fun callFoo() = foo()
|
||||||
|
|
||||||
|
inline fun buzz(): Int {
|
||||||
|
val o = object {
|
||||||
|
fun f() = 111
|
||||||
|
}
|
||||||
|
return o.f()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: lib.js
|
||||||
|
|
||||||
|
function bar() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = lib.foo()
|
||||||
|
if (a != 23) return "fail: simple function: $a"
|
||||||
|
|
||||||
|
val b = lib.bar()
|
||||||
|
if (b != 42) return "fail: native function: $b"
|
||||||
|
|
||||||
|
val c = lib.baz()
|
||||||
|
if (c != 99) return "fail: inline function: $c"
|
||||||
|
|
||||||
|
val d = lib.buzz()
|
||||||
|
if (d != 111) return "fail: inline function with object expression: $d"
|
||||||
|
|
||||||
|
val e = lib.callFoo()
|
||||||
|
if (e != 23) return "fail: inline function calling another function: $e"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_FILE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1286
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
var foo = 23
|
||||||
|
|
||||||
|
var bar: Int = 42
|
||||||
|
get() = field
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsName("faz") var baz = 99
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: lib.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (foo != 23) return "fail: simple property initial value: $foo"
|
||||||
|
foo = 24
|
||||||
|
if (foo != 24) return "fail: simple property new value: $foo"
|
||||||
|
|
||||||
|
if (bar != 42) return "fail: property with accessor initial value: $bar"
|
||||||
|
bar = 43
|
||||||
|
if (bar != 43) return "fail: property with accessor new value: $bar"
|
||||||
|
|
||||||
|
if (baz != 99) return "fail: renamed property initial value: $baz"
|
||||||
|
baz = 100
|
||||||
|
if (baz != 100) return "fail: renamed property new value: $baz"
|
||||||
|
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_FILE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1287
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
val foo = 23
|
||||||
|
|
||||||
|
val boo: Int
|
||||||
|
get() = 42
|
||||||
|
|
||||||
|
external val bar: Int = definedExternally
|
||||||
|
|
||||||
|
external val far: Int
|
||||||
|
get() = definedExternally
|
||||||
|
|
||||||
|
// TODO: annotations like this are not serialized properly. Uncomment after KT-14529 gets fixed
|
||||||
|
/*
|
||||||
|
val fuzz: Int
|
||||||
|
@JsName("getBuzz") get() = 55
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline fun fetchFoo() = foo
|
||||||
|
|
||||||
|
@JsName("fee")
|
||||||
|
val tee = 2525
|
||||||
|
|
||||||
|
// FILE: lib.js
|
||||||
|
|
||||||
|
var bar = 99
|
||||||
|
var far = 111
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: lib.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (foo != 23) return "fail: simple property: $foo"
|
||||||
|
if (boo != 42) return "fail: property with accessor: $boo"
|
||||||
|
if (bar != 99) return "fail: native property: $bar"
|
||||||
|
if (far != 111) return "fail: native property with accessor: $far"
|
||||||
|
//if (fuzz != 55) return "fail: property with JsName on accessor: $fuzz"
|
||||||
|
if (tee != 2525) return "fail: native property with JsName: $tee"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_MODULE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1289
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
object O {
|
||||||
|
operator fun invoke() = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun callO() = O()
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = O()
|
||||||
|
if (a != "OK") return "fail: simple: $a"
|
||||||
|
|
||||||
|
val b = callO()
|
||||||
|
if (b != "OK") return "fail: inline: $a"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_MODULE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1291
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
class A(val x: Int) {
|
||||||
|
constructor(a: Int, b: Int) : this(a + b)
|
||||||
|
}
|
||||||
|
|
||||||
|
external class B(x: Int) {
|
||||||
|
constructor(a: Int, b: Int)
|
||||||
|
|
||||||
|
val x: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: may be useful after implementing local classes in inline functions
|
||||||
|
/*
|
||||||
|
inline fun foo(p: Int, q: Int, r: Int): Pair<Int, Int> {
|
||||||
|
class C(val x : Int) {
|
||||||
|
constructor(a: Int, b: Int) : this(a + b)
|
||||||
|
}
|
||||||
|
return Pair(C(p).x, C(q, r).x)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline fun callPrimaryConstructor(x: Int) = A(x).x
|
||||||
|
|
||||||
|
inline fun callSecondaryConstructor(x: Int, y: Int) = A(x, y).x
|
||||||
|
|
||||||
|
// FILE: lib.js
|
||||||
|
|
||||||
|
function B(x, y) {
|
||||||
|
this.x = x;
|
||||||
|
if (typeof y !== 'undefined') {
|
||||||
|
this.x += y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = A(23).x
|
||||||
|
if (a != 23) return "fail: primary constructor: $a"
|
||||||
|
|
||||||
|
val b = A(40, 2).x
|
||||||
|
if (b != 42) return "fail: secondary constructor: $b"
|
||||||
|
|
||||||
|
val c = B(99).x
|
||||||
|
if (c != 99) return "fail: native primary constructor: $c"
|
||||||
|
|
||||||
|
val d = B(100, 11).x
|
||||||
|
if (d != 111) return "fail: native secondary constructor: $d"
|
||||||
|
|
||||||
|
/*
|
||||||
|
val (e, f) = foo(123, 320, 1)
|
||||||
|
if (e != 123) return "fail: local primary constructor: $e"
|
||||||
|
if (f != 321) return "fail: local secondary constructor: $f"
|
||||||
|
*/
|
||||||
|
|
||||||
|
val g = callPrimaryConstructor(55)
|
||||||
|
if (g != 55) return "fail: primary constructor from inline function: $g"
|
||||||
|
|
||||||
|
val h = callSecondaryConstructor(990, 9)
|
||||||
|
if (h != 999) return "fail: secondary constructor from inline function: $h"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_MODULE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1292
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
fun foo() = 23
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.A
|
||||||
|
|
||||||
|
class B : A() {
|
||||||
|
fun bar() = foo() + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val result = B().bar()
|
||||||
|
if (result != 24) return "fail: $result"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_MODULE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1283
|
||||||
|
// MODULE: lib1
|
||||||
|
// FILE: lib1.kt
|
||||||
|
|
||||||
|
fun foo() = "OK"
|
||||||
|
|
||||||
|
// MODULE: lib2(lib1)
|
||||||
|
// FILE: lib2.kt
|
||||||
|
|
||||||
|
inline fun bar() = foo()
|
||||||
|
|
||||||
|
// MODULE: main(lib1, lib2)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun box() = bar()
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_MODULE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1283
|
||||||
|
// MODULE: 1
|
||||||
|
// FILE: lib1.kt
|
||||||
|
|
||||||
|
fun foo() = "OK"
|
||||||
|
|
||||||
|
// MODULE: 2(1)
|
||||||
|
// FILE: lib2.kt
|
||||||
|
|
||||||
|
inline fun bar() = foo()
|
||||||
|
|
||||||
|
// MODULE: main(2)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun box() = bar()
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_MODULE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1283
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
fun bar(f: () -> String) = f()
|
||||||
|
|
||||||
|
inline fun foo(): String {
|
||||||
|
return bar { "OK" }
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box() = foo()
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_MODULE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1289
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
var log = ""
|
||||||
|
|
||||||
|
object O {
|
||||||
|
init {
|
||||||
|
log += "O.init;"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun result() = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getResult(): String {
|
||||||
|
log += "before;"
|
||||||
|
val result = O.result()
|
||||||
|
log += "after;"
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val result = getResult()
|
||||||
|
if (result != "OK") return "fail: unexpected result: $result"
|
||||||
|
|
||||||
|
if (log != "before;O.init;after;") return "fail: wrong evaluation order: $log"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_MODULE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1382
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
object O {
|
||||||
|
val result = "OK"
|
||||||
|
|
||||||
|
inline fun foo(): String {
|
||||||
|
val o = object {
|
||||||
|
fun bar() = O
|
||||||
|
}
|
||||||
|
return fetch(o.bar())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fetch(o: O) = o.result
|
||||||
|
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box() = O.foo()
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_MODULE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1284
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
object O
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var o: Any = O
|
||||||
|
if (o !is O) return "fail1"
|
||||||
|
if (!(o is O)) return "fail2"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_MODULE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1290
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
class A(val x: Int)
|
||||||
|
|
||||||
|
fun A.foo() = 23 + x
|
||||||
|
|
||||||
|
inline fun A.baz() = 99 + x
|
||||||
|
|
||||||
|
inline fun A.callFoo() = foo()
|
||||||
|
|
||||||
|
inline fun A.buzz(): Int {
|
||||||
|
val o = object {
|
||||||
|
fun f() = 111 + x
|
||||||
|
}
|
||||||
|
return o.f()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = A(1).foo()
|
||||||
|
if (a != 24) return "fail: simple function: $a"
|
||||||
|
|
||||||
|
val c = A(1).baz()
|
||||||
|
if (c != 100) return "fail: inline function: $c"
|
||||||
|
|
||||||
|
val d = A(1).buzz()
|
||||||
|
if (d != 112) return "fail: inline function with object expression: $d"
|
||||||
|
|
||||||
|
val e = A(2).callFoo()
|
||||||
|
if (e != 25) return "fail: inline function calling another function: $e"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_MODULE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1287
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
fun foo() = 23
|
||||||
|
|
||||||
|
external fun bar(): Int = definedExternally
|
||||||
|
|
||||||
|
inline fun baz() = 99
|
||||||
|
|
||||||
|
inline fun callFoo() = foo()
|
||||||
|
|
||||||
|
inline fun buzz(): Int {
|
||||||
|
val o = object {
|
||||||
|
fun f() = 111
|
||||||
|
}
|
||||||
|
return o.f()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: lib.js
|
||||||
|
|
||||||
|
function bar() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = lib.foo()
|
||||||
|
if (a != 23) return "fail: simple function: $a"
|
||||||
|
|
||||||
|
val b = lib.bar()
|
||||||
|
if (b != 42) return "fail: native function: $b"
|
||||||
|
|
||||||
|
val c = lib.baz()
|
||||||
|
if (c != 99) return "fail: inline function: $c"
|
||||||
|
|
||||||
|
val d = lib.buzz()
|
||||||
|
if (d != 111) return "fail: inline function with object expression: $d"
|
||||||
|
|
||||||
|
val e = lib.callFoo()
|
||||||
|
if (e != 23) return "fail: inline function calling another function: $e"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_MODULE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1286
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
var foo = 23
|
||||||
|
|
||||||
|
var bar: Int = 42
|
||||||
|
get() = field
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsName("faz") var baz = 99
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: lib.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (foo != 23) return "fail: simple property initial value: $foo"
|
||||||
|
foo = 24
|
||||||
|
if (foo != 24) return "fail: simple property new value: $foo"
|
||||||
|
|
||||||
|
if (bar != 42) return "fail: property with accessor initial value: $bar"
|
||||||
|
bar = 43
|
||||||
|
if (bar != 43) return "fail: property with accessor new value: $bar"
|
||||||
|
|
||||||
|
if (baz != 99) return "fail: renamed property initial value: $baz"
|
||||||
|
baz = 100
|
||||||
|
if (baz != 100) return "fail: renamed property new value: $baz"
|
||||||
|
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
// SPLIT_PER_MODULE
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1287
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
val foo = 23
|
||||||
|
|
||||||
|
val boo: Int
|
||||||
|
get() = 42
|
||||||
|
|
||||||
|
external val bar: Int = definedExternally
|
||||||
|
|
||||||
|
external val far: Int
|
||||||
|
get() = definedExternally
|
||||||
|
|
||||||
|
// TODO: annotations like this are not serialized properly. Uncomment after KT-14529 gets fixed
|
||||||
|
/*
|
||||||
|
val fuzz: Int
|
||||||
|
@JsName("getBuzz") get() = 55
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline fun fetchFoo() = foo
|
||||||
|
|
||||||
|
@JsName("fee")
|
||||||
|
val tee = 2525
|
||||||
|
|
||||||
|
// FILE: lib.js
|
||||||
|
|
||||||
|
var bar = 99
|
||||||
|
var far = 111
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: lib.kt
|
||||||
|
package main
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (foo != 23) return "fail: simple property: $foo"
|
||||||
|
if (boo != 42) return "fail: property with accessor: $boo"
|
||||||
|
if (bar != 99) return "fail: native property: $bar"
|
||||||
|
if (far != 111) return "fail: native property with accessor: $far"
|
||||||
|
//if (fuzz != 55) return "fail: property with JsName on accessor: $fuzz"
|
||||||
|
if (tee != 2525) return "fail: native property with JsName: $tee"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1252
|
||||||
|
// INFER_MAIN_MODULE
|
||||||
|
// ES_MODULES
|
||||||
|
|
||||||
|
// MODULE: export-all-file
|
||||||
|
// FILE: lib.kt
|
||||||
|
@file:JsExport
|
||||||
|
|
||||||
|
abstract class A {
|
||||||
|
abstract fun foo(k: String): String
|
||||||
|
}
|
||||||
|
|
||||||
|
class B : A() {
|
||||||
|
override fun foo(k: String): String {
|
||||||
|
return "O" + k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: entry.mjs
|
||||||
|
// ENTRY_ES_MODULE
|
||||||
|
import { B } from "./export-all-file/index.js";
|
||||||
|
console.assert(new B().foo("K") == "OK");
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// SKIP_MINIFICATION
|
||||||
|
// INFER_MAIN_MODULE
|
||||||
|
// SKIP_NODE_JS
|
||||||
|
// ES_MODULES
|
||||||
|
|
||||||
|
// MODULE: non-identifier-module-name
|
||||||
|
// FILE: lib.kt
|
||||||
|
@JsName("foo")
|
||||||
|
@JsExport
|
||||||
|
public fun foo(k: String): String = "O$k"
|
||||||
|
|
||||||
|
// FILE: entry.mjs
|
||||||
|
// ENTRY_ES_MODULE
|
||||||
|
import { foo } from "./non-identifier-module-name/index.js";
|
||||||
|
console.assert(foo("K") == "OK");
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1252
|
||||||
|
// INFER_MAIN_MODULE
|
||||||
|
|
||||||
|
// ES_MODULES
|
||||||
|
// MODULE: overriden-chain-non-export-intermediate
|
||||||
|
// FILE: lib.kt
|
||||||
|
@JsExport
|
||||||
|
abstract class A {
|
||||||
|
abstract fun foo(): String
|
||||||
|
|
||||||
|
abstract fun bar(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class B : A() {
|
||||||
|
abstract fun baz(): String
|
||||||
|
|
||||||
|
override fun foo(): String = "foo"
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
class C : B() {
|
||||||
|
override fun bar(): String = "bar"
|
||||||
|
override fun baz(): String = "baz"
|
||||||
|
|
||||||
|
fun bay(): String = "bay"
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: entry.mjs
|
||||||
|
// ENTRY_ES_MODULE
|
||||||
|
import { C } from "./overriden-chain-non-export-intermediate/index.js";
|
||||||
|
|
||||||
|
function test(c) {
|
||||||
|
if (c.foo() === "foo" && c.bar() === "bar" && c.bay() == "bay") return "OK"
|
||||||
|
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
|
||||||
|
console.assert(test(new C()) == "OK");
|
||||||
Vendored
+41
@@ -0,0 +1,41 @@
|
|||||||
|
// EXPECTED_REACHABLE_NODES: 1252
|
||||||
|
// INFER_MAIN_MODULE
|
||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
|
||||||
|
// MODULE: overriden-external-method-with-same-name-method
|
||||||
|
// FILE: lib.kt
|
||||||
|
external abstract class Foo {
|
||||||
|
abstract fun o(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Bar : Foo() {
|
||||||
|
abstract fun String.o(): String
|
||||||
|
|
||||||
|
override fun o(): String {
|
||||||
|
return "O".o()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
class Baz : Bar() {
|
||||||
|
override fun String.o(): String {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: foo.js
|
||||||
|
function Foo() {}
|
||||||
|
Foo.prototype.k = function() {
|
||||||
|
return "K"
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: entry.mjs
|
||||||
|
// ENTRY_ES_MODULE
|
||||||
|
import { Baz } from "./overriden-external-method-with-same-name-method/index.js";
|
||||||
|
|
||||||
|
function test(foo) {
|
||||||
|
return foo.o() + foo.k()
|
||||||
|
}
|
||||||
|
|
||||||
|
console.assert(test(new Baz()) == "OK");
|
||||||
Vendored
+44
@@ -0,0 +1,44 @@
|
|||||||
|
// EXPECTED_REACHABLE_NODES: 1252
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
|
// INFER_MAIN_MODULE
|
||||||
|
// ES_MODULES
|
||||||
|
|
||||||
|
// MODULE: overriden-external-method-with-same-stable-name-method
|
||||||
|
// FILE: lib.kt
|
||||||
|
external abstract class Foo {
|
||||||
|
abstract fun o(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Bar : Foo() {
|
||||||
|
@JsName("oStable")
|
||||||
|
abstract fun String.o(): String
|
||||||
|
|
||||||
|
override fun o(): String {
|
||||||
|
return "O".o()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
class Baz : Bar() {
|
||||||
|
override fun String.o(): String {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: foo.js
|
||||||
|
function Foo() {}
|
||||||
|
Foo.prototype.k = function() {
|
||||||
|
return "K"
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: entry.mjs
|
||||||
|
// ENTRY_ES_MODULE
|
||||||
|
import { Baz } from "./overriden-external-method-with-same-stable-name-method/index.js";
|
||||||
|
|
||||||
|
function test(foo) {
|
||||||
|
const oStable = foo.oStable("OK")
|
||||||
|
if (oStable !== "OK") return "false: " + oStable
|
||||||
|
return foo.o() + foo.k()
|
||||||
|
}
|
||||||
|
|
||||||
|
console.assert(test(new Baz()) == "OK");
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// IGNORE_BACKEND: JS
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1270
|
||||||
|
// SKIP_MINIFICATION
|
||||||
|
// INFER_MAIN_MODULE
|
||||||
|
// ES_MODULES
|
||||||
|
|
||||||
|
// MODULE: if
|
||||||
|
// FILE: lib.kt
|
||||||
|
@JsName("foo")
|
||||||
|
@JsExport
|
||||||
|
public fun foo(k: String): String = "O$k"
|
||||||
|
|
||||||
|
// FILE: entry.mjs
|
||||||
|
// ENTRY_ES_MODULE
|
||||||
|
import { foo } from "./if/index.js";
|
||||||
|
|
||||||
|
console.assert(foo("K") == "OK");
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: a.kt
|
||||||
|
@file:JsModule("./foo.mjs")
|
||||||
|
|
||||||
|
external fun fooF(): String
|
||||||
|
|
||||||
|
// FILE: b.kt
|
||||||
|
@file:JsModule("./bar.mjs")
|
||||||
|
|
||||||
|
external fun barF(): String
|
||||||
|
|
||||||
|
// FILE: c.kt
|
||||||
|
// RECOMPILE
|
||||||
|
fun dummyF() = "dummy"
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val foo = fooF()
|
||||||
|
if (foo != "foo") return "fail1: $foo"
|
||||||
|
|
||||||
|
val bar = barF()
|
||||||
|
if (bar != "bar") return "fail2: $bar"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: foo.mjs
|
||||||
|
export function fooF() {
|
||||||
|
return "foo";
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: bar.mjs
|
||||||
|
export function barF() {
|
||||||
|
return "bar";
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
// ES_MODULES
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
interface I {
|
||||||
|
fun ok(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun ok(): I {
|
||||||
|
return object : I {
|
||||||
|
override fun ok() = "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsName("convolutedOk")
|
||||||
|
@JsExport
|
||||||
|
inline fun convolutedOk(): I {
|
||||||
|
val fail = object : I {
|
||||||
|
override fun ok() = "fail"
|
||||||
|
}.ok()
|
||||||
|
|
||||||
|
return ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
fun testOk(ok: Any): String {
|
||||||
|
if (ok !is I) return "fail"
|
||||||
|
return ok.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: entry.mjs
|
||||||
|
// ENTRY_ES_MODULE
|
||||||
|
import { convolutedOk, testOk } from "./JS_TESTS/index.js";
|
||||||
|
|
||||||
|
console.assert(testOk(convolutedOk()) == "OK");
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user