Debug abort without deprecation
Change-Id: Ia55f7c2ff302d5e58aaed110e5eb88cdffc7d1a9
Reviewed-on: https://dart-review.googlesource.com/63120
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index 22fc6b6..fcd9d47 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -33,8 +33,6 @@
import '../fasta/command_line_reporting.dart' as command_line_reporting;
-import '../fasta/deprecated_problems.dart' show deprecated_InputError;
-
import '../fasta/fasta_codes.dart'
show
FormattedMessage,
@@ -55,9 +53,9 @@
import '../fasta/messages.dart' show getLocation;
-import '../fasta/problems.dart' show unimplemented;
+import '../fasta/problems.dart' show DebugAbort, unimplemented;
-import '../fasta/severity.dart' show Severity, severityTexts;
+import '../fasta/severity.dart' show Severity;
import '../fasta/ticker.dart' show Ticker;
@@ -219,9 +217,8 @@
}
_raw.onProblem(format(message, severity), severity, formattedContext);
if (command_line_reporting.shouldThrowOn(severity)) {
- if (verbose) print(StackTrace.current);
- throw new deprecated_InputError(message.uri, message.charOffset,
- "Compilation aborted due to fatal ${severityTexts[severity]}.");
+ throw new DebugAbort(
+ message.uri, message.charOffset, severity, StackTrace.current);
}
return;
}
diff --git a/pkg/front_end/lib/src/fasta/command_line_reporting.dart b/pkg/front_end/lib/src/fasta/command_line_reporting.dart
index 28414b3..e54dad5 100644
--- a/pkg/front_end/lib/src/fasta/command_line_reporting.dart
+++ b/pkg/front_end/lib/src/fasta/command_line_reporting.dart
@@ -22,15 +22,13 @@
import 'crash.dart' show Crash, safeToString;
-import 'deprecated_problems.dart' show deprecated_InputError;
-
import 'fasta_codes.dart' show LocatedMessage;
-import 'messages.dart' show getLocation, getSourceLine, isVerbose;
+import 'messages.dart' show getLocation, getSourceLine;
-import 'problems.dart' show unhandled;
+import 'problems.dart' show DebugAbort, unhandled;
-import 'severity.dart' show Severity, severityPrefixes, severityTexts;
+import 'severity.dart' show Severity, severityPrefixes;
import 'scanner/characters.dart' show $CARET, $SPACE, $TAB;
@@ -179,11 +177,7 @@
}
print(text);
if (shouldThrowOn(severity)) {
- if (isVerbose) print(StackTrace.current);
- // TODO(sigmund,ahe): ensure there is no circularity when InputError is
- // handled.
- throw new deprecated_InputError(uri, charOffset,
- "Compilation aborted due to fatal ${severityTexts[severity]}.");
+ throw new DebugAbort(uri, charOffset, severity, StackTrace.current);
}
}
diff --git a/pkg/front_end/lib/src/fasta/compiler_context.dart b/pkg/front_end/lib/src/fasta/compiler_context.dart
index e979f14..eca094e 100644
--- a/pkg/front_end/lib/src/fasta/compiler_context.dart
+++ b/pkg/front_end/lib/src/fasta/compiler_context.dart
@@ -111,6 +111,8 @@
return context;
}
+ static bool get isActive => Zone.current[compilerContextKey] != null;
+
/// Perform [action] in a [Zone] where [this] will be available as
/// `CompilerContext.current`.
Future<T> runInContext<T>(Future<T> action(CompilerContext c)) {
diff --git a/pkg/front_end/lib/src/fasta/deprecated_problems.dart b/pkg/front_end/lib/src/fasta/deprecated_problems.dart
index 8e52ae6..004b591 100644
--- a/pkg/front_end/lib/src/fasta/deprecated_problems.dart
+++ b/pkg/front_end/lib/src/fasta/deprecated_problems.dart
@@ -11,9 +11,14 @@
import 'crash.dart' show safeToString;
import 'messages.dart'
- show LocatedMessage, noLength, isVerbose, templateUnspecified;
+ show
+ LocatedMessage,
+ isVerbose,
+ noLength,
+ templateInternalProblemDebugAbort,
+ templateUnspecified;
-import 'severity.dart' show Severity;
+import 'severity.dart' show Severity, severityTexts;
import 'crash.dart' show Crash, reportCrash, resetCrashReporting;
@@ -50,10 +55,29 @@
///
/// Static method to discourage use and requiring call-sites to include the
/// text `deprecated_`.
- static LocatedMessage toMessage(deprecated_InputError error) {
- return templateUnspecified
- .withArguments(safeToString(error.error))
- .withLocation(error.uri, error.charOffset, noLength);
+ static LocatedMessage deprecated_toMessage(deprecated_InputError error) {
+ if (error is DebugAbort) {
+ return error.toMessage();
+ } else {
+ return templateUnspecified
+ .withArguments(safeToString(error.error))
+ .withLocation(error.uri, error.charOffset, noLength);
+ }
+ }
+}
+
+class DebugAbort extends deprecated_InputError {
+ final StackTrace trace;
+
+ final Severity severity;
+
+ DebugAbort(Uri uri, int charOffset, this.severity, this.trace)
+ : super(uri, charOffset, "");
+
+ LocatedMessage toMessage() {
+ return templateInternalProblemDebugAbort
+ .withArguments(severityTexts[severity], "$trace")
+ .withLocation(uri, charOffset, noLength);
}
}
@@ -67,9 +91,11 @@
return await action();
} on Crash {
rethrow;
+ } on DebugAbort {
+ rethrow;
} on deprecated_InputError catch (e, s) {
if (onInputError != null) {
- return onInputError(deprecated_InputError.toMessage(e));
+ return onInputError(deprecated_InputError.deprecated_toMessage(e));
} else {
return reportCrash(e, s, currentUri());
}
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 12d35f9..e8c41e4 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -3316,6 +3316,27 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name, String string)>
+ templateInternalProblemDebugAbort =
+ const Template<Message Function(String name, String string)>(
+ messageTemplate: r"""Compilation aborted due to fatal '#name' at:
+#string""", withArguments: _withArgumentsInternalProblemDebugAbort);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, String string)>
+ codeInternalProblemDebugAbort =
+ const Code<Message Function(String name, String string)>(
+ "InternalProblemDebugAbort", templateInternalProblemDebugAbort,
+ severity: Severity.internalProblem);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsInternalProblemDebugAbort(String name, String string) {
+ return new Message(codeInternalProblemDebugAbort,
+ message: """Compilation aborted due to fatal '${name}' at:
+${string}""", arguments: {'name': name, 'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeInternalProblemExtendingUnmodifiableScope =
messageInternalProblemExtendingUnmodifiableScope;
diff --git a/pkg/front_end/lib/src/fasta/problems.dart b/pkg/front_end/lib/src/fasta/problems.dart
index d16e520..d0c8cc8 100644
--- a/pkg/front_end/lib/src/fasta/problems.dart
+++ b/pkg/front_end/lib/src/fasta/problems.dart
@@ -17,6 +17,8 @@
import 'severity.dart' show Severity;
+export 'deprecated_problems.dart' show DebugAbort;
+
/// Used to report an internal error.
///
/// Internal errors should be avoided as best as possible, but are preferred
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index 12d3cb3..a180656 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -39,7 +39,7 @@
import '../parser.dart' show Assert, MemberKind, Parser, optional;
-import '../problems.dart' show internalProblem, unexpected;
+import '../problems.dart' show DebugAbort, internalProblem, unexpected;
import '../type_inference/type_inference_engine.dart' show TypeInferenceEngine;
@@ -752,6 +752,8 @@
listener.checkEmpty(token.charOffset);
listenerFinishFunction(listener, startToken, metadata, kind,
metadataConstants, formals, asyncModifier, body);
+ } on DebugAbort {
+ rethrow;
} on deprecated_InputError {
rethrow;
} catch (e, s) {
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index a6b4507..b5ce197 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1394,6 +1394,10 @@
#string
severity: INTERNAL_PROBLEM
+InternalProblemDebugAbort:
+ template: "Compilation aborted due to fatal '#name' at:\n#string"
+ severity: INTERNAL_PROBLEM
+
LocalDefinitionHidesExport:
template: "Local definition of '#name' hides export from '#uri'."
severity: IGNORED
diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart
index 258e081..99ee0b3 100644
--- a/pkg/front_end/tool/_fasta/command_line.dart
+++ b/pkg/front_end/tool/_fasta/command_line.dart
@@ -4,7 +4,9 @@
library fasta.tool.command_line;
-import 'dart:io' show exit;
+import 'dart:async' show Future;
+
+import 'dart:io' show exit, exitCode;
import 'package:build_integration/file_system/single_root.dart'
show SingleRootFileSystem;
@@ -25,6 +27,9 @@
import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
+import 'package:front_end/src/fasta/deprecated_problems.dart'
+ show deprecated_InputError;
+
import 'package:front_end/src/fasta/fasta_codes.dart'
show
Message,
@@ -33,7 +38,7 @@
messageFastaUsageShort,
templateUnspecified;
-import 'package:front_end/src/fasta/problems.dart' show unhandled;
+import 'package:front_end/src/fasta/problems.dart' show DebugAbort, unhandled;
import 'package:front_end/src/fasta/severity.dart' show Severity;
@@ -458,3 +463,26 @@
// TODO(ahe): Don't use [templateUnspecified].
return templateUnspecified.withArguments("$sb");
}
+
+Future<T> runProtectedFromAbort<T>(Future<T> Function() action,
+ [T failingValue]) async {
+ if (CompilerContext.isActive) {
+ throw "runProtectedFromAbort should be called from 'main',"
+ " that is, outside a compiler context.";
+ }
+ try {
+ return await action();
+ } on DebugAbort catch (e) {
+ print(e.toMessage().message);
+
+ // DebugAbort should never happen in production code, so we want test.py to
+ // treat this as a crash which is signalled by exiting with 255.
+ exit(255);
+ } on deprecated_InputError catch (e) {
+ exitCode = 1;
+ await CompilerContext.runWithDefaultOptions((c) => new Future<void>.sync(
+ () => c.report(
+ deprecated_InputError.deprecated_toMessage(e), Severity.error)));
+ }
+ return failingValue;
+}
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index a79de85..7635437 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -27,7 +27,7 @@
import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
import 'package:front_end/src/fasta/deprecated_problems.dart'
- show deprecated_InputError, deprecated_inputError;
+ show deprecated_inputError;
import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget;
@@ -42,8 +42,6 @@
import 'package:front_end/src/fasta/kernel/utils.dart'
show printComponentText, writeComponentToFile;
-import 'package:front_end/src/fasta/severity.dart' show Severity;
-
import 'package:front_end/src/fasta/ticker.dart' show Ticker;
import 'package:front_end/src/fasta/uri_translator.dart' show UriTranslator;
@@ -55,7 +53,7 @@
import 'additional_targets.dart' show installAdditionalTargets;
-import 'command_line.dart' show withGlobalOptions;
+import 'command_line.dart' show runProtectedFromAbort, withGlobalOptions;
const bool summary = const bool.fromEnvironment("summary", defaultValue: false);
@@ -101,14 +99,7 @@
if (i > 0) {
print("\n");
}
- try {
- await compilePlatform(arguments);
- } on deprecated_InputError catch (e) {
- exitCode = 1;
- await CompilerContext.runWithDefaultOptions((c) => new Future<void>.sync(
- () => c.report(deprecated_InputError.toMessage(e), Severity.error)));
- return null;
- }
+ await runProtectedFromAbort<void>(() => compilePlatform(arguments));
}
}
@@ -149,14 +140,10 @@
}
Future<bool> batchCompileArguments(List<String> arguments) async {
- try {
- return await withGlobalOptions("compile", arguments, true,
- (CompilerContext c, _) => batchCompileImpl(c));
- } on deprecated_InputError catch (e) {
- await CompilerContext.runWithDefaultOptions((c) => new Future<void>.sync(
- () => c.report(deprecated_InputError.toMessage(e), Severity.error)));
- return false;
- }
+ return runProtectedFromAbort<bool>(
+ () => withGlobalOptions("compile", arguments, true,
+ (CompilerContext c, _) => batchCompileImpl(c)),
+ false);
}
Future<bool> batchCompile(CompilerOptions options, Uri input, Uri output) {
@@ -203,7 +190,7 @@
}
Future<KernelTarget> outline(List<String> arguments) async {
- try {
+ return await runProtectedFromAbort<KernelTarget>(() async {
return await withGlobalOptions("outline", arguments, true,
(CompilerContext c, _) async {
if (c.options.verbose) {
@@ -213,16 +200,11 @@
new CompileTask(c, new Ticker(isVerbose: c.options.verbose));
return await task.buildOutline(c.options.output);
});
- } on deprecated_InputError catch (e) {
- exitCode = 1;
- await CompilerContext.runWithDefaultOptions((c) => new Future<void>.sync(
- () => c.report(deprecated_InputError.toMessage(e), Severity.error)));
- return null;
- }
+ });
}
Future<Uri> compile(List<String> arguments) async {
- try {
+ return await runProtectedFromAbort<Uri>(() async {
return await withGlobalOptions("compile", arguments, true,
(CompilerContext c, _) async {
if (c.options.verbose) {
@@ -232,12 +214,7 @@
new CompileTask(c, new Ticker(isVerbose: c.options.verbose));
return await task.compile();
});
- } on deprecated_InputError catch (e) {
- exitCode = 1;
- await CompilerContext.runWithDefaultOptions((c) => new Future<void>.sync(
- () => c.report(deprecated_InputError.toMessage(e), Severity.error)));
- return null;
- }
+ });
}
class CompileTask {