mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:27:17 +00:00
5cff200999
Part of https://github.com/dart-lang/sdk/issues/49749 Change-Id: I245a68f48a217e26ad2e1a74a8996a8fef128da0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/280421 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
134 lines
4.6 KiB
Dart
134 lines
4.6 KiB
Dart
// Copyright (c) 2022, 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.
|
|
|
|
// SharedOptions=--enable-experiment=patterns,records
|
|
|
|
import "package:expect/expect.dart";
|
|
|
|
main() {
|
|
Expect.equals('0: int', differentFinalityNotUsedInBody(0, 0));
|
|
Expect.equals('1: final int', differentFinalityNotUsedInBody(1, 1));
|
|
Expect.equals('2: var', differentFinalityNotUsedInBody(2, 2));
|
|
Expect.equals('3: final', differentFinalityNotUsedInBody(3, 3));
|
|
|
|
Expect.equals('0: int', differentTypeNotUsedInBody(0, 0));
|
|
Expect.equals('true: bool', differentTypeNotUsedInBody(1, true));
|
|
Expect.equals('s: var', differentTypeNotUsedInBody(2, 's'));
|
|
|
|
Expect.equals('unique: unique', differentVariableNotUsedInBody(0, 'unique'));
|
|
Expect.equals('in: inTwo', differentVariableNotUsedInBody(1, 'in'));
|
|
Expect.equals('two: inTwo', differentVariableNotUsedInBody(2, 'two'));
|
|
|
|
Expect.equals('one: var', sharedAnnotatedAndUnannotated(0, 'one'));
|
|
Expect.equals('two: Object', sharedAnnotatedAndUnannotated(1, 'two'));
|
|
|
|
Expect.equals('one: var', sharedAnnotatedAndPromotionInferred(0, 'one'));
|
|
Expect.equals('two: String', sharedAnnotatedAndPromotionInferred(1, 'two'));
|
|
|
|
Expect.equals('0: 0: list', sharedDifferentContext([0, true]));
|
|
Expect.equals('1: 1: map', sharedDifferentContext({'a': 1, 'b': true}));
|
|
Expect.equals('2: 2: record', sharedDifferentContext((a: 2, b: true)));
|
|
Expect.equals('3: 3: nested', sharedDifferentContext((a: 3, b: [true])));
|
|
}
|
|
|
|
/// OK if variables in different cases have different finality if not used in
|
|
/// the body.
|
|
Object? differentFinalityNotUsedInBody(int caseKey, Object value) {
|
|
switch ((caseKey, value)) {
|
|
case (0, int x) when _guard(x, 'int'):
|
|
case (1, final int x) when _guard(x, 'final int'):
|
|
case (2, var x) when _guard(x, 'var'):
|
|
case (3, final x) when _guard(x, 'final'):
|
|
return _matchedCase();
|
|
default:
|
|
Expect.fail('Should not reach this.');
|
|
}
|
|
}
|
|
|
|
/// OK if variables in different cases have different types if not used in the
|
|
/// body.
|
|
Object? differentTypeNotUsedInBody(int caseKey, Object value) {
|
|
switch ((caseKey, value)) {
|
|
case (0, int x) when _guard(x, 'int'):
|
|
case (1, bool x) when _guard(x, 'bool'):
|
|
case (2, var x) when _guard(x, 'var'): // Infer Object.
|
|
return _matchedCase();
|
|
default:
|
|
Expect.fail('Should not reach this.');
|
|
}
|
|
}
|
|
|
|
/// OK if some variables only exist in some cases if they aren't used in the
|
|
/// body.
|
|
Object? differentVariableNotUsedInBody(int caseKey, Object value) {
|
|
switch ((caseKey, value)) {
|
|
case (0, var unique) when _guard(unique, 'unique'):
|
|
case (1, var inTwo) when _guard(inTwo, 'inTwo'):
|
|
case (2, var inTwo) when _guard(inTwo, 'inTwo'):
|
|
return _matchedCase();
|
|
default:
|
|
Expect.fail('Should not reach this.');
|
|
}
|
|
}
|
|
|
|
/// Variables can be shared if not all are annotated as long as the inferred
|
|
/// type matches.
|
|
Object? sharedAnnotatedAndUnannotated(int caseKey, Object value) {
|
|
switch ((caseKey, value)) {
|
|
case (0, var a) when _guard(a, 'var'):
|
|
case (1, Object a) when _guard(a, 'Object'):
|
|
// Use pattern variable in body:
|
|
Expect.equals(value, a);
|
|
return _matchedCase();
|
|
default:
|
|
Expect.fail('Should not reach this.');
|
|
}
|
|
}
|
|
|
|
/// Variables can be shared if not all are annotated as long as the type
|
|
/// inferred using promotion matches.
|
|
Object? sharedAnnotatedAndPromotionInferred(int caseKey, Object value) {
|
|
// Promote value to String.
|
|
if (value is String) {
|
|
switch ((caseKey, value)) {
|
|
case (0, var a) when _guard(a, 'var'):
|
|
case (1, String a) when _guard(a, 'String'):
|
|
// Use pattern variable in body:
|
|
Expect.equals(value, a);
|
|
return _matchedCase();
|
|
default:
|
|
Expect.fail('Should not reach this.');
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Variables can be shared even when they occur in different contexts in their
|
|
/// respective patterns.
|
|
Object? sharedDifferentContext(Object value) {
|
|
// OK, since inferred type is same as annotated.
|
|
switch (value) {
|
|
case [int a, bool b] when _guard(a, 'list'):
|
|
case {'b': bool b, 'a': int a} when _guard(a, 'map'):
|
|
case (a: int a, b: bool b) when _guard(a, 'record'):
|
|
case (a: int a, b: [bool b]) when _guard(a, 'nested'):
|
|
// Use pattern variables in body:
|
|
return '$a: ${_matchedCase()}';
|
|
default:
|
|
Expect.fail('Should not reach this.');
|
|
}
|
|
}
|
|
|
|
String _lastMatch = 'none';
|
|
|
|
bool _guard(Object guardVariable, String label) {
|
|
_lastMatch = '$guardVariable: $label';
|
|
return true;
|
|
}
|
|
|
|
String _matchedCase() {
|
|
var result = _lastMatch;
|
|
_lastMatch = 'none';
|
|
return result;
|
|
}
|