Remove some unnecessary dynamic invocations in the platform libraries.
Change-Id: Ia72033e37c4d8292eabd95aeff97e4cb29e81823 Reviewed-on: https://dart-review.googlesource.com/c/82204 Commit-Queue: Lasse R.H. Nielsen <lrn@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
6d9dc93d0e
commit
5226b5c307
@@ -344,10 +344,12 @@ class DateTime {
|
||||
int get weekday => Primitives.getWeekday(this);
|
||||
|
||||
@patch
|
||||
bool operator ==(Object other) =>
|
||||
other is DateTime &&
|
||||
_value == other.millisecondsSinceEpoch &&
|
||||
isUtc == other.isUtc;
|
||||
bool operator ==(dynamic other) {
|
||||
Object promotableOther = other;
|
||||
return promotableOther is DateTime &&
|
||||
_value == promotableOther.millisecondsSinceEpoch &&
|
||||
isUtc == promotableOther.isUtc;
|
||||
}
|
||||
|
||||
@patch
|
||||
bool isBefore(DateTime other) => _value < other.millisecondsSinceEpoch;
|
||||
|
||||
@@ -73,10 +73,12 @@ class DateTime {
|
||||
}
|
||||
|
||||
@patch
|
||||
bool operator ==(Object other) =>
|
||||
other is DateTime &&
|
||||
_value == other.microsecondsSinceEpoch &&
|
||||
isUtc == other.isUtc;
|
||||
bool operator ==(dynamic other) {
|
||||
Object promotableOther = other;
|
||||
return promotableOther is DateTime &&
|
||||
_value == promotableOther.microsecondsSinceEpoch &&
|
||||
isUtc == promotableOther.isUtc;
|
||||
}
|
||||
|
||||
@patch
|
||||
bool isBefore(DateTime other) => _value < other.microsecondsSinceEpoch;
|
||||
|
||||
@@ -377,10 +377,12 @@ class DateTime {
|
||||
int get weekday => Primitives.getWeekday(this);
|
||||
|
||||
@patch
|
||||
bool operator ==(Object other) =>
|
||||
other is DateTime &&
|
||||
_value == other.millisecondsSinceEpoch &&
|
||||
isUtc == other.isUtc;
|
||||
bool operator ==(dynamic other) {
|
||||
Object promotableOther = other;
|
||||
return promotableOther is DateTime &&
|
||||
_value == promotableOther.millisecondsSinceEpoch &&
|
||||
isUtc == promotableOther.isUtc;
|
||||
}
|
||||
|
||||
@patch
|
||||
bool isBefore(DateTime other) => _value < other.millisecondsSinceEpoch;
|
||||
|
||||
@@ -7,6 +7,10 @@ part of dart.async;
|
||||
_invokeErrorHandler(
|
||||
Function errorHandler, Object error, StackTrace stackTrace) {
|
||||
if (errorHandler is ZoneBinaryCallback<dynamic, Null, Null>) {
|
||||
// Dynamic invocation because we don't know the actual type of the
|
||||
// first argument or the error object, but we should successfully call
|
||||
// the handler if they match up.
|
||||
// TODO(lrn): Should we? Why not the same below for the unary case?
|
||||
return (errorHandler as dynamic)(error, stackTrace);
|
||||
} else {
|
||||
ZoneUnaryCallback unaryErrorHandler = errorHandler;
|
||||
|
||||
@@ -57,11 +57,7 @@ class _BroadcastSubscription<T> extends _ControllerSubscription<T> {
|
||||
}
|
||||
|
||||
abstract class _BroadcastStreamController<T>
|
||||
implements
|
||||
StreamController<T>,
|
||||
_StreamControllerLifecycle<T>,
|
||||
_EventSink<T>,
|
||||
_EventDispatch<T> {
|
||||
implements _StreamControllerBase<T> {
|
||||
static const int _STATE_INITIAL = 0;
|
||||
static const int _STATE_EVENT_ID = 1;
|
||||
static const int _STATE_FIRING = 2;
|
||||
|
||||
@@ -312,10 +312,14 @@ abstract class Future<T> {
|
||||
factory Future.delayed(Duration duration, [FutureOr<T> computation()]) {
|
||||
_Future<T> result = new _Future<T>();
|
||||
new Timer(duration, () {
|
||||
try {
|
||||
result._complete(computation?.call());
|
||||
} catch (e, s) {
|
||||
_completeWithErrorCallback(result, e, s);
|
||||
if (computation == null) {
|
||||
result._complete(null);
|
||||
} else {
|
||||
try {
|
||||
result._complete(computation());
|
||||
} catch (e, s) {
|
||||
_completeWithErrorCallback(result, e, s);
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
@@ -521,7 +525,7 @@ abstract class Future<T> {
|
||||
*/
|
||||
static Future doWhile(FutureOr<bool> action()) {
|
||||
_Future doneSignal = new _Future();
|
||||
var nextIteration;
|
||||
void Function(bool) nextIteration;
|
||||
// Bind this callback explicitly so that each iteration isn't bound in the
|
||||
// context of all the previous iterations' callbacks.
|
||||
// This avoids, e.g., deeply nested stack traces from the stack trace
|
||||
|
||||
@@ -426,15 +426,14 @@ abstract class Stream<T> {
|
||||
* The returned stream is a broadcast stream if this stream is.
|
||||
*/
|
||||
Stream<E> asyncMap<E>(FutureOr<E> convert(T event)) {
|
||||
StreamController<E> controller;
|
||||
_StreamControllerBase<E> controller;
|
||||
StreamSubscription<T> subscription;
|
||||
|
||||
void onListen() {
|
||||
final add = controller.add;
|
||||
assert(controller is _StreamController ||
|
||||
assert(controller is _StreamController<E> ||
|
||||
controller is _BroadcastStreamController);
|
||||
final _EventSink<E> eventSink = controller as Object;
|
||||
final addError = eventSink._addError;
|
||||
final addError = controller._addError;
|
||||
subscription = this.listen((T event) {
|
||||
FutureOr<E> newValue;
|
||||
try {
|
||||
@@ -495,12 +494,11 @@ abstract class Stream<T> {
|
||||
* The returned stream is a broadcast stream if this stream is.
|
||||
*/
|
||||
Stream<E> asyncExpand<E>(Stream<E> convert(T event)) {
|
||||
StreamController<E> controller;
|
||||
_StreamControllerBase<E> controller;
|
||||
StreamSubscription<T> subscription;
|
||||
void onListen() {
|
||||
assert(controller is _StreamController ||
|
||||
controller is _BroadcastStreamController);
|
||||
final _EventSink<E> eventSink = controller as Object;
|
||||
subscription = this.listen((T event) {
|
||||
Stream<E> newStream;
|
||||
try {
|
||||
@@ -514,7 +512,7 @@ abstract class Stream<T> {
|
||||
controller.addStream(newStream).whenComplete(subscription.resume);
|
||||
}
|
||||
},
|
||||
onError: eventSink._addError, // Avoid Zone error replacement.
|
||||
onError: controller._addError, // Avoid Zone error replacement.
|
||||
onDone: controller.close);
|
||||
}
|
||||
|
||||
@@ -1474,7 +1472,7 @@ abstract class Stream<T> {
|
||||
* and the subscriptions' timers can be paused individually.
|
||||
*/
|
||||
Stream<T> timeout(Duration timeLimit, {void onTimeout(EventSink<T> sink)}) {
|
||||
StreamController<T> controller;
|
||||
_StreamControllerBase<T> controller;
|
||||
// The following variables are set on listen.
|
||||
StreamSubscription<T> subscription;
|
||||
Timer timer;
|
||||
@@ -1491,8 +1489,7 @@ abstract class Stream<T> {
|
||||
timer.cancel();
|
||||
assert(controller is _StreamController ||
|
||||
controller is _BroadcastStreamController);
|
||||
dynamic eventSink = controller;
|
||||
eventSink._addError(error, stackTrace); // Avoid Zone error replacement.
|
||||
controller._addError(error, stackTrace); // Avoid Zone error replacement.
|
||||
timer = zone.createTimer(timeLimit, timeout);
|
||||
}
|
||||
|
||||
|
||||
@@ -381,17 +381,20 @@ abstract class _StreamControllerLifecycle<T> {
|
||||
Future _recordCancel(StreamSubscription<T> subscription) => null;
|
||||
}
|
||||
|
||||
// Base type for implementations of stream controllers.
|
||||
abstract class _StreamControllerBase<T>
|
||||
implements
|
||||
StreamController<T>,
|
||||
_StreamControllerLifecycle<T>,
|
||||
_EventSink<T>,
|
||||
_EventDispatch<T> {}
|
||||
|
||||
/**
|
||||
* Default implementation of [StreamController].
|
||||
*
|
||||
* Controls a stream that only supports a single controller.
|
||||
*/
|
||||
abstract class _StreamController<T>
|
||||
implements
|
||||
StreamController<T>,
|
||||
_StreamControllerLifecycle<T>,
|
||||
_EventSink<T>,
|
||||
_EventDispatch<T> {
|
||||
abstract class _StreamController<T> implements _StreamControllerBase<T> {
|
||||
// The states are bit-flags. More than one can be set at a time.
|
||||
//
|
||||
// The "subscription state" goes through the states:
|
||||
|
||||
@@ -238,7 +238,7 @@ abstract class IterableBase<E> extends Iterable<E> {
|
||||
}
|
||||
return "$leftDelimiter...$rightDelimiter";
|
||||
}
|
||||
List parts = [];
|
||||
List<String> parts = <String>[];
|
||||
_toStringVisiting.add(iterable);
|
||||
try {
|
||||
_iterablePartsToStrings(iterable, parts);
|
||||
@@ -296,7 +296,7 @@ bool _isToStringVisiting(Object o) {
|
||||
/**
|
||||
* Convert elements of [iterable] to strings and store them in [parts].
|
||||
*/
|
||||
void _iterablePartsToStrings(Iterable iterable, List parts) {
|
||||
void _iterablePartsToStrings(Iterable iterable, List<String> parts) {
|
||||
/*
|
||||
* This is the complicated part of [iterableToShortString].
|
||||
* It is extracted as a separate function to avoid having too much code
|
||||
@@ -337,8 +337,8 @@ void _iterablePartsToStrings(Iterable iterable, List parts) {
|
||||
|
||||
// Find last two elements. One or more of them may already be in the
|
||||
// parts array. Include their length in `length`.
|
||||
var penultimate = null;
|
||||
var ultimate = null;
|
||||
Object penultimate = null;
|
||||
Object ultimate = null;
|
||||
if (!it.moveNext()) {
|
||||
if (count <= headCount + tailCount) return;
|
||||
ultimateString = parts.removeLast();
|
||||
|
||||
@@ -13,9 +13,10 @@ abstract class Encoding extends Codec<String, List<int>> {
|
||||
|
||||
Future<String> decodeStream(Stream<List<int>> byteStream) {
|
||||
return byteStream
|
||||
.transform(decoder)
|
||||
.fold(StringBuffer(), (buffer, string) => buffer..write(string))
|
||||
.then((buffer) => buffer.toString());
|
||||
.transform<String>(decoder)
|
||||
.fold(StringBuffer(),
|
||||
(StringBuffer buffer, String string) => buffer..write(string))
|
||||
.then((StringBuffer buffer) => buffer.toString());
|
||||
}
|
||||
|
||||
/// Name of the encoding.
|
||||
|
||||
@@ -404,7 +404,7 @@ class DateTime implements Comparable<DateTime> {
|
||||
* See [isAtSameMomentAs] for a comparison that compares moments in time
|
||||
* independently of their zones.
|
||||
*/
|
||||
external bool operator ==(other);
|
||||
external bool operator ==(dynamic other);
|
||||
|
||||
/**
|
||||
* Returns true if [this] occurs before [other].
|
||||
|
||||
+16
-16
@@ -23,32 +23,31 @@ part of dart.core;
|
||||
*
|
||||
* To create a new Duration object, use this class's single constructor
|
||||
* giving the appropriate arguments:
|
||||
*
|
||||
* Duration fastestMarathon = new Duration(hours:2, minutes:3, seconds:2);
|
||||
*
|
||||
* ```dart
|
||||
* Duration fastestMarathon = new Duration(hours:2, minutes:3, seconds:2);
|
||||
* ```
|
||||
* The [Duration] is the sum of all individual parts.
|
||||
* This means that individual parts can be larger than the next-bigger unit.
|
||||
* For example, [inMinutes] can be greater than 59.
|
||||
*
|
||||
* assert(fastestMarathon.inMinutes == 123);
|
||||
*
|
||||
* ```dart
|
||||
* assert(fastestMarathon.inMinutes == 123);
|
||||
* ```
|
||||
* All individual parts are allowed to be negative.
|
||||
*
|
||||
* Use one of the properties, such as [inDays],
|
||||
* to retrieve the integer value of the Duration in the specified time unit.
|
||||
* Note that the returned value is rounded down.
|
||||
* For example,
|
||||
*
|
||||
* Duration aLongWeekend = new Duration(hours:88);
|
||||
* assert(aLongWeekend.inDays == 3);
|
||||
*
|
||||
* ```dart
|
||||
* Duration aLongWeekend = new Duration(hours:88);
|
||||
* assert(aLongWeekend.inDays == 3);
|
||||
* ```
|
||||
* This class provides a collection of arithmetic
|
||||
* and comparison operators,
|
||||
* plus a set of constants useful for converting time units.
|
||||
*
|
||||
* See [DateTime] to represent a point in time.
|
||||
* See [Stopwatch] to measure time-spans.
|
||||
*
|
||||
*/
|
||||
class Duration implements Comparable<Duration> {
|
||||
static const int microsecondsPerMillisecond = 1000;
|
||||
@@ -212,17 +211,18 @@ class Duration implements Comparable<Duration> {
|
||||
int get inMicroseconds => _duration;
|
||||
|
||||
/**
|
||||
* Returns `true` if this Duration is the same object as [other].
|
||||
* Returns `true` if this [Duration] is the same object as [other].
|
||||
*/
|
||||
bool operator ==(other) {
|
||||
if (other is! Duration) return false;
|
||||
return _duration == other._duration;
|
||||
bool operator ==(dynamic other) {
|
||||
Object promotableOther = other;
|
||||
return promotableOther is Duration &&
|
||||
_duration == promotableOther.inMicroseconds;
|
||||
}
|
||||
|
||||
int get hashCode => _duration.hashCode;
|
||||
|
||||
/**
|
||||
* Compares this Duration to [other], returning zero if the values are equal.
|
||||
* Compares this [Duration] to [other], returning zero if the values are equal.
|
||||
*
|
||||
* Returns a negative integer if this `Duration` is shorter than
|
||||
* [other], or a positive integer if it is longer.
|
||||
|
||||
@@ -265,7 +265,7 @@ class RangeError extends ArgumentError {
|
||||
* The [length] is the length of [indexable] at the time of the error.
|
||||
* If `length` is omitted, it defaults to `indexable.length`.
|
||||
*/
|
||||
factory RangeError.index(int index, indexable,
|
||||
factory RangeError.index(int index, dynamic indexable,
|
||||
[String name, String message, int length]) = IndexError;
|
||||
|
||||
/**
|
||||
@@ -292,9 +292,9 @@ class RangeError extends ArgumentError {
|
||||
* If [length] is provided, it is used as the length of the indexable object,
|
||||
* otherwise the length is found as `indexable.length`.
|
||||
*/
|
||||
static void checkValidIndex(int index, var indexable,
|
||||
static void checkValidIndex(int index, dynamic indexable,
|
||||
[String name, int length, String message]) {
|
||||
if (length == null) length = indexable.length;
|
||||
length ??= indexable.length;
|
||||
// Comparing with `0` as receiver produces better dart2js type inference.
|
||||
if (0 > index || index >= length) {
|
||||
if (name == null) name = "index";
|
||||
@@ -390,10 +390,10 @@ class IndexError extends ArgumentError implements RangeError {
|
||||
*
|
||||
* The message is used as part of the string representation of the error.
|
||||
*/
|
||||
IndexError(int invalidValue, indexable,
|
||||
IndexError(int invalidValue, dynamic indexable,
|
||||
[String name, String message, int length])
|
||||
: this.indexable = indexable,
|
||||
this.length = (length != null) ? length : indexable.length,
|
||||
this.length = length ?? indexable.length,
|
||||
super.value(invalidValue, name,
|
||||
(message != null) ? message : "Index out of range");
|
||||
|
||||
@@ -404,6 +404,7 @@ class IndexError extends ArgumentError implements RangeError {
|
||||
String get _errorName => "RangeError";
|
||||
String get _errorExplanation {
|
||||
assert(_hasValue);
|
||||
int invalidValue = this.invalidValue;
|
||||
if (invalidValue < 0) {
|
||||
return ": index must not be negative";
|
||||
}
|
||||
|
||||
@@ -98,78 +98,81 @@ class FormatException implements Exception {
|
||||
report = "$report: $message";
|
||||
}
|
||||
int offset = this.offset;
|
||||
if (source is! String) {
|
||||
Object objectSource = this.source;
|
||||
if (objectSource is String) {
|
||||
String source = objectSource;
|
||||
if (offset != null && (offset < 0 || offset > source.length)) {
|
||||
offset = null;
|
||||
}
|
||||
// Source is string and offset is null or valid.
|
||||
if (offset == null) {
|
||||
if (source.length > 78) {
|
||||
source = source.substring(0, 75) + "...";
|
||||
}
|
||||
return "$report\n$source";
|
||||
}
|
||||
int lineNum = 1;
|
||||
int lineStart = 0;
|
||||
bool previousCharWasCR = false;
|
||||
for (int i = 0; i < offset; i++) {
|
||||
int char = source.codeUnitAt(i);
|
||||
if (char == 0x0a) {
|
||||
if (lineStart != i || !previousCharWasCR) {
|
||||
lineNum++;
|
||||
}
|
||||
lineStart = i + 1;
|
||||
previousCharWasCR = false;
|
||||
} else if (char == 0x0d) {
|
||||
lineNum++;
|
||||
lineStart = i + 1;
|
||||
previousCharWasCR = true;
|
||||
}
|
||||
}
|
||||
if (lineNum > 1) {
|
||||
report += " (at line $lineNum, character ${offset - lineStart + 1})\n";
|
||||
} else {
|
||||
report += " (at character ${offset + 1})\n";
|
||||
}
|
||||
int lineEnd = source.length;
|
||||
for (int i = offset; i < source.length; i++) {
|
||||
int char = source.codeUnitAt(i);
|
||||
if (char == 0x0a || char == 0x0d) {
|
||||
lineEnd = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int length = lineEnd - lineStart;
|
||||
int start = lineStart;
|
||||
int end = lineEnd;
|
||||
String prefix = "";
|
||||
String postfix = "";
|
||||
if (length > 78) {
|
||||
// Can't show entire line. Try to anchor at the nearest end, if
|
||||
// one is within reach.
|
||||
int index = offset - lineStart;
|
||||
if (index < 75) {
|
||||
end = start + 75;
|
||||
postfix = "...";
|
||||
} else if (end - offset < 75) {
|
||||
start = end - 75;
|
||||
prefix = "...";
|
||||
} else {
|
||||
// Neither end is near, just pick an area around the offset.
|
||||
start = offset - 36;
|
||||
end = offset + 36;
|
||||
prefix = postfix = "...";
|
||||
}
|
||||
}
|
||||
String slice = source.substring(start, end);
|
||||
int markOffset = offset - start + prefix.length;
|
||||
return "$report$prefix$slice$postfix\n${" " * markOffset}^\n";
|
||||
} else {
|
||||
// The source is not a string.
|
||||
if (offset != null) {
|
||||
report += " (at offset $offset)";
|
||||
}
|
||||
return report;
|
||||
}
|
||||
if (offset != null && (offset < 0 || offset > source.length)) {
|
||||
offset = null;
|
||||
}
|
||||
// Source is string and offset is null or valid.
|
||||
if (offset == null) {
|
||||
String source = this.source;
|
||||
if (source.length > 78) {
|
||||
source = source.substring(0, 75) + "...";
|
||||
}
|
||||
return "$report\n$source";
|
||||
}
|
||||
int lineNum = 1;
|
||||
int lineStart = 0;
|
||||
bool previousCharWasCR = false;
|
||||
for (int i = 0; i < offset; i++) {
|
||||
int char = source.codeUnitAt(i);
|
||||
if (char == 0x0a) {
|
||||
if (lineStart != i || !previousCharWasCR) {
|
||||
lineNum++;
|
||||
}
|
||||
lineStart = i + 1;
|
||||
previousCharWasCR = false;
|
||||
} else if (char == 0x0d) {
|
||||
lineNum++;
|
||||
lineStart = i + 1;
|
||||
previousCharWasCR = true;
|
||||
}
|
||||
}
|
||||
if (lineNum > 1) {
|
||||
report += " (at line $lineNum, character ${offset - lineStart + 1})\n";
|
||||
} else {
|
||||
report += " (at character ${offset + 1})\n";
|
||||
}
|
||||
int lineEnd = source.length;
|
||||
for (int i = offset; i < source.length; i++) {
|
||||
int char = source.codeUnitAt(i);
|
||||
if (char == 0x0a || char == 0x0d) {
|
||||
lineEnd = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int length = lineEnd - lineStart;
|
||||
int start = lineStart;
|
||||
int end = lineEnd;
|
||||
String prefix = "";
|
||||
String postfix = "";
|
||||
if (length > 78) {
|
||||
// Can't show entire line. Try to anchor at the nearest end, if
|
||||
// one is within reach.
|
||||
int index = offset - lineStart;
|
||||
if (index < 75) {
|
||||
end = start + 75;
|
||||
postfix = "...";
|
||||
} else if (end - offset < 75) {
|
||||
start = end - 75;
|
||||
prefix = "...";
|
||||
} else {
|
||||
// Neither end is near, just pick an area around the offset.
|
||||
start = offset - 36;
|
||||
end = offset + 36;
|
||||
prefix = postfix = "...";
|
||||
}
|
||||
}
|
||||
String slice = source.substring(start, end);
|
||||
int markOffset = offset - start + prefix.length;
|
||||
return "$report$prefix$slice$postfix\n${" " * markOffset}^\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2114,7 +2114,7 @@ class _Uri implements Uri {
|
||||
if (path != null && pathSegments != null) {
|
||||
throw new ArgumentError('Both path and pathSegments specified');
|
||||
}
|
||||
var result;
|
||||
String result;
|
||||
if (path != null) {
|
||||
result = _normalizeOrSubstring(path, start, end, _pathCharOrSlashTable,
|
||||
escapeDelimiters: true);
|
||||
@@ -2739,10 +2739,11 @@ class _Uri implements Uri {
|
||||
return _hashCodeCache ??= toString().hashCode;
|
||||
}
|
||||
|
||||
static List _createList() => [];
|
||||
static List<String> _createList() => <String>[];
|
||||
|
||||
static Map _splitQueryStringAll(String query, {Encoding encoding: utf8}) {
|
||||
Map result = {};
|
||||
static Map<String, List<String>> _splitQueryStringAll(String query,
|
||||
{Encoding encoding: utf8}) {
|
||||
var result = <String, List<String>>{};
|
||||
int i = 0;
|
||||
int start = 0;
|
||||
int equalsIndex = -1;
|
||||
@@ -3316,7 +3317,7 @@ class UriData {
|
||||
buffer.write(";charset=");
|
||||
buffer.write(_Uri._uriEncode(_tokenCharTable, charsetName, utf8, false));
|
||||
}
|
||||
parameters?.forEach((var key, var value) {
|
||||
parameters?.forEach((key, value) {
|
||||
if (key.isEmpty) {
|
||||
throw new ArgumentError.value("", "Parameter names must not be empty");
|
||||
}
|
||||
|
||||
@@ -554,8 +554,9 @@ class Isolate {
|
||||
StreamController controller;
|
||||
RawReceivePort port;
|
||||
void handleError(message) {
|
||||
String errorDescription = message[0];
|
||||
String stackDescription = message[1];
|
||||
List listMessage = message;
|
||||
String errorDescription = listMessage[0];
|
||||
String stackDescription = listMessage[1];
|
||||
var error = new RemoteError(errorDescription, stackDescription);
|
||||
controller.addError(error, error.stackTrace);
|
||||
}
|
||||
|
||||
@@ -23,9 +23,13 @@ class Point<T extends num> {
|
||||
* `other` is a `Point` with
|
||||
* [x] equal to `other.x` and [y] equal to `other.y`.
|
||||
*/
|
||||
bool operator ==(other) {
|
||||
if (other is! Point) return false;
|
||||
return x == other.x && y == other.y;
|
||||
bool operator ==(dynamic other) {
|
||||
// Cannot change parameter type to `Object` in case some class
|
||||
// inherits the type and uses their argument dynamically.
|
||||
Object promotableOther = other;
|
||||
return promotableOther is Point &&
|
||||
x == promotableOther.x &&
|
||||
y == promotableOther.y;
|
||||
}
|
||||
|
||||
int get hashCode => _JenkinsSmiHash.hash2(x.hashCode, y.hashCode);
|
||||
|
||||
@@ -38,12 +38,15 @@ abstract class _RectangleBase<T extends num> {
|
||||
return 'Rectangle ($left, $top) $width x $height';
|
||||
}
|
||||
|
||||
bool operator ==(other) {
|
||||
if (other is! Rectangle) return false;
|
||||
return left == other.left &&
|
||||
top == other.top &&
|
||||
right == other.right &&
|
||||
bottom == other.bottom;
|
||||
bool operator ==(dynamic other) {
|
||||
// Can't change argument type to `Object` since subclasses inherit it
|
||||
// and uses their argument dynamically.
|
||||
Object promotableOther = other;
|
||||
return promotableOther is Rectangle &&
|
||||
left == promotableOther.left &&
|
||||
top == promotableOther.top &&
|
||||
right == promotableOther.right &&
|
||||
bottom == promotableOther.bottom;
|
||||
}
|
||||
|
||||
int get hashCode => _JenkinsSmiHash.hash4(
|
||||
|
||||
@@ -68,12 +68,6 @@
|
||||
"Dynamic invocation of 'call'.": 4,
|
||||
"Dynamic invocation of 'then'.": 1
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/async/future.dart": {
|
||||
"Dynamic invocation of 'call'.": 1
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/async/stream.dart": {
|
||||
"Dynamic invocation of 'dart.async::_addError'.": 1
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/async/async_error.dart": {
|
||||
"Dynamic invocation of 'call'.": 1
|
||||
},
|
||||
@@ -90,10 +84,6 @@
|
||||
"Dynamic access of 'dart.collection::_element'.": 1,
|
||||
"Dynamic access of 'dart.collection::_first'.": 1
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/collection/iterable.dart": {
|
||||
"Dynamic access of 'length'.": 2,
|
||||
"Dynamic invocation of '+'.": 2
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/html/dart2js/html_dart2js.dart": {
|
||||
"Dynamic access of 'style'.": 1,
|
||||
"Dynamic access of 'left'.": 3,
|
||||
@@ -219,45 +209,15 @@
|
||||
"Dynamic invocation of '-'.": 1,
|
||||
"Dynamic invocation of '>='.": 1
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/core/duration.dart": {
|
||||
"Dynamic access of 'dart.core::_duration'.": 1
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/core/errors.dart": {
|
||||
"Dynamic access of 'length'.": 2,
|
||||
"Dynamic invocation of '<'.": 1
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/core/exceptions.dart": {
|
||||
"Dynamic access of 'length'.": 3,
|
||||
"Dynamic invocation of 'codeUnitAt'.": 2,
|
||||
"Dynamic invocation of 'substring'.": 1
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/core/uri.dart": {
|
||||
"Dynamic access of 'isEmpty'.": 1,
|
||||
"Dynamic invocation of 'startsWith'.": 1,
|
||||
"Dynamic invocation of 'add'.": 1
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/math/point.dart": {
|
||||
"Dynamic access of 'x'.": 1,
|
||||
"Dynamic access of 'y'.": 1
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/math/rectangle.dart": {
|
||||
"Dynamic access of 'left'.": 1,
|
||||
"Dynamic access of 'top'.": 1,
|
||||
"Dynamic access of 'right'.": 1,
|
||||
"Dynamic access of 'bottom'.": 1
|
||||
"Dynamic access of 'length'.": 2
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/_internal/js_runtime/lib/convert_patch.dart": {
|
||||
"Dynamic invocation of 'clear'.": 1
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/convert/encoding.dart": {
|
||||
"Dynamic invocation of 'write'.": 1
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/convert/json.dart": {
|
||||
"Dynamic invocation of 'toJson'.": 1
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/isolate/isolate.dart": {
|
||||
"Dynamic invocation of '[]'.": 2
|
||||
},
|
||||
"org-dartlang-sdk:///sdk/lib/_http/crypto.dart": {
|
||||
"Dynamic invocation of '+'.": 2,
|
||||
"Dynamic invocation of '&'.": 3,
|
||||
|
||||
Reference in New Issue
Block a user