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

/// Opaque name used by mirrors, invocations and [Function.apply].
abstract class Symbol {
  /// The symbol corresponding to the name of the unary minus operator.
  static const Symbol unaryMinus = Symbol("unary-");

  /// The empty symbol.
  ///
  /// The empty symbol is the name of libraries with no library declaration,
  /// and the base-name of the unnamed constructor.
  static const Symbol empty = Symbol("");

  /// Constructs a new [Symbol] representing the provided name.
  ///
  /// Symbols created from equal [name] strings are themselves equal.
  /// If the symbols are created using `const`, symbols with the
  /// same [name] strings are canonicalized and identical.
  ///
  /// Some [name] strings create symbols which can also be created using
  /// a symbol literal, or be implicitly created while running Dart programs,
  /// for example through [Object.noSuchMethod].
  ///
  /// If [name] is a single Dart identifier
  /// that does not start with an underscore,
  /// or it is a qualified identifier (multiple identifiers separated by `.`s),
  /// or it is the name of a user definable operator different from `unary-`
  /// (one of "`+`", "`-`", "`*`", "`/`", "`%`", "`~/`", "`&`", "`|`",
  ///   "`^`", "`~`", "`<<`", "`>>`", "`>>>`", "`<`", "`<=`", "`>`", "`>=`",
  ///   "`==`", "`[]`", or "`[]=`"),
  /// then the result of `Symbol(name)` is equal to the symbol literal
  /// created by prefixing `#` to the contents of [name],
  /// and `const Symbol(name)` is identical to that symbol literal.
  /// That is `#foo == Symbol("foo")` and
  /// `identical(#foo, const Symbol("foo"))`.
  ///
  /// If [name] is a single identifier that does not start with an underscore
  /// followed by a `=`, then the symbol is a setter name, and can be equal
  /// to the [Invocation.memberName] in an [Object.noSuchMethod] invocation.
  ///
  /// Private symbol literals, like `#_foo`, cannot be created using the
  /// symbol constructor.
  /// A symbol like `const Symbol("_foo")` is not equal to any symbol literal,
  /// or to any source name symbol introduced by `noSuchMethod`.
  ///
  /// ```dart
  /// assert(Symbol("foo") == Symbol("foo"));
  /// assert(Symbol("foo") == #foo);
  /// assert(identical(const Symbol("foo"), const Symbol("foo")));
  /// assert(identical(const Symbol("foo"), #foo));
  /// assert(Symbol("[]=") == #[]=]);
  /// assert(identical(const Symbol("[]="), #[]=));
  /// assert(Symbol("foo.bar") == #foo.bar);
  /// assert(identical(const Symbol("foo.bar"), #foo.bar));
  /// ```
  ///
  /// The created instance overrides [Object.==].
  const factory Symbol(String name) = internal.Symbol;

  /// Returns a hash code compatible with [operator==].
  ///
  /// Equal symbols have the same hash code.
  int get hashCode;

  /// Symbols are equal to other symbols with an equal (`==`) name string.
  ///
  /// Symbols representing library private names also need to represent
  /// names from the same library.
  bool operator ==(Object other);
}
