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:
Alexander Udalov
2017-04-06 20:19:22 +03:00
parent ce145c015d
commit d8d3bafbe9
19 changed files with 73 additions and 52 deletions
@@ -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;
@@ -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;
}
@@ -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
@@ -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
View File
@@ -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
View File
@@ -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)