// 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,
        has63BitSmis,
        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:ffi" show Pointer, Struct, Union;

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 "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";
}
