All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tschuchort.compiletesting.KotlinJsCompilation.kt Maven / Gradle / Ivy

package com.tschuchort.compiletesting

import java.io.File
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.js.K2JSCompiler
import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi

@ExperimentalCompilerApi
@Suppress("MemberVisibilityCanBePrivate")
class KotlinJsCompilation : AbstractKotlinCompilation() {

  @Deprecated("It is senseless to use with IR compiler. Only for compatibility.")
  var outputFileName: String? = null

  /**
   * Generate unpacked KLIB into parent directory of output JS file. In combination with -meta-info
   * generates both IR and pre-IR versions of library.
   */
  var irProduceKlibDir: Boolean = false

  /** Generate packed klib into file specified by -output. Disables pre-IR backend */
  var irProduceKlibFile: Boolean = false

  /** Generates JS file using IR backend. Also disables pre-IR backend */
  var irProduceJs: Boolean = true

  /** Perform experimental dead code elimination */
  var irDce: Boolean = false

  /** Print declarations' reachability info to stdout during performing DCE */
  var irDcePrintReachabilityInfo: Boolean = false

  /** Specify a compilation module name for IR backend */
  var irModuleName: String? = null

  /** Base name of generated files */
  var moduleName: String? = null

  /**
   * Path to the kotlin-stdlib-js.jar
   * If none is given, it will be searched for in the host
   * process' classpaths
   */
  var kotlinStdLibJsJar: File? by default {
    HostEnvironment.kotlinStdLibJsJar
  }

  /**
   * Generate TypeScript declarations .d.ts file alongside JS file. Available in IR backend only
   */
  var generateDts: Boolean = false

  // *.class files, Jars and resources (non-temporary) that are created by the
  // compilation will land here
  val outputDir get() = workingDir.resolve("output")

  // setup common arguments for the two kotlinc calls
  private fun jsArgs() = commonArguments(K2JSCompilerArguments()) { args ->
    // the compiler should never look for stdlib or reflect in the
    // kotlinHome directory (which is null anyway). We will put them
    // in the classpath manually if they're needed
    args.noStdlib = true

    args.moduleKind = "commonjs"
    outputFileName?.let {
      args.outputFile = File(outputDir, it).absolutePath
    }
    args.outputDir = outputDir.absolutePath
    args.sourceMapBaseDirs = jsClasspath().joinToString(separator = File.pathSeparator)
    args.libraries = listOfNotNull(kotlinStdLibJsJar).joinToString(separator = ":")

    args.irProduceKlibDir = irProduceKlibDir
    args.irProduceKlibFile = irProduceKlibFile
    args.irProduceJs = irProduceJs
    args.irDce = irDce
    args.irDcePrintReachabilityInfo = irDcePrintReachabilityInfo
    args.moduleName = moduleName
    args.irModuleName = irModuleName
    args.generateDts = generateDts
  }

  /** Runs the compilation task */
  fun compile(): JsCompilationResult {
    // make sure all needed directories exist
    sourcesDir.deleteRecursively()
    sourcesDir.mkdirs()
    outputDir.mkdirs()

    // write given sources to working directory
    val sourceFiles = sources.map { it.writeTo(sourcesDir) }

    pluginClasspaths.forEach { filepath ->
      if (!filepath.exists()) {
        error("Plugin $filepath not found")
        return makeResult(KotlinCompilation.ExitCode.INTERNAL_ERROR)
      }
    }


    /* Work around for warning that sometimes happens:
    "Failed to initialize native filesystem for Windows
    java.lang.RuntimeException: Could not find installation home path.
    Please make sure bin/idea.properties is present in the installation directory"
    See: https://github.com/arturbosch/detekt/issues/630
    */
    withSystemProperty("idea.use.native.fs.for.win", "false") {
      // step 1: compile Kotlin files
      return makeResult(compileKotlin(sourceFiles, K2JSCompiler(), jsArgs()))
    }
  }

  private fun makeResult(exitCode: KotlinCompilation.ExitCode): JsCompilationResult {
    val messages = internalMessageBuffer.readUtf8()

    if (exitCode != KotlinCompilation.ExitCode.OK)
      searchSystemOutForKnownErrors(messages)

    return JsCompilationResult(exitCode, messages, diagnostics, this)
  }

  private fun jsClasspath() = mutableListOf().apply {
    addAll(classpaths)
    addAll(listOfNotNull(kotlinStdLibCommonJar, kotlinStdLibJsJar))

    if (inheritClassPath) {
      addAll(hostClasspaths)
      log("Inheriting classpaths:  " + hostClasspaths.joinToString(File.pathSeparator))
    }
  }.distinct()
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy