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

import '../compiler_new.dart' as api;
import 'common/backend_api.dart';
import 'common/tasks.dart';
import 'common.dart';
import 'common_elements.dart';
import 'compiler.dart' show Compiler;
import 'deferred_load.dart' show DeferredLoadTask;
import 'elements/entities.dart';
import 'elements/types.dart';
import 'enqueue.dart';
import 'environment.dart';
import 'js_backend/backend.dart';
import 'js_backend/backend_usage.dart';
import 'js_backend/interceptor_data.dart';
import 'js_backend/mirrors_analysis.dart';
import 'js_backend/mirrors_data.dart';
import 'js_backend/native_data.dart';
import 'js_backend/no_such_method_registry.dart';
import 'js_backend/runtime_types.dart';
import 'library_loader.dart';
import 'native/enqueue.dart' show NativeResolutionEnqueuer;
import 'native/resolver.dart';
import 'patch_parser.dart';
import 'resolved_uri_translator.dart';
import 'universe/class_hierarchy_builder.dart';
import 'universe/world_builder.dart';
import 'universe/world_impact.dart';

/// Strategy pattern that defines the connection between the input format and
/// the resolved element model.
abstract class FrontendStrategy {
  /// Creates library loader task for this strategy.
  LibraryLoaderTask createLibraryLoader(
      ResolvedUriTranslator uriTranslator,
      ScriptLoader scriptLoader,
      api.CompilerInput compilerInput,
      ElementScanner scriptScanner,
      PatchResolverFunction patchResolverFunc,
      PatchParserTask patchParser,
      Environment environment,
      DiagnosticReporter reporter,
      Measurer measurer);

  /// Returns the [ElementEnvironment] for the element model used in this
  /// strategy.
  ElementEnvironment get elementEnvironment;

  /// Returns the [CommonElements] for the element model used in this
  /// strategy.
  CommonElements get commonElements;

  /// Returns the [DartTypes] for the element model used in this strategy.
  DartTypes get dartTypes;

  /// Returns the [AnnotationProcessor] for this strategy.
  AnnotationProcessor get annotationProcesser;

  NativeBasicData get nativeBasicData;

  /// Creates a [DeferredLoadTask] for the element model used in this strategy.
  DeferredLoadTask createDeferredLoadTask(Compiler compiler);

  /// Creates the [NativeClassFinder] for this strategy.
  NativeClassFinder createNativeClassFinder(NativeBasicData nativeBasicData);

  /// Creates the [NoSuchMethodResolver] corresponding the resolved model of
  /// this strategy.
  NoSuchMethodResolver createNoSuchMethodResolver();

  /// Returns the [RuntimeTypesNeedBuilder] used by this frontend strategy.
  RuntimeTypesNeedBuilder get runtimeTypesNeedBuilderForTesting;

  /// Creates the [ResolutionWorldBuilder] corresponding to the element model
  /// used in this strategy.
  ResolutionWorldBuilder createResolutionWorldBuilder(
      NativeBasicData nativeBasicData,
      NativeDataBuilder nativeDataBuilder,
      InterceptorDataBuilder interceptorDataBuilder,
      BackendUsageBuilder backendUsageBuilder,
      RuntimeTypesNeedBuilder rtiNeedBuilder,
      NativeResolutionEnqueuer nativeResolutionEnqueuer,
      NoSuchMethodRegistry noSuchMethodRegistry,
      SelectorConstraintsStrategy selectorConstraintsStrategy,
      ClassHierarchyBuilder classHierarchyBuilder,
      ClassQueries classQueries);

  /// Creates the [WorkItemBuilder] corresponding to how a resolved model for
  /// a single member is obtained in this strategy.
  WorkItemBuilder createResolutionWorkItemBuilder(
      NativeBasicData nativeBasicData,
      NativeDataBuilder nativeDataBuilder,
      ImpactTransformer impactTransformer,
      Map<Entity, WorldImpact> impactCache);

  /// Computes the main function from [mainLibrary] adding additional world
  /// impact to [impactBuilder].
  FunctionEntity computeMain(
      LibraryEntity mainLibrary, WorldImpactBuilder impactBuilder);

  // TODO(johnniwinther): Reuse the following classes between strategies:

  /// Creates the [MirrorsDataBuilder] for this strategy.
  MirrorsDataBuilder createMirrorsDataBuilder();

  /// Creates the [MirrorsResolutionAnalysis] for this strategy.
  // TODO(johnniwinther): Avoid passing [JavaScriptBackend].
  MirrorsResolutionAnalysis createMirrorsResolutionAnalysis(
      JavaScriptBackend backend);

  /// Creates the [RuntimeTypesNeedBuilder] for this strategy.
  RuntimeTypesNeedBuilder createRuntimeTypesNeedBuilder();

  /// Creates the [ClassQueries] for this strategy.
  ClassQueries createClassQueries();

  /// Creates a [SourceSpan] from [spannable] in context of [currentElement].
  SourceSpan spanFromSpannable(Spannable spannable, Entity currentElement);
}

/// Class that performs the mechanics to investigate annotations in the code.
abstract class AnnotationProcessor {
  void extractNativeAnnotations(LibraryEntity library);

  void extractJsInteropAnnotations(LibraryEntity library);

  void processJsInteropAnnotations(
      NativeBasicData nativeBasicData, NativeDataBuilder nativeDataBuilder);
}

abstract class FrontendStrategyBase implements FrontendStrategy {
  final NativeBasicDataBuilderImpl nativeBasicDataBuilder =
      new NativeBasicDataBuilderImpl();
  NativeBasicData _nativeBasicData;

  NativeBasicData get nativeBasicData {
    if (_nativeBasicData == null) {
      _nativeBasicData = nativeBasicDataBuilder.close(elementEnvironment);
      assert(
          _nativeBasicData != null,
          failedAt(NO_LOCATION_SPANNABLE,
              "NativeBasicData has not been computed yet."));
    }
    return _nativeBasicData;
  }
}

/// Class that deletes the contents of an [WorldImpact] cache.
// TODO(redemption): this can be deleted when we sunset the old front end.
abstract class ImpactCacheDeleter {
  bool retainCachesForTesting;

  /// Removes the [WorldImpact] for [element] from the resolution cache. Later
  /// calls to [getWorldImpact] or [computeWorldImpact] returns an empty impact.
  void uncacheWorldImpact(Entity element);

  /// Removes the [WorldImpact]s for all [Element]s in the resolution cache. ,
  /// Later calls to [getWorldImpact] or [computeWorldImpact] returns an empty
  /// impact.
  void emptyCache();
}
