Introduce "-Xreport-output-files" to report source-output mapping for JPS
This makes "-verbose" not required for JPS to run correctly and therefore allows to print more useful debugging stuff in the compiler and read them in CLI, for example. The output will also be more readable because there'll be no "output" messages
This commit is contained in:
+3
@@ -84,6 +84,9 @@ public abstract class CommonCompilerArguments implements Serializable {
|
||||
@Argument(value = "-Xallow-kotlin-package", description = "Allow compiling code in package 'kotlin'")
|
||||
public boolean allowKotlinPackage;
|
||||
|
||||
@Argument(value = "-Xreport-output-files", description = "Report source to output files mapping")
|
||||
public boolean reportOutputFiles;
|
||||
|
||||
@Argument(value = "-Xplugin", valueDescription = "<path>", description = "Load plugins from the given classpath")
|
||||
public String[] pluginClasspaths;
|
||||
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ public enum CompilerMessageSeverity {
|
||||
OUTPUT;
|
||||
|
||||
public static final EnumSet<CompilerMessageSeverity> ERRORS = EnumSet.of(ERROR, EXCEPTION);
|
||||
public static final EnumSet<CompilerMessageSeverity> VERBOSE = EnumSet.of(OUTPUT, LOGGING);
|
||||
public static final EnumSet<CompilerMessageSeverity> VERBOSE = EnumSet.of(LOGGING);
|
||||
|
||||
public boolean isError() {
|
||||
return ERRORS.contains(this);
|
||||
|
||||
@@ -220,6 +220,9 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
|
||||
if (arguments.intellijPluginRoot != null) {
|
||||
configuration.put(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT, arguments.intellijPluginRoot);
|
||||
}
|
||||
if (arguments.reportOutputFiles) {
|
||||
configuration.put(CommonConfigurationKeys.REPORT_OUTPUT_FILES, true);
|
||||
}
|
||||
@SuppressWarnings("deprecation")
|
||||
CompilerJarLocator locator = services.get(CompilerJarLocator.class);
|
||||
if (locator != null) {
|
||||
|
||||
@@ -24,23 +24,22 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
|
||||
import java.io.File
|
||||
|
||||
fun OutputFileCollection.writeAll(outputDir: File, report: (file: OutputFile, sources: List<File>, output: File) -> Unit) {
|
||||
fun OutputFileCollection.writeAll(outputDir: File, report: ((file: OutputFile, sources: List<File>, output: File) -> Unit)?) {
|
||||
for (file in asList()) {
|
||||
val sources = file.sourceFiles
|
||||
val output = File(outputDir, file.relativePath)
|
||||
report(file, sources, output)
|
||||
report?.invoke(file, sources, output)
|
||||
FileUtil.writeToFile(output, file.asByteArray())
|
||||
}
|
||||
}
|
||||
|
||||
private val REPORT_NOTHING: (OutputFile, List<File>, File) -> Unit = { _, _, _ -> }
|
||||
|
||||
fun OutputFileCollection.writeAllTo(outputDir: File) {
|
||||
writeAll(outputDir, REPORT_NOTHING)
|
||||
writeAll(outputDir, null)
|
||||
}
|
||||
|
||||
fun OutputFileCollection.writeAll(outputDir: File, messageCollector: MessageCollector) {
|
||||
writeAll(outputDir) { _, sources, output ->
|
||||
fun OutputFileCollection.writeAll(outputDir: File, messageCollector: MessageCollector, reportOutputFiles: Boolean) {
|
||||
if (!reportOutputFiles) writeAllTo(outputDir)
|
||||
else writeAll(outputDir) { _, sources, output ->
|
||||
messageCollector.report(CompilerMessageSeverity.OUTPUT, OutputMessageUtil.formatOutputMessage(sources, output))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +211,8 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||
|
||||
OutputUtilsKt.writeAll(outputFiles, outputDir, messageCollector);
|
||||
OutputUtilsKt.writeAll(outputFiles, outputDir, messageCollector,
|
||||
configuration.getBoolean(CommonConfigurationKeys.REPORT_OUTPUT_FILES));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
+7
-4
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.codegen.GeneratedClassLoader
|
||||
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationStateEventCallback
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.addKotlinSourceRoots
|
||||
@@ -87,19 +88,21 @@ object KotlinToJVMBytecodeCompiler {
|
||||
outputFiles: OutputFileCollection,
|
||||
mainClass: FqName?
|
||||
) {
|
||||
val reportOutputFiles = configuration.getBoolean(CommonConfigurationKeys.REPORT_OUTPUT_FILES)
|
||||
val jarPath = configuration.get(JVMConfigurationKeys.OUTPUT_JAR)
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
|
||||
if (jarPath != null) {
|
||||
val includeRuntime = configuration.get(JVMConfigurationKeys.INCLUDE_RUNTIME, false)
|
||||
CompileEnvironmentUtil.writeToJar(jarPath, includeRuntime, mainClass, outputFiles)
|
||||
messageCollector.report(
|
||||
OUTPUT, OutputMessageUtil.formatOutputMessage(outputFiles.asList().flatMap { it.sourceFiles }.distinct(), jarPath)
|
||||
)
|
||||
if (reportOutputFiles) {
|
||||
val message = OutputMessageUtil.formatOutputMessage(outputFiles.asList().flatMap { it.sourceFiles }.distinct(), jarPath)
|
||||
messageCollector.report(OUTPUT, message)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val outputDir = configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY) ?: File(".")
|
||||
outputFiles.writeAll(outputDir, messageCollector)
|
||||
outputFiles.writeAll(outputDir, messageCollector, reportOutputFiles)
|
||||
}
|
||||
|
||||
private fun createOutputFilesFlushingCallbackIfPossible(configuration: CompilerConfiguration): GenerationStateEventCallback {
|
||||
|
||||
@@ -25,6 +25,9 @@ object CommonConfigurationKeys {
|
||||
|
||||
@JvmField
|
||||
val MODULE_NAME = CompilerConfigurationKey<String>("module name")
|
||||
|
||||
@JvmField
|
||||
val REPORT_OUTPUT_FILES = CompilerConfigurationKey<Boolean>("report output files")
|
||||
}
|
||||
|
||||
var CompilerConfiguration.languageVersionSettings: LanguageVersionSettings
|
||||
|
||||
+1
@@ -424,6 +424,7 @@ class IncrementalJvmCompilerRunner(
|
||||
val destination = args.destination
|
||||
args.destination = null
|
||||
args.module = moduleFile.absolutePath
|
||||
args.reportOutputFiles = true
|
||||
val outputItemCollector = OutputItemsCollectorImpl()
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val messageCollector = MessageCollectorWrapper(messageCollector, outputItemCollector)
|
||||
|
||||
+1
@@ -5,6 +5,7 @@ where advanced options include:
|
||||
-Xrepeat=<count> Repeat compilation (for performance analysis)
|
||||
-Xskip-metadata-version-check Load classes with bad metadata version anyway (incl. pre-release classes)
|
||||
-Xallow-kotlin-package Allow compiling code in package 'kotlin'
|
||||
-Xreport-output-files Report source to output files mapping
|
||||
-Xplugin=<path> Load plugins from the given classpath
|
||||
-Xmulti-platform Enable experimental language support for multi-platform projects
|
||||
-Xno-check-impl Do not check presence of 'impl' modifier in multi-platform projects
|
||||
|
||||
+1
@@ -18,6 +18,7 @@ where advanced options include:
|
||||
-Xrepeat=<count> Repeat compilation (for performance analysis)
|
||||
-Xskip-metadata-version-check Load classes with bad metadata version anyway (incl. pre-release classes)
|
||||
-Xallow-kotlin-package Allow compiling code in package 'kotlin'
|
||||
-Xreport-output-files Report source to output files mapping
|
||||
-Xplugin=<path> Load plugins from the given classpath
|
||||
-Xmulti-platform Enable experimental language support for multi-platform projects
|
||||
-Xno-check-impl Do not check presence of 'impl' modifier in multi-platform projects
|
||||
|
||||
@@ -4,10 +4,6 @@ Buildfile: [TestData]/build.xml
|
||||
build:
|
||||
[kotlin2js] Compiling [[TestData]/root1] => [[Temp]/out.js]
|
||||
[kotlin2js] logging: compiling source files: [TestData]/root1/foo.kt
|
||||
[kotlin2js] output: output:
|
||||
[kotlin2js] [Temp]/out.js
|
||||
[kotlin2js] Sources:
|
||||
[kotlin2js] [TestData]/root1/foo.kt
|
||||
|
||||
BUILD SUCCESSFUL
|
||||
Total time: [time]
|
||||
|
||||
@@ -5,10 +5,6 @@ build:
|
||||
[kotlinc] Compiling [[TestData]/hello.kt] => [[Temp]/hello.jar]
|
||||
[kotlinc] logging: using Kotlin home directory [KotlinProjectHome]/dist/kotlinc
|
||||
[kotlinc] logging: configuring the compilation environment
|
||||
[kotlinc] output: output:
|
||||
[kotlinc] [Temp]/hello.jar
|
||||
[kotlinc] Sources:
|
||||
[kotlinc] [TestData]/hello.kt
|
||||
|
||||
BUILD SUCCESSFUL
|
||||
Total time: [time]
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.daemon.common.*
|
||||
import org.jetbrains.kotlin.integration.KotlinIntegrationTestBase
|
||||
import org.jetbrains.kotlin.scripts.captureOut
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import org.junit.Assert
|
||||
import java.io.File
|
||||
import java.net.URLClassLoader
|
||||
@@ -110,7 +109,8 @@ class CompilerApiTest : KotlinIntegrationTestBase() {
|
||||
fun testHelloAppLocal() {
|
||||
val messageCollector = TestMessageCollector()
|
||||
val jar = tmpdir.absolutePath + File.separator + "hello.jar"
|
||||
val (code, outputs) = compileLocally(messageCollector, "-include-runtime", File(getHelloAppBaseDir(), "hello.kt").absolutePath, "-d", jar)
|
||||
val (code, outputs) = compileLocally(messageCollector, "-include-runtime", File(getHelloAppBaseDir(), "hello.kt").absolutePath,
|
||||
"-d", jar, "-Xreport-output-files")
|
||||
Assert.assertEquals(0, code)
|
||||
Assert.assertTrue(outputs.isNotEmpty())
|
||||
Assert.assertEquals(jar, outputs.first().outputFile?.absolutePath)
|
||||
@@ -129,12 +129,13 @@ class CompilerApiTest : KotlinIntegrationTestBase() {
|
||||
|
||||
val daemonJVMOptions = configureDaemonJVMOptions("D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"${logFile.loggerCompatiblePath}\"",
|
||||
inheritMemoryLimits = false, inheritAdditionalProperties = false)
|
||||
val messageCollector = TestMessageCollector()
|
||||
val jar = tmpdir.absolutePath + File.separator + "hello.jar"
|
||||
|
||||
try {
|
||||
val (code, outputs) = compileOnDaemon(flagFile, compilerId, daemonJVMOptions, daemonOptions, messageCollector,
|
||||
"-include-runtime", File(getHelloAppBaseDir(), "hello.kt").absolutePath, "-d", jar)
|
||||
val (code, outputs) = compileOnDaemon(
|
||||
flagFile, compilerId, daemonJVMOptions, daemonOptions, TestMessageCollector(), "-include-runtime",
|
||||
File(getHelloAppBaseDir(), "hello.kt").absolutePath, "-d", jar, "-Xreport-output-files"
|
||||
)
|
||||
Assert.assertEquals(0, code)
|
||||
Assert.assertTrue(outputs.isNotEmpty())
|
||||
Assert.assertEquals(jar, outputs.first().outputFile?.absolutePath)
|
||||
@@ -149,7 +150,8 @@ class CompilerApiTest : KotlinIntegrationTestBase() {
|
||||
|
||||
fun testSimpleScriptLocal() {
|
||||
val messageCollector = TestMessageCollector()
|
||||
val (code, outputs) = compileLocally(messageCollector, File(getSimpleScriptBaseDir(), "script.kts").absolutePath, "-d", tmpdir.absolutePath)
|
||||
val (code, outputs) = compileLocally(messageCollector, File(getSimpleScriptBaseDir(), "script.kts").absolutePath,
|
||||
"-d", tmpdir.absolutePath, "-Xreport-output-files")
|
||||
Assert.assertEquals(0, code)
|
||||
Assert.assertTrue(outputs.isNotEmpty())
|
||||
Assert.assertEquals(File(tmpdir, "Script.class").absolutePath, outputs.first().outputFile?.absolutePath)
|
||||
@@ -168,12 +170,11 @@ class CompilerApiTest : KotlinIntegrationTestBase() {
|
||||
|
||||
val daemonJVMOptions = configureDaemonJVMOptions("D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"${logFile.loggerCompatiblePath}\"",
|
||||
inheritMemoryLimits = false, inheritAdditionalProperties = false)
|
||||
val messageCollector = TestMessageCollector()
|
||||
val jar = tmpdir.absolutePath + File.separator + "hello.jar"
|
||||
|
||||
try {
|
||||
val (code, outputs) = compileOnDaemon(flagFile, compilerId, daemonJVMOptions, daemonOptions, messageCollector,
|
||||
File(getSimpleScriptBaseDir(), "script.kts").absolutePath, "-d", tmpdir.absolutePath)
|
||||
val (code, outputs) = compileOnDaemon(
|
||||
flagFile, compilerId, daemonJVMOptions, daemonOptions, TestMessageCollector(),
|
||||
File(getSimpleScriptBaseDir(), "script.kts").absolutePath, "-Xreport-output-files", "-d", tmpdir.absolutePath
|
||||
)
|
||||
Assert.assertEquals(0, code)
|
||||
Assert.assertTrue(outputs.isNotEmpty())
|
||||
Assert.assertEquals(File(tmpdir, "Script.class").absolutePath, outputs.first().outputFile?.absolutePath)
|
||||
|
||||
Reference in New Issue
Block a user