blob: f2489821ce15c3e1842a9366385701ee2769b33d [file] [log] [blame]
// Copyright (c) 2015, 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.
// @dart = 2.9
import "dart:async";
import "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";
class Tracer {
final String expected;
final String name;
int counter = 0;
Tracer(this.expected, [this.name]);
void trace(msg) {
Expect.equals(expected[counter], msg);
counter++;
}
void done() {
Expect.equals(expected.length, counter, "Received too few traces");
}
}
foo1(Tracer tracer) async {
try {
tracer.trace("a");
// This await forces dart2js to rewrite the try into a state machine
// instead of relying on the existing structure.
await new Future.value(3); //# forceAwait: ok
tracer.trace("b");
throw "Error";
} catch (error) {
tracer.trace("c");
Expect.equals("Error", error);
throw "Error2";
tracer.trace("d");
} finally {
tracer.trace("e");
}
tracer.trace("f");
}
foo2(Tracer tracer) async {
try {
tracer.trace("a");
await new Future.value(3); //# forceAwait: continued
tracer.trace("b");
throw "Error";
tracer.trace("c");
} catch (error) {
tracer.trace("d");
Expect.equals("Error", error);
await new Future.error("Error2");
} finally {
tracer.trace("e");
}
tracer.trace("f");
}
foo3(Tracer tracer) async {
try {
tracer.trace("a");
await new Future.value(3); //# forceAwait: continued
tracer.trace("b");
throw "Error";
tracer.trace("c");
} catch (error) {
Expect.equals("Error", error);
tracer.trace("d");
return;
} finally {
tracer.trace("e");
}
tracer.trace("f");
}
foo4(Tracer tracer) async {
try {
try {
await new Future.value(3); //# forceAwait: continued
tracer.trace("a");
throw "Error";
} catch (error) {
tracer.trace("b");
Expect.equals("Error", error);
throw "Error2";
}
} catch (error) {
Expect.equals("Error2", error);
tracer.trace("c");
}
tracer.trace("d");
}
foo5(Tracer tracer) async {
try {
tracer.trace("a");
try {
await new Future.value(3); //# forceAwait: continued
tracer.trace("b");
throw "Error";
} catch (error) {
tracer.trace("c");
Expect.equals("Error", error);
throw "Error2";
}
} finally {
tracer.trace("d");
}
tracer.trace("e");
}
foo6(Tracer tracer) async {
try {
try {
await new Future.value(3); //# forceAwait: continued
tracer.trace("a");
throw "Error";
} catch (error) {
tracer.trace("b");
Expect.equals("Error", error);
throw "Error2";
} finally {
tracer.trace("c");
throw "Error3";
}
} catch (error) {
tracer.trace("d");
Expect.equals("Error3", error);
}
tracer.trace("e");
}
foo7(Tracer tracer) async {
try {
try {
await new Future.value(3); //# forceAwait: continued
tracer.trace("a");
throw "Error";
} catch (error) {
Expect.equals("Error", error);
tracer.trace("b");
throw "Error2";
} finally {
tracer.trace("c");
throw "Error3";
}
} finally {
tracer.trace("d");
}
tracer.trace("e");
}
foo8(Tracer tracer) async {
try {
try {
await new Future.value(3); //# forceAwait: continued
tracer.trace("a");
throw "Error";
} catch (error) {
Expect.equals("Error", error);
tracer.trace("b");
return;
} finally {
tracer.trace("c");
throw "Error3";
}
} finally {
tracer.trace("d");
}
tracer.trace("e");
}
foo9(Tracer tracer) async {
try {
while (true) {
try {
await new Future.value(3); //# forceAwait: continued
tracer.trace("a");
throw "Error";
} catch (error) {
Expect.equals("Error", error);
tracer.trace("b");
return;
} finally {
tracer.trace("c");
break;
}
tracer.trace("d");
}
} finally {
tracer.trace("e");
}
tracer.trace("f");
}
foo10(Tracer tracer) async {
try {
int i = 0;
while (true) {
try {
try {
tracer.trace("a");
throw "Error";
} catch (error) {
tracer.trace("b");
try {
await new Future.value(3); // //# forceAwait: continued
throw "Error2";
} catch (error) {
tracer.trace("c");
} finally {
tracer.trace("d");
}
tracer.trace("e");
throw "Error3";
} finally {
tracer.trace("f");
// Continue and breaks 'eats' Error3.
if (i == 0) continue;
if (i == 1) break;
}
} finally {
tracer.trace("g");
i++;
}
}
} finally {
tracer.trace("h");
}
tracer.trace("i");
}
foo11(Tracer tracer) async {
try {
bool firstTime = true;
while (true) {
tracer.trace("a");
if (firstTime) {
try {
await new Future.value(3); //# forceAwait: continued
tracer.trace("b");
throw "Error";
} catch (error) {
Expect.equals("Error", error);
tracer.trace("c");
firstTime = false;
continue;
} finally {
tracer.trace("d");
}
} else {
tracer.trace("e");
return;
}
}
} finally {
tracer.trace("f");
}
tracer.trace("g");
}
foo12(Tracer tracer) async {
try {
bool firstTime = true;
while (true) {
tracer.trace("a");
if (firstTime) {
try {
await new Future.value(3); //# forceAwait: continued
tracer.trace("b");
throw "Error";
} catch (error) {
Expect.equals("Error", error);
tracer.trace("c");
firstTime = false;
continue;
} finally {
tracer.trace("d");
break;
}
} else {
tracer.trace("e");
return;
}
}
} finally {
tracer.trace("f");
}
tracer.trace("g");
}
foo13(Tracer tracer) async {
try {
try {
tracer.trace("a");
return;
} catch (error) {
tracer.trace("b");
} finally {
tracer.trace("c");
try {
try {
await new Future.value(3); // //# forceAwait: continued
tracer.trace("d");
throw "Error";
} finally {
tracer.trace("e");
}
} finally {
tracer.trace("f");
}
}
} finally {
tracer.trace("g");
}
tracer.trace("h");
}
foo14(Tracer tracer) async {
try {
try {
tracer.trace("a");
throw "Error";
} catch (error) {
tracer.trace("b");
try {
await new Future.value(3); // //# forceAwait: continued
throw "Error2";
} catch (error) {
tracer.trace("c");
} finally {
tracer.trace("d");
}
tracer.trace("e");
throw "Error3";
} finally {
tracer.trace("f");
}
} finally {
tracer.trace("g");
}
tracer.trace("h");
}
foo15(Tracer tracer) async {
try {
try {
tracer.trace("a");
throw "Error";
} catch (error) {
tracer.trace("b");
try {
await new Future.value(3); // //# forceAwait: continued
throw "Error2";
} catch (error) {
tracer.trace("c");
} finally {
tracer.trace("d");
}
tracer.trace("e");
throw "Error3";
} finally {
tracer.trace("f");
return;
}
} finally {
tracer.trace("g");
}
tracer.trace("h");
}
foo16(Tracer tracer) async {
try {
try {
tracer.trace("a");
throw "Error";
} catch (error) {
tracer.trace("b");
try {
await new Future.value(3); // //# forceAwait: continued
throw "Error2";
} catch (error) {
tracer.trace("c");
} finally {
tracer.trace("d");
return;
}
tracer.trace("e");
throw "Error3";
} finally {
tracer.trace("f");
}
} finally {
tracer.trace("g");
}
tracer.trace("h");
}
foo17(Tracer tracer) async {
try {
tracer.trace("a");
} finally {
try {
tracer.trace("b");
throw "Error";
} catch (error) {
await new Future.value(3); // //# forceAwait: continued
Expect.equals("Error", error);
tracer.trace("c");
} finally {
tracer.trace("d");
}
tracer.trace("e");
}
tracer.trace("f");
}
foo18(Tracer tracer) async {
try {
tracer.trace("a");
} finally {
try {
tracer.trace("b");
} finally {
await new Future.value(3); // //# forceAwait: continued
tracer.trace("c");
}
tracer.trace("d");
}
tracer.trace("e");
}
runTest(expectedTrace, fun, [expectedError]) async {
Tracer tracer = new Tracer(expectedTrace, expectedTrace);
try {
await fun(tracer);
} catch (error) {
Expect.equals(expectedError, error);
tracer.trace("X");
}
tracer.done();
}
test() async {
await runTest("abceX", foo1, "Error2");
await runTest("abdeX", foo2, "Error2");
await runTest("abde", foo3);
await runTest("abcd", foo4);
await runTest("abcdX", foo5, "Error2");
await runTest("abcde", foo6);
await runTest("abcdX", foo7, "Error3");
await runTest("abcdX", foo8, "Error3");
await runTest("abcef", foo9);
await runTest("abcdefgabcdefghi", foo10);
await runTest("abcdaef", foo11);
await runTest("abcdfg", foo12);
await runTest("acdefgX", foo13, "Error");
await runTest("abcdefgX", foo14, "Error3");
await runTest("abcdefgX", foo14, "Error3");
await runTest("abcdefg", foo15);
await runTest("abcdfg", foo16);
await runTest("abcdef", foo17);
await runTest("abcde", foo18);
}
void main() {
asyncTest(test);
}