Add MessageCollector#hasErrors, get rid of MessageSeverityCollector

Also fix duplicated wrapping of a message collector into a message severity
collector (in CLICompiler and in the beginning of doExecute in
K2JVMCompiler/K2JSCompiler)
This commit is contained in:
Alexander Udalov
2016-02-14 18:01:39 +03:00
parent c5e2f55ea7
commit 3c81bb4bfc
15 changed files with 107 additions and 111 deletions
@@ -28,4 +28,8 @@ public enum CompilerMessageSeverity {
public static final EnumSet<CompilerMessageSeverity> ERRORS = EnumSet.of(ERROR, EXCEPTION); 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(OUTPUT, LOGGING);
public boolean isError() {
return ERRORS.contains(this);
}
} }
@@ -36,4 +36,9 @@ public class FilteringMessageCollector implements MessageCollector {
messageCollector.report(severity, message, location); messageCollector.report(severity, message, location);
} }
} }
@Override
public boolean hasErrors() {
return messageCollector.hasErrors();
}
} }
@@ -47,19 +47,23 @@ public class GroupingMessageCollector implements MessageCollector {
} }
} }
public void flush() { @Override
boolean hasError = false; public boolean hasErrors() {
for (Map.Entry<String, Message> entry : groupedMessages.entries()) {
Collection<String> keys = sortedKeys(); if (entry.getValue().severity.isError()) {
for (String path : keys) { return true;
for (Message message : groupedMessages.get(path)) {
hasError |= CompilerMessageSeverity.ERRORS.contains(message.severity);
} }
} }
for (String path : keys) { return false;
}
public void flush() {
boolean hasErrors = hasErrors();
for (String path : sortedKeys()) {
for (Message message : groupedMessages.get(path)) { for (Message message : groupedMessages.get(path)) {
if (!hasError || CompilerMessageSeverity.ERRORS.contains(message.severity)) { if (!hasErrors || message.severity.isError()) {
delegate.report(message.severity, message.message, message.location); delegate.report(message.severity, message.message, message.location);
} }
} }
@@ -19,17 +19,19 @@ package org.jetbrains.kotlin.cli.common.messages;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public interface MessageCollector { public interface MessageCollector {
MessageCollector NONE = new MessageCollector() { MessageCollector NONE = new MessageCollector() {
@Override @Override
public void report( public void report(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location) {
@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location
) {
// Do nothing // Do nothing
} }
@Override
public boolean hasErrors() {
return false;
}
}; };
void report(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location); void report(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location);
boolean hasErrors();
} }
@@ -1,49 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.cli.common.messages;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Set;
public class MessageSeverityCollector implements MessageCollector {
private final MessageCollector delegate;
private final Set<CompilerMessageSeverity> reportedSeverities = Sets.newHashSet();
public MessageSeverityCollector(@NotNull MessageCollector delegate) {
this.delegate = delegate;
}
@Override
public void report(
@NotNull CompilerMessageSeverity severity,
@NotNull String message,
@NotNull CompilerMessageLocation location
) {
delegate.report(severity, message, location);
reportedSeverities.add(severity);
}
public boolean anyReported(@NotNull CompilerMessageSeverity... severities) {
return reportedSeverities.containsAll(Arrays.asList(severities));
}
}
@@ -187,9 +187,8 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
} }
Disposable rootDisposable = Disposer.newDisposable(); Disposable rootDisposable = Disposer.newDisposable();
try { try {
MessageSeverityCollector severityCollector = new MessageSeverityCollector(groupingCollector); ExitCode code = doExecute(arguments, services, groupingCollector, rootDisposable);
ExitCode code = doExecute(arguments, services, severityCollector, rootDisposable); exitCode = groupingCollector.hasErrors() ? COMPILATION_ERROR : code;
exitCode = severityCollector.anyReported(CompilerMessageSeverity.ERROR) ? COMPILATION_ERROR : code;
} }
catch (CompilationCanceledException e) { catch (CompilationCanceledException e) {
messageCollector.report(CompilerMessageSeverity.INFO, "Compilation was canceled", CompilerMessageLocation.NO_LOCATION); messageCollector.report(CompilerMessageSeverity.INFO, "Compilation was canceled", CompilerMessageLocation.NO_LOCATION);
@@ -42,10 +42,7 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
import java.util.* import java.util.*
class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector) {
class AnalyzerWithCompilerReport(collector: MessageCollector) {
private val messageCollector: MessageSeverityCollector = MessageSeverityCollector(collector)
lateinit var analysisResult: AnalysisResult lateinit var analysisResult: AnalysisResult
private fun reportIncompleteHierarchies() { private fun reportIncompleteHierarchies() {
@@ -115,7 +112,7 @@ class AnalyzerWithCompilerReport(collector: MessageCollector) {
class SyntaxErrorReport(val isHasErrors: Boolean, val isAllErrorsAtEof: Boolean) class SyntaxErrorReport(val isHasErrors: Boolean, val isAllErrorsAtEof: Boolean)
fun hasErrors(): Boolean { fun hasErrors(): Boolean {
return messageCollector.anyReported(CompilerMessageSeverity.ERROR) return messageCollector.hasErrors()
} }
interface Analyzer { interface Analyzer {
@@ -21,12 +21,14 @@ import org.jetbrains.annotations.NotNull;
import java.io.PrintStream; import java.io.PrintStream;
public class PrintingMessageCollector implements MessageCollector { public class PrintingMessageCollector implements MessageCollector {
@SuppressWarnings("UseOfSystemOutOrSystemErr")
public static final MessageCollector PLAIN_TEXT_TO_SYSTEM_ERR = public static final MessageCollector PLAIN_TEXT_TO_SYSTEM_ERR =
new PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false); new PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false);
private final boolean verbose; private final boolean verbose;
private final PrintStream errStream; private final PrintStream errStream;
private final MessageRenderer messageRenderer; private final MessageRenderer messageRenderer;
private boolean hasErrors = false;
public PrintingMessageCollector(@NotNull PrintStream errStream, @NotNull MessageRenderer messageRenderer, boolean verbose) { public PrintingMessageCollector(@NotNull PrintStream errStream, @NotNull MessageRenderer messageRenderer, boolean verbose) {
this.verbose = verbose; this.verbose = verbose;
@@ -42,6 +44,13 @@ public class PrintingMessageCollector implements MessageCollector {
) { ) {
if (!verbose && CompilerMessageSeverity.VERBOSE.contains(severity)) return; if (!verbose && CompilerMessageSeverity.VERBOSE.contains(severity)) return;
hasErrors |= severity.isError();
errStream.println(messageRenderer.render(severity, message, location)); errStream.println(messageRenderer.render(severity, message, location));
} }
@Override
public boolean hasErrors() {
return hasErrors;
}
} }
@@ -35,7 +35,10 @@ import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys;
import org.jetbrains.kotlin.cli.common.ExitCode; import org.jetbrains.kotlin.cli.common.ExitCode;
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments; import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments;
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants; import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants;
import org.jetbrains.kotlin.cli.common.messages.*; import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport;
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation;
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity;
import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
import org.jetbrains.kotlin.cli.common.output.outputUtils.OutputUtilsKt; import org.jetbrains.kotlin.cli.common.output.outputUtils.OutputUtilsKt;
import org.jetbrains.kotlin.cli.jvm.compiler.CompilerJarLocator; import org.jetbrains.kotlin.cli.jvm.compiler.CompilerJarLocator;
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles; import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
@@ -74,27 +77,24 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
return new K2JSCompilerArguments(); return new K2JSCompilerArguments();
} }
@NotNull @NotNull
@Override @Override
protected ExitCode doExecute( protected ExitCode doExecute(
@NotNull K2JSCompilerArguments arguments, @NotNull K2JSCompilerArguments arguments,
@NotNull Services services, @NotNull Services services,
@NotNull MessageCollector messageCollector, @NotNull final MessageCollector messageCollector,
@NotNull Disposable rootDisposable @NotNull Disposable rootDisposable
) { ) {
final MessageSeverityCollector messageSeverityCollector = new MessageSeverityCollector(messageCollector);
if (arguments.freeArgs.isEmpty()) { if (arguments.freeArgs.isEmpty()) {
if (arguments.version) { if (arguments.version) {
return OK; return OK;
} }
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, "Specify at least one source file or directory", NO_LOCATION); messageCollector.report(CompilerMessageSeverity.ERROR, "Specify at least one source file or directory", NO_LOCATION);
return COMPILATION_ERROR; return COMPILATION_ERROR;
} }
CompilerConfiguration configuration = new CompilerConfiguration(); CompilerConfiguration configuration = new CompilerConfiguration();
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageSeverityCollector); configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector);
CompilerJarLocator locator = services.get(CompilerJarLocator.class); CompilerJarLocator locator = services.get(CompilerJarLocator.class);
if (locator != null) { if (locator != null) {
@@ -109,21 +109,21 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
List<KtFile> sourcesFiles = environmentForJS.getSourceFiles(); List<KtFile> sourcesFiles = environmentForJS.getSourceFiles();
if (arguments.outputFile == null) { if (arguments.outputFile == null) {
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, "Specify output file via -output", CompilerMessageLocation.NO_LOCATION); messageCollector.report(CompilerMessageSeverity.ERROR, "Specify output file via -output", CompilerMessageLocation.NO_LOCATION);
return ExitCode.COMPILATION_ERROR; return ExitCode.COMPILATION_ERROR;
} }
if (messageSeverityCollector.anyReported(CompilerMessageSeverity.ERROR)) { if (messageCollector.hasErrors()) {
return ExitCode.COMPILATION_ERROR; return ExitCode.COMPILATION_ERROR;
} }
if (sourcesFiles.isEmpty()) { if (sourcesFiles.isEmpty()) {
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, "No source files", CompilerMessageLocation.NO_LOCATION); messageCollector.report(CompilerMessageSeverity.ERROR, "No source files", CompilerMessageLocation.NO_LOCATION);
return COMPILATION_ERROR; return COMPILATION_ERROR;
} }
if (arguments.verbose) { if (arguments.verbose) {
reportCompiledSourcesList(messageSeverityCollector, sourcesFiles); reportCompiledSourcesList(messageCollector, sourcesFiles);
} }
File outputFile = new File(arguments.outputFile); File outputFile = new File(arguments.outputFile);
@@ -132,14 +132,14 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
if (config.checkLibFilesAndReportErrors(new Function1<String, Unit>() { if (config.checkLibFilesAndReportErrors(new Function1<String, Unit>() {
@Override @Override
public Unit invoke(String message) { public Unit invoke(String message) {
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION); messageCollector.report(CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION);
return Unit.INSTANCE; return Unit.INSTANCE;
} }
})) { })) {
return COMPILATION_ERROR; return COMPILATION_ERROR;
} }
AnalyzerWithCompilerReport analyzerWithCompilerReport = analyzeAndReportErrors(messageSeverityCollector, sourcesFiles, config); AnalyzerWithCompilerReport analyzerWithCompilerReport = analyzeAndReportErrors(messageCollector, sourcesFiles, config);
if (analyzerWithCompilerReport.hasErrors()) { if (analyzerWithCompilerReport.hasErrors()) {
return COMPILATION_ERROR; return COMPILATION_ERROR;
} }
@@ -154,7 +154,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
if (arguments.outputPrefix != null) { if (arguments.outputPrefix != null) {
outputPrefixFile = new File(arguments.outputPrefix); outputPrefixFile = new File(arguments.outputPrefix);
if (!outputPrefixFile.exists()) { if (!outputPrefixFile.exists()) {
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, messageCollector.report(CompilerMessageSeverity.ERROR,
"Output prefix file '" + arguments.outputPrefix + "' not found", "Output prefix file '" + arguments.outputPrefix + "' not found",
CompilerMessageLocation.NO_LOCATION); CompilerMessageLocation.NO_LOCATION);
return ExitCode.COMPILATION_ERROR; return ExitCode.COMPILATION_ERROR;
@@ -165,7 +165,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
if (arguments.outputPostfix != null) { if (arguments.outputPostfix != null) {
outputPostfixFile = new File(arguments.outputPostfix); outputPostfixFile = new File(arguments.outputPostfix);
if (!outputPostfixFile.exists()) { if (!outputPostfixFile.exists()) {
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, messageCollector.report(CompilerMessageSeverity.ERROR,
"Output postfix file '" + arguments.outputPostfix + "' not found", "Output postfix file '" + arguments.outputPostfix + "' not found",
CompilerMessageLocation.NO_LOCATION); CompilerMessageLocation.NO_LOCATION);
return ExitCode.COMPILATION_ERROR; return ExitCode.COMPILATION_ERROR;
@@ -185,7 +185,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
AnalyzerWithCompilerReport.Companion.reportDiagnostics(translationResult.getDiagnostics(), messageSeverityCollector); AnalyzerWithCompilerReport.Companion.reportDiagnostics(translationResult.getDiagnostics(), messageCollector);
if (!(translationResult instanceof TranslationResult.Success)) return ExitCode.COMPILATION_ERROR; if (!(translationResult instanceof TranslationResult.Success)) return ExitCode.COMPILATION_ERROR;
@@ -193,7 +193,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
OutputFileCollection outputFiles = successResult.getOutputFiles(outputFile, outputPrefixFile, outputPostfixFile); OutputFileCollection outputFiles = successResult.getOutputFiles(outputFile, outputPrefixFile, outputPostfixFile);
if (outputFile.isDirectory()) { if (outputFile.isDirectory()) {
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, messageCollector.report(CompilerMessageSeverity.ERROR,
"Cannot open output file '" + outputFile.getPath() + "': is a directory", "Cannot open output file '" + outputFile.getPath() + "': is a directory",
CompilerMessageLocation.NO_LOCATION); CompilerMessageLocation.NO_LOCATION);
return ExitCode.COMPILATION_ERROR; return ExitCode.COMPILATION_ERROR;
@@ -206,7 +206,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
OutputUtilsKt.writeAll(outputFiles, outputDir, messageSeverityCollector); OutputUtilsKt.writeAll(outputFiles, outputDir, messageCollector);
return OK; return OK;
} }
@@ -47,17 +47,16 @@ import java.util.concurrent.TimeUnit
class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() { class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
override fun doExecute(arguments: K2JVMCompilerArguments, services: Services, messageCollector: MessageCollector, rootDisposable: Disposable): ExitCode { override fun doExecute(arguments: K2JVMCompilerArguments, services: Services, messageCollector: MessageCollector, rootDisposable: Disposable): ExitCode {
val messageSeverityCollector = MessageSeverityCollector(messageCollector)
val paths = if (arguments.kotlinHome != null) val paths = if (arguments.kotlinHome != null)
KotlinPathsFromHomeDir(File(arguments.kotlinHome)) KotlinPathsFromHomeDir(File(arguments.kotlinHome))
else else
PathUtil.getKotlinPathsForCompiler() PathUtil.getKotlinPathsForCompiler()
messageSeverityCollector.report(CompilerMessageSeverity.LOGGING, "Using Kotlin home directory " + paths.homePath, CompilerMessageLocation.NO_LOCATION) messageCollector.report(CompilerMessageSeverity.LOGGING, "Using Kotlin home directory " + paths.homePath, CompilerMessageLocation.NO_LOCATION)
PerformanceCounter.setTimeCounterEnabled(arguments.reportPerf) PerformanceCounter.setTimeCounterEnabled(arguments.reportPerf)
val configuration = CompilerConfiguration() val configuration = CompilerConfiguration()
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageSeverityCollector) configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
if (IncrementalCompilation.isEnabled()) { if (IncrementalCompilation.isEnabled()) {
val incrementalCompilationComponents = services.get(IncrementalCompilationComponents::class.java) val incrementalCompilationComponents = services.get(IncrementalCompilationComponents::class.java)
@@ -73,32 +72,32 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
} }
} }
catch (t: Throwable) { catch (t: Throwable) {
MessageCollectorUtil.reportException(messageSeverityCollector, t) MessageCollectorUtil.reportException(messageCollector, t)
return INTERNAL_ERROR return INTERNAL_ERROR
} }
try { try {
PluginCliParser.loadPlugins(arguments, configuration) PluginCliParser.loadPlugins(arguments, configuration)
} }
catch (e: PluginCliOptionProcessingException) { catch (e: PluginCliOptionProcessingException) {
val message = e.message + "\n\n" + cliPluginUsageString(e.pluginId, e.options) val message = e.message + "\n\n" + cliPluginUsageString(e.pluginId, e.options)
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION) messageCollector.report(CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION)
return INTERNAL_ERROR return INTERNAL_ERROR
} }
catch (e: CliOptionProcessingException) { catch (e: CliOptionProcessingException) {
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, e.message!!, CompilerMessageLocation.NO_LOCATION) messageCollector.report(CompilerMessageSeverity.ERROR, e.message!!, CompilerMessageLocation.NO_LOCATION)
return INTERNAL_ERROR return INTERNAL_ERROR
} }
catch (t: Throwable) { catch (t: Throwable) {
MessageCollectorUtil.reportException(messageSeverityCollector, t) MessageCollectorUtil.reportException(messageCollector, t)
return INTERNAL_ERROR return INTERNAL_ERROR
} }
if (arguments.script) { if (arguments.script) {
if (arguments.freeArgs.isEmpty()) { if (arguments.freeArgs.isEmpty()) {
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, "Specify script source path to evaluate", CompilerMessageLocation.NO_LOCATION) messageCollector.report(
CompilerMessageSeverity.ERROR, "Specify script source path to evaluate", CompilerMessageLocation.NO_LOCATION
)
return COMPILATION_ERROR return COMPILATION_ERROR
} }
configuration.addKotlinSourceRoot(arguments.freeArgs.get(0)) configuration.addKotlinSourceRoot(arguments.freeArgs.get(0))
@@ -138,16 +137,16 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
putAdvancedOptions(configuration, arguments) putAdvancedOptions(configuration, arguments)
messageSeverityCollector.report(CompilerMessageSeverity.LOGGING, "Configuring the compilation environment", CompilerMessageLocation.NO_LOCATION) messageCollector.report(CompilerMessageSeverity.LOGGING, "Configuring the compilation environment", CompilerMessageLocation.NO_LOCATION)
try { try {
val destination = arguments.destination val destination = arguments.destination
if (arguments.module != null) { if (arguments.module != null) {
val sanitizedCollector = FilteringMessageCollector(messageSeverityCollector, `in`(CompilerMessageSeverity.VERBOSE)) val sanitizedCollector = FilteringMessageCollector(messageCollector, `in`(CompilerMessageSeverity.VERBOSE))
val moduleScript = CompileEnvironmentUtil.loadModuleDescriptions(arguments.module, sanitizedCollector) val moduleScript = CompileEnvironmentUtil.loadModuleDescriptions(arguments.module, sanitizedCollector)
if (destination != null) { if (destination != null) {
messageSeverityCollector.report( messageCollector.report(
CompilerMessageSeverity.WARNING, CompilerMessageSeverity.WARNING,
"The '-d' option with a directory destination is ignored because '-module' is specified", "The '-d' option with a directory destination is ignored because '-module' is specified",
CompilerMessageLocation.NO_LOCATION CompilerMessageLocation.NO_LOCATION
@@ -161,14 +160,14 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
configuration.put(JVMConfigurationKeys.MODULE_XML_FILE, moduleFile) configuration.put(JVMConfigurationKeys.MODULE_XML_FILE, moduleFile)
val environment = createCoreEnvironment(rootDisposable, configuration) val environment = createCoreEnvironment(rootDisposable, configuration)
if (messageSeverityCollector.anyReported(CompilerMessageSeverity.ERROR)) return COMPILATION_ERROR if (messageCollector.hasErrors()) return COMPILATION_ERROR
KotlinToJVMBytecodeCompiler.compileModules(environment, directory) KotlinToJVMBytecodeCompiler.compileModules(environment, directory)
} }
else if (arguments.script) { else if (arguments.script) {
val scriptArgs = arguments.freeArgs.subList(1, arguments.freeArgs.size) val scriptArgs = arguments.freeArgs.subList(1, arguments.freeArgs.size)
val environment = createCoreEnvironment(rootDisposable, configuration) val environment = createCoreEnvironment(rootDisposable, configuration)
if (messageSeverityCollector.anyReported(CompilerMessageSeverity.ERROR)) return COMPILATION_ERROR if (messageCollector.hasErrors()) return COMPILATION_ERROR
return KotlinToJVMBytecodeCompiler.compileAndExecuteScript(environment, paths, scriptArgs) return KotlinToJVMBytecodeCompiler.compileAndExecuteScript(environment, paths, scriptArgs)
} }
@@ -183,13 +182,13 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
} }
val environment = createCoreEnvironment(rootDisposable, configuration) val environment = createCoreEnvironment(rootDisposable, configuration)
if (messageSeverityCollector.anyReported(CompilerMessageSeverity.ERROR)) return COMPILATION_ERROR if (messageCollector.hasErrors()) return COMPILATION_ERROR
if (environment.getSourceFiles().isEmpty()) { if (environment.getSourceFiles().isEmpty()) {
if (arguments.version) { if (arguments.version) {
return OK return OK
} }
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, "No source files", CompilerMessageLocation.NO_LOCATION) messageCollector.report(CompilerMessageSeverity.ERROR, "No source files", CompilerMessageLocation.NO_LOCATION)
return COMPILATION_ERROR return COMPILATION_ERROR
} }
@@ -204,7 +203,11 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
return OK return OK
} }
catch (e: CompilationException) { catch (e: CompilationException) {
messageSeverityCollector.report(CompilerMessageSeverity.EXCEPTION, OutputMessageUtil.renderException(e), MessageUtil.psiElementToMessageLocation(e.element)) messageCollector.report(
CompilerMessageSeverity.EXCEPTION,
OutputMessageUtil.renderException(e),
MessageUtil.psiElementToMessageLocation(e.element)
)
return INTERNAL_ERROR return INTERNAL_ERROR
} }
} }
@@ -33,7 +33,7 @@ import java.io.IOException;
public abstract class AbstractModuleXmlParserTest extends TestCase { public abstract class AbstractModuleXmlParserTest extends TestCase {
protected void doTest(String xmlPath) throws IOException { protected static void doTest(String xmlPath) throws IOException {
File txtFile = new File(FileUtil.getNameWithoutExtension(xmlPath) + ".txt"); File txtFile = new File(FileUtil.getNameWithoutExtension(xmlPath) + ".txt");
ModuleScriptData result = ModuleXmlParser.parseModuleScript(xmlPath, new MessageCollector() { ModuleScriptData result = ModuleXmlParser.parseModuleScript(xmlPath, new MessageCollector() {
@@ -43,6 +43,11 @@ public abstract class AbstractModuleXmlParserTest extends TestCase {
) { ) {
throw new AssertionError(MessageRenderer.PLAIN_FULL_PATHS.render(severity, message, location)); throw new AssertionError(MessageRenderer.PLAIN_FULL_PATHS.render(severity, message, location));
} }
@Override
public boolean hasErrors() {
throw new UnsupportedOperationException();
}
}); });
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@@ -689,8 +689,10 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
} }
class MessageCollectorAdapter(private val context: CompileContext) : MessageCollector { class MessageCollectorAdapter(private val context: CompileContext) : MessageCollector {
private var hasErrors = false
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) { override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) {
hasErrors = hasErrors or severity.isError
var prefix = "" var prefix = ""
if (severity == EXCEPTION) { if (severity == EXCEPTION) {
prefix = INTERNAL_ERROR_PREFIX prefix = INTERNAL_ERROR_PREFIX
@@ -705,6 +707,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
)) ))
} }
override fun hasErrors(): Boolean = hasErrors
private fun renderLocationIfNeeded(location: CompilerMessageLocation): String { private fun renderLocationIfNeeded(location: CompilerMessageLocation): String {
if (location == CompilerMessageLocation.NO_LOCATION) return "" if (location == CompilerMessageLocation.NO_LOCATION) return ""
@@ -687,11 +687,18 @@ private fun <T: Any> ExtraPropertiesExtension.getOrNull(id: String): T? {
} }
class GradleMessageCollector(val logger: Logger, val outputCollector: OutputItemsCollector? = null) : MessageCollector { class GradleMessageCollector(val logger: Logger, val outputCollector: OutputItemsCollector? = null) : MessageCollector {
private var hasErrors = false
override fun hasErrors() = hasErrors
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) { override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) {
val text = with(StringBuilder()) { val text = with(StringBuilder()) {
append(when (severity) { append(when (severity) {
in CompilerMessageSeverity.VERBOSE -> "v" in CompilerMessageSeverity.VERBOSE -> "v"
in CompilerMessageSeverity.ERRORS -> "e" in CompilerMessageSeverity.ERRORS -> {
hasErrors = true
"e"
}
CompilerMessageSeverity.INFO -> "i" CompilerMessageSeverity.INFO -> "i"
CompilerMessageSeverity.WARNING -> "w" CompilerMessageSeverity.WARNING -> "w"
else -> throw IllegalArgumentException("Unknown CompilerMessageSeverity: $severity") else -> throw IllegalArgumentException("Unknown CompilerMessageSeverity: $severity")
@@ -35,7 +35,6 @@ import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.repository.ComponentDependency; import org.codehaus.plexus.component.repository.ComponentDependency;
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys; import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys;
import org.jetbrains.kotlin.cli.common.messages.MessageSeverityCollector;
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler; import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler;
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles; import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment; import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
@@ -158,7 +157,7 @@ public class ExecuteKotlinScriptMojo extends AbstractMojo {
CompilerConfiguration configuration = new CompilerConfiguration(); CompilerConfiguration configuration = new CompilerConfiguration();
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, new MessageSeverityCollector(messageCollector)); configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector);
List<File> deps = new ArrayList<File>(); List<File> deps = new ArrayList<File>();
@@ -24,11 +24,17 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
public class MavenPluginLogMessageCollector implements MessageCollector { public class MavenPluginLogMessageCollector implements MessageCollector {
private final Log log; private final Log log;
private boolean hasErrors = false;
public MavenPluginLogMessageCollector(Log log) { public MavenPluginLogMessageCollector(Log log) {
this.log = log; this.log = log;
} }
@Override
public boolean hasErrors() {
return hasErrors;
}
@Override @Override
public void report(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location) { public void report(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location) {
String path = location.getPath(); String path = location.getPath();
@@ -39,6 +45,7 @@ public class MavenPluginLogMessageCollector implements MessageCollector {
if (CompilerMessageSeverity.VERBOSE.contains(severity)) { if (CompilerMessageSeverity.VERBOSE.contains(severity)) {
log.debug(text); log.debug(text);
} else if (CompilerMessageSeverity.ERRORS.contains(severity)) { } else if (CompilerMessageSeverity.ERRORS.contains(severity)) {
hasErrors = true;
log.error(text); log.error(text);
} else if (severity == CompilerMessageSeverity.INFO) { } else if (severity == CompilerMessageSeverity.INFO) {
log.info(text); log.info(text);