// Copyright (c) 2017, 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_backend.element_strategy;

import '../backend_strategy.dart';
import '../closure.dart' show ClosureConversionTask, ClosureTask;
import '../common.dart';
import '../common/codegen.dart';
import '../common/tasks.dart';
import '../common/work.dart';
import '../compiler.dart';
import '../elements/elements.dart';
import '../enqueue.dart';
import '../inferrer/type_graph_inferrer.dart' show AstTypeGraphInferrer;
import '../io/multi_information.dart' show MultiSourceInformationStrategy;
import '../io/position_information.dart' show PositionSourceInformationStrategy;
import '../io/source_information.dart';
import '../io/start_end_information.dart'
    show StartEndSourceInformationStrategy;
import '../js/js_source_mapping.dart' show JavaScriptSourceInformationStrategy;
import '../js_backend/backend.dart';
import '../js_backend/native_data.dart';
import '../js_emitter/sorter.dart';
import '../resolution/resolution_strategy.dart';
import '../ssa/builder.dart';
import '../ssa/rasta_ssa_builder_task.dart';
import '../ssa/ssa.dart';
import '../types/types.dart';
import '../options.dart';
import '../universe/world_builder.dart';
import '../universe/world_impact.dart';
import '../world.dart';

/// Strategy for using the [Element] model from the resolver as the backend
/// model.
class ElementBackendStrategy extends ComputeSpannableMixin
    implements BackendStrategy {
  final Compiler _compiler;
  final ClosureConversionTask closureDataLookup;
  SourceInformationStrategy _sourceInformationStrategy;

  ElementBackendStrategy(this._compiler)
      : closureDataLookup = new ClosureTask(_compiler);

  ClosedWorldRefiner createClosedWorldRefiner(
          covariant ClosedWorldImpl closedWorld) =>
      closedWorld;

  Sorter get sorter => const ElementSorter();

  @override
  CodegenWorldBuilder createCodegenWorldBuilder(
      NativeBasicData nativeBasicData,
      ClosedWorld closedWorld,
      SelectorConstraintsStrategy selectorConstraintsStrategy) {
    return new ElementCodegenWorldBuilderImpl(
        _compiler.backend.constants,
        closedWorld.elementEnvironment,
        nativeBasicData,
        closedWorld,
        selectorConstraintsStrategy);
  }

  @override
  WorkItemBuilder createCodegenWorkItemBuilder(ClosedWorld closedWorld) {
    return new ElementCodegenWorkItemBuilder(
        _compiler.backend, closedWorld, _compiler.options);
  }

  @override
  SsaBuilder createSsaBuilder(CompilerTask task, JavaScriptBackend backend,
      SourceInformationStrategy sourceInformationStrategy) {
    return _compiler.options.useKernelInSsa
        ? new RastaSsaBuilder(task, backend, sourceInformationStrategy)
        : new SsaAstBuilder(task, backend, sourceInformationStrategy);
  }

  SourceInformationStrategy get sourceInformationStrategy {
    return _sourceInformationStrategy ??= createSourceInformationStrategy(
        generateSourceMap: _compiler.options.generateSourceMap,
        useMultiSourceInfo: _compiler.options.useMultiSourceInfo,
        useNewSourceInfo: _compiler.options.useNewSourceInfo);
  }

  static SourceInformationStrategy createSourceInformationStrategy(
      {bool generateSourceMap: false,
      bool useMultiSourceInfo: false,
      bool useNewSourceInfo: false}) {
    if (!generateSourceMap) return const JavaScriptSourceInformationStrategy();
    if (useMultiSourceInfo) {
      if (useNewSourceInfo) {
        return const MultiSourceInformationStrategy(const [
          const PositionSourceInformationStrategy(),
          const StartEndSourceInformationStrategy()
        ]);
      } else {
        return const MultiSourceInformationStrategy(const [
          const StartEndSourceInformationStrategy(),
          const PositionSourceInformationStrategy()
        ]);
      }
    } else if (useNewSourceInfo) {
      return const PositionSourceInformationStrategy();
    } else {
      return const StartEndSourceInformationStrategy();
    }
  }

  @override
  TypesInferrer createTypesInferrer(ClosedWorldRefiner closedWorldRefiner,
      {bool disableTypeInference: false}) {
    return new AstTypeGraphInferrer(
        _compiler, closedWorldRefiner.closedWorld, closedWorldRefiner,
        disableTypeInference: disableTypeInference);
  }
}

/// Builder that creates the work item necessary for the code generation of a
/// [MemberElement].
class ElementCodegenWorkItemBuilder extends WorkItemBuilder {
  final JavaScriptBackend _backend;
  final ClosedWorld _closedWorld;
  final CompilerOptions _options;

  ElementCodegenWorkItemBuilder(
      this._backend, this._closedWorld, this._options);

  @override
  WorkItem createWorkItem(MemberElement element) {
    assert(element.isDeclaration, failedAt(element));
    // Don't generate code for foreign elements.
    if (_backend.isForeign(_closedWorld.commonElements, element)) return null;
    if (element.isAbstract) return null;

    // Codegen inlines field initializers. It only needs to generate
    // code for checked setters.
    if (element.isField && element.isInstanceMember) {
      if (!_options.enableTypeAssertions ||
          element.enclosingElement.isClosure) {
        return null;
      }
    }
    return new ElementCodegenWorkItem(_backend, _closedWorld, element);
  }
}

class ElementCodegenWorkItem extends CodegenWorkItem {
  CodegenRegistry registry;
  final ResolvedAst resolvedAst;
  final JavaScriptBackend _backend;
  final ClosedWorld _closedWorld;

  factory ElementCodegenWorkItem(JavaScriptBackend backend,
      ClosedWorld closedWorld, MemberElement element) {
    // If this assertion fails, the resolution callbacks of the backend may be
    // missing call of form registry.registerXXX. Alternatively, the code
    // generation could spuriously be adding dependencies on things we know we
    // don't need.
    assert(element.hasResolvedAst,
        failedAt(element, "$element has no resolved ast."));
    ResolvedAst resolvedAst = element.resolvedAst;
    return new ElementCodegenWorkItem.internal(
        resolvedAst, backend, closedWorld);
  }

  ElementCodegenWorkItem.internal(
      this.resolvedAst, this._backend, this._closedWorld);

  MemberElement get element => resolvedAst.element;

  WorldImpact run() {
    registry = new CodegenRegistry(_closedWorld.elementEnvironment, element);
    return _backend.codegen(this, _closedWorld);
  }

  String toString() => 'CodegenWorkItem(${resolvedAst.element})';
}
