// 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 dart2js.js_emitter;

class NsmEmitter extends CodeEmitterHelper {
  final List<Selector> trivialNsmHandlers = <Selector>[];

  /// If this is true then we can generate the noSuchMethod handlers at startup
  /// time, instead of them being emitted as part of the Object class.
  bool get generateTrivialNsmHandlers => true;

  // If we need fewer than this many noSuchMethod handlers we can save space by
  // just emitting them in JS, rather than emitting the JS needed to generate
  // them at run time.
  static const VERY_FEW_NO_SUCH_METHOD_HANDLERS = 10;

  static const MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING = 4;

  void emitNoSuchMethodHandlers(AddPropertyFunction addProperty) {
    // Do not generate no such method handlers if there is no class.
    if (compiler.codegenWorld.directlyInstantiatedClasses.isEmpty) return;

    String noSuchMethodName = namer.publicInstanceMethodNameByArity(
        Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT);

    // Keep track of the JavaScript names we've already added so we
    // do not introduce duplicates (bad for code size).
    Map<String, Selector> addedJsNames = new Map<String, Selector>();

    void addNoSuchMethodHandlers(String ignore, Set<Selector> selectors) {
      // Cache the object class and type.
      ClassElement objectClass = compiler.objectClass;
      DartType objectType = objectClass.rawType;

      for (Selector selector in selectors) {
        TypeMask mask = selector.mask;
        if (mask == null) {
          mask = new TypeMask.subclass(compiler.objectClass, compiler.world);
        }

        if (!mask.needsNoSuchMethodHandling(selector, compiler.world)) continue;
        String jsName = namer.invocationMirrorInternalName(selector);
        addedJsNames[jsName] = selector;
        String reflectionName = emitter.getReflectionName(selector, jsName);
        if (reflectionName != null) {
          emitter.mangledFieldNames[jsName] = reflectionName;
        }
      }
    }

    compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers);
    compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers);
    compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers);

    // Set flag used by generateMethod helper below.  If we have very few
    // handlers we use addProperty for them all, rather than try to generate
    // them at runtime.
    bool haveVeryFewNoSuchMemberHandlers =
        (addedJsNames.length < VERY_FEW_NO_SUCH_METHOD_HANDLERS);

    jsAst.Expression generateMethod(String jsName, Selector selector) {
      // Values match JSInvocationMirror in js-helper library.
      int type = selector.invocationMirrorKind;
      List<String> parameterNames =
          new List.generate(selector.argumentCount, (i) => '\$$i');

      List<jsAst.Expression> argNames =
          selector.getOrderedNamedArguments().map((String name) =>
              js.string(name)).toList();

      String methodName = selector.invocationMirrorMemberName;
      String internalName = namer.invocationMirrorInternalName(selector);
      String reflectionName = emitter.getReflectionName(selector, internalName);
      if (!haveVeryFewNoSuchMemberHandlers &&
          isTrivialNsmHandler(type, argNames, selector, internalName) &&
          reflectionName == null) {
        trivialNsmHandlers.add(selector);
        return null;
      }

      assert(backend.isInterceptedName(Compiler.NO_SUCH_METHOD));
      jsAst.Expression expression =
          js('''this.#noSuchMethodName(this,
                    #createInvocationMirror(#methodName,
                                            #internalName,
                                            #type,
                                            #arguments,
                                            #namedArguments))''',
             {'noSuchMethodName': noSuchMethodName,
              'createInvocationMirror':
                  backend.emitter.staticFunctionAccess(
                      backend.getCreateInvocationMirror()),
              'methodName':
                  js.string(compiler.enableMinification
                      ? internalName : methodName),
              'internalName': js.string(internalName),
              'type': js.number(type),
              'arguments':
                  new jsAst.ArrayInitializer(parameterNames.map(js).toList()),
              'namedArguments': new jsAst.ArrayInitializer(argNames)});

      if (backend.isInterceptedName(selector.name)) {
        return js(r'function($receiver, #) { return # }',
                  [parameterNames, expression]);
      } else {
        return js(r'function(#) { return # }', [parameterNames, expression]);
      }
    }

    for (String jsName in addedJsNames.keys.toList()..sort()) {
      Selector selector = addedJsNames[jsName];
      jsAst.Expression method = generateMethod(jsName, selector);
      if (method != null) {
        addProperty(jsName, method);
        String reflectionName = emitter.getReflectionName(selector, jsName);
        if (reflectionName != null) {
          bool accessible = compiler.world.allFunctions.filter(selector).any(
              (Element e) => backend.isAccessibleByReflection(e));
          addProperty('+$reflectionName', js(accessible ? '2' : '0'));
        }
      }
    }
  }

  // Identify the noSuchMethod handlers that are so simple that we can
  // generate them programatically.
  bool isTrivialNsmHandler(
      int type, List argNames, Selector selector, String internalName) {
    if (!generateTrivialNsmHandlers) return false;
    // Check for interceptor calling convention.
    if (backend.isInterceptedName(selector.name)) {
      // We can handle the calling convention used by intercepted names in the
      // diff encoding, but we don't use that for non-minified code.
      if (!compiler.enableMinification) return false;
      String shortName = namer.invocationMirrorInternalName(selector);
      if (shortName.length > MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING) {
        return false;
      }
    }
    // Check for named arguments.
    if (argNames.length != 0) return false;
    // Check for unexpected name (this doesn't really happen).
    if (internalName.startsWith(namer.getterPrefix[0])) return type == 1;
    if (internalName.startsWith(namer.setterPrefix[0])) return type == 2;
    return type == 0;
  }

  /**
   * Adds (at runtime) the handlers to the Object class which catch calls to
   * methods that the object does not have.  The handlers create an invocation
   * mirror object.
   *
   * The current version only gives you the minified name when minifying (when
   * not minifying this method is not called).
   *
   * In order to generate the noSuchMethod handlers we only need the minified
   * name of the method.  We test the first character of the minified name to
   * determine if it is a getter or a setter, and we use the arguments array at
   * runtime to get the number of arguments and their values.  If the method
   * involves named arguments etc. then we don't handle it here, but emit the
   * handler method directly on the Object class.
   *
   * The minified names are mostly 1-4 character names, which we emit in sorted
   * order (primary key is length, secondary ordering is lexicographic).  This
   * gives an order like ... dD dI dX da ...
   *
   * Gzip is good with repeated text, but it can't diff-encode, so we do that
   * for it.  We encode the minified names in a comma-separated string, but all
   * the 1-4 character names are encoded before the first comma as a series of
   * base 26 numbers.  The last digit of each number is lower case, the others
   * are upper case, so 1 is "b" and 26 is "Ba".
   *
   * We think of the minified names as base 88 numbers using the ASCII
   * characters from # to z.  The base 26 numbers each encode the delta from
   * the previous minified name to the next.  So if there is a minified name
   * called Df and the next is Dh, then they are 2971 and 2973 when thought of
   * as base 88 numbers.  The difference is 2, which is "c" in lower-case-
   * terminated base 26.
   *
   * The reason we don't encode long minified names with this method is that
   * decoding the base 88 numbers would overflow JavaScript's puny integers.
   *
   * There are some selectors that have a special calling convention (because
   * they are called with the receiver as the first argument).  They need a
   * slightly different noSuchMethod handler, so we handle these first.
   */
  List<jsAst.Statement> buildTrivialNsmHandlers() {
    List<jsAst.Statement> statements = <jsAst.Statement>[];
    if (trivialNsmHandlers.length == 0) return statements;
    // Sort by calling convention, JS name length and by JS name.
    trivialNsmHandlers.sort((a, b) {
      bool aIsIntercepted = backend.isInterceptedName(a.name);
      bool bIsIntercepted = backend.isInterceptedName(b.name);
      if (aIsIntercepted != bIsIntercepted) return aIsIntercepted ? -1 : 1;
      String aName = namer.invocationMirrorInternalName(a);
      String bName = namer.invocationMirrorInternalName(b);
      if (aName.length != bName.length) return aName.length - bName.length;
      return aName.compareTo(bName);
    });

    // Find out how many selectors there are with the special calling
    // convention.
    int firstNormalSelector = trivialNsmHandlers.length;
    for (int i = 0; i < trivialNsmHandlers.length; i++) {
      if (!backend.isInterceptedName(trivialNsmHandlers[i].name)) {
        firstNormalSelector = i;
        break;
      }
    }

    // Get the short names (JS names, perhaps minified).
    Iterable<String> shorts = trivialNsmHandlers.map((selector) =>
         namer.invocationMirrorInternalName(selector));
    final diffShorts = <String>[];
    var diffEncoding = new StringBuffer();

    // Treat string as a number in base 88 with digits in ASCII order from # to
    // z.  The short name sorting is based on length, and uses ASCII order for
    // equal length strings so this means that names are ascending.  The hash
    // character, #, is never given as input, but we need it because it's the
    // implicit leading zero (otherwise we could not code names with leading
    // dollar signs).
    int fromBase88(String x) {
      int answer = 0;
      for (int i = 0; i < x.length; i++) {
        int c = x.codeUnitAt(i);
        // No support for Unicode minified identifiers in JS.
        assert(c >= $$ && c <= $z);
        answer *= 88;
        answer += c - $HASH;
      }
      return answer;
    }

    // Big endian encoding, A = 0, B = 1...
    // A lower case letter terminates the number.
    String toBase26(int x) {
      int c = x;
      var encodingChars = <int>[];
      encodingChars.add($a + (c % 26));
      while (true) {
        c ~/= 26;
        if (c == 0) break;
        encodingChars.add($A + (c % 26));
      }
      return new String.fromCharCodes(encodingChars.reversed.toList());
    }

    bool minify = compiler.enableMinification;
    bool useDiffEncoding = minify && shorts.length > 30;

    int previous = 0;
    int nameCounter = 0;
    for (String short in shorts) {
      // Emit period that resets the diff base to zero when we switch to normal
      // calling convention (this avoids the need to code negative diffs).
      if (useDiffEncoding && nameCounter == firstNormalSelector) {
        diffEncoding.write(".");
        previous = 0;
      }
      if (short.length <= MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING &&
          useDiffEncoding) {
        int base63 = fromBase88(short);
        int diff = base63 - previous;
        previous = base63;
        String base26Diff = toBase26(diff);
        diffEncoding.write(base26Diff);
      } else {
        if (useDiffEncoding || diffEncoding.length != 0) {
          diffEncoding.write(",");
        }
        diffEncoding.write(short);
      }
      nameCounter++;
    }

    // Startup code that loops over the method names and puts handlers on the
    // Object class to catch noSuchMethod invocations.
    ClassElement objectClass = compiler.objectClass;
    jsAst.Expression createInvocationMirror = backend.emitter
        .staticFunctionAccess(backend.getCreateInvocationMirror());
    String noSuchMethodName = namer.publicInstanceMethodNameByArity(
        Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT);
    var type = 0;
    if (useDiffEncoding) {
      statements.add(js.statement('''{
          var objectClassObject = processedClasses.collected[#objectClass],
              shortNames = #diffEncoding.split(","),
              nameNumber = 0,
              diffEncodedString = shortNames[0],
              calculatedShortNames = [0, 1];    // 0, 1 are args for splice.
          // If we are loading a deferred library the object class will not be in
          // the collectedClasses so objectClassObject is undefined, and we skip
          // setting up the names.

          if (objectClassObject) {
            if (objectClassObject instanceof Array)
              objectClassObject = objectClassObject[1];
            for (var i = 0; i < diffEncodedString.length; i++) {
              var codes = [],
                  diff = 0,
                  digit = diffEncodedString.charCodeAt(i);
              if (digit == ${$PERIOD}) {
                nameNumber = 0;
                digit = diffEncodedString.charCodeAt(++i);
              }
              for (; digit <= ${$Z};) {
                diff *= 26;
                diff += (digit - ${$A});
                digit = diffEncodedString.charCodeAt(++i);
              }
              diff *= 26;
              diff += (digit - ${$a});
              nameNumber += diff;
              for (var remaining = nameNumber;
                   remaining > 0;
                   remaining = (remaining / 88) | 0) {
                codes.unshift(${$HASH} + remaining % 88);
              }
              calculatedShortNames.push(
                String.fromCharCode.apply(String, codes));
            }
            shortNames.splice.apply(shortNames, calculatedShortNames);
          }
        }''', {'objectClass': js.string(namer.getNameOfClass(objectClass)),
               'diffEncoding': js.string('$diffEncoding')}));
    } else {
      // No useDiffEncoding version.
      Iterable<String> longs = trivialNsmHandlers.map((selector) =>
             selector.invocationMirrorMemberName);
      statements.add(js.statement(
          'var objectClassObject = processedClasses.collected[#objectClass],'
          '    shortNames = #diffEncoding.split(",")',
          {'objectClass': js.string(namer.getNameOfClass(objectClass)),
           'diffEncoding': js.string('$diffEncoding')}));
      if (!minify) {
        statements.add(js.statement('var longNames = #longs.split(",")',
                {'longs': js.string(longs.join(','))}));
      }
      statements.add(js.statement(
          'if (objectClassObject instanceof Array)'
          '  objectClassObject = objectClassObject[1];'));
    }

    // TODO(9631): This is no longer valid for native methods.
    String whatToPatch = emitter.nativeEmitter.handleNoSuchMethod ?
                         "Object.prototype" :
                         "objectClassObject";

    List<jsAst.Expression> sliceOffsetArguments =
        firstNormalSelector == 0
        ? []
        : (firstNormalSelector == shorts.length
            ? [js.number(1)]
            : [js('(j < #) ? 1 : 0', js.number(firstNormalSelector))]);

    var sliceOffsetParams = sliceOffsetArguments.isEmpty ? [] : ['sliceOffset'];

    statements.add(js.statement('''
      // If we are loading a deferred library the object class will not be in
      // the collectedClasses so objectClassObject is undefined, and we skip
      // setting up the names.
      if (objectClassObject) {
        for (var j = 0; j < shortNames.length; j++) {
          var type = 0;
          var short = shortNames[j];
          if (short[0] == "${namer.getterPrefix[0]}") type = 1;
          if (short[0] == "${namer.setterPrefix[0]}") type = 2;
          // Generate call to:
          //
          //     createInvocationMirror(String name, internalName, type,
          //         arguments, argumentNames)
          //
          $whatToPatch[short] = (function(name, short,
                                          type, #sliceOffsetParams) {
              return function() {
                return this.#noSuchMethodName(this,
                    #createInvocationMirror(name, short, type,
                        Array.prototype.slice.call(arguments,
                                                   #sliceOffsetParams),
                                                   []));
              }
          })(#names[j], short, type, #sliceOffsetArguments);
        }
      }''', {
          'sliceOffsetParams': sliceOffsetParams,
          'noSuchMethodName': noSuchMethodName,
          'createInvocationMirror': createInvocationMirror,
          'names': minify ? 'shortNames' : 'longNames',
          'sliceOffsetArguments': sliceOffsetArguments}));

    return statements;
  }
}
