Command line interface
This commit is contained in:
@@ -14,6 +14,8 @@ dependencies {
|
|||||||
compile(project(":compiler:backend"))
|
compile(project(":compiler:backend"))
|
||||||
compile(project(":compiler:backend.jvm"))
|
compile(project(":compiler:backend.jvm"))
|
||||||
compile(project(":compiler:ir.backend.common"))
|
compile(project(":compiler:ir.backend.common"))
|
||||||
|
compile(project(":compiler:ir.serialization.js"))
|
||||||
|
compile(project(":compiler:backend.js"))
|
||||||
compile(project(":compiler:light-classes"))
|
compile(project(":compiler:light-classes"))
|
||||||
compile(project(":compiler:serialization"))
|
compile(project(":compiler:serialization"))
|
||||||
compile(project(":compiler:plugin-api"))
|
compile(project(":compiler:plugin-api"))
|
||||||
|
|||||||
+12
@@ -103,6 +103,18 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
|||||||
|
|
||||||
// Advanced options
|
// Advanced options
|
||||||
|
|
||||||
|
|
||||||
|
@Argument(value = "-Xir", description = "Use IR backend")
|
||||||
|
var irBackend: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
|
@Argument(
|
||||||
|
value = "-Xir-produce-only",
|
||||||
|
valueDescription = "{ klib, js }",
|
||||||
|
description = "Type of output to produce. Overrides -meta-info argument."
|
||||||
|
)
|
||||||
|
var irProduceOnly: String? by NullableStringFreezableVar(null)
|
||||||
|
|
||||||
|
|
||||||
@GradleOption(DefaultValues.BooleanTrueDefault::class)
|
@GradleOption(DefaultValues.BooleanTrueDefault::class)
|
||||||
@Argument(value = "-Xtyped-arrays", description = "Translate primitive arrays to JS typed arrays")
|
@Argument(value = "-Xtyped-arrays", description = "Translate primitive arrays to JS typed arrays")
|
||||||
var typedArrays: Boolean by FreezableVar(true)
|
var typedArrays: Boolean by FreezableVar(true)
|
||||||
|
|||||||
@@ -84,6 +84,15 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
|||||||
private static final Map<String, ModuleKind> moduleKindMap = new HashMap<>();
|
private static final Map<String, ModuleKind> moduleKindMap = new HashMap<>();
|
||||||
private static final Map<String, SourceMapSourceEmbedding> sourceMapContentEmbeddingMap = new LinkedHashMap<>();
|
private static final Map<String, SourceMapSourceEmbedding> sourceMapContentEmbeddingMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
private K2JsIrCompiler irCompiler = null;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private K2JsIrCompiler getIrCompiler() {
|
||||||
|
if (irCompiler == null)
|
||||||
|
irCompiler = new K2JsIrCompiler();
|
||||||
|
return irCompiler;
|
||||||
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
moduleKindMap.put(K2JsArgumentConstants.MODULE_PLAIN, ModuleKind.PLAIN);
|
moduleKindMap.put(K2JsArgumentConstants.MODULE_PLAIN, ModuleKind.PLAIN);
|
||||||
moduleKindMap.put(K2JsArgumentConstants.MODULE_COMMONJS, ModuleKind.COMMON_JS);
|
moduleKindMap.put(K2JsArgumentConstants.MODULE_COMMONJS, ModuleKind.COMMON_JS);
|
||||||
@@ -163,6 +172,10 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
|||||||
) {
|
) {
|
||||||
MessageCollector messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY);
|
MessageCollector messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY);
|
||||||
|
|
||||||
|
if (arguments.getIrBackend()) {
|
||||||
|
return getIrCompiler().doExecute(arguments, configuration, rootDisposable, paths);
|
||||||
|
}
|
||||||
|
|
||||||
if (arguments.getFreeArgs().isEmpty() && !IncrementalCompilation.isEnabledForJs()) {
|
if (arguments.getFreeArgs().isEmpty() && !IncrementalCompilation.isEnabledForJs()) {
|
||||||
if (arguments.getVersion()) {
|
if (arguments.getVersion()) {
|
||||||
return OK;
|
return OK;
|
||||||
@@ -362,6 +375,11 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
|||||||
@NotNull CompilerConfiguration configuration, @NotNull K2JSCompilerArguments arguments,
|
@NotNull CompilerConfiguration configuration, @NotNull K2JSCompilerArguments arguments,
|
||||||
@NotNull Services services
|
@NotNull Services services
|
||||||
) {
|
) {
|
||||||
|
if (arguments.getIrBackend()) {
|
||||||
|
getIrCompiler().setupPlatformSpecificArgumentsAndServices(configuration, arguments, services);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MessageCollector messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY);
|
MessageCollector messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY);
|
||||||
|
|
||||||
if (arguments.getTarget() != null) {
|
if (arguments.getTarget() != null) {
|
||||||
|
|||||||
@@ -0,0 +1,383 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.cli.js
|
||||||
|
|
||||||
|
import com.intellij.openapi.Disposable
|
||||||
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
|
import org.jetbrains.kotlin.cli.common.*
|
||||||
|
import org.jetbrains.kotlin.cli.common.ExitCode.COMPILATION_ERROR
|
||||||
|
import org.jetbrains.kotlin.cli.common.ExitCode.OK
|
||||||
|
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||||
|
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants
|
||||||
|
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.MessageUtil
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser
|
||||||
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
|
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||||
|
import org.jetbrains.kotlin.config.Services
|
||||||
|
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
|
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
|
||||||
|
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.KlibModuleRef
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.generateKLib
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.compile
|
||||||
|
import org.jetbrains.kotlin.js.config.EcmaVersion
|
||||||
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.js.config.JsConfig
|
||||||
|
import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
|
import org.jetbrains.kotlin.utils.JsMetadataVersion
|
||||||
|
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||||
|
import org.jetbrains.kotlin.utils.join
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
import java.util.zip.ZipFile
|
||||||
|
|
||||||
|
enum class ProduceKind {
|
||||||
|
DEFAULT, // Determine what to produce based on js-v1 options
|
||||||
|
JS,
|
||||||
|
KLIB
|
||||||
|
}
|
||||||
|
|
||||||
|
class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||||
|
|
||||||
|
override val performanceManager: CommonCompilerPerformanceManager =
|
||||||
|
object : CommonCompilerPerformanceManager("Kotlin to JS (IR) Compiler") {}
|
||||||
|
|
||||||
|
override fun createArguments(): K2JSCompilerArguments {
|
||||||
|
return K2JSCompilerArguments()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun extractKlibFromZip(library: String, messageCollector: MessageCollector): File? {
|
||||||
|
val zipLib = ZipFile(library)
|
||||||
|
val tempDir = createTempDir(File(library).name, "klibjar")
|
||||||
|
tempDir.deleteOnExit()
|
||||||
|
var extractedKlibDir: File? = null
|
||||||
|
for (entry in zipLib.entries()) {
|
||||||
|
if (!entry.isDirectory) {
|
||||||
|
zipLib.getInputStream(entry).use { input ->
|
||||||
|
val outputEntryFile = File(tempDir, entry.name)
|
||||||
|
outputEntryFile.parentFile.mkdirs()
|
||||||
|
outputEntryFile.outputStream().use { output ->
|
||||||
|
input.copyTo(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (entry.name.endsWith("KLIB/")) {
|
||||||
|
extractedKlibDir = File(tempDir, entry.name)
|
||||||
|
messageCollector.report(INFO, "Klib $library is extracted into $extractedKlibDir")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return extractedKlibDir
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadIrLibrary(library: String, messageCollector: MessageCollector): KlibModuleRef? {
|
||||||
|
val libraryFile = File(library)
|
||||||
|
var klibDir = when {
|
||||||
|
FileUtil.isJarOrZip(libraryFile) -> {
|
||||||
|
extractKlibFromZip(library, messageCollector) ?: return null
|
||||||
|
}
|
||||||
|
!libraryFile.isDirectory -> {
|
||||||
|
messageCollector.report(ERROR, "Klib $library must be a directory")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
else ->
|
||||||
|
libraryFile
|
||||||
|
}
|
||||||
|
|
||||||
|
var klibFiles = klibDir.listFiles()
|
||||||
|
if (klibFiles.isEmpty()) {
|
||||||
|
messageCollector.report(STRONG_WARNING, "Klib $library directory is empty")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sometines gradle gives us a directory with klib directory inside
|
||||||
|
val klibDirInsideDir = klibFiles.find { it.name.endsWith("KLIB") }
|
||||||
|
if (klibDirInsideDir != null) {
|
||||||
|
klibDir = klibDirInsideDir
|
||||||
|
klibFiles = klibDir.listFiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
val metadataFile = klibFiles.find { it.extension == "klm" }
|
||||||
|
|
||||||
|
if (metadataFile == null) {
|
||||||
|
messageCollector.report(STRONG_WARNING, "No metadata file (.klm) for klib: $klibDir")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return KlibModuleRef(metadataFile.nameWithoutExtension, klibDir.absolutePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doExecute(
|
||||||
|
arguments: K2JSCompilerArguments,
|
||||||
|
configuration: CompilerConfiguration,
|
||||||
|
rootDisposable: Disposable,
|
||||||
|
paths: KotlinPaths?
|
||||||
|
): ExitCode {
|
||||||
|
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||||
|
|
||||||
|
if (arguments.freeArgs.isEmpty() && !IncrementalCompilation.isEnabledForJs()) {
|
||||||
|
if (arguments.version) {
|
||||||
|
return OK
|
||||||
|
}
|
||||||
|
messageCollector.report(ERROR, "Specify at least one source file or directory", null)
|
||||||
|
return COMPILATION_ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
val pluginLoadResult = PluginCliParser.loadPluginsSafe(
|
||||||
|
arguments.pluginClasspaths,
|
||||||
|
arguments.pluginOptions,
|
||||||
|
configuration
|
||||||
|
)
|
||||||
|
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult
|
||||||
|
|
||||||
|
val libraries = configureLibraries(arguments.libraries)
|
||||||
|
|
||||||
|
configuration.put(JSConfigurationKeys.LIBRARIES, libraries)
|
||||||
|
configuration.put(JSConfigurationKeys.TRANSITIVE_LIBRARIES, libraries)
|
||||||
|
|
||||||
|
val commonSourcesArray = arguments.commonSources
|
||||||
|
val commonSources = commonSourcesArray?.toSet() ?: emptySet()
|
||||||
|
for (arg in arguments.freeArgs) {
|
||||||
|
configuration.addKotlinSourceRoot(arg, commonSources.contains(arg))
|
||||||
|
}
|
||||||
|
|
||||||
|
val environmentForJS =
|
||||||
|
KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JS_CONFIG_FILES)
|
||||||
|
|
||||||
|
val project = environmentForJS.project
|
||||||
|
val sourcesFiles = environmentForJS.getSourceFiles()
|
||||||
|
|
||||||
|
environmentForJS.configuration.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage)
|
||||||
|
|
||||||
|
if (!checkKotlinPackageUsage(environmentForJS, sourcesFiles)) return ExitCode.COMPILATION_ERROR
|
||||||
|
|
||||||
|
val outputFilePath = arguments.outputFile
|
||||||
|
if (outputFilePath == null) {
|
||||||
|
messageCollector.report(ERROR, "IR: Specify output file via -output", null)
|
||||||
|
return ExitCode.COMPILATION_ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
if (messageCollector.hasErrors()) {
|
||||||
|
return ExitCode.COMPILATION_ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourcesFiles.isEmpty() && !IncrementalCompilation.isEnabledForJs()) {
|
||||||
|
messageCollector.report(ERROR, "No source files", null)
|
||||||
|
return COMPILATION_ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arguments.verbose) {
|
||||||
|
reportCompiledSourcesList(messageCollector, sourcesFiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
val outputFile = File(outputFilePath)
|
||||||
|
|
||||||
|
configuration.put(CommonConfigurationKeys.MODULE_NAME, FileUtil.getNameWithoutExtension(outputFile))
|
||||||
|
|
||||||
|
val config = JsConfig(project, configuration)
|
||||||
|
val outputDir: File = outputFile.parentFile ?: outputFile.absoluteFile.parentFile!!
|
||||||
|
try {
|
||||||
|
config.configuration.put(JSConfigurationKeys.OUTPUT_DIR, outputDir.canonicalFile)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
messageCollector.report(ERROR, "Could not resolve output directory", null)
|
||||||
|
return ExitCode.COMPILATION_ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Handle main call parameters
|
||||||
|
|
||||||
|
val dependencies = libraries.flatMap { listOfNotNull(loadIrLibrary(it, messageCollector)) }
|
||||||
|
.distinctBy { it.moduleName }
|
||||||
|
|
||||||
|
val produceKind = produceMap[arguments.irProduceOnly]
|
||||||
|
if (produceKind == null) {
|
||||||
|
messageCollector.report(ERROR, "Unknown produce kind: ${arguments.irProduceOnly}. Valid values are: js, klib")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (produceKind == ProduceKind.JS || produceKind == ProduceKind.DEFAULT) {
|
||||||
|
val compiledModule = compile(
|
||||||
|
project,
|
||||||
|
sourcesFiles,
|
||||||
|
configuration,
|
||||||
|
immediateDependencies = dependencies,
|
||||||
|
allDependencies = dependencies
|
||||||
|
)
|
||||||
|
|
||||||
|
outputFile.writeText(compiledModule)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (produceKind == ProduceKind.KLIB || (produceKind == ProduceKind.DEFAULT && arguments.metaInfo)) {
|
||||||
|
val outputKlibPath = "$outputFilePath.KLIB"
|
||||||
|
generateKLib(
|
||||||
|
project = config.project,
|
||||||
|
files = sourcesFiles,
|
||||||
|
configuration = config.configuration,
|
||||||
|
immediateDependencies = dependencies,
|
||||||
|
allDependencies = dependencies,
|
||||||
|
outputKlibPath = outputKlibPath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setupPlatformSpecificArgumentsAndServices(
|
||||||
|
configuration: CompilerConfiguration,
|
||||||
|
arguments: K2JSCompilerArguments,
|
||||||
|
services: Services
|
||||||
|
) {
|
||||||
|
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||||
|
|
||||||
|
if (arguments.target != null) {
|
||||||
|
assert("v5" == arguments.target) { "Unsupported ECMA version: " + arguments.target!! }
|
||||||
|
}
|
||||||
|
configuration.put(JSConfigurationKeys.TARGET, EcmaVersion.defaultVersion())
|
||||||
|
|
||||||
|
// TODO: Support source maps
|
||||||
|
if (arguments.sourceMap) {
|
||||||
|
messageCollector.report(WARNING, "source-map argument is not supported yet", null)
|
||||||
|
} else {
|
||||||
|
if (arguments.sourceMapPrefix != null) {
|
||||||
|
messageCollector.report(WARNING, "source-map-prefix argument has no effect without source map", null)
|
||||||
|
}
|
||||||
|
if (arguments.sourceMapBaseDirs != null) {
|
||||||
|
messageCollector.report(WARNING, "source-map-source-root argument has no effect without source map", null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arguments.metaInfo) {
|
||||||
|
configuration.put(JSConfigurationKeys.META_INFO, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration.put(JSConfigurationKeys.TYPED_ARRAYS_ENABLED, arguments.typedArrays)
|
||||||
|
|
||||||
|
configuration.put(JSConfigurationKeys.FRIEND_PATHS_DISABLED, arguments.friendModulesDisabled)
|
||||||
|
|
||||||
|
val friendModules = arguments.friendModules
|
||||||
|
if (!arguments.friendModulesDisabled && friendModules != null) {
|
||||||
|
val friendPaths = friendModules
|
||||||
|
.split(File.pathSeparator.toRegex())
|
||||||
|
.dropLastWhile { it.isEmpty() }
|
||||||
|
.toTypedArray()
|
||||||
|
.filterNot { it.isEmpty() }
|
||||||
|
|
||||||
|
configuration.put(JSConfigurationKeys.FRIEND_PATHS, friendPaths)
|
||||||
|
}
|
||||||
|
|
||||||
|
val moduleKindName = arguments.moduleKind
|
||||||
|
var moduleKind: ModuleKind? = if (moduleKindName != null) moduleKindMap[moduleKindName] else ModuleKind.PLAIN
|
||||||
|
if (moduleKind == null) {
|
||||||
|
messageCollector.report(
|
||||||
|
ERROR, "Unknown module kind: $moduleKindName. Valid values are: plain, amd, commonjs, umd", null
|
||||||
|
)
|
||||||
|
moduleKind = ModuleKind.PLAIN
|
||||||
|
}
|
||||||
|
configuration.put(JSConfigurationKeys.MODULE_KIND, moduleKind)
|
||||||
|
|
||||||
|
val incrementalDataProvider = services[IncrementalDataProvider::class.java]
|
||||||
|
if (incrementalDataProvider != null) {
|
||||||
|
configuration.put(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER, incrementalDataProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
val incrementalResultsConsumer = services[IncrementalResultsConsumer::class.java]
|
||||||
|
if (incrementalResultsConsumer != null) {
|
||||||
|
configuration.put(JSConfigurationKeys.INCREMENTAL_RESULTS_CONSUMER, incrementalResultsConsumer)
|
||||||
|
}
|
||||||
|
|
||||||
|
val lookupTracker = services[LookupTracker::class.java]
|
||||||
|
if (lookupTracker != null) {
|
||||||
|
configuration.put(CommonConfigurationKeys.LOOKUP_TRACKER, lookupTracker)
|
||||||
|
}
|
||||||
|
|
||||||
|
val expectActualTracker = services[ExpectActualTracker::class.java]
|
||||||
|
if (expectActualTracker != null) {
|
||||||
|
configuration.put(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER, expectActualTracker)
|
||||||
|
}
|
||||||
|
|
||||||
|
val sourceMapEmbedContentString = arguments.sourceMapEmbedSources
|
||||||
|
var sourceMapContentEmbedding: SourceMapSourceEmbedding? = if (sourceMapEmbedContentString != null)
|
||||||
|
sourceMapContentEmbeddingMap[sourceMapEmbedContentString]
|
||||||
|
else
|
||||||
|
SourceMapSourceEmbedding.INLINING
|
||||||
|
if (sourceMapContentEmbedding == null) {
|
||||||
|
val message = "Unknown source map source embedding mode: " + sourceMapEmbedContentString + ". Valid values are: " +
|
||||||
|
StringUtil.join(sourceMapContentEmbeddingMap.keys, ", ")
|
||||||
|
messageCollector.report(ERROR, message, null)
|
||||||
|
sourceMapContentEmbedding = SourceMapSourceEmbedding.INLINING
|
||||||
|
}
|
||||||
|
configuration.put(JSConfigurationKeys.SOURCE_MAP_EMBED_SOURCES, sourceMapContentEmbedding)
|
||||||
|
|
||||||
|
if (!arguments.sourceMap && sourceMapEmbedContentString != null) {
|
||||||
|
messageCollector.report(WARNING, "source-map-embed-sources argument has no effect without source map", null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun executableScriptFileName(): String {
|
||||||
|
return "kotlinc-js -Xir"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createMetadataVersion(versionArray: IntArray): BinaryVersion {
|
||||||
|
// TODO: Support metadata versions for klibs
|
||||||
|
return JsMetadataVersion(*versionArray)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val moduleKindMap = mapOf(
|
||||||
|
K2JsArgumentConstants.MODULE_PLAIN to ModuleKind.PLAIN,
|
||||||
|
K2JsArgumentConstants.MODULE_COMMONJS to ModuleKind.COMMON_JS,
|
||||||
|
K2JsArgumentConstants.MODULE_AMD to ModuleKind.AMD,
|
||||||
|
K2JsArgumentConstants.MODULE_UMD to ModuleKind.UMD
|
||||||
|
)
|
||||||
|
private val sourceMapContentEmbeddingMap = mapOf(
|
||||||
|
K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_ALWAYS to SourceMapSourceEmbedding.ALWAYS,
|
||||||
|
K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_NEVER to SourceMapSourceEmbedding.NEVER,
|
||||||
|
K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_INLINING to SourceMapSourceEmbedding.INLINING
|
||||||
|
)
|
||||||
|
private val produceMap = mapOf(
|
||||||
|
null to ProduceKind.DEFAULT,
|
||||||
|
"js" to ProduceKind.JS,
|
||||||
|
"klib" to ProduceKind.KLIB
|
||||||
|
)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
CLITool.doMain(K2JsIrCompiler(), args)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reportCompiledSourcesList(messageCollector: MessageCollector, sourceFiles: List<KtFile>) {
|
||||||
|
val fileNames = sourceFiles.map { file ->
|
||||||
|
val virtualFile = file.virtualFile
|
||||||
|
if (virtualFile != null) {
|
||||||
|
MessageUtil.virtualFileToPath(virtualFile)
|
||||||
|
} else {
|
||||||
|
file.name + " (no virtual file)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
messageCollector.report(LOGGING, "Compiling source files: " + join(fileNames, ", "), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun configureLibraries(libraryString: String?): List<String> =
|
||||||
|
libraryString?.splitByPathSeparator() ?: emptyList()
|
||||||
|
|
||||||
|
private fun String.splitByPathSeparator(): List<String> {
|
||||||
|
return this.split(File.pathSeparator.toRegex())
|
||||||
|
.dropLastWhile { it.isEmpty() }
|
||||||
|
.toTypedArray()
|
||||||
|
.filterNot { it.isEmpty() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ fun compile(
|
|||||||
project: Project,
|
project: Project,
|
||||||
files: List<KtFile>,
|
files: List<KtFile>,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
phaseConfig: PhaseConfig,
|
phaseConfig: PhaseConfig = PhaseConfig(jsPhases),
|
||||||
immediateDependencies: List<KlibModuleRef>,
|
immediateDependencies: List<KlibModuleRef>,
|
||||||
allDependencies: List<KlibModuleRef>
|
allDependencies: List<KlibModuleRef>
|
||||||
): String {
|
): String {
|
||||||
|
|||||||
+2
@@ -2,6 +2,8 @@ Usage: kotlinc-js <options> <source files>
|
|||||||
where advanced options include:
|
where advanced options include:
|
||||||
-Xfriend-modules=<path> Paths to friend modules
|
-Xfriend-modules=<path> Paths to friend modules
|
||||||
-Xfriend-modules-disabled Disable internal declaration export
|
-Xfriend-modules-disabled Disable internal declaration export
|
||||||
|
-Xir Use IR backend
|
||||||
|
-Xir-produce-only={ klib, js } Type of output to produce. Overrides -meta-info argument.
|
||||||
-Xtyped-arrays Translate primitive arrays to JS typed arrays
|
-Xtyped-arrays Translate primitive arrays to JS typed arrays
|
||||||
-Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info
|
-Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info
|
||||||
-Xallow-result-return-type Allow compiling code when `kotlin.Result` is used as a return type
|
-Xallow-result-return-type Allow compiling code when `kotlin.Result` is used as a return type
|
||||||
|
|||||||
+13
-1
@@ -567,8 +567,20 @@ open class Kotlin2JsCompile : AbstractKotlinCompile<K2JSCompilerArguments>(), Ko
|
|||||||
logger.debug("Calling compiler")
|
logger.debug("Calling compiler")
|
||||||
destinationDir.mkdirs()
|
destinationDir.mkdirs()
|
||||||
|
|
||||||
|
val libraryFilter: (File) -> Boolean
|
||||||
|
|
||||||
|
if ("-Xir" in args.freeArgs) {
|
||||||
|
logger.kotlinDebug("Using JS IR backend")
|
||||||
|
incremental = false
|
||||||
|
|
||||||
|
// TODO: Detect IR libraries
|
||||||
|
libraryFilter = { true }
|
||||||
|
} else {
|
||||||
|
libraryFilter = LibraryUtils::isKotlinJavascriptLibrary
|
||||||
|
}
|
||||||
|
|
||||||
val dependencies = compileClasspath
|
val dependencies = compileClasspath
|
||||||
.filter { LibraryUtils.isKotlinJavascriptLibrary(it) }
|
.filter(libraryFilter)
|
||||||
.map { it.canonicalPath }
|
.map { it.canonicalPath }
|
||||||
|
|
||||||
args.libraries = (dependencies + listOfNotNull(friendDependency)).distinct().let {
|
args.libraries = (dependencies + listOfNotNull(friendDependency)).distinct().let {
|
||||||
|
|||||||
Reference in New Issue
Block a user