| // 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. |
| |
| // Derived from co19/LanguageFeatures/Patterns/invocation_keys_A08_t01.dart |
| |
| import "dart:collection"; |
| |
| bool get hasUnsoundNullSafety => const <Null>[] is List<Object>; |
| |
| String unsoundResult = "containsKey(key1);" |
| "[key1];" |
| "containsKey(key2);" |
| "[key2];"; |
| |
| String soundResult = "[key1];" |
| "[key2];"; |
| |
| class MyMap<K, V> extends MapBase<K, V> { |
| Map<K, V> _inner; |
| String log = ""; |
| |
| MyMap(this._inner); |
| |
| @override |
| operator [](Object? key) { |
| log += "[$key];"; |
| return _inner[key]; |
| } |
| |
| @override |
| void operator []=(key, value) { |
| log += "[$key]=$value;"; |
| _inner[key] = value; |
| } |
| |
| @override |
| void clear() { |
| log += "clear();"; |
| _inner.clear(); |
| } |
| |
| @override |
| Iterable<K> get keys { |
| log += "keys;"; |
| return _inner.keys; |
| } |
| |
| @override |
| remove(Object? key) { |
| log += "remove($key);"; |
| return _inner.remove(key); |
| } |
| |
| @override |
| int get length { |
| log += "length;"; |
| return _inner.length; |
| } |
| |
| @override |
| bool containsKey(Object? key) { |
| log += "containsKey($key);"; |
| return _inner.containsKey(key); |
| } |
| |
| void clearLog() { |
| log = ""; |
| } |
| } |
| |
| String test1(Object o) { |
| switch (o) { |
| case <String, int>{"key1": 1, "key2": 3}: // Expect call [key1], [key2] |
| return "match-2"; |
| case <String, int>{"key1": 1, "key2": 2}: // Expect no additional calls |
| return "match-3"; |
| default: |
| return "no match"; |
| } |
| } |
| |
| String test2(Object o) => switch (o) { |
| <String, int>{"key1": 1, "key2": 3} => "match-2", |
| <String, int>{"key1": 1, "key2": 2} => "match-3", |
| _ => "no match" |
| }; |
| |
| main() { |
| final map = MyMap<String, int>({"key1": 1, "key2": 2}); |
| expect("match-3", test1(map)); |
| expect(hasUnsoundNullSafety ? unsoundResult : soundResult, map.log); |
| map.clearLog(); |
| |
| expect("match-3", test2(map)); |
| expect(hasUnsoundNullSafety ? unsoundResult : soundResult, map.log); |
| map.clearLog(); |
| |
| var {"key1": x1, "key2": x2} = map; |
| expect(hasUnsoundNullSafety ? unsoundResult : soundResult, map.log); |
| map.clearLog(); |
| |
| final {"key1": y1, "key2": y2} = map; |
| expect(hasUnsoundNullSafety ? unsoundResult : soundResult, map.log); |
| } |
| |
| expect(expected, actual) { |
| if (expected != actual) throw 'Expected $expected, actual $actual'; |
| } |