// Copyright (c) 2016, 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.md file.

library _fe_analyzer_shared.scanner;

import 'dart:convert' show unicodeReplacementCharacterRune, utf8;

import 'token.dart' show Token;

import 'abstract_scanner.dart'
    show LanguageVersionChanged, ScannerConfiguration;

import 'string_scanner.dart' show StringScanner;

import 'utf8_bytes_scanner.dart' show Utf8BytesScanner;

import 'recover.dart' show scannerRecovery;

export 'abstract_scanner.dart'
    show LanguageVersionChanged, ScannerConfiguration;

export 'token_impl.dart'
    show
        LanguageVersionToken,
        StringToken,
        isBinaryOperator,
        isMinusOperator,
        isTernaryOperator,
        isUnaryOperator,
        isUserDefinableOperator;

export 'error_token.dart' show ErrorToken, buildUnexpectedCharacterToken;

export 'token_impl.dart' show LanguageVersionToken;

export 'token_constants.dart' show EOF_TOKEN;

export 'utf8_bytes_scanner.dart' show Utf8BytesScanner;

export 'string_scanner.dart' show StringScanner;

export 'token.dart' show Keyword, Token;

const int unicodeReplacementCharacter = unicodeReplacementCharacterRune;

typedef Token Recover(List<int> bytes, Token tokens, List<int> lineStarts);

abstract class Scanner {
  /// Returns true if an error occurred during [tokenize].
  bool get hasErrors;

  List<int> get lineStarts;

  /// Configure which tokens are produced.
  set configuration(ScannerConfiguration config);

  Token tokenize();
}

class ScannerResult {
  final Token tokens;
  final List<int> lineStarts;
  final bool hasErrors;

  ScannerResult(this.tokens, this.lineStarts, this.hasErrors);
}

/// Scan/tokenize the given UTF8 [bytes].
ScannerResult scan(List<int> bytes,
    {ScannerConfiguration? configuration,
    bool includeComments: false,
    LanguageVersionChanged? languageVersionChanged}) {
  if (bytes.last != 0) {
    throw new ArgumentError("[bytes]: the last byte must be null.");
  }
  Scanner scanner = new Utf8BytesScanner(bytes,
      configuration: configuration,
      includeComments: includeComments,
      languageVersionChanged: languageVersionChanged);
  return _tokenizeAndRecover(scanner, bytes: bytes);
}

/// Scan/tokenize the given [source].
ScannerResult scanString(String source,
    {ScannerConfiguration? configuration,
    bool includeComments: false,
    LanguageVersionChanged? languageVersionChanged}) {
  // ignore: unnecessary_null_comparison
  assert(source != null, 'source must not be null');
  StringScanner scanner = new StringScanner(source,
      configuration: configuration,
      includeComments: includeComments,
      languageVersionChanged: languageVersionChanged);
  return _tokenizeAndRecover(scanner, source: source);
}

ScannerResult _tokenizeAndRecover(Scanner scanner,
    {List<int>? bytes, String? source}) {
  Token tokens = scanner.tokenize();
  if (scanner.hasErrors) {
    if (bytes == null) bytes = utf8.encode(source!);
    tokens = scannerRecovery(bytes, tokens, scanner.lineStarts);
  }
  return new ScannerResult(tokens, scanner.lineStarts, scanner.hasErrors);
}
