mirror of
https://github.com/dart-lang/sdk
synced 2024-10-02 23:24:42 +00:00
Add operators &
, |
and ^
to bool
.
Change-Id: Idd6472f239445914c1ff1ab68fc7b38fa6b320ae Reviewed-on: https://dart-review.googlesource.com/25240 Commit-Queue: Lasse R.H. Nielsen <lrn@google.com> Reviewed-by: Leaf Petersen <leafp@google.com> Reviewed-by: Lasse R.H. Nielsen <lrn@google.com> Reviewed-by: Florian Loitsch <floitsch@google.com>
This commit is contained in:
parent
5af9844382
commit
cc08d0e1da
|
@ -20,6 +20,7 @@
|
|||
be unmodifiable incorrectly allowed new methods added in Dart 2 to
|
||||
succeed.
|
||||
* Exported `Future` and `Stream` from `dart:core`.
|
||||
* Added operators `&`, `|` and `^` to `bool`.
|
||||
|
||||
#### `dart:async`
|
||||
|
||||
|
|
|
@ -42,6 +42,15 @@ class JSBool extends Interceptor implements bool {
|
|||
@notNull
|
||||
int get hashCode => this ? (2 * 3 * 23 * 3761) : (269 * 811);
|
||||
|
||||
@notNull
|
||||
bool operator &(@nullCheck bool other) => JS('bool', "# && #", other, this);
|
||||
|
||||
@notNull
|
||||
bool operator |(@nullCheck bool other) => JS('bool', "# || #", other, this);
|
||||
|
||||
@notNull
|
||||
bool operator ^(@nullCheck bool other) => !identical(this, other);
|
||||
|
||||
Type get runtimeType => bool;
|
||||
}
|
||||
|
||||
|
|
|
@ -543,7 +543,13 @@ class Expect {
|
|||
// A test failure doesn't count as throwing.
|
||||
if (e is ExpectException) rethrow;
|
||||
if (e is T && (check == null || check(e))) return;
|
||||
_fail("Expect.throws$msg: Unexpected '$e'\n$s");
|
||||
// Throws something unexpected.
|
||||
String type = "";
|
||||
if (T != dynamic && T != Object) {
|
||||
type = "<$T>";
|
||||
}
|
||||
_fail("Expect.throws$type$msg: "
|
||||
"Unexpected '${Error.safeToString(e)}'\n$s");
|
||||
}
|
||||
_fail('Expect.throws$msg fails: Did not throw');
|
||||
}
|
||||
|
@ -602,14 +608,16 @@ class Expect {
|
|||
static void type<T>(Object object, [String reason]) {
|
||||
if (object is T) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.type($object is $T$msg) fails, was ${object.runtimeType}");
|
||||
_fail("Expect.type($object is $T$msg) fails "
|
||||
"on ${Error.safeToString(object)}");
|
||||
}
|
||||
|
||||
/// Checks that [object] does not have type [T].
|
||||
static void notType<T>(Object object, [String reason]) {
|
||||
if (object is! T) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.type($object is! $T$msg) fails, was ${object.runtimeType}");
|
||||
_fail("Expect.type($object is! $T$msg) fails"
|
||||
"on ${Error.safeToString(object)}");
|
||||
}
|
||||
|
||||
static String _getMessage(String reason) =>
|
||||
|
|
|
@ -330,9 +330,6 @@ ThisAsIdentifier/example: Fail
|
|||
ThisOrSuperAccessInFieldInitializer/example: Fail
|
||||
TooFewArguments/example: Fail
|
||||
TooManyArguments/example: Fail
|
||||
TopLevelOperator/script1: Fail
|
||||
TopLevelOperator/script2: Fail
|
||||
TopLevelOperator/script3: Fail
|
||||
TypeAfterVar/example: Fail
|
||||
TypeArgumentMismatch/example: Fail
|
||||
TypeArgumentsOnTypeVariable/script1: Fail
|
||||
|
|
|
@ -16,6 +16,7 @@ import 'dart:_js_helper'
|
|||
JSSyntaxRegExp,
|
||||
Primitives,
|
||||
argumentErrorValue,
|
||||
checkBool,
|
||||
checkInt,
|
||||
checkNull,
|
||||
checkNum,
|
||||
|
@ -364,6 +365,12 @@ class JSBool extends Interceptor implements bool {
|
|||
// Note: if you change this, also change the function [S].
|
||||
String toString() => JS('String', r'String(#)', this);
|
||||
|
||||
bool operator &(bool other) => JS('bool', "# && #", checkBool(other), this);
|
||||
|
||||
bool operator |(bool other) => JS('bool', "# || #", checkBool(other), this);
|
||||
|
||||
bool operator ^(bool other) => !identical(this, checkBool(other));
|
||||
|
||||
// The values here are SMIs, co-prime and differ about half of the bit
|
||||
// positions, including the low bit, so they are different mod 2^k.
|
||||
int get hashCode => this ? (2 * 3 * 23 * 3761) : (269 * 811);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
part of dart.core;
|
||||
|
||||
/**
|
||||
* The reserved words [:true:] and [:false:] denote objects that are the only
|
||||
* The reserved words `true` and `false` denote objects that are the only two
|
||||
* instances of this class.
|
||||
*
|
||||
* It is a compile-time error for a class to attempt to extend or implement
|
||||
|
@ -23,21 +23,22 @@ class bool {
|
|||
* the result is the [defaultValue].
|
||||
*
|
||||
* The result is the same as would be returned by:
|
||||
*
|
||||
* (const String.fromEnvironment(name) == "true")
|
||||
* ? true
|
||||
* : (const String.fromEnvironment(name) == "false")
|
||||
* ? false
|
||||
* : defaultValue
|
||||
*
|
||||
* ```dart
|
||||
* (const String.fromEnvironment(name) == "true")
|
||||
* ? true
|
||||
* : (const String.fromEnvironment(name) == "false")
|
||||
* ? false
|
||||
* : defaultValue
|
||||
* ```
|
||||
* Example:
|
||||
*
|
||||
* const loggingFlag = const bool.fromEnvironment("logging");
|
||||
*
|
||||
* ```dart
|
||||
* const loggingFlag = const bool.fromEnvironment("logging");
|
||||
* ```
|
||||
* If you want to use a different truth-string than `"true"`, you can use the
|
||||
* [String.fromEnvironment] constructor directly:
|
||||
*
|
||||
* const isLoggingOn = (const String.fromEnvironment("logging") == "on");
|
||||
* ```dart
|
||||
* const isLoggingOn = (const String.fromEnvironment("logging") == "on");
|
||||
* ```
|
||||
*/
|
||||
// The .fromEnvironment() constructors are special in that we do not want
|
||||
// users to call them using "new". We prohibit that by giving them bodies
|
||||
|
@ -50,9 +51,24 @@ class bool {
|
|||
|
||||
external int get hashCode;
|
||||
|
||||
/// The logical conjuncton ("and") of this and [other].
|
||||
///
|
||||
/// Returns `true` if both this and [other] are `true`, and `false` otherwise.
|
||||
//TODO(lrn): Remove "as bool" in Dart 2.
|
||||
bool operator &(bool other) => (other as bool) && this;
|
||||
|
||||
/// The logical disjunction ("inclusive or") of this and [other].
|
||||
///
|
||||
/// Returns `true` if either this or [other] is `true`, and `false` otherwise.
|
||||
bool operator |(bool other) => (other as bool) || this;
|
||||
|
||||
/// The logical exclusive disjuction ("exclusive or") of this and [other].
|
||||
///
|
||||
/// Returns whether this and [other] are neither both `true` nor both `false`.
|
||||
bool operator ^(bool other) => !(other as bool) == this;
|
||||
|
||||
/**
|
||||
* Returns [:"true":] if the receiver is [:true:], or [:"false":] if the
|
||||
* receiver is [:false:].
|
||||
* Returns either `"true"` for `true` and `"false"` for `false`.
|
||||
*/
|
||||
String toString() {
|
||||
return this ? "true" : "false";
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
# Tests that produce compile-time errors even in legacy mode.
|
||||
[ $runtime == none ]
|
||||
Language/Expressions/Bitwise_Expressions/syntax_t01/02: Skip
|
||||
Language/Variables/constant_initialization_t03: CompileTimeError # Uppercase constants removed
|
||||
Language/Variables/constant_variable_t09: CompileTimeError # Uppercase constants removed
|
||||
LibTest/core/double/operator_GE_A01_t03: CompileTimeError # Uppercase constants removed
|
||||
|
@ -42,6 +43,7 @@ LibTest/math/Rectangle/operator_equality_A04_t01: CompileTimeError # Uppercase c
|
|||
|
||||
# Tests that fail either at compile-time or at runtime.
|
||||
[ $runtime != none ]
|
||||
Language/Expressions/Bitwise_Expressions/syntax_t01/02: Skip
|
||||
Language/Expressions/Numbers/static_type_of_double_t01: RuntimeError # Uppercase constants removed
|
||||
Language/Expressions/Object_Identity/constant_objects_t01: RuntimeError # Uppercase constants removed
|
||||
Language/Expressions/Object_Identity/double_t02: RuntimeError # Uppercase constants removed
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# 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.
|
||||
|
||||
core_runtime_types_test: RuntimeError # Does not expect bool to have operators.
|
||||
maps_test: Skip # Maps class no longer exists
|
||||
|
||||
[ $compiler == dart2analyzer ]
|
||||
|
|
46
tests/corelib_2/bool_operator_test.dart
Normal file
46
tests/corelib_2/bool_operator_test.dart
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) 2017, 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.
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
main() {
|
||||
void test(bool b1, bool b2) {
|
||||
var and1 = b1 && b2;
|
||||
var and2 = b1 & b2;
|
||||
var and3 = b1 ? b2 ? true : false : false;
|
||||
var or1 = b1 || b2;
|
||||
var or2 = b1 | b2;
|
||||
var or3 = b1 ? true : b2 ? true : false;
|
||||
var xor1 = b1 != b2;
|
||||
var xor2 = b1 ^ b2;
|
||||
var xor3 = b1 ? b2 ? false : true : b2 ? true : false;
|
||||
var nb1 = !b1;
|
||||
var nb2 = !b2;
|
||||
Expect.equals(and3, and1);
|
||||
Expect.equals(and3, and2);
|
||||
Expect.equals(or3, or1);
|
||||
Expect.equals(or3, or2);
|
||||
Expect.equals(xor3, xor1);
|
||||
Expect.equals(xor3, xor2);
|
||||
Expect.notEquals(nb1, b1);
|
||||
Expect.notEquals(nb2, b2);
|
||||
}
|
||||
|
||||
test(true, false);
|
||||
test(true, true);
|
||||
test(false, true);
|
||||
test(false, false);
|
||||
|
||||
Expect.isTrue(true || (throw "unreachable"));
|
||||
Expect.throws(() => false || (throw "unreachable"));
|
||||
|
||||
Expect.isFalse(false && (throw "unreachable"));
|
||||
Expect.throws(() => true && (throw "unreachable"));
|
||||
|
||||
Expect.throws(() => true | (throw "unreachable"));
|
||||
Expect.throws(() => false | (throw "unreachable"));
|
||||
|
||||
Expect.throws(() => true & (throw "unreachable"));
|
||||
Expect.throws(() => false & (throw "unreachable"));
|
||||
}
|
|
@ -46,13 +46,16 @@ class CoreRuntimeTypesTest {
|
|||
assertListEquals(a, b);
|
||||
}
|
||||
|
||||
static assertTypeError(void f()) {
|
||||
Expect.throws(
|
||||
static assertTypeError(void f(), [String message]) {
|
||||
Expect.throws<Error>(
|
||||
f,
|
||||
(exception) =>
|
||||
(exception is TypeError) ||
|
||||
(exception is CastError) ||
|
||||
(exception is AssertionError) ||
|
||||
(exception is NoSuchMethodError) ||
|
||||
(exception is ArgumentError));
|
||||
(exception is ArgumentError),
|
||||
message);
|
||||
}
|
||||
|
||||
static testBooleanOperators() {
|
||||
|
@ -94,46 +97,49 @@ class CoreRuntimeTypesTest {
|
|||
for (var i = 0; i < objs.length; i++) {
|
||||
for (var j = i + 1; j < objs.length; j++) {
|
||||
testBinaryOperatorErrors(objs[i], objs[j]);
|
||||
// Allow "String * int".
|
||||
if (j > 2) testBinaryOperatorErrors(objs[j], objs[i]);
|
||||
}
|
||||
if (objs[i] != 1) {
|
||||
testUnaryOperatorErrors(objs[i]);
|
||||
testBinaryOperatorErrors(objs[j], objs[i]);
|
||||
}
|
||||
testUnaryOperatorErrors(objs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static testBinaryOperatorErrors(x, y) {
|
||||
assertTypeError(() {
|
||||
x - y;
|
||||
});
|
||||
x + y;
|
||||
}, "$x+$y");
|
||||
assertTypeError(() {
|
||||
x * y;
|
||||
});
|
||||
x - y;
|
||||
}, "$x-$y");
|
||||
// String.* is the only non-same-type binary operator we have.
|
||||
if (x is! String && y is! int) {
|
||||
assertTypeError(() {
|
||||
x * y;
|
||||
}, "$x*$y");
|
||||
}
|
||||
assertTypeError(() {
|
||||
x / y;
|
||||
});
|
||||
}, "$x/$y");
|
||||
assertTypeError(() {
|
||||
x | y;
|
||||
});
|
||||
}, "$x|$y");
|
||||
assertTypeError(() {
|
||||
x ^ y;
|
||||
});
|
||||
}, "$x^$y");
|
||||
assertTypeError(() {
|
||||
x & y;
|
||||
});
|
||||
}, "$x&$y");
|
||||
assertTypeError(() {
|
||||
x << y;
|
||||
});
|
||||
}, "$x<<$y");
|
||||
assertTypeError(() {
|
||||
x >> y;
|
||||
});
|
||||
}, "$x>>$y");
|
||||
assertTypeError(() {
|
||||
x ~/ y;
|
||||
});
|
||||
}, "$x~/$y");
|
||||
assertTypeError(() {
|
||||
x % y;
|
||||
});
|
||||
}, "$x%$y");
|
||||
|
||||
testComparisonOperatorErrors(x, y);
|
||||
}
|
||||
|
@ -143,27 +149,34 @@ class CoreRuntimeTypesTest {
|
|||
assertEquals(x != y, true);
|
||||
assertTypeError(() {
|
||||
x < y;
|
||||
});
|
||||
}, "$x<$y");
|
||||
assertTypeError(() {
|
||||
x <= y;
|
||||
});
|
||||
}, "$x<=$y");
|
||||
assertTypeError(() {
|
||||
x > y;
|
||||
});
|
||||
}, "$x>$y");
|
||||
assertTypeError(() {
|
||||
x >= y;
|
||||
});
|
||||
}, "$x>=$y");
|
||||
}
|
||||
|
||||
static testUnaryOperatorErrors(x) {
|
||||
// TODO(jimhug): Add guard for 'is num' when 'is' is working
|
||||
assertTypeError(() {
|
||||
~x;
|
||||
});
|
||||
assertTypeError(() {
|
||||
-x;
|
||||
});
|
||||
// TODO(jimhug): Add check for !x as an error when x is not a bool
|
||||
if (x is! int) {
|
||||
assertTypeError(() {
|
||||
~x;
|
||||
}, "~$x");
|
||||
}
|
||||
if (x is! num) {
|
||||
assertTypeError(() {
|
||||
-x;
|
||||
}, "-$x");
|
||||
}
|
||||
if (x is! bool) {
|
||||
assertTypeError(() {
|
||||
!x;
|
||||
}, "!$x");
|
||||
}
|
||||
}
|
||||
|
||||
static testRationalMethods() {
|
||||
|
|
|
@ -20,6 +20,7 @@ bigint_from_test: RuntimeError # Issue 32589
|
|||
bigint_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
|
||||
bit_twiddling_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
|
||||
compare_to2_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
|
||||
core_runtime_types_test: RuntimeError # Issue 34147
|
||||
date_time11_test: RuntimeError, Pass # Fails when US is on winter time, issue 31285.
|
||||
date_time_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
|
||||
double_ceil_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
|
||||
|
@ -288,6 +289,9 @@ symbol_reserved_word_test/12: RuntimeError # Issues 11669 and 31936 - throwing c
|
|||
symbol_test/none: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
|
||||
unicode_test: RuntimeError # Issue 18061: German double S.
|
||||
|
||||
[ $compiler != fasta && !$strong ]
|
||||
core_runtime_types_test: SkipByDesign
|
||||
|
||||
[ $compiler == none && $runtime == vm ]
|
||||
from_environment_const_type_undefined_test/09: MissingCompileTimeError
|
||||
from_environment_const_type_undefined_test/11: MissingCompileTimeError
|
||||
|
|
Loading…
Reference in a new issue