Deprecate HasNextIterator.

Bug: https://dartbug.com/50883
Change-Id: I983e07072052a0538e4c04cc66e7fd2ad2bc1242
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278121
Reviewed-by: Michael Thomsen <mit@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
This commit is contained in:
Lasse R.H. Nielsen 2023-01-09 12:14:33 +00:00 committed by Commit Queue
parent 54da3e4608
commit 8a891ba869
2 changed files with 44 additions and 27 deletions

View file

@ -69,6 +69,12 @@
[`DeferredLibrary`]: https://api.dart.dev/stable/2.18.4/dart-async/DeferredLibrary-class.html
[`deferred as`]: https://dart.dev/guides/language/language-tour#deferred-loading
#### `dart:collection`
- Deprecated the `HasNextIterator` class ([#50883][]).
[#50883]: https://github.com/dart-lang/sdk/issues/50883
#### `dart:developer`
- **Breaking change** [#49529][]:

View file

@ -4,40 +4,51 @@
part of dart.collection;
/// The [HasNextIterator] class wraps an [Iterator] and provides methods to
/// iterate over an object using `hasNext` and `next`.
/// Wrapper for [Iterator] providing the pre-Dart 1.0 iterator interface.
///
/// An [HasNextIterator] does not implement the [Iterator] interface.
/// This class should not be used in new code.
///
/// The [HasNextIterator] class wraps an [Iterator] and provides methods to
/// iterate over an object using [hasNext] and [next].
///
/// The [HasNextIterator] does not implement the [Iterator] interface.
///
/// This class was intended for migration to the current [Iterator]
/// interface, from an earlier interface using [hasNext] and [next].
/// The API change happened in the Dart 1.0 release.
/// Any other use of this class should be migrated to using the
/// current API directly, e.g., using a separate variable to
/// cache the [Iterator.moveNext] result, so that [hasNext] can be
/// checked multiple times.
@Deprecated("Will be removed in a later version of the Dart SDK")
class HasNextIterator<E> {
static const int _HAS_NEXT_AND_NEXT_IN_CURRENT = 0;
static const int _NO_NEXT = 1;
static const int _NOT_MOVED_YET = 2;
Iterator<E> _iterator;
int _state = _NOT_MOVED_YET;
HasNextIterator(this._iterator);
/// Cache for `_iterator.moveNext()`, used by `hasNext`.
///
/// Is reset to `null` when [next] consumes a current element.
/// Will not change again after becoming `false`.
bool? _hasNext;
bool get hasNext {
if (_state == _NOT_MOVED_YET) _move();
return _state == _HAS_NEXT_AND_NEXT_IN_CURRENT;
}
HasNextIterator(Iterator<E> iterator) : _iterator = iterator;
/// Whether the iterator has a next element.
///
/// Should be checked to be `true` before calling [next].
bool get hasNext => _ensureHasNext;
/// Ensures [_hasNext] has a value, and provides that value.
bool get _ensureHasNext => _hasNext ??= _iterator.moveNext();
/// Provides the next element of the iterable, and moves past it.
///
/// Must only be used when [hasNext] is `true`.
/// The value of [hasNext] can change after calling this method.
E next() {
// Call to hasNext is necessary to make sure we are positioned at the first
// element when we start iterating.
if (!hasNext) throw StateError("No more elements");
assert(_state == _HAS_NEXT_AND_NEXT_IN_CURRENT);
E result = _iterator.current;
_move();
return result;
}
void _move() {
if (_iterator.moveNext()) {
_state = _HAS_NEXT_AND_NEXT_IN_CURRENT;
} else {
_state = _NO_NEXT;
if (_ensureHasNext) {
_hasNext = null;
return _iterator.current;
}
throw StateError("No more elements");
}
}