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

library dart2js.js_emitter.lazy_emitter.model_emitter;

import '../../compiler.dart' show
    Compiler;
import '../../constants/values.dart' show
    ConstantValue,
    FunctionConstantValue;
import '../../core_types.dart' show
    CoreClasses;
import '../../elements/elements.dart' show
    ClassElement,
    FunctionElement;
import '../../js/js.dart' as js;
import '../../js_backend/js_backend.dart' show
    JavaScriptBackend,
    Namer,
    ConstantEmitter;

import '../js_emitter.dart' show NativeEmitter;
import '../constant_ordering.dart' show deepCompareConstants;

import 'package:js_runtime/shared/embedded_names.dart' show
    CREATE_NEW_ISOLATE,
    DEFERRED_LIBRARY_URIS,
    DEFERRED_LIBRARY_HASHES,
    GET_TYPE_FROM_NAME,
    INITIALIZE_LOADED_HUNK,
    INTERCEPTORS_BY_TAG,
    IS_HUNK_INITIALIZED,
    IS_HUNK_LOADED,
    LEAF_TAGS,
    MANGLED_GLOBAL_NAMES,
    METADATA,
    TYPE_TO_INTERCEPTOR_MAP,
    TYPES;

import '../js_emitter.dart' show NativeGenerator, buildTearOffCode;
import '../model.dart';

class ModelEmitter {
  final Compiler compiler;
  final Namer namer;
  ConstantEmitter constantEmitter;
  final NativeEmitter nativeEmitter;

  JavaScriptBackend get backend => compiler.backend;

  /// For deferred loading we communicate the initializers via this global var.
  static const String deferredInitializersGlobal =
      r"$__dart_deferred_initializers__";

  static const String deferredExtension = "part.js";

  static const String typeNameProperty = r"builtin$cls";

  ModelEmitter(Compiler compiler, Namer namer, this.nativeEmitter)
      : this.compiler = compiler,
        this.namer = namer {

    this.constantEmitter = new ConstantEmitter(
        compiler, namer, this.generateConstantReference,
        constantListGenerator);
  }

  js.Expression constantListGenerator(js.Expression array) {
    // TODO(floitsch): remove hard-coded name.
    return js.js('makeConstList(#)', [array]);
  }

  js.Expression generateEmbeddedGlobalAccess(String global) {
    return js.js(generateEmbeddedGlobalAccessString(global));
  }

  String generateEmbeddedGlobalAccessString(String global) {
    // TODO(floitsch): don't use 'init' as global embedder storage.
    return 'init.$global';
  }

  bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
    if (constant.isFunction) return true;    // Already emitted.
    if (constant.isPrimitive) return true;   // Inlined.
    if (constant.isDummy) return true;       // Inlined.
    // The name is null when the constant is already a JS constant.
    // TODO(floitsch): every constant should be registered, so that we can
    // share the ones that take up too much space (like some strings).
    if (namer.constantName(constant) == null) return true;
    return false;
  }

  // TODO(floitsch): copied from full emitter. Adjust or share.
  int compareConstants(ConstantValue a, ConstantValue b) {
    // Inlined constants don't affect the order and sometimes don't even have
    // names.
    int cmp1 = isConstantInlinedOrAlreadyEmitted(a) ? 0 : 1;
    int cmp2 = isConstantInlinedOrAlreadyEmitted(b) ? 0 : 1;
    if (cmp1 + cmp2 < 2) return cmp1 - cmp2;

    // Emit constant interceptors first. Constant interceptors for primitives
    // might be used by code that builds other constants.  See Issue 18173.
    if (a.isInterceptor != b.isInterceptor) {
      return a.isInterceptor ? -1 : 1;
    }

    // Sorting by the long name clusters constants with the same constructor
    // which compresses a tiny bit better.
    int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
    if (r != 0) return r;

    // Resolve collisions in the long name by using a structural order.
    return deepCompareConstants(a, b);
  }

  js.Expression generateStaticClosureAccess(FunctionElement element) {
    return js.js('#.#()',
        [namer.globalObjectFor(element), namer.staticClosureName(element)]);
  }

  js.Expression generateConstantReference(ConstantValue value) {
    if (value.isFunction) {
      FunctionConstantValue functionConstant = value;
      return generateStaticClosureAccess(functionConstant.element);
    }

    // We are only interested in the "isInlined" part, but it does not hurt to
    // test for the other predicates.
    if (isConstantInlinedOrAlreadyEmitted(value)) {
      return constantEmitter.generate(value);
    }
    return js.js('#.#()', [namer.globalObjectForConstant(value),
                           namer.constantName(value)]);
  }

  int emitProgram(Program program) {
    List<Fragment> fragments = program.fragments;
    MainFragment mainFragment = fragments.first;
    Iterable<Fragment> deferredFragments = program.deferredFragments;

    int totalSize = 0;

    // We have to emit the deferred fragments first, since we need their
    // deferred hash (which depends on the output) when emitting the main
    // fragment.
    List<js.Expression> fragmentsCode = deferredFragments.map(
            (DeferredFragment deferredUnit) {
      js.Expression types =
          program.metadataTypesForOutputUnit(deferredUnit.outputUnit);
      return emitDeferredFragment(types, deferredUnit, program.holders);
    }).toList();

    js.Statement mainAst = emitMainFragment(program);

    js.TokenCounter counter = new js.TokenCounter();
    fragmentsCode.forEach(counter.countTokens);
    counter.countTokens(mainAst);

    program.finalizers.forEach((js.TokenFinalizer f) => f.finalizeTokens());

    for (int i = 0; i < fragmentsCode.length; ++i) {
      String code = js.prettyPrint(fragmentsCode[i], compiler).getText();
      totalSize += code.length;
      compiler.outputProvider(fragments[i+1].outputFileName, deferredExtension)
        ..add(code)
        ..close();
    }

    String mainCode = js.prettyPrint(mainAst, compiler).getText();
    compiler.outputProvider(mainFragment.outputFileName, 'js')
        ..add(buildGeneratedBy(compiler))
        ..add(mainCode)
        ..close();
    totalSize += mainCode.length;

    return totalSize;
  }

  /// Returns a [js.Literal] that represents the string result of unparsing
  /// [value].
  ///
  /// The returned node will, when its string value is requested, pretty-print
  /// the given [value] and, if [protectForEval] is true, wrap the resulting
  /// string in parenthesis. The result is also escaped.
  ///
  /// See [_UnparsedNode] for details.
  js.Literal unparse(Compiler compiler, js.Node value,
                     {bool protectForEval: true}) {
    return new js.UnparsedNode(value, compiler, protectForEval);
  }

  String buildGeneratedBy(compiler) {
    var suffix = '';
    if (compiler.hasBuildId) suffix = ' version: ${compiler.buildId}';
    return '// Generated by dart2js, the Dart to JavaScript compiler$suffix.\n';
  }

  js.Statement emitMainFragment(Program program) {
    MainFragment fragment = program.fragments.first;
    List<js.Expression> elements = fragment.libraries.map(emitLibrary).toList();
    elements.add(
        emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields));
    elements.add(emitConstants(fragment.constants));

    js.Expression code = new js.ArrayInitializer(elements);

    Map<String, dynamic> holes =
      {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap),
       'holders': emitHolders(program.holders),
       'tearOff': buildTearOffCode(backend),
       'parseFunctionDescriptor':
           js.js.statement(parseFunctionDescriptorBoilerplate,
               {'argumentCount': js.string(namer.requiredParameterField),
                'defaultArgumentValues': js.string(namer.defaultValuesField),
                'callName': js.string(namer.callNameField)}),

       'cyclicThrow':
           backend.emitter.staticFunctionAccess(
               backend.helpers.cyclicThrowHelper),
       'outputContainsConstantList': program.outputContainsConstantList,
       'embeddedGlobals': emitEmbeddedGlobals(program),
       'readMetadataTypeFunction': readMetadataTypeFunction,
       'staticNonFinals':
            emitStaticNonFinalFields(fragment.staticNonFinalFields),
       'operatorIsPrefix': js.string(namer.operatorIsPrefix),
       'callName': js.string(namer.callNameField),
       'argumentCount': js.string(namer.requiredParameterField),
       'defaultArgumentValues': js.string(namer.defaultValuesField),
       'eagerClasses': emitEagerClassInitializations(fragment.libraries),
       'invokeMain': fragment.invokeMain,
       'code': code};

    holes.addAll(nativeHoles(program));

    return js.js.statement(boilerplate, holes);
  }

  Map<String, dynamic> nativeHoles(Program program) {
    Map<String, dynamic> nativeHoles = <String, dynamic>{};

    js.Statement nativeIsolateAffinityTagInitialization;
    if (NativeGenerator.needsIsolateAffinityTagInitialization(backend)) {
      nativeIsolateAffinityTagInitialization =
          NativeGenerator.generateIsolateAffinityTagInitialization(
              backend,
              generateEmbeddedGlobalAccess,
              // TODO(floitsch): internStringFunction.
              js.js("(function(x) { return x; })", []));
    } else {
      nativeIsolateAffinityTagInitialization = js.js.statement(";");
    }
    nativeHoles['nativeIsolateAffinityTagInitialization'] =
        nativeIsolateAffinityTagInitialization;


    js.Expression nativeInfoAccess = js.js('nativeInfo', []);
    js.Expression constructorAccess = js.js('constructor', []);
    Function subclassReadGenerator = (js.Expression subclass) {
      return js.js('holdersMap[#][#].ensureResolved()', [subclass, subclass]);
    };
    js.Expression interceptorsByTagAccess =
        generateEmbeddedGlobalAccess(INTERCEPTORS_BY_TAG);
    js.Expression leafTagsAccess =
        generateEmbeddedGlobalAccess(LEAF_TAGS);
    js.Statement nativeInfoHandler = NativeGenerator.buildNativeInfoHandler(
        nativeInfoAccess,
        constructorAccess,
        subclassReadGenerator,
        interceptorsByTagAccess,
        leafTagsAccess);

    nativeHoles['needsNativeSupport'] = program.needsNativeSupport;
    nativeHoles['needsNoNativeSupport'] = !program.needsNativeSupport;
    nativeHoles['nativeInfoHandler'] = nativeInfoHandler;

    return nativeHoles;
  }

  js.Block emitHolders(List<Holder> holders) {
    // The top-level variables for holders must *not* be renamed by the
    // JavaScript pretty printer because a lot of code already uses the
    // non-renamed names. The generated code looks like this:
    //
    //    var H = {}, ..., G = {};
    //    var holders = [ H, ..., G ];
    //
    // and it is inserted at the top of the top-level function expression
    // that covers the entire program.

    List<js.Statement> statements = [
        new js.ExpressionStatement(
            new js.VariableDeclarationList(holders.map((e) =>
                new js.VariableInitialization(
                    new js.VariableDeclaration(e.name, allowRename: false),
                    new js.ObjectInitializer(const []))).toList())),
        js.js.statement('var holders = #', new js.ArrayInitializer(
            holders.map((e) => new js.VariableUse(e.name))
                   .toList(growable: false))),
        js.js.statement('var holdersMap = Object.create(null)')
    ];
    return new js.Block(statements);
  }

  js.Block emitEmbeddedGlobals(Program program) {
    List<js.Property> globals = <js.Property>[];

    if (program.loadMap.isNotEmpty) {
      globals.addAll(emitEmbeddedGlobalsForDeferredLoading(program.loadMap));
    }

    if (program.typeToInterceptorMap != null) {
      globals.add(new js.Property(js.string(TYPE_TO_INTERCEPTOR_MAP),
                                  program.typeToInterceptorMap));
    }

    if (program.hasIsolateSupport) {
      String isolateName = namer.staticStateHolder;
      globals.add(
          new js.Property(js.string(CREATE_NEW_ISOLATE),
                          js.js('function () { return $isolateName; }')));
      // TODO(floitsch): add remaining isolate functions.
    }

    globals.add(emitMangledGlobalNames());

    globals.add(emitGetTypeFromName());

    globals.addAll(emitMetadata(program));

    if (program.needsNativeSupport) {
      globals.add(new js.Property(js.string(INTERCEPTORS_BY_TAG),
                                  js.js('Object.create(null)', [])));
      globals.add(new js.Property(js.string(LEAF_TAGS),
                                  js.js('Object.create(null)', [])));
    }

    js.ObjectInitializer globalsObject = new js.ObjectInitializer(globals);

    List<js.Statement> statements =
        [new js.ExpressionStatement(
            new js.VariableDeclarationList(
                [new js.VariableInitialization(
                    new js.VariableDeclaration("init", allowRename: false),
                    globalsObject)]))];
    return new js.Block(statements);
  }

  js.Property emitMangledGlobalNames() {
    List<js.Property> names = <js.Property>[];

    CoreClasses coreClasses = compiler.coreClasses;
    // We want to keep the original names for the most common core classes when
    // calling toString on them.
    List<ClassElement> nativeClassesNeedingUnmangledName =
        [coreClasses.intClass, coreClasses.doubleClass, coreClasses.numClass,
         coreClasses.stringClass, coreClasses.boolClass, coreClasses.nullClass,
         coreClasses.listClass];
    nativeClassesNeedingUnmangledName.forEach((element) {
        names.add(new js.Property(js.quoteName(namer.className(element)),
                                  js.string(element.name)));
    });

    return new js.Property(js.string(MANGLED_GLOBAL_NAMES),
                           new js.ObjectInitializer(names));
  }

  js.Statement emitDeferredInitializerGlobal(Map loadMap) {
    if (loadMap.isEmpty) return new js.Block.empty();

    return js.js.statement("""
  if (typeof($deferredInitializersGlobal) === 'undefined')
    var $deferredInitializersGlobal = Object.create(null);""");
  }

  Iterable<js.Property> emitEmbeddedGlobalsForDeferredLoading(
      Map<String, List<Fragment>> loadMap) {

    List<js.Property> globals = <js.Property>[];

    js.ArrayInitializer fragmentUris(List<Fragment> fragments) {
      return js.stringArray(fragments.map((DeferredFragment fragment) =>
          "${fragment.outputFileName}.$deferredExtension"));
    }
    js.ArrayInitializer fragmentHashes(List<Fragment> fragments) {
      // TODO(floitsch): the hash must depend on the generated code.
      return js.numArray(
          fragments.map((DeferredFragment fragment) => fragment.hashCode));
    }

    List<js.Property> uris = new List<js.Property>(loadMap.length);
    List<js.Property> hashes = new List<js.Property>(loadMap.length);
    int count = 0;
    loadMap.forEach((String loadId, List<Fragment> fragmentList) {
      uris[count] =
          new js.Property(js.string(loadId), fragmentUris(fragmentList));
      hashes[count] =
          new js.Property(js.string(loadId), fragmentHashes(fragmentList));
      count++;
    });

    globals.add(new js.Property(js.string(DEFERRED_LIBRARY_URIS),
                                new js.ObjectInitializer(uris)));
    globals.add(new js.Property(js.string(DEFERRED_LIBRARY_HASHES),
                                new js.ObjectInitializer(hashes)));

    js.Expression isHunkLoadedFunction =
        js.js("function(hash) { return !!$deferredInitializersGlobal[hash]; }");
    globals.add(new js.Property(js.string(IS_HUNK_LOADED),
                                isHunkLoadedFunction));

    js.Expression isHunkInitializedFunction =
        js.js("function(hash) { return false; }");
    globals.add(new js.Property(js.string(IS_HUNK_INITIALIZED),
                                isHunkInitializedFunction));

    js.Expression typesAccess = generateEmbeddedGlobalAccess(TYPES);

    /// See [emitEmbeddedGlobalsForDeferredLoading] for the format of the
    /// deferred hunk.
    js.Expression initializeLoadedHunkFunction =
        js.js("""
          function(hash) {
            var hunk = $deferredInitializersGlobal[hash];
            $setupProgramName(hunk[0], #typesAccess.length);
            eval(hunk[1]);
            var deferredTypes = eval(hunk[2]);
            #typesAccess.push.apply(#typesAccess, deferredTypes);
          }""", {'typesAccess': typesAccess});

    globals.add(new js.Property(js.string(INITIALIZE_LOADED_HUNK),
                                initializeLoadedHunkFunction));

    return globals;
  }

  js.Property emitGetTypeFromName() {
    js.Expression function =
        js.js( """function(name) {
                    return holdersMap[name][name].ensureResolved();
                  }""");
    return new js.Property(js.string(GET_TYPE_FROM_NAME), function);
  }

  static final String readMetadataTypeName = "readMetadataType";

  js.Statement get readMetadataTypeFunction {
    // Types are non-evaluated and must be compiled at first use.
    // Compiled strings are guaranteed not to be strings, and it's thus safe
    // to use a type-test to determine if a type has already been compiled.
    return js.js.statement('''function $readMetadataTypeName(index) {
      var type = #typesAccess[index];
      if (typeof type == 'string') {
        type = expressionCompile(type);
        #typesAccess[index] = type;
      }
      return type;
    }''', {"typesAccess": generateEmbeddedGlobalAccess(TYPES)});
  }

  js.Template get templateForReadType {
    // TODO(floitsch): make sure that no local variable shadows the access to
    // the readMetadataType function.
    return js.js.expressionTemplateFor('$readMetadataTypeName(#)');
  }

  static final String readMetadataName = "readLazyMetadata";
  static final String lazyMetadataName = "lazy_$METADATA";

  js.Statement get readMetadataFunction {
    // Types are non-evaluated and must be compiled at first use.
    // Compiled strings are guaranteed not to be strings, and it's thus safe
    // to use a type-test to determine if a type has already been compiled.
    return js.js.statement('''function $readMetadataName(index) {
      var lazyMetadata = #lazyMetadataAccess[index];
      if (typeof lazyMetadata == 'string') {
        #metadataAccess[index] = expressionCompile(lazyMetadata);
        #lazyMetadataAccess[index] = null;
      }
      return #metadataAccess[index];
    }''', {
      "lazyMetadataAccess": generateEmbeddedGlobalAccess(lazyMetadataName),
      "metadataAccess": generateEmbeddedGlobalAccess(METADATA)
    });
  }

  js.Template get templateForReadMetadata {
    // TODO(floitsch): make sure that no local variable shadows the access to
    // the readMetadata function.
    return js.js.expressionTemplateFor('$readMetadataName(#)');
  }

  List<js.Property> emitMetadata(Program program) {
    List<js.Property> metadataGlobals = <js.Property>[];

    js.Property createGlobal(js.Expression metadata, String global) {
      return new js.Property(js.string(global), metadata);
    }

    metadataGlobals.add(createGlobal(program.metadata, METADATA));
    js.Expression types =
        program.metadataTypesForOutputUnit(program.mainFragment.outputUnit);
    metadataGlobals.add(createGlobal(types, TYPES));

    return metadataGlobals;
  }

  js.Expression emitDeferredFragment(js.Expression deferredTypes,
                                     DeferredFragment fragment,
                                     List<Holder> holders) {
    // TODO(floitsch): initialize eager classes.
    // TODO(floitsch): the hash must depend on the output.
    int hash = fragment.hashCode;

    List<js.Expression> deferredCode =
        fragment.libraries.map(emitLibrary).toList();

    deferredCode.add(
        emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields));
    deferredCode.add(emitConstants(fragment.constants));

    js.ArrayInitializer deferredArray = new js.ArrayInitializer(deferredCode);

    // This is the code that must be evaluated after all deferred classes have
    // been setup.
    js.Statement immediateCode = new js.Block([
        emitStaticNonFinalFields(fragment.staticNonFinalFields),
        emitEagerClassInitializations(fragment.libraries)]);


    js.Literal immediateString = unparse(compiler, immediateCode);

    js.ArrayInitializer hunk =
        new js.ArrayInitializer([deferredArray, immediateString,
                                 deferredTypes]);

    return js.js("$deferredInitializersGlobal[$hash] = #", hunk);
  }

  // This string should be referenced wherever JavaScript code makes assumptions
  // on the constants format.
  static final String constantsDescription =
      "The constants are encoded as a follows:"
      "   [constantsHolderIndex, name, code, name2, code2, ...]."
      "The array is completely empty if there is no constant at all.";

  js.ArrayInitializer emitConstants(List<Constant> constants) {
    List<js.Expression> data = <js.Expression>[];
    if (constants.isNotEmpty) {
      int holderIndex = constants.first.holder.index;
      data.add(js.number(holderIndex));
      data.addAll(constants.expand((Constant constant) {
        assert(constant.holder.index == holderIndex);
        js.Expression code = constantEmitter.generate(constant.value);
        return [js.quoteName(constant.name), unparse(compiler, code)];
      }));
    }
    return new js.ArrayInitializer(data);
  }

  js.Block emitStaticNonFinalFields(List<StaticField> fields) {
    Iterable<js.Statement> statements = fields.map((StaticField field) {
      return js.js.statement("#.# = #;",
                             [field.holder.name, field.name, field.code]);
    });
    return new js.Block(statements.toList());
  }

  js.Expression emitLazilyInitializedStatics(List<StaticField> fields) {
    Iterable fieldDescriptors = fields.expand((field) =>
        [ js.quoteName(field.name),
          js.quoteName(namer.deriveLazyInitializerName(field.name)),
          js.number(field.holder.index),
          emitLazyInitializer(field) ]);
    return new js.ArrayInitializer(fieldDescriptors.toList(growable: false));
  }

  js.Block emitEagerClassInitializations(List<Library> libraries) {
    js.Statement createInstantiation(Class cls) {
      return js.js.statement('new #.#()', [cls.holder.name, cls.name]);
    }

    List<js.Statement> instantiations =
        libraries.expand((Library library) => library.classes)
                 .where((Class cls) => cls.isEager)
                 .map(createInstantiation)
                 .toList(growable: false);
    return new js.Block(instantiations);
  }

  // This string should be referenced wherever JavaScript code makes assumptions
  // on the mixin format.
  static final String nativeInfoDescription =
      "A class is encoded as follows:"
      "   [name, class-code, holder-index], or "
      "   [name, class-code, native-info, holder-index].";

  js.Expression emitLibrary(Library library) {
    Iterable staticDescriptors = library.statics.expand(emitStaticMethod);

    Iterable classDescriptors = library.classes.expand((Class cls) {
      js.Literal name = js.quoteName(cls.name);
      js.LiteralNumber holderIndex = js.number(cls.holder.index);
      js.Expression emittedClass = emitClass(cls);
      js.Expression nativeInfo = NativeGenerator.encodeNativeInfo(cls);
      if (nativeInfo == null) {
        return [name, emittedClass, holderIndex];
      } else {
        return [name, emittedClass, nativeInfo, holderIndex];
      }
    });

    js.Expression staticArray =
        new js.ArrayInitializer(staticDescriptors.toList(growable: false));
    js.Expression classArray =
        new js.ArrayInitializer(classDescriptors.toList(growable: false));

    return new js.ArrayInitializer([staticArray, classArray]);
  }

  js.Expression _generateConstructor(Class cls) {
    List<js.Name> fieldNames = const <js.Name>[];

    // If the class is not directly instantiated we only need it for inheritance
    // or RTI. In either case we don't need its fields.
    if (cls.isDirectlyInstantiated && !cls.isNative) {
      fieldNames = cls.fields.map((Field field) => field.name).toList();
    }
    js.Name name = cls.name;

    Iterable<js.Name> assignments = fieldNames.map((js.Name field) {
        return js.js("this.#field = #field", {"field": field});
      });

    return js.js('function #(#) { # }', [name, fieldNames, assignments]);
  }

  Method _generateGetter(Field field) {
    String getterTemplateFor(int flags) {
      switch (flags) {
        case 1: return "function() { return this[#]; }";
        case 2: return "function(receiver) { return receiver[#]; }";
        case 3: return "function(receiver) { return this[#]; }";
      }
      return null;
    }

    js.Expression fieldName = js.quoteName(field.name);
    js.Expression code = js.js(getterTemplateFor(field.getterFlags), fieldName);
    js.Name getterName = namer.deriveGetterName(field.accessorName);
    return new StubMethod(getterName, code);
  }

  Method _generateSetter(Field field) {
    String setterTemplateFor(int flags) {
      switch (flags) {
        case 1: return "function(val) { return this[#] = val; }";
        case 2: return "function(receiver, val) { return receiver[#] = val; }";
        case 3: return "function(receiver, val) { return this[#] = val; }";
      }
      return null;
    }
    js.Expression fieldName = js.quoteName(field.name);
    js.Expression code = js.js(setterTemplateFor(field.setterFlags), fieldName);
    js.Name setterName = namer.deriveSetterName(field.accessorName);
    return new StubMethod(setterName, code);
  }

  Iterable<Method> _generateGettersSetters(Class cls) {
    Iterable<Method> getters = cls.fields
        .where((Field field) => field.needsGetter)
        .map(_generateGetter);

    Iterable<Method> setters = cls.fields
        .where((Field field) => field.needsUncheckedSetter)
        .map(_generateSetter);

    return [getters, setters].expand((x) => x);
  }

  // This string should be referenced wherever JavaScript code makes assumptions
  // on the mixin format.
  static final String mixinFormatDescription =
      "Mixins have a reference to their mixin class at the place of the usual"
      "constructor. If they are instantiated the constructor follows the"
      "reference.";

  js.Expression emitClass(Class cls) {
    List elements = [js.quoteName(cls.superclassName, allowNull: true),
                     js.number(cls.superclassHolderIndex)];

    if (cls.isMixinApplication) {
      MixinApplication mixin = cls;
      elements.add(js.quoteName(mixin.mixinClass.name));
      elements.add(js.number(mixin.mixinClass.holder.index));
      if (cls.isDirectlyInstantiated) {
        elements.add(_generateConstructor(cls));
      }
    } else {
      elements.add(_generateConstructor(cls));
    }
    Iterable<Method> methods = cls.methods;
    Iterable<Method> isChecks = cls.isChecks;
    Iterable<Method> callStubs = cls.callStubs;
    Iterable<Method> typeVariableReaderStubs = cls.typeVariableReaderStubs;
    Iterable<Method> noSuchMethodStubs = cls.noSuchMethodStubs;
    Iterable<Method> gettersSetters = _generateGettersSetters(cls);
    Iterable<Method> allMethods =
        [methods, isChecks, callStubs, typeVariableReaderStubs,
         noSuchMethodStubs, gettersSetters].expand((x) => x);
    elements.addAll(allMethods.expand(emitInstanceMethod));

    return unparse(compiler, new js.ArrayInitializer(elements));
  }

  js.Expression emitLazyInitializer(StaticField field) {
    assert(field.isLazy);
    return unparse(compiler, field.code);
  }

  /// JavaScript code template that implements parsing of a function descriptor.
  /// Descriptors are used in place of the actual JavaScript function
  /// definition in the output if additional information needs to be passed to
  /// facilitate the generation of tearOffs at runtime. The format is an array
  /// with the following fields:
  ///
  /// * [InstanceMethod.aliasName] (optional).
  /// * [Method.code]
  /// * [DartMethod.callName]
  /// * isInterceptedMethod (optional, present if [DartMethod.needsTearOff]).
  /// * [DartMethod.tearOffName] (optional, present if
  ///   [DartMethod.needsTearOff]).
  /// * functionType (optional, present if [DartMethod.needsTearOff]).
  ///
  /// followed by
  ///
  /// * [ParameterStubMethod.name]
  /// * [ParameterStubMethod.callName]
  /// * [ParameterStubMethod.code]
  ///
  /// for each stub in [DartMethod.parameterStubs].
  ///
  /// If the closure could be used in `Function.apply` (i.e.
  /// [DartMethod.canBeApplied] is true) then the following fields are appended:
  ///
  /// * [DartMethod.requiredParameterCount]
  /// * [DartMethod.optionalParameterDefaultValues]

  static final String parseFunctionDescriptorBoilerplate = r"""
function parseFunctionDescriptor(proto, name, descriptor, typesOffset) {
  if (descriptor instanceof Array) {
    // 'pos' points to the last read entry.
    var f, pos = -1;
    var aliasOrFunction = descriptor[++pos];
    if (typeof aliasOrFunction == "string") {
      // Install the alias for super calls on the prototype chain.
      proto[aliasOrFunction] = f = descriptor[++pos];
    } else {
      f = aliasOrFunction;
    }

    proto[name] = f;
    var funs = [f];
    f[#callName] = descriptor[++pos];

    var isInterceptedOrParameterStubName = descriptor[pos + 1];
    var isIntercepted, tearOffName, reflectionInfo;
    if (typeof isInterceptedOrParameterStubName == "boolean") {
      isIntercepted = descriptor[++pos];
      tearOffName = descriptor[++pos];
      reflectionInfo = descriptor[++pos];
      if (typeof reflectionInfo == "number") {
        reflectionInfo = reflectionInfo + typesOffset;
      }
    }

    // We iterate in blocks of 3 but have to stop before we reach the (optional)
    // two trailing items. To accomplish this, we only iterate until we reach
    // length - 2.
    for (++pos; pos < descriptor.length - 2; pos += 3) {
      var stub = descriptor[pos + 2];
      stub[#callName] = descriptor[pos + 1];
      proto[descriptor[pos]] = stub;
      funs.push(stub);
    }

    if (tearOffName) {
      proto[tearOffName] =
          tearOff(funs, reflectionInfo, false, name, isIntercepted);
    }
    if (pos < descriptor.length) {
      f[#argumentCount] = descriptor[pos];
      f[#defaultArgumentValues] = descriptor[pos + 1];
    }
  } else {
    proto[name] = descriptor;
  }
}
""";

  js.Expression _encodeOptionalParameterDefaultValues(DartMethod method) {
    // TODO(herhut): Replace [js.LiteralNull] with [js.ArrayHole].
    if (method.optionalParameterDefaultValues is List) {
      List<ConstantValue> defaultValues = method.optionalParameterDefaultValues;
      Iterable<js.Expression> elements =
          defaultValues.map(generateConstantReference);
      return new js.ArrayInitializer(elements.toList());
    } else {
      Map<String, ConstantValue> defaultValues =
          method.optionalParameterDefaultValues;
      List<js.Property> properties = <js.Property>[];
      defaultValues.forEach((String name, ConstantValue value) {
        properties.add(new js.Property(js.string(name),
            generateConstantReference(value)));
      });
      return new js.ObjectInitializer(properties);
    }
  }

  Iterable<js.Expression> emitInstanceMethod(Method method) {

    List<js.Expression> makeNameCodePair(Method method) {
      return [js.quoteName(method.name), method.code];
    }

    List<js.Expression> makeNameCallNameCodeTriplet(ParameterStubMethod stub) {
      js.Expression callName = stub.callName == null
          ? new js.LiteralNull()
          : js.quoteName(stub.callName);
      return [js.quoteName(stub.name), callName, stub.code];
    }

    if (method is InstanceMethod) {
      if (method.needsTearOff || method.aliasName != null) {
        /// See [parseFunctionDescriptorBoilerplate] for a full description of
        /// the format.
        // [name, [aliasName, function, callName, isIntercepted, tearOffName,
        // functionType, stub1_name, stub1_callName, stub1_code, ...]
        var data = [];
        if (method.aliasName != null) {
          data.add(js.quoteName(method.aliasName));
        }
        data.add(method.code);
        data.add(js.quoteName(method.callName, allowNull: true));

        if (method.needsTearOff) {
          bool isIntercepted = backend.isInterceptedMethod(method.element);
          data.add(new js.LiteralBool(isIntercepted));
          data.add(js.quoteName(method.tearOffName));
          data.add((method.functionType));
        }

        data.addAll(method.parameterStubs.expand(makeNameCallNameCodeTriplet));
        if (method.canBeApplied) {
          data.add(js.number(method.requiredParameterCount));
          data.add(_encodeOptionalParameterDefaultValues(method));
        }
        return [js.quoteName(method.name), new js.ArrayInitializer(data)];
      } else {
        // TODO(floitsch): not the most efficient way...
        return ([method]..addAll(method.parameterStubs))
            .expand(makeNameCodePair);
      }
    } else {
      return makeNameCodePair(method);
    }
  }

  Iterable<js.Expression> emitStaticMethod(StaticMethod method) {
    js.Expression holderIndex = js.number(method.holder.index);
    List<js.Expression> output = <js.Expression>[];

    void _addMethod(Method method) {
      js.Expression unparsed = unparse(compiler, method.code);
      output.add(js.quoteName(method.name));
      output.add(holderIndex);
      output.add(unparsed);
    }

    List<js.Expression> makeNameCallNameCodeTriplet(ParameterStubMethod stub) {
      js.Expression callName = stub.callName == null
          ? new js.LiteralNull()
          : js.quoteName(stub.callName);
      return [js.quoteName(stub.name), callName, unparse(compiler, stub.code)];
    }

    _addMethod(method);
    // TODO(floitsch): can there be anything else than a StaticDartMethod?
    if (method is StaticDartMethod) {
      if (method.needsTearOff) {
        /// The format emitted is the same as for the parser specified at
        /// [parseFunctionDescriptorBoilerplate] except for the missing
        /// field whether the method is intercepted.
        // [name, [function, callName, tearOffName, functionType,
        //     stub1_name, stub1_callName, stub1_code, ...]
        var data = [unparse(compiler, method.code)];
        data.add(js.quoteName(method.callName));
        data.add(js.quoteName(method.tearOffName));
        data.add(method.functionType);
        data.addAll(method.parameterStubs.expand(makeNameCallNameCodeTriplet));
        if (method.canBeApplied) {
          data.add(js.number(method.requiredParameterCount));
          data.add(_encodeOptionalParameterDefaultValues(method));
        }
        return [js.quoteName(method.name), holderIndex,
                new js.ArrayInitializer(data)];
      } else {
        method.parameterStubs.forEach(_addMethod);
      }
    }
    return output;
  }

  static final String setupProgramName = "setupProgram";

  static final String boilerplate = """
{
// Declare deferred-initializer global.
#deferredInitializer;

(function(start, program) {
  // Initialize holder objects.
  #holders;
  var nativeInfos = Object.create(null);

  // Counter to generate unique names for tear offs.
  var functionCounter = 0;

  function $setupProgramName(program, typesOffset) {
    for (var i = 0; i < program.length - 2; i++) {
      setupLibrary(program[i], typesOffset);
    }
    setupLazyStatics(program[i]);
    setupConstants(program[i + 1]);
  }

  function setupLibrary(library, typesOffset) {
    var statics = library[0];
    for (var i = 0; i < statics.length; i += 3) {
      var holderIndex = statics[i + 1];
      setupStatic(statics[i], holders[holderIndex], statics[i + 2],
                  typesOffset);
    }

    var classes = library[1];
    for (var i = 0; i < classes.length; i += 3) {
      var name = classes[i];
      var cls = classes[i + 1];

      if (#needsNativeSupport) {
        // $nativeInfoDescription.
        var indexOrNativeInfo = classes[i + 2];
        if (typeof indexOrNativeInfo == "number") {
          var holderIndex = classes[i + 2];
        } else {
          nativeInfos[name] = indexOrNativeInfo;
          holderIndex = classes[i + 3];
          i++;
        }
      }

      if (#needsNoNativeSupport) {
        var holderIndex = classes[i + 2];
      }

      holdersMap[name] = holders[holderIndex];
      setupClass(name, holders[holderIndex], cls, typesOffset);
    }
  }

  function setupLazyStatics(statics) {
    for (var i = 0; i < statics.length; i += 4) {
      var name = statics[i];
      var getterName = statics[i + 1];
      var holderIndex = statics[i + 2];
      var initializer = statics[i + 3];
      setupLazyStatic(name, getterName, holders[holderIndex], initializer);
    }
  }

  function setupConstants(constants) {
    // $constantsDescription.
    if (constants.length == 0) return;
    // We assume that all constants are in the same holder.
    var holder = holders[constants[0]];
    for (var i = 1; i < constants.length; i += 2) {
      var name = constants[i];
      var initializer = constants[i + 1];
      setupConstant(name, holder, initializer);
    }
  }

  function setupStatic(name, holder, descriptor, typesOffset) {
    if (typeof descriptor == 'string') {
      holder[name] = function() {
        if (descriptor == null) {
          // Already compiled. This happens when we have calls to the static as
          // arguments to the static: `foo(foo(499))`;
          return holder[name].apply(this, arguments);
        }
        var method = compile(name, descriptor);
        holder[name] = method;
        descriptor = null;  // GC the descriptor.
        return method.apply(this, arguments);
      };
    } else {
      // Parse the tear off information and generate compile handlers.
      // TODO(herhut): Share parser with instance methods.      
      function compileAllStubs(typesOffset) {
        var funs;
        var fun = compile(name, descriptor[0]);
        fun[#callName] = descriptor[1];
        holder[name] = fun;
        funs = [fun];
        // We iterate in blocks of 3 but have to stop before we reach the
        // (optional) two trailing items. To accomplish this, we only iterate
        // until we reach length - 2.
        for (var pos = 4; pos < descriptor.length - 2; pos += 3) {
          var stubName = descriptor[pos];
          fun = compile(stubName, descriptor[pos + 2]);
          fun[#callName] = descriptor[pos + 1];
          holder[stubName] = fun;
          funs.push(fun);
        }
        if (descriptor[2] != null) {  // tear-off name.
          // functions, reflectionInfo, isStatic, name, isIntercepted.
          var reflectionInfo = descriptor[3];
          if (typeof reflectionInfo == "number") {
            reflectionInfo = reflectionInfo + typesOffset;
          }
          holder[descriptor[2]] = 
              tearOff(funs, reflectionInfo, true, name, false);
        }
        if (pos < descriptor.length) {
          fun[#argumentCount] = descriptor[pos];
          fun[#defaultArgumentValues] = descriptor[pos + 1];
        }
      }

      function setupCompileAllAndDelegateStub(name, typesOffset) {
        holder[name] = function() {
          // The descriptor is null if we already compiled this function. This
          // happens when we have calls to the static as arguments to the
          // static: `foo(foo(499))`;
          if (descriptor != null) {
            compileAllStubs(typesOffset);
            descriptor = null;  // GC the descriptor.
          }
          return holder[name].apply(this, arguments);
        };
      }

      setupCompileAllAndDelegateStub(name, typesOffset);
      for (var pos = 4; pos < descriptor.length; pos += 3) {
        setupCompileAllAndDelegateStub(descriptor[pos], typesOffset);
      }
      if (descriptor[2] != null) {  // tear-off name.
        setupCompileAllAndDelegateStub(descriptor[2], typesOffset)
      }
    }
  }

  function setupLazyStatic(name, getterName, holder, descriptor) {
    holder[name] = null;
    holder[getterName] = function() {
      var initializer = compile(name, descriptor);
      holder[getterName] = function() { #cyclicThrow(name) };
      var result;
      var sentinelInProgress = descriptor;
      try {
        result = holder[name] = sentinelInProgress;
        result = holder[name] = initializer();
      } finally {
        // Use try-finally, not try-catch/throw as it destroys the stack trace.
        if (result === sentinelInProgress) {
          // The lazy static (holder[name]) might have been set to a different
          // value. According to spec we still have to reset it to null, if the
          // initialization failed.
          holder[name] = null;
        }
        // TODO(floitsch): the function should probably be unique for each
        // static.
        holder[getterName] = function() { return this[name]; };
      }
      return result;
    };
  }

  function setupConstant(name, holder, descriptor) {
    var c;
    holder[name] = function() {
      if (descriptor !== null) {
        c = compile(name, descriptor);
        name = null;
        descriptor = null;
      }
      return c;
    };
  }

  function setupClass(name, holder, descriptor, typesOffset) {
    var patch = function() {
      if (patch.ensureResolved == patch) {
        // We have not yet been compiled.
        var constructor = compileConstructor(name, descriptor, typesOffset);
        holder[name] = constructor;
        name = holder = descriptor = null;  // GC the captured arguments.
        // Make sure we can invoke 'ensureResolved' multiple times on the patch
        // function.
        patch.ensureResolved = function() { return constructor; };
        constructor.ensureResolved = function() { return this; };
      } else {
        // This can happen when arguments to the constructor are of the same
        // class, like in `new A(new A(null))`.
        constructor = patch.ensureResolved();
      }
      // If the patch has been called as "ensureResolved" return.
      if (this === patch) return constructor;
      var object = new constructor();
      constructor.apply(object, arguments);
      return object;
    };

    // We store the patch function on itself to make it
    // possible to resolve superclass references without constructing instances.
    patch.ensureResolved = patch;
    holder[name] = patch;
  }

  #tearOff;

  #parseFunctionDescriptor;

  function compileConstructor(name, descriptor, typesOffset) {
    descriptor = compile(name, descriptor);
    var prototype = determinePrototype(descriptor);
    var constructor;
    var functionsIndex;
    // $mixinFormatDescription.
    if (typeof descriptor[2] !== 'function') {
      fillPrototypeWithMixedIn(descriptor[2], descriptor[3], prototype);
      // descriptor[4] contains the constructor if the mixin application is
      // directly instantiated.
      if (typeof descriptor[4] === 'function') {
        constructor = descriptor[4];
        functionsIndex = 5;
      } else {
        constructor = function() {};
        functionsIndex = 4;
      }
    } else {
      constructor = descriptor[2];
      functionsIndex = 3;
    }

    for (var i = functionsIndex; i < descriptor.length; i += 2) {
      parseFunctionDescriptor(prototype, descriptor[i], descriptor[i + 1],
                              typesOffset);
    }

    constructor.$typeNameProperty = name;  // Needed for RTI.
    constructor.prototype = prototype;
    prototype[#operatorIsPrefix + name] = constructor;
    prototype.constructor = constructor;
    return constructor;
  }

  function fillPrototypeWithMixedIn(mixinName, mixinHolderIndex, prototype) {
    var mixin = holders[mixinHolderIndex][mixinName].ensureResolved();
    var mixinPrototype = mixin.prototype;

    // Fill the prototype with the mixin's properties.
    var mixinProperties = Object.keys(mixinPrototype);
    for (var i = 0; i < mixinProperties.length; i++) {
      var p = mixinProperties[i];
      prototype[p] = mixinPrototype[p];
    }
  }

  function determinePrototype(descriptor) {
    var superclassName = descriptor[0];
    if (!superclassName) return { };

    // Look up the superclass constructor function in the right holder.
    var holderIndex = descriptor[1];
    var superclass = holders[holderIndex][superclassName].ensureResolved();

    // Create a new prototype object chained to the superclass prototype.
    var intermediate = function() { };
    intermediate.prototype = superclass.prototype;
    return new intermediate();
  }

  function compile(__name__, __s__) {
    'use strict';
    // TODO(floitsch): evaluate the performance impact of the string
    // concatenations.
    return eval(__s__ + "\\n//# sourceURL=" + __name__ + ".js");
  }

  if (#outputContainsConstantList) {
    function makeConstList(list) {
      // By assigning a function to the properties they become part of the
      // hidden class. The actual values of the fields don't matter, since we
      // only check if they exist.
      list.immutable\$list = Array;
      list.fixed\$length = Array;
      return list;
    }
  }

  if (#needsNativeSupport) {
    function handleNativeClassInfos() {
      for (var nativeClass in nativeInfos) {
        var constructor = holdersMap[nativeClass][nativeClass].ensureResolved();
        var nativeInfo = nativeInfos[nativeClass];
        #nativeInfoHandler;
      }
    }
  }

  $setupProgramName(program, 0);

  // Initialize globals.
  #embeddedGlobals;

  function expressionCompile(__s__) {
    'use strict';
    return eval('(' + __s__ + ')');
  }

  #readMetadataTypeFunction;

  // TODO(floitsch): this order means that native classes may not be
  // referenced from constants. I'm mostly afraid of things like using them as
  // generic arguments (which should be fine, but maybe there are other
  // similar things).
  // Initialize natives.
  if (#needsNativeSupport) handleNativeClassInfos();

  // Initialize static non-final fields.
  #staticNonFinals;

  // Add native boilerplate code.
  #nativeIsolateAffinityTagInitialization;

  // Initialize eager classes.
  #eagerClasses;

  var end = Date.now();
  // print('Setup: ' + (end - start) + ' ms.');

  #invokeMain;  // Start main.

})(Date.now(), #code)
}""";

}
