[K/JS] Rework main function call to support it in per-file
This commit is contained in:
@@ -72,6 +72,13 @@ private val K2JSCompilerArguments.granularity: JsGenerationGranularity
|
||||
else -> JsGenerationGranularity.WHOLE_PROGRAM
|
||||
}
|
||||
|
||||
private val K2JSCompilerArguments.dtsStrategy: TsCompilationStrategy
|
||||
get() = when {
|
||||
!this.generateDts -> TsCompilationStrategy.NONE
|
||||
this.irPerFile -> TsCompilationStrategy.EACH_FILE
|
||||
else -> TsCompilationStrategy.MERGED
|
||||
}
|
||||
|
||||
private class DisposableZipFileSystemAccessor private constructor(
|
||||
private val zipAccessor: ZipFileSystemCacheableAccessor
|
||||
) : Disposable, ZipFileSystemAccessor by zipAccessor {
|
||||
@@ -100,6 +107,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
) {
|
||||
private fun lowerIr(): LoweredIr {
|
||||
return compile(
|
||||
mainCallArguments,
|
||||
module,
|
||||
phaseConfig,
|
||||
IrFactoryImplForJsIC(WholeWorldStageController()),
|
||||
@@ -122,7 +130,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
|
||||
private fun makeJsCodeGenerator(): JsCodeGenerator {
|
||||
val ir = lowerIr()
|
||||
val transformer = IrModuleToJsTransformer(ir.context, mainCallArguments, ir.moduleFragmentToUniqueName)
|
||||
val transformer = IrModuleToJsTransformer(ir.context, ir.moduleFragmentToUniqueName, mainCallArguments != null)
|
||||
|
||||
val mode = TranslationMode.fromFlags(arguments.irDce, arguments.granularity, arguments.irMinimizedMemberNames)
|
||||
return transformer.makeJsCodeGenerator(ir.allModules, mode)
|
||||
@@ -303,7 +311,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
)
|
||||
|
||||
val (outputs, rebuiltModules) = jsExecutableProducer.buildExecutable(arguments.granularity, outJsProgram = false)
|
||||
outputs.writeAll(outputDir, outputName, arguments.generateDts, moduleName, moduleKind)
|
||||
outputs.writeAll(outputDir, outputName, arguments.dtsStrategy, moduleName, moduleKind)
|
||||
|
||||
icCaches.cacheGuard.release()
|
||||
|
||||
@@ -391,7 +399,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
|
||||
messageCollector.report(INFO, "Executable production duration: ${System.currentTimeMillis() - start}ms")
|
||||
|
||||
outputs.writeAll(outputDir, outputName, arguments.generateDts, moduleName, moduleKind)
|
||||
outputs.writeAll(outputDir, outputName, arguments.dtsStrategy, moduleName, moduleKind)
|
||||
} catch (e: CompilationException) {
|
||||
messageCollector.report(
|
||||
ERROR,
|
||||
@@ -611,10 +619,10 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
cacheDir = cacheDirectory,
|
||||
compilerConfiguration = configurationJs,
|
||||
irFactory = { IrFactoryImplForJsIC(WholeWorldStageController()) },
|
||||
mainArguments = mainCallArguments,
|
||||
compilerInterfaceFactory = { mainModule, cfg ->
|
||||
JsIrCompilerWithIC(
|
||||
mainModule,
|
||||
mainCallArguments,
|
||||
cfg,
|
||||
arguments.granularity,
|
||||
PhaseConfig(jsPhases),
|
||||
|
||||
@@ -62,12 +62,13 @@ class JsIrBackendContext(
|
||||
val additionalExportedDeclarationNames: Set<FqName>,
|
||||
keep: Set<String>,
|
||||
override val configuration: CompilerConfiguration, // TODO: remove configuration from backend context
|
||||
val mainCallArguments: List<String>?,
|
||||
val dceRuntimeDiagnostic: RuntimeDiagnostic? = null,
|
||||
val safeExternalBoolean: Boolean = false,
|
||||
val safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null,
|
||||
override val mapping: JsMapping = JsMapping(),
|
||||
val granularity: JsGenerationGranularity = JsGenerationGranularity.WHOLE_PROGRAM,
|
||||
val incrementalCacheEnabled: Boolean = false
|
||||
val incrementalCacheEnabled: Boolean = false,
|
||||
) : JsCommonBackendContext {
|
||||
override val scriptMode: Boolean get() = false
|
||||
|
||||
|
||||
@@ -863,6 +863,12 @@ val constEvaluationPhase = makeJsModulePhase(
|
||||
description = "Evaluate functions that are marked as `IntrinsicConstEvaluation`",
|
||||
).toModuleLowering()
|
||||
|
||||
val mainFunctionCallWrapperLowering = makeJsModulePhase(
|
||||
::MainFunctionCallWrapperLowering,
|
||||
name = "MainFunctionCallWrapperLowering",
|
||||
description = "Generate main function call inside the wrapper-function"
|
||||
).toModuleLowering()
|
||||
|
||||
val loweringList = listOf<Lowering>(
|
||||
scriptRemoveReceiverLowering,
|
||||
validateIrBeforeLowering,
|
||||
@@ -968,6 +974,7 @@ val loweringList = listOf<Lowering>(
|
||||
callsLoweringPhase,
|
||||
escapedIdentifiersLowering,
|
||||
implicitlyExportedDeclarationsMarkingLowering,
|
||||
mainFunctionCallWrapperLowering,
|
||||
cleanupLoweringPhase,
|
||||
// Currently broken due to static members lowering making single-open-class
|
||||
// files non-recognizable as single-class files
|
||||
|
||||
@@ -17,6 +17,8 @@ class JsMapping : DefaultMapping() {
|
||||
val esClassWhichNeedBoxParameters = DefaultDelegateFactory.newDeclarationToValueMapping<IrClass, Boolean>()
|
||||
val esClassToPossibilityForOptimization = DefaultDelegateFactory.newDeclarationToValueMapping<IrClass, MutableReference<Boolean>>()
|
||||
|
||||
// Main function wrappers
|
||||
val mainFunctionToItsWrapper = DefaultDelegateFactory.newDeclarationToDeclarationMapping<IrSimpleFunction, IrSimpleFunction>()
|
||||
val outerThisFieldSymbols = DefaultDelegateFactory.newDeclarationToDeclarationMapping<IrClass, IrField>()
|
||||
val innerClassConstructors = DefaultDelegateFactory.newDeclarationToDeclarationMapping<IrConstructor, IrConstructor>()
|
||||
val originalInnerClassPrimaryConstructorByClass = DefaultDelegateFactory.newDeclarationToDeclarationMapping<IrClass, IrConstructor>()
|
||||
|
||||
@@ -37,6 +37,7 @@ class LoweredIr(
|
||||
)
|
||||
|
||||
fun compile(
|
||||
mainCallArguments: List<String>?,
|
||||
depsDescriptors: ModulesStructure,
|
||||
phaseConfig: PhaseConfig,
|
||||
irFactory: IrFactory,
|
||||
@@ -56,6 +57,7 @@ fun compile(
|
||||
return compileIr(
|
||||
moduleFragment,
|
||||
depsDescriptors.mainModule,
|
||||
mainCallArguments,
|
||||
depsDescriptors.compilerConfiguration,
|
||||
dependencyModules,
|
||||
moduleToName,
|
||||
@@ -75,6 +77,7 @@ fun compile(
|
||||
fun compileIr(
|
||||
moduleFragment: IrModuleFragment,
|
||||
mainModule: MainModule,
|
||||
mainCallArguments: List<String>?,
|
||||
configuration: CompilerConfiguration,
|
||||
dependencyModules: List<IrModuleFragment>,
|
||||
moduleToName: Map<IrModuleFragment, String>,
|
||||
@@ -109,7 +112,8 @@ fun compileIr(
|
||||
safeExternalBoolean = safeExternalBoolean,
|
||||
safeExternalBooleanDiagnostic = safeExternalBooleanDiagnostic,
|
||||
granularity = granularity,
|
||||
incrementalCacheEnabled = false
|
||||
incrementalCacheEnabled = false,
|
||||
mainCallArguments = mainCallArguments
|
||||
)
|
||||
|
||||
// Load declarations referenced during `context` initialization
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
class JsIrCompilerWithIC(
|
||||
private val mainModule: IrModuleFragment,
|
||||
private val mainArguments: List<String>?,
|
||||
configuration: CompilerConfiguration,
|
||||
granularity: JsGenerationGranularity,
|
||||
private val phaseConfig: PhaseConfig,
|
||||
@@ -42,15 +43,12 @@ class JsIrCompilerWithIC(
|
||||
keep = emptySet(),
|
||||
configuration = configuration,
|
||||
granularity = granularity,
|
||||
incrementalCacheEnabled = true
|
||||
incrementalCacheEnabled = true,
|
||||
mainCallArguments = mainArguments
|
||||
)
|
||||
}
|
||||
|
||||
override fun compile(
|
||||
allModules: Collection<IrModuleFragment>,
|
||||
dirtyFiles: Collection<IrFile>,
|
||||
mainArguments: List<String>?
|
||||
): List<() -> JsIrProgramFragments> {
|
||||
override fun compile(allModules: Collection<IrModuleFragment>, dirtyFiles: Collection<IrFile>): List<() -> JsIrProgramFragments> {
|
||||
val shouldGeneratePolyfills = context.configuration.getBoolean(JSConfigurationKeys.GENERATE_POLYFILLS)
|
||||
|
||||
allModules.forEach {
|
||||
@@ -64,7 +62,7 @@ class JsIrCompilerWithIC(
|
||||
|
||||
lowerPreservingTags(allModules, context, phaseConfig, context.irFactory.stageController as WholeWorldStageController)
|
||||
|
||||
val transformer = IrModuleToJsTransformer(context, mainArguments)
|
||||
val transformer = IrModuleToJsTransformer(context, shouldReferMainFunction = mainArguments != null)
|
||||
return transformer.makeIrFragmentsGenerators(dirtyFiles, allModules)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,13 +114,9 @@ private fun buildRoots(modules: Iterable<IrModuleFragment>, context: JsIrBackend
|
||||
dceRuntimeDiagnostic.unreachableDeclarationMethod(context).owner.acceptVoid(declarationsCollector)
|
||||
}
|
||||
|
||||
// TODO: Generate calls to main as IR->IR lowering and reference coroutineEmptyContinuation directly
|
||||
JsMainFunctionDetector(context).getMainFunctionOrNull(modules.last())?.let { mainFunction ->
|
||||
add(mainFunction)
|
||||
if (mainFunction.isLoweredSuspendFunction(context)) {
|
||||
context.coroutineEmptyContinuation.owner.acceptVoid(declarationsCollector)
|
||||
}
|
||||
}
|
||||
JsMainFunctionDetector(context).getMainFunctionOrNull(modules.last())
|
||||
?.let { context.mapping.mainFunctionToItsWrapper[it] }
|
||||
?.let { add(it) }
|
||||
|
||||
addIfNotNull(context.intrinsics.void.owner.backingField)
|
||||
addAll(context.testFunsPerFile.values)
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.serialization.cityHash64String
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsGenerationGranularity
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrProgramFragment
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrProgramFragments
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
@@ -30,11 +29,7 @@ import java.nio.file.Files
|
||||
import java.util.EnumSet
|
||||
|
||||
fun interface JsIrCompilerICInterface {
|
||||
fun compile(
|
||||
allModules: Collection<IrModuleFragment>,
|
||||
dirtyFiles: Collection<IrFile>,
|
||||
mainArguments: List<String>?
|
||||
): List<() -> JsIrProgramFragments>
|
||||
fun compile(allModules: Collection<IrModuleFragment>, dirtyFiles: Collection<IrFile>): List<() -> JsIrProgramFragments>
|
||||
}
|
||||
|
||||
fun interface JsIrCompilerICInterfaceFactory {
|
||||
@@ -62,7 +57,6 @@ class CacheUpdater(
|
||||
cacheDir: String,
|
||||
private val compilerConfiguration: CompilerConfiguration,
|
||||
private val irFactory: () -> IrFactory,
|
||||
private val mainArguments: List<String>?,
|
||||
private val compilerInterfaceFactory: JsIrCompilerICInterfaceFactory
|
||||
) {
|
||||
private val stopwatch = StopwatchIC()
|
||||
@@ -646,7 +640,7 @@ class CacheUpdater(
|
||||
}
|
||||
}
|
||||
|
||||
val fragmentGenerators = compilerForIC.compile(loadedFragments.values, dirtyFilesForCompiling, mainArguments)
|
||||
val fragmentGenerators = compilerForIC.compile(loadedFragments.values, dirtyFilesForCompiling)
|
||||
|
||||
dirtyFilesForRestoring.mapIndexedTo(ArrayList(dirtyFilesForRestoring.size)) { i, libFileAndSrcFile ->
|
||||
Triple(libFileAndSrcFile.first, libFileAndSrcFile.second, fragmentGenerators[i])
|
||||
@@ -805,6 +799,7 @@ fun rebuildCacheForDirtyFiles(
|
||||
|
||||
val compilerWithIC = JsIrCompilerWithIC(
|
||||
currentIrModule,
|
||||
mainArguments,
|
||||
configuration,
|
||||
JsGenerationGranularity.PER_MODULE,
|
||||
PhaseConfig(jsPhases),
|
||||
@@ -815,7 +810,7 @@ fun rebuildCacheForDirtyFiles(
|
||||
loadedIr.loadUnboundSymbols()
|
||||
internationService.clear()
|
||||
|
||||
val fragments = compilerWithIC.compile(loadedIr.loadedFragments.values, dirtyIrFiles, mainArguments).memoryOptimizedMap { it() }
|
||||
val fragments = compilerWithIC.compile(loadedIr.loadedFragments.values, dirtyIrFiles).memoryOptimizedMap { it() }
|
||||
|
||||
return currentIrModule to dirtyIrFiles.zip(fragments)
|
||||
}
|
||||
|
||||
+5
-6
@@ -61,9 +61,7 @@ class JsExecutableProducer(
|
||||
stopwatch.startNext("Loading JS IR modules with updated cross module references")
|
||||
jsMultiArtifactCache.loadRequiredJsIrModules(crossModuleReferences)
|
||||
|
||||
fun CacheInfo?.compileModule(moduleName: String, generateCallToMain: Boolean): CompilationOutputs {
|
||||
if (this == null) return jsMultiArtifactCache.fetchCompiledJsCodeForNullCacheInfo()
|
||||
|
||||
fun CacheInfo.compileModule(moduleName: String, isMainModule: Boolean): CompilationOutputs {
|
||||
if (jsIrHeader.associatedModule == null) {
|
||||
stopwatch.startNext("Fetching cached JS code")
|
||||
val compilationOutputs = jsMultiArtifactCache.fetchCompiledJsCode(this)
|
||||
@@ -85,7 +83,7 @@ class JsExecutableProducer(
|
||||
moduleKind = moduleKind,
|
||||
associatedModule.fragments,
|
||||
sourceMapsInfo = sourceMapsInfo,
|
||||
generateCallToMain = generateCallToMain,
|
||||
generateCallToMain = isMainModule,
|
||||
crossModuleReferences = crossRef,
|
||||
outJsProgram = outJsProgram
|
||||
)
|
||||
@@ -95,12 +93,13 @@ class JsExecutableProducer(
|
||||
return jsMultiArtifactCache.commitCompiledJsCode(this, compiledModule)
|
||||
}
|
||||
|
||||
val (cachedMainModule, cachedOtherModules) = jsMultiArtifactCache.getMainModuleAndDependencies(cachedProgram)
|
||||
val cachedMainModule = cachedProgram.last()
|
||||
val cachedOtherModules = cachedProgram.dropLast(1)
|
||||
|
||||
val mainModuleCompilationOutput = cachedMainModule
|
||||
.compileModule(mainModuleName, true)
|
||||
.apply {
|
||||
dependencies = cachedOtherModules.map {
|
||||
dependencies += cachedOtherModules.map {
|
||||
it.jsIrHeader.externalModuleName to it.compileModule(it.jsIrHeader.externalModuleName, false)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-3
@@ -14,10 +14,8 @@ abstract class JsMultiArtifactCache<T : JsMultiArtifactCache.CacheInfo> {
|
||||
abstract fun loadProgramHeadersFromCache(): List<T>
|
||||
abstract fun loadRequiredJsIrModules(crossModuleReferences: Map<JsIrModuleHeader, CrossModuleReferences>)
|
||||
abstract fun fetchCompiledJsCode(cacheInfo: T): CompilationOutputsCached?
|
||||
abstract fun commitCompiledJsCode(cacheInfo: T, compilationOutputs: CompilationOutputsBuilt): CompilationOutputs
|
||||
abstract fun fetchCompiledJsCodeForNullCacheInfo(): CompilationOutputs
|
||||
abstract fun loadJsIrModule(cacheInfo: T): JsIrModule
|
||||
abstract fun getMainModuleAndDependencies(cacheInfo: List<T>): Pair<T?, List<T>>
|
||||
abstract fun commitCompiledJsCode(cacheInfo: T, compilationOutputs: CompilationOutputsBuilt): CompilationOutputs
|
||||
|
||||
protected fun File.writeIfNotNull(data: String?) {
|
||||
if (data != null) {
|
||||
|
||||
+65
-23
@@ -30,6 +30,7 @@ class JsPerFileCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMult
|
||||
|
||||
private fun SrcFileArtifact.loadJsIrModuleHeaders(moduleArtifact: ModuleArtifact) = with(loadJsIrFragments()!!) {
|
||||
LoadedJsIrModuleHeaders(
|
||||
mainFragment.mainFunction,
|
||||
mainFragment.run {
|
||||
asIrModuleHeader(
|
||||
getMainFragmentExternalName(moduleArtifact),
|
||||
@@ -95,6 +96,7 @@ class JsPerFileCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMult
|
||||
|
||||
open class MainFileCachedInfo(moduleArtifact: ModuleArtifact, fileArtifact: SrcFileArtifact, moduleHeader: JsIrModuleHeader? = null) :
|
||||
SerializableCachedFileInfo(moduleArtifact, fileArtifact, moduleHeader) {
|
||||
var mainFunctionTag: String? = null
|
||||
var exportFileCachedInfo: ExportFileCachedInfo? = null
|
||||
|
||||
val jsFileArtifact by lazy(LazyThreadSafetyMode.NONE) { getArtifactWithName(CACHED_FILE_JS) }
|
||||
@@ -114,13 +116,33 @@ class JsPerFileCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMult
|
||||
assert(cachedFileInfos.size > 1) { "Merge is unnecessary" }
|
||||
val isModified = cachedFileInfos.any { it.fileArtifact.isModified() }
|
||||
val mainAndExportHeaders = when {
|
||||
isModified -> cachedFileInfos.map { it.fileArtifact.loadJsIrModuleHeaders(moduleArtifact) }
|
||||
else -> cachedFileInfos.map { LoadedJsIrModuleHeaders(it.jsIrHeader, it.exportFileCachedInfo?.jsIrHeader) }
|
||||
isModified -> cachedFileInfos.asSequence().map { it.fileArtifact.loadJsIrModuleHeaders(moduleArtifact) }
|
||||
else -> cachedFileInfos.asSequence().map {
|
||||
LoadedJsIrModuleHeaders(
|
||||
it.mainFunctionTag,
|
||||
it.jsIrHeader,
|
||||
it.exportFileCachedInfo?.jsIrHeader
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val mainHeaders = mutableListOf<JsIrModuleHeader>()
|
||||
val exportHeaders = mutableListOf<JsIrModuleHeader>()
|
||||
|
||||
for (loadedIrModuleHeaders in mainAndExportHeaders) {
|
||||
mainHeaders.add(loadedIrModuleHeaders.mainHeader)
|
||||
|
||||
loadedIrModuleHeaders.exportHeader
|
||||
?.let { exportHeaders.add(it) }
|
||||
|
||||
loadedIrModuleHeaders.mainFunctionTag
|
||||
.takeIf { mainFunctionTag == null }
|
||||
?.let { mainFunctionTag = it }
|
||||
}
|
||||
val (mainHeaders, exportHeaders) = mainAndExportHeaders.map(LoadedJsIrModuleHeaders::toPair).unzip()
|
||||
|
||||
jsIrHeader = mainHeaders.merge()
|
||||
exportFileCachedInfo = exportHeaders.filterNotNull().takeIf { it.isNotEmpty() }
|
||||
exportFileCachedInfo = exportHeaders
|
||||
.takeIf { it.isNotEmpty() }
|
||||
?.let {
|
||||
ExportFileCachedInfo.Merged(
|
||||
filePrefix,
|
||||
@@ -152,6 +174,8 @@ class JsPerFileCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMult
|
||||
|
||||
class ModuleProxyFileCachedInfo(moduleArtifact: ModuleArtifact, moduleHeader: JsIrModuleHeader? = null) :
|
||||
CachedFileInfo(moduleArtifact, moduleHeader) {
|
||||
var mainFunctionTag: String? = null
|
||||
|
||||
val jsFileArtifact by lazy(LazyThreadSafetyMode.NONE) { getArtifactWithName(CACHED_FILE_JS) }
|
||||
val dtsFileArtifact by lazy(LazyThreadSafetyMode.NONE) { getArtifactWithName(CACHED_FILE_D_TS) }
|
||||
val moduleHeaderArtifact by lazy(LazyThreadSafetyMode.NONE) { getArtifactWithName(JS_MODULE_HEADER) }
|
||||
@@ -162,6 +186,7 @@ class JsPerFileCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMult
|
||||
return generateProxyIrModuleWith(
|
||||
jsIrHeader.externalModuleName,
|
||||
jsIrHeader.externalModuleName,
|
||||
mainFunctionTag,
|
||||
jsIrHeader.importedWithEffectInModuleWithName
|
||||
)
|
||||
}
|
||||
@@ -206,6 +231,7 @@ class JsPerFileCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMult
|
||||
return mainFileCachedFileInfo.readModuleHeaderCache {
|
||||
mainFileCachedFileInfo.apply {
|
||||
exportFileCachedInfo = fetchFileInfoForExportedPart(this)
|
||||
mainFunctionTag = ifTrue { readString() }
|
||||
loadSingleCachedFileInfo(this)
|
||||
}
|
||||
}
|
||||
@@ -213,7 +239,10 @@ class JsPerFileCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMult
|
||||
|
||||
private fun ModuleArtifact.fetchModuleProxyFileInfo(): CachedFileInfo.ModuleProxyFileCachedInfo? {
|
||||
val mainFileCachedFileInfo = CachedFileInfo.ModuleProxyFileCachedInfo(this)
|
||||
return mainFileCachedFileInfo.moduleHeaderArtifact?.useCodedInputIfExists { loadSingleCachedFileInfo(mainFileCachedFileInfo) }
|
||||
return mainFileCachedFileInfo.moduleHeaderArtifact?.useCodedInputIfExists {
|
||||
mainFileCachedFileInfo.mainFunctionTag = ifTrue { readString() }
|
||||
loadSingleCachedFileInfo(mainFileCachedFileInfo)
|
||||
}
|
||||
}
|
||||
|
||||
private fun CodedInputStream.fetchFileInfoForExportedPart(mainCachedFileInfo: CachedFileInfo.MainFileCachedInfo): CachedFileInfo.ExportFileCachedInfo? {
|
||||
@@ -238,28 +267,38 @@ class JsPerFileCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMult
|
||||
is CachedFileInfo.MainFileCachedInfo -> {
|
||||
moduleHeaderArtifact?.useCodedOutput {
|
||||
ifNotNull(exportFileCachedInfo) { commitSingleFileInfo(it) }
|
||||
ifNotNull(mainFunctionTag) { writeStringNoTag(it) }
|
||||
commitSingleFileInfo(this@commitFileInfo)
|
||||
}
|
||||
}
|
||||
is CachedFileInfo.ModuleProxyFileCachedInfo -> {
|
||||
moduleHeaderArtifact?.useCodedOutput {
|
||||
ifNotNull(mainFunctionTag) { writeStringNoTag(it) }
|
||||
commitSingleFileInfo(this@commitFileInfo)
|
||||
}
|
||||
}
|
||||
is CachedFileInfo.ExportFileCachedInfo -> {}
|
||||
}
|
||||
|
||||
private fun ModuleArtifact.generateModuleProxyFileCachedInfo(importedWithEffectInModuleWithName: String? = null): CachedFileInfo {
|
||||
return CachedFileInfo.ModuleProxyFileCachedInfo(
|
||||
this,
|
||||
generateProxyIrModuleWith(moduleExternalName, moduleExternalName, importedWithEffectInModuleWithName).makeModuleHeader()
|
||||
)
|
||||
private fun ModuleArtifact.generateModuleProxyFileCachedInfo(
|
||||
mainFunctionTag: String?,
|
||||
importedWithEffectInModuleWithName: String? = null
|
||||
): CachedFileInfo {
|
||||
val moduleHeader = generateProxyIrModuleWith(
|
||||
moduleExternalName,
|
||||
moduleExternalName,
|
||||
mainFunctionTag,
|
||||
importedWithEffectInModuleWithName
|
||||
).makeModuleHeader()
|
||||
return CachedFileInfo.ModuleProxyFileCachedInfo(this, moduleHeader)
|
||||
.also { it.mainFunctionTag = mainFunctionTag }
|
||||
}
|
||||
|
||||
private fun ModuleArtifact.loadFileInfoFor(fileArtifact: SrcFileArtifact): CachedFileInfo.MainFileCachedInfo {
|
||||
val headers = fileArtifact.loadJsIrModuleHeaders(this)
|
||||
|
||||
val mainCachedFileInfo = CachedFileInfo.MainFileCachedInfo(this, fileArtifact, headers.mainHeader)
|
||||
.apply { mainFunctionTag = headers.mainFunctionTag }
|
||||
|
||||
if (headers.exportHeader != null) {
|
||||
val tsDeclarationsHash = fileArtifact.loadJsIrFragments()?.exportFragment?.dts?.raw?.cityHash64()
|
||||
@@ -286,10 +325,6 @@ class JsPerFileCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMult
|
||||
is CachedFileInfo.ModuleProxyFileCachedInfo -> jsFileArtifact?.let { CachedFileArtifacts(it, null, dtsFileArtifact) }
|
||||
}
|
||||
|
||||
override fun getMainModuleAndDependencies(cacheInfo: List<CachedFileInfo>) = null to cacheInfo
|
||||
|
||||
override fun fetchCompiledJsCodeForNullCacheInfo() = PerFileEntryPointCompilationOutput()
|
||||
|
||||
override fun fetchCompiledJsCode(cacheInfo: CachedFileInfo) =
|
||||
cacheInfo.cachedFiles?.let { (jsCodeFile, sourceMapFile, tsDeclarationsFile) ->
|
||||
jsCodeFile.ifExists { this }
|
||||
@@ -302,8 +337,7 @@ class JsPerFileCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMult
|
||||
compilationOutputs.writeJsCodeIntoModuleCache(jsCodeFile, jsMapFile)
|
||||
} ?: compilationOutputs
|
||||
|
||||
override fun loadJsIrModule(cacheInfo: CachedFileInfo): JsIrModule =
|
||||
cacheInfo.loadJsIrModule()
|
||||
override fun loadJsIrModule(cacheInfo: CachedFileInfo): JsIrModule = cacheInfo.loadJsIrModule()
|
||||
|
||||
override fun loadProgramHeadersFromCache(): List<CachedFileInfo> {
|
||||
val mainModuleArtifact = moduleArtifacts.last()
|
||||
@@ -317,6 +351,13 @@ class JsPerFileCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMult
|
||||
override val CachedFileInfo.artifactName get() = jsIrHeader.externalModuleName
|
||||
override val CachedFileInfo.hasEffect get() = jsIrHeader.importedWithEffectInModuleWithName != null
|
||||
override val CachedFileInfo.hasExport get() = this is CachedFileInfo.MainFileCachedInfo && exportFileCachedInfo != null
|
||||
override val CachedFileInfo.packageFqn get() = moduleFragmentToExternalName.excludeFileNameFromExternalName(jsIrHeader.moduleName)
|
||||
override val CachedFileInfo.mainFunction
|
||||
get() = when (this) {
|
||||
is CachedFileInfo.MainFileCachedInfo -> mainFunctionTag
|
||||
is CachedFileInfo.ModuleProxyFileCachedInfo -> mainFunctionTag
|
||||
else -> error("Unexpected CachedFileInfo type ${this::class.simpleName}")
|
||||
}
|
||||
|
||||
override fun SrcFileArtifact.generateArtifact(module: ModuleArtifact) = when {
|
||||
isModified() -> module.loadFileInfoFor(this)
|
||||
@@ -329,10 +370,10 @@ class JsPerFileCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMult
|
||||
else -> CachedFileInfo.MainFileCachedInfo.Merged(map { it as CachedFileInfo.MainFileCachedInfo })
|
||||
}
|
||||
|
||||
override fun ModuleArtifact.generateArtifact(moduleNameForEffects: String?) =
|
||||
override fun ModuleArtifact.generateArtifact(mainFunctionTag: String?, moduleNameForEffects: String?) =
|
||||
fetchModuleProxyFileInfo()?.takeIf {
|
||||
it.jsIrHeader.importedWithEffectInModuleWithName == moduleNameForEffects
|
||||
} ?: generateModuleProxyFileCachedInfo(moduleNameForEffects)
|
||||
it.mainFunction == mainFunctionTag && it.jsIrHeader.importedWithEffectInModuleWithName == moduleNameForEffects
|
||||
} ?: generateModuleProxyFileCachedInfo(mainFunctionTag, moduleNameForEffects)
|
||||
}
|
||||
|
||||
return perFileGenerator.generatePerFileArtifacts(moduleArtifacts)
|
||||
@@ -358,8 +399,9 @@ class JsPerFileCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMult
|
||||
}
|
||||
|
||||
private data class CachedFileArtifacts(val jsCodeFile: File, val sourceMapFile: File?, val tsDeclarationsFile: File?)
|
||||
private data class LoadedJsIrModuleHeaders(val mainHeader: JsIrModuleHeader, val exportHeader: JsIrModuleHeader?) {
|
||||
fun toPair() = mainHeader to exportHeader
|
||||
}
|
||||
|
||||
private data class LoadedJsIrModuleHeaders(
|
||||
val mainFunctionTag: String?,
|
||||
val mainHeader: JsIrModuleHeader,
|
||||
val exportHeader: JsIrModuleHeader?
|
||||
)
|
||||
}
|
||||
@@ -57,12 +57,6 @@ class JsPerModuleCache(private val moduleArtifacts: List<ModuleArtifact>) : JsMu
|
||||
|
||||
override fun loadJsIrModule(cacheInfo: CachedModuleInfo) = cacheInfo.artifact.loadJsIrModule()
|
||||
|
||||
override fun getMainModuleAndDependencies(cacheInfo: List<CachedModuleInfo>) =
|
||||
cacheInfo.last() to cacheInfo.dropLast(1)
|
||||
|
||||
override fun fetchCompiledJsCodeForNullCacheInfo() =
|
||||
error("Should never happen for per module granularity")
|
||||
|
||||
override fun fetchCompiledJsCode(cacheInfo: CachedModuleInfo) = cacheInfo.artifact.artifactsDir?.let { cacheDir ->
|
||||
val jsCodeFile = File(cacheDir, CACHED_MODULE_JS).ifExists { this }
|
||||
val sourceMapFile = File(cacheDir, CACHED_MODULE_JS_MAP).ifExists { this }
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.FileLoweringPass
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsMainFunctionDetector
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isLoweredSuspendFunction
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isStringArrayParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.util.toIrConst
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
|
||||
class MainFunctionCallWrapperLowering(private val context: JsIrBackendContext) : FileLoweringPass {
|
||||
private val mainFunctionDetector = JsMainFunctionDetector(context)
|
||||
private var IrSimpleFunction.mainFunctionWrapper by context.mapping.mainFunctionToItsWrapper
|
||||
private val mainFunctionArgs by lazy(LazyThreadSafetyMode.NONE) {
|
||||
context.mainCallArguments ?: error("Expect to have main call args at this point")
|
||||
}
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
if (context.mainCallArguments == null) return
|
||||
val mainFunction = mainFunctionDetector.getMainFunctionOrNull(irFile) ?: return
|
||||
val mainFunctionWrapper = context.irFactory.stageController.restrictTo(mainFunction) {
|
||||
mainFunction.generateWrapperForMainFunction().also {
|
||||
mainFunction.mainFunctionWrapper = it
|
||||
}
|
||||
}
|
||||
|
||||
irFile.declarations.add(mainFunctionWrapper)
|
||||
}
|
||||
|
||||
private fun IrSimpleFunction.generateWrapperForMainFunction(): IrSimpleFunction {
|
||||
val originalFunctionSymbol = symbol
|
||||
return context.irFactory.createSimpleFunction(
|
||||
startOffset = UNDEFINED_OFFSET,
|
||||
endOffset = UNDEFINED_OFFSET,
|
||||
origin = JsIrBuilder.SYNTHESIZED_DECLARATION,
|
||||
name = Name.identifier("mainWrapper"),
|
||||
visibility = visibility,
|
||||
isInline = false,
|
||||
isExpect = false,
|
||||
returnType = returnType,
|
||||
modality = modality,
|
||||
symbol = IrSimpleFunctionSymbolImpl(),
|
||||
isTailrec = false,
|
||||
isSuspend = false,
|
||||
isOperator = false,
|
||||
isInfix = false
|
||||
).also {
|
||||
it.parent = parent
|
||||
it.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET).apply {
|
||||
statements.add(JsIrBuilder.buildCall(originalFunctionSymbol).apply {
|
||||
generateMainArguments().forEachIndexed(this::putValueArgument)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrSimpleFunction.generateMainArguments(): List<IrExpression> {
|
||||
val generateArgv = valueParameters.firstOrNull()?.isStringArrayParameter() ?: false
|
||||
val generateContinuation = isLoweredSuspendFunction(context)
|
||||
|
||||
return listOfNotNull(
|
||||
runIf(generateArgv) {
|
||||
JsIrBuilder.buildArray(
|
||||
mainFunctionArgs.map { it.toIrConst(context.irBuiltIns.stringType) },
|
||||
valueParameters.first().type,
|
||||
context.irBuiltIns.stringType
|
||||
)
|
||||
},
|
||||
runIf(generateContinuation) {
|
||||
JsIrBuilder.buildCall(context.coroutineEmptyContinuation.owner.getter!!.symbol)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
+14
-36
@@ -20,6 +20,12 @@ val ModuleKind.extension: String
|
||||
else -> REGULAR_EXTENSION
|
||||
}
|
||||
|
||||
enum class TsCompilationStrategy {
|
||||
NONE,
|
||||
MERGED,
|
||||
EACH_FILE
|
||||
}
|
||||
|
||||
abstract class CompilationOutputs {
|
||||
var dependencies: Collection<Pair<String, CompilationOutputs>> = emptyList()
|
||||
|
||||
@@ -31,7 +37,7 @@ abstract class CompilationOutputs {
|
||||
|
||||
fun createWrittenFilesContainer(): MutableSet<File> = LinkedHashSet(2 * (dependencies.size + 1) + 1)
|
||||
|
||||
open fun writeAll(outputDir: File, outputName: String, genDTS: Boolean, moduleName: String, moduleKind: ModuleKind): Collection<File> {
|
||||
open fun writeAll(outputDir: File, outputName: String, dtsStrategy: TsCompilationStrategy, moduleName: String, moduleKind: ModuleKind): Collection<File> {
|
||||
val writtenFiles = createWrittenFilesContainer()
|
||||
|
||||
fun File.writeAsJsFile(out: CompilationOutputs) {
|
||||
@@ -43,6 +49,12 @@ abstract class CompilationOutputs {
|
||||
|
||||
writtenFiles += jsFile
|
||||
writtenFiles += jsMapFile
|
||||
|
||||
out.tsDefinitions.takeIf { dtsStrategy == TsCompilationStrategy.EACH_FILE }?.let {
|
||||
val tsFile = jsFile.dtsForJsFile
|
||||
tsFile.writeText(listOf(it).toTypeScript(name, moduleKind))
|
||||
writtenFiles += tsFile
|
||||
}
|
||||
}
|
||||
|
||||
dependencies.forEach { (name, content) ->
|
||||
@@ -52,7 +64,7 @@ abstract class CompilationOutputs {
|
||||
val outputJsFile = outputDir.resolve("$outputName${moduleKind.extension}")
|
||||
outputJsFile.writeAsJsFile(this)
|
||||
|
||||
if (genDTS) {
|
||||
if (dtsStrategy == TsCompilationStrategy.MERGED) {
|
||||
val dtsFile = outputJsFile.dtsForJsFile
|
||||
dtsFile.writeText(getFullTsDefinition(moduleName, moduleKind))
|
||||
writtenFiles += dtsFile
|
||||
@@ -112,40 +124,6 @@ class CompilationOutputsBuilt(
|
||||
}
|
||||
}
|
||||
|
||||
// The output emulates the main module that has all the dependencies. In per-module we expect that the last processed module is a main module
|
||||
// and after the compilation we rename it with the provided [outputName] and save all of its dependencies, but with the per-file mode we don't have
|
||||
// this last "main" module, as a result we need to emulate it with the output. Also, it helps to save .d.ts files file-by-file instead of the generating
|
||||
// one big main .d.ts file
|
||||
class PerFileEntryPointCompilationOutput : CompilationOutputs() {
|
||||
override val tsDefinitions: TypeScriptFragment? = null
|
||||
override val jsProgram: JsProgram? = null
|
||||
|
||||
override fun writeJsCode(outputJsFile: File, outputJsMapFile: File) {}
|
||||
|
||||
override fun writeAll(outputDir: File, outputName: String, genDTS: Boolean, moduleName: String, moduleKind: ModuleKind): Collection<File> {
|
||||
val writtenFiles = createWrittenFilesContainer()
|
||||
|
||||
dependencies.forEach { (name, content) ->
|
||||
val dependencyFile = outputDir.resolve("$name${moduleKind.extension}").also { it.parentFile.mkdirs() }
|
||||
val jsMapFile = dependencyFile.mapForJsFile
|
||||
val jsFile = dependencyFile.normalizedAbsoluteFile
|
||||
val tsFile = jsFile.dtsForJsFile
|
||||
|
||||
content.writeJsCode(jsFile, jsMapFile)
|
||||
|
||||
writtenFiles += jsFile
|
||||
writtenFiles += jsMapFile
|
||||
|
||||
content.tsDefinitions.takeIf { genDTS }?.let {
|
||||
tsFile.writeText(listOf(it).toTypeScript(name, moduleKind))
|
||||
writtenFiles += tsFile
|
||||
}
|
||||
}
|
||||
|
||||
return writtenFiles.also { deleteNonWrittenFiles(outputDir, it) }
|
||||
}
|
||||
}
|
||||
|
||||
class CompilationOutputsCached(
|
||||
private val jsCodeFile: File,
|
||||
private val sourceMapFile: File?,
|
||||
|
||||
+35
-38
@@ -48,12 +48,25 @@ val String.safeModuleName: String
|
||||
val IrModuleFragment.safeName: String
|
||||
get() = name.asString().safeModuleName
|
||||
|
||||
fun generateProxyIrModuleWith(safeName: String, externalName: String, importedWithEffectInModuleWithName: String? = null) = JsIrModule(
|
||||
safeName,
|
||||
externalName,
|
||||
listOf(JsIrProgramFragment(safeName, "<proxy-file>")),
|
||||
importedWithEffectInModuleWithName = importedWithEffectInModuleWithName
|
||||
)
|
||||
fun generateProxyIrModuleWith(
|
||||
safeName: String,
|
||||
externalName: String,
|
||||
mainFunction: String?,
|
||||
importedWithEffectInModuleWithName: String? = null
|
||||
): JsIrModule {
|
||||
val programFragment = JsIrProgramFragment(safeName, "<proxy-file>").apply {
|
||||
mainFunction?.let {
|
||||
this.mainFunction = it
|
||||
this.nameBindings[it] = JsName("main", true)
|
||||
}
|
||||
}
|
||||
return JsIrModule(
|
||||
safeName,
|
||||
externalName,
|
||||
listOf(programFragment),
|
||||
importedWithEffectInModuleWithName = importedWithEffectInModuleWithName
|
||||
)
|
||||
}
|
||||
|
||||
enum class JsGenerationGranularity {
|
||||
WHOLE_PROGRAM,
|
||||
@@ -127,8 +140,8 @@ class JsCodeGenerator(
|
||||
|
||||
class IrModuleToJsTransformer(
|
||||
private val backendContext: JsIrBackendContext,
|
||||
private val mainArguments: List<String>?,
|
||||
moduleToName: Map<IrModuleFragment, String> = emptyMap(),
|
||||
private val shouldReferMainFunction: Boolean = false,
|
||||
private val removeUnusedAssociatedObjects: Boolean = true,
|
||||
) {
|
||||
private val shouldGeneratePolyfills = backendContext.configuration.getBoolean(JSConfigurationKeys.GENERATE_POLYFILLS)
|
||||
@@ -274,12 +287,14 @@ class IrModuleToJsTransformer(
|
||||
override val JsIrModules.artifactName get() = this.mainModule.externalModuleName
|
||||
override val JsIrModules.hasEffect get() = this.mainModule.importedWithEffectInModuleWithName != null
|
||||
override val JsIrModules.hasExport get() = this.exportModule != null
|
||||
override val JsIrModules.packageFqn get() = this.mainModule.fragments.first().packageFqn
|
||||
override val JsIrModules.mainFunction get() = this.mainModule.fragments.first().mainFunction
|
||||
|
||||
override fun List<JsIrModules>.merge() =
|
||||
JsIrModules(map { it.mainModule }.merge(), mapNotNull { it.exportModule }.ifNotEmpty { merge() })
|
||||
|
||||
override fun IrAndExportedDeclarations.generateArtifact(moduleNameForEffects: String?) =
|
||||
JsIrModules(toJsIrProxyModule(moduleNameForEffects))
|
||||
override fun IrAndExportedDeclarations.generateArtifact(mainFunctionTag: String?, moduleNameForEffects: String?) =
|
||||
JsIrModules(toJsIrProxyModule(mainFunctionTag, moduleNameForEffects))
|
||||
|
||||
override fun IrFileExports.generateArtifact(module: IrAndExportedDeclarations) = takeIf { !file.couldBeSkipped() }
|
||||
?.let { generateProgramFragment(it, mode) }
|
||||
@@ -316,10 +331,14 @@ class IrModuleToJsTransformer(
|
||||
)
|
||||
}
|
||||
|
||||
private fun IrAndExportedDeclarations.toJsIrProxyModule(importedWithEffectInModuleWithName: String? = null): JsIrModule {
|
||||
private fun IrAndExportedDeclarations.toJsIrProxyModule(
|
||||
mainFunction: String?,
|
||||
importedWithEffectInModuleWithName: String? = null
|
||||
): JsIrModule {
|
||||
return generateProxyIrModuleWith(
|
||||
fragment.safeName,
|
||||
moduleFragmentToNameMapper.getExternalNameFor(fragment),
|
||||
mainFunction,
|
||||
importedWithEffectInModuleWithName
|
||||
)
|
||||
}
|
||||
@@ -404,15 +423,6 @@ class IrModuleToJsTransformer(
|
||||
result.initializers.statements += staticContext.initializerBlock.statements
|
||||
result.eagerInitializers.statements += staticContext.eagerInitializerBlock.statements
|
||||
|
||||
if (mainArguments != null) {
|
||||
JsMainFunctionDetector(backendContext).getMainFunctionOrNull(fileExports.file)?.let {
|
||||
val jsName = staticContext.getNameForStaticFunction(it)
|
||||
val generateArgv = it.valueParameters.firstOrNull()?.isStringArrayParameter() ?: false
|
||||
val generateContinuation = it.isLoweredSuspendFunction(backendContext)
|
||||
result.mainFunction = JsInvocation(jsName.makeRef(), generateMainArguments(generateArgv, generateContinuation, staticContext)).makeStmt()
|
||||
}
|
||||
}
|
||||
|
||||
backendContext.testFunsPerFile[fileExports.file]?.let {
|
||||
result.testFunInvocation = JsInvocation(staticContext.getNameForStaticFunction(it).makeRef()).makeStmt()
|
||||
result.suiteFn = staticContext.getNameForStaticFunction(backendContext.suiteFun!!.owner)
|
||||
@@ -422,6 +432,12 @@ class IrModuleToJsTransformer(
|
||||
|
||||
val definitionSet = fileExports.file.declarations.toSet()
|
||||
|
||||
if (shouldReferMainFunction) {
|
||||
JsMainFunctionDetector(backendContext).getMainFunctionOrNull(fileExports.file)
|
||||
?.let { backendContext.mapping.mainFunctionToItsWrapper[it] }
|
||||
?.let { result.mainFunction = definitionSet.computeTag(it) }
|
||||
}
|
||||
|
||||
result.computeAndSaveNameBindings(definitionSet, nameGenerator)
|
||||
result.computeAndSaveImports(definitionSet, nameGenerator)
|
||||
result.computeAndSaveDefinitions(definitionSet, fileExports)
|
||||
@@ -494,25 +510,6 @@ class IrModuleToJsTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateMainArguments(
|
||||
generateArgv: Boolean,
|
||||
generateContinuation: Boolean,
|
||||
staticContext: JsStaticContext,
|
||||
): List<JsExpression> {
|
||||
val mainArguments = this.mainArguments!!
|
||||
val mainArgumentsArray =
|
||||
if (generateArgv) JsArrayLiteral(mainArguments.map { JsStringLiteral(it) }) else null
|
||||
|
||||
val continuation = if (generateContinuation) {
|
||||
backendContext.coroutineEmptyContinuation.owner
|
||||
.let { it.getter!! }
|
||||
.let { staticContext.getNameForStaticFunction(it) }
|
||||
.let { JsInvocation(it.makeRef()) }
|
||||
} else null
|
||||
|
||||
return listOfNotNull(mainArgumentsArray, continuation)
|
||||
}
|
||||
|
||||
private fun IrFile.couldBeSkipped(): Boolean = declarations.all { it.origin == JsCodeOutliningLowering.OUTLINED_JS_CODE_ORIGIN }
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ class JsIrProgramFragment(val name: String, val packageFqn: String) {
|
||||
val classes = mutableMapOf<JsName, JsIrIcClassModel>()
|
||||
val initializers = JsCompositeBlock()
|
||||
val eagerInitializers = JsCompositeBlock()
|
||||
var mainFunction: JsStatement? = null
|
||||
var mainFunction: String? = null
|
||||
var testFunInvocation: JsStatement? = null
|
||||
var suiteFn: JsName? = null
|
||||
val definitions = mutableSetOf<String>()
|
||||
|
||||
+9
-4
@@ -5,6 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsMainFunctionDetector
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||
@@ -59,7 +61,6 @@ class Merger(
|
||||
|
||||
rename(f.initializers)
|
||||
rename(f.eagerInitializers)
|
||||
f.mainFunction?.let { rename(it) }
|
||||
f.testFunInvocation?.let { rename(it) }
|
||||
f.suiteFn?.let { f.suiteFn = rename(it) }
|
||||
}
|
||||
@@ -247,7 +248,9 @@ class Merger(
|
||||
moduleBody.endRegion()
|
||||
}
|
||||
|
||||
val callToMain = fragments.sortedBy { it.packageFqn }.firstNotNullOfOrNull { it.mainFunction }
|
||||
val fragmentWithMainFunction = JsMainFunctionDetector.pickMainFunctionFromCandidates(fragments) {
|
||||
JsMainFunctionDetector.MainFunctionCandidate(it.packageFqn, it.mainFunction)
|
||||
}
|
||||
|
||||
val exportStatements = declareAndCallJsExporter() + additionalExports + transitiveJsExport()
|
||||
|
||||
@@ -267,8 +270,10 @@ class Merger(
|
||||
statements.addWithComment("block: imports", importStatements)
|
||||
statements += moduleBody
|
||||
statements.addWithComment("block: exports", exportStatements)
|
||||
if (generateCallToMain) {
|
||||
callToMain?.let { this.statements += it }
|
||||
if (generateCallToMain && fragmentWithMainFunction != null) {
|
||||
val mainFunctionTag = fragmentWithMainFunction.mainFunction ?: error("Expect to have main function signature at this point")
|
||||
val mainFunctionName = fragmentWithMainFunction.nameBindings[mainFunctionTag] ?: error("Expect to have name binding for tag $mainFunctionTag")
|
||||
statements += JsInvocation(mainFunctionName.makeRef()).makeStmt()
|
||||
}
|
||||
this.statements += JsReturn(internalModuleName.makeRef())
|
||||
}
|
||||
|
||||
+4
@@ -42,6 +42,10 @@ class ModuleFragmentToExternalName(private val jsOutputNamesMapping: Map<IrModul
|
||||
return module.getJsOutputName()
|
||||
}
|
||||
|
||||
fun excludeFileNameFromExternalName(externalName: String): String {
|
||||
return externalName.substringBeforeLast('/')
|
||||
}
|
||||
|
||||
private fun IrModuleFragment.getJsOutputName(): String {
|
||||
return jsOutputNamesMapping[this] ?: sanitizeName(safeName)
|
||||
}
|
||||
|
||||
+22
-5
@@ -5,6 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsMainFunctionDetector
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
import org.jetbrains.kotlin.utils.putToMultiMap
|
||||
|
||||
interface PerFileGenerator<Module, File, Artifact> {
|
||||
@@ -16,10 +18,12 @@ interface PerFileGenerator<Module, File, Artifact> {
|
||||
val Artifact.artifactName: String
|
||||
val Artifact.hasEffect: Boolean
|
||||
val Artifact.hasExport: Boolean
|
||||
val Artifact.packageFqn: String
|
||||
val Artifact.mainFunction: String?
|
||||
|
||||
fun List<Artifact>.merge(): Artifact
|
||||
fun File.generateArtifact(module: Module): Artifact?
|
||||
fun Module.generateArtifact(moduleNameForEffects: String?): Artifact
|
||||
fun Module.generateArtifact(mainFunctionTag: String?, moduleNameForEffects: String?): Artifact
|
||||
|
||||
fun generatePerFileArtifacts(modules: List<Module>): List<Artifact> {
|
||||
var someModuleHasEffect = false
|
||||
@@ -29,8 +33,8 @@ interface PerFileGenerator<Module, File, Artifact> {
|
||||
var hasModuleLevelEffect = false
|
||||
var hasFileWithExportedDeclaration = false
|
||||
|
||||
for (file in module.fileList) {
|
||||
val generatedArtifact = file.generateArtifact(module) ?: continue
|
||||
val artifacts = module.fileList.mapNotNull {
|
||||
val generatedArtifact = it.generateArtifact(module) ?: return@mapNotNull null
|
||||
|
||||
if (generatedArtifact.hasExport) {
|
||||
hasFileWithExportedDeclaration = true
|
||||
@@ -41,15 +45,28 @@ interface PerFileGenerator<Module, File, Artifact> {
|
||||
}
|
||||
|
||||
putToMultiMap(generatedArtifact.artifactName, generatedArtifact)
|
||||
|
||||
generatedArtifact
|
||||
}
|
||||
|
||||
if (hasModuleLevelEffect) {
|
||||
someModuleHasEffect = true
|
||||
}
|
||||
|
||||
if (hasFileWithExportedDeclaration || hasModuleLevelEffect || (module.isMain && someModuleHasEffect)) {
|
||||
val mainFunctionTag = runIf(module.isMain) {
|
||||
JsMainFunctionDetector
|
||||
.pickMainFunctionFromCandidates(artifacts) {
|
||||
JsMainFunctionDetector.MainFunctionCandidate(
|
||||
it.packageFqn,
|
||||
it.mainFunction
|
||||
)
|
||||
}
|
||||
?.mainFunction
|
||||
}
|
||||
|
||||
if (mainFunctionTag != null || hasFileWithExportedDeclaration || hasModuleLevelEffect || (module.isMain && someModuleHasEffect)) {
|
||||
val proxyArtifact =
|
||||
module.generateArtifact(mainModuleName.takeIf { !module.isMain && hasModuleLevelEffect }) ?: continue
|
||||
module.generateArtifact(mainFunctionTag, mainModuleName.takeIf { !module.isMain && hasModuleLevelEffect }) ?: continue
|
||||
putToMultiMap(proxyArtifact.artifactName, proxyArtifact)
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -71,6 +71,17 @@ class JsMainFunctionDetector(val context: JsCommonBackendContext) {
|
||||
|
||||
return resultPair?.second
|
||||
}
|
||||
|
||||
class MainFunctionCandidate(val packageFqn: String, val mainFunctionTag: String?)
|
||||
companion object {
|
||||
inline fun <T> pickMainFunctionFromCandidates(candidates: List<T>, convertToCandidate: (T) -> MainFunctionCandidate): T? {
|
||||
return candidates
|
||||
.map { it to convertToCandidate(it) }
|
||||
.sortedBy { it.second.packageFqn }
|
||||
.firstOrNull { it.second.mainFunctionTag != null }
|
||||
?.first
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ private class JsIrAstDeserializer(private val source: ByteArray) {
|
||||
readRepeated { classes[nameTable[readInt()]] = readIrIcClassModel() }
|
||||
|
||||
ifTrue { testFunInvocation = readStatement() }
|
||||
ifTrue { mainFunction = readStatement() }
|
||||
ifTrue { mainFunction = readString() }
|
||||
ifTrue { dts = TypeScriptFragment(readString()) }
|
||||
ifTrue { suiteFn = nameTable[readInt()] }
|
||||
|
||||
|
||||
+1
-1
@@ -156,7 +156,7 @@ private class JsIrAstSerializer {
|
||||
}
|
||||
|
||||
ifNotNull(fragment.mainFunction) {
|
||||
writeStatement(it)
|
||||
writeString(it)
|
||||
}
|
||||
|
||||
ifNotNull(fragment.dts) {
|
||||
|
||||
@@ -17,7 +17,8 @@ class ProjectInfo(
|
||||
val steps: List<ProjectBuildStep>,
|
||||
val muted: Boolean,
|
||||
val moduleKind: ModuleKind,
|
||||
val ignoredGranularities: Set<JsGenerationGranularity>
|
||||
val ignoredGranularities: Set<JsGenerationGranularity>,
|
||||
val callMain: Boolean
|
||||
) {
|
||||
|
||||
class ProjectBuildStep(
|
||||
@@ -71,6 +72,7 @@ class ModuleInfo(val moduleName: String) {
|
||||
}
|
||||
|
||||
const val PROJECT_INFO_FILE = "project.info"
|
||||
private const val CALL_MAIN = "CALL_MAIN"
|
||||
private const val MODULES_LIST = "MODULES"
|
||||
private const val MODULES_KIND = "MODULE_KIND"
|
||||
private const val LIBS_LIST = "libs"
|
||||
@@ -173,6 +175,7 @@ class ProjectInfoParser(infoFile: File) : InfoParser<ProjectInfo>(infoFile) {
|
||||
val steps = mutableListOf<ProjectInfo.ProjectBuildStep>()
|
||||
val ignoredGranularities = mutableSetOf<JsGenerationGranularity>()
|
||||
var muted = false
|
||||
var callMain = false
|
||||
var moduleKind = ModuleKind.ES
|
||||
|
||||
loop { line ->
|
||||
@@ -191,6 +194,7 @@ class ProjectInfoParser(infoFile: File) : InfoParser<ProjectInfo>(infoFile) {
|
||||
|
||||
when {
|
||||
op == MODULES_LIST -> libraries += split[1].splitAndTrim()
|
||||
op == CALL_MAIN && split[1].trim() == "true" -> callMain = true
|
||||
op == IGNORE_PER_FILE && split[1].trim() == "true" -> ignoredGranularities += JsGenerationGranularity.PER_FILE
|
||||
op == IGNORE_PER_MODULE && split[1].trim() == "true" -> ignoredGranularities += JsGenerationGranularity.PER_MODULE
|
||||
op == MODULES_KIND -> moduleKind = split[1].trim()
|
||||
@@ -222,7 +226,7 @@ class ProjectInfoParser(infoFile: File) : InfoParser<ProjectInfo>(infoFile) {
|
||||
false
|
||||
}
|
||||
|
||||
return ProjectInfo(entryName, libraries, steps, muted, moduleKind, ignoredGranularities)
|
||||
return ProjectInfo(entryName, libraries, steps, muted, moduleKind, ignoredGranularities, callMain)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -605,14 +605,15 @@ class GenerateIrRuntime {
|
||||
symbolTable,
|
||||
additionalExportedDeclarationNames = emptySet(),
|
||||
keep = emptySet(),
|
||||
configuration
|
||||
configuration,
|
||||
null
|
||||
)
|
||||
|
||||
ExternalDependenciesGenerator(symbolTable, listOf(jsLinker)).generateUnboundSymbolsAsDependencies()
|
||||
|
||||
jsPhases.invokeToplevel(phaseConfig, context, listOf(module))
|
||||
|
||||
val transformer = IrModuleToJsTransformer(context, null)
|
||||
val transformer = IrModuleToJsTransformer(context, shouldReferMainFunction = false)
|
||||
|
||||
return transformer.generateModule(listOf(module), setOf(TranslationMode.PER_MODULE_DEV), false)
|
||||
}
|
||||
|
||||
@@ -25,10 +25,7 @@ import org.jetbrains.kotlin.ir.backend.js.SourceMapsInfo
|
||||
import org.jetbrains.kotlin.ir.backend.js.WholeWorldStageController
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.jsPhases
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CompilationOutputs
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsGenerationGranularity
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.extension
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.safeModuleName
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImplForJsIC
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.js.test.converters.ClassicJsBackendFacade
|
||||
@@ -44,6 +41,7 @@ import org.jetbrains.kotlin.test.builders.LanguageVersionSettingsBuilder
|
||||
import org.jetbrains.kotlin.test.util.JUnit4Assertions
|
||||
import org.jetbrains.kotlin.test.utils.TestDisposable
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
import org.junit.ComparisonFailure
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import java.io.File
|
||||
@@ -313,11 +311,16 @@ abstract class AbstractInvalidationTest(
|
||||
)
|
||||
}
|
||||
|
||||
private fun writeJsCode(stepId: Int, mainModuleName: String, jsOutput: CompilationOutputs): List<String> {
|
||||
private fun writeJsCode(
|
||||
stepId: Int,
|
||||
mainModuleName: String,
|
||||
jsOutput: CompilationOutputs,
|
||||
dtsStrategy: TsCompilationStrategy
|
||||
): List<String> {
|
||||
val compiledJsFiles = jsOutput.writeAll(
|
||||
jsDir,
|
||||
mainModuleName,
|
||||
true,
|
||||
dtsStrategy,
|
||||
mainModuleName,
|
||||
projectInfo.moduleKind
|
||||
).filter {
|
||||
@@ -341,6 +344,12 @@ abstract class AbstractInvalidationTest(
|
||||
fun execute() {
|
||||
if (granularity in projectInfo.ignoredGranularities) return
|
||||
|
||||
val mainArguments = runIf(projectInfo.callMain) { emptyList<String>() }
|
||||
val dtsStrategy = when (granularity) {
|
||||
JsGenerationGranularity.PER_FILE -> TsCompilationStrategy.EACH_FILE
|
||||
else -> TsCompilationStrategy.MERGED
|
||||
}
|
||||
|
||||
for (projStep in projectInfo.steps) {
|
||||
val testInfo = projStep.order.map { setupTestStep(projStep, it) }
|
||||
|
||||
@@ -363,10 +372,10 @@ abstract class AbstractInvalidationTest(
|
||||
cacheDir = buildDir.resolve("incremental-cache").absolutePath,
|
||||
compilerConfiguration = configuration,
|
||||
irFactory = { IrFactoryImplForJsIC(WholeWorldStageController()) },
|
||||
mainArguments = null,
|
||||
compilerInterfaceFactory = { mainModule, cfg ->
|
||||
JsIrCompilerWithIC(
|
||||
mainModule,
|
||||
mainArguments,
|
||||
cfg,
|
||||
granularity,
|
||||
getPhaseConfig(projStep.id),
|
||||
@@ -390,7 +399,7 @@ abstract class AbstractInvalidationTest(
|
||||
)
|
||||
|
||||
val (jsOutput, rebuiltModules) = jsExecutableProducer.buildExecutable(granularity, outJsProgram = true)
|
||||
val writtenFiles = writeJsCode(projStep.id, mainModuleName, jsOutput)
|
||||
val writtenFiles = writeJsCode(projStep.id, mainModuleName, jsOutput, dtsStrategy)
|
||||
|
||||
verifyJsExecutableProducerBuildModules(projStep.id, rebuiltModules, dirtyData)
|
||||
verifyJsCode(projStep.id, mainModuleName, writtenFiles)
|
||||
|
||||
@@ -138,10 +138,13 @@ class JsIrBackendFacade(
|
||||
PhaseConfig(jsPhases)
|
||||
}
|
||||
|
||||
val mainArguments = JsEnvironmentConfigurator.getMainCallParametersForModule(module)
|
||||
.run { if (shouldBeGenerated()) arguments() else null }
|
||||
|
||||
val loweredIr = compileIr(
|
||||
irModuleFragment.apply { resolveTestPaths() },
|
||||
MainModule.Klib(inputArtifact.outputFile.absolutePath),
|
||||
mainArguments,
|
||||
configuration,
|
||||
dependencyModules.onEach { it.resolveTestPaths() },
|
||||
emptyMap(),
|
||||
@@ -157,12 +160,10 @@ class JsIrBackendFacade(
|
||||
granularity = granularity,
|
||||
)
|
||||
|
||||
return loweredIr2JsArtifact(module, loweredIr)
|
||||
return loweredIr2JsArtifact(module, loweredIr, mainArguments != null)
|
||||
}
|
||||
|
||||
private fun loweredIr2JsArtifact(module: TestModule, loweredIr: LoweredIr): BinaryArtifacts.Js {
|
||||
val mainArguments = JsEnvironmentConfigurator.getMainCallParametersForModule(module)
|
||||
.run { if (shouldBeGenerated()) arguments() else null }
|
||||
private fun loweredIr2JsArtifact(module: TestModule, loweredIr: LoweredIr, shouldReferMainFunction: Boolean): BinaryArtifacts.Js {
|
||||
val runIrDce = JsEnvironmentConfigurationDirectives.RUN_IR_DCE in module.directives
|
||||
val onlyIrDce = JsEnvironmentConfigurationDirectives.ONLY_IR_DCE in module.directives
|
||||
val perModuleOnly = JsEnvironmentConfigurationDirectives.SPLIT_PER_MODULE in module.directives
|
||||
@@ -178,12 +179,12 @@ class JsIrBackendFacade(
|
||||
|
||||
val transformer = IrModuleToJsTransformer(
|
||||
loweredIr.context,
|
||||
mainArguments,
|
||||
moduleToName = runIf(isEsModules) {
|
||||
loweredIr.allModules.associateWith {
|
||||
"./${getJsArtifactSimpleName(testServices, it.safeName)}_v5".minifyIfNeed()
|
||||
}
|
||||
} ?: emptyMap()
|
||||
} ?: emptyMap(),
|
||||
shouldReferMainFunction,
|
||||
)
|
||||
// If runIrDce then include DCE results
|
||||
// If perModuleOnly then skip whole program
|
||||
@@ -290,7 +291,7 @@ class JsIrBackendFacade(
|
||||
val tmpBuildDir = rootDir.resolve("tmp-build")
|
||||
// CompilationOutputs keeps the `outputDir` clean by removing all outdated JS and other unknown files.
|
||||
// To ensure that useful files around `outputFile`, such as irdump, are not removed, use `tmpBuildDir` instead.
|
||||
val allJsFiles = writeAll(tmpBuildDir, outputFile.nameWithoutExtension, false, moduleId, moduleKind).filter {
|
||||
val allJsFiles = writeAll(tmpBuildDir, outputFile.nameWithoutExtension, TsCompilationStrategy.NONE, moduleId, moduleKind).filter {
|
||||
it.extension == "js" || it.extension == "mjs"
|
||||
}
|
||||
|
||||
|
||||
Generated
+6
@@ -343,6 +343,12 @@ public class JsFirInvalidationPerFileTestGenerated extends AbstractJsFirInvalida
|
||||
runTest("js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mainFunction")
|
||||
public void testMainFunction() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/mainFunction/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mainModuleInvalidation")
|
||||
public void testMainModuleInvalidation() throws Exception {
|
||||
|
||||
Generated
+6
@@ -343,6 +343,12 @@ public class JsFirInvalidationPerModuleTestGenerated extends AbstractJsFirInvali
|
||||
runTest("js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mainFunction")
|
||||
public void testMainFunction() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/mainFunction/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mainModuleInvalidation")
|
||||
public void testMainModuleInvalidation() throws Exception {
|
||||
|
||||
Generated
+6
@@ -343,6 +343,12 @@ public class JsIrES6InvalidationPerFileTestGenerated extends AbstractJsIrES6Inva
|
||||
runTest("js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mainFunction")
|
||||
public void testMainFunction() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/mainFunction/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mainModuleInvalidation")
|
||||
public void testMainModuleInvalidation() throws Exception {
|
||||
|
||||
+6
@@ -343,6 +343,12 @@ public class JsIrES6InvalidationPerModuleTestGenerated extends AbstractJsIrES6In
|
||||
runTest("js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mainFunction")
|
||||
public void testMainFunction() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/mainFunction/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mainModuleInvalidation")
|
||||
public void testMainModuleInvalidation() throws Exception {
|
||||
|
||||
Generated
+6
@@ -343,6 +343,12 @@ public class JsIrInvalidationPerFileTestGenerated extends AbstractJsIrInvalidati
|
||||
runTest("js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mainFunction")
|
||||
public void testMainFunction() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/mainFunction/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mainModuleInvalidation")
|
||||
public void testMainModuleInvalidation() throws Exception {
|
||||
|
||||
Generated
+6
@@ -343,6 +343,12 @@ public class JsIrInvalidationPerModuleTestGenerated extends AbstractJsIrInvalida
|
||||
runTest("js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mainFunction")
|
||||
public void testMainFunction() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/mainFunction/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mainModuleInvalidation")
|
||||
public void testMainModuleInvalidation() throws Exception {
|
||||
|
||||
+58
@@ -2598,6 +2598,64 @@ public class FirJsBoxTestGenerated extends AbstractFirJsBoxTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("js/js.translator/testData/box/esModules/main")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Main {
|
||||
@Test
|
||||
public void testAllFilesPresentInMain() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/main"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("differentMains.kt")
|
||||
public void testDifferentMains() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/differentMains.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incremental.kt")
|
||||
public void testIncremental() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/incremental.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("noArgs.kt")
|
||||
public void testNoArgs() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/noArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMain.kt")
|
||||
public void testSuspendMain() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMain.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMainNoArgs.kt")
|
||||
public void testSuspendMainNoArgs() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMainNoArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMainThrows.kt")
|
||||
public void testSuspendMainThrows() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMainThrows.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoMains.kt")
|
||||
public void testTwoMains() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/twoMains.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("js/js.translator/testData/box/esModules/native")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+58
@@ -2704,6 +2704,64 @@ public class FirJsES6BoxTestGenerated extends AbstractFirJsES6BoxTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("js/js.translator/testData/box/esModules/main")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Main {
|
||||
@Test
|
||||
public void testAllFilesPresentInMain() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/main"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("differentMains.kt")
|
||||
public void testDifferentMains() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/differentMains.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incremental.kt")
|
||||
public void testIncremental() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/incremental.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("noArgs.kt")
|
||||
public void testNoArgs() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/noArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMain.kt")
|
||||
public void testSuspendMain() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMain.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMainNoArgs.kt")
|
||||
public void testSuspendMainNoArgs() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMainNoArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMainThrows.kt")
|
||||
public void testSuspendMainThrows() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMainThrows.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoMains.kt")
|
||||
public void testTwoMains() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/twoMains.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("js/js.translator/testData/box/esModules/native")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+58
@@ -2704,6 +2704,64 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("js/js.translator/testData/box/esModules/main")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Main {
|
||||
@Test
|
||||
public void testAllFilesPresentInMain() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/main"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("differentMains.kt")
|
||||
public void testDifferentMains() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/differentMains.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incremental.kt")
|
||||
public void testIncremental() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/incremental.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("noArgs.kt")
|
||||
public void testNoArgs() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/noArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMain.kt")
|
||||
public void testSuspendMain() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMain.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMainNoArgs.kt")
|
||||
public void testSuspendMainNoArgs() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMainNoArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMainThrows.kt")
|
||||
public void testSuspendMainThrows() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMainThrows.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoMains.kt")
|
||||
public void testTwoMains() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/twoMains.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("js/js.translator/testData/box/esModules/native")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+58
@@ -2598,6 +2598,64 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("js/js.translator/testData/box/esModules/main")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Main {
|
||||
@Test
|
||||
public void testAllFilesPresentInMain() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/main"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("differentMains.kt")
|
||||
public void testDifferentMains() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/differentMains.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incremental.kt")
|
||||
public void testIncremental() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/incremental.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("noArgs.kt")
|
||||
public void testNoArgs() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/noArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMain.kt")
|
||||
public void testSuspendMain() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMain.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMainNoArgs.kt")
|
||||
public void testSuspendMainNoArgs() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMainNoArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMainThrows.kt")
|
||||
public void testSuspendMainThrows() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMainThrows.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoMains.kt")
|
||||
public void testTwoMains() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/twoMains.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("js/js.translator/testData/box/esModules/native")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1281
|
||||
// ES_MODULES
|
||||
// CALL_MAIN
|
||||
|
||||
var ok: String = "OK"
|
||||
|
||||
fun main(args: Array<Int>) {
|
||||
ok += "Fail Int"
|
||||
}
|
||||
|
||||
fun main(args: Array<in String>) {
|
||||
ok += "Fail IN"
|
||||
}
|
||||
|
||||
fun main(args: Array<String>): Unit? {
|
||||
ok += "Fail return Unit?"
|
||||
return Unit
|
||||
}
|
||||
|
||||
fun Any.main(args: Array<String>) {
|
||||
ok += "Fail Any.main(...)"
|
||||
}
|
||||
|
||||
fun box() = ok
|
||||
@@ -0,0 +1,56 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1281
|
||||
// ES_MODULES
|
||||
// CALL_MAIN
|
||||
|
||||
// FILE: ok.kt
|
||||
|
||||
package ok
|
||||
|
||||
var ok: String = "fail"
|
||||
|
||||
// FILE: 1.kt
|
||||
// RECOMPILE
|
||||
|
||||
package a.a
|
||||
|
||||
import ok.*
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
ok = "fail: b.b"
|
||||
}
|
||||
|
||||
// FILE: 0.kt
|
||||
|
||||
package b
|
||||
|
||||
import ok.*
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
ok = "fail: b"
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
package a
|
||||
|
||||
import ok.*
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
ok = "OK"
|
||||
}
|
||||
|
||||
// FILE: 3.kt
|
||||
|
||||
package a.b
|
||||
|
||||
import ok.*
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
ok = "fail: a.b"
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
import ok.*
|
||||
|
||||
fun box() = ok
|
||||
@@ -0,0 +1,11 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1281
|
||||
// ES_MODULES
|
||||
// CALL_MAIN
|
||||
|
||||
var ok: String = "fail"
|
||||
|
||||
fun main() {
|
||||
ok = "OK"
|
||||
}
|
||||
|
||||
fun box() = ok
|
||||
@@ -0,0 +1,13 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1281
|
||||
// ES_MODULES
|
||||
// CALL_MAIN
|
||||
|
||||
var ok: String = "fail"
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
if (0 != args.size) error("fail")
|
||||
|
||||
ok = "OK"
|
||||
}
|
||||
|
||||
fun box() = ok
|
||||
@@ -0,0 +1,27 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1296
|
||||
// ES_MODULES
|
||||
// CALL_MAIN
|
||||
|
||||
import kotlin.coroutines.*
|
||||
|
||||
var ok: String = "fail"
|
||||
|
||||
var callback: () -> Unit = {}
|
||||
|
||||
suspend fun main(args: Array<String>) {
|
||||
if (0 != args.size) error("Fail")
|
||||
|
||||
suspendCoroutine<Unit> { cont ->
|
||||
callback = {
|
||||
cont.resume(Unit)
|
||||
}
|
||||
}
|
||||
|
||||
ok = "OK"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if ("fail" != ok) return "Fail"
|
||||
callback()
|
||||
return ok
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1296
|
||||
// ES_MODULES
|
||||
// CALL_MAIN
|
||||
|
||||
import kotlin.coroutines.*
|
||||
|
||||
var ok: String = "fail"
|
||||
|
||||
var callback: () -> Unit = {}
|
||||
|
||||
suspend fun main() {
|
||||
suspendCoroutine<Unit> { cont ->
|
||||
callback = {
|
||||
cont.resume(Unit)
|
||||
}
|
||||
}
|
||||
|
||||
ok = "OK"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if ("fail" != ok) error("Fail")
|
||||
callback()
|
||||
return ok
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1299
|
||||
// ES_MODULES
|
||||
// CALL_MAIN
|
||||
|
||||
import kotlin.coroutines.*
|
||||
|
||||
var callback: () -> Unit = {}
|
||||
|
||||
val exception = Exception()
|
||||
|
||||
suspend fun main() {
|
||||
|
||||
suspendCoroutine<Unit> { cont ->
|
||||
callback = {
|
||||
cont.resume(Unit)
|
||||
}
|
||||
}
|
||||
|
||||
throw exception
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
callback()
|
||||
} catch (e: Exception) {
|
||||
if (e !== exception) return "Fail"
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1281
|
||||
// ES_MODULES
|
||||
// CALL_MAIN
|
||||
|
||||
var o: String = "fail O"
|
||||
var k: String = "K"
|
||||
|
||||
fun main() {
|
||||
k = "fail K"
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
if (args.size != 0) error("Fail")
|
||||
|
||||
o = "O"
|
||||
}
|
||||
|
||||
fun box() = o + k
|
||||
@@ -0,0 +1,7 @@
|
||||
package foo.bar
|
||||
|
||||
var ok = "Fail"
|
||||
|
||||
fun main() {
|
||||
ok = "OK"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package foo.bar
|
||||
|
||||
var ok = "OK"
|
||||
|
||||
fun main(args: Array<Int>) {
|
||||
ok += "Fail Int"
|
||||
}
|
||||
|
||||
fun main(args: Array<in String>) {
|
||||
ok += "Fail IN"
|
||||
}
|
||||
|
||||
fun main(args: Array<String>): Unit? {
|
||||
ok += "Fail return Unit?"
|
||||
return Unit
|
||||
}
|
||||
|
||||
fun Any.main(args: Array<String>) {
|
||||
ok += "Fail Any.main(...)"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package foo.bar
|
||||
|
||||
import kotlin.coroutines.*
|
||||
|
||||
var ok: String = "fail"
|
||||
|
||||
var callback: () -> Unit = {}
|
||||
|
||||
suspend fun main(args: Array<String>) {
|
||||
if (0 != args.size) error("Fail")
|
||||
|
||||
suspendCoroutine<Unit> { cont ->
|
||||
callback = {
|
||||
cont.resume(Unit)
|
||||
}
|
||||
}
|
||||
|
||||
ok = "OK"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package foo.bar
|
||||
|
||||
var ok = "fail"
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
if (args.size != 0) {
|
||||
ok = "Fail with args zie"
|
||||
} else {
|
||||
ok = "OK"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package foo
|
||||
|
||||
import foo.bar.ok
|
||||
|
||||
fun main() {
|
||||
ok = "OK2"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
var ok = "Fail"
|
||||
fun main() {
|
||||
ok = "OK"
|
||||
}
|
||||
fun box(stepId: Int): String {
|
||||
return when (stepId) {
|
||||
0 -> ok
|
||||
else -> "Unknown"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import foo.bar.ok
|
||||
|
||||
fun box(stepId: Int): String {
|
||||
return when (stepId) {
|
||||
0 -> ok
|
||||
1 -> ok
|
||||
2 -> ok
|
||||
3 -> ok
|
||||
4 -> ok
|
||||
5 -> if (ok != "OK2") "Fail" else "OK"
|
||||
else -> "Unknown"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import foo.bar.ok
|
||||
import foo.bar.callback
|
||||
|
||||
fun box(stepId: Int): String {
|
||||
return when (stepId) {
|
||||
0 -> ok
|
||||
1 -> ok
|
||||
2 -> ok
|
||||
3 -> {
|
||||
if (ok != "fail") return "Fail"
|
||||
callback()
|
||||
ok
|
||||
}
|
||||
4 -> ok
|
||||
5 -> if (ok != "OK2") "Fail" else "OK"
|
||||
else -> "Unknown"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import foo.bar.ok
|
||||
|
||||
fun box(stepId: Int): String {
|
||||
return when (stepId) {
|
||||
0 -> ok
|
||||
1 -> ok
|
||||
2 -> ok
|
||||
3 -> ok
|
||||
4 -> ok
|
||||
5 -> if (ok != "OK2") "Fail" else "OK"
|
||||
else -> "Unknown"
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
STEP 0:
|
||||
modifications:
|
||||
U : m.0.kt -> m.kt
|
||||
added file: m.kt
|
||||
STEP 1:
|
||||
modifications:
|
||||
U : m.1.kt -> m.kt
|
||||
U : f.1.kt -> f.kt
|
||||
added file: f.kt
|
||||
modified ir: m.kt
|
||||
STEP 2:
|
||||
modifications:
|
||||
U : f.2.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
STEP 3:
|
||||
modifications:
|
||||
U : f.3.kt -> f.kt
|
||||
U : m.3.kt -> m.kt
|
||||
modified ir: f.kt, m.kt
|
||||
STEP 4:
|
||||
modifications:
|
||||
U : f.4.kt -> f.kt
|
||||
U : m.4.kt -> m.kt
|
||||
modified ir: f.kt, m.kt
|
||||
STEP 5:
|
||||
modifications:
|
||||
U : l.5.kt -> l.kt
|
||||
added file: l.kt
|
||||
updated exports: f.kt
|
||||
@@ -0,0 +1,27 @@
|
||||
MODULES: main
|
||||
CALL_MAIN: true
|
||||
|
||||
STEP 0:
|
||||
libs: main
|
||||
dirty js modules: main
|
||||
dirty js files: main/m, main/m.export, main
|
||||
STEP 1:
|
||||
libs: main
|
||||
dirty js modules: main
|
||||
dirty js files: main/foo/bar/f, main/m, main
|
||||
STEP 2:
|
||||
libs: main
|
||||
dirty js modules: main
|
||||
dirty js files: main/foo/bar/f, main
|
||||
STEP 3:
|
||||
libs: main
|
||||
dirty js modules: main
|
||||
dirty js files: main/foo/bar/f, main/m, main
|
||||
STEP 4:
|
||||
libs: main
|
||||
dirty js modules: main
|
||||
dirty js files: main/foo/bar/f, main/m, main
|
||||
STEP 5:
|
||||
libs: main
|
||||
dirty js modules: main
|
||||
dirty js files: main/foo/l, main/foo/bar/f, main
|
||||
Generated
+58
@@ -356,6 +356,64 @@ public class FirWasmJsTranslatorTestGenerated extends AbstractFirWasmJsTranslato
|
||||
runTest("js/js.translator/testData/box/esModules/jsName/jsTopLevelClashes.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("js/js.translator/testData/box/esModules/main")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Main {
|
||||
@Test
|
||||
public void testAllFilesPresentInMain() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/main"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("differentMains.kt")
|
||||
public void testDifferentMains() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/differentMains.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incremental.kt")
|
||||
public void testIncremental() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/incremental.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("noArgs.kt")
|
||||
public void testNoArgs() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/noArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMain.kt")
|
||||
public void testSuspendMain() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMain.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMainNoArgs.kt")
|
||||
public void testSuspendMainNoArgs() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMainNoArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMainThrows.kt")
|
||||
public void testSuspendMainThrows() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMainThrows.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoMains.kt")
|
||||
public void testTwoMains() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/twoMains.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
Generated
+58
@@ -356,6 +356,64 @@ public class K1WasmJsTranslatorTestGenerated extends AbstractK1WasmJsTranslatorT
|
||||
runTest("js/js.translator/testData/box/esModules/jsName/jsTopLevelClashes.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("js/js.translator/testData/box/esModules/main")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Main {
|
||||
@Test
|
||||
public void testAllFilesPresentInMain() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/esModules/main"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("differentMains.kt")
|
||||
public void testDifferentMains() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/differentMains.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incremental.kt")
|
||||
public void testIncremental() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/incremental.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("noArgs.kt")
|
||||
public void testNoArgs() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/noArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMain.kt")
|
||||
public void testSuspendMain() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMain.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMainNoArgs.kt")
|
||||
public void testSuspendMainNoArgs() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMainNoArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendMainThrows.kt")
|
||||
public void testSuspendMainThrows() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/suspendMainThrows.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoMains.kt")
|
||||
public void testTwoMains() throws Exception {
|
||||
runTest("js/js.translator/testData/box/esModules/main/twoMains.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
Reference in New Issue
Block a user