blob: ea295ff1a32cc7470380203ad9ec0d0472675134 [file] [log] [blame] [edit]
// 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, a pattern is matched against a value. This determines
/// whether or not the match fails and the pattern refutes the value. If the
/// match succeeds, the pattern may also destructure data from the object or
/// bind variables.
///
/// Refutable patterns usually occur in a context where match refutation causes
/// execution to skip over the body of code where any variables bound by the
/// pattern are in scope. If a pattern match failure occurs in an irrefutable
/// context, a runtime error is thrown.
///
/// To match a pattern p against a value v:
/// ...
/// Relational:
/// i. Evaluate the right-hand constant expression to c.
/// ii. If the operator is ==:
/// a. Let r be the result of v == c.
/// b. The pattern matches if r is true and fails otherwise. This takes into
/// account the built-in semantics that null is only equal to null. The
/// result will always be a bool since operator == on Object is declared to
/// return bool.
/// iii. Else if the operator is !=:
/// a. Let r be the result of v == c.
/// b. The pattern matches if r is false and fails otherwise. This takes into
/// account the built-in semantics that null is only equal to null.
/// iv. Else the operator is a comparison operator op:
/// a. Let r be the result of calling op on v with argument c.
/// b. If r is not a bool then throw a runtime error. This can happen if the
/// operator on v's type returns dynamic.
/// c. The pattern matches if r is true and fails otherwise.
///
/// @description Check that if the operator is `!=` then the pattern matches if
/// `v == c` returns false.
/// @author sgrekhov22@gmail.com
import "../../Utils/expect.dart";
class C {
final int value;
String log = "";
C(this.value);
void clearLog() {
log = "";
}
@override
bool operator ==(Object other) {
log += "C($value)==$other;";
if (other is int) {
return this.value == other;
}
return super == other;
}
@override
int get hashCode => throw "Never used";
}
String test1(C c) {
switch (c) {
case != 1:
return "1";
case != 2:
return "2";
default:
return "no match";
}
}
String test2(C c) {
if (c case != 1) {
return "1";
}
if (c case != 2) {
return "2";
}
return "no match";
}
String test3(C c) {
return switch (c) {
!= 1 => "1",
!= 2 => "2",
_ => "no match"
};
}
main() {
C c1 = C(1);
C c2 = C(2);
Expect.equals("2", test1(c1));
Expect.equals("C(1)==1;C(1)==2;", c1.log);
Expect.equals("1", test1(c2));
Expect.equals("C(2)==1;", c2.log);
c1.clearLog();
c2.clearLog();
Expect.equals("2", test2(c1));
Expect.equals("C(1)==1;C(1)==2;", c1.log);
Expect.equals("1", test2(c2));
Expect.equals("C(2)==1;", c2.log);
c1.clearLog();
c2.clearLog();
Expect.equals("2", test3(c1));
Expect.equals("C(1)==1;C(1)==2;", c1.log);
Expect.equals("1", test3(c2));
Expect.equals("C(2)==1;", c2.log);
}