Skip to content

Commit d06592b

Browse files
nshahancommit-bot@chromium.org
authored andcommitted
[dartdevc] Add details to failed assertion messages
* Source file location * Assertion source code This change embeds the information as strings into the compiled source. In the future we could reconstruct the source file location at runtime from the stack trace. In tests with various large applications this added roughly 1MB (0.1MB compressed) or less to the compiled file size. Fixes: flutter#36995 Change-Id: I2634f7eab6e54eec209094b52429987dd62c0828 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103568 Reviewed-by: Vijay Menon <vsm@google.com> Commit-Queue: Nicholas Shahan <nshahan@google.com>
1 parent cca2bb3 commit d06592b

4 files changed

Lines changed: 57 additions & 10 deletions

File tree

pkg/dev_compiler/lib/src/analyzer/code_generator.dart

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4150,10 +4150,20 @@ class CodeGenerator extends Object
41504150
} else if (isNullable(condition)) {
41514151
jsCondition = runtimeCall('test(#)', [jsCondition]);
41524152
}
4153-
return js.statement(' if (!#) #.assertFailed(#);', [
4153+
4154+
var location = _getLocation(condition.offset);
4155+
return js.statement(' if (!#) #.assertFailed(#, #, #, #, #);', [
41544156
jsCondition,
41554157
runtimeModule,
4156-
message != null ? [_visitExpression(message)] : []
4158+
if (message == null)
4159+
JS.LiteralNull()
4160+
else
4161+
_visitExpression(message),
4162+
js.escapedString(location.sourceUrl.toString()),
4163+
// Lines and columns are typically printed with 1 based indexing.
4164+
js.number(location.line + 1),
4165+
js.number(location.column + 1),
4166+
js.escapedString(condition.toSource()),
41574167
]);
41584168
}
41594169

pkg/dev_compiler/lib/src/kernel/compiler.dart

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'dart:collection';
6+
import 'dart:convert';
67
import 'dart:math' show max, min;
78

89
import 'package:front_end/src/api_unstable/ddc.dart' show TypeSchemaEnvironment;
@@ -3185,10 +3186,24 @@ class ProgramCompiler extends Object
31853186
} else if (isNullable(condition)) {
31863187
jsCondition = runtimeCall('test(#)', [jsCondition]);
31873188
}
3188-
return js.statement(' if (!#) #.assertFailed(#);', [
3189+
3190+
var encodedConditionSource = node
3191+
.enclosingComponent.uriToSource[node.location.file].source
3192+
.sublist(node.conditionStartOffset, node.conditionEndOffset);
3193+
var conditionSource = utf8.decode(encodedConditionSource);
3194+
var location = _getLocation(node.conditionStartOffset);
3195+
return js.statement(' if (!#) #.assertFailed(#, #, #, #, #);', [
31893196
jsCondition,
31903197
runtimeModule,
3191-
node.message != null ? [_visitExpression(node.message)] : []
3198+
if (node.message == null)
3199+
JS.LiteralNull()
3200+
else
3201+
_visitExpression(node.message),
3202+
js.escapedString(location.sourceUrl.toString()),
3203+
// Lines and columns are typically printed with 1 based indexing.
3204+
js.number(location.line + 1),
3205+
js.number(location.column + 1),
3206+
js.escapedString(conditionSource),
31923207
]);
31933208
}
31943209

pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/errors.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,13 @@ throwUnimplementedError(String message) {
3333
throw UnimplementedError(message);
3434
}
3535

36-
assertFailed(message) {
36+
// TODO(nshahan) Cleanup embeded strings and extract file location at runtime
37+
// from the stacktrace.
38+
assertFailed(String message,
39+
[String fileUri, int line, int column, String conditionSource]) {
3740
if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
38-
throw AssertionErrorImpl(message);
41+
42+
throw AssertionErrorImpl(message, fileUri, line, column, conditionSource);
3943
}
4044

4145
throwCyclicInitializationError([Object field]) {

pkg/dev_compiler/tool/input_sdk/private/js_helper.dart

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -738,10 +738,28 @@ class RuntimeError extends Error {
738738

739739
/// Error thrown by DDC when an `assert()` fails (with or without a message).
740740
class AssertionErrorImpl extends AssertionError {
741-
AssertionErrorImpl(message) : super(message);
742-
String toString() =>
743-
"Assertion failed: " +
744-
(message != null ? Error.safeToString(message) : "is not true");
741+
final String _fileUri;
742+
final int _line;
743+
final int _column;
744+
final String _conditionSource;
745+
746+
AssertionErrorImpl(Object message,
747+
[this._fileUri, this._line, this._column, this._conditionSource])
748+
: super(message);
749+
750+
String toString() {
751+
var failureMessage = "";
752+
if (_fileUri != null &&
753+
_line != null &&
754+
_column != null &&
755+
_conditionSource != null) {
756+
failureMessage += "$_fileUri:${_line}:${_column}\n$_conditionSource\n";
757+
}
758+
failureMessage +=
759+
message != null ? Error.safeToString(message) : "is not true";
760+
761+
return "Assertion failed: $failureMessage";
762+
}
745763
}
746764

747765
/**

0 commit comments

Comments
 (0)