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

import '../../scanner/token.dart' show Token;

import '../fasta_codes.dart' show Message, Template, templateExpectedIdentifier;

import '../scanner/token_constants.dart' show IDENTIFIER_TOKEN;

import 'identifier_context_impl.dart';

import 'parser.dart' show Parser;

/// Information about the parser state that is passed to the listener at the
/// time an identifier is encountered. It is also used by the parser for error
/// recovery when a recovery template is defined.
///
/// This can be used by the listener to determine the context in which the
/// identifier appears; that in turn can help the listener decide how to resolve
/// the identifier (if the listener is doing resolution).
class IdentifierContext {
  /// Identifier is being declared as the name of an import prefix (i.e. `Foo`
  /// in `import "..." as Foo;`)
  static const importPrefixDeclaration = const ImportPrefixIdentifierContext();

  /// Identifier is the start of a dotted name in a conditional import or
  /// export.
  static const dottedName = const DottedNameIdentifierContext();

  /// Identifier is part of a dotted name in a conditional import or export, but
  /// it's not the first identifier of the dotted name.
  static const dottedNameContinuation =
      const DottedNameIdentifierContext.continuation();

  /// Identifier is one of the shown/hidden names in an import/export
  /// combinator.
  static const combinator = const IdentifierContext('combinator');

  /// Identifier is the start of a name in an annotation that precedes a
  /// declaration (i.e. it appears directly after an `@`).
  static const metadataReference =
      const IdentifierContext('metadataReference', isScopeReference: true);

  /// Identifier is part of a name in an annotation that precedes a declaration,
  /// but it's not the first identifier in the name.
  static const metadataContinuation =
      const IdentifierContext('metadataContinuation', isContinuation: true);

  /// Identifier is part of a name in an annotation that precedes a declaration,
  /// but it appears after type parameters (e.g. `foo` in `@X<Y>.foo()`).
  static const metadataContinuationAfterTypeArguments = const IdentifierContext(
      'metadataContinuationAfterTypeArguments',
      isContinuation: true);

  /// Identifier is the name being declared by a typedef declaration.
  static const typedefDeclaration = const TypedefDeclarationIdentifierContext();

  /// Identifier is a field initializer in a formal parameter list (i.e. it
  /// appears directly after `this.`).
  static const fieldInitializer = const FieldInitializerIdentifierContext();

  /// Identifier is a formal parameter being declared as part of a function,
  /// method, or typedef declaration.
  static const formalParameterDeclaration = const IdentifierContext(
      'formalParameterDeclaration',
      inDeclaration: true);

  /// Identifier is the start of a library name (e.g. `foo` in the directive
  /// 'library foo;`).
  static const libraryName = const LibraryIdentifierContext();

  /// Identifier is part of a library name, but it's not the first identifier in
  /// the name.
  static const libraryNameContinuation =
      const LibraryIdentifierContext.continuation();

  /// Identifier is the start of a library name referenced by a `part of`
  /// directive (e.g. `foo` in the directive `part of foo;`).
  static const partName =
      const IdentifierContext('partName', inLibraryOrPartOfDeclaration: true);

  /// Identifier is part of a library name referenced by a `part of` directive,
  /// but it's not the first identifier in the name.
  static const partNameContinuation = const IdentifierContext(
      'partNameContinuation',
      inLibraryOrPartOfDeclaration: true,
      isContinuation: true);

  /// Identifier is the type name being declared by an enum declaration.
  static const enumDeclaration = const EnumDeclarationIdentifierContext();

  /// Identifier is an enumerated value name being declared by an enum
  /// declaration.
  static const enumValueDeclaration =
      const EnumValueDeclarationIdentifierContext();

  /// Identifier is the name being declared by a class declaration or a named
  /// mixin application, for example, `Foo` in `class Foo = X with Y;`.
  static const classOrNamedMixinDeclaration =
      const ClassOrNamedMixinIdentifierContext();

  /// Identifier is the name of a type variable being declared (e.g. `Foo` in
  /// `class C<Foo extends num> {}`).
  static const typeVariableDeclaration =
      const TypeVariableDeclarationIdentifierContext();

  /// Identifier is the start of a reference to a type that starts with prefix.
  static const prefixedTypeReference =
      const TypeReferenceIdentifierContext.prefixed();

  /// Identifier is the start of a reference to a type declared elsewhere.
  static const typeReference = const TypeReferenceIdentifierContext();

  /// Identifier is part of a reference to a type declared elsewhere, but it's
  /// not the first identifier of the reference.
  static const typeReferenceContinuation =
      const TypeReferenceIdentifierContext.continuation();

  /// Identifier is a name being declared by a top level variable declaration.
  static const topLevelVariableDeclaration =
      const TopLevelDeclarationIdentifierContext(
          'topLevelVariableDeclaration', const [';', '=', ',']);

  /// Identifier is a name being declared by a field declaration.
  static const fieldDeclaration = const FieldDeclarationIdentifierContext();

  /// Identifier is the name being declared by a top level function declaration.
  static const topLevelFunctionDeclaration =
      const TopLevelDeclarationIdentifierContext(
          'topLevelFunctionDeclaration', const ['<', '(', '{', '=>']);

  /// Identifier is the start of the name being declared by a method
  /// declaration.
  static const methodDeclaration = const MethodDeclarationIdentifierContext();

  /// Identifier is part of the name being declared by a method declaration,
  /// but it's not the first identifier of the name.
  ///
  /// In valid Dart, this can only happen if the identifier is the name of a
  /// named constructor which is being declared, e.g. `foo` in
  /// `class C { C.foo(); }`.
  static const methodDeclarationContinuation =
      const MethodDeclarationIdentifierContext.continuation();

  /// Identifier appears after the word `operator` in a method declaration.
  ///
  /// TODO(paulberry,ahe): Does this ever occur in valid Dart, or does it only
  /// occur as part of error recovery?  If it's only as part of error recovery,
  /// perhaps we should just re-use methodDeclaration.
  static const operatorName =
      const MethodDeclarationIdentifierContext.continuation();

  /// Identifier is the name being declared by a local function declaration that
  /// uses a "get" or "set" keyword.
  ///
  /// TODO(paulberry,ahe): Does this ever occur in valid Dart, or does it only
  /// occur as part of error recovery?  If it's only as part of error recovery,
  /// perhaps we should just re-use localFunctionDeclaration.
  static const localAccessorDeclaration =
      const IdentifierContext('localAccessorDeclaration', inDeclaration: true);

  /// Identifier is the start of the name being declared by a local function
  /// declaration.
  static const localFunctionDeclaration =
      const LocalFunctionDeclarationIdentifierContext();

  /// Identifier is part of the name being declared by a local function
  /// declaration, but it's not the first identifier of the name.
  ///
  /// TODO(paulberry,ahe): Does this ever occur in valid Dart, or does it only
  /// occur as part of error recovery?
  static const localFunctionDeclarationContinuation =
      const LocalFunctionDeclarationIdentifierContext.continuation();

  /// Identifier is the name appearing in a function expression.
  ///
  /// TODO(paulberry,ahe): What is an example of valid Dart code where this
  /// would occur?
  static const functionExpressionName =
      const IdentifierContext('functionExpressionName');

  /// Identifier is the start of a reference to a constructor declared
  /// elsewhere.
  static const constructorReference =
      const IdentifierContext('constructorReference', isScopeReference: true);

  /// Identifier is part of a reference to a constructor declared elsewhere, but
  /// it's not the first identifier of the reference.
  static const constructorReferenceContinuation = const IdentifierContext(
      'constructorReferenceContinuation',
      isContinuation: true);

  /// Identifier is part of a reference to a constructor declared elsewhere, but
  /// it appears after type parameters (e.g. `foo` in `X<Y>.foo`).
  static const constructorReferenceContinuationAfterTypeArguments =
      const IdentifierContext(
          'constructorReferenceContinuationAfterTypeArguments',
          isContinuation: true);

  /// Identifier is the declaration of a label (i.e. it is followed by `:` and
  /// then a statement).
  static const labelDeclaration =
      const IdentifierContext('labelDeclaration', inDeclaration: true);

  /// Identifier is the start of a reference occurring in a literal symbol (e.g.
  /// `foo` in `#foo`).
  static const literalSymbol =
      const IdentifierContext('literalSymbol', inSymbol: true);

  /// Identifier is part of a reference occurring in a literal symbol, but it's
  /// not the first identifier of the reference (e.g. `foo` in `#prefix.foo`).
  static const literalSymbolContinuation = const IdentifierContext(
      'literalSymbolContinuation',
      inSymbol: true,
      isContinuation: true);

  /// Identifier appears in an expression, and it does not immediately follow a
  /// `.`.
  static const expression = const ExpressionIdentifierContext();

  /// Identifier appears in an expression, and it immediately follows a `.`.
  static const expressionContinuation =
      const ExpressionIdentifierContext.continuation();

  /// Identifier is a reference to a named argument of a function or method
  /// invocation (e.g. `foo` in `f(foo: 0);`.
  static const namedArgumentReference = const IdentifierContext(
      'namedArgumentReference',
      allowedInConstantExpression: true);

  /// Identifier is a name being declared by a local variable declaration.
  static const localVariableDeclaration =
      const LocalVariableDeclarationIdentifierContext();

  /// Identifier is a reference to a label (e.g. `foo` in `break foo;`).
  /// Labels have their own scope.
  static const labelReference = const IdentifierContext('labelReference');

  final String _name;

  /// Indicates whether the identifier represents a name which is being
  /// declared.
  final bool inDeclaration;

  /// Indicates whether the identifier is within a `library` or `part of`
  /// declaration.
  final bool inLibraryOrPartOfDeclaration;

  /// Indicates whether the identifier is within a symbol literal.
  final bool inSymbol;

  /// Indicates whether the identifier follows a `.`.
  final bool isContinuation;

  /// Indicates whether the identifier should be looked up in the current scope.
  final bool isScopeReference;

  /// Indicates whether built-in identifiers are allowed in this context.
  final bool isBuiltInIdentifierAllowed;

  /// Indicated whether the identifier is allowed in a context where constant
  /// expressions are required.
  final bool allowedInConstantExpression;

  final Template<_MessageWithArgument<Token>> recoveryTemplate;

  const IdentifierContext(this._name,
      {this.inDeclaration: false,
      this.inLibraryOrPartOfDeclaration: false,
      this.inSymbol: false,
      this.isContinuation: false,
      this.isScopeReference: false,
      this.isBuiltInIdentifierAllowed: true,
      bool allowedInConstantExpression,
      this.recoveryTemplate: templateExpectedIdentifier})
      : this.allowedInConstantExpression =
            // Generally, declarations are legal in constant expressions.  A
            // continuation doesn't affect constant expressions: if what it's
            // continuing is a problem, it has already been reported.
            allowedInConstantExpression ??
                (inDeclaration || isContinuation || inSymbol);

  String toString() => _name;

  /// Ensure that the next token is an identifier (or keyword which should be
  /// treated as an identifier) and return that identifier.
  /// Report errors as necessary via [parser].
  Token ensureIdentifier(Token token, Parser parser) {
    assert(token.next.kind != IDENTIFIER_TOKEN);
    // TODO(danrubel): Implement this method for each identifier context
    // such that they return a non-null value.
    return null;
  }
}

// TODO(ahe): Remove when analyzer supports generalized function syntax.
typedef _MessageWithArgument<T> = Message Function(T);
