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

library dart2js.js_emitter.code_emitter_task;

import '../common.dart';
import '../common/metrics.dart' show Metric, Metrics, CountMetric;
import '../common/tasks.dart' show CompilerTask;
import '../compiler.dart' show Compiler;
import '../constants/values.dart';
import '../deferred_load.dart' show OutputUnit;
import '../elements/entities.dart';
import '../js/js.dart' as jsAst;
import '../js_backend/backend.dart' show CodegenInputs;
import '../js_backend/inferred_data.dart';
import '../js_backend/namer.dart' show Namer;
import '../js_backend/runtime_types.dart'
    show RuntimeTypesChecks;
import '../js_model/js_strategy.dart';
import '../options.dart';
import '../universe/codegen_world_builder.dart';
import '../world.dart' show JClosedWorld;
import 'program_builder/program_builder.dart';
import 'startup_emitter/emitter.dart' as startup_js_emitter;
import 'startup_emitter/fragment_merger.dart';

import 'metadata_collector.dart' show MetadataCollector;
import 'model.dart';
import 'native_emitter.dart' show NativeEmitter;

/// Generates the code for all used classes in the program. Static fields (even
/// in classes) are ignored, since they can be treated as non-class elements.
///
/// The code for the containing (used) methods must exist in the `universe`.
class CodeEmitterTask extends CompilerTask {
  RuntimeTypesChecks _rtiChecks;
  NativeEmitter _nativeEmitter;
  MetadataCollector metadataCollector;
  Emitter _emitter;
  final Compiler _compiler;
  final bool _generateSourceMap;

  JsBackendStrategy get _backendStrategy => _compiler.backendStrategy;

  CompilerOptions get options => _compiler.options;

  @deprecated
  // This field should be removed. It's currently only needed for dump-info and
  // tests.
  // The field is set after the program has been emitted.
  /// Contains a list of all classes that are emitted.
  Set<ClassEntity> neededClasses;

  @override
  final _EmitterMetrics metrics = _EmitterMetrics();

  CodeEmitterTask(this._compiler, this._generateSourceMap)
      : super(_compiler.measurer);

  NativeEmitter get nativeEmitter {
    assert(
        _nativeEmitter != null,
        failedAt(
            NO_LOCATION_SPANNABLE, "NativeEmitter has not been created yet."));
    return _nativeEmitter;
  }

  Emitter get emitter {
    assert(_emitter != null,
        failedAt(NO_LOCATION_SPANNABLE, "Emitter has not been created yet."));
    return _emitter;
  }

  @override
  String get name => 'Code emitter';

  void _finalizeRti(CodegenInputs codegen, CodegenWorld codegenWorld) {
    // Compute the required type checks to know which classes need a
    // 'is$' method.
    _rtiChecks = _backendStrategy.rtiChecksBuilder.computeRequiredChecks(codegenWorld, options);
  }

  /// Creates the [Emitter] for this task.
  void createEmitter(
      Namer namer, CodegenInputs codegen, JClosedWorld closedWorld) {
    measure(() {
      _nativeEmitter = new NativeEmitter(
          this, closedWorld, _backendStrategy.nativeCodegenEnqueuer);
      _emitter = new startup_js_emitter.EmitterImpl(
          _compiler.options,
          _compiler.reporter,
          _compiler.outputProvider,
          _compiler.dumpInfoTask,
          namer,
          closedWorld,
          codegen.rtiRecipeEncoder,
          _nativeEmitter,
          _backendStrategy.sourceInformationStrategy,
          this,
          _generateSourceMap);
      metadataCollector = new MetadataCollector(
          _compiler.reporter, _emitter, codegen.rtiRecipeEncoder);
    });
  }

  int assembleProgram(
      Namer namer,
      JClosedWorld closedWorld,
      InferredData inferredData,
      CodegenInputs codegenInputs,
      CodegenWorld codegenWorld) {
    return measure(() {
      measureSubtask('finalize rti', () {
        _finalizeRti(codegenInputs, codegenWorld);
      });
      ProgramBuilder programBuilder = ProgramBuilder(
          _compiler.options,
          closedWorld.elementEnvironment,
          closedWorld.commonElements,
          closedWorld.outputUnitData,
          codegenWorld,
          _backendStrategy.nativeCodegenEnqueuer,
          closedWorld.backendUsage,
          closedWorld.nativeData,
          closedWorld.rtiNeed,
          closedWorld.interceptorData,
          _rtiChecks,
          codegenInputs.rtiRecipeEncoder,
          codegenWorld.oneShotInterceptorData,
          _backendStrategy.customElementsCodegenAnalysis,
          _backendStrategy.generatedCode,
          namer,
          this,
          closedWorld,
          closedWorld.fieldAnalysis,
          inferredData,
          _backendStrategy.sourceInformationStrategy,
          closedWorld.sorter,
          _rtiChecks.requiredClasses,
          closedWorld.elementEnvironment.mainFunction);
      int size = emitter.emitProgram(programBuilder, codegenWorld);
      // TODO(floitsch): we shouldn't need the `neededClasses` anymore.
      neededClasses = programBuilder.collector.neededClasses;
      return size;
    });
  }
}

/// Interface for the subset of the [Emitter] that can be used during modular
/// code generation.
///
/// Note that the emission phase is not itself modular but performed on
/// the closed world computed by the codegen enqueuer.
abstract class ModularEmitter {
  /// Returns the JS prototype of the given class [e].
  jsAst.Expression prototypeAccess(ClassEntity e);

  /// Returns the JS function representing the given function.
  ///
  /// The function must be invoked and can not be used as closure.
  jsAst.Expression staticFunctionAccess(FunctionEntity element);

  jsAst.Expression staticFieldAccess(FieldEntity element);

  /// Returns the JS function that must be invoked to get the value of the
  /// lazily initialized static.
  jsAst.Expression isolateLazyInitializerAccess(covariant FieldEntity element);

  /// Returns the closure expression of a static function.
  jsAst.Expression staticClosureAccess(covariant FunctionEntity element);

  /// Returns the JS constructor of the given element.
  ///
  /// The returned expression must only be used in a JS `new` expression.
  jsAst.Expression constructorAccess(ClassEntity e);

  /// Returns the JS name representing the type [e].
  jsAst.Name typeAccessNewRti(ClassEntity e);

  /// Returns the JS name representing the type variable [e].
  jsAst.Name typeVariableAccessNewRti(TypeVariableEntity e);

  /// Returns the JS code for accessing the embedded [global].
  jsAst.Expression generateEmbeddedGlobalAccess(String global);

  /// Returns the JS code for accessing the given [constant].
  jsAst.Expression constantReference(ConstantValue constant);

  /// Returns the JS code for accessing the global property [global].
  String generateEmbeddedGlobalAccessString(String global);
}

/// Interface for the emitter that is used during the emission phase on the
/// closed world computed by the codegen enqueuer.
///
/// These methods are _not_ available during modular code generation.
abstract class Emitter implements ModularEmitter {
  Program get programForTesting;

  List<PreFragment> get preDeferredFragmentsForTesting;

  /// The set of omitted [OutputUnits].
  Set<OutputUnit> get omittedOutputUnits;

  /// A map of loadId to list of [FinalizedFragments].
  Map<String, List<FinalizedFragment>> get finalizedFragmentsToLoad;

  /// The [FragmentMerger] itself.
  FragmentMerger get fragmentMerger;

  /// Uses the [programBuilder] to generate a model of the program, emits
  /// the program, and returns the size of the generated output.
  int emitProgram(ProgramBuilder programBuilder, CodegenWorld codegenWorld);

  /// Returns the JS prototype of the given interceptor class [e].
  jsAst.Expression interceptorPrototypeAccess(ClassEntity e);

  /// Returns the JS constructor of the given interceptor class [e].
  jsAst.Expression interceptorClassAccess(ClassEntity e);

  /// Returns the JS expression representing a function that returns 'null'
  jsAst.Expression generateFunctionThatReturnsNull();

  int compareConstants(ConstantValue a, ConstantValue b);
  bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant);

  /// Returns the size of the code generated for a given output [unit].
  int generatedSize(OutputUnit unit);
}

class _EmitterMetrics implements Metrics {
  @override
  String get namespace => 'emitter';

  CountMetric hunkListElements = CountMetric('hunkListElements');

  @override
  Iterable<Metric> get primary => [];

  @override
  Iterable<Metric> get secondary => [hunkListElements];
}
