Version 2.12.0-241.0.dev
Merge commit '04e8aa58ee81bed52a63d4bbb10791a9eb018d7e' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index 31b5e0f..f5498a2 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -9555,26 +9555,6 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name)>
- templateUseOfDeprecatedIdentifier =
- const Template<Message Function(String name)>(
- messageTemplate: r"""'#name' is deprecated.""",
- withArguments: _withArgumentsUseOfDeprecatedIdentifier);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)> codeUseOfDeprecatedIdentifier =
- const Code<Message Function(String name)>("UseOfDeprecatedIdentifier",
- severity: Severity.ignored);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsUseOfDeprecatedIdentifier(String name) {
- if (name.isEmpty) throw 'No name provided';
- name = demangleMixinApplicationName(name);
- return new Message(codeUseOfDeprecatedIdentifier,
- message: """'${name}' is deprecated.""", arguments: {'name': name});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name)>
templateValueForRequiredParameterNotProvidedError =
const Template<Message Function(String name)>(
messageTemplate:
diff --git a/pkg/front_end/lib/src/fasta/identifiers.dart b/pkg/front_end/lib/src/fasta/identifiers.dart
index 644cd6a..64d6f92 100644
--- a/pkg/front_end/lib/src/fasta/identifiers.dart
+++ b/pkg/front_end/lib/src/fasta/identifiers.dart
@@ -11,62 +11,31 @@
import 'problems.dart' show unhandled, unsupported;
class Identifier {
- final String name;
- final int charOffset;
+ final Token token;
- Identifier(Token token)
- : name = token.lexeme,
- charOffset = token.charOffset;
+ Identifier(this.token);
- Identifier._(this.name, this.charOffset);
+ String get name => token.lexeme;
- factory Identifier.preserveToken(Token token) {
- return new _TokenIdentifier(token);
- }
+ int get charOffset => token.charOffset;
Expression get initializer => null;
int get endCharOffset => charOffset + name.length;
QualifiedName withQualifier(Object qualifier) {
- return new QualifiedName._(qualifier, name, charOffset);
+ return new QualifiedName(qualifier, token);
}
@override
String toString() => "identifier($name)";
}
-class _TokenIdentifier implements Identifier {
- final Token token;
-
- _TokenIdentifier(this.token);
-
- @override
- String get name => token.lexeme;
-
- @override
- int get charOffset => token.charOffset;
-
- @override
- Expression get initializer => null;
-
- @override
- int get endCharOffset => charOffset + name.length;
-
- @override
- QualifiedName withQualifier(Object qualifier) {
- return new _TokenQualifiedName(qualifier, token);
- }
-
- @override
- String toString() => "token-identifier($name)";
-}
-
-class InitializedIdentifier extends _TokenIdentifier {
+class InitializedIdentifier extends Identifier {
@override
final Expression initializer;
- InitializedIdentifier(_TokenIdentifier identifier, this.initializer)
+ InitializedIdentifier(Identifier identifier, this.initializer)
: super(identifier.token);
@override
@@ -83,8 +52,7 @@
QualifiedName(this.qualifier, Token suffix) : super(suffix);
- QualifiedName._(this.qualifier, String name, int charOffset)
- : super._(name, charOffset);
+ Token get suffix => token;
@override
QualifiedName withQualifier(Object qualifier) {
@@ -95,23 +63,6 @@
String toString() => "qualified-name($qualifier, $name)";
}
-class _TokenQualifiedName extends _TokenIdentifier implements QualifiedName {
- @override
- final Object qualifier;
-
- _TokenQualifiedName(this.qualifier, Token suffix)
- : assert(qualifier is! Identifier || qualifier is _TokenIdentifier),
- super(suffix);
-
- @override
- QualifiedName withQualifier(Object qualifier) {
- return unsupported("withQualifier", charOffset, null);
- }
-
- @override
- String toString() => "token-qualified-name($qualifier, $name)";
-}
-
void flattenQualifiedNameOn(
QualifiedName name, StringBuffer buffer, int charOffset, Uri fileUri) {
final Object qualifier = name.qualifier;
@@ -142,8 +93,3 @@
return unhandled("${name.runtimeType}", "flattenName", charOffset, fileUri);
}
}
-
-Token deprecated_extractToken(Identifier identifier) {
- _TokenIdentifier tokenIdentifier = identifier;
- return tokenIdentifier?.token;
-}
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index c7a0a91..a478938 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -80,12 +80,7 @@
import '../fasta_codes.dart' show LocatedMessage, Message, noLength, Template;
import '../identifiers.dart'
- show
- Identifier,
- InitializedIdentifier,
- QualifiedName,
- deprecated_extractToken,
- flattenName;
+ show Identifier, InitializedIdentifier, QualifiedName, flattenName;
import '../messages.dart' as messages show getLocationFromUri;
@@ -633,9 +628,7 @@
Object expression = pop();
if (expression is Identifier) {
Identifier identifier = expression;
- expression = new UnresolvedNameGenerator(
- this,
- deprecated_extractToken(identifier),
+ expression = new UnresolvedNameGenerator(this, identifier.token,
new Name(identifier.name, libraryBuilder.nameOrigin));
}
if (name?.isNotEmpty ?? false) {
@@ -1997,13 +1990,6 @@
void handleIdentifier(Token token, IdentifierContext context) {
debugEvent("handleIdentifier");
String name = token.lexeme;
- if (name.startsWith("deprecated") &&
- // Note that the previous check is redundant, but faster in the common
- // case (when [name] isn't deprecated).
- (name == "deprecated" || name.startsWith("deprecated_"))) {
- addProblem(fasta.templateUseOfDeprecatedIdentifier.withArguments(name),
- offsetForToken(token), lengthForToken(token));
- }
if (context.isScopeReference) {
assert(!inInitializer ||
this.scope == enclosingScope ||
@@ -2031,7 +2017,7 @@
if (token.isSynthetic) {
push(new ParserRecovery(offsetForToken(token)));
} else {
- push(new Identifier.preserveToken(token));
+ push(new Identifier(token));
}
}
@@ -2503,7 +2489,7 @@
assert(isConst == (constantContext == ConstantContext.inferred));
VariableDeclaration variable = new VariableDeclarationImpl(
identifier.name, functionNestingLevel,
- forSyntheticToken: deprecated_extractToken(identifier).isSynthetic,
+ forSyntheticToken: identifier.token.isSynthetic,
initializer: initializer,
type: buildDartType(currentLocalVariableType),
isFinal: isFinal,
@@ -3282,7 +3268,7 @@
if (name is QualifiedName) {
QualifiedName qualified = name;
Object prefix = qualified.qualifier;
- Token suffix = deprecated_extractToken(qualified);
+ Token suffix = qualified.suffix;
if (prefix is Generator) {
name = prefix.qualifiedLookup(suffix);
} else {
@@ -4016,7 +4002,7 @@
identifier.charOffset, identifier.name.length);
}
} else if (qualifier is Generator) {
- type = qualifier.qualifiedLookup(deprecated_extractToken(identifier));
+ type = qualifier.qualifiedLookup(identifier.token);
identifier = null;
} else if (qualifier is ProblemBuilder) {
type = qualifier;
@@ -4334,8 +4320,7 @@
]));
Arguments arguments = pop();
Identifier nameLastIdentifier = pop(NullValue.Identifier);
- Token nameLastToken =
- deprecated_extractToken(nameLastIdentifier) ?? nameToken;
+ Token nameLastToken = nameLastIdentifier?.token ?? nameToken;
String name = pop();
List<UnresolvedType> typeArguments = pop();
@@ -4807,7 +4792,7 @@
void endFunctionName(Token beginToken, Token token) {
debugEvent("FunctionName");
Identifier name = pop();
- Token nameToken = deprecated_extractToken(name);
+ Token nameToken = name.token;
VariableDeclaration variable = new VariableDeclarationImpl(
name.name, functionNestingLevel,
forSyntheticToken: nameToken.isSynthetic,
@@ -6102,7 +6087,7 @@
@override
void handleSymbolVoid(Token token) {
debugEvent("SymbolVoid");
- push(new Identifier.preserveToken(token));
+ push(new Identifier(token));
}
@override
diff --git a/pkg/front_end/lib/src/fasta/loader.dart b/pkg/front_end/lib/src/fasta/loader.dart
index cfdb636..0c917db 100644
--- a/pkg/front_end/lib/src/fasta/loader.dart
+++ b/pkg/front_end/lib/src/fasta/loader.dart
@@ -306,7 +306,7 @@
List<LocatedMessage> context,
bool problemOnLibrary: false,
List<Uri> involvedFiles}) {
- severity = target.fixSeverity(severity, message, fileUri);
+ severity ??= message.code.severity;
if (severity == Severity.ignored) return null;
String trace = """
message: ${message.message}
diff --git a/pkg/front_end/lib/src/fasta/rewrite_severity.dart b/pkg/front_end/lib/src/fasta/rewrite_severity.dart
deleted file mode 100644
index 5fd9ae8..0000000
--- a/pkg/front_end/lib/src/fasta/rewrite_severity.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2018, 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.
-
-import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
-
-import 'messages.dart' as msg;
-
-Severity rewriteSeverity(
- Severity severity, msg.Code<Object> code, Uri fileUri) {
- if (severity != Severity.ignored) {
- return severity;
- }
-
- String path = fileUri.path;
- String fastaPath = "/pkg/front_end/lib/src/fasta/";
- int index = path.indexOf(fastaPath);
- if (index == -1) {
- fastaPath = "/pkg/front_end/tool/_fasta/";
- index = path.indexOf(fastaPath);
- if (index == -1) return severity;
- }
- if (code == msg.codeUseOfDeprecatedIdentifier) {
- // TODO(ahe): Remove the exceptions below.
- // We plan to remove all uses of deprecated identifiers from Fasta. The
- // strategy is to remove files from the list below one by one. To get
- // started on cleaning up a given file, simply remove it from the list
- // below and compile Fasta with itself to get a list of remaining call
- // sites.
- switch (path.substring(fastaPath.length + index)) {
- case "command_line.dart":
- case "kernel/body_builder.dart":
- return severity;
- }
- }
- return Severity.error;
-}
diff --git a/pkg/front_end/lib/src/fasta/target_implementation.dart b/pkg/front_end/lib/src/fasta/target_implementation.dart
index 264ad8e..2b8a091 100644
--- a/pkg/front_end/lib/src/fasta/target_implementation.dart
+++ b/pkg/front_end/lib/src/fasta/target_implementation.dart
@@ -22,8 +22,6 @@
import 'messages.dart' show FormattedMessage, LocatedMessage, Message;
-import 'rewrite_severity.dart' show rewriteSeverity;
-
import 'target.dart' show Target;
import 'ticker.dart' show Ticker;
@@ -190,11 +188,6 @@
involvedFiles: involvedFiles);
}
- Severity fixSeverity(Severity severity, Message message, Uri fileUri) {
- severity ??= message.code.severity;
- return rewriteSeverity(severity, message.code, fileUri);
- }
-
String get currentSdkVersionString {
return CompilerContext.current.options.currentSdkVersion;
}
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 9bb52f9..5c8b909 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -3716,10 +3716,6 @@
template: "The field that corresponds to the parameter."
severity: CONTEXT
-UseOfDeprecatedIdentifier:
- template: "'#name' is deprecated."
- severity: IGNORED
-
InitializeFromDillNotSelfContained:
template: |
Tried to initialize from a previous compilation (#string), but the file was not self-contained. This might be a bug.
diff --git a/pkg/vm_service/test/get_stack_test.dart b/pkg/vm_service/test/get_stack_test.dart
index 5889996..2cd0f93 100644
--- a/pkg/vm_service/test/get_stack_test.dart
+++ b/pkg/vm_service/test/get_stack_test.dart
@@ -52,11 +52,12 @@
// Before the first await.
hasStoppedAtBreakpoint,
stoppedAtLine(LINE_A),
+ // At LINE_A we're still running sync. so no asyncCausalFrames.
(VmService service, IsolateRef isolateRef) async {
final result = await service.getStack(isolateRef.id);
expect(result.frames, hasLength(16));
- expect(result.asyncCausalFrames, hasLength(16));
+ expect(result.asyncCausalFrames, isNull);
expect(result.awaiterFrames, hasLength(16));
expectFrames(result.frames, [
@@ -73,20 +74,6 @@
[equals('Regular'), endsWith(' testMain')],
]);
- expectFrames(result.asyncCausalFrames, [
- [equals('Regular'), endsWith(' func10')],
- [equals('Regular'), endsWith(' func9')],
- [equals('Regular'), endsWith(' func8')],
- [equals('Regular'), endsWith(' func7')],
- [equals('Regular'), endsWith(' func6')],
- [equals('Regular'), endsWith(' func5')],
- [equals('Regular'), endsWith(' func4')],
- [equals('Regular'), endsWith(' func3')],
- [equals('Regular'), endsWith(' func2')],
- [equals('Regular'), endsWith(' func1')],
- [equals('Regular'), endsWith(' testMain')],
- ]);
-
expectFrames(result.awaiterFrames, [
[equals('AsyncActivation'), endsWith(' func10')],
[equals('AsyncActivation'), endsWith(' func9')],
@@ -101,10 +88,10 @@
[equals('AsyncActivation'), endsWith(' testMain')],
]);
},
- // After resuming the continuation - i.e. running async.
resumeIsolate,
hasStoppedAtBreakpoint,
stoppedAtLine(LINE_B),
+ // After resuming the continuation - i.e. running async.
(VmService service, IsolateRef isolateRef) async {
final result = await service.getStack(isolateRef.id);
diff --git a/runtime/observatory/tests/service/causal_async_stack_presence_test.dart b/runtime/observatory/tests/service/causal_async_stack_presence_test.dart
index 3a90e4a..01331cd 100644
--- a/runtime/observatory/tests/service/causal_async_stack_presence_test.dart
+++ b/runtime/observatory/tests/service/causal_async_stack_presence_test.dart
@@ -11,8 +11,8 @@
import 'test_helper.dart';
const LINE_C = 19;
-const LINE_A = 24;
-const LINE_B = 30;
+const LINE_A = 25;
+const LINE_B = 31;
foobar() {
debugger();
@@ -20,6 +20,7 @@
}
helper() async {
+ await 0; // Yield. The rest will run async.
debugger();
print('helper'); // LINE_A.
foobar();
@@ -36,6 +37,7 @@
(Isolate isolate) async {
ServiceMap stack = await isolate.getStack();
// No causal frames because we are in a completely synchronous stack.
+ // Async function hasn't yielded yet.
expect(stack['asyncCausalFrames'], isNull);
},
resumeIsolate,
@@ -43,7 +45,7 @@
stoppedAtLine(LINE_A),
(Isolate isolate) async {
ServiceMap stack = await isolate.getStack();
- // Has causal frames (we are inside an async function)
+ // Async function has yielded once, so it's now running async.
expect(stack['asyncCausalFrames'], isNotNull);
},
resumeIsolate,
diff --git a/runtime/observatory/tests/service/causal_async_star_stack_presence_test.dart b/runtime/observatory/tests/service/causal_async_star_stack_presence_test.dart
index 4d3e448..9b605cb 100644
--- a/runtime/observatory/tests/service/causal_async_star_stack_presence_test.dart
+++ b/runtime/observatory/tests/service/causal_async_star_stack_presence_test.dart
@@ -39,7 +39,7 @@
(Isolate isolate) async {
ServiceMap stack = await isolate.getStack();
// No causal frames because we are in a completely synchronous stack.
- expect(stack['asyncCausalFrames'], isNotNull);
+ expect(stack['asyncCausalFrames'], isNull);
},
resumeIsolate,
hasStoppedAtBreakpoint,
diff --git a/runtime/observatory_2/tests/service_2/causal_async_stack_presence_test.dart b/runtime/observatory_2/tests/service_2/causal_async_stack_presence_test.dart
index f52f4a1..cd9ef6a 100644
--- a/runtime/observatory_2/tests/service_2/causal_async_stack_presence_test.dart
+++ b/runtime/observatory_2/tests/service_2/causal_async_stack_presence_test.dart
@@ -11,8 +11,8 @@
import 'test_helper.dart';
const LINE_C = 19;
-const LINE_A = 24;
-const LINE_B = 30;
+const LINE_A = 25;
+const LINE_B = 31;
foobar() {
debugger();
@@ -20,6 +20,7 @@
}
helper() async {
+ await 0; // Yield. The rest will run async.
debugger();
print('helper'); // LINE_A.
foobar();
diff --git a/runtime/observatory_2/tests/service_2/causal_async_star_stack_presence_test.dart b/runtime/observatory_2/tests/service_2/causal_async_star_stack_presence_test.dart
index 7fb385a..8acf40d 100644
--- a/runtime/observatory_2/tests/service_2/causal_async_star_stack_presence_test.dart
+++ b/runtime/observatory_2/tests/service_2/causal_async_star_stack_presence_test.dart
@@ -39,7 +39,7 @@
(Isolate isolate) async {
ServiceMap stack = await isolate.getStack();
// No causal frames because we are in a completely synchronous stack.
- expect(stack['asyncCausalFrames'], isNotNull);
+ expect(stack['asyncCausalFrames'], isNull);
},
resumeIsolate,
hasStoppedAtBreakpoint,
diff --git a/runtime/tests/vm/dart/causal_stacks/utils.dart b/runtime/tests/vm/dart/causal_stacks/utils.dart
index 73ffe1d..8b75f98 100644
--- a/runtime/tests/vm/dart/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart/causal_stacks/utils.dart
@@ -178,12 +178,22 @@
return Future.sync(throwAsync).whenComplete(() => 'nop');
}
+// ----
+// Scenario: Future.then:
+// ----
+
+Future futureThen() {
+ return Future.value(0).then((value) {
+ throwSync();
+ });
+}
+
// Helpers:
// We want lines that either start with a frame index or an async gap marker.
final _lineRE = RegExp(r'^(?:#(?<number>\d+)|<asynchronous suspension>)');
-void assertStack(List<String> expects, StackTrace stackTrace,
+Future<void> assertStack(List<String> expects, StackTrace stackTrace,
[String? debugInfoFilename]) async {
final original = await Stream.value(stackTrace.toString())
.transform(const LineSplitter())
@@ -253,7 +263,7 @@
await f();
Expect.fail('No exception thrown!');
} on String catch (e, s) {
- assertStack(expectedStack, s, debugInfoFilename);
+ return assertStack(expectedStack, s, debugInfoFilename);
}
}
@@ -267,7 +277,7 @@
await f().then((e) => Expect.fail('No exception thrown!'));
Expect.fail('No exception thrown!');
} on String catch (e, s) {
- assertStack(expectedStack, s, debugInfoFilename);
+ return assertStack(expectedStack, s, debugInfoFilename);
}
}
@@ -278,7 +288,7 @@
await f().catchError((e, s) {
stackTrace = s;
});
- assertStack(expectedStack, stackTrace, debugInfoFilename);
+ return assertStack(expectedStack, stackTrace, debugInfoFilename);
}
// ----
@@ -327,39 +337,32 @@
r'^#13 Future._propagateToListeners ',
r'^#14 Future._completeWithValue ',
r'^#15 _completeOnAsyncReturn ',
- r'^#16 doTestAwaitCatchError ',
+ r'^#16 assertStack ',
r'^#17 _RootZone.runUnary ',
r'^#18 _FutureListener.handleValue ',
r'^#19 Future._propagateToListeners.handleValueCallback ',
r'^#20 Future._propagateToListeners ',
- r'^#21 Future._completeError ',
- r'^#22 _completeOnAsyncError ',
- r'^#23 allYield ',
- r'^#24 _asyncErrorWrapperHelper.errorCallback ',
- r'^#25 _RootZone.runBinary ',
- r'^#26 _FutureListener.handleError ',
- r'^#27 Future._propagateToListeners.handleError ',
- r'^#28 Future._propagateToListeners ',
- r'^#29 Future._completeError ',
- r'^#30 _completeOnAsyncError ',
- r'^#31 allYield2 ',
- r'^#32 _asyncErrorWrapperHelper.errorCallback ',
- r'^#33 _RootZone.runBinary ',
- r'^#34 _FutureListener.handleError ',
- r'^#35 Future._propagateToListeners.handleError ',
- r'^#36 Future._propagateToListeners ',
- r'^#37 Future._completeError ',
- r'^#38 _completeOnAsyncError ',
- r'^#39 allYield3 ',
- r'^#40 _RootZone.runUnary ',
- r'^#41 _FutureListener.handleValue ',
- r'^#42 Future._propagateToListeners.handleValueCallback ',
- r'^#43 Future._propagateToListeners ',
- r'^#44 Future._addListener.<anonymous closure> ',
- r'^#45 _microtaskLoop ',
- r'^#46 _startMicrotaskLoop ',
- r'^#47 _runPendingImmediateCallback ',
- r'^#48 _RawReceivePortImpl._handleMessage ',
+ r'^#21 Future._complete ',
+ r'^#22 Stream.toList.<anonymous closure> ',
+ r'^#23 _RootZone.runGuarded ',
+ r'^#24 _BufferingStreamSubscription._sendDone.sendDone ',
+ r'^#25 _BufferingStreamSubscription._sendDone ',
+ r'^#26 _BufferingStreamSubscription._close ',
+ r'^#27 _SinkTransformerStreamSubscription._close ',
+ r'^#28 _EventSinkWrapper.close ',
+ r'^#29 _StringAdapterSink.close ',
+ r'^#30 _LineSplitterSink.close ',
+ r'^#31 _SinkTransformerStreamSubscription._handleDone ',
+ r'^#32 _RootZone.runGuarded ',
+ r'^#33 _BufferingStreamSubscription._sendDone.sendDone ',
+ r'^#34 _BufferingStreamSubscription._sendDone ',
+ r'^#35 _DelayedDone.perform ',
+ r'^#36 _StreamImplEvents.handleNext ',
+ r'^#37 _PendingEvents.schedule.<anonymous closure> ',
+ r'^#38 _microtaskLoop ',
+ r'^#39 _startMicrotaskLoop ',
+ r'^#40 _runPendingImmediateCallback ',
+ r'^#41 _RawReceivePortImpl._handleMessage ',
],
debugInfoFilename);
await doTestAwaitThen(
@@ -375,34 +378,32 @@
r'^#13 Future._propagateToListeners ',
r'^#14 Future._completeWithValue ',
r'^#15 _completeOnAsyncReturn ',
- r'^#16 doTestAwait ',
- r'^#17 _asyncErrorWrapperHelper.errorCallback ',
- r'^#18 _RootZone.runBinary ',
- r'^#19 _FutureListener.handleError ',
- r'^#20 Future._propagateToListeners.handleError ',
- r'^#21 Future._propagateToListeners ',
- r'^#22 Future._completeError ',
- r'^#23 _completeOnAsyncError ',
- r'^#24 noYields ',
- r'^#25 _asyncErrorWrapperHelper.errorCallback ',
- r'^#26 _RootZone.runBinary ',
- r'^#27 _FutureListener.handleError ',
- r'^#28 Future._propagateToListeners.handleError ',
- r'^#29 Future._propagateToListeners ',
- r'^#30 Future._completeError ',
- r'^#31 _completeOnAsyncError ',
- r'^#32 noYields2 ',
- r'^#33 _asyncErrorWrapperHelper.errorCallback ',
- r'^#34 _RootZone.runBinary ',
- r'^#35 _FutureListener.handleError ',
- r'^#36 Future._propagateToListeners.handleError ',
- r'^#37 Future._propagateToListeners ',
- r'^#38 Future._completeError ',
- r'^#39 Future._asyncCompleteError.<anonymous closure> ',
- r'^#40 _microtaskLoop ',
- r'^#41 _startMicrotaskLoop ',
- r'^#42 _runPendingImmediateCallback ',
- r'^#43 _RawReceivePortImpl._handleMessage ',
+ r'^#16 assertStack ',
+ r'^#17 _RootZone.runUnary ',
+ r'^#18 _FutureListener.handleValue ',
+ r'^#19 Future._propagateToListeners.handleValueCallback ',
+ r'^#20 Future._propagateToListeners ',
+ r'^#21 Future._complete ',
+ r'^#22 Stream.toList.<anonymous closure> ',
+ r'^#23 _RootZone.runGuarded ',
+ r'^#24 _BufferingStreamSubscription._sendDone.sendDone ',
+ r'^#25 _BufferingStreamSubscription._sendDone ',
+ r'^#26 _BufferingStreamSubscription._close ',
+ r'^#27 _SinkTransformerStreamSubscription._close ',
+ r'^#28 _EventSinkWrapper.close ',
+ r'^#29 _StringAdapterSink.close ',
+ r'^#30 _LineSplitterSink.close ',
+ r'^#31 _SinkTransformerStreamSubscription._handleDone ',
+ r'^#32 _RootZone.runGuarded ',
+ r'^#33 _BufferingStreamSubscription._sendDone.sendDone ',
+ r'^#34 _BufferingStreamSubscription._sendDone ',
+ r'^#35 _DelayedDone.perform ',
+ r'^#36 _StreamImplEvents.handleNext ',
+ r'^#37 _PendingEvents.schedule.<anonymous closure> ',
+ r'^#38 _microtaskLoop ',
+ r'^#39 _startMicrotaskLoop ',
+ r'^#40 _runPendingImmediateCallback ',
+ r'^#41 _RawReceivePortImpl._handleMessage ',
],
debugInfoFilename);
await doTestAwaitCatchError(
@@ -418,34 +419,32 @@
r'^#13 Future._propagateToListeners ',
r'^#14 Future._completeWithValue ',
r'^#15 _completeOnAsyncReturn ',
- r'^#16 doTestAwaitThen ',
- r'^#17 _asyncErrorWrapperHelper.errorCallback ',
- r'^#18 _RootZone.runBinary ',
- r'^#19 _FutureListener.handleError ',
- r'^#20 Future._propagateToListeners.handleError ',
- r'^#21 Future._propagateToListeners ',
- r'^#22 Future._completeError ',
- r'^#23 _completeOnAsyncError ',
- r'^#24 noYields ',
- r'^#25 _asyncErrorWrapperHelper.errorCallback ',
- r'^#26 _RootZone.runBinary ',
- r'^#27 _FutureListener.handleError ',
- r'^#28 Future._propagateToListeners.handleError ',
- r'^#29 Future._propagateToListeners ',
- r'^#30 Future._completeError ',
- r'^#31 _completeOnAsyncError ',
- r'^#32 noYields2 ',
- r'^#33 _asyncErrorWrapperHelper.errorCallback ',
- r'^#34 _RootZone.runBinary ',
- r'^#35 _FutureListener.handleError ',
- r'^#36 Future._propagateToListeners.handleError ',
- r'^#37 Future._propagateToListeners ',
- r'^#38 Future._completeError ',
- r'^#39 Future._asyncCompleteError.<anonymous closure> ',
- r'^#40 _microtaskLoop ',
- r'^#41 _startMicrotaskLoop ',
- r'^#42 _runPendingImmediateCallback ',
- r'^#43 _RawReceivePortImpl._handleMessage ',
+ r'^#16 assertStack ',
+ r'^#17 _RootZone.runUnary ',
+ r'^#18 _FutureListener.handleValue ',
+ r'^#19 Future._propagateToListeners.handleValueCallback ',
+ r'^#20 Future._propagateToListeners ',
+ r'^#21 Future._complete ',
+ r'^#22 Stream.toList.<anonymous closure> ',
+ r'^#23 _RootZone.runGuarded ',
+ r'^#24 _BufferingStreamSubscription._sendDone.sendDone ',
+ r'^#25 _BufferingStreamSubscription._sendDone ',
+ r'^#26 _BufferingStreamSubscription._close ',
+ r'^#27 _SinkTransformerStreamSubscription._close ',
+ r'^#28 _EventSinkWrapper.close ',
+ r'^#29 _StringAdapterSink.close ',
+ r'^#30 _LineSplitterSink.close ',
+ r'^#31 _SinkTransformerStreamSubscription._handleDone ',
+ r'^#32 _RootZone.runGuarded ',
+ r'^#33 _BufferingStreamSubscription._sendDone.sendDone ',
+ r'^#34 _BufferingStreamSubscription._sendDone ',
+ r'^#35 _DelayedDone.perform ',
+ r'^#36 _StreamImplEvents.handleNext ',
+ r'^#37 _PendingEvents.schedule.<anonymous closure> ',
+ r'^#38 _microtaskLoop ',
+ r'^#39 _startMicrotaskLoop ',
+ r'^#40 _runPendingImmediateCallback ',
+ r'^#41 _RawReceivePortImpl._handleMessage ',
],
debugInfoFilename);
@@ -642,329 +641,497 @@
await doTestAwaitCatchError(
futureSyncWhenComplete, expected, debugInfoFilename);
}
+
+ {
+ final expected = const <String>[
+ r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
+ r'^#1 futureThen.<anonymous closure> \(.*/utils.dart:187(:5)?\)$',
+ r'^#2 _RootZone.runUnary ',
+ r'^#3 _FutureListener.handleValue ',
+ r'^#4 Future._propagateToListeners.handleValueCallback ',
+ r'^#5 Future._propagateToListeners ',
+ r'^#6 Future._completeWithValue ',
+ r'^#7 Future._asyncCompleteWithValue.<anonymous closure> ',
+ r'^#8 _microtaskLoop ',
+ r'^#9 _startMicrotaskLoop ',
+ r'^#10 _runPendingImmediateCallback ',
+ r'^#11 _RawReceivePortImpl._handleMessage ',
+ ];
+ await doTestAwait(futureThen, expected, debugInfoFilename);
+ await doTestAwaitThen(futureThen, expected, debugInfoFilename);
+ await doTestAwaitCatchError(futureThen, expected, debugInfoFilename);
+ }
}
// For: --lazy-async-stacks
Future<void> doTestsLazy([String? debugInfoFilename]) async {
- final allYieldExpected = const <String>[
- r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
- r'^#1 allYield3 \(.*/utils.dart:39(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 allYield2 \(.*/utils.dart:34(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#3 allYield \(.*/utils.dart:29(:3)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- allYield,
- allYieldExpected +
- const <String>[
- r'^#4 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#5 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#6 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- allYield,
- allYieldExpected +
- const <String>[
- r'^#4 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(allYield, allYieldExpected, debugInfoFilename);
+ // allYield
+ {
+ final allYieldExpected = const <String>[
+ r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
+ r'^#1 allYield3 \(.*/utils.dart:39(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 allYield2 \(.*/utils.dart:34(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#3 allYield \(.*/utils.dart:29(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ allYield,
+ allYieldExpected +
+ const <String>[
+ r'^#4 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#5 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#6 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ allYield,
+ allYieldExpected +
+ const <String>[
+ r'^#4 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#5 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#6 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ allYield,
+ allYieldExpected +
+ const <String>[
+ r'^#4 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#5 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#6 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
- final noYieldsExpected = const <String>[
- r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
- r'^#1 noYields3 \(.*/utils.dart:54(:3)?\)$',
- r'^#2 noYields2 \(.*/utils.dart:50(:9)?\)$',
- r'^#3 noYields \(.*/utils.dart:46(:9)?\)$',
- ];
- await doTestAwait(
- noYields,
- noYieldsExpected +
- const <String>[
- r'^#4 doTestAwait ',
- r'^#5 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#6 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- noYields,
- noYieldsExpected +
- const <String>[
- r'^#4 doTestAwaitThen ',
- r'^#5 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#6 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(
- noYields,
- noYieldsExpected +
- const <String>[
- r'^#4 doTestAwaitCatchError ',
- r'^#5 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#6 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
+ // noYields
+ {
+ final noYieldsExpected = const <String>[
+ r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
+ r'^#1 noYields3 \(.*/utils.dart:54(:3)?\)$',
+ r'^#2 noYields2 \(.*/utils.dart:50(:9)?\)$',
+ r'^#3 noYields \(.*/utils.dart:46(:9)?\)$',
+ ];
+ await doTestAwait(
+ noYields,
+ noYieldsExpected +
+ const <String>[
+ r'^#4 doTestAwait ',
+ r'^#5 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#6 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ noYields,
+ noYieldsExpected +
+ const <String>[
+ r'^#4 doTestAwaitThen ',
+ r'^#5 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#6 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ noYields,
+ noYieldsExpected +
+ const <String>[
+ r'^#4 doTestAwaitCatchError ',
+ r'^#5 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#6 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
- final mixedYieldsExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 mixedYields2 \(.*/utils.dart:66(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 mixedYields \(.*/utils.dart:61(:3)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- mixedYields,
- mixedYieldsExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- mixedYields,
- mixedYieldsExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(
- mixedYields, mixedYieldsExpected, debugInfoFilename);
+ // mixedYields
+ {
+ final mixedYieldsExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 mixedYields2 \(.*/utils.dart:66(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 mixedYields \(.*/utils.dart:61(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ mixedYields,
+ mixedYieldsExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ mixedYields,
+ mixedYieldsExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ mixedYields,
+ mixedYieldsExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
- final syncSuffixExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 syncSuffix2 \(.*/utils.dart:82(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 syncSuffix \(.*/utils.dart:77(:3)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- syncSuffix,
- syncSuffixExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- syncSuffix,
- syncSuffixExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(
- syncSuffix, syncSuffixExpected, debugInfoFilename);
+ // syncSuffix
+ {
+ final syncSuffixExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 syncSuffix2 \(.*/utils.dart:82(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 syncSuffix \(.*/utils.dart:77(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ syncSuffix,
+ syncSuffixExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ syncSuffix,
+ syncSuffixExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ syncSuffix,
+ syncSuffixExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
- final nonAsyncNoStackExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 nonAsyncNoStack1 \(.*/utils.dart:95(:36)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 nonAsyncNoStack \(.*/utils.dart:93(:35)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- nonAsyncNoStack,
- nonAsyncNoStackExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- nonAsyncNoStack,
- nonAsyncNoStackExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(
- nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
+ // nonAsyncNoStack
+ {
+ final nonAsyncNoStackExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 nonAsyncNoStack1 \(.*/utils.dart:95(:36)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 nonAsyncNoStack \(.*/utils.dart:93(:35)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ nonAsyncNoStack,
+ nonAsyncNoStackExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ nonAsyncNoStack,
+ nonAsyncNoStackExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ nonAsyncNoStack,
+ nonAsyncNoStackExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
- final asyncStarThrowSyncExpected = const <String>[
- r'^#0 throwSync \(.+/utils.dart:16(:3)?\)$',
- r'^#1 asyncStarThrowSync \(.+/utils.dart:112(:11)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 awaitEveryAsyncStarThrowSync \(.+/utils.dart:104(:3)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- awaitEveryAsyncStarThrowSync,
- asyncStarThrowSyncExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- awaitEveryAsyncStarThrowSync,
- asyncStarThrowSyncExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(awaitEveryAsyncStarThrowSync,
- asyncStarThrowSyncExpected, debugInfoFilename);
+ // awaitEveryAsyncStarThrowSync
+ {
+ final asyncStarThrowSyncExpected = const <String>[
+ r'^#0 throwSync \(.+/utils.dart:16(:3)?\)$',
+ r'^#1 asyncStarThrowSync \(.+/utils.dart:112(:11)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 awaitEveryAsyncStarThrowSync \(.+/utils.dart:104(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ awaitEveryAsyncStarThrowSync,
+ asyncStarThrowSyncExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ awaitEveryAsyncStarThrowSync,
+ asyncStarThrowSyncExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ awaitEveryAsyncStarThrowSync,
+ asyncStarThrowSyncExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
- final asyncStarThrowAsyncExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 awaitEveryAsyncStarThrowAsync \(.+/utils.dart:117(:3)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- awaitEveryAsyncStarThrowAsync,
- asyncStarThrowAsyncExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- awaitEveryAsyncStarThrowAsync,
- asyncStarThrowAsyncExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(awaitEveryAsyncStarThrowAsync,
- asyncStarThrowAsyncExpected, debugInfoFilename);
+ // awaitEveryAsyncStarThrowAsync
+ {
+ final asyncStarThrowAsyncExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 awaitEveryAsyncStarThrowAsync \(.+/utils.dart:117(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ awaitEveryAsyncStarThrowAsync,
+ asyncStarThrowAsyncExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ awaitEveryAsyncStarThrowAsync,
+ asyncStarThrowAsyncExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ awaitEveryAsyncStarThrowAsync,
+ asyncStarThrowAsyncExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
- final listenAsyncStartExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 listenAsyncStarThrowAsync.<anonymous closure> \(.+/utils.dart(:0)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
- await doTestAwaitThen(
- listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
- await doTestAwaitCatchError(
- listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
+ // listenAsyncStarThrowAsync
+ {
+ final listenAsyncStartExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 listenAsyncStarThrowAsync.<anonymous closure> \(.+/utils.dart(:0)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
+ await doTestAwaitThen(
+ listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
+ await doTestAwaitCatchError(
+ listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
+ }
- final customErrorZoneExpected = const <String>[
- r'#0 throwSync \(.*/utils.dart:16(:3)?\)$',
- r'#1 allYield3 \(.*/utils.dart:39(:3)?\)$',
- r'<asynchronous suspension>$',
- r'#2 allYield2 \(.*/utils.dart:34(:3)?\)$',
- r'<asynchronous suspension>$',
- r'#3 allYield \(.*/utils.dart:29(:3)?\)$',
- r'<asynchronous suspension>$',
- r'#4 customErrorZone.<anonymous closure> \(.*/utils.dart:144(:5)?\)$',
- r'<asynchronous suspension>$',
- ];
- await doTestAwait(
- customErrorZone, customErrorZoneExpected, debugInfoFilename);
- await doTestAwaitThen(
- customErrorZone, customErrorZoneExpected, debugInfoFilename);
- await doTestAwaitCatchError(
- customErrorZone, customErrorZoneExpected, debugInfoFilename);
+ // customErrorZone
+ {
+ final customErrorZoneExpected = const <String>[
+ r'#0 throwSync \(.*/utils.dart:16(:3)?\)$',
+ r'#1 allYield3 \(.*/utils.dart:39(:3)?\)$',
+ r'<asynchronous suspension>$',
+ r'#2 allYield2 \(.*/utils.dart:34(:3)?\)$',
+ r'<asynchronous suspension>$',
+ r'#3 allYield \(.*/utils.dart:29(:3)?\)$',
+ r'<asynchronous suspension>$',
+ r'#4 customErrorZone.<anonymous closure> \(.*/utils.dart:144(:5)?\)$',
+ r'<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ customErrorZone, customErrorZoneExpected, debugInfoFilename);
+ await doTestAwaitThen(
+ customErrorZone, customErrorZoneExpected, debugInfoFilename);
+ await doTestAwaitCatchError(
+ customErrorZone, customErrorZoneExpected, debugInfoFilename);
+ }
- final awaitTimeoutExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 Future.timeout.<anonymous closure> \(dart:async/future_impl.dart',
- r'^<asynchronous suspension>$',
- r'^#2 awaitTimeout ',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- awaitTimeout,
- awaitTimeoutExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- awaitTimeout,
- awaitTimeoutExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(
- awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
+ // awaitTimeout
+ {
+ final awaitTimeoutExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 Future.timeout.<anonymous closure> \(dart:async/future_impl.dart',
+ r'^<asynchronous suspension>$',
+ r'^#2 awaitTimeout ',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ awaitTimeout,
+ awaitTimeoutExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ awaitTimeout,
+ awaitTimeoutExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ awaitTimeout,
+ awaitTimeoutExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
- final awaitWaitExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 Future.wait.<anonymous closure> \(dart:async/future.dart',
- r'^<asynchronous suspension>$',
- r'^#2 awaitWait ',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- awaitWait,
- awaitWaitExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- awaitWait,
- awaitWaitExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(awaitWait, awaitWaitExpected, debugInfoFilename);
+ // awaitWait
+ {
+ final awaitWaitExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 Future.wait.<anonymous closure> \(dart:async/future.dart',
+ r'^<asynchronous suspension>$',
+ r'^#2 awaitWait ',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ awaitWait,
+ awaitWaitExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ awaitWait,
+ awaitWaitExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ awaitWait,
+ awaitWaitExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
+ // futureSyncWhenComplete
{
final expected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -986,11 +1153,70 @@
futureSyncWhenComplete,
expected +
const <String>[
- r'^#1 doTestAwaitThen.<anonymous closure> ',
+ r'^#1 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#2 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#3 main ',
r'^<asynchronous suspension>$',
],
debugInfoFilename);
await doTestAwaitCatchError(
- futureSyncWhenComplete, expected, debugInfoFilename);
+ futureSyncWhenComplete,
+ expected +
+ const <String>[
+ r'^#1 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#2 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#3 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
+
+ // futureThen
+ {
+ final expected = const <String>[
+ r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
+ r'^#1 futureThen.<anonymous closure> ',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ futureThen,
+ expected +
+ const <String>[
+ r'^#2 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#3 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#4 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ futureThen,
+ expected +
+ const <String>[
+ r'^#2 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#3 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#4 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ futureThen,
+ expected +
+ const <String>[
+ r'^#2 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#3 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#4 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
}
}
diff --git a/runtime/tests/vm/dart_2/causal_stacks/utils.dart b/runtime/tests/vm/dart_2/causal_stacks/utils.dart
index 192984f..b7c4e02 100644
--- a/runtime/tests/vm/dart_2/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart_2/causal_stacks/utils.dart
@@ -178,12 +178,22 @@
return Future.sync(throwAsync).whenComplete(() => 'nop');
}
+// ----
+// Scenario: Future.then:
+// ----
+
+Future futureThen() {
+ return Future.value(0).then((value) {
+ throwSync();
+ });
+}
+
// Helpers:
// We want lines that either start with a frame index or an async gap marker.
final _lineRE = RegExp(r'^(?:#(?<number>\d+)|<asynchronous suspension>)');
-void assertStack(List<String> expects, StackTrace stackTrace,
+Future<void> assertStack(List<String> expects, StackTrace stackTrace,
[String debugInfoFilename]) async {
final original = await Stream.value(stackTrace.toString())
.transform(const LineSplitter())
@@ -253,7 +263,7 @@
await f();
Expect.fail('No exception thrown!');
} on String catch (e, s) {
- assertStack(expectedStack, s, debugInfoFilename);
+ return assertStack(expectedStack, s, debugInfoFilename);
}
}
@@ -267,7 +277,7 @@
await f().then((e) => Expect.fail('No exception thrown!'));
Expect.fail('No exception thrown!');
} on String catch (e, s) {
- assertStack(expectedStack, s, debugInfoFilename);
+ return assertStack(expectedStack, s, debugInfoFilename);
}
}
@@ -278,7 +288,7 @@
await f().catchError((e, s) {
stackTrace = s;
});
- assertStack(expectedStack, stackTrace, debugInfoFilename);
+ return assertStack(expectedStack, stackTrace, debugInfoFilename);
}
// ----
@@ -327,39 +337,32 @@
r'^#13 Future._propagateToListeners ',
r'^#14 Future._completeWithValue ',
r'^#15 _completeOnAsyncReturn ',
- r'^#16 doTestAwaitCatchError ',
+ r'^#16 assertStack ',
r'^#17 _RootZone.runUnary ',
r'^#18 _FutureListener.handleValue ',
r'^#19 Future._propagateToListeners.handleValueCallback ',
r'^#20 Future._propagateToListeners ',
- r'^#21 Future._completeError ',
- r'^#22 _completeOnAsyncError ',
- r'^#23 allYield ',
- r'^#24 _asyncErrorWrapperHelper.errorCallback ',
- r'^#25 _RootZone.runBinary ',
- r'^#26 _FutureListener.handleError ',
- r'^#27 Future._propagateToListeners.handleError ',
- r'^#28 Future._propagateToListeners ',
- r'^#29 Future._completeError ',
- r'^#30 _completeOnAsyncError ',
- r'^#31 allYield2 ',
- r'^#32 _asyncErrorWrapperHelper.errorCallback ',
- r'^#33 _RootZone.runBinary ',
- r'^#34 _FutureListener.handleError ',
- r'^#35 Future._propagateToListeners.handleError ',
- r'^#36 Future._propagateToListeners ',
- r'^#37 Future._completeError ',
- r'^#38 _completeOnAsyncError ',
- r'^#39 allYield3 ',
- r'^#40 _RootZone.runUnary ',
- r'^#41 _FutureListener.handleValue ',
- r'^#42 Future._propagateToListeners.handleValueCallback ',
- r'^#43 Future._propagateToListeners ',
- r'^#44 Future._addListener.<anonymous closure> ',
- r'^#45 _microtaskLoop ',
- r'^#46 _startMicrotaskLoop ',
- r'^#47 _runPendingImmediateCallback ',
- r'^#48 _RawReceivePortImpl._handleMessage ',
+ r'^#21 Future._complete ',
+ r'^#22 Stream.toList.<anonymous closure> ',
+ r'^#23 _RootZone.runGuarded ',
+ r'^#24 _BufferingStreamSubscription._sendDone.sendDone ',
+ r'^#25 _BufferingStreamSubscription._sendDone ',
+ r'^#26 _BufferingStreamSubscription._close ',
+ r'^#27 _SinkTransformerStreamSubscription._close ',
+ r'^#28 _EventSinkWrapper.close ',
+ r'^#29 _StringAdapterSink.close ',
+ r'^#30 _LineSplitterSink.close ',
+ r'^#31 _SinkTransformerStreamSubscription._handleDone ',
+ r'^#32 _RootZone.runGuarded ',
+ r'^#33 _BufferingStreamSubscription._sendDone.sendDone ',
+ r'^#34 _BufferingStreamSubscription._sendDone ',
+ r'^#35 _DelayedDone.perform ',
+ r'^#36 _StreamImplEvents.handleNext ',
+ r'^#37 _PendingEvents.schedule.<anonymous closure> ',
+ r'^#38 _microtaskLoop ',
+ r'^#39 _startMicrotaskLoop ',
+ r'^#40 _runPendingImmediateCallback ',
+ r'^#41 _RawReceivePortImpl._handleMessage ',
],
debugInfoFilename);
await doTestAwaitThen(
@@ -375,34 +378,32 @@
r'^#13 Future._propagateToListeners ',
r'^#14 Future._completeWithValue ',
r'^#15 _completeOnAsyncReturn ',
- r'^#16 doTestAwait ',
- r'^#17 _asyncErrorWrapperHelper.errorCallback ',
- r'^#18 _RootZone.runBinary ',
- r'^#19 _FutureListener.handleError ',
- r'^#20 Future._propagateToListeners.handleError ',
- r'^#21 Future._propagateToListeners ',
- r'^#22 Future._completeError ',
- r'^#23 _completeOnAsyncError ',
- r'^#24 noYields ',
- r'^#25 _asyncErrorWrapperHelper.errorCallback ',
- r'^#26 _RootZone.runBinary ',
- r'^#27 _FutureListener.handleError ',
- r'^#28 Future._propagateToListeners.handleError ',
- r'^#29 Future._propagateToListeners ',
- r'^#30 Future._completeError ',
- r'^#31 _completeOnAsyncError ',
- r'^#32 noYields2 ',
- r'^#33 _asyncErrorWrapperHelper.errorCallback ',
- r'^#34 _RootZone.runBinary ',
- r'^#35 _FutureListener.handleError ',
- r'^#36 Future._propagateToListeners.handleError ',
- r'^#37 Future._propagateToListeners ',
- r'^#38 Future._completeError ',
- r'^#39 Future._asyncCompleteError.<anonymous closure> ',
- r'^#40 _microtaskLoop ',
- r'^#41 _startMicrotaskLoop ',
- r'^#42 _runPendingImmediateCallback ',
- r'^#43 _RawReceivePortImpl._handleMessage ',
+ r'^#16 assertStack ',
+ r'^#17 _RootZone.runUnary ',
+ r'^#18 _FutureListener.handleValue ',
+ r'^#19 Future._propagateToListeners.handleValueCallback ',
+ r'^#20 Future._propagateToListeners ',
+ r'^#21 Future._complete ',
+ r'^#22 Stream.toList.<anonymous closure> ',
+ r'^#23 _RootZone.runGuarded ',
+ r'^#24 _BufferingStreamSubscription._sendDone.sendDone ',
+ r'^#25 _BufferingStreamSubscription._sendDone ',
+ r'^#26 _BufferingStreamSubscription._close ',
+ r'^#27 _SinkTransformerStreamSubscription._close ',
+ r'^#28 _EventSinkWrapper.close ',
+ r'^#29 _StringAdapterSink.close ',
+ r'^#30 _LineSplitterSink.close ',
+ r'^#31 _SinkTransformerStreamSubscription._handleDone ',
+ r'^#32 _RootZone.runGuarded ',
+ r'^#33 _BufferingStreamSubscription._sendDone.sendDone ',
+ r'^#34 _BufferingStreamSubscription._sendDone ',
+ r'^#35 _DelayedDone.perform ',
+ r'^#36 _StreamImplEvents.handleNext ',
+ r'^#37 _PendingEvents.schedule.<anonymous closure> ',
+ r'^#38 _microtaskLoop ',
+ r'^#39 _startMicrotaskLoop ',
+ r'^#40 _runPendingImmediateCallback ',
+ r'^#41 _RawReceivePortImpl._handleMessage ',
],
debugInfoFilename);
await doTestAwaitCatchError(
@@ -418,34 +419,32 @@
r'^#13 Future._propagateToListeners ',
r'^#14 Future._completeWithValue ',
r'^#15 _completeOnAsyncReturn ',
- r'^#16 doTestAwaitThen ',
- r'^#17 _asyncErrorWrapperHelper.errorCallback ',
- r'^#18 _RootZone.runBinary ',
- r'^#19 _FutureListener.handleError ',
- r'^#20 Future._propagateToListeners.handleError ',
- r'^#21 Future._propagateToListeners ',
- r'^#22 Future._completeError ',
- r'^#23 _completeOnAsyncError ',
- r'^#24 noYields ',
- r'^#25 _asyncErrorWrapperHelper.errorCallback ',
- r'^#26 _RootZone.runBinary ',
- r'^#27 _FutureListener.handleError ',
- r'^#28 Future._propagateToListeners.handleError ',
- r'^#29 Future._propagateToListeners ',
- r'^#30 Future._completeError ',
- r'^#31 _completeOnAsyncError ',
- r'^#32 noYields2 ',
- r'^#33 _asyncErrorWrapperHelper.errorCallback ',
- r'^#34 _RootZone.runBinary ',
- r'^#35 _FutureListener.handleError ',
- r'^#36 Future._propagateToListeners.handleError ',
- r'^#37 Future._propagateToListeners ',
- r'^#38 Future._completeError ',
- r'^#39 Future._asyncCompleteError.<anonymous closure> ',
- r'^#40 _microtaskLoop ',
- r'^#41 _startMicrotaskLoop ',
- r'^#42 _runPendingImmediateCallback ',
- r'^#43 _RawReceivePortImpl._handleMessage ',
+ r'^#16 assertStack ',
+ r'^#17 _RootZone.runUnary ',
+ r'^#18 _FutureListener.handleValue ',
+ r'^#19 Future._propagateToListeners.handleValueCallback ',
+ r'^#20 Future._propagateToListeners ',
+ r'^#21 Future._complete ',
+ r'^#22 Stream.toList.<anonymous closure> ',
+ r'^#23 _RootZone.runGuarded ',
+ r'^#24 _BufferingStreamSubscription._sendDone.sendDone ',
+ r'^#25 _BufferingStreamSubscription._sendDone ',
+ r'^#26 _BufferingStreamSubscription._close ',
+ r'^#27 _SinkTransformerStreamSubscription._close ',
+ r'^#28 _EventSinkWrapper.close ',
+ r'^#29 _StringAdapterSink.close ',
+ r'^#30 _LineSplitterSink.close ',
+ r'^#31 _SinkTransformerStreamSubscription._handleDone ',
+ r'^#32 _RootZone.runGuarded ',
+ r'^#33 _BufferingStreamSubscription._sendDone.sendDone ',
+ r'^#34 _BufferingStreamSubscription._sendDone ',
+ r'^#35 _DelayedDone.perform ',
+ r'^#36 _StreamImplEvents.handleNext ',
+ r'^#37 _PendingEvents.schedule.<anonymous closure> ',
+ r'^#38 _microtaskLoop ',
+ r'^#39 _startMicrotaskLoop ',
+ r'^#40 _runPendingImmediateCallback ',
+ r'^#41 _RawReceivePortImpl._handleMessage ',
],
debugInfoFilename);
@@ -642,337 +641,505 @@
await doTestAwaitCatchError(
futureSyncWhenComplete, expected, debugInfoFilename);
}
+
+ {
+ final expected = const <String>[
+ r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
+ r'^#1 futureThen.<anonymous closure> \(.*/utils.dart:187(:5)?\)$',
+ r'^#2 _RootZone.runUnary ',
+ r'^#3 _FutureListener.handleValue ',
+ r'^#4 Future._propagateToListeners.handleValueCallback ',
+ r'^#5 Future._propagateToListeners ',
+ r'^#6 Future._completeWithValue ',
+ r'^#7 Future._asyncCompleteWithValue.<anonymous closure> ',
+ r'^#8 _microtaskLoop ',
+ r'^#9 _startMicrotaskLoop ',
+ r'^#10 _runPendingImmediateCallback ',
+ r'^#11 _RawReceivePortImpl._handleMessage ',
+ ];
+ await doTestAwait(futureThen, expected, debugInfoFilename);
+ await doTestAwaitThen(futureThen, expected, debugInfoFilename);
+ await doTestAwaitCatchError(futureThen, expected, debugInfoFilename);
+ }
}
// For: --lazy-async-stacks
Future<void> doTestsLazy([String debugInfoFilename]) async {
- final allYieldExpected = const <String>[
- r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
- r'^#1 allYield3 \(.*/utils.dart:39(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 allYield2 \(.*/utils.dart:34(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#3 allYield \(.*/utils.dart:29(:3)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- allYield,
- allYieldExpected +
- const <String>[
- r'^#4 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#5 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#6 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- allYield,
- allYieldExpected +
- const <String>[
- r'^#4 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(allYield, allYieldExpected, debugInfoFilename);
-
- final noYieldsExpected = const <String>[
- r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
- r'^#1 noYields3 \(.*/utils.dart:54(:3)?\)$',
- r'^#2 noYields2 \(.*/utils.dart:50(:9)?\)$',
- r'^#3 noYields \(.*/utils.dart:46(:9)?\)$',
- ];
- await doTestAwait(
- noYields,
- noYieldsExpected +
- const <String>[
- r'^#4 doTestAwait ',
- r'^#5 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#6 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- noYields,
- noYieldsExpected +
- const <String>[
- r'^#4 doTestAwaitThen ',
- r'^#5 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#6 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(
- noYields,
- noYieldsExpected +
- const <String>[
- r'^#4 doTestAwaitCatchError ',
- r'^#5 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#6 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
-
- final mixedYieldsExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 mixedYields2 \(.*/utils.dart:66(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 mixedYields \(.*/utils.dart:61(:3)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- mixedYields,
- mixedYieldsExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- mixedYields,
- mixedYieldsExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(
- mixedYields, mixedYieldsExpected, debugInfoFilename);
-
- final syncSuffixExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 syncSuffix2 \(.*/utils.dart:82(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 syncSuffix \(.*/utils.dart:77(:3)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- syncSuffix,
- syncSuffixExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- syncSuffix,
- syncSuffixExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(
- syncSuffix, syncSuffixExpected, debugInfoFilename);
-
- final nonAsyncNoStackExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 nonAsyncNoStack1 \(.*/utils.dart:95(:36)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 nonAsyncNoStack \(.*/utils.dart:93(:35)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- nonAsyncNoStack,
- nonAsyncNoStackExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- nonAsyncNoStack,
- nonAsyncNoStackExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(
- nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename);
-
- final asyncStarThrowSyncExpected = const <String>[
- r'^#0 throwSync \(.+/utils.dart:16(:3)?\)$',
- r'^#1 asyncStarThrowSync \(.+/utils.dart:112(:11)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 awaitEveryAsyncStarThrowSync \(.+/utils.dart:104(:3)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- awaitEveryAsyncStarThrowSync,
- asyncStarThrowSyncExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- awaitEveryAsyncStarThrowSync,
- asyncStarThrowSyncExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(awaitEveryAsyncStarThrowSync,
- asyncStarThrowSyncExpected, debugInfoFilename);
-
- final asyncStarThrowAsyncExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 awaitEveryAsyncStarThrowAsync \(.+/utils.dart:117(:3)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- awaitEveryAsyncStarThrowAsync,
- asyncStarThrowAsyncExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- awaitEveryAsyncStarThrowAsync,
- asyncStarThrowAsyncExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(awaitEveryAsyncStarThrowAsync,
- asyncStarThrowAsyncExpected, debugInfoFilename);
-
- final listenAsyncStartExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$',
- r'^<asynchronous suspension>$',
- r'^#2 listenAsyncStarThrowAsync.<anonymous closure> \(.+/utils.dart(:0)?\)$',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
- await doTestAwaitThen(
- listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
- await doTestAwaitCatchError(
- listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
-
- final customErrorZoneExpected = const <String>[
- r'#0 throwSync \(.*/utils.dart:16(:3)?\)$',
- r'#1 allYield3 \(.*/utils.dart:39(:3)?\)$',
- r'<asynchronous suspension>$',
- r'#2 allYield2 \(.*/utils.dart:34(:3)?\)$',
- r'<asynchronous suspension>$',
- r'#3 allYield \(.*/utils.dart:29(:3)?\)$',
- r'<asynchronous suspension>$',
- r'#4 customErrorZone.<anonymous closure> \(.*/utils.dart:144(:5)?\)$',
- r'<asynchronous suspension>$',
- ];
- await doTestAwait(
- customErrorZone, customErrorZoneExpected, debugInfoFilename);
- await doTestAwaitThen(
- customErrorZone, customErrorZoneExpected, debugInfoFilename);
- await doTestAwaitCatchError(
- customErrorZone, customErrorZoneExpected, debugInfoFilename);
-
- final awaitTimeoutExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 Future.timeout.<anonymous closure> \(dart:async/future_impl.dart',
- r'^<asynchronous suspension>$',
- r'^#2 awaitTimeout ',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- awaitTimeout,
- awaitTimeoutExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- awaitTimeout,
- awaitTimeoutExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(
- awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
-
- final awaitWaitExpected = const <String>[
- r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^<asynchronous suspension>$',
- r'^#1 Future.wait.<anonymous closure> \(dart:async/future.dart',
- r'^<asynchronous suspension>$',
- r'^#2 awaitWait ',
- r'^<asynchronous suspension>$',
- ];
- await doTestAwait(
- awaitWait,
- awaitWaitExpected +
- const <String>[
- r'^#3 doTestAwait ',
- r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
- r'^<asynchronous suspension>$',
- r'^#5 main ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitThen(
- awaitWait,
- awaitWaitExpected +
- const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
- r'^<asynchronous suspension>$',
- ],
- debugInfoFilename);
- await doTestAwaitCatchError(awaitWait, awaitWaitExpected, debugInfoFilename);
-
+ // allYield
{
- final expect = const <String>[
+ final allYieldExpected = const <String>[
+ r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
+ r'^#1 allYield3 \(.*/utils.dart:39(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 allYield2 \(.*/utils.dart:34(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#3 allYield \(.*/utils.dart:29(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ allYield,
+ allYieldExpected +
+ const <String>[
+ r'^#4 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#5 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#6 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ allYield,
+ allYieldExpected +
+ const <String>[
+ r'^#4 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#5 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#6 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ allYield,
+ allYieldExpected +
+ const <String>[
+ r'^#4 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#5 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#6 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
+
+ // noYields
+ {
+ final noYieldsExpected = const <String>[
+ r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
+ r'^#1 noYields3 \(.*/utils.dart:54(:3)?\)$',
+ r'^#2 noYields2 \(.*/utils.dart:50(:9)?\)$',
+ r'^#3 noYields \(.*/utils.dart:46(:9)?\)$',
+ ];
+ await doTestAwait(
+ noYields,
+ noYieldsExpected +
+ const <String>[
+ r'^#4 doTestAwait ',
+ r'^#5 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#6 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ noYields,
+ noYieldsExpected +
+ const <String>[
+ r'^#4 doTestAwaitThen ',
+ r'^#5 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#6 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ noYields,
+ noYieldsExpected +
+ const <String>[
+ r'^#4 doTestAwaitCatchError ',
+ r'^#5 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#6 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
+
+ // mixedYields
+ {
+ final mixedYieldsExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 mixedYields2 \(.*/utils.dart:66(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 mixedYields \(.*/utils.dart:61(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ mixedYields,
+ mixedYieldsExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ mixedYields,
+ mixedYieldsExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ mixedYields,
+ mixedYieldsExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
+
+ // syncSuffix
+ {
+ final syncSuffixExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 syncSuffix2 \(.*/utils.dart:82(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 syncSuffix \(.*/utils.dart:77(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ syncSuffix,
+ syncSuffixExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ syncSuffix,
+ syncSuffixExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ syncSuffix,
+ syncSuffixExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
+
+ // nonAsyncNoStack
+ {
+ final nonAsyncNoStackExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 nonAsyncNoStack1 \(.*/utils.dart:95(:36)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 nonAsyncNoStack \(.*/utils.dart:93(:35)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ nonAsyncNoStack,
+ nonAsyncNoStackExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ nonAsyncNoStack,
+ nonAsyncNoStackExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ nonAsyncNoStack,
+ nonAsyncNoStackExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
+
+ // awaitEveryAsyncStarThrowSync
+ {
+ final asyncStarThrowSyncExpected = const <String>[
+ r'^#0 throwSync \(.+/utils.dart:16(:3)?\)$',
+ r'^#1 asyncStarThrowSync \(.+/utils.dart:112(:11)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 awaitEveryAsyncStarThrowSync \(.+/utils.dart:104(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ awaitEveryAsyncStarThrowSync,
+ asyncStarThrowSyncExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ awaitEveryAsyncStarThrowSync,
+ asyncStarThrowSyncExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ awaitEveryAsyncStarThrowSync,
+ asyncStarThrowSyncExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
+
+ // awaitEveryAsyncStarThrowAsync
+ {
+ final asyncStarThrowAsyncExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 awaitEveryAsyncStarThrowAsync \(.+/utils.dart:117(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ awaitEveryAsyncStarThrowAsync,
+ asyncStarThrowAsyncExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ awaitEveryAsyncStarThrowAsync,
+ asyncStarThrowAsyncExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ awaitEveryAsyncStarThrowAsync,
+ asyncStarThrowAsyncExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
+
+ // listenAsyncStarThrowAsync
+ {
+ final listenAsyncStartExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#2 listenAsyncStarThrowAsync.<anonymous closure> \(.+/utils.dart(:0)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
+ await doTestAwaitThen(
+ listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
+ await doTestAwaitCatchError(
+ listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename);
+ }
+
+ // customErrorZone
+ {
+ final customErrorZoneExpected = const <String>[
+ r'#0 throwSync \(.*/utils.dart:16(:3)?\)$',
+ r'#1 allYield3 \(.*/utils.dart:39(:3)?\)$',
+ r'<asynchronous suspension>$',
+ r'#2 allYield2 \(.*/utils.dart:34(:3)?\)$',
+ r'<asynchronous suspension>$',
+ r'#3 allYield \(.*/utils.dart:29(:3)?\)$',
+ r'<asynchronous suspension>$',
+ r'#4 customErrorZone.<anonymous closure> \(.*/utils.dart:144(:5)?\)$',
+ r'<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ customErrorZone, customErrorZoneExpected, debugInfoFilename);
+ await doTestAwaitThen(
+ customErrorZone, customErrorZoneExpected, debugInfoFilename);
+ await doTestAwaitCatchError(
+ customErrorZone, customErrorZoneExpected, debugInfoFilename);
+ }
+
+ // awaitTimeout
+ {
+ final awaitTimeoutExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 Future.timeout.<anonymous closure> \(dart:async/future_impl.dart',
+ r'^<asynchronous suspension>$',
+ r'^#2 awaitTimeout ',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ awaitTimeout,
+ awaitTimeoutExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ awaitTimeout,
+ awaitTimeoutExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ awaitTimeout,
+ awaitTimeoutExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
+
+ // awaitWait
+ {
+ final awaitWaitExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 Future.wait.<anonymous closure> \(dart:async/future.dart',
+ r'^<asynchronous suspension>$',
+ r'^#2 awaitWait ',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ awaitWait,
+ awaitWaitExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ awaitWait,
+ awaitWaitExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ awaitWait,
+ awaitWaitExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#4 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
+
+ // futureSyncWhenComplete
+ {
+ final expected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
r'^<asynchronous suspension>$',
];
await doTestAwait(
futureSyncWhenComplete,
- expect +
+ expected +
const <String>[
r'^#1 doTestAwait ',
r'^<asynchronous suspension>$',
@@ -984,13 +1151,72 @@
debugInfoFilename);
await doTestAwaitThen(
futureSyncWhenComplete,
- expect +
+ expected +
const <String>[
- r'^#1 doTestAwaitThen.<anonymous closure> ',
+ r'^#1 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#2 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#3 main ',
r'^<asynchronous suspension>$',
],
debugInfoFilename);
await doTestAwaitCatchError(
- futureSyncWhenComplete, expect, debugInfoFilename);
+ futureSyncWhenComplete,
+ expected +
+ const <String>[
+ r'^#1 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#2 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#3 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ }
+
+ // futureThen
+ {
+ final expected = const <String>[
+ r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$',
+ r'^#1 futureThen.<anonymous closure> ',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ futureThen,
+ expected +
+ const <String>[
+ r'^#2 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#3 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#4 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ futureThen,
+ expected +
+ const <String>[
+ r'^#2 doTestAwaitThen ',
+ r'^<asynchronous suspension>$',
+ r'^#3 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#4 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ futureThen,
+ expected +
+ const <String>[
+ r'^#2 doTestAwaitCatchError ',
+ r'^<asynchronous suspension>$',
+ r'^#3 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#4 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
}
}
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index e221513..134b26b 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -1042,7 +1042,20 @@
field->untag()->end_token_pos_ = d->ReadTokenPosition();
field->untag()->guarded_cid_ = d->ReadCid();
field->untag()->is_nullable_ = d->ReadCid();
- field->untag()->static_type_exactness_state_ = d->Read<int8_t>();
+ const int8_t static_type_exactness_state = d->Read<int8_t>();
+#if defined(TARGET_ARCH_X64)
+ field->untag()->static_type_exactness_state_ =
+ static_type_exactness_state;
+#else
+ // We might produce core snapshots using X64 VM and then consume
+ // them in IA32 or ARM VM. In which case we need to simply ignore
+ // static type exactness state written into snapshot because non-X64
+ // builds don't have this feature enabled.
+ // TODO(dartbug.com/34170) Support other architectures.
+ USE(static_type_exactness_state);
+ field->untag()->static_type_exactness_state_ =
+ StaticTypeExactnessState::NotTracking().Encode();
+#endif // defined(TARGET_ARCH_X64)
#if !defined(DART_PRECOMPILED_RUNTIME)
field->untag()->kernel_offset_ = d->Read<uint32_t>();
#endif
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 185af0a..6822001 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -196,6 +196,8 @@
V(_Utf8Decoder, _scan, Utf8DecoderScan, 0xb35ced99) \
V(_Future, timeout, FutureTimeout, 0x6ad7d1ef) \
V(Future, wait, FutureWait, 0x264aacc2) \
+ V(_RootZone, runUnary, RootZoneRunUnary, 0x76e41d34) \
+ V(_FutureListener, handleValue, FutureListenerHandleValue, 0x73894d16) \
// List of intrinsics:
// (class-name, function-name, intrinsification method, fingerprint).
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 7f6775d..51975f3 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1848,7 +1848,7 @@
/*skip_frames=*/0, &on_sync_frame,
&has_async);
- // If the entire stack is sync, return no trace.
+ // If the entire stack is sync, return no (async) trace.
if (!has_async) {
return nullptr;
}
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 5a6c5a9..96ad60d 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -528,6 +528,19 @@
frames_.Unpoison();
}
+StackFrameIterator::StackFrameIterator(const StackFrameIterator& orig)
+ : validate_(orig.validate_),
+ entry_(orig.thread_),
+ exit_(orig.thread_),
+ frames_(orig.thread_),
+ current_frame_(nullptr),
+ thread_(orig.thread_) {
+ frames_.fp_ = orig.frames_.fp_;
+ frames_.sp_ = orig.frames_.sp_;
+ frames_.pc_ = orig.frames_.pc_;
+ frames_.Unpoison();
+}
+
StackFrame* StackFrameIterator::NextFrame() {
// When we are at the start of iteration after having created an
// iterator object, current_frame_ will be NULL as we haven't seen
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index 92f864f..6969642 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -236,6 +236,8 @@
Thread* thread,
CrossThreadPolicy cross_thread_policy);
+ StackFrameIterator(const StackFrameIterator& orig);
+
// Checks if a next frame exists.
bool HasNextFrame() const { return frames_.fp_ != 0; }
@@ -300,7 +302,6 @@
Thread* thread_;
friend class ProfilerDartStackWalker;
- DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
};
// Iterator for iterating over all dart frames (skips over exit frames,
@@ -339,6 +340,8 @@
thread,
cross_thread_policy) {}
+ DartFrameIterator(const DartFrameIterator& orig) : frames_(orig.frames_) {}
+
// Get next dart frame.
StackFrame* NextFrame() {
StackFrame* frame = frames_.NextFrame();
@@ -350,8 +353,6 @@
private:
StackFrameIterator frames_;
-
- DISALLOW_COPY_AND_ASSIGN(DartFrameIterator);
};
// Iterator for iterating over all inlined dart functions in an optimized
diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc
index ae8849a..a231568 100644
--- a/runtime/vm/stack_trace.cc
+++ b/runtime/vm/stack_trace.cc
@@ -10,11 +10,18 @@
namespace dart {
-// Keep in sync with
-// sdk/lib/async/stream_controller.dart:_StreamController._STATE_SUBSCRIBED.
+// Keep in sync with:
+// - sdk/lib/async/stream_controller.dart:_StreamController._STATE_SUBSCRIBED.
const intptr_t k_StreamController__STATE_SUBSCRIBED = 1;
-// sdk/lib/async/future_impl.dart:_FutureListener.stateWhencomplete.
-const intptr_t k_FutureListener_stateWhencomplete = 8;
+// - sdk/lib/async/future_impl.dart:_FutureListener.stateThen.
+const intptr_t k_FutureListener_stateThen = 1;
+// - sdk/lib/async/future_impl.dart:_FutureListener.stateCatchError.
+const intptr_t k_FutureListener_stateCatchError = 2;
+// - sdk/lib/async/future_impl.dart:_FutureListener.stateWhenComplete.
+const intptr_t k_FutureListener_stateWhenComplete = 8;
+
+// Keep in sync with sdk/lib/async/future_impl.dart:_FutureListener.handleValue.
+const intptr_t kNumArgsFutureListenerHandleValue = 1;
// Find current yield index from async closure.
// Async closures contains a variable, :await_jump_var that holds the index into
@@ -140,21 +147,19 @@
ASSERT(!future.IsNull());
ASSERT(future.GetClassId() == future_impl_class.id());
- listener_ = Instance::Cast(future).GetField(future_result_or_listeners_field);
- if (listener_.GetClassId() != future_listener_class.id()) {
+ // Since this function is recursive, we have to keep a local ref.
+ auto& listener = Object::Handle(
+ Instance::Cast(future).GetField(future_result_or_listeners_field));
+ if (listener.GetClassId() != future_listener_class.id()) {
return Closure::null();
}
- // If the _FutureListener is a whenComplete listener, follow the Future being
- // completed, `result`, instead of the dangling whenComplete `callback`.
- state_ = Instance::Cast(listener_).GetField(future_listener_state_field);
- ASSERT(state_.IsSmi());
- if (Smi::Cast(state_).Value() == k_FutureListener_stateWhencomplete) {
- future_ = Instance::Cast(listener_).GetField(future_listener_result_field);
- return GetCallerInFutureImpl(future_);
+ callback_ = GetCallerInFutureListener(listener);
+ if (callback_.IsInstance() && !callback_.IsNull()) {
+ return Closure::Cast(callback_).ptr();
}
- callback_ = Instance::Cast(listener_).GetField(callback_field);
+ callback_ = Instance::Cast(listener).GetField(callback_field);
// This happens for e.g.: await f().catchError(..);
if (callback_.IsNull()) {
return Closure::null();
@@ -221,22 +226,46 @@
UNREACHABLE(); // If no onData is found we have a bug.
}
+ClosurePtr CallerClosureFinder::GetCallerInFutureListener(
+ const Object& future_listener) {
+ ASSERT(future_listener.GetClassId() == future_listener_class.id());
+
+ state_ =
+ Instance::Cast(future_listener).GetField(future_listener_state_field);
+
+ auto value = Smi::Cast(state_).Value();
+ // If the _FutureListener is a `then`, `catchError`, or `whenComplete`
+ // listener, follow the Future being completed, `result`, instead of the
+ // dangling whenComplete `callback`.
+ if (value == k_FutureListener_stateThen ||
+ value == k_FutureListener_stateCatchError ||
+ value == k_FutureListener_stateWhenComplete) {
+ future_ =
+ Instance::Cast(future_listener).GetField(future_listener_result_field);
+ return GetCallerInFutureImpl(future_);
+ }
+
+ return Closure::null();
+}
+
ClosurePtr CallerClosureFinder::FindCaller(const Closure& receiver_closure) {
receiver_function_ = receiver_closure.function();
receiver_context_ = receiver_closure.context();
if (receiver_function_.IsAsyncClosure()) {
return FindCallerInAsyncClosure(receiver_context_);
- } else if (receiver_function_.IsAsyncGenClosure()) {
+ }
+ if (receiver_function_.IsAsyncGenClosure()) {
return FindCallerInAsyncGenClosure(receiver_context_);
- } else if (receiver_function_.IsLocalFunction()) {
+ }
+ if (receiver_function_.IsLocalFunction()) {
parent_function_ = receiver_function_.parent_function();
if (parent_function_.recognized_kind() ==
MethodRecognizer::kFutureTimeout) {
context_entry_ = receiver_context_.At(Context::kFutureTimeoutFutureIndex);
return GetCallerInFutureImpl(context_entry_);
- } else if (parent_function_.recognized_kind() ==
- MethodRecognizer::kFutureWait) {
+ }
+ if (parent_function_.recognized_kind() == MethodRecognizer::kFutureWait) {
receiver_context_ = receiver_context_.parent();
ASSERT(!receiver_context_.IsNull());
context_entry_ = receiver_context_.At(Context::kFutureWaitFutureIndex);
@@ -300,6 +329,114 @@
UNREACHABLE();
}
+ClosurePtr StackTraceUtils::ClosureFromFrameFunction(
+ Zone* zone,
+ CallerClosureFinder* caller_closure_finder,
+ const DartFrameIterator& frames,
+ StackFrame* frame,
+ bool* skip_frame,
+ bool* is_async) {
+ auto& closure = Closure::Handle(zone);
+ auto& function = Function::Handle(zone);
+
+ function = frame->LookupDartFunction();
+ if (function.IsNull()) {
+ return Closure::null();
+ }
+
+ if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
+ {
+ NoSafepointScope nsp;
+
+ // Next, look up caller's closure on the stack and walk backwards
+ // through the yields.
+ ObjectPtr* last_caller_obj =
+ reinterpret_cast<ObjectPtr*>(frame->GetCallerSp());
+ closure = FindClosureInFrame(last_caller_obj, function);
+
+ // If this async function hasn't yielded yet, we're still dealing with a
+ // normal stack. Continue to next frame as usual.
+ if (!caller_closure_finder->IsRunningAsync(closure)) {
+ return Closure::null();
+ }
+ }
+
+ *is_async = true;
+
+ // Skip: Already handled this as a sync. frame.
+ return caller_closure_finder->FindCaller(closure);
+ }
+
+ // May have been called from `_FutureListener.handleValue`, which means its
+ // receiver holds the Future chain.
+ if (function.recognized_kind() == MethodRecognizer::kRootZoneRunUnary) {
+ DartFrameIterator future_frames(frames);
+ frame = future_frames.NextFrame();
+ function = frame->LookupDartFunction();
+ if (function.recognized_kind() !=
+ MethodRecognizer::kFutureListenerHandleValue) {
+ return Closure::null();
+ }
+ }
+ if (function.recognized_kind() ==
+ MethodRecognizer::kFutureListenerHandleValue) {
+ *is_async = true;
+ *skip_frame = true;
+
+ // The _FutureListener receiver is at the top of the previous frame, right
+ // before the arguments to the call.
+ Object& receiver =
+ Object::Handle(*(reinterpret_cast<ObjectPtr*>(frame->GetCallerSp()) +
+ kNumArgsFutureListenerHandleValue));
+
+ return caller_closure_finder->GetCallerInFutureListener(receiver);
+ }
+
+ return Closure::null();
+}
+
+void StackTraceUtils::UnwindAwaiterChain(
+ Zone* zone,
+ const GrowableObjectArray& code_array,
+ const GrowableObjectArray& pc_offset_array,
+ CallerClosureFinder* caller_closure_finder,
+ ClosurePtr leaf_closure) {
+ auto& code = Code::Handle(zone);
+ auto& function = Function::Handle(zone);
+ auto& closure = Closure::Handle(zone, leaf_closure);
+ auto& pc_descs = PcDescriptors::Handle(zone);
+ auto& offset = Smi::Handle(zone);
+
+ // Inject async suspension marker.
+ code_array.Add(StubCode::AsynchronousGapMarker());
+ offset = Smi::New(0);
+ pc_offset_array.Add(offset);
+
+ // Traverse the trail of async futures all the way up.
+ for (; !closure.IsNull();
+ closure = caller_closure_finder->FindCaller(closure)) {
+ function = closure.function();
+ if (function.IsNull()) {
+ continue;
+ }
+ // In hot-reload-test-mode we sometimes have to do this:
+ code = function.EnsureHasCode();
+ RELEASE_ASSERT(!code.IsNull());
+ code_array.Add(code);
+ pc_descs = code.pc_descriptors();
+ offset = Smi::New(FindPcOffset(pc_descs, GetYieldIndex(closure)));
+ // Unlike other sources of PC offsets, the offset may be 0 here if we
+ // reach a non-async closure receiving the yielded value.
+ ASSERT(offset.Value() >= 0);
+ pc_offset_array.Add(offset);
+
+ // Inject async suspension marker.
+ code_array.Add(StubCode::AsynchronousGapMarker());
+ offset = Smi::New(0);
+ pc_offset_array.Add(offset);
+ }
+}
+
void StackTraceUtils::CollectFramesLazy(
Thread* thread,
const GrowableObjectArray& code_array,
@@ -320,13 +457,10 @@
return;
}
- auto& function = Function::Handle(zone);
auto& code = Code::Handle(zone);
auto& offset = Smi::Handle(zone);
- auto& closure = Closure::Handle(zone);
CallerClosureFinder caller_closure_finder(zone);
- auto& pc_descs = PcDescriptors::Handle();
// Start by traversing the sync. part of the stack.
for (; frame != nullptr; frame = frames.NextFrame()) {
@@ -335,79 +469,36 @@
continue;
}
- function = frame->LookupDartFunction();
+ // If we encounter a known part of the async/Future mechanism, unwind the
+ // awaiter chain from the closures.
+ bool skip_frame = false;
+ bool is_async = false;
+ auto closure_ptr = ClosureFromFrameFunction(
+ zone, &caller_closure_finder, frames, frame, &skip_frame, &is_async);
- // Add the current synchronous frame.
- code = frame->LookupDartCode();
- ASSERT(function.ptr() == code.function());
- code_array.Add(code);
- const intptr_t pc_offset = frame->pc() - code.PayloadStart();
- ASSERT(pc_offset > 0 && pc_offset <= code.Size());
- offset = Smi::New(pc_offset);
- pc_offset_array.Add(offset);
- if (on_sync_frames != nullptr) {
- (*on_sync_frames)(frame);
+ // This isn't a special (async) frame we should skip.
+ if (!skip_frame) {
+ // Add the current synchronous frame.
+ code = frame->LookupDartCode();
+ code_array.Add(code);
+ const intptr_t pc_offset = frame->pc() - code.PayloadStart();
+ ASSERT(pc_offset > 0 && pc_offset <= code.Size());
+ offset = Smi::New(pc_offset);
+ pc_offset_array.Add(offset);
+ // Callback for sync frame.
+ if (on_sync_frames != nullptr) {
+ (*on_sync_frames)(frame);
+ }
}
- // Either continue the loop (sync-async case) or find all await'ers and
- // return.
- if (!function.IsNull() &&
- (function.IsAsyncClosure() || function.IsAsyncGenClosure())) {
+ // This frame is running async.
+ // Note: The closure might still be null in case it's an unawaited future.
+ if (is_async) {
+ UnwindAwaiterChain(zone, code_array, pc_offset_array,
+ &caller_closure_finder, closure_ptr);
if (has_async != nullptr) {
*has_async = true;
}
-
- {
- NoSafepointScope nsp;
-
- // Next, look up caller's closure on the stack and walk backwards
- // through the yields.
- ObjectPtr* last_caller_obj =
- reinterpret_cast<ObjectPtr*>(frame->GetCallerSp());
- closure = FindClosureInFrame(last_caller_obj, function);
-
- // If this async function hasn't yielded yet, we're still dealing with a
- // normal stack. Continue to next frame as usual.
- if (!caller_closure_finder.IsRunningAsync(closure)) {
- continue;
- }
- }
-
- // Inject async suspension marker.
- code_array.Add(StubCode::AsynchronousGapMarker());
- offset = Smi::New(0);
- pc_offset_array.Add(offset);
-
- // Skip: Already handled this frame's function above.
- closure = caller_closure_finder.FindCaller(closure);
-
- // Traverse the trail of async futures all the way up.
- for (; !closure.IsNull();
- closure = caller_closure_finder.FindCaller(closure)) {
- function = closure.function();
- // In hot-reload-test-mode we sometimes have to do this:
- if (!function.HasCode()) {
- function.EnsureHasCode();
- }
- if (function.HasCode()) {
- code = function.CurrentCode();
- code_array.Add(code);
- pc_descs = code.pc_descriptors();
- offset = Smi::New(FindPcOffset(pc_descs, GetYieldIndex(closure)));
- } else {
- UNREACHABLE();
- }
- // Unlike other sources of PC offsets, the offset may be 0 here if we
- // reach a non-async closure receiving the yielded value.
- ASSERT(offset.Value() >= 0);
- pc_offset_array.Add(offset);
-
- // Inject async suspension marker.
- code_array.Add(StubCode::AsynchronousGapMarker());
- offset = Smi::New(0);
- pc_offset_array.Add(offset);
- }
-
// Ignore the rest of the stack; already unwound all async calls.
return;
}
diff --git a/runtime/vm/stack_trace.h b/runtime/vm/stack_trace.h
index 215da83..75ba724 100644
--- a/runtime/vm/stack_trace.h
+++ b/runtime/vm/stack_trace.h
@@ -21,6 +21,8 @@
ClosurePtr GetCallerInFutureImpl(const Object& future_);
+ ClosurePtr GetCallerInFutureListener(const Object& future_listener);
+
ClosurePtr FindCallerInAsyncClosure(const Context& receiver_context);
ClosurePtr FindCallerInAsyncGenClosure(const Context& receiver_context);
@@ -61,6 +63,8 @@
Field& state_field;
Field& on_data_field;
Field& state_data_field;
+
+ DISALLOW_COPY_AND_ASSIGN(CallerClosureFinder);
};
class StackTraceUtils : public AllStatic {
@@ -69,6 +73,20 @@
static ClosurePtr FindClosureInFrame(ObjectPtr* last_object_in_caller,
const Function& function);
+ static ClosurePtr ClosureFromFrameFunction(
+ Zone* zone,
+ CallerClosureFinder* caller_closure_finder,
+ const DartFrameIterator& frames,
+ StackFrame* frame,
+ bool* skip_frame,
+ bool* is_async);
+
+ static void UnwindAwaiterChain(Zone* zone,
+ const GrowableObjectArray& code_array,
+ const GrowableObjectArray& pc_offset_array,
+ CallerClosureFinder* caller_closure_finder,
+ ClosurePtr leaf_closure);
+
/// Collects all frames on the current stack until an async/async* frame is
/// hit which has yielded before (i.e. is not in sync-async case).
///
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index df8a347..a9f2b80 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -63,18 +63,19 @@
}
class _FutureListener<S, T> {
+ // Keep in sync with sdk/runtime/vm/stack_trace.cc.
static const int maskValue = 1;
static const int maskError = 2;
static const int maskTestError = 4;
- static const int maskWhencomplete = 8;
+ static const int maskWhenComplete = 8;
static const int stateChain = 0;
static const int stateThen = maskValue;
static const int stateThenOnerror = maskValue | maskError;
- static const int stateCatcherror = maskError;
- static const int stateCatcherrorTest = maskError | maskTestError;
- static const int stateWhencomplete = maskWhencomplete;
+ static const int stateCatchError = maskError;
+ static const int stateCatchErrorTest = maskError | maskTestError;
+ static const int stateWhenComplete = maskWhenComplete;
static const int maskType =
- maskValue | maskError | maskTestError | maskWhencomplete;
+ maskValue | maskError | maskTestError | maskWhenComplete;
static const int stateIsAwait = 16;
// Listeners on the same future are linked through this link.
@@ -109,18 +110,18 @@
stateIsAwait;
_FutureListener.catchError(this.result, this.errorCallback, this.callback)
- : state = (callback == null) ? stateCatcherror : stateCatcherrorTest;
+ : state = (callback == null) ? stateCatchError : stateCatchErrorTest;
_FutureListener.whenComplete(this.result, this.callback)
: errorCallback = null,
- state = stateWhencomplete;
+ state = stateWhenComplete;
_Zone get _zone => result._zone;
bool get handlesValue => (state & maskValue != 0);
bool get handlesError => (state & maskError != 0);
- bool get hasErrorTest => (state & maskType == stateCatcherrorTest);
- bool get handlesComplete => (state & maskType == stateWhencomplete);
+ bool get hasErrorTest => (state & maskType == stateCatchErrorTest);
+ bool get handlesComplete => (state & maskType == stateWhenComplete);
bool get isAwait => (state & stateIsAwait != 0);
FutureOr<T> Function(S) get _onValue {
@@ -148,6 +149,8 @@
return _onError != null;
}
+ @pragma("vm:recognized", "other")
+ @pragma("vm:never-inline")
FutureOr<T> handleValue(S sourceResult) {
return _zone.runUnary<FutureOr<T>, S>(_onValue, sourceResult);
}
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index 4f0873d..5400814 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -1608,6 +1608,7 @@
return _rootRun(null, null, this, f);
}
+ @pragma("vm:recognized", "other")
R runUnary<R, T>(R f(T arg), T arg) {
if (identical(Zone._current, _rootZone)) return f(arg);
return _rootRunUnary(null, null, this, f, arg);
diff --git a/tools/VERSION b/tools/VERSION
index 9f61f00..e07d271 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 240
+PRERELEASE 241
PRERELEASE_PATCH 0
\ No newline at end of file