// 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.

part of dart._internal;

/**
 * Implementation of [core.Symbol].  This class uses the same name as
 * a core class so a user can't tell the difference.
 *
 * The purpose of this class is to hide [_name] from user code, but
 * make it accessible to Dart platform code via the static method
 * [getName].
 */
class Symbol implements core.Symbol {
  final String _name;

  /**
   * Source of RegExp matching Dart reserved words.
   *
   * Reserved words are not allowed as identifiers.
   */
  static const String reservedWordRE =
      r'(?:assert|break|c(?:a(?:se|tch)|lass|on(?:st|tinue))|d(?:efault|o)|'
      r'e(?:lse|num|xtends)|f(?:alse|inal(?:ly)?|or)|i[fns]|n(?:ew|ull)|'
      r'ret(?:hrow|urn)|s(?:uper|witch)|t(?:h(?:is|row)|r(?:ue|y))|'
      r'v(?:ar|oid)|w(?:hile|ith))';
  /**
   * Source of RegExp matching any public identifier.
   *
   * A public identifier is a valid identifier (not a reserved word)
   * that doesn't start with '_'.
   */
  static const String publicIdentifierRE =
      r'(?!' '$reservedWordRE' r'\b(?!\$))[a-zA-Z$][\w$]*';
  /**
   * Source of RegExp matching any identifier.
   *
   * It matches identifiers but not reserved words. The identifiers
   * may start with '_'.
   */
  static const String identifierRE =
      r'(?!' '$reservedWordRE' r'\b(?!\$))[a-zA-Z$_][\w$]*';
  /**
   * Source of RegExp matching a declarable operator names.
   *
   * The operators that can be declared using `operator` declarations are
   * also the only ones allowed as symbols. The name of the operators is
   * the same as the operator itself except for unary minus, where the name
   * is "unary-".
   */
  static const String operatorRE =
      r'(?:[\-+*/%&|^]|\[\]=?|==|~/?|<[<=]?|>[>=]?|unary-)';

  // Grammar if symbols:
  //    symbol ::= qualifiedName | <empty>
  //    qualifiedName ::= publicIdentifier '.' qualifiedName | name
  //    name ::= publicIdentifier
  //           | publicIdentifier '='
  //           | operator
  // where publicIdentifier is any valid identifier (not a reserved word)
  // that isn't private (doesn't start with '_').
  //
  // Railroad diagram of the accepted grammar:
  //
  //    /----------------\
  //    |                |
  //    |          /-[.]-/     /-[=]-\
  //    \         /           /       \
  //  -------[id]------------------------->
  //       \                     /
  //        \------[operator]---/
  //            \              /
  //             \------------/
  //

  /**
   * RegExp that validates a non-empty non-private symbol.
   *
   * The empty symbol is handled before this regexp is used, and is not
   * accepted.
   */
  static final RegExp publicSymbolPattern = new RegExp(
      '^(?:$operatorRE\$|$publicIdentifierRE(?:=?\$|[.](?!\$)))+?\$');

  // The grammar of symbols that may be private is the same as for public
  // symbols, except that "publicIdentifier" is replaced by "identifier",
  // which matches any identifier.

  /**
   * RegExp that validates a non-empty symbol.
   *
   * Private symbols are accepted.
   *
   * The empty symbol is handled before this regexp is used, and is not
   * accepted.
   */
  static final RegExp symbolPattern =
      new RegExp('^(?:$operatorRE\$|$identifierRE(?:=?\$|[.](?!\$)))+?\$');

  external const Symbol(String name);

  /**
   * Platform-private method used by the mirror system to create
   * otherwise invalid names.
   */
  const Symbol.unvalidated(this._name);

  // This is called by dart2js.
  Symbol.validated(String name) : this._name = validatePublicSymbol(name);

  bool operator ==(Object other) => other is Symbol && _name == other._name;

  external int get hashCode;

  external toString();

  /// Platform-private accessor which cannot be called from user libraries.
  static String getName(Symbol symbol) => symbol._name;

  static String validatePublicSymbol(String name) {
    if (name.isEmpty || publicSymbolPattern.hasMatch(name)) return name;
    if (name.startsWith('_')) {
      // There may be other private parts in a qualified name than the first
      // one, but this is a common case that deserves a specific error
      // message.
      throw new ArgumentError('"$name" is a private identifier');
    }
    throw new ArgumentError('"$name" is not a valid (qualified) symbol name');
  }

  /**
   * Checks whether name is a valid symbol name.
   *
   * This test allows both private and non-private symbols.
   */
  static bool isValidSymbol(String name) {
    return (name.isEmpty || symbolPattern.hasMatch(name));
  }

  external static String computeUnmangledName(Symbol symbol);
}
