[JS TESTS] Rewrite js ir tests using new test infrastructure
This commit is contained in:
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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.test.services
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
|
||||||
|
class JsLibraryProvider(private val testServices: TestServices) : TestService {
|
||||||
|
private val descriptorToLibrary = mutableMapOf<ModuleDescriptor, KotlinLibrary>()
|
||||||
|
private val stdlibPathToDescriptor = mutableMapOf<String, ModuleDescriptorImpl>()
|
||||||
|
|
||||||
|
fun getDescriptorByPath(path: String): ModuleDescriptorImpl {
|
||||||
|
return stdlibPathToDescriptor[path] ?: testServices.assertions.fail {
|
||||||
|
"There is no library with path $path"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setDescriptorAndLibraryByName(name: String, descriptor: ModuleDescriptorImpl, library: KotlinLibrary) {
|
||||||
|
stdlibPathToDescriptor[name] = descriptor
|
||||||
|
descriptorToLibrary[descriptor] = library
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCompiledLibraryByDescriptor(descriptor: ModuleDescriptor): KotlinLibrary {
|
||||||
|
return descriptorToLibrary[descriptor] ?: testServices.assertions.fail {
|
||||||
|
"There is no library for descriptor ${descriptor.name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPathByDescriptor(descriptor: ModuleDescriptor): String {
|
||||||
|
return stdlibPathToDescriptor.entries.single { it.value == descriptor }.key
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDescriptorByCompiledLibrary(library: KotlinLibrary): ModuleDescriptor {
|
||||||
|
return descriptorToLibrary.filterValues { it == library }.keys.singleOrNull() ?: testServices.assertions.fail {
|
||||||
|
"There is no descriptor for library ${library.libraryName}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getOrCreateStdlibByPath(path: String, create: (String) -> Pair<ModuleDescriptorImpl, KotlinLibrary>): ModuleDescriptorImpl {
|
||||||
|
return stdlibPathToDescriptor.getOrPut(path) {
|
||||||
|
create(path).let {
|
||||||
|
descriptorToLibrary += it
|
||||||
|
it.first
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val TestServices.jsLibraryProvider: JsLibraryProvider by TestServices.testServiceAccessor()
|
||||||
+3
@@ -103,3 +103,6 @@ val TestFile.isJavaFile: Boolean
|
|||||||
|
|
||||||
val TestFile.isJsFile: Boolean
|
val TestFile.isJsFile: Boolean
|
||||||
get() = name.endsWith(".js")
|
get() = name.endsWith(".js")
|
||||||
|
|
||||||
|
val TestFile.isMjsFile: Boolean
|
||||||
|
get() = name.endsWith(".mjs")
|
||||||
|
|||||||
+42
@@ -96,6 +96,11 @@ object JsEnvironmentConfigurationDirectives : SimpleDirectivesContainer() {
|
|||||||
applicability = DirectiveApplicability.Global
|
applicability = DirectiveApplicability.Global
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val SPLIT_PER_FILE by directive(
|
||||||
|
description = "",
|
||||||
|
applicability = DirectiveApplicability.Global
|
||||||
|
)
|
||||||
|
|
||||||
val SKIP_MANGLE_VERIFICATION by directive(
|
val SKIP_MANGLE_VERIFICATION by directive(
|
||||||
description = "",
|
description = "",
|
||||||
applicability = DirectiveApplicability.Global
|
applicability = DirectiveApplicability.Global
|
||||||
@@ -183,6 +188,8 @@ object JsEnvironmentConfigurationDirectives : SimpleDirectivesContainer() {
|
|||||||
applicability = DirectiveApplicability.Global
|
applicability = DirectiveApplicability.Global
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Directives for IR tests
|
||||||
|
|
||||||
val RUN_IR_DCE by directive(
|
val RUN_IR_DCE by directive(
|
||||||
description = "Enables dead code elimination on IR",
|
description = "Enables dead code elimination on IR",
|
||||||
applicability = DirectiveApplicability.Global
|
applicability = DirectiveApplicability.Global
|
||||||
@@ -192,4 +199,39 @@ object JsEnvironmentConfigurationDirectives : SimpleDirectivesContainer() {
|
|||||||
description = "Enables pir on IR", // TODO what `pir` stands for?
|
description = "Enables pir on IR", // TODO what `pir` stands for?
|
||||||
applicability = DirectiveApplicability.Global
|
applicability = DirectiveApplicability.Global
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val RUN_IC by directive(
|
||||||
|
description = "",
|
||||||
|
applicability = DirectiveApplicability.Global
|
||||||
|
)
|
||||||
|
|
||||||
|
val LOWER_PER_MODULE by directive(
|
||||||
|
description = "",
|
||||||
|
applicability = DirectiveApplicability.Global
|
||||||
|
)
|
||||||
|
|
||||||
|
val KLIB_MAIN_MODULE by directive(
|
||||||
|
description = "Specify that main module is actually a klib",
|
||||||
|
applicability = DirectiveApplicability.Global
|
||||||
|
)
|
||||||
|
|
||||||
|
val ES_MODULES by directive(
|
||||||
|
description = "",
|
||||||
|
applicability = DirectiveApplicability.Global
|
||||||
|
)
|
||||||
|
|
||||||
|
val ENTRY_ES_MODULE by directive(
|
||||||
|
description = "",
|
||||||
|
applicability = DirectiveApplicability.File
|
||||||
|
)
|
||||||
|
|
||||||
|
val RUN_ES6_MODE by directive(
|
||||||
|
description = "",
|
||||||
|
applicability = DirectiveApplicability.Global
|
||||||
|
)
|
||||||
|
|
||||||
|
val PER_MODULE by directive(
|
||||||
|
description = "",
|
||||||
|
applicability = DirectiveApplicability.Global
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+52
-6
@@ -10,15 +10,21 @@ import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
|||||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||||
import org.jetbrains.kotlin.codegen.CodegenFactory
|
import org.jetbrains.kotlin.codegen.CodegenFactory
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.generateIrForKlibSerialization
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.sortDependencies
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
|
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
|
||||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
|
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
|
||||||
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
||||||
import org.jetbrains.kotlin.test.model.BackendKinds
|
import org.jetbrains.kotlin.test.model.BackendKinds
|
||||||
import org.jetbrains.kotlin.test.model.Frontend2BackendConverter
|
import org.jetbrains.kotlin.test.model.Frontend2BackendConverter
|
||||||
import org.jetbrains.kotlin.test.model.FrontendKinds
|
import org.jetbrains.kotlin.test.model.FrontendKinds
|
||||||
import org.jetbrains.kotlin.test.model.TestModule
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
import org.jetbrains.kotlin.test.services.*
|
||||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
|
||||||
|
|
||||||
class ClassicFrontend2IrConverter(
|
class ClassicFrontend2IrConverter(
|
||||||
testServices: TestServices
|
testServices: TestServices
|
||||||
@@ -27,10 +33,18 @@ class ClassicFrontend2IrConverter(
|
|||||||
FrontendKinds.ClassicFrontend,
|
FrontendKinds.ClassicFrontend,
|
||||||
BackendKinds.IrBackend
|
BackendKinds.IrBackend
|
||||||
) {
|
) {
|
||||||
override fun transform(
|
override val additionalServices: List<ServiceRegistrationData>
|
||||||
module: TestModule,
|
get() = listOf(service(::JsLibraryProvider))
|
||||||
inputArtifact: ClassicFrontendOutputArtifact
|
|
||||||
): IrBackendInput {
|
override fun transform(module: TestModule, inputArtifact: ClassicFrontendOutputArtifact): IrBackendInput {
|
||||||
|
return when (module.targetBackend) {
|
||||||
|
TargetBackend.JVM_IR -> transformToJvmIr(module, inputArtifact)
|
||||||
|
TargetBackend.JS_IR -> transformToJsIr(module, inputArtifact)
|
||||||
|
else -> testServices.assertions.fail { "Target backend ${module.targetBackend} not supported for transformation into IR" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transformToJvmIr(module: TestModule, inputArtifact: ClassicFrontendOutputArtifact): IrBackendInput {
|
||||||
val (psiFiles, analysisResult, project, _) = inputArtifact
|
val (psiFiles, analysisResult, project, _) = inputArtifact
|
||||||
|
|
||||||
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||||
@@ -52,4 +66,36 @@ class ClassicFrontend2IrConverter(
|
|||||||
codegenFactory.convertToIr(CodegenFactory.IrConversionInput.fromGenerationState(state))
|
codegenFactory.convertToIr(CodegenFactory.IrConversionInput.fromGenerationState(state))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun transformToJsIr(module: TestModule, inputArtifact: ClassicFrontendOutputArtifact): IrBackendInput {
|
||||||
|
val (psiFiles, analysisResult, project, _) = inputArtifact
|
||||||
|
|
||||||
|
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||||
|
val verifySignatures = JsEnvironmentConfigurationDirectives.SKIP_MANGLE_VERIFICATION !in module.directives
|
||||||
|
|
||||||
|
val dependencies = testServices.moduleDescriptorProvider.getModuleDescriptor(module).allDependencyModules
|
||||||
|
val allDependencies = dependencies.associateBy { testServices.jsLibraryProvider.getCompiledLibraryByDescriptor(it) }
|
||||||
|
|
||||||
|
val expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
|
||||||
|
val moduleFragment = generateIrForKlibSerialization(
|
||||||
|
project,
|
||||||
|
psiFiles.values.toList(),
|
||||||
|
configuration,
|
||||||
|
analysisResult,
|
||||||
|
sortDependencies(allDependencies),
|
||||||
|
mutableListOf(),
|
||||||
|
expectDescriptorToSymbol,
|
||||||
|
IrFactoryImpl,
|
||||||
|
verifySignatures
|
||||||
|
) {
|
||||||
|
testServices.jsLibraryProvider.getDescriptorByCompiledLibrary(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
return IrBackendInput.JsIrBackendInput(
|
||||||
|
moduleFragment,
|
||||||
|
psiFiles.values.toList(),
|
||||||
|
bindingContext = analysisResult.bindingContext,
|
||||||
|
expectDescriptorToSymbol = expectDescriptorToSymbol,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+88
-1
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory
|
|||||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
|
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider
|
import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace
|
import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||||
@@ -19,6 +20,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
|
|||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys.JVM_TARGET
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys.JVM_TARGET
|
||||||
import org.jetbrains.kotlin.config.JvmTarget
|
import org.jetbrains.kotlin.config.JvmTarget
|
||||||
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.container.get
|
import org.jetbrains.kotlin.container.get
|
||||||
import org.jetbrains.kotlin.context.ModuleContext
|
import org.jetbrains.kotlin.context.ModuleContext
|
||||||
import org.jetbrains.kotlin.context.ProjectContext
|
import org.jetbrains.kotlin.context.ProjectContext
|
||||||
@@ -30,7 +32,16 @@ import org.jetbrains.kotlin.frontend.java.di.initJvmBuiltInsForTopDownAnalysis
|
|||||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||||
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
|
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.JsFactories
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.TopDownAnalyzerFacadeForJSIR
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.jsResolveLibraries
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.toResolverLogger
|
||||||
|
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||||
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
|
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
|
||||||
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.konan.properties.propertyList
|
||||||
|
import org.jetbrains.kotlin.library.KLIB_PROPERTY_DEPENDS
|
||||||
|
import org.jetbrains.kotlin.library.unresolvedDependencies
|
||||||
import org.jetbrains.kotlin.load.java.lazy.SingleModuleClassResolver
|
import org.jetbrains.kotlin.load.java.lazy.SingleModuleClassResolver
|
||||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
|
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -49,7 +60,9 @@ import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
|
|||||||
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
|
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.MetadataPartProvider
|
import org.jetbrains.kotlin.serialization.deserialization.MetadataPartProvider
|
||||||
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
||||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
|
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
|
||||||
import org.jetbrains.kotlin.test.model.*
|
import org.jetbrains.kotlin.test.model.*
|
||||||
import org.jetbrains.kotlin.test.services.*
|
import org.jetbrains.kotlin.test.services.*
|
||||||
@@ -163,7 +176,10 @@ class ClassicFrontendFacade(
|
|||||||
friendsDescriptors,
|
friendsDescriptors,
|
||||||
hasCommonModules
|
hasCommonModules
|
||||||
)
|
)
|
||||||
targetPlatform.isJs() -> performJsModuleResolve(project, configuration, files, dependentDescriptors)
|
targetPlatform.isJs() -> when {
|
||||||
|
module.targetBackend?.isIR != true -> performJsModuleResolve(project, configuration, files, dependentDescriptors)
|
||||||
|
else -> performJsIrModuleResolve(module, project, configuration, files, dependentDescriptors, friendsDescriptors)
|
||||||
|
}
|
||||||
targetPlatform.isNative() -> performNativeModuleResolve(module, project, files)
|
targetPlatform.isNative() -> performNativeModuleResolve(module, project, files)
|
||||||
targetPlatform.isCommon() -> performCommonModuleResolve(module, files)
|
targetPlatform.isCommon() -> performCommonModuleResolve(module, files)
|
||||||
else -> error("Should not be here")
|
else -> error("Should not be here")
|
||||||
@@ -257,6 +273,77 @@ class ClassicFrontendFacade(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun loadKlib(names: List<String>, configuration: CompilerConfiguration): List<ModuleDescriptorImpl> {
|
||||||
|
val resolvedLibraries = jsResolveLibraries(
|
||||||
|
names,
|
||||||
|
configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
|
||||||
|
configuration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger()
|
||||||
|
).getFullResolvedList()
|
||||||
|
|
||||||
|
var builtInsModule: KotlinBuiltIns? = null
|
||||||
|
val dependencies = mutableListOf<ModuleDescriptorImpl>()
|
||||||
|
|
||||||
|
return resolvedLibraries.zip(names).map { (resolvedLibrary, klibPath) ->
|
||||||
|
testServices.jsLibraryProvider.getOrCreateStdlibByPath(klibPath) {
|
||||||
|
val storageManager = LockBasedStorageManager("ModulesStructure")
|
||||||
|
val isBuiltIns = resolvedLibrary.library.unresolvedDependencies.isEmpty()
|
||||||
|
|
||||||
|
val moduleDescriptor = JsFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
|
||||||
|
resolvedLibrary.library,
|
||||||
|
configuration.languageVersionSettings,
|
||||||
|
storageManager,
|
||||||
|
builtInsModule,
|
||||||
|
packageAccessHandler = null,
|
||||||
|
lookupTracker = LookupTracker.DO_NOTHING
|
||||||
|
)
|
||||||
|
if (isBuiltIns) builtInsModule = moduleDescriptor.builtIns
|
||||||
|
dependencies += moduleDescriptor
|
||||||
|
moduleDescriptor.setDependencies(dependencies)
|
||||||
|
|
||||||
|
Pair(moduleDescriptor, resolvedLibrary.library)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
|
private fun performJsIrModuleResolve(
|
||||||
|
module: TestModule,
|
||||||
|
project: Project,
|
||||||
|
configuration: CompilerConfiguration,
|
||||||
|
files: List<KtFile>,
|
||||||
|
dependentDescriptors: List<ModuleDescriptorImpl>,
|
||||||
|
friendsDescriptors: List<ModuleDescriptorImpl>,
|
||||||
|
): AnalysisResult {
|
||||||
|
// val jsConfig = JsEnvironmentConfigurator.createJsConfig(project, configuration)
|
||||||
|
|
||||||
|
val runtimeKlibsNames = JsEnvironmentConfigurator.getStdlibPathsForModule(module)
|
||||||
|
val runtimeKlibs = loadKlib(runtimeKlibsNames, configuration)
|
||||||
|
val transitiveLibraries = configuration[JSConfigurationKeys.TRANSITIVE_LIBRARIES]!!.map {
|
||||||
|
testServices.jsLibraryProvider.getDescriptorByPath(File(it).absolutePath.replace("_v5.meta.js", "").replace("outputDir", "outputKlibDir"))
|
||||||
|
}
|
||||||
|
val friendLibraries = configuration[JSConfigurationKeys.FRIEND_PATHS]!!.map {
|
||||||
|
testServices.jsLibraryProvider.getDescriptorByPath(File(it).absolutePath.replace("_v5.meta.js", "").replace("outputDir", "outputKlibDir"))
|
||||||
|
}
|
||||||
|
val allDependencies = runtimeKlibs + dependentDescriptors + transitiveLibraries
|
||||||
|
|
||||||
|
val analyzer = AnalyzerWithCompilerReport(configuration)
|
||||||
|
val builtInModuleDescriptor = allDependencies.firstNotNullOfOrNull { it.builtIns }?.builtInsModule
|
||||||
|
analyzer.analyzeAndReport(files) {
|
||||||
|
TopDownAnalyzerFacadeForJSIR.analyzeFiles(
|
||||||
|
files,
|
||||||
|
project,
|
||||||
|
configuration,
|
||||||
|
allDependencies,
|
||||||
|
friendsDescriptors + friendLibraries,
|
||||||
|
CompilerEnvironment,
|
||||||
|
thisIsBuiltInsModule = builtInModuleDescriptor == null,
|
||||||
|
customBuiltInsModule = builtInModuleDescriptor
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return analyzer.analysisResult
|
||||||
|
}
|
||||||
|
|
||||||
private fun performNativeModuleResolve(
|
private fun performNativeModuleResolve(
|
||||||
module: TestModule,
|
module: TestModule,
|
||||||
project: Project,
|
project: Project,
|
||||||
|
|||||||
@@ -6,9 +6,12 @@
|
|||||||
package org.jetbrains.kotlin.test.model
|
package org.jetbrains.kotlin.test.model
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ClassFileFactory
|
import org.jetbrains.kotlin.codegen.ClassFileFactory
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.js.TranslationResultValue
|
import org.jetbrains.kotlin.incremental.js.TranslationResultValue
|
||||||
import org.jetbrains.kotlin.ir.backend.js.CompilerResult
|
import org.jetbrains.kotlin.ir.backend.js.CompilerResult
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsProgram
|
import org.jetbrains.kotlin.js.backend.ast.JsProgram
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.LoweredIr
|
||||||
import org.jetbrains.kotlin.js.facade.TranslationResult
|
import org.jetbrains.kotlin.js.facade.TranslationResult
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -26,8 +29,13 @@ object BinaryArtifacts {
|
|||||||
open fun unwrap(): Js = this
|
open fun unwrap(): Js = this
|
||||||
|
|
||||||
class OldJsArtifact(override val outputFile: File, val translationResult: TranslationResult) : Js()
|
class OldJsArtifact(override val outputFile: File, val translationResult: TranslationResult) : Js()
|
||||||
|
|
||||||
class JsIrArtifact(override val outputFile: File, val compilerResult: CompilerResult) : Js()
|
class JsIrArtifact(override val outputFile: File, val compilerResult: CompilerResult) : Js()
|
||||||
|
|
||||||
|
class JsKlibArtifact(override val outputFile: File, val descriptor: ModuleDescriptor, val library: KotlinLibrary) : Js()
|
||||||
|
|
||||||
|
class JsEsArtifact(override val outputFile: File, val outputDceFile: File?) : Js()
|
||||||
|
|
||||||
data class IncrementalJsArtifact(val originalArtifact: Js, val recompiledArtifact: Js) : Js() {
|
data class IncrementalJsArtifact(val originalArtifact: Js, val recompiledArtifact: Js) : Js() {
|
||||||
override val outputFile: File
|
override val outputFile: File
|
||||||
get() = unwrap().outputFile
|
get() = unwrap().outputFile
|
||||||
|
|||||||
+60
-5
@@ -6,14 +6,18 @@
|
|||||||
package org.jetbrains.kotlin.test.services.configuration
|
package org.jetbrains.kotlin.test.services.configuration
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.js.config.*
|
import org.jetbrains.kotlin.js.config.*
|
||||||
|
import org.jetbrains.kotlin.js.facade.MainCallParameters
|
||||||
import org.jetbrains.kotlin.resolve.CompilerEnvironment
|
import org.jetbrains.kotlin.resolve.CompilerEnvironment
|
||||||
import org.jetbrains.kotlin.serialization.js.JsModuleDescriptor
|
import org.jetbrains.kotlin.serialization.js.JsModuleDescriptor
|
||||||
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil
|
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil
|
||||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
|
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
|
||||||
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
||||||
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.MODULE_KIND
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.MODULE_KIND
|
||||||
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.NO_INLINE
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.NO_INLINE
|
||||||
@@ -39,6 +43,7 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
|
|||||||
const val OLD_MODULE_SUFFIX = "_old"
|
const val OLD_MODULE_SUFFIX = "_old"
|
||||||
|
|
||||||
private const val OUTPUT_DIR_NAME = "outputDir"
|
private const val OUTPUT_DIR_NAME = "outputDir"
|
||||||
|
private const val OUTPUT_KLIB_DIR_NAME = "outputKlibDir"
|
||||||
private const val DCE_OUTPUT_DIR_NAME = "dceOutputDir"
|
private const val DCE_OUTPUT_DIR_NAME = "dceOutputDir"
|
||||||
private const val PIR_OUTPUT_DIR_NAME = "pirOutputDir"
|
private const val PIR_OUTPUT_DIR_NAME = "pirOutputDir"
|
||||||
private const val MINIFICATION_OUTPUT_DIR_NAME = "minOutputDir"
|
private const val MINIFICATION_OUTPUT_DIR_NAME = "minOutputDir"
|
||||||
@@ -66,10 +71,26 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
|
|||||||
return getJsArtifactsOutputDir(testServices).absolutePath + "/" + getJsArtifactSimpleName(testServices, moduleName) + "_v5"
|
return getJsArtifactsOutputDir(testServices).absolutePath + "/" + getJsArtifactSimpleName(testServices, moduleName) + "_v5"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getJsKlibArtifactPath(testServices: TestServices, moduleName: String): String {
|
||||||
|
return getJsKlibOutputDir(testServices).absolutePath + "/" + getJsArtifactSimpleName(testServices, moduleName)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDceJsArtifactPath(testServices: TestServices, moduleName: String): String {
|
||||||
|
return getDceJsArtifactsOutputDir(testServices).absolutePath + "/" + getJsArtifactSimpleName(testServices, moduleName) + "_v5"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPirJsArtifactPath(testServices: TestServices, moduleName: String): String {
|
||||||
|
return getPirJsArtifactsOutputDir(testServices).absolutePath + "/" + getJsArtifactSimpleName(testServices, moduleName) + "_v5"
|
||||||
|
}
|
||||||
|
|
||||||
fun getJsArtifactsOutputDir(testServices: TestServices): File {
|
fun getJsArtifactsOutputDir(testServices: TestServices): File {
|
||||||
return testServices.temporaryDirectoryManager.getOrCreateTempDirectory(OUTPUT_DIR_NAME)
|
return testServices.temporaryDirectoryManager.getOrCreateTempDirectory(OUTPUT_DIR_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getJsKlibOutputDir(testServices: TestServices): File {
|
||||||
|
return testServices.temporaryDirectoryManager.getOrCreateTempDirectory(OUTPUT_KLIB_DIR_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
fun getDceJsArtifactsOutputDir(testServices: TestServices): File {
|
fun getDceJsArtifactsOutputDir(testServices: TestServices): File {
|
||||||
return testServices.temporaryDirectoryManager.getOrCreateTempDirectory(DCE_OUTPUT_DIR_NAME)
|
return testServices.temporaryDirectoryManager.getOrCreateTempDirectory(DCE_OUTPUT_DIR_NAME)
|
||||||
}
|
}
|
||||||
@@ -98,6 +119,39 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
|
|||||||
project, configuration, CompilerEnvironment, METADATA_CACHE, (JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST).toSet()
|
project, configuration, CompilerEnvironment, METADATA_CACHE, (JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST).toSet()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getMainModule(testServices: TestServices): TestModule {
|
||||||
|
val modules = testServices.moduleStructure.modules
|
||||||
|
val inferMainModule = JsEnvironmentConfigurationDirectives.INFER_MAIN_MODULE in testServices.moduleStructure.allDirectives
|
||||||
|
return when {
|
||||||
|
inferMainModule -> modules.last()
|
||||||
|
else -> modules.singleOrNull { it.name == ModuleStructureExtractor.DEFAULT_MODULE_NAME } ?: modules.single()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isMainModule(module: TestModule, testServices: TestServices): Boolean {
|
||||||
|
return module == getMainModule(testServices)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getMainModuleName(testServices: TestServices): String {
|
||||||
|
return getMainModule(testServices).name
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getStdlibPathsForModule(module: TestModule): List<String> {
|
||||||
|
val needsFullIrRuntime = JsEnvironmentConfigurationDirectives.KJS_WITH_FULL_RUNTIME in module.directives ||
|
||||||
|
ConfigurationDirectives.WITH_STDLIB in module.directives ||
|
||||||
|
ConfigurationDirectives.WITH_RUNTIME in module.directives
|
||||||
|
|
||||||
|
val names = if (needsFullIrRuntime) listOf("full.stdlib", "kotlin.test") else listOf("reduced.stdlib")
|
||||||
|
return names.map { System.getProperty("kotlin.js.$it.path") }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getMainCallParametersForModule(module: TestModule): MainCallParameters {
|
||||||
|
return when (JsEnvironmentConfigurationDirectives.CALL_MAIN) {
|
||||||
|
in module.directives -> MainCallParameters.mainWithArguments(listOf())
|
||||||
|
else -> MainCallParameters.noCall()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -111,7 +165,8 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
|
|||||||
val registeredDirectives = module.directives
|
val registeredDirectives = module.directives
|
||||||
val moduleKinds = registeredDirectives[MODULE_KIND]
|
val moduleKinds = registeredDirectives[MODULE_KIND]
|
||||||
val moduleKind = when (moduleKinds.size) {
|
val moduleKind = when (moduleKinds.size) {
|
||||||
0 -> testServices.moduleStructure.allDirectives[MODULE_KIND].singleOrNull() ?: ModuleKind.PLAIN
|
0 -> testServices.moduleStructure.allDirectives[MODULE_KIND].singleOrNull()
|
||||||
|
?: if (JsEnvironmentConfigurationDirectives.ES_MODULES in registeredDirectives) ModuleKind.ES else ModuleKind.PLAIN
|
||||||
1 -> moduleKinds.single()
|
1 -> moduleKinds.single()
|
||||||
else -> error("Too many module kinds passed ${moduleKinds.joinToArrayString()}")
|
else -> error("Too many module kinds passed ${moduleKinds.joinToArrayString()}")
|
||||||
}
|
}
|
||||||
@@ -143,6 +198,9 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
|
|||||||
if (errorIgnorancePolicy.allowErrors) {
|
if (errorIgnorancePolicy.allowErrors) {
|
||||||
configuration.put(JSConfigurationKeys.DEVELOPER_MODE, true)
|
configuration.put(JSConfigurationKeys.DEVELOPER_MODE, true)
|
||||||
}
|
}
|
||||||
|
if (errorIgnorancePolicy != ErrorTolerancePolicy.DEFAULT) {
|
||||||
|
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
|
||||||
|
}
|
||||||
|
|
||||||
val multiModule = testServices.moduleStructure.modules.size > 1
|
val multiModule = testServices.moduleStructure.modules.size > 1
|
||||||
configuration.put(JSConfigurationKeys.META_INFO, multiModule)
|
configuration.put(JSConfigurationKeys.META_INFO, multiModule)
|
||||||
@@ -160,10 +218,7 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
|
|||||||
|
|
||||||
configuration.put(
|
configuration.put(
|
||||||
JSConfigurationKeys.FILE_PATHS_PREFIX_MAP,
|
JSConfigurationKeys.FILE_PATHS_PREFIX_MAP,
|
||||||
mapOf(
|
mapOf(File(".").absolutePath.removeSuffix(".") to "")
|
||||||
// tmpDir.absolutePath to "<TMP>", // TODO check do we need this on js ir tests
|
|
||||||
File(".").absolutePath.removeSuffix(".") to ""
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
configuration.put(CommonConfigurationKeys.EXPECT_ACTUAL_LINKER, EXPECT_ACTUAL_LINKER in registeredDirectives)
|
configuration.put(CommonConfigurationKeys.EXPECT_ACTUAL_LINKER, EXPECT_ACTUAL_LINKER in registeredDirectives)
|
||||||
|
|||||||
-1
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.test.generators
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
|
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
|
||||||
import org.jetbrains.kotlin.generators.util.TestGeneratorUtil
|
import org.jetbrains.kotlin.generators.util.TestGeneratorUtil
|
||||||
import org.jetbrains.kotlin.js.testNew.*
|
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import org.jetbrains.kotlin.test.runners.*
|
import org.jetbrains.kotlin.test.runners.*
|
||||||
import org.jetbrains.kotlin.test.runners.codegen.*
|
import org.jetbrains.kotlin.test.runners.codegen.*
|
||||||
|
|||||||
@@ -288,9 +288,11 @@ projectTest("jsTest", parallel = true, jUnitMode = JUnitMode.Mix) {
|
|||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
}
|
}
|
||||||
|
|
||||||
projectTest("jsIrTest", true) {
|
projectTest("jsIrTest", true, jUnitMode = JUnitMode.JUnit5) {
|
||||||
systemProperty("kotlin.js.ir.pir", "false")
|
systemProperty("kotlin.js.ir.pir", "false")
|
||||||
setUpJsBoxTests(jsEnabled = false, jsIrEnabled = true)
|
setUpJsBoxTests(jsEnabled = false, jsIrEnabled = true)
|
||||||
|
maxHeapSize = "3g"
|
||||||
|
useJUnitPlatform()
|
||||||
}
|
}
|
||||||
|
|
||||||
projectTest("jsEs6IrTest", true) {
|
projectTest("jsEs6IrTest", true) {
|
||||||
@@ -315,9 +317,11 @@ projectTest("jsEs6IrTest", true) {
|
|||||||
setUpBoxTests()
|
setUpBoxTests()
|
||||||
}
|
}
|
||||||
|
|
||||||
projectTest("jsPirTest", true) {
|
projectTest("jsPirTest", parallel = true, jUnitMode = JUnitMode.JUnit5) {
|
||||||
systemProperty("kotlin.js.ir.skipRegularMode", "true")
|
systemProperty("kotlin.js.ir.skipRegularMode", "true")
|
||||||
setUpJsBoxTests(jsEnabled = false, jsIrEnabled = true)
|
setUpJsBoxTests(jsEnabled = false, jsIrEnabled = true)
|
||||||
|
maxHeapSize = "3g"
|
||||||
|
useJUnitPlatform()
|
||||||
}
|
}
|
||||||
|
|
||||||
projectTest("quickTest", parallel = true, jUnitMode = JUnitMode.Mix) {
|
projectTest("quickTest", parallel = true, jUnitMode = JUnitMode.Mix) {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractIrCodegenBoxWasmTest
|
|||||||
import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractIrCodegenWasmJsInteropWasmTest
|
import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractIrCodegenWasmJsInteropWasmTest
|
||||||
import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractJsTranslatorWasmTest
|
import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractJsTranslatorWasmTest
|
||||||
import org.jetbrains.kotlin.js.testNew.*
|
import org.jetbrains.kotlin.js.testNew.*
|
||||||
import org.jetbrains.kotlin.js.testNew.AbstractWebDemoExamplesTest
|
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
@@ -36,10 +35,6 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
generateTestGroupSuite(args) {
|
generateTestGroupSuite(args) {
|
||||||
testGroup("js/js.tests/tests-gen", "js/js.translator/testData", testRunnerMethodName = "runTest0") {
|
testGroup("js/js.tests/tests-gen", "js/js.translator/testData", testRunnerMethodName = "runTest0") {
|
||||||
testClass<AbstractIrBoxJsTest> {
|
|
||||||
model("box/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR)
|
|
||||||
}
|
|
||||||
|
|
||||||
testClass<AbstractJsTranslatorWasmTest> {
|
testClass<AbstractJsTranslatorWasmTest> {
|
||||||
model("box/main", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.WASM)
|
model("box/main", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.WASM)
|
||||||
model("box/kotlin.test/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.WASM)
|
model("box/kotlin.test/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.WASM)
|
||||||
@@ -67,14 +62,6 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testGroup("js/js.tests/tests-gen", "compiler/testData", testRunnerMethodName = "runTest0") {
|
testGroup("js/js.tests/tests-gen", "compiler/testData", testRunnerMethodName = "runTest0") {
|
||||||
testClass<AbstractIrJsCodegenBoxTest> {
|
|
||||||
model("codegen/box", targetBackend = TargetBackend.JS_IR, excludeDirs = jvmOnlyBoxTests + "compileKotlinAgainstKotlin")
|
|
||||||
}
|
|
||||||
|
|
||||||
testClass<AbstractIrJsCodegenBoxErrorTest> {
|
|
||||||
model("codegen/boxError", targetBackend = TargetBackend.JS_IR, excludeDirs = jvmOnlyBoxTests + "compileKotlinAgainstKotlin")
|
|
||||||
}
|
|
||||||
|
|
||||||
testClass<AbstractIrCodegenBoxWasmTest> {
|
testClass<AbstractIrCodegenBoxWasmTest> {
|
||||||
model(
|
model(
|
||||||
"codegen/box", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.WASM, excludeDirs = listOf(
|
"codegen/box", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.WASM, excludeDirs = listOf(
|
||||||
@@ -108,10 +95,6 @@ fun main(args: Array<String>) {
|
|||||||
model("codegen/box", targetBackend = TargetBackend.JS_IR_ES6, excludeDirs = jvmOnlyBoxTests)
|
model("codegen/box", targetBackend = TargetBackend.JS_IR_ES6, excludeDirs = jvmOnlyBoxTests)
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractIrJsCodegenInlineTest> {
|
|
||||||
model("codegen/boxInline/", targetBackend = TargetBackend.JS_IR)
|
|
||||||
}
|
|
||||||
|
|
||||||
testClass<AbstractIrJsCodegenInlineES6Test> {
|
testClass<AbstractIrJsCodegenInlineES6Test> {
|
||||||
model("codegen/boxInline/", targetBackend = TargetBackend.JS_IR_ES6)
|
model("codegen/boxInline/", targetBackend = TargetBackend.JS_IR_ES6)
|
||||||
}
|
}
|
||||||
@@ -145,6 +128,10 @@ fun main(args: Array<String>) {
|
|||||||
testClass<AbstractWebDemoExamplesTest> {
|
testClass<AbstractWebDemoExamplesTest> {
|
||||||
model("webDemoExamples/")
|
model("webDemoExamples/")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractIrBoxJsTest> {
|
||||||
|
model("box/", pattern = "^([^_](.+))\\.kt$")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
testGroup("js/js.tests/tests-gen", "compiler/testData", testRunnerMethodName = "runTest0") {
|
testGroup("js/js.tests/tests-gen", "compiler/testData", testRunnerMethodName = "runTest0") {
|
||||||
@@ -159,6 +146,18 @@ fun main(args: Array<String>) {
|
|||||||
testClass<AbstractJsLegacyPrimitiveArraysBoxTest> {
|
testClass<AbstractJsLegacyPrimitiveArraysBoxTest> {
|
||||||
model("codegen/box/arrays")
|
model("codegen/box/arrays")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractIrJsCodegenBoxTest> {
|
||||||
|
model("codegen/box", excludeDirs = jvmOnlyBoxTests + "compileKotlinAgainstKotlin")
|
||||||
|
}
|
||||||
|
|
||||||
|
testClass<AbstractIrJsCodegenBoxErrorTest> {
|
||||||
|
model("codegen/boxError", excludeDirs = jvmOnlyBoxTests + "compileKotlinAgainstKotlin")
|
||||||
|
}
|
||||||
|
|
||||||
|
testClass<AbstractIrJsCodegenInlineTest> {
|
||||||
|
model("codegen/boxInline")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -462,9 +462,9 @@ abstract class BasicIrBoxTest(
|
|||||||
dtsFile.write(compiledModule.tsDefinitions ?: error("No ts definitions"))
|
dtsFile.write(compiledModule.tsDefinitions ?: error("No ts definitions"))
|
||||||
}
|
}
|
||||||
|
|
||||||
compiledOutput.jsProgram?.let {
|
compiledOutput.jsProgram?.let {
|
||||||
JsAstHandler.processUnitsOfJsProgram(it, units, targetBackend = TargetBackend.JS_IR) { Assert.fail(it) }
|
JsAstHandler.processUnitsOfJsProgram(it, units, targetBackend = TargetBackend.JS_IR) { Assert.fail(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateTestFile(outputDir: File, config: JsConfig, customTestModule: String?) {
|
private fun generateTestFile(outputDir: File, config: JsConfig, customTestModule: String?) {
|
||||||
|
|||||||
-18
@@ -7,24 +7,6 @@ package org.jetbrains.kotlin.js.test.ir.semantics
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.js.test.BasicIrBoxTest
|
import org.jetbrains.kotlin.js.test.BasicIrBoxTest
|
||||||
|
|
||||||
abstract class AbstractIrBoxJsTest : BasicIrBoxTest(TEST_DATA_DIR_PATH + "box/", "irBox/")
|
|
||||||
|
|
||||||
abstract class AbstractIrJsCodegenBoxTest : BasicIrBoxTest(
|
|
||||||
"compiler/testData/codegen/box/",
|
|
||||||
"codegen/irBox/"
|
|
||||||
)
|
|
||||||
|
|
||||||
abstract class AbstractIrJsCodegenBoxErrorTest : BasicIrBoxTest(
|
|
||||||
"compiler/testData/codegen/boxError/",
|
|
||||||
"codegen/irBoxError/"
|
|
||||||
)
|
|
||||||
|
|
||||||
abstract class AbstractIrJsCodegenInlineTest : BasicIrBoxTest(
|
|
||||||
"compiler/testData/codegen/boxInline/",
|
|
||||||
"codegen/irBoxInline/"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
abstract class AbstractIrCodegenWasmJsInteropJsTest : BasicIrBoxTest(
|
abstract class AbstractIrCodegenWasmJsInteropJsTest : BasicIrBoxTest(
|
||||||
"compiler/testData/codegen/wasmJsInterop",
|
"compiler/testData/codegen/wasmJsInterop",
|
||||||
"codegen/wasmJsInteropJs"
|
"codegen/wasmJsInteropJs"
|
||||||
|
|||||||
+8
-2
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHan
|
|||||||
import org.jetbrains.kotlin.test.model.*
|
import org.jetbrains.kotlin.test.model.*
|
||||||
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
|
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
|
||||||
import org.jetbrains.kotlin.test.runners.codegen.commonClassicFrontendHandlersForCodegenTest
|
import org.jetbrains.kotlin.test.runners.codegen.commonClassicFrontendHandlersForCodegenTest
|
||||||
|
import org.jetbrains.kotlin.test.services.JsLibraryProvider
|
||||||
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
|
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
|
||||||
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
||||||
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
|
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
|
||||||
@@ -35,7 +36,8 @@ abstract class AbstractJsBlackBoxCodegenTestBase<R : ResultingArtifact.FrontendO
|
|||||||
abstract val frontendFacade: Constructor<FrontendFacade<R>>
|
abstract val frontendFacade: Constructor<FrontendFacade<R>>
|
||||||
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, I>>
|
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, I>>
|
||||||
abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Js>>
|
abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Js>>
|
||||||
abstract val recompileFacade: Constructor<AbstractTestFacade<BinaryArtifacts.Js, BinaryArtifacts.Js>>
|
abstract val afterBackendFacade: Constructor<AbstractTestFacade<BinaryArtifacts.Js, BinaryArtifacts.Js>>?
|
||||||
|
abstract val recompileFacade: Constructor<AbstractTestFacade<BinaryArtifacts.Js, BinaryArtifacts.Js>>?
|
||||||
|
|
||||||
override fun TestConfigurationBuilder.configuration() {
|
override fun TestConfigurationBuilder.configuration() {
|
||||||
globalDefaults {
|
globalDefaults {
|
||||||
@@ -52,6 +54,7 @@ abstract class AbstractJsBlackBoxCodegenTestBase<R : ResultingArtifact.FrontendO
|
|||||||
+JsEnvironmentConfigurationDirectives.TYPED_ARRAYS
|
+JsEnvironmentConfigurationDirectives.TYPED_ARRAYS
|
||||||
+JsEnvironmentConfigurationDirectives.GENERATE_NODE_JS_RUNNER
|
+JsEnvironmentConfigurationDirectives.GENERATE_NODE_JS_RUNNER
|
||||||
if (skipMinification) +JsEnvironmentConfigurationDirectives.SKIP_MINIFICATION
|
if (skipMinification) +JsEnvironmentConfigurationDirectives.SKIP_MINIFICATION
|
||||||
|
if (getBoolean("kotlin.js.ir.skipRegularMode")) +JsEnvironmentConfigurationDirectives.SKIP_REGULAR_MODE
|
||||||
}
|
}
|
||||||
|
|
||||||
useConfigurators(
|
useConfigurators(
|
||||||
@@ -65,6 +68,8 @@ abstract class AbstractJsBlackBoxCodegenTestBase<R : ResultingArtifact.FrontendO
|
|||||||
::CoroutineHelpersSourceFilesProvider,
|
::CoroutineHelpersSourceFilesProvider,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
useAdditionalService(::JsLibraryProvider)
|
||||||
|
|
||||||
useAfterAnalysisCheckers(
|
useAfterAnalysisCheckers(
|
||||||
::JsFailingTestSuppressor,
|
::JsFailingTestSuppressor,
|
||||||
::BlackBoxCodegenSuppressor,
|
::BlackBoxCodegenSuppressor,
|
||||||
@@ -80,7 +85,8 @@ abstract class AbstractJsBlackBoxCodegenTestBase<R : ResultingArtifact.FrontendO
|
|||||||
irHandlersStep()
|
irHandlersStep()
|
||||||
|
|
||||||
facadeStep(backendFacade)
|
facadeStep(backendFacade)
|
||||||
facadeStep(recompileFacade)
|
afterBackendFacade?.let { facadeStep(it) }
|
||||||
|
recompileFacade?.let { facadeStep(it) }
|
||||||
jsArtifactsHandlersStep {
|
jsArtifactsHandlersStep {
|
||||||
useHandlers(
|
useHandlers(
|
||||||
::JsBoxRunner,
|
::JsBoxRunner,
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* 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.testNew
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.js.testNew.converters.JsIrBackendFacade
|
||||||
|
import org.jetbrains.kotlin.js.testNew.converters.JsKlibBackendFacade
|
||||||
|
import org.jetbrains.kotlin.js.testNew.handlers.*
|
||||||
|
import org.jetbrains.kotlin.parsing.parseBoolean
|
||||||
|
import org.jetbrains.kotlin.test.Constructor
|
||||||
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
|
import org.jetbrains.kotlin.test.backend.classic.ClassicBackendInput
|
||||||
|
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
|
||||||
|
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||||
|
import org.jetbrains.kotlin.test.builders.configureJsArtifactsHandlersStep
|
||||||
|
import org.jetbrains.kotlin.test.builders.jsArtifactsHandlersStep
|
||||||
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
||||||
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
|
||||||
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
|
||||||
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
|
||||||
|
import org.jetbrains.kotlin.test.model.*
|
||||||
|
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
||||||
|
import java.lang.Boolean.getBoolean
|
||||||
|
|
||||||
|
abstract class AbstractJsIrTest(
|
||||||
|
pathToTestDir: String,
|
||||||
|
testGroupOutputDirPrefix: String,
|
||||||
|
) : AbstractJsBlackBoxCodegenTestBase<ClassicFrontendOutputArtifact, IrBackendInput>(
|
||||||
|
FrontendKinds.ClassicFrontend, TargetBackend.JS_IR, pathToTestDir, testGroupOutputDirPrefix, skipMinification = true
|
||||||
|
) {
|
||||||
|
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
|
||||||
|
get() = ::ClassicFrontendFacade
|
||||||
|
|
||||||
|
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, IrBackendInput>>
|
||||||
|
get() = ::ClassicFrontend2IrConverter
|
||||||
|
|
||||||
|
override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Js>>
|
||||||
|
get() = ::JsKlibBackendFacade
|
||||||
|
|
||||||
|
override val afterBackendFacade: Constructor<AbstractTestFacade<BinaryArtifacts.Js, BinaryArtifacts.Js>>?
|
||||||
|
get() = ::JsIrBackendFacade
|
||||||
|
|
||||||
|
override val recompileFacade: Constructor<AbstractTestFacade<BinaryArtifacts.Js, BinaryArtifacts.Js>>?
|
||||||
|
get() = null
|
||||||
|
|
||||||
|
private fun getBoolean(s: String, default: Boolean) = System.getProperty(s)?.let { parseBoolean(it) } ?: default
|
||||||
|
|
||||||
|
override fun configure(builder: TestConfigurationBuilder) {
|
||||||
|
super.configure(builder)
|
||||||
|
with(builder) {
|
||||||
|
defaultDirectives {
|
||||||
|
val runIc = getBoolean("kotlin.js.ir.icMode")
|
||||||
|
val lowerPerModule = runIc || getBoolean("kotlin.js.ir.lowerPerModule")
|
||||||
|
if (runIc) +JsEnvironmentConfigurationDirectives.RUN_IC
|
||||||
|
if (lowerPerModule) +JsEnvironmentConfigurationDirectives.LOWER_PER_MODULE
|
||||||
|
if (getBoolean("kotlin.js.ir.klibMainModule")) +JsEnvironmentConfigurationDirectives.KLIB_MAIN_MODULE
|
||||||
|
if (getBoolean("kotlin.js.ir.es6")) +JsEnvironmentConfigurationDirectives.RUN_ES6_MODE
|
||||||
|
if (getBoolean("kotlin.js.ir.perModule")) +JsEnvironmentConfigurationDirectives.PER_MODULE
|
||||||
|
if (getBoolean("kotlin.js.ir.dce", true)) +JsEnvironmentConfigurationDirectives.RUN_IR_DCE
|
||||||
|
if (!lowerPerModule && getBoolean("kotlin.js.ir.pir", true)) +JsEnvironmentConfigurationDirectives.RUN_IR_PIR
|
||||||
|
}
|
||||||
|
|
||||||
|
configureJsArtifactsHandlersStep {
|
||||||
|
useHandlers(
|
||||||
|
::JsIrArtifactsDumpHandler,
|
||||||
|
::JsAstHandler,
|
||||||
|
::JsBoxRunner,
|
||||||
|
::NodeJsGeneratorHandler,
|
||||||
|
::JsMinifierRunner,
|
||||||
|
::JsArtifactsDumpHandler,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class AbstractIrBoxJsTest : AbstractJsIrTest(
|
||||||
|
pathToTestDir = "${JsEnvironmentConfigurator.TEST_DATA_DIR_PATH}/box/",
|
||||||
|
testGroupOutputDirPrefix = "box/"
|
||||||
|
)
|
||||||
|
|
||||||
|
open class AbstractIrJsCodegenBoxTest : AbstractJsIrTest(
|
||||||
|
pathToTestDir = "compiler/testData/codegen/box/",
|
||||||
|
testGroupOutputDirPrefix = "codegen/irBox/"
|
||||||
|
)
|
||||||
|
|
||||||
|
open class AbstractIrJsCodegenBoxErrorTest : AbstractJsIrTest(
|
||||||
|
pathToTestDir = "compiler/testData/codegen/boxError/",
|
||||||
|
testGroupOutputDirPrefix = "codegen/irBoxError/"
|
||||||
|
)
|
||||||
|
|
||||||
|
open class AbstractIrJsCodegenInlineTest : AbstractJsIrTest(
|
||||||
|
pathToTestDir = "compiler/testData/codegen/boxInline/",
|
||||||
|
testGroupOutputDirPrefix = "codegen/irBoxInline/"
|
||||||
|
)
|
||||||
|
|
||||||
@@ -35,6 +35,9 @@ abstract class AbstractJsTest(
|
|||||||
override val backendFacade: Constructor<BackendFacade<ClassicBackendInput, BinaryArtifacts.Js>>
|
override val backendFacade: Constructor<BackendFacade<ClassicBackendInput, BinaryArtifacts.Js>>
|
||||||
get() = ::ClassicJsBackendFacade
|
get() = ::ClassicJsBackendFacade
|
||||||
|
|
||||||
|
override val afterBackendFacade: Constructor<AbstractTestFacade<BinaryArtifacts.Js, BinaryArtifacts.Js>>?
|
||||||
|
get() = null
|
||||||
|
|
||||||
override val recompileFacade: Constructor<AbstractTestFacade<BinaryArtifacts.Js, BinaryArtifacts.Js>>
|
override val recompileFacade: Constructor<AbstractTestFacade<BinaryArtifacts.Js, BinaryArtifacts.Js>>
|
||||||
get() = { RecompileModuleJsBackendFacade(it, frontendFacade, frontendToBackendConverter) }
|
get() = { RecompileModuleJsBackendFacade(it, frontendFacade, frontendToBackendConverter) }
|
||||||
|
|
||||||
|
|||||||
+19
-19
@@ -38,6 +38,25 @@ class ClassicJsBackendFacade(
|
|||||||
) : ClassicBackendFacade<BinaryArtifacts.Js>(testServices, ArtifactKinds.Js) {
|
) : ClassicBackendFacade<BinaryArtifacts.Js>(testServices, ArtifactKinds.Js) {
|
||||||
companion object {
|
companion object {
|
||||||
const val KOTLIN_TEST_INTERNAL = "\$kotlin_test_internal\$"
|
const val KOTLIN_TEST_INTERNAL = "\$kotlin_test_internal\$"
|
||||||
|
|
||||||
|
fun wrapWithModuleEmulationMarkers(content: String, moduleKind: ModuleKind, moduleId: String): String {
|
||||||
|
val escapedModuleId = StringUtil.escapeStringCharacters(moduleId)
|
||||||
|
|
||||||
|
return when (moduleKind) {
|
||||||
|
ModuleKind.COMMON_JS -> "$KOTLIN_TEST_INTERNAL.beginModule();\n" +
|
||||||
|
"$content\n" +
|
||||||
|
"$KOTLIN_TEST_INTERNAL.endModule(\"$escapedModuleId\");"
|
||||||
|
|
||||||
|
ModuleKind.AMD, ModuleKind.UMD ->
|
||||||
|
"if (typeof $KOTLIN_TEST_INTERNAL !== \"undefined\") { " +
|
||||||
|
"$KOTLIN_TEST_INTERNAL.setModuleId(\"$escapedModuleId\"); }\n" +
|
||||||
|
"$content\n"
|
||||||
|
|
||||||
|
ModuleKind.PLAIN -> content
|
||||||
|
|
||||||
|
ModuleKind.ES -> error("Module emulation markers are not supported for ES modules")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(testServices: TestServices) : this(testServices, incrementalCompilationEnabled = false)
|
constructor(testServices: TestServices) : this(testServices, incrementalCompilationEnabled = false)
|
||||||
@@ -45,25 +64,6 @@ class ClassicJsBackendFacade(
|
|||||||
override val additionalServices: List<ServiceRegistrationData>
|
override val additionalServices: List<ServiceRegistrationData>
|
||||||
get() = listOf(service(::JsClassicIncrementalDataProvider))
|
get() = listOf(service(::JsClassicIncrementalDataProvider))
|
||||||
|
|
||||||
private fun wrapWithModuleEmulationMarkers(content: String, moduleKind: ModuleKind, moduleId: String): String {
|
|
||||||
val escapedModuleId = StringUtil.escapeStringCharacters(moduleId)
|
|
||||||
|
|
||||||
return when (moduleKind) {
|
|
||||||
ModuleKind.COMMON_JS -> "$KOTLIN_TEST_INTERNAL.beginModule();\n" +
|
|
||||||
"$content\n" +
|
|
||||||
"$KOTLIN_TEST_INTERNAL.endModule(\"$escapedModuleId\");"
|
|
||||||
|
|
||||||
ModuleKind.AMD, ModuleKind.UMD ->
|
|
||||||
"if (typeof $KOTLIN_TEST_INTERNAL !== \"undefined\") { " +
|
|
||||||
"$KOTLIN_TEST_INTERNAL.setModuleId(\"$escapedModuleId\"); }\n" +
|
|
||||||
"$content\n"
|
|
||||||
|
|
||||||
ModuleKind.PLAIN -> content
|
|
||||||
|
|
||||||
ModuleKind.ES -> error("Module emulation markers are not supported for ES modules")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun transform(module: TestModule, inputArtifact: ClassicBackendInput): BinaryArtifacts.Js {
|
override fun transform(module: TestModule, inputArtifact: ClassicBackendInput): BinaryArtifacts.Js {
|
||||||
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||||
val (psiFiles, analysisResult, project, _) = inputArtifact
|
val (psiFiles, analysisResult, project, _) = inputArtifact
|
||||||
|
|||||||
@@ -0,0 +1,241 @@
|
|||||||
|
/*
|
||||||
|
* 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.testNew.converters
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
|
||||||
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
|
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.JsGenerationOptions
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.codegen.generateEsModules
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||||
|
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||||
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
|
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
|
||||||
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.js.test.esModulesSubDir
|
||||||
|
import org.jetbrains.kotlin.js.testNew.handlers.JsBoxRunner.Companion.TEST_FUNCTION
|
||||||
|
import org.jetbrains.kotlin.js.testNew.utils.extractTestPackage
|
||||||
|
import org.jetbrains.kotlin.library.uniqueName
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
||||||
|
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||||
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
||||||
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
|
||||||
|
import org.jetbrains.kotlin.test.frontend.classic.moduleDescriptorProvider
|
||||||
|
import org.jetbrains.kotlin.test.model.*
|
||||||
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
|
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||||
|
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
||||||
|
import org.jetbrains.kotlin.test.services.jsLibraryProvider
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class JsIrBackendFacade(
|
||||||
|
val testServices: TestServices
|
||||||
|
) : AbstractTestFacade<BinaryArtifacts.Js, BinaryArtifacts.Js>() {
|
||||||
|
override val inputKind: ArtifactKinds.Js
|
||||||
|
get() = ArtifactKinds.Js
|
||||||
|
override val outputKind: ArtifactKinds.Js
|
||||||
|
get() = ArtifactKinds.Js
|
||||||
|
|
||||||
|
override fun transform(module: TestModule, inputArtifact: BinaryArtifacts.Js): BinaryArtifacts.Js? {
|
||||||
|
if (inputArtifact !is BinaryArtifacts.Js.JsKlibArtifact) {
|
||||||
|
error("JsIrBackendFacade expects BinaryArtifacts.Js.JsKlibArtifact as input")
|
||||||
|
}
|
||||||
|
|
||||||
|
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||||
|
val isMainModule = JsEnvironmentConfigurator.isMainModule(module, testServices)
|
||||||
|
if (!isMainModule) return inputArtifact
|
||||||
|
|
||||||
|
val moduleInfo = loadIrFromKlib(module, configuration, inputArtifact)
|
||||||
|
return compileIrToJs(module, moduleInfo, configuration, inputArtifact)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun compileIrToJs(
|
||||||
|
module: TestModule,
|
||||||
|
moduleInfo: IrModuleInfo,
|
||||||
|
configuration: CompilerConfiguration,
|
||||||
|
inputArtifact: BinaryArtifacts.Js,
|
||||||
|
): BinaryArtifacts.Js? {
|
||||||
|
val (irModuleFragment, dependencyModules, _, symbolTable, deserializer, _) = moduleInfo
|
||||||
|
|
||||||
|
val generateDts = false // TODO
|
||||||
|
val splitPerModule = JsEnvironmentConfigurationDirectives.SPLIT_PER_MODULE in module.directives
|
||||||
|
val splitPerFile = JsEnvironmentConfigurationDirectives.SPLIT_PER_FILE in module.directives
|
||||||
|
val perModule = JsEnvironmentConfigurationDirectives.PER_MODULE in module.directives
|
||||||
|
|
||||||
|
val granularity = when {
|
||||||
|
splitPerModule || perModule -> JsGenerationGranularity.PER_MODULE
|
||||||
|
splitPerFile -> JsGenerationGranularity.PER_FILE
|
||||||
|
else -> JsGenerationGranularity.WHOLE_PROGRAM
|
||||||
|
}
|
||||||
|
|
||||||
|
val testPackage = extractTestPackage(testServices)
|
||||||
|
val mainArguments = JsEnvironmentConfigurator.getMainCallParametersForModule(module)
|
||||||
|
.run { if (shouldBeGenerated()) arguments() else null }
|
||||||
|
val lowerPerModule = JsEnvironmentConfigurationDirectives.LOWER_PER_MODULE in module.directives
|
||||||
|
val runIrPir = JsEnvironmentConfigurationDirectives.RUN_IR_PIR in module.directives &&
|
||||||
|
JsEnvironmentConfigurationDirectives.SKIP_DCE_DRIVEN !in module.directives
|
||||||
|
val runIrDce = JsEnvironmentConfigurationDirectives.RUN_IR_DCE in module.directives
|
||||||
|
val skipRegularMode = JsEnvironmentConfigurationDirectives.SKIP_REGULAR_MODE in module.directives
|
||||||
|
|
||||||
|
val esModules = JsEnvironmentConfigurationDirectives.ES_MODULES in module.directives
|
||||||
|
if (skipRegularMode && !runIrPir) return null
|
||||||
|
val loweredIr = compileIr(
|
||||||
|
irModuleFragment,
|
||||||
|
MainModule.Klib(inputArtifact.outputFile.absolutePath),
|
||||||
|
configuration,
|
||||||
|
dependencyModules,
|
||||||
|
irModuleFragment.irBuiltins,
|
||||||
|
symbolTable,
|
||||||
|
deserializer,
|
||||||
|
PhaseConfig(jsPhases), // TODO debug mode
|
||||||
|
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, TEST_FUNCTION))),
|
||||||
|
dceDriven = runIrPir,
|
||||||
|
dceRuntimeDiagnostic = null,
|
||||||
|
es6mode = JsEnvironmentConfigurationDirectives.RUN_ES6_MODE in module.directives,
|
||||||
|
propertyLazyInitialization = JsEnvironmentConfigurationDirectives.PROPERTY_LAZY_INITIALIZATION in module.directives,
|
||||||
|
baseClassIntoMetadata = false,
|
||||||
|
lowerPerModule = lowerPerModule,
|
||||||
|
safeExternalBoolean = JsEnvironmentConfigurationDirectives.SAFE_EXTERNAL_BOOLEAN in module.directives,
|
||||||
|
safeExternalBooleanDiagnostic = module.directives[JsEnvironmentConfigurationDirectives.SAFE_EXTERNAL_BOOLEAN_DIAGNOSTIC].singleOrNull(),
|
||||||
|
granularity = granularity
|
||||||
|
)
|
||||||
|
|
||||||
|
val outputFile = File(JsEnvironmentConfigurator.getJsModuleArtifactPath(testServices, module.name) + ".js")
|
||||||
|
val dceOutputFile = File(JsEnvironmentConfigurator.getDceJsArtifactPath(testServices, module.name) + ".js")
|
||||||
|
val pirOutputFile = File(JsEnvironmentConfigurator.getPirJsArtifactPath(testServices, module.name) + ".js")
|
||||||
|
val dontSkipDceDriven = JsEnvironmentConfigurationDirectives.SKIP_DCE_DRIVEN !in module.directives
|
||||||
|
if (!esModules) {
|
||||||
|
val transformer = IrModuleToJsTransformer(
|
||||||
|
loweredIr.context,
|
||||||
|
mainArguments,
|
||||||
|
fullJs = true,
|
||||||
|
dceJs = if (runIrPir && dontSkipDceDriven) false else runIrDce,
|
||||||
|
multiModule = granularity == JsGenerationGranularity.PER_MODULE,
|
||||||
|
relativeRequirePath = false
|
||||||
|
)
|
||||||
|
return BinaryArtifacts.Js.JsIrArtifact(outputFile, transformer.generateModule(loweredIr.allModules))
|
||||||
|
}
|
||||||
|
|
||||||
|
val options = JsGenerationOptions(generatePackageJson = true, generateTypeScriptDefinitions = generateDts)
|
||||||
|
if (dontSkipDceDriven) {
|
||||||
|
generateEsModules(loweredIr, jsOutputSink(outputFile.parentFile.esModulesSubDir), mainArguments, granularity, options)
|
||||||
|
if (runIrDce) {
|
||||||
|
eliminateDeadDeclarations(loweredIr.allModules, loweredIr.context)
|
||||||
|
generateEsModules(loweredIr, jsOutputSink(dceOutputFile.parentFile.esModulesSubDir), mainArguments, granularity, options)
|
||||||
|
return BinaryArtifacts.Js.JsEsArtifact(outputFile, dceOutputFile)
|
||||||
|
}
|
||||||
|
return BinaryArtifacts.Js.JsEsArtifact(outputFile, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runIrPir && dontSkipDceDriven) {
|
||||||
|
generateEsModules(loweredIr, jsOutputSink(pirOutputFile.parentFile.esModulesSubDir), mainArguments, granularity, options)
|
||||||
|
return BinaryArtifacts.Js.JsEsArtifact(pirOutputFile, null)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadIrFromKlib(
|
||||||
|
module: TestModule,
|
||||||
|
configuration: CompilerConfiguration,
|
||||||
|
inputArtifact: BinaryArtifacts.Js.JsKlibArtifact
|
||||||
|
): IrModuleInfo {
|
||||||
|
val dependencies = testServices.moduleDescriptorProvider.getModuleDescriptor(module).allDependencyModules
|
||||||
|
val allDependencies = dependencies.associateBy { testServices.jsLibraryProvider.getCompiledLibraryByDescriptor(it) }
|
||||||
|
|
||||||
|
val messageLogger = configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None
|
||||||
|
val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), IrFactoryImpl)
|
||||||
|
|
||||||
|
val mainModuleLib = inputArtifact.library
|
||||||
|
val moduleDescriptor = inputArtifact.descriptor
|
||||||
|
val friendLibraries = configuration[JSConfigurationKeys.FRIEND_PATHS]!!.map {
|
||||||
|
val descriptor = testServices.jsLibraryProvider.getDescriptorByPath(
|
||||||
|
File(it).absolutePath
|
||||||
|
.replace("_v5.meta.js", "")
|
||||||
|
.replace("outputDir", "outputKlibDir")
|
||||||
|
)
|
||||||
|
testServices.jsLibraryProvider.getCompiledLibraryByDescriptor(descriptor)
|
||||||
|
}
|
||||||
|
val friendModules = mapOf(mainModuleLib.uniqueName to friendLibraries.map { it.uniqueName })
|
||||||
|
|
||||||
|
return getIrModuleInfoForKlib(
|
||||||
|
moduleDescriptor,
|
||||||
|
sortDependencies(allDependencies) + mainModuleLib,
|
||||||
|
friendModules,
|
||||||
|
null,
|
||||||
|
configuration,
|
||||||
|
symbolTable,
|
||||||
|
messageLogger,
|
||||||
|
loadFunctionInterfacesIntoStdlib = true,
|
||||||
|
emptyMap(),
|
||||||
|
{ emptySet() },
|
||||||
|
{ if (it == mainModuleLib) moduleDescriptor else testServices.jsLibraryProvider.getDescriptorByCompiledLibrary(it) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadIrFromSources(
|
||||||
|
module: TestModule,
|
||||||
|
configuration: CompilerConfiguration,
|
||||||
|
inputArtifact: ClassicFrontendOutputArtifact
|
||||||
|
): IrModuleInfo {
|
||||||
|
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT
|
||||||
|
val messageLogger = configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None
|
||||||
|
val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), IrFactoryImpl)
|
||||||
|
val verifySignatures = JsEnvironmentConfigurationDirectives.SKIP_MANGLE_VERIFICATION !in module.directives
|
||||||
|
|
||||||
|
val dependencies = testServices.moduleDescriptorProvider.getModuleDescriptor(module).allDependencyModules
|
||||||
|
val allDependencies = dependencies.associateBy { testServices.jsLibraryProvider.getCompiledLibraryByDescriptor(it) }
|
||||||
|
|
||||||
|
val psi2Ir = Psi2IrTranslator(
|
||||||
|
configuration.languageVersionSettings,
|
||||||
|
Psi2IrConfiguration(errorPolicy.allowErrors)
|
||||||
|
)
|
||||||
|
val psi2IrContext = psi2Ir.createGeneratorContext(
|
||||||
|
inputArtifact.analysisResult.moduleDescriptor,
|
||||||
|
inputArtifact.analysisResult.bindingContext,
|
||||||
|
symbolTable
|
||||||
|
)
|
||||||
|
|
||||||
|
return getIrModuleInfoForSourceFiles(
|
||||||
|
psi2IrContext,
|
||||||
|
inputArtifact.project,
|
||||||
|
configuration,
|
||||||
|
inputArtifact.allKtFiles.values.toList(),
|
||||||
|
sortDependencies(allDependencies),
|
||||||
|
emptyMap(),
|
||||||
|
emptyMap(),
|
||||||
|
symbolTable,
|
||||||
|
messageLogger,
|
||||||
|
loadFunctionInterfacesIntoStdlib = true,
|
||||||
|
verifySignatures,
|
||||||
|
{ emptySet() },
|
||||||
|
{ testServices.jsLibraryProvider.getDescriptorByCompiledLibrary(it) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldRunAnalysis(module: TestModule): Boolean {
|
||||||
|
return JsEnvironmentConfigurator.isMainModule(module, testServices)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* 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.testNew.converters
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.*
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.codegen.CompilerOutputSink
|
||||||
|
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||||
|
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
|
||||||
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.library.KotlinAbiVersion
|
||||||
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
|
import org.jetbrains.kotlin.test.backend.ir.IrBackendFacade
|
||||||
|
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
|
||||||
|
import org.jetbrains.kotlin.test.frontend.classic.moduleDescriptorProvider
|
||||||
|
import org.jetbrains.kotlin.test.model.ArtifactKinds
|
||||||
|
import org.jetbrains.kotlin.test.model.BinaryArtifacts
|
||||||
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
|
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||||
|
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
||||||
|
import org.jetbrains.kotlin.test.services.jsLibraryProvider
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class JsKlibBackendFacade(
|
||||||
|
testServices: TestServices
|
||||||
|
) : IrBackendFacade<BinaryArtifacts.Js>(testServices, ArtifactKinds.Js) {
|
||||||
|
override fun transform(module: TestModule, inputArtifact: IrBackendInput): BinaryArtifacts.Js {
|
||||||
|
if (inputArtifact !is IrBackendInput.JsIrBackendInput) {
|
||||||
|
error("JsIrBackendFacade expects IrBackendInput.JsIrBackendInput as input")
|
||||||
|
}
|
||||||
|
|
||||||
|
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||||
|
val project = testServices.compilerConfigurationProvider.getProject(module)
|
||||||
|
|
||||||
|
val outputFile = JsEnvironmentConfigurator.getJsKlibArtifactPath(testServices, module.name)
|
||||||
|
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT
|
||||||
|
val hasErrors = TopDownAnalyzerFacadeForJSIR.checkForErrors(inputArtifact.sourceFiles, inputArtifact.bindingContext, errorPolicy)
|
||||||
|
|
||||||
|
val dependencies = testServices.moduleDescriptorProvider.getModuleDescriptor(module).allDependencyModules.map { it as ModuleDescriptorImpl }
|
||||||
|
val allDependencies = dependencies.map { testServices.jsLibraryProvider.getCompiledLibraryByDescriptor(it) }
|
||||||
|
|
||||||
|
serializeModuleIntoKlib(
|
||||||
|
configuration[CommonConfigurationKeys.MODULE_NAME]!!,
|
||||||
|
project,
|
||||||
|
configuration,
|
||||||
|
configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None,
|
||||||
|
inputArtifact.bindingContext,
|
||||||
|
inputArtifact.sourceFiles,
|
||||||
|
klibPath = outputFile,
|
||||||
|
allDependencies,
|
||||||
|
inputArtifact.irModuleFragment,
|
||||||
|
inputArtifact.expectDescriptorToSymbol,
|
||||||
|
cleanFiles = emptyList(),
|
||||||
|
nopack = true,
|
||||||
|
perFile = false,
|
||||||
|
containsErrorCode = hasErrors,
|
||||||
|
abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data
|
||||||
|
jsOutputName = null
|
||||||
|
)
|
||||||
|
|
||||||
|
val lib = jsResolveLibraries(
|
||||||
|
dependencies.map { testServices.jsLibraryProvider.getPathByDescriptor(it) } + listOf(outputFile),
|
||||||
|
configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
|
||||||
|
configuration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger()
|
||||||
|
).getFullResolvedList().last().library
|
||||||
|
|
||||||
|
val moduleDescriptor = JsFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
|
||||||
|
lib,
|
||||||
|
configuration.languageVersionSettings,
|
||||||
|
LockBasedStorageManager("ModulesStructure"),
|
||||||
|
testServices.moduleDescriptorProvider.getModuleDescriptor(module).builtIns,
|
||||||
|
packageAccessHandler = null,
|
||||||
|
lookupTracker = LookupTracker.DO_NOTHING
|
||||||
|
)
|
||||||
|
moduleDescriptor.setDependencies(dependencies + moduleDescriptor)
|
||||||
|
testServices.moduleDescriptorProvider.replaceModuleDescriptorForModule(module, moduleDescriptor)
|
||||||
|
|
||||||
|
return BinaryArtifacts.Js.JsKlibArtifact(File(outputFile), moduleDescriptor, lib)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,9 +25,12 @@ class JsAstHandler(testServices: TestServices) : JsBinaryArtifactHandler(testSer
|
|||||||
|
|
||||||
override fun processModule(module: TestModule, info: BinaryArtifacts.Js) {
|
override fun processModule(module: TestModule, info: BinaryArtifacts.Js) {
|
||||||
val ktFiles = module.files.filter { it.isKtFile }.map { it.originalContent }
|
val ktFiles = module.files.filter { it.isKtFile }.map { it.originalContent }
|
||||||
val result = (info.unwrap() as? BinaryArtifacts.Js.OldJsArtifact)?.translationResult
|
val jsProgram = when (val artifact = info.unwrap()) {
|
||||||
?: throw IllegalArgumentException("JsBoxRunner suppose to work only with old js backend")
|
is BinaryArtifacts.Js.OldJsArtifact -> (artifact.translationResult as TranslationResult.Success).program
|
||||||
processJsProgram((result as TranslationResult.Success).program, ktFiles, module.targetBackend!!) {
|
is BinaryArtifacts.Js.JsIrArtifact -> artifact.compilerResult.outputs?.jsProgram ?: return
|
||||||
|
else -> return
|
||||||
|
}
|
||||||
|
processJsProgram(jsProgram, ktFiles, module.targetBackend!!) {
|
||||||
testServices.assertions.fail { it }
|
testServices.assertions.fail { it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,17 +5,28 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.js.testNew.handlers
|
package org.jetbrains.kotlin.js.testNew.handlers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.js.test.esModulesSubDir
|
||||||
|
import org.jetbrains.kotlin.js.test.v8tool
|
||||||
import org.jetbrains.kotlin.js.testNew.utils.*
|
import org.jetbrains.kotlin.js.testNew.utils.*
|
||||||
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
||||||
import org.jetbrains.kotlin.test.services.defaultsProvider
|
import org.jetbrains.kotlin.test.services.defaultsProvider
|
||||||
import org.jetbrains.kotlin.test.services.moduleStructure
|
import org.jetbrains.kotlin.test.services.moduleStructure
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class JsBoxRunner(testServices: TestServices) : AbstractJsArtifactsCollector(testServices) {
|
class JsBoxRunner(testServices: TestServices) : AbstractJsArtifactsCollector(testServices) {
|
||||||
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {
|
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {
|
||||||
if (someAssertionWasFailed) return
|
if (someAssertionWasFailed) return
|
||||||
|
|
||||||
|
if (JsEnvironmentConfigurationDirectives.ES_MODULES in testServices.moduleStructure.allDirectives) {
|
||||||
|
runEsCode()
|
||||||
|
} else {
|
||||||
|
runJsCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun runJsCode() {
|
||||||
val globalDirectives = testServices.moduleStructure.allDirectives
|
val globalDirectives = testServices.moduleStructure.allDirectives
|
||||||
val dontRunGeneratedCode = globalDirectives[JsEnvironmentConfigurationDirectives.DONT_RUN_GENERATED_CODE]
|
val dontRunGeneratedCode = globalDirectives[JsEnvironmentConfigurationDirectives.DONT_RUN_GENERATED_CODE]
|
||||||
.contains(testServices.defaultsProvider.defaultTargetBackend?.name)
|
.contains(testServices.defaultsProvider.defaultTargetBackend?.name)
|
||||||
@@ -45,6 +56,35 @@ class JsBoxRunner(testServices: TestServices) : AbstractJsArtifactsCollector(tes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun runEsCode() {
|
||||||
|
val globalDirectives = testServices.moduleStructure.allDirectives
|
||||||
|
|
||||||
|
val esmOutputDir = JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices).esModulesSubDir
|
||||||
|
val esmDceOutputDir = JsEnvironmentConfigurator.getDceJsArtifactsOutputDir(testServices).esModulesSubDir
|
||||||
|
val esmPirOutputDir = JsEnvironmentConfigurator.getPirJsArtifactsOutputDir(testServices).esModulesSubDir
|
||||||
|
|
||||||
|
val dontSkipRegularMode = JsEnvironmentConfigurationDirectives.SKIP_REGULAR_MODE !in globalDirectives
|
||||||
|
val dontSkipDceDriven = JsEnvironmentConfigurationDirectives.SKIP_DCE_DRIVEN !in globalDirectives
|
||||||
|
val runIrDce = JsEnvironmentConfigurationDirectives.RUN_IR_DCE in globalDirectives
|
||||||
|
val runIrPir = JsEnvironmentConfigurationDirectives.RUN_IR_PIR in globalDirectives
|
||||||
|
if (dontSkipRegularMode) {
|
||||||
|
singleRunEsCode(esmOutputDir)
|
||||||
|
if (runIrDce) {
|
||||||
|
singleRunEsCode(esmDceOutputDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runIrPir && dontSkipDceDriven) {
|
||||||
|
singleRunEsCode(esmPirOutputDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun singleRunEsCode(esmOutputDir: File) {
|
||||||
|
val perFileEsModuleFile = "$esmOutputDir/test.mjs"
|
||||||
|
val (allNonEsModuleFiles, inputJsFilesAfter) = extractAllFilesForEsRunner(testServices, modulesToArtifact, esmOutputDir)
|
||||||
|
v8tool.run(*allNonEsModuleFiles.toTypedArray(), perFileEsModuleFile, *inputJsFilesAfter.toTypedArray())
|
||||||
|
}
|
||||||
|
|
||||||
private fun runGeneratedCode(jsFiles: List<String>, testModuleName: String?, testPackage: String?, withModuleSystem: Boolean) {
|
private fun runGeneratedCode(jsFiles: List<String>, testModuleName: String?, testPackage: String?, withModuleSystem: Boolean) {
|
||||||
getTestChecker(testServices)
|
getTestChecker(testServices)
|
||||||
.check(jsFiles, testModuleName, testPackage, TEST_FUNCTION, DEFAULT_EXPECTED_RESULT, withModuleSystem)
|
.check(jsFiles, testModuleName, testPackage, TEST_FUNCTION, DEFAULT_EXPECTED_RESULT, withModuleSystem)
|
||||||
|
|||||||
+104
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* 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.testNew.handlers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.CompilationOutputs
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.jsResolveLibraries
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.toResolverLogger
|
||||||
|
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||||
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.js.test.esModulesSubDir
|
||||||
|
import org.jetbrains.kotlin.js.testNew.converters.ClassicJsBackendFacade.Companion.wrapWithModuleEmulationMarkers
|
||||||
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
|
import org.jetbrains.kotlin.test.backend.handlers.JsBinaryArtifactHandler
|
||||||
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
||||||
|
import org.jetbrains.kotlin.test.model.BinaryArtifacts
|
||||||
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
|
import org.jetbrains.kotlin.test.services.*
|
||||||
|
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
||||||
|
import org.jetbrains.kotlin.util.DummyLogger
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class JsIrArtifactsDumpHandler(testServices: TestServices) : JsBinaryArtifactHandler(testServices) {
|
||||||
|
override fun processModule(module: TestModule, info: BinaryArtifacts.Js) {
|
||||||
|
when (val artifact = info.unwrap()) {
|
||||||
|
is BinaryArtifacts.Js.JsIrArtifact -> {
|
||||||
|
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||||
|
val moduleId = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)
|
||||||
|
val moduleKind = configuration.get(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN)
|
||||||
|
val outputFile = File(JsEnvironmentConfigurator.getJsModuleArtifactPath(testServices, module.name) + ".js")
|
||||||
|
val outputDceFile = File(JsEnvironmentConfigurator.getDceJsArtifactPath(testServices, module.name) + ".js")
|
||||||
|
val outputPirFile = File(JsEnvironmentConfigurator.getPirJsArtifactPath(testServices, module.name) + ".js")
|
||||||
|
|
||||||
|
val runIrPir = JsEnvironmentConfigurationDirectives.RUN_IR_PIR in module.directives
|
||||||
|
val dontSkipDceDriven = JsEnvironmentConfigurationDirectives.SKIP_DCE_DRIVEN !in module.directives
|
||||||
|
val dontSkipRegularMode = JsEnvironmentConfigurationDirectives.SKIP_REGULAR_MODE !in module.directives
|
||||||
|
|
||||||
|
if (dontSkipRegularMode) {
|
||||||
|
artifact.compilerResult.outputs!!.writeTo(outputFile, moduleId, moduleKind)
|
||||||
|
artifact.compilerResult.outputsAfterDce?.writeTo(outputDceFile, moduleId, moduleKind)
|
||||||
|
} else if (runIrPir && dontSkipDceDriven) {
|
||||||
|
artifact.compilerResult.outputs!!.writeTo(outputPirFile, moduleId, moduleKind)
|
||||||
|
} else {
|
||||||
|
TODO("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
is BinaryArtifacts.Js.JsKlibArtifact -> {
|
||||||
|
testServices.jsLibraryProvider.setDescriptorAndLibraryByName(info.outputFile.absolutePath, artifact.descriptor as ModuleDescriptorImpl, artifact.library)
|
||||||
|
}
|
||||||
|
is BinaryArtifacts.Js.JsEsArtifact -> {
|
||||||
|
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||||
|
val moduleName = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)
|
||||||
|
val esmTestFile = info.outputFile.parentFile.esModulesSubDir.resolve("test.mjs")
|
||||||
|
createEsTestFile(esmTestFile, moduleName)
|
||||||
|
|
||||||
|
val dceEsmTestFile = artifact.outputDceFile?.parentFile?.esModulesSubDir?.resolve("test.mjs") ?: return
|
||||||
|
createEsTestFile(dceEsmTestFile, moduleName)
|
||||||
|
}
|
||||||
|
else -> return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO write dts
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createEsTestFile(file: File, moduleName: String) {
|
||||||
|
val customTestModule = testServices.moduleStructure.modules
|
||||||
|
.flatMap { it.files }
|
||||||
|
.singleOrNull { JsEnvironmentConfigurationDirectives.ENTRY_ES_MODULE in it.directives }
|
||||||
|
val customTestModuleText = customTestModule?.let { testServices.sourceFileProvider.getContentOfSourceFile(it) }
|
||||||
|
|
||||||
|
val defaultTestModule =
|
||||||
|
"""
|
||||||
|
import { box } from './${moduleName}/index.js';
|
||||||
|
let res = box();
|
||||||
|
if (res !== "OK") {
|
||||||
|
throw "Wrong result: " + String(res);
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
file.writeText(customTestModuleText ?: defaultTestModule)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
|
||||||
|
|
||||||
|
private fun CompilationOutputs.writeTo(outputFile: File, moduleId: String, moduleKind: ModuleKind) {
|
||||||
|
val wrappedCode = wrapWithModuleEmulationMarkers(jsCode, moduleId = moduleId, moduleKind = moduleKind)
|
||||||
|
outputFile.write(wrappedCode)
|
||||||
|
|
||||||
|
dependencies.forEach { (moduleId, outputs) ->
|
||||||
|
val moduleWrappedCode = wrapWithModuleEmulationMarkers(outputs.jsCode, moduleKind, moduleId)
|
||||||
|
val dependencyPath = outputFile.absolutePath.replace("_v5.js", "-${moduleId}_v5.js")
|
||||||
|
File(dependencyPath).write(moduleWrappedCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun File.write(text: String) {
|
||||||
|
parentFile.mkdirs()
|
||||||
|
writeText(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,8 +28,9 @@ class JsMinifierRunner(testServices: TestServices) : AbstractJsArtifactsCollecto
|
|||||||
val globalDirectives = testServices.moduleStructure.allDirectives
|
val globalDirectives = testServices.moduleStructure.allDirectives
|
||||||
val dontRunGeneratedCode = globalDirectives[JsEnvironmentConfigurationDirectives.DONT_RUN_GENERATED_CODE]
|
val dontRunGeneratedCode = globalDirectives[JsEnvironmentConfigurationDirectives.DONT_RUN_GENERATED_CODE]
|
||||||
.contains(testServices.defaultsProvider.defaultTargetBackend?.name)
|
.contains(testServices.defaultsProvider.defaultTargetBackend?.name)
|
||||||
|
val esModules = JsEnvironmentConfigurationDirectives.ES_MODULES in globalDirectives
|
||||||
|
|
||||||
if (dontRunGeneratedCode) return
|
if (dontRunGeneratedCode || esModules) return
|
||||||
|
|
||||||
val allJsFiles = getOnlyJsFilesForRunner(testServices, modulesToArtifact)
|
val allJsFiles = getOnlyJsFilesForRunner(testServices, modulesToArtifact)
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class JsSourceMapHandler(testServices: TestServices) : JsBinaryArtifactHandler(t
|
|||||||
override fun processModule(module: TestModule, info: BinaryArtifacts.Js) {
|
override fun processModule(module: TestModule, info: BinaryArtifacts.Js) {
|
||||||
val outputFile = File(JsEnvironmentConfigurator.getJsModuleArtifactPath(testServices, module.name))
|
val outputFile = File(JsEnvironmentConfigurator.getJsModuleArtifactPath(testServices, module.name))
|
||||||
val result = (info.unwrap() as? BinaryArtifacts.Js.OldJsArtifact)?.translationResult
|
val result = (info.unwrap() as? BinaryArtifacts.Js.OldJsArtifact)?.translationResult
|
||||||
?: throw IllegalArgumentException("JsBoxRunner suppose to work only with old js backend")
|
?: throw IllegalArgumentException("JsSourceMapHandler suppose to work only with old js backend")
|
||||||
val remap = JsEnvironmentConfigurationDirectives.SKIP_SOURCEMAP_REMAPPING !in module.directives
|
val remap = JsEnvironmentConfigurationDirectives.SKIP_SOURCEMAP_REMAPPING !in module.directives
|
||||||
checkSourceMap(outputFile, (result as TranslationResult.Success).program, remap) { expected, actual ->
|
checkSourceMap(outputFile, (result as TranslationResult.Success).program, remap) { expected, actual ->
|
||||||
testServices.assertions.assertEquals(expected, actual)
|
testServices.assertions.assertEquals(expected, actual)
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ package org.jetbrains.kotlin.js.testNew.handlers
|
|||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import org.jetbrains.kotlin.js.testNew.utils.extractTestPackage
|
import org.jetbrains.kotlin.js.testNew.utils.extractTestPackage
|
||||||
import org.jetbrains.kotlin.js.testNew.utils.getMainModuleName
|
|
||||||
import org.jetbrains.kotlin.js.testNew.utils.getOnlyJsFilesForRunner
|
import org.jetbrains.kotlin.js.testNew.utils.getOnlyJsFilesForRunner
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
|
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
|
||||||
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
||||||
|
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator.Companion.getMainModuleName
|
||||||
import org.jetbrains.kotlin.test.services.defaultsProvider
|
import org.jetbrains.kotlin.test.services.defaultsProvider
|
||||||
import org.jetbrains.kotlin.test.services.moduleStructure
|
import org.jetbrains.kotlin.test.services.moduleStructure
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -30,8 +30,9 @@ class NodeJsGeneratorHandler(testServices: TestServices) : AbstractJsArtifactsCo
|
|||||||
.contains(testServices.defaultsProvider.defaultTargetBackend?.name)
|
.contains(testServices.defaultsProvider.defaultTargetBackend?.name)
|
||||||
val generateNodeJsRunner = JsEnvironmentConfigurationDirectives.GENERATE_NODE_JS_RUNNER in globalDirectives
|
val generateNodeJsRunner = JsEnvironmentConfigurationDirectives.GENERATE_NODE_JS_RUNNER in globalDirectives
|
||||||
val skipNodeJs = JsEnvironmentConfigurationDirectives.SKIP_NODE_JS in globalDirectives
|
val skipNodeJs = JsEnvironmentConfigurationDirectives.SKIP_NODE_JS in globalDirectives
|
||||||
|
val esModules = JsEnvironmentConfigurationDirectives.ES_MODULES in globalDirectives
|
||||||
|
|
||||||
if (dontRunGeneratedCode || !generateNodeJsRunner || skipNodeJs) return
|
if (dontRunGeneratedCode || !generateNodeJsRunner || skipNodeJs || esModules) return
|
||||||
|
|
||||||
val mainModuleName = getMainModuleName(testServices)
|
val mainModuleName = getMainModuleName(testServices)
|
||||||
val outputDir = File(JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices).absolutePath)
|
val outputDir = File(JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices).absolutePath)
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.js.testNew.handlers.JsBoxRunner.Companion.TEST_FUNCT
|
|||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.INFER_MAIN_MODULE
|
|
||||||
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.NO_JS_MODULE_SYSTEM
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.NO_JS_MODULE_SYSTEM
|
||||||
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.RUN_PLAIN_BOX_FUNCTION
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.RUN_PLAIN_BOX_FUNCTION
|
||||||
import org.jetbrains.kotlin.test.model.BinaryArtifacts
|
import org.jetbrains.kotlin.test.model.BinaryArtifacts
|
||||||
@@ -21,6 +20,7 @@ import org.jetbrains.kotlin.test.model.TestFile
|
|||||||
import org.jetbrains.kotlin.test.model.TestModule
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
import org.jetbrains.kotlin.test.services.*
|
import org.jetbrains.kotlin.test.services.*
|
||||||
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
||||||
|
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator.Companion.getMainModule
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
private const val MODULE_EMULATION_FILE = "${JsEnvironmentConfigurator.TEST_DATA_DIR_PATH}/moduleEmulation.js"
|
private const val MODULE_EMULATION_FILE = "${JsEnvironmentConfigurator.TEST_DATA_DIR_PATH}/moduleEmulation.js"
|
||||||
@@ -52,6 +52,19 @@ private fun extractJsFiles(
|
|||||||
return before to after
|
return before to after
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun extractMjsFiles(esmOutputDir: File, modulesToArtifact: Map<TestModule, BinaryArtifacts.Js>): List<String> {
|
||||||
|
fun copyInputMjsFile(inputMjsFile: TestFile): String {
|
||||||
|
val targetFile = File(esmOutputDir, inputMjsFile.name)
|
||||||
|
targetFile.writeText(inputMjsFile.originalContent)
|
||||||
|
return targetFile.absolutePath
|
||||||
|
}
|
||||||
|
|
||||||
|
return modulesToArtifact
|
||||||
|
.flatMap { moduleToArtifact -> moduleToArtifact.key.files }
|
||||||
|
.filter { it.isMjsFile }
|
||||||
|
.map { copyInputMjsFile(it) }
|
||||||
|
}
|
||||||
|
|
||||||
private fun getAdditionalFiles(testServices: TestServices): List<String> {
|
private fun getAdditionalFiles(testServices: TestServices): List<String> {
|
||||||
val originalFile = testServices.moduleStructure.originalTestDataFiles.first()
|
val originalFile = testServices.moduleStructure.originalTestDataFiles.first()
|
||||||
|
|
||||||
@@ -67,6 +80,14 @@ private fun getAdditionalFiles(testServices: TestServices): List<String> {
|
|||||||
return additionalFiles
|
return additionalFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getAdditionalMjsFiles(testServices: TestServices): List<String> {
|
||||||
|
val originalFile = testServices.moduleStructure.originalTestDataFiles.first()
|
||||||
|
|
||||||
|
return originalFile.parentFile.resolve(originalFile.nameWithoutExtension + ".mjs")
|
||||||
|
.takeIf { it.exists() }
|
||||||
|
?.let { listOf(it.absolutePath) } ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
private fun getAdditionalMainFiles(testServices: TestServices): List<String> {
|
private fun getAdditionalMainFiles(testServices: TestServices): List<String> {
|
||||||
val originalFile = testServices.moduleStructure.originalTestDataFiles.first()
|
val originalFile = testServices.moduleStructure.originalTestDataFiles.first()
|
||||||
val additionalFiles = mutableListOf<String>()
|
val additionalFiles = mutableListOf<String>()
|
||||||
@@ -98,34 +119,62 @@ fun getAllFilesForRunner(
|
|||||||
val additionalFiles = getAdditionalFiles(testServices)
|
val additionalFiles = getAdditionalFiles(testServices)
|
||||||
val additionalMainFiles = getAdditionalMainFiles(testServices)
|
val additionalMainFiles = getAdditionalMainFiles(testServices)
|
||||||
|
|
||||||
val artifactsPaths = modulesToArtifact.values.map { it.outputFile.absolutePath }
|
val artifactsPaths = modulesToArtifact.values.map { it.outputFile.absolutePath }.filter { !File(it).isDirectory }
|
||||||
val dceJsFiles = artifactsPaths.map { it.replace(outputDir.absolutePath, dceOutputDir.absolutePath) }
|
val klibDependencies = modulesToArtifact.values
|
||||||
val pirJsFiles = artifactsPaths.map { it.replace(outputDir.absolutePath, pirOutputDir.absolutePath) }
|
.filterIsInstance<BinaryArtifacts.Js.JsIrArtifact>()
|
||||||
|
.singleOrNull()?.let { artifact ->
|
||||||
|
artifact.compilerResult?.outputs?.dependencies?.map { (moduleId, _) ->
|
||||||
|
artifact.outputFile.absolutePath.replace("_v5.js", "-${moduleId}_v5.js")
|
||||||
|
}
|
||||||
|
} ?: emptyList()
|
||||||
|
val dceJsFiles = (klibDependencies + artifactsPaths).map { it.replace(outputDir.absolutePath, dceOutputDir.absolutePath) }
|
||||||
|
val pirJsFiles = (klibDependencies + artifactsPaths).map { it.replace(outputDir.absolutePath, pirOutputDir.absolutePath) }
|
||||||
|
|
||||||
val allJsFiles = additionalFiles + inputJsFilesBefore + artifactsPaths + commonFiles + additionalMainFiles + inputJsFilesAfter
|
val allJsFiles = additionalFiles + inputJsFilesBefore + klibDependencies + artifactsPaths + commonFiles + additionalMainFiles + inputJsFilesAfter
|
||||||
val dceAllJsFiles = additionalFiles + inputJsFilesBefore + dceJsFiles + commonFiles + additionalMainFiles + inputJsFilesAfter
|
val dceAllJsFiles = additionalFiles + inputJsFilesBefore + dceJsFiles + commonFiles + additionalMainFiles + inputJsFilesAfter
|
||||||
val pirAllJsFiles = additionalFiles + inputJsFilesBefore + pirJsFiles + commonFiles + additionalMainFiles + inputJsFilesAfter
|
val pirAllJsFiles = additionalFiles + inputJsFilesBefore + pirJsFiles + commonFiles + additionalMainFiles + inputJsFilesAfter
|
||||||
|
|
||||||
return Triple(allJsFiles, dceAllJsFiles, pirAllJsFiles)
|
return Triple(allJsFiles, dceAllJsFiles, pirAllJsFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun extractAllFilesForEsRunner(
|
||||||
|
testServices: TestServices, modulesToArtifact: Map<TestModule, BinaryArtifacts.Js>, esmOutputDir: File
|
||||||
|
): Pair<List<String>, List<String>> {
|
||||||
|
val originalFile = testServices.moduleStructure.originalTestDataFiles.first()
|
||||||
|
|
||||||
|
val commonFiles = JsAdditionalSourceProvider.getAdditionalJsFiles(originalFile.parent).map { it.absolutePath }
|
||||||
|
val (inputJsFilesBefore, inputJsFilesAfter) = extractJsFiles(testServices, modulesToArtifact)
|
||||||
|
val additionalFiles = getAdditionalFiles(testServices)
|
||||||
|
val additionalMjsFiles = getAdditionalMjsFiles(testServices)
|
||||||
|
val additionalMainFiles = getAdditionalMainFiles(testServices)
|
||||||
|
|
||||||
|
val allNonEsModuleFiles = additionalFiles + inputJsFilesBefore + commonFiles
|
||||||
|
|
||||||
|
// Copy __main file if present
|
||||||
|
if (additionalMainFiles.isNotEmpty()) {
|
||||||
|
val newFileName = File(esmOutputDir, "test.mjs")
|
||||||
|
newFileName.delete()
|
||||||
|
File(additionalMainFiles.first()).copyTo(newFileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy all .mjs files into generated directory
|
||||||
|
modulesToArtifact
|
||||||
|
.flatMap { moduleToArtifact -> moduleToArtifact.key.files }
|
||||||
|
.filter { it.isMjsFile }
|
||||||
|
.map { File(esmOutputDir, it.name).writeText(it.originalContent) }
|
||||||
|
|
||||||
|
additionalMjsFiles.forEach { mjsFile ->
|
||||||
|
val outFile = File(esmOutputDir, File(mjsFile).name)
|
||||||
|
File(mjsFile).copyTo(outFile, overwrite = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Pair(allNonEsModuleFiles, inputJsFilesAfter)
|
||||||
|
}
|
||||||
|
|
||||||
fun getOnlyJsFilesForRunner(testServices: TestServices, modulesToArtifact: Map<TestModule, BinaryArtifacts.Js>): List<String> {
|
fun getOnlyJsFilesForRunner(testServices: TestServices, modulesToArtifact: Map<TestModule, BinaryArtifacts.Js>): List<String> {
|
||||||
return getAllFilesForRunner(testServices, modulesToArtifact).first
|
return getAllFilesForRunner(testServices, modulesToArtifact).first
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getMainModule(testServices: TestServices): TestModule {
|
|
||||||
val modules = testServices.moduleStructure.modules
|
|
||||||
val inferMainModule = INFER_MAIN_MODULE in testServices.moduleStructure.allDirectives
|
|
||||||
return when {
|
|
||||||
inferMainModule -> modules.last()
|
|
||||||
else -> modules.singleOrNull { it.name == ModuleStructureExtractor.DEFAULT_MODULE_NAME } ?: modules.single()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getMainModuleName(testServices: TestServices): String {
|
|
||||||
return getMainModule(testServices).name
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getTestModuleName(testServices: TestServices): String? {
|
fun getTestModuleName(testServices: TestServices): String? {
|
||||||
val runPlainBoxFunction = RUN_PLAIN_BOX_FUNCTION in testServices.moduleStructure.allDirectives
|
val runPlainBoxFunction = RUN_PLAIN_BOX_FUNCTION in testServices.moduleStructure.allDirectives
|
||||||
if (runPlainBoxFunction) return null
|
if (runPlainBoxFunction) return null
|
||||||
@@ -144,10 +193,10 @@ fun extractTestPackage(testServices: TestServices): String? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ktFiles.single { ktFile ->
|
return ktFiles.singleOrNull { ktFile ->
|
||||||
val boxFunction = ktFile.declarations.find { it is KtNamedFunction && it.name == TEST_FUNCTION }
|
val boxFunction = ktFile.declarations.find { it is KtNamedFunction && it.name == TEST_FUNCTION }
|
||||||
boxFunction != null
|
boxFunction != null
|
||||||
}.packageFqName.asString().takeIf { it.isNotEmpty() }
|
}?.packageFqName?.asString()?.takeIf { it.isNotEmpty() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTestChecker(testServices: TestServices): AbstractJsTestChecker {
|
fun getTestChecker(testServices: TestServices): AbstractJsTestChecker {
|
||||||
|
|||||||
+1759
-652
File diff suppressed because it is too large
Load Diff
+25
-22
@@ -3,123 +3,126 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.ir.semantics;
|
package org.jetbrains.kotlin.js.testNew;
|
||||||
|
|
||||||
import com.intellij.testFramework.TestDataPath;
|
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.util.KtTestUtil;
|
||||||
import org.jetbrains.kotlin.test.TargetBackend;
|
import org.jetbrains.kotlin.test.TargetBackend;
|
||||||
import org.jetbrains.kotlin.test.TestMetadata;
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@TestMetadata("compiler/testData/codegen/boxError")
|
@TestMetadata("compiler/testData/codegen/boxError")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
|
||||||
public class IrJsCodegenBoxErrorTestGenerated extends AbstractIrJsCodegenBoxErrorTest {
|
public class IrJsCodegenBoxErrorTestGenerated extends AbstractIrJsCodegenBoxErrorTest {
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
@Test
|
||||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInBoxError() throws Exception {
|
public void testAllFilesPresentInBoxError() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxError"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true, "testsWithJava9", "testsWithJava15", "testsWithJava17", "compileKotlinAgainstKotlin");
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxError"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true, "testsWithJava9", "testsWithJava15", "testsWithJava17", "compileKotlinAgainstKotlin");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/boxError/semantic")
|
@TestMetadata("compiler/testData/codegen/boxError/semantic")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
public class Semantic {
|
||||||
public static class Semantic extends AbstractIrJsCodegenBoxErrorTest {
|
@Test
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInSemantic() throws Exception {
|
public void testAllFilesPresentInSemantic() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxError/semantic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxError/semantic"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("castToErrorType.kt")
|
@TestMetadata("castToErrorType.kt")
|
||||||
public void testCastToErrorType() throws Exception {
|
public void testCastToErrorType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/semantic/castToErrorType.kt");
|
runTest("compiler/testData/codegen/boxError/semantic/castToErrorType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("catchErrorType.kt")
|
@TestMetadata("catchErrorType.kt")
|
||||||
public void testCatchErrorType() throws Exception {
|
public void testCatchErrorType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/semantic/catchErrorType.kt");
|
runTest("compiler/testData/codegen/boxError/semantic/catchErrorType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("evaluationOrder.kt")
|
@TestMetadata("evaluationOrder.kt")
|
||||||
public void testEvaluationOrder() throws Exception {
|
public void testEvaluationOrder() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/semantic/evaluationOrder.kt");
|
runTest("compiler/testData/codegen/boxError/semantic/evaluationOrder.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("mismatchTypeParameters.kt")
|
@TestMetadata("mismatchTypeParameters.kt")
|
||||||
public void testMismatchTypeParameters() throws Exception {
|
public void testMismatchTypeParameters() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/semantic/mismatchTypeParameters.kt");
|
runTest("compiler/testData/codegen/boxError/semantic/mismatchTypeParameters.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("missedBody.kt")
|
@TestMetadata("missedBody.kt")
|
||||||
public void testMissedBody() throws Exception {
|
public void testMissedBody() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/semantic/missedBody.kt");
|
runTest("compiler/testData/codegen/boxError/semantic/missedBody.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("reifiedNonInline.kt")
|
@TestMetadata("reifiedNonInline.kt")
|
||||||
public void testReifiedNonInline() throws Exception {
|
public void testReifiedNonInline() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/semantic/reifiedNonInline.kt");
|
runTest("compiler/testData/codegen/boxError/semantic/reifiedNonInline.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("reifiedWithWrongArguments.kt")
|
@TestMetadata("reifiedWithWrongArguments.kt")
|
||||||
public void testReifiedWithWrongArguments() throws Exception {
|
public void testReifiedWithWrongArguments() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/semantic/reifiedWithWrongArguments.kt");
|
runTest("compiler/testData/codegen/boxError/semantic/reifiedWithWrongArguments.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("typeMismatch.kt")
|
@TestMetadata("typeMismatch.kt")
|
||||||
public void testTypeMismatch() throws Exception {
|
public void testTypeMismatch() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/semantic/typeMismatch.kt");
|
runTest("compiler/testData/codegen/boxError/semantic/typeMismatch.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("unmatchedArguments.kt")
|
@TestMetadata("unmatchedArguments.kt")
|
||||||
public void testUnmatchedArguments() throws Exception {
|
public void testUnmatchedArguments() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/semantic/unmatchedArguments.kt");
|
runTest("compiler/testData/codegen/boxError/semantic/unmatchedArguments.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("unresolvedFunctionReferece.kt")
|
@TestMetadata("unresolvedFunctionReferece.kt")
|
||||||
public void testUnresolvedFunctionReferece() throws Exception {
|
public void testUnresolvedFunctionReferece() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/semantic/unresolvedFunctionReferece.kt");
|
runTest("compiler/testData/codegen/boxError/semantic/unresolvedFunctionReferece.kt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/boxError/syntax")
|
@TestMetadata("compiler/testData/codegen/boxError/syntax")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
public class Syntax {
|
||||||
public static class Syntax extends AbstractIrJsCodegenBoxErrorTest {
|
@Test
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
|
||||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInSyntax() throws Exception {
|
public void testAllFilesPresentInSyntax() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxError/syntax"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxError/syntax"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("arrowReference.kt")
|
@TestMetadata("arrowReference.kt")
|
||||||
public void testArrowReference() throws Exception {
|
public void testArrowReference() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/syntax/arrowReference.kt");
|
runTest("compiler/testData/codegen/boxError/syntax/arrowReference.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("evaluationOrder.kt")
|
@TestMetadata("evaluationOrder.kt")
|
||||||
public void testEvaluationOrder() throws Exception {
|
public void testEvaluationOrder() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/syntax/evaluationOrder.kt");
|
runTest("compiler/testData/codegen/boxError/syntax/evaluationOrder.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("incorectLexicalName.kt")
|
@TestMetadata("incorectLexicalName.kt")
|
||||||
public void testIncorectLexicalName() throws Exception {
|
public void testIncorectLexicalName() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/syntax/incorectLexicalName.kt");
|
runTest("compiler/testData/codegen/boxError/syntax/incorectLexicalName.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@TestMetadata("missedArgument.kt")
|
@TestMetadata("missedArgument.kt")
|
||||||
public void testMissedArgument() throws Exception {
|
public void testMissedArgument() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxError/syntax/missedArgument.kt");
|
runTest("compiler/testData/codegen/boxError/syntax/missedArgument.kt");
|
||||||
+6048
-2686
File diff suppressed because it is too large
Load Diff
+945
-520
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user