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

/**
 * This library contains the infrastructure to parse and integrate patch files.
 *
 * Three types of elements can be patched: [LibraryElement], [ClassElement],
 * [FunctionElement]. Patches are introduced in patch libraries which are loaded
 * together with the corresponding origin library. Which libraries that are
 * patched is determined by the [dart2jsPatchPath] field of [LibraryInfo] found
 * in [:lib/_internal/libraries.dart:].
 *
 * Patch libraries are parsed like regular library and thus provided with their
 * own elements. These elements which are distinct from the elements from the
 * patched library and the relation between patched and patch elements is
 * established through the [:patch:] and [:origin:] fields found on
 * [LibraryElement], [ClassElement] and [FunctionElement]. The [:patch:] fields
 * are set on the patched elements to point to their corresponding patch
 * element, and the [:origin:] elements are set on the patch elements to point
 * their corresponding patched elements.
 *
 * The fields [Element.isPatched] and [Element.isPatch] can be used to determine
 * whether the [:patch:] or [:origin:] field, respectively, has been set on an
 * element, regardless of whether the element is one of the three patchable
 * element types or not.
 *
 * ## Variants of Classes and Functions ##
 *
 * With patches there are four variants of classes and function:
 *
 * Regular: A class or function which is not declared in a patch library and
 *   which has no corresponding patch.
 * Origin: A class or function which is not declared in a patch library and
 *   which has a corresponding patch. Origin functions must use the [:external:]
 *   modifier and can have no body. Origin classes and functions are also
 *   called 'patched'.
 * Patch: A class or function which is declared in a patch library and which
 *   has a corresponding origin. Both patch classes and patch functions must use
 *   the [:patch:] modifier.
 * Injected: A class or function (or even field) which is declared in a
 *   patch library and which has no corresponding origin. An injected element
 *   cannot use the [:patch:] modifier. Injected elements are never visible from
 *   outside the patch library in which they have been declared. For this
 *   reason, injected elements are often declared private and therefore called
 *   also called 'patch private'.
 *
 * Examples of the variants is shown in the code below:
 *
 *     // In the origin library:
 *     class RegularClass { // A regular class.
 *       void regularMethod() {} // A regular method.
 *     }
 *     class PatchedClass { // An origin class.
 *       int regularField; // A regular field.
 *       void regularMethod() {} // A regular method.
 *       external void patchedMethod(); // An origin method.
 *     }
 *
 *     // In the patch library:
 *     class _InjectedClass { // An injected class.
 *       void _injectedMethod() {} // An injected method.
 *     }
 *     patch class PatchedClass { // A patch class.
 *       int _injectedField; { // An injected field.
 *       patch void patchedMethod() {} // A patch method.
 *     }
 *
 *
 * ## Declaration and Implementation ##
 *
 * With patches we have two views on elements: as the 'declaration' which
 * introduces the entity and defines its interface, and as the 'implementation'
 * which defines the actual implementation of the entity.
 *
 * Every element has a 'declaration' and an 'implementation' element. For
 * regular and injected elements these are the same. For origin elements the
 * declaration is the element itself and the implementation is the patch element
 * found through its [:patch:] field. For patch elements the implementation is
 * the element itself and the declaration is the origin element found through
 * its [:origin:] field. The declaration and implementation of any element is
 * conveniently available through the [Element.declaration] and
 * [Element.implementation] getters.
 *
 * Most patch-related invariants enforced through-out the compiler are defined
 * in terms of 'declaration' and 'implementation', and tested through the
 * predicate getters [Element.isDeclaration] and [Element.isImplementation].
 * Patch invariants are stated both in comments and as assertions.
 *
 *
 * ## General invariant guidelines ##
 *
 * For [LibraryElement] we always use declarations. This means the
 * [Element.getLibrary] method will only return library declarations. Patch
 * library implementations are only accessed through calls to
 * [Element.getImplementationLibrary] which is used to setup the correct
 * [Element.enclosingElement] relation between patch/injected elements and the
 * patch library.
 *
 * For [ClassElement] and [FunctionElement] we use declarations for determining
 * identity and implementations for work based on the AST nodes, such as
 * resolution, type-checking, type inference, building SSA graphs, etc.
 * - Worklist only contain declaration elements.
 * - Most maps and sets use declarations exclusively, and their individual
 *   invariants are stated in the field comments.
 * - [TreeElements] only map to patch elements from inside a patch library.
 *   TODO(johnniwinther): Simplify this invariant to use only declarations in
 *   [TreeElements].
 * - Builders shift between declaration and implementation depending on usages.
 * - Compile-time constants use constructor implementation exclusively.
 * - Work on function parameters is performed on the declaration of the function
 *   element.
 */

library patchparser;

import "dart:uri";
import "tree/tree.dart" as tree;
import "dart2jslib.dart" as leg;  // CompilerTask, Compiler.
import "apiimpl.dart";
import "scanner/scannerlib.dart";  // Scanner, Parsers, Listeners
import "elements/elements.dart";
import 'util/util.dart';

class PatchParserTask extends leg.CompilerTask {
  PatchParserTask(leg.Compiler compiler): super(compiler);
  final String name = "Patching Parser";

  /**
   * Scans a library patch file, applies the method patches and
   * injections to the library, and returns a list of class
   * patches.
   */
  void patchLibrary(leg.LibraryDependencyHandler handler,
                    Uri patchUri, LibraryElement originLibrary) {

    leg.Script script = compiler.readScript(patchUri, null);
    var patchLibrary = new LibraryElement(script, patchUri, originLibrary);
    handler.registerNewLibrary(patchLibrary);
    LinkBuilder<tree.LibraryTag> imports = new LinkBuilder<tree.LibraryTag>();
    compiler.withCurrentElement(patchLibrary.entryCompilationUnit, () {
      // This patches the elements of the patch library into [library].
      // Injected elements are added directly under the compilation unit.
      // Patch elements are stored on the patched functions or classes.
      scanLibraryElements(patchLibrary.entryCompilationUnit, imports);
    });
    // After scanning declarations, we handle the import tags in the patch.
    // TODO(lrn): These imports end up in the original library and are in
    // scope for the original methods too. This should be fixed.
    compiler.importHelperLibrary(originLibrary);
    for (tree.LibraryTag tag in imports.toLink()) {
      compiler.libraryLoader.registerLibraryFromTag(handler, patchLibrary, tag);
    }
  }

  void scanLibraryElements(
        CompilationUnitElement compilationUnit,
        LinkBuilder<tree.LibraryTag> imports) {
    measure(() {
      // TODO(lrn): Possibly recursively handle #source directives in patch.
      leg.Script script = compilationUnit.script;
      Token tokens = new StringScanner(script.text).tokenize();
      Function idGenerator = compiler.getNextFreeClassId;
      PatchListener patchListener =
          new PatchElementListener(compiler,
                                   compilationUnit,
                                   idGenerator,
                                   imports);
      new PatchParser(patchListener).parseUnit(tokens);
    });
  }

  void parsePatchClassNode(PartialClassElement element) {
    // Parse [PartialClassElement] using a "patch"-aware parser instead
    // of calling its [parseNode] method.
    if (element.cachedNode != null) return;

    return measure(() => compiler.withCurrentElement(element, () {
      PatchMemberListener listener = new PatchMemberListener(compiler, element);
      Parser parser = new PatchClassElementParser(listener);
      Token token = parser.parseTopLevelDeclaration(element.beginToken);
      assert(identical(token, element.endToken.next));
      element.cachedNode = listener.popNode();
      assert(listener.nodes.isEmpty);

      Link<Element> patches = element.localMembers;
      applyContainerPatch(element.origin, patches);
    }));
  }

  void applyContainerPatch(ScopeContainerElement original,
                           Link<Element> patches) {
    while (!patches.isEmpty) {
      Element patchElement = patches.head;
      Element originalElement = original.localLookup(patchElement.name);
      if (patchElement.isAccessor() && originalElement != null) {
        if (!identical(originalElement.kind, ElementKind.ABSTRACT_FIELD)) {
          compiler.internalError(
              "Cannot patch non-getter/setter with getter/setter",
              element: originalElement);
        }
        AbstractFieldElement originalField = originalElement;
        if (patchElement.isGetter()) {
          originalElement = originalField.getter;
        } else {
          originalElement = originalField.setter;
        }
      }
      if (originalElement == null) {
        if (isPatchElement(patchElement)) {
          compiler.internalError("Cannot patch non-existing member '"
                        "${patchElement.name.slowToString()}'.");
        }
      } else {
        patchMember(originalElement, patchElement);
      }
      patches = patches.tail;
    }
  }

  bool isPatchElement(Element element) {
    // TODO(lrn): More checks needed if we introduce metadata for real.
    // In that case, it must have the identifier "native" as metadata.
    for (Link link = element.metadata; !link.isEmpty; link = link.tail) {
      if (link.head is PatchMetadataAnnotation) return true;
    }
    return false;
  }

  void patchMember(Element originalElement, Element patchElement) {
    // The original library has an element with the same name as the patch
    // library element.
    // In this case, the patch library element must be a function marked as
    // "patch" and it must have the same signature as the function it patches.
    if (!isPatchElement(patchElement)) {
      compiler.internalError("Cannot overwrite existing '"
                    "${originalElement.name.slowToString()}' with non-patch.");
    }
    if (originalElement is! FunctionElement) {
      // TODO(lrn): Handle class declarations too.
      compiler.internalError("Can only patch functions", element: originalElement);
    }
    FunctionElement original = originalElement;
    if (!original.modifiers.isExternal()) {
      compiler.internalError("Can only patch external functions.", element: original);
    }
    if (patchElement is! FunctionElement ||
        !patchSignatureMatches(original, patchElement)) {
      compiler.internalError("Can only patch functions with matching signatures",
                    element: original);
    }
    applyFunctionPatch(original, patchElement);
  }

  bool patchSignatureMatches(FunctionElement original, FunctionElement patch) {
    // TODO(lrn): Check that patches actually match the signature of
    // the function it's patching.
    return true;
  }

  void applyFunctionPatch(FunctionElement element,
                          FunctionElement patchElement) {
    if (element.isPatched) {
      compiler.internalError("Trying to patch a function more than once.",
                    element: element);
    }
    if (element.cachedNode != null) {
      compiler.internalError("Trying to patch an already compiled function.",
                    element: element);
    }
    // Don't just assign the patch field. This also updates the cachedNode.
    element.setPatch(patchElement);
    patchElement.origin = element;
  }
}

/**
 * Extension of the [Listener] interface to handle the extra "patch" pseudo-
 * keyword in patch files.
 * Patch files shouldn't have a type named "patch".
 */
abstract class PatchListener extends Listener {
  void beginPatch(Token patch);
  void endPatch(Token patch);
}

/**
 * Partial parser that extends the top-level and class grammars to allow the
 * word "patch" in front of some declarations.
 */
class PatchParser extends PartialParser {
  PatchParser(PatchListener listener) : super(listener);

  PatchListener get patchListener => listener;

  bool isPatch(Token token) {
    return token.stringValue == null &&
           token.slowToString() == "patch";
  }

  /**
   * Parse top-level declarations, and allow "patch" in front of functions
   * and classes.
   */
  Token parseTopLevelDeclaration(Token token) {
    if (!isPatch(token)) {
      return super.parseTopLevelDeclaration(token);
    }
    Token patch = token;
    token = token.next;
    String value = token.stringValue;
    if (identical(value, 'interface')
        || identical(value, 'typedef')
        || identical(value, '#')
        || identical(value, 'abstract')) {
      // At the top level, you can only patch functions and classes.
      // Patch classes and functions can't be marked abstract.
      return listener.unexpected(patch);
    }
    patchListener.beginPatch(patch);
    token = super.parseTopLevelDeclaration(token);
    patchListener.endPatch(patch);
    return token;
  }

  /**
   * Parse a class member.
   * If the member starts with "patch", it's a member override.
   * Only methods can be overridden, including constructors, getters and
   * setters, but not fields. If "patch" occurs in front of a field, the error
   * is caught elsewhere.
   */
  Token parseMember(Token token) {
    if (!isPatch(token)) {
      return super.parseMember(token);
    }
    Token patch = token;
    patchListener.beginPatch(patch);
    token = super.parseMember(token.next);
    patchListener.endPatch(patch);
    return token;
  }
}

/**
 * Partial parser for patch files that also handles the members of class
 * declarations.
 */
class PatchClassElementParser extends PatchParser {
  PatchClassElementParser(PatchListener listener) : super(listener);

  Token parseClassBody(Token token) => fullParseClassBody(token);
}

/**
 * Extension of [ElementListener] for parsing patch files.
 */
class PatchElementListener extends ElementListener implements PatchListener {
  final LinkBuilder<tree.LibraryTag> imports;
  bool isMemberPatch = false;
  bool isClassPatch = false;

  PatchElementListener(leg.DiagnosticListener listener,
                       CompilationUnitElement patchElement,
                       int idGenerator(),
                       this.imports)
    : super(listener, patchElement, idGenerator);

  MetadataAnnotation popMetadata() {
    // TODO(ahe): Remove this method.
    popNode(); // Discard null.
    return new PatchMetadataAnnotation();
  }

  void beginPatch(Token token) {
    if (identical(token.next.stringValue, "class")) {
      isClassPatch = true;
    } else {
      isMemberPatch = true;
    }
    handleIdentifier(token);
  }

  void endPatch(Token token) {
    if (identical(token.next.stringValue, "class")) {
      isClassPatch = false;
    } else {
      isMemberPatch = false;
    }
  }

  /**
    * Allow script tags (import only, the parser rejects the rest for now) in
    * patch files. The import tags will be added to the library.
    */
  bool allowLibraryTags() => true;

  void addLibraryTag(tree.LibraryTag tag) {
    super.addLibraryTag(tag);
    imports.addLast(tag);
  }

  void pushElement(Element element) {
    if (isMemberPatch || (isClassPatch && element is ClassElement)) {
      // Apply patch.
      element.addMetadata(popMetadata());
      LibraryElement originLibrary = compilationUnitElement.getLibrary();
      assert(originLibrary.isPatched);
      Element existing = originLibrary.localLookup(element.name);
      if (isMemberPatch) {
        if (element is! FunctionElement) {
          listener.internalErrorOnElement(element,
                                          "Member patch is not a function.");
        }
        FunctionElement functionElement = element;
        if (identical(existing.kind, ElementKind.ABSTRACT_FIELD)) {
          if (!element.isAccessor()) {
            listener.internalErrorOnElement(
                functionElement, "Patching non-accessor with accessor");
          }
          AbstractFieldElement field = existing;
          if (functionElement.isGetter()) {
            existing = field.getter;
          } else {
            existing = field.setter;
          }
        }
        if (existing is! FunctionElement) {
          listener.internalErrorOnElement(functionElement,
                                          "No corresponding method for patch.");
        }
        FunctionElement existingFunction = existing;
        if (existingFunction.isPatched) {
          listener.internalErrorOnElement(
              functionElement, "Patching the same function more than once.");
        }
        existingFunction.patch = functionElement;
        functionElement.origin = existingFunction;
      } else {
        assert(leg.invariant(element, element is ClassElement));
        ClassElement classElement = element;
        if (existing is! ClassElement) {
          listener.internalErrorOnElement(
              classElement, "Patching a non-class with a class patch.");
        }
        ClassElement existingClass = existing;
        if (existingClass.isPatched) {
          listener.internalErrorOnElement(
              classElement, "Patching the same class more than once.");
        }
        existingClass.patch = classElement;
        classElement.origin = existingClass;
      }
    }
    super.pushElement(element);
  }
}

/**
 * Extension of [MemberListener] for parsing patch class bodies.
 */
class PatchMemberListener extends MemberListener implements PatchListener {
  bool isMemberPatch = false;
  bool isClassPatch = false;
  PatchMemberListener(leg.DiagnosticListener listener,
                      Element enclosingElement)
    : super(listener, enclosingElement);

  MetadataAnnotation popMetadata() {
    // TODO(ahe): Remove this method.
    popNode(); // Discard null.
    return new PatchMetadataAnnotation();
  }

  void beginPatch(Token token) {
    if (identical(token.next.stringValue, "class")) {
      isClassPatch = true;
    } else {
      isMemberPatch = true;
    }
    handleIdentifier(token);
  }

  void endPatch(Token token) {
    if (identical(token.next.stringValue, "class")) {
      isClassPatch = false;
    } else {
      isMemberPatch = false;
    }
  }

  void addMember(Element element) {
    if (isMemberPatch || (isClassPatch && element is ClassElement)) {
      element.addMetadata(popMetadata());
    }
    super.addMember(element);
  }
}

// TODO(ahe): Get rid of this class.
class PatchMetadataAnnotation extends MetadataAnnotation {
  final leg.Constant value = null;

  PatchMetadataAnnotation() : super(STATE_DONE);
}
