| // 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); |
| } |