// Copyright (c) 2014, 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 InterceptorStubGenerator {
  final Compiler compiler;
  final Namer namer;
  final JavaScriptBackend backend;
  final ClosedWorld closedWorld;

  InterceptorStubGenerator(
      this.compiler, this.namer, this.backend, this.closedWorld);

  Emitter get emitter => backend.emitter.emitter;

  BackendHelpers get helpers => backend.helpers;

  jsAst.Expression generateGetInterceptorMethod(Set<ClassElement> classes) {
    jsAst.Expression interceptorFor(ClassElement cls) {
      return backend.emitter.interceptorPrototypeAccess(cls);
    }

    /**
     * Build a JavaScrit AST node for doing a type check on
     * [cls]. [cls] must be a non-native interceptor class.
     */
    jsAst.Statement buildInterceptorCheck(ClassElement cls) {
      jsAst.Expression condition;
      assert(backend.isInterceptorClass(cls));
      if (cls == helpers.jsBoolClass) {
        condition = js('(typeof receiver) == "boolean"');
      } else if (cls == helpers.jsIntClass ||
          cls == helpers.jsDoubleClass ||
          cls == helpers.jsNumberClass) {
        throw 'internal error';
      } else if (cls == helpers.jsArrayClass ||
          cls == helpers.jsMutableArrayClass ||
          cls == helpers.jsFixedArrayClass ||
          cls == helpers.jsExtendableArrayClass) {
        condition = js('receiver.constructor == Array');
      } else if (cls == helpers.jsStringClass) {
        condition = js('(typeof receiver) == "string"');
      } else if (cls == helpers.jsNullClass) {
        condition = js('receiver == null');
      } else {
        throw 'internal error';
      }
      return js.statement('if (#) return #', [condition, interceptorFor(cls)]);
    }

    bool hasArray = false;
    bool hasBool = false;
    bool hasDouble = false;
    bool hasInt = false;
    bool hasNull = false;
    bool hasNumber = false;
    bool hasString = false;
    bool hasNative = false;
    bool anyNativeClasses =
        compiler.enqueuer.codegen.nativeEnqueuer.hasInstantiatedNativeClasses;

    for (ClassElement cls in classes) {
      if (cls == helpers.jsArrayClass ||
          cls == helpers.jsMutableArrayClass ||
          cls == helpers.jsFixedArrayClass ||
          cls == helpers.jsExtendableArrayClass)
        hasArray = true;
      else if (cls == helpers.jsBoolClass)
        hasBool = true;
      else if (cls == helpers.jsDoubleClass)
        hasDouble = true;
      else if (cls == helpers.jsIntClass)
        hasInt = true;
      else if (cls == helpers.jsNullClass)
        hasNull = true;
      else if (cls == helpers.jsNumberClass)
        hasNumber = true;
      else if (cls == helpers.jsStringClass)
        hasString = true;
      else {
        // The set of classes includes classes mixed-in to interceptor classes
        // and user extensions of native classes.
        //
        // The set of classes also includes the 'primitive' interceptor
        // PlainJavaScriptObject even when it has not been resolved, since it is
        // only resolved through the reference in getNativeInterceptor when
        // getNativeInterceptor is marked as used.  Guard against probing
        // unresolved PlainJavaScriptObject by testing for anyNativeClasses.

        if (anyNativeClasses) {
          if (backend.isNativeOrExtendsNative(cls)) hasNative = true;
        }
      }
    }
    if (hasDouble) {
      hasNumber = true;
    }
    if (hasInt) hasNumber = true;

    if (classes.containsAll(backend.interceptedClasses)) {
      // I.e. this is the general interceptor.
      hasNative = anyNativeClasses;
    }

    List<jsAst.Statement> statements = <jsAst.Statement>[];

    if (hasNumber) {
      jsAst.Statement whenNumber;

      /// Note: there are two number classes in play: Dart's [num],
      /// and JavaScript's Number (typeof receiver == 'number').  This
      /// is the fallback used when we have determined that receiver
      /// is a JavaScript Number.
      jsAst.Expression interceptorForNumber = interceptorFor(
          hasDouble ? helpers.jsDoubleClass : helpers.jsNumberClass);

      if (hasInt) {
        whenNumber = js.statement(
            '''{
            if (Math.floor(receiver) == receiver) return #;
            return #;
        }''',
            [interceptorFor(helpers.jsIntClass), interceptorForNumber]);
      } else {
        whenNumber = js.statement('return #', interceptorForNumber);
      }
      statements
          .add(js.statement('if (typeof receiver == "number") #;', whenNumber));
    }

    if (hasString) {
      statements.add(buildInterceptorCheck(helpers.jsStringClass));
    }
    if (hasNull) {
      statements.add(buildInterceptorCheck(helpers.jsNullClass));
    } else {
      // Returning "undefined" or "null" here will provoke a JavaScript
      // TypeError which is later identified as a null-error by
      // [unwrapException] in js_helper.dart.
      statements.add(js.statement('if (receiver == null) return receiver'));
    }
    if (hasBool) {
      statements.add(buildInterceptorCheck(helpers.jsBoolClass));
    }
    // TODO(ahe): It might be faster to check for Array before
    // function and bool.
    if (hasArray) {
      statements.add(buildInterceptorCheck(helpers.jsArrayClass));
    }

    if (hasNative) {
      statements.add(js.statement(
          r'''{
          if (typeof receiver != "object") {
              if (typeof receiver == "function" ) return #;
              return receiver;
          }
          if (receiver instanceof #) return receiver;
          return #(receiver);
      }''',
          [
            interceptorFor(helpers.jsJavaScriptFunctionClass),
            backend.emitter
                .constructorAccess(compiler.commonElements.objectClass),
            backend.emitter
                .staticFunctionAccess(helpers.getNativeInterceptorMethod)
          ]));
    } else {
      ClassElement jsUnknown = helpers.jsUnknownJavaScriptObjectClass;
      if (compiler.codegenWorld.directlyInstantiatedClasses
          .contains(jsUnknown)) {
        statements.add(js.statement('if (!(receiver instanceof #)) return #;', [
          backend.emitter
              .constructorAccess(compiler.commonElements.objectClass),
          interceptorFor(jsUnknown)
        ]));
      }

      statements.add(js.statement('return receiver'));
    }

    return js('''function(receiver) { #; }''', new jsAst.Block(statements));
  }

  // Returns a statement that takes care of performance critical
  // common case for a one-shot interceptor, or null if there is no
  // fast path.
  jsAst.Statement _fastPathForOneShotInterceptor(
      Selector selector, Set<ClassElement> classes) {
    if (selector.isOperator) {
      String name = selector.name;
      if (name == '==') {
        return js.statement('''{
          if (receiver == null) return a0 == null;
          if (typeof receiver != "object")
            return a0 != null && receiver === a0;
        }''');
      }
      if (!classes.contains(helpers.jsIntClass) &&
          !classes.contains(helpers.jsNumberClass) &&
          !classes.contains(helpers.jsDoubleClass)) {
        return null;
      }
      if (selector.argumentCount == 1) {
        // The following operators do not map to a JavaScript operator.
        if (name == '~/' || name == '<<' || name == '%' || name == '>>') {
          return null;
        }
        jsAst.Expression result = js('receiver $name a0');
        if (name == '&' || name == '|' || name == '^') {
          result = js('# >>> 0', result);
        }
        return js.statement(
            'if (typeof receiver == "number" && typeof a0 == "number")'
            '  return #;',
            result);
      } else if (name == 'unary-') {
        return js
            .statement('if (typeof receiver == "number") return -receiver');
      } else {
        assert(name == '~');
        return js.statement('''
          if (typeof receiver == "number" && Math.floor(receiver) == receiver)
            return (~receiver) >>> 0;
          ''');
      }
    } else if (selector.isIndex || selector.isIndexSet) {
      // For an index operation, this code generates:
      //
      //    if (typeof a0 === "number") {
      //      if (receiver.constructor == Array ||
      //          typeof receiver == "string") {
      //        if (a0 >>> 0 === a0 && a0 < receiver.length) {
      //          return receiver[a0];
      //        }
      //      }
      //    }
      //
      // For an index set operation, this code generates:
      //
      //    if (typeof a0 === "number") {
      //      if (receiver.constructor == Array && !receiver.immutable$list) {
      //        if (a0 >>> 0 === a0 && a0 < receiver.length) {
      //          return receiver[a0] = a1;
      //        }
      //      }
      //    }
      bool containsArray = classes.contains(helpers.jsArrayClass);
      bool containsString = classes.contains(helpers.jsStringClass);
      bool containsJsIndexable =
          helpers.jsIndexingBehaviorInterface.isResolved &&
              classes.any((cls) {
                return closedWorld.isSubtypeOf(
                    cls, helpers.jsIndexingBehaviorInterface);
              });
      // The index set operator requires a check on its set value in
      // checked mode, so we don't optimize the interceptor if the
      // compiler has type assertions enabled.
      if (selector.isIndexSet &&
          (compiler.options.enableTypeAssertions || !containsArray)) {
        return null;
      }
      if (!containsArray && !containsString) {
        return null;
      }
      jsAst.Expression arrayCheck = js('receiver.constructor == Array');
      jsAst.Expression indexableCheck =
          backend.generateIsJsIndexableCall(js('receiver'), js('receiver'));

      jsAst.Expression orExp(left, right) {
        return left == null ? right : js('# || #', [left, right]);
      }

      if (selector.isIndex) {
        jsAst.Expression typeCheck;
        if (containsArray) {
          typeCheck = arrayCheck;
        }

        if (containsString) {
          typeCheck = orExp(typeCheck, js('typeof receiver == "string"'));
        }

        if (containsJsIndexable) {
          typeCheck = orExp(typeCheck, indexableCheck);
        }

        return js.statement(
            '''
          if (typeof a0 === "number")
            if (#)
              if ((a0 >>> 0) === a0 && a0 < receiver.length)
                return receiver[a0];
          ''',
            typeCheck);
      } else {
        jsAst.Expression typeCheck;
        if (containsArray) {
          typeCheck = arrayCheck;
        }

        if (containsJsIndexable) {
          typeCheck = orExp(typeCheck, indexableCheck);
        }

        return js.statement(
            r'''
          if (typeof a0 === "number")
            if (# && !receiver.immutable$list &&
                (a0 >>> 0) === a0 && a0 < receiver.length)
              return receiver[a0] = a1;
          ''',
            typeCheck);
      }
    }
    return null;
  }

  jsAst.Expression generateOneShotInterceptor(jsAst.Name name) {
    Selector selector = backend.oneShotInterceptors[name];
    Set<ClassElement> classes = backend.getInterceptedClassesOn(selector.name);
    jsAst.Name getInterceptorName = namer.nameForGetInterceptor(classes);

    List<String> parameterNames = <String>[];
    parameterNames.add('receiver');

    if (selector.isSetter) {
      parameterNames.add('value');
    } else {
      for (int i = 0; i < selector.argumentCount; i++) {
        parameterNames.add('a$i');
      }
    }

    jsAst.Name invocationName = backend.namer.invocationName(selector);
    String globalObject = namer.globalObjectFor(helpers.interceptorsLibrary);

    jsAst.Statement optimizedPath =
        _fastPathForOneShotInterceptor(selector, classes);
    if (optimizedPath == null) optimizedPath = js.statement(';');

    return js('function(#) { #; return #.#(receiver).#(#) }', [
      parameterNames,
      optimizedPath,
      globalObject,
      getInterceptorName,
      invocationName,
      parameterNames
    ]);
  }

  jsAst.ArrayInitializer generateTypeToInterceptorMap() {
    // TODO(sra): Perhaps inject a constant instead?
    CustomElementsAnalysis analysis = backend.customElementsAnalysis;
    if (!analysis.needsTable) return null;

    List<jsAst.Expression> elements = <jsAst.Expression>[];
    JavaScriptConstantCompiler handler = backend.constants;
    List<ConstantValue> constants =
        handler.getConstantsForEmission(emitter.compareConstants);
    for (ConstantValue constant in constants) {
      if (constant is TypeConstantValue) {
        TypeConstantValue typeConstant = constant;
        Element element = typeConstant.representedType.element;
        if (element is ClassElement) {
          ClassElement classElement = element;
          if (!analysis.needsClass(classElement)) continue;

          elements.add(emitter.constantReference(constant));
          elements.add(backend.emitter.interceptorClassAccess(classElement));

          // Create JavaScript Object map for by-name lookup of generative
          // constructors.  For example, the class A has three generative
          // constructors
          //
          //     class A {
          //       A() {}
          //       A.foo() {}
          //       A.bar() {}
          //     }
          //
          // Which are described by the map
          //
          //     {"": A.A$, "foo": A.A$foo, "bar": A.A$bar}
          //
          // We expect most of the time the map will be a singleton.
          var properties = [];
          for (Element member in analysis.constructors(classElement)) {
            properties.add(new jsAst.Property(js.string(member.name),
                backend.emitter.staticFunctionAccess(member)));
          }

          var map = new jsAst.ObjectInitializer(properties);
          elements.add(map);
        }
      }
    }

    return new jsAst.ArrayInitializer(elements);
  }
}
