// Copyright (c) 2012, 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 "package:expect/expect.dart";

// Test cascades, issues 7494 (vm), 7689 (dart2js).

main() {
  var a = new Element(null);
  Expect.equals(1, a.path0.length);
  Expect.equals(a, a.path0[0]);

  // Issue 7693: e0 ? e1 : e2..f() parses as (e0 ? e1 : e2)..f().
  Expect.equals(2, a.path1.length);
  Expect.equals(a, a.path1[0]);
  Expect.equals(a, a.path1[1]);

  Expect.equals(1, a.path2.length); // NPE.

  var b = new Element(a);
  Expect.equals(2, b.path0.length);
  Expect.equals(a, b.path0[0]);
  Expect.equals(b, b.path0[1]);

  Expect.equals(3, b.path1.length);
  Expect.equals(a, b.path1[0]);
  Expect.equals(a, b.path1[1]);
  Expect.equals(b, b.path1[2]);

  Expect.equals(2, b.path2.length); // NPE.

  // Regression test for dartdevc comma expressions (js_ast printer did not
  // generate parentheses around the comma expression).
  var expectedList = [3, 2, 1];
  for (var actual in expectedList.toList()..sort()) {
    Expect.equals(
        expectedList.removeLast(), actual, "list items should be sorted");
  }
}

class Element {
  final Element parent;

  Element(this.parent);

  List<Element> get path0 {
    if (parent == null) {
      return <Element>[this];
    } else {
      return parent.path0..add(this);
    }
  }

  List<Element> get path1 {
    return (parent == null) ? <Element>[this] : parent.path1
      ..add(this);
  }

  List<Element> get path2 {
    return (parent == null) ? <Element>[this] : (parent.path2..add(this));
  }
}
