// 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/sdk_library_metadata/lib/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.
 * - [tree.TreeElements] only map to patch elements from inside a patch library.
 *   TODO(johnniwinther): Simplify this invariant to use only declarations in
 *   [tree.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 dart2js.patchparser;

import 'dart:async';

import 'constants/values.dart' show
    ConstantValue;
import 'common.dart';
import 'compiler.dart' show
    Compiler;
import 'common/tasks.dart' show
    CompilerTask;
import 'dart_types.dart' show
    DartType;
import 'elements/elements.dart';
import 'elements/modelx.dart' show
    BaseFunctionElementX,
    ClassElementX,
    GetterElementX,
    LibraryElementX,
    MetadataAnnotationX,
    SetterElementX;
import 'js_backend/js_backend.dart' show
    JavaScriptBackend;
import 'library_loader.dart' show
    LibraryLoader;
import 'options.dart' show
    ParserOptions;
import 'parser/listener.dart' show
    Listener,
    ParserError;
import 'parser/element_listener.dart' show
    ElementListener;
import 'parser/member_listener.dart' show
    MemberListener;
import 'parser/partial_elements.dart' show
  PartialClassElement;
import 'parser/partial_parser.dart' show
    PartialParser;
import 'parser/parser.dart' show
    Parser;
import 'scanner/scanner.dart' show
    Scanner;
import 'script.dart';
import 'tokens/token.dart' show
    StringToken,
    Token;

class PatchParserTask extends CompilerTask {
  final String name = "Patching Parser";
  final ParserOptions parserOptions;

  PatchParserTask(Compiler compiler, this.parserOptions) : super(compiler);

  /**
   * Scans a library patch file, applies the method patches and
   * injections to the library, and returns a list of class
   * patches.
   */
  Future patchLibrary(LibraryLoader loader,
                      Uri patchUri, LibraryElement originLibrary) {
    return compiler.readScript(patchUri, originLibrary)
        .then((Script script) {
      var patchLibrary = new LibraryElementX(script, null, originLibrary);
      return reporter.withCurrentElement(patchLibrary, () {
        loader.registerNewLibrary(patchLibrary);
        reporter.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);
        });
        return loader.processLibraryTags(patchLibrary);
      });
    });
  }

  void scanLibraryElements(CompilationUnitElement compilationUnit) {
    measure(() {
      // TODO(johnniwinther): Test that parts and exports are handled correctly.
      Script script = compilationUnit.script;
      Token tokens = new Scanner(script.file).tokenize();
      Function idGenerator = compiler.getNextFreeClassId;
      Listener patchListener = new PatchElementListener(compiler,
                                                        compilationUnit,
                                                        idGenerator);
      try {
        new PartialParser(patchListener, parserOptions).parseUnit(tokens);
      } on ParserError catch (e) {
        // No need to recover from a parser error in platform libraries, user
        // will never see this if the libraries are tested correctly.
        reporter.internalError(
            compilationUnit, "Parser error in patch file: $e");
      }
    });
  }

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

    measure(() => reporter.withCurrentElement(cls, () {
      MemberListener listener = new PatchMemberListener(compiler, cls);
      Parser parser = new PatchClassElementParser(listener, parserOptions);
      try {
        Token token = parser.parseTopLevelDeclaration(cls.beginToken);
        assert(identical(token, cls.endToken.next));
      } on ParserError catch (e) {
        // No need to recover from a parser error in platform libraries, user
        // will never see this if the libraries are tested correctly.
        reporter.internalError(
            cls, "Parser error in patch file: $e");
      }
      cls.cachedNode = listener.popNode();
      assert(listener.nodes.isEmpty);
    }));
  }
}

class PatchMemberListener extends MemberListener {
  final Compiler compiler;

  PatchMemberListener(Compiler compiler, ClassElement enclosingClass)
      : this.compiler = compiler,
        super(compiler.parsing.getScannerOptionsFor(enclosingClass),
              compiler.reporter,
              enclosingClass);

  @override
  void addMember(Element patch) {
    addMetadata(patch);

    PatchVersion patchVersion = getPatchVersion(compiler, patch);
    if (patchVersion != null) {
      if (patchVersion.isActive(compiler.patchVersion)) {
        Element origin = enclosingClass.origin.localLookup(patch.name);
        patchElement(compiler, reporter, origin, patch);
        enclosingClass.addMember(patch, reporter);
      } else {
        // Skip this element.
      }
    } else {
      if (Name.isPublicName(patch.name)) {
        reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
      }
      enclosingClass.addMember(patch, reporter);
    }
  }
}

/**
 * Partial parser for patch files that also handles the members of class
 * declarations.
 */
class PatchClassElementParser extends PartialParser {
  PatchClassElementParser(Listener listener, ParserOptions options)
      : super(listener, options);

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

/**
 * Extension of [ElementListener] for parsing patch files.
 */
class PatchElementListener extends ElementListener implements Listener {
  final Compiler compiler;

  PatchElementListener(Compiler compiler,
                       CompilationUnitElement patchElement,
                       int idGenerator())
    : this.compiler = compiler,
      super(compiler.parsing.getScannerOptionsFor(patchElement),
            compiler.reporter, patchElement, idGenerator);

  @override
  void pushElement(Element patch) {
    popMetadata(patch);

    PatchVersion patchVersion = getPatchVersion(compiler, patch);
    if (patchVersion != null) {
      if (patchVersion.isActive(compiler.patchVersion)) {
        LibraryElement originLibrary = compilationUnitElement.library;
        assert(originLibrary.isPatched);
        Element origin = originLibrary.localLookup(patch.name);
        patchElement(compiler, reporter, origin, patch);
        compilationUnitElement.addMember(patch, reporter);
      } else {
        // Skip this element.
      }
    } else {
      if (Name.isPublicName(patch.name)) {
        reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
      }
      compilationUnitElement.addMember(patch, reporter);
    }
  }
}

void patchElement(Compiler compiler,
                  DiagnosticReporter reporter,
                  Element origin,
                  Element patch) {
  if (origin == null) {
    reporter.reportErrorMessage(
        patch, MessageKind.PATCH_NON_EXISTING, {'name': patch.name});
    return;
  }

  if (!(origin.isClass ||
        origin.isConstructor ||
        origin.isFunction ||
        origin.isAbstractField)) {
    // TODO(ahe): Remove this error when the parser rejects all bad modifiers.
    reporter.reportErrorMessage(origin, MessageKind.PATCH_NONPATCHABLE);
    return;
  }
  if (patch.isClass) {
    tryPatchClass(compiler, reporter, origin, patch);
  } else if (patch.isGetter) {
    tryPatchGetter(reporter, origin, patch);
  } else if (patch.isSetter) {
    tryPatchSetter(reporter, origin, patch);
  } else if (patch.isConstructor) {
    tryPatchConstructor(reporter, origin, patch);
  } else if(patch.isFunction) {
    tryPatchFunction(reporter, origin, patch);
  } else {
    // TODO(ahe): Remove this error when the parser rejects all bad modifiers.
    reporter.reportErrorMessage(patch, MessageKind.PATCH_NONPATCHABLE);
  }
}

void tryPatchClass(Compiler compiler,
                   DiagnosticReporter reporter,
                   Element origin,
                   ClassElement patch) {
  if (!origin.isClass) {
    reporter.reportError(
        reporter.createMessage(
            origin,
            MessageKind.PATCH_NON_CLASS,
            {'className': patch.name}),
        <DiagnosticMessage>[
            reporter.createMessage(
                patch,
                MessageKind.PATCH_POINT_TO_CLASS,
                {'className': patch.name}),
        ]);
    return;
  }
  patchClass(compiler, reporter, origin, patch);
}

void patchClass(Compiler compiler,
                DiagnosticReporter reporter,
                ClassElementX origin,
                ClassElementX patch) {
  if (origin.isPatched) {
    reporter.internalError(origin,
        "Patching the same class more than once.");
  }
  origin.applyPatch(patch);
  checkNativeAnnotation(compiler, patch);
}

/// Check whether [cls] has a `@Native(...)` annotation, and if so, set its
/// native name from the annotation.
checkNativeAnnotation(Compiler compiler, ClassElement cls) {
  EagerAnnotationHandler.checkAnnotation(compiler, cls,
      const NativeAnnotationHandler());
}

checkJsInteropAnnotation(Compiler compiler, element) {
  EagerAnnotationHandler.checkAnnotation(compiler, element,
      const JsInteropAnnotationHandler());
}


/// Abstract interface for pre-resolution detection of metadata.
///
/// The detection is handled in two steps:
/// - match the annotation syntactically and assume that the annotation is valid
///   if it looks correct,
/// - setup a deferred action to check that the annotation has a valid constant
///   value and report an internal error if not.
abstract class EagerAnnotationHandler<T> {
  /// Checks that [annotation] looks like a matching annotation and optionally
  /// applies actions on [element]. Returns a non-null annotation marker if the
  /// annotation matched and should be validated.
  T apply(Compiler compiler,
          Element element,
          MetadataAnnotation annotation);

  /// Checks that the annotation value is valid.
  void validate(Compiler compiler,
                Element element,
                MetadataAnnotation annotation,
                ConstantValue constant);


  /// Checks [element] for metadata matching the [handler]. Return a non-null
  /// annotation marker matching metadata was found.
  static checkAnnotation(Compiler compiler,
                         Element element,
                         EagerAnnotationHandler handler) {
    for (MetadataAnnotation annotation in element.implementation.metadata) {
      var result = handler.apply(compiler, element, annotation);
      if (result != null) {
        // TODO(johnniwinther): Perform this check in
        // [Compiler.onLibrariesLoaded].
        compiler.enqueuer.resolution.addDeferredAction(element, () {
          annotation.ensureResolved(compiler.resolution);
          handler.validate(
              compiler, element, annotation,
              compiler.constants.getConstantValue(annotation.constant));
        });
        return result;
      }
    }
    return null;
  }
}

/// Annotation handler for pre-resolution detection of `@Native(...)`
/// annotations.
class NativeAnnotationHandler implements EagerAnnotationHandler<String> {
  const NativeAnnotationHandler();

  String getNativeAnnotation(MetadataAnnotation annotation) {
    if (annotation.beginToken != null &&
        annotation.beginToken.next.value == 'Native') {
      // Skipping '@', 'Native', and '('.
      Token argument = annotation.beginToken.next.next.next;
      if (argument is StringToken) {
        return argument.value;
      }
    }
    return null;
  }

  String apply(Compiler compiler,
             Element element,
             MetadataAnnotation annotation) {
    if (element.isClass) {
      String native = getNativeAnnotation(annotation);
      if (native != null) {
        JavaScriptBackend backend = compiler.backend;
        backend.nativeData.setNativeClassTagInfo(element, native);
        return native;
      }
    }
    return null;
  }

  void validate(Compiler compiler,
                Element element,
                MetadataAnnotation annotation,
                ConstantValue constant) {
    DartType annotationType = constant.getType(compiler.coreTypes);
    if (annotationType.element != compiler.nativeAnnotationClass) {
      DiagnosticReporter reporter = compiler.reporter;
      reporter.internalError(annotation, 'Invalid @Native(...) annotation.');
    }
  }
}

/// Annotation handler for pre-resolution detection of `@JS(...)`
/// annotations.
class JsInteropAnnotationHandler implements EagerAnnotationHandler<bool> {
  const JsInteropAnnotationHandler();

  bool hasJsNameAnnotation(MetadataAnnotation annotation) =>
      annotation.beginToken != null && annotation.beginToken.next.value == 'JS';

  bool apply(Compiler compiler,
             Element element,
             MetadataAnnotation annotation) {
    bool hasJsInterop = hasJsNameAnnotation(annotation);
    if (hasJsInterop) {
      JavaScriptBackend backend = compiler.backend;
      backend.nativeData.markAsJsInterop(element);
    }
    // Due to semantics of apply in the baseclass we have to return null to
    // indicate that no match was found.
    return hasJsInterop ? true : null;
  }

  @override
  void validate(Compiler compiler,
                Element element,
                MetadataAnnotation annotation,
                ConstantValue constant) {
    JavaScriptBackend backend = compiler.backend;
    if (constant.getType(compiler.coreTypes).element !=
        backend.helpers.jsAnnotationClass) {
      compiler.reporter.internalError(annotation, 'Invalid @JS(...) annotation.');
    }
  }
}

/// Annotation handler for pre-resolution detection of `@patch` annotations.
class PatchAnnotationHandler implements EagerAnnotationHandler<PatchVersion> {
  const PatchAnnotationHandler();

  PatchVersion getPatchVersion(MetadataAnnotation annotation) {
    if (annotation.beginToken != null) {
      if (annotation.beginToken.next.value == 'patch') {
        return const PatchVersion(null);
      } else if (annotation.beginToken.next.value == 'patch_full') {
        return const PatchVersion('full');
      } else if (annotation.beginToken.next.value == 'patch_lazy') {
        return const PatchVersion('lazy');
      } else if (annotation.beginToken.next.value == 'patch_startup') {
        return const PatchVersion('startup');
      }
    }
    return null;
  }

  @override
  PatchVersion apply(Compiler compiler,
                     Element element,
                     MetadataAnnotation annotation) {
    return getPatchVersion(annotation);
  }

  @override
  void validate(Compiler compiler,
                Element element,
                MetadataAnnotation annotation,
                ConstantValue constant) {
    DartType annotationType = constant.getType(compiler.coreTypes);
    if (annotationType.element != compiler.patchAnnotationClass) {
      DiagnosticReporter reporter = compiler.reporter;
      reporter.internalError(annotation, 'Invalid patch annotation.');
    }
  }
}


void tryPatchGetter(DiagnosticReporter reporter,
                    Element origin,
                    FunctionElement patch) {
  if (!origin.isAbstractField) {
    reporter.reportError(
        reporter.createMessage(
            origin,
            MessageKind.PATCH_NON_GETTER,
            {'name': origin.name}),
        <DiagnosticMessage>[
            reporter.createMessage(
                patch,
                MessageKind.PATCH_POINT_TO_GETTER,
                {'getterName': patch.name}),
        ]);
    return;
  }
  AbstractFieldElement originField = origin;
  if (originField.getter == null) {
    reporter.reportError(
        reporter.createMessage(
            origin,
            MessageKind.PATCH_NO_GETTER,
            {'getterName': patch.name}),
        <DiagnosticMessage>[
            reporter.createMessage(
                patch,
                MessageKind.PATCH_POINT_TO_GETTER,
                {'getterName': patch.name}),
        ]);
    return;
  }
  GetterElementX getter = originField.getter;
  patchFunction(reporter, getter, patch);
}

void tryPatchSetter(DiagnosticReporter reporter,
                    Element origin,
                    FunctionElement patch) {
  if (!origin.isAbstractField) {
    reporter.reportError(
        reporter.createMessage(
            origin,
            MessageKind.PATCH_NON_SETTER,
            {'name': origin.name}),
        <DiagnosticMessage>[
            reporter.createMessage(
                patch,
                MessageKind.PATCH_POINT_TO_SETTER,
                {'setterName': patch.name}),
        ]);
    return;
  }
  AbstractFieldElement originField = origin;
  if (originField.setter == null) {
    reporter.reportError(
        reporter.createMessage(
            origin,
            MessageKind.PATCH_NO_SETTER,
            {'setterName': patch.name}),
        <DiagnosticMessage>[
              reporter.createMessage(
                  patch,
                  MessageKind.PATCH_POINT_TO_SETTER,
                  {'setterName': patch.name}),
        ]);
    return;
  }
  SetterElementX setter = originField.setter;
  patchFunction(reporter, setter, patch);
}

void tryPatchConstructor(DiagnosticReporter reporter,
                         Element origin,
                         FunctionElement patch) {
  if (!origin.isConstructor) {
    reporter.reportError(
        reporter.createMessage(
            origin,
            MessageKind.PATCH_NON_CONSTRUCTOR,
            {'constructorName': patch.name}),
        <DiagnosticMessage>[
            reporter.createMessage(
                patch,
                MessageKind.PATCH_POINT_TO_CONSTRUCTOR,
                {'constructorName': patch.name}),
        ]);
    return;
  }
  patchFunction(reporter, origin, patch);
}

void tryPatchFunction(DiagnosticReporter reporter,
                      Element origin,
                      FunctionElement patch) {
  if (!origin.isFunction) {
    reporter.reportError(
        reporter.createMessage(
            origin,
            MessageKind.PATCH_NON_FUNCTION,
            {'functionName': patch.name}),
        <DiagnosticMessage>[
            reporter.createMessage(
                patch,
                MessageKind.PATCH_POINT_TO_FUNCTION,
                {'functionName': patch.name}),
        ]);
    return;
  }
  patchFunction(reporter, origin, patch);
}

void patchFunction(DiagnosticReporter reporter,
                   BaseFunctionElementX origin,
                   BaseFunctionElementX patch) {
  if (!origin.modifiers.isExternal) {
    reporter.reportError(
        reporter.createMessage(origin, MessageKind.PATCH_NON_EXTERNAL),
        <DiagnosticMessage>[
              reporter.createMessage(
                  patch,
                  MessageKind.PATCH_POINT_TO_FUNCTION,
                  {'functionName': patch.name}),
        ]);
    return;
  }
  if (origin.isPatched) {
    reporter.internalError(origin,
        "Trying to patch a function more than once.");
  }
  origin.applyPatch(patch);
}

PatchVersion getPatchVersion(Compiler compiler, Element element) {
  return EagerAnnotationHandler.checkAnnotation(compiler, element,
      const PatchAnnotationHandler());
}

class PatchVersion {
  final String tag;

  const PatchVersion(this.tag);

  bool isActive(String patchTag) => tag == null || tag == patchTag;

  String toString() => 'PatchVersion($tag)';
}
