// Copyright (c) 2013, 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.

/// Note: the VM concatenates all patch files into a single patch file. This
/// file is the first patch in "dart:core" which contains all the imports
/// used by patches of that library. We plan to change this when we have a
/// shared front end and simply use parts.

import "dart:_internal" as internal show Symbol;

import "dart:_internal"
    show
        allocateOneByteString,
        allocateTwoByteString,
        ClassID,
        CodeUnits,
        copyRangeFromUint8ListToOneByteString,
        EfficientLengthIterable,
        FixedLengthListBase,
        IterableElementError,
        ListIterator,
        Lists,
        POWERS_OF_TEN,
        SubListIterable,
        UnmodifiableListBase,
        is64Bit,
        makeFixedListUnmodifiable,
        makeListFixedLength,
        patch,
        unsafeCast,
        writeIntoOneByteString,
        writeIntoTwoByteString;

import "dart:async" show Completer, DeferredLoadException, Future, Timer;

import "dart:collection"
    show
        HashMap,
        IterableBase,
        LinkedHashMap,
        LinkedList,
        LinkedListEntry,
        ListBase,
        MapBase,
        Maps,
        UnmodifiableMapBase,
        UnmodifiableMapView;

import "dart:convert" show ascii, Encoding, json, latin1, utf8;

import "dart:isolate" show Isolate;

import "dart:math" show Random;

import "dart:typed_data"
    show Endian, Uint8List, Int64List, Uint16List, Uint32List;

/// These are the additional parts of this patch library:
// part "array.dart";
// part "array_patch.dart";
// part "bigint_patch.dart";
// part "bool_patch.dart";
// part "date_patch.dart";
// part "double.dart";
// part "double_patch.dart";
// part "errors_patch.dart";
// part "expando_patch.dart";
// part "function.dart";
// part "function_patch.dart";
// part "growable_array.dart";
// part "identical_patch.dart";
// part "immutable_map.dart";
// part "integers.dart";
// part "integers_patch.dart";
// part "invocation_mirror_patch.dart";
// part "lib_prefix.dart";
// part "map_patch.dart";
// part "null_patch.dart";
// part "object_patch.dart";
// part "regexp_patch.dart";
// part "stacktrace.dart";
// part "stopwatch_patch.dart";
// part "string_buffer_patch.dart";
// part "string_patch.dart";
// part "type_patch.dart";
// part "uri_patch.dart";
// part "weak_property.dart";

@patch
class num {
  num _addFromInteger(int other);
  num _subFromInteger(int other);
  num _mulFromInteger(int other);
  int _truncDivFromInteger(int other);
  num _moduloFromInteger(int other);
  num _remainderFromInteger(int other);
  bool _greaterThanFromInteger(int other);
  bool _equalToInteger(int other);
}

// _SyncIterable and _syncIterator are used by the compiler to
// implement sync* generator functions. A sync* generator allocates
// and returns a new _SyncIterable object.

typedef _SyncGeneratorCallback<T> = bool Function(
    _SyncIterator<T>, Object?, StackTrace?);
typedef _SyncGeneratorCallbackCallback<T> = _SyncGeneratorCallback<T>
    Function();

class _SyncIterable<T> extends IterableBase<T> {
  // Closure that effectively "clones" the inner _moveNextFn.
  // This means a _SyncIterable creates _SyncIterators that do not share state.
  final _SyncGeneratorCallbackCallback<T> _moveNextFnMaker;

  const _SyncIterable(this._moveNextFnMaker);

  Iterator<T> get iterator {
    return _SyncIterator<T>(_moveNextFnMaker());
  }
}

class _SyncIterator<T> implements Iterator<T> {
  _SyncGeneratorCallback<T>? _moveNextFn;
  Iterator<T>? _yieldEachIterator;

  // Stack of suspended _moveNextFn (sync_op).
  List<_SyncGeneratorCallback<T>>? _stack;

  // These two fields are set by generated code for the yield and yield*
  // statement.
  T? _current;
  Iterable<T>? _yieldEachIterable;

  @override
  T get current => _current as T;

  _SyncIterator(this._moveNextFn);

  @pragma('vm:prefer-inline')
  bool _handleMoveNextFnCompletion() {
    _moveNextFn = null;
    _current = null;
    final stack = _stack;
    if (stack != null && stack.isNotEmpty) {
      _moveNextFn = stack.removeLast();
      return true;
    }
    return false;
  }

  @override
  bool moveNext() {
    if (_moveNextFn == null) {
      return false;
    }

    Object? pendingException;
    StackTrace? pendingStackTrace;
    while (true) {
      // If the active iterator isn't a nested _SyncIterator, we have to
      // delegate downwards from the immediate iterator.
      final iterator = _yieldEachIterator;
      if (iterator != null) {
        try {
          if (iterator.moveNext()) {
            _current = iterator.current;
            return true;
          }
        } catch (e, st) {
          pendingException = e;
          pendingStackTrace = st;
        }
        _yieldEachIterator = null;
      }

      // Start by calling _moveNextFn (sync_op) to move to the next value (or
      // nested iterator).
      try {
        final haveMore =
            _moveNextFn!.call(this, pendingException, pendingStackTrace);
        // Exception was handled.
        pendingException = null;
        pendingStackTrace = null;
        if (!haveMore) {
          if (_handleMoveNextFnCompletion()) {
            continue;
          }
          return false;
        }
      } catch (e, st) {
        pendingException = e;
        pendingStackTrace = st;
        if (_handleMoveNextFnCompletion()) {
          continue;
        }
        rethrow;
      }

      // Case: yield* some_iterator.
      final iterable = _yieldEachIterable;
      if (iterable != null) {
        if (iterable is _SyncIterable) {
          // We got a recursive yield* of sync* function. Instead of creating
          // a new iterator we replace our _moveNextFn (remembering the
          // current _moveNextFn for later resumption).
          if (_stack == null) {
            _stack = [];
          }
          _stack!.add(_moveNextFn!);
          final typedIterable = unsafeCast<_SyncIterable<T>>(iterable);

          _moveNextFn = typedIterable._moveNextFnMaker();
        } else {
          _yieldEachIterator = iterable.iterator;
        }
        _yieldEachIterable = null;
        _current = null;

        // Fetch the next item.
        continue;
      }

      // We've successfully found the next `current` value.
      return true;
    }
  }
}

@patch
class StackTrace {
  @patch
  static StackTrace get current native "StackTrace_current";
}
