mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
Make ArgumentError.check* functions return the valid argument.
This makes these checks useful in situations where you don't want to spend an extra statement, like `=>` bodies or initializer lists (including forwarding generative constructors). Change-Id: Ia55b8741a7c75af631db48ac70e64597d8f96c73 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135649 Commit-Queue: Lasse R.H. Nielsen <lrn@google.com> Reviewed-by: Lasse R.H. Nielsen <lrn@google.com> Reviewed-by: Bob Nystrom <rnystrom@google.com>
This commit is contained in:
parent
1181f44378
commit
8ab3dcf709
7 changed files with 119 additions and 16 deletions
|
@ -23,6 +23,11 @@
|
||||||
which was added to `AssertionError` when the second operand to `assert`
|
which was added to `AssertionError` when the second operand to `assert`
|
||||||
was allowed. The value of that getter on a `TypeError` was the same
|
was allowed. The value of that getter on a `TypeError` was the same
|
||||||
string as returned by `toString`, so it is still available.
|
string as returned by `toString`, so it is still available.
|
||||||
|
* `ArgumentError.checkNotNull` and the `RangeError` static methods
|
||||||
|
`checkValueInInterval`, `checkValidIndex` and `checkNotNegative`
|
||||||
|
all return their first argument on success.
|
||||||
|
This makes these functions more convenient to use in-line in,
|
||||||
|
for example, `=>` function bodies or constructor initialization lists.
|
||||||
|
|
||||||
#### `dart:developer`
|
#### `dart:developer`
|
||||||
|
|
||||||
|
|
|
@ -423,7 +423,7 @@ library from "org-dartlang-test:///main.dart" as main {
|
||||||
return 1.{dart.core::int::unary-}();
|
return 1.{dart.core::int::unary-}();
|
||||||
}
|
}
|
||||||
method /* from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insert(dart.core::int* index, generic-covariant-impl dart.core::int* element) → void {
|
method /* from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insert(dart.core::int* index, generic-covariant-impl dart.core::int* element) → void {
|
||||||
dart.core::ArgumentError::checkNotNull(index, "index");
|
dart.core::ArgumentError::checkNotNull<dart.core::int*>(index, "index");
|
||||||
dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index");
|
dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index");
|
||||||
if(index.{dart.core::num::==}(this.{dart.core::List::length})) {
|
if(index.{dart.core::num::==}(this.{dart.core::List::length})) {
|
||||||
this.{dart.collection::ListMixin::add}(element);
|
this.{dart.collection::ListMixin::add}(element);
|
||||||
|
|
|
@ -423,7 +423,7 @@ library from "org-dartlang-test:///main.dart" as main {
|
||||||
return 1.{dart.core::int::unary-}();
|
return 1.{dart.core::int::unary-}();
|
||||||
}
|
}
|
||||||
method /* from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insert(dart.core::int* index, generic-covariant-impl dart.core::int* element) → void {
|
method /* from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insert(dart.core::int* index, generic-covariant-impl dart.core::int* element) → void {
|
||||||
dart.core::ArgumentError::checkNotNull(index, "index");
|
dart.core::ArgumentError::checkNotNull<dart.core::int*>(index, "index");
|
||||||
dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index");
|
dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index");
|
||||||
if(index.{dart.core::num::==}(this.{dart.core::List::length})) {
|
if(index.{dart.core::num::==}(this.{dart.core::List::length})) {
|
||||||
this.{dart.collection::ListMixin::add}(element);
|
this.{dart.collection::ListMixin::add}(element);
|
||||||
|
|
|
@ -184,10 +184,16 @@ class ArgumentError extends Error {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throws if [argument] is `null`.
|
* Throws if [argument] is `null`.
|
||||||
|
*
|
||||||
|
* If [name] is supplied, it is used as the parameter name
|
||||||
|
* in the error message.
|
||||||
|
*
|
||||||
|
* Returns the [argument] if it is not null.
|
||||||
*/
|
*/
|
||||||
@Since("2.1")
|
@Since("2.1")
|
||||||
static void checkNotNull(Object argument, [String name]) {
|
static T checkNotNull<@Since("2.8") T>(T argument, [String name]) {
|
||||||
if (argument == null) throw ArgumentError.notNull(name);
|
if (argument == null) throw ArgumentError.notNull(name);
|
||||||
|
return argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper functions for toString overridden in subclasses.
|
// Helper functions for toString overridden in subclasses.
|
||||||
|
@ -279,30 +285,42 @@ class RangeError extends ArgumentError {
|
||||||
[String name, String message, int length]) = IndexError;
|
[String name, String message, int length]) = IndexError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that a [value] lies in a specific interval.
|
* Check that an integer [value] lies in a specific interval.
|
||||||
*
|
*
|
||||||
* Throws if [value] is not in the interval.
|
* Throws if [value] is not in the interval.
|
||||||
* The interval is from [minValue] to [maxValue], both inclusive.
|
* The interval is from [minValue] to [maxValue], both inclusive.
|
||||||
|
*
|
||||||
|
* If [name] or [message] are provided, they are used as the parameter
|
||||||
|
* name and message text of the thrown error.
|
||||||
|
*
|
||||||
|
* Returns [value] if it is in the interval.
|
||||||
*/
|
*/
|
||||||
static void checkValueInInterval(int value, int minValue, int maxValue,
|
static int checkValueInInterval(int value, int minValue, int maxValue,
|
||||||
[String name, String message]) {
|
[String name, String message]) {
|
||||||
if (value < minValue || value > maxValue) {
|
if (value < minValue || value > maxValue) {
|
||||||
throw RangeError.range(value, minValue, maxValue, name, message);
|
throw RangeError.range(value, minValue, maxValue, name, message);
|
||||||
}
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that a value is a valid index into an indexable object.
|
* Check that [index] is a valid index into an indexable object.
|
||||||
*
|
*
|
||||||
* Throws if [index] is not a valid index into [indexable].
|
* Throws if [index] is not a valid index into [indexable].
|
||||||
*
|
*
|
||||||
* An indexable object is one that has a `length` and a and index-operator
|
* An indexable object is one that has a `length` and a and index-operator
|
||||||
* `[]` that accepts an index if `0 <= index < length`.
|
* `[]` that accepts an index if `0 <= index < length`.
|
||||||
*
|
*
|
||||||
|
* If [name] or [message] are provided, they are used as the parameter
|
||||||
|
* name and message text of the thrown error. If [name] is omitted, it
|
||||||
|
* defaults to `"index"`.
|
||||||
|
*
|
||||||
* If [length] is provided, it is used as the length of the indexable object,
|
* If [length] is provided, it is used as the length of the indexable object,
|
||||||
* otherwise the length is found as `indexable.length`.
|
* otherwise the length is found as `indexable.length`.
|
||||||
|
*
|
||||||
|
* Returns [index] if it is a valid index.
|
||||||
*/
|
*/
|
||||||
static void checkValidIndex(int index, dynamic indexable,
|
static int checkValidIndex(int index, dynamic indexable,
|
||||||
[String name, int length, String message]) {
|
[String name, int length, String message]) {
|
||||||
length ??= indexable.length;
|
length ??= indexable.length;
|
||||||
// Comparing with `0` as receiver produces better dart2js type inference.
|
// Comparing with `0` as receiver produces better dart2js type inference.
|
||||||
|
@ -310,6 +328,7 @@ class RangeError extends ArgumentError {
|
||||||
name ??= "index";
|
name ??= "index";
|
||||||
throw RangeError.index(index, indexable, name, message, length);
|
throw RangeError.index(index, indexable, name, message, length);
|
||||||
}
|
}
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -347,12 +366,19 @@ class RangeError extends ArgumentError {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that an integer value isn't negative.
|
* Check that an integer value is non-negative.
|
||||||
*
|
*
|
||||||
* Throws if the value is negative.
|
* Throws if the value is negative.
|
||||||
|
*
|
||||||
|
* If [name] or [message] are provided, they are used as the parameter
|
||||||
|
* name and message text of the thrown error. If [name] is omitted, it
|
||||||
|
* defaults to `index`.
|
||||||
|
*
|
||||||
|
* Returns [value] if it is not negative.
|
||||||
*/
|
*/
|
||||||
static void checkNotNegative(int value, [String name, String message]) {
|
static int checkNotNegative(int value, [String name, String message]) {
|
||||||
if (value < 0) throw RangeError.range(value, 0, null, name, message);
|
if (value < 0) throw RangeError.range(value, 0, null, name, message);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get _errorName => "RangeError";
|
String get _errorName => "RangeError";
|
||||||
|
|
|
@ -182,10 +182,16 @@ class ArgumentError extends Error {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throws if [argument] is `null`.
|
* Throws if [argument] is `null`.
|
||||||
|
*
|
||||||
|
* If [name] is supplied, it is used as the parameter name
|
||||||
|
* in the error message.
|
||||||
|
*
|
||||||
|
* Returns the [argument] if it is not null.
|
||||||
*/
|
*/
|
||||||
@Since("2.1")
|
@Since("2.1")
|
||||||
static void checkNotNull(Object? argument, [String? name]) {
|
static T checkNotNull<@Since("2.8") T>(T? argument, [String? name]) {
|
||||||
if (argument == null) throw ArgumentError.notNull(name);
|
if (argument == null) throw ArgumentError.notNull(name);
|
||||||
|
return argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper functions for toString overridden in subclasses.
|
// Helper functions for toString overridden in subclasses.
|
||||||
|
@ -274,30 +280,42 @@ class RangeError extends ArgumentError {
|
||||||
[String? name, String? message, int? length]) = IndexError;
|
[String? name, String? message, int? length]) = IndexError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that a [value] lies in a specific interval.
|
* Check that an integer [value] lies in a specific interval.
|
||||||
*
|
*
|
||||||
* Throws if [value] is not in the interval.
|
* Throws if [value] is not in the interval.
|
||||||
* The interval is from [minValue] to [maxValue], both inclusive.
|
* The interval is from [minValue] to [maxValue], both inclusive.
|
||||||
|
*
|
||||||
|
* If [name] or [message] are provided, they are used as the parameter
|
||||||
|
* name and message text of the thrown error.
|
||||||
|
*
|
||||||
|
* Returns [value] if it is in the interval.
|
||||||
*/
|
*/
|
||||||
static void checkValueInInterval(int value, int minValue, int maxValue,
|
static int checkValueInInterval(int value, int minValue, int maxValue,
|
||||||
[String? name, String? message]) {
|
[String? name, String? message]) {
|
||||||
if (value < minValue || value > maxValue) {
|
if (value < minValue || value > maxValue) {
|
||||||
throw RangeError.range(value, minValue, maxValue, name, message);
|
throw RangeError.range(value, minValue, maxValue, name, message);
|
||||||
}
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that a value is a valid index into an indexable object.
|
* Check that [index] is a valid index into an indexable object.
|
||||||
*
|
*
|
||||||
* Throws if [index] is not a valid index into [indexable].
|
* Throws if [index] is not a valid index into [indexable].
|
||||||
*
|
*
|
||||||
* An indexable object is one that has a `length` and a and index-operator
|
* An indexable object is one that has a `length` and a and index-operator
|
||||||
* `[]` that accepts an index if `0 <= index < length`.
|
* `[]` that accepts an index if `0 <= index < length`.
|
||||||
*
|
*
|
||||||
|
* If [name] or [message] are provided, they are used as the parameter
|
||||||
|
* name and message text of the thrown error. If [name] is omitted, it
|
||||||
|
* defaults to `"index"`.
|
||||||
|
*
|
||||||
* If [length] is provided, it is used as the length of the indexable object,
|
* If [length] is provided, it is used as the length of the indexable object,
|
||||||
* otherwise the length is found as `indexable.length`.
|
* otherwise the length is found as `indexable.length`.
|
||||||
|
*
|
||||||
|
* Returns [index] if it is a valid index.
|
||||||
*/
|
*/
|
||||||
static void checkValidIndex(int index, dynamic indexable,
|
static int checkValidIndex(int index, dynamic indexable,
|
||||||
[String? name, int? length, String? message]) {
|
[String? name, int? length, String? message]) {
|
||||||
length ??= (indexable.length as int);
|
length ??= (indexable.length as int);
|
||||||
// Comparing with `0` as receiver produces better dart2js type inference.
|
// Comparing with `0` as receiver produces better dart2js type inference.
|
||||||
|
@ -305,6 +323,7 @@ class RangeError extends ArgumentError {
|
||||||
name ??= "index";
|
name ??= "index";
|
||||||
throw RangeError.index(index, indexable, name, message, length);
|
throw RangeError.index(index, indexable, name, message, length);
|
||||||
}
|
}
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -342,12 +361,19 @@ class RangeError extends ArgumentError {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that an integer value isn't negative.
|
* Check that an integer value is non-negative.
|
||||||
*
|
*
|
||||||
* Throws if the value is negative.
|
* Throws if the value is negative.
|
||||||
|
*
|
||||||
|
* If [name] or [message] are provided, they are used as the parameter
|
||||||
|
* name and message text of the thrown error. If [name] is omitted, it
|
||||||
|
* defaults to `index`.
|
||||||
|
*
|
||||||
|
* Returns [value] if it is not negative.
|
||||||
*/
|
*/
|
||||||
static void checkNotNegative(int value, [String? name, String? message]) {
|
static int checkNotNegative(int value, [String? name, String? message]) {
|
||||||
if (value < 0) throw RangeError.range(value, 0, null, name, message);
|
if (value < 0) throw RangeError.range(value, 0, null, name, message);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get _errorName => "RangeError";
|
String get _errorName => "RangeError";
|
||||||
|
|
|
@ -74,4 +74,27 @@ main() {
|
||||||
"RangeError: Index out of range: "
|
"RangeError: Index out of range: "
|
||||||
"index must not be negative: -5",
|
"index must not be negative: -5",
|
||||||
new RangeError.index(-5, [1, 2, 3]).toString());
|
new RangeError.index(-5, [1, 2, 3]).toString());
|
||||||
|
|
||||||
|
Expect.equals(42, ArgumentError.checkNotNull(42));
|
||||||
|
Expect.equals(42, ArgumentError.checkNotNull(42, "name"));
|
||||||
|
Expect.throwsArgumentError(() => ArgumentError.checkNotNull(null));
|
||||||
|
|
||||||
|
Expect.equals(1, RangeError.checkNotNegative(1));
|
||||||
|
Expect.equals(0, RangeError.checkNotNegative(0));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkNotNegative(-1));
|
||||||
|
|
||||||
|
Expect.equals(1, RangeError.checkValueInInterval(1, 0, 2));
|
||||||
|
Expect.equals(1, RangeError.checkValueInInterval(1, 1, 2));
|
||||||
|
Expect.equals(1, RangeError.checkValueInInterval(1, 0, 1));
|
||||||
|
Expect.equals(1, RangeError.checkValueInInterval(1, 1, 1));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValueInInterval(1, 2, 3));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValueInInterval(1, 1, 0));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValueInInterval(0, 1, 0));
|
||||||
|
|
||||||
|
Expect.equals(1, RangeError.checkValidIndex(1, [1, 2]));
|
||||||
|
Expect.equals(1, RangeError.checkValidIndex(1, null, null, 2));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValidIndex(1, []));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValidIndex(1, null, null, 1));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValidIndex(-1, [1, 2, 3]));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValidIndex(-1, null, null, 3));
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,4 +74,27 @@ main() {
|
||||||
"RangeError: Index out of range: "
|
"RangeError: Index out of range: "
|
||||||
"index must not be negative: -5",
|
"index must not be negative: -5",
|
||||||
new RangeError.index(-5, [1, 2, 3]).toString());
|
new RangeError.index(-5, [1, 2, 3]).toString());
|
||||||
|
|
||||||
|
Expect.equals(42, ArgumentError.checkNotNull(42));
|
||||||
|
Expect.equals(42, ArgumentError.checkNotNull(42, "name"));
|
||||||
|
Expect.throwsArgumentError(() => ArgumentError.checkNotNull(null));
|
||||||
|
|
||||||
|
Expect.equals(1, RangeError.checkNotNegative(1));
|
||||||
|
Expect.equals(0, RangeError.checkNotNegative(0));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkNotNegative(-1));
|
||||||
|
|
||||||
|
Expect.equals(1, RangeError.checkValueInInterval(1, 0, 2));
|
||||||
|
Expect.equals(1, RangeError.checkValueInInterval(1, 1, 2));
|
||||||
|
Expect.equals(1, RangeError.checkValueInInterval(1, 0, 1));
|
||||||
|
Expect.equals(1, RangeError.checkValueInInterval(1, 1, 1));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValueInInterval(1, 2, 3));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValueInInterval(1, 1, 0));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValueInInterval(0, 1, 0));
|
||||||
|
|
||||||
|
Expect.equals(1, RangeError.checkValidIndex(1, [1, 2]));
|
||||||
|
Expect.equals(1, RangeError.checkValidIndex(1, null, null, 2));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValidIndex(1, []));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValidIndex(1, null, null, 1));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValidIndex(-1, [1, 2, 3]));
|
||||||
|
Expect.throwsRangeError(() => RangeError.checkValidIndex(-1, null, null, 3));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue