blob: 27615c971c720cc09bca6bcfac40015d42f01be7 [file] [log] [blame]
// Copyright (c) 2023, 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.
/// @assertion At runtime, whenever the runtime semantics say to call a member
/// or access a record field, if a previous call or access with that same
/// invocation key has already been evaluated, we reuse the result.
/// ...
/// Given a set of patterns s matching a value expression v, we bind an
/// invocation key to each member invocation and record field access in s like
/// so:
/// 1. Let i be an invocation key with no parent, no extension type, named this,
/// with an empty argument list. This is the root node of the invocation key
/// tree and represents the matched value itself.
/// 2. For each pattern p in s with parent invocation i, bind invocation keys to
/// it and its subpatterns using the following procedure:
/// To bind invocation keys in a pattern p using parent invocation i:
/// ...
/// List:
/// i. Bind i : ("length", []) to the length getter invocation.
/// ii. For each element subpattern s:
/// a. If s is a rest element:
/// a. Let e be i : ("sublist()", [h, t]) where h is the number of elements
/// preceding s and t is the number of elements following it.
/// b. Bind e to the sublist() invocation for s.
/// b. Else if s precedes a rest element (or there is no rest element):
/// a. Let e be i : ("[]", [index]) where index is the zero-based index of
/// this element subpattern.
/// b. Bind e to the [] invocation for s.
/// c. Else s is a non-rest element after the rest element:
/// a. Let e be i : ("tail[]", [index]) where index is the zero-based index
/// of this element subpattern.
/// b. Bind e to the [] invocation for s.
/// d. Bind invocations in the element subpattern using parent e.
///
/// @description Checks that for a list pattern invocation keys with different
/// parent keys are invoked
/// @author sgrekhov22@gmail.com
import "../../Utils/expect.dart";
import "patterns_collections_lib.dart";
String test1(Object o) {
switch (o) {
case <List<int>>[[1], [3]]: // Expect call length, [0], length, [0]
return "match-1";
case <List<int>>[[1], [_]]: // Expect no new calls
return "match-2";
default:
return "no match";
}
}
String test2(Object o) =>
switch (o) {
<List<int>>[[1], [3]] => "match-1",
<List<int>>[[1], [_]] => "match-2",
_ => "no match"
};
main() {
final ml = MyList<int>([1]);
Expect.equals("match-2", test1([ml, ml]));
Expect.equals("length;[0];length;[0];", ml.log);
ml.clearLog();
Expect.equals("match-2", test2([ml, ml]));
Expect.equals("length;[0];length;[0];", ml.log);
ml.clearLog();
}