Index: pkg/front_end/lib/src/fasta/command_line_reporting.dart |
diff --git a/pkg/front_end/lib/src/fasta/command_line_reporting.dart b/pkg/front_end/lib/src/fasta/command_line_reporting.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..37cd08d555b36e6645bca5e9a9a19ccc73ffbd49 |
--- /dev/null |
+++ b/pkg/front_end/lib/src/fasta/command_line_reporting.dart |
@@ -0,0 +1,188 @@ |
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+/// Provides a default implementation of the report and format methods of |
+/// [CompilerContext] that are suitable for command-line tools. The methods in |
+/// this library aren't intended to be called directly, instead, one should use |
+/// [CompilerContext]. |
+library fasta.command_line_reporting; |
+ |
+import 'dart:io' show exitCode; |
+ |
+import 'package:kernel/ast.dart' show Location; |
+ |
+import 'colors.dart' show cyan, magenta, red; |
+ |
+import 'compiler_context.dart' show CompilerContext; |
+ |
+import 'deprecated_problems.dart' show deprecated_InputError; |
+ |
+import 'fasta_codes.dart' show LocatedMessage, Message; |
+ |
+import 'messages.dart' show getLocation, getSourceLine, isVerbose; |
+ |
+import 'problems.dart' show unhandled; |
+ |
+import 'severity.dart' show Severity; |
+ |
+import 'util/relativize.dart' show relativizeUri; |
+ |
+const bool hideWarnings = false; |
+ |
+/// Formats [message] as a string that is suitable for output from a |
+/// command-line tool. This includes source snippets and different colors based |
+/// on [severity]. |
+/// |
+/// It is a assumed that a formatted message is reported to a user, so |
+/// [exitCode] is also set depending on the value of |
+/// `CompilerContext.current.options.setExitCodeOnProblem`. |
+/// |
+/// This is shared implementation used by methods below, and isn't intended to |
+/// be called directly. |
+String formatInternal(Message message, Severity severity, Uri uri, int offset) { |
+ if (CompilerContext.current.options.setExitCodeOnProblem) { |
+ exitCode = 1; |
+ } |
+ String text = |
+ "${severityName(severity, capitalized: true)}: ${message.message}"; |
+ if (message.tip != null) { |
+ text += "\n${message.tip}"; |
+ } |
+ if (CompilerContext.enableColors) { |
+ switch (severity) { |
+ case Severity.error: |
+ case Severity.internalProblem: |
+ text = red(text); |
+ break; |
+ |
+ case Severity.nit: |
+ text = cyan(text); |
+ break; |
+ |
+ case Severity.warning: |
+ text = magenta(text); |
+ break; |
+ } |
+ } |
+ |
+ if (uri != null) { |
+ String path = relativizeUri(uri); |
+ Location location = offset == -1 ? null : getLocation(path, offset); |
+ String sourceLine = getSourceLine(location); |
+ if (sourceLine == null) { |
+ sourceLine = ""; |
+ } else { |
+ // TODO(ahe): We only print a single point in the source line as we don't |
+ // have end positions. Also, we should be able to use package:source_span |
+ // to produce this. |
+ sourceLine = "\n$sourceLine\n" |
+ "${' ' * (location.column - 1)}^"; |
+ } |
+ String position = location?.toString() ?? path; |
+ return "$position: $text$sourceLine"; |
+ } else { |
+ return text; |
+ } |
+} |
+ |
+/// Are problems of [severity] suppressed? |
+bool isHidden(Severity severity) { |
+ switch (severity) { |
+ case Severity.error: |
+ case Severity.internalProblem: |
+ return false; |
+ |
+ case Severity.nit: |
+ return !isVerbose; |
+ |
+ case Severity.warning: |
+ return hideWarnings; |
+ } |
+ return unhandled("$severity", "isHidden", -1, null); |
+} |
+ |
+/// Are problems of [severity] fatal? That is, should the compiler terminate |
+/// immediately? |
+bool isFatal(Severity severity) { |
+ switch (severity) { |
+ case Severity.error: |
+ return CompilerContext.current.options.errorsAreFatal; |
+ |
+ case Severity.internalProblem: |
+ return true; |
+ |
+ case Severity.nit: |
+ return CompilerContext.current.options.nitsAreFatal; |
+ |
+ case Severity.warning: |
+ return CompilerContext.current.options.warningsAreFatal; |
+ } |
+ return unhandled("$severity", "isFatal", -1, null); |
+} |
+ |
+/// Convert [severity] to a name that can be used to prefix a message. |
+String severityName(Severity severity, {bool capitalized: false}) { |
+ switch (severity) { |
+ case Severity.error: |
+ return capitalized ? "Error" : "error"; |
+ |
+ case Severity.internalProblem: |
+ return capitalized ? "Internal problem" : "internal problem"; |
+ |
+ case Severity.nit: |
+ return capitalized ? "Nit" : "nit"; |
+ |
+ case Severity.warning: |
+ return capitalized ? "Warning" : "warning"; |
+ } |
+ return unhandled("$severity", "severityName", -1, null); |
+} |
+ |
+void _printAndThrowIfFatal( |
+ String text, Severity severity, Uri uri, int charOffset) { |
+ print(text); |
+ if (isFatal(severity)) { |
+ if (isVerbose) print(StackTrace.current); |
+ throw new deprecated_InputError(uri, charOffset, |
+ "Compilation aborted due to fatal ${severityName(severity)}."); |
+ } |
+} |
+ |
+/// Report [message] unless [severity] is suppressed (see [isHidden]). Throws |
+/// an exception if [severity] is fatal (see [isFatal]). |
+/// |
+/// This method isn't intended to be called directly. Use |
+/// [CompilerContext.report] instead. |
+void report(LocatedMessage message, Severity severity) { |
+ if (isHidden(severity)) return; |
+ _printAndThrowIfFatal( |
+ format(message, severity), severity, message.uri, message.charOffset); |
+} |
+ |
+/// Similar to [report]. |
+/// |
+/// This method isn't intended to be called directly. Use |
+/// [CompilerContext.reportWithoutLocation] instead. |
+void reportWithoutLocation(Message message, Severity severity) { |
+ if (isHidden(severity)) return; |
+ _printAndThrowIfFatal( |
+ formatWithoutLocation(message, severity), severity, null, -1); |
+} |
+ |
+/// Formats [message] as described in [formatInternal]. |
+/// |
+/// This method isn't intended to be called directly. Use |
+/// [CompilerContext.format] instead. |
+String format(LocatedMessage message, Severity severity) { |
+ return formatInternal( |
+ message.messageObject, severity, message.uri, message.charOffset); |
+} |
+ |
+/// Formats [message] as described in [formatInternal]. |
+/// |
+/// This method isn't intended to be called directly. Use |
+/// [CompilerContext.formatWithoutLocation] instead. |
+String formatWithoutLocation(Message message, Severity severity) { |
+ return formatInternal(message, severity, null, -1); |
+} |