// Copyright (c) 2015, 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.

// @dart = 2.10

library js.source_mapping;

import '../io/code_output.dart'
    show BufferedCodeOutput, SourceLocations, SourceLocationsProvider;
import '../io/source_information.dart'
    show SourceLocation, SourceInformation, SourceInformationStrategy;
import 'js.dart';

/// [SourceInformationStrategy] that can associate source information with
/// JavaScript output.
class JavaScriptSourceInformationStrategy extends SourceInformationStrategy {
  const JavaScriptSourceInformationStrategy();

  /// Creates a processor that can associate source information on [Node] with
  /// code offsets in a [SourceMapper] provided by [sourceMapperProvider].
  /// Source information for each [Node] is provider by [reader].
  SourceInformationProcessor createProcessor(
      SourceMapperProvider sourceMapperProvider,
      SourceInformationReader reader) {
    return const SourceInformationProcessor();
  }
}

/// Interface for deriving [SourceInformation] from a [Node].
///
/// The base implementation read the value of the node itself.
class SourceInformationReader {
  const SourceInformationReader();

  SourceInformation getSourceInformation(Node node) => node.sourceInformation;
}

/// An observer of code positions of printed JavaScript [Node]s.
class CodePositionListener {
  const CodePositionListener();

  /// Called to associate [node] with the provided start position.
  ///
  /// The nodes are seen in pre-traversal order.
  void onStartPosition(Node node, int startPosition) {}

  /// Called to associate [node] with the provided start, end and closing
  /// positions.
  ///
  /// The nodes are seen in post-traversal order.
  void onPositions(
      Node node, int startPosition, int endPosition, int closingPosition) {}
}

/// Interface for creating [SourceMapper]s for multiple source information
/// engines.
abstract class SourceMapperProvider {
  SourceMapper createSourceMapper(String name);
}

/// Base implementation of [SourceMapperProvider].
class SourceMapperProviderImpl implements SourceMapperProvider {
  final SourceLocationsProvider provider;

  SourceMapperProviderImpl(this.provider);

  @override
  SourceMapper createSourceMapper(String name) {
    return SourceLocationsMapper(provider.createSourceLocations(name));
  }
}

/// An interface for mapping code offsets with [SourceLocation]s for JavaScript
/// [Node]s.
abstract class SourceMapper {
  /// Associate [codeOffset] with [sourceLocation] for [node].
  void register(Node node, int codeOffset, SourceLocation sourceLocation);

  /// Associate [codeOffset] with an inlining call at [sourceLocation].
  void registerPush(
      int codeOffset, SourceLocation sourceLocation, String inlinedMethodName);

  /// Associate [codeOffset] with an inlining return.
  ///
  /// If [isEmpty] is true, also associate that the inlining stack is empty at
  /// [codeOffset].
  void registerPop(int codeOffset, {bool isEmpty = false});
}

/// An implementation of [SourceMapper] that stores the information directly
/// into a [SourceLocations] object.
class SourceLocationsMapper implements SourceMapper {
  final SourceLocations sourceLocations;

  SourceLocationsMapper(this.sourceLocations);

  @override
  void register(Node node, int codeOffset, SourceLocation sourceLocation) {
    sourceLocations.addSourceLocation(codeOffset, sourceLocation);
  }

  @override
  void registerPush(
      int codeOffset, SourceLocation sourceLocation, String inlinedMethodName) {
    sourceLocations.addPush(codeOffset, sourceLocation, inlinedMethodName);
  }

  @override
  void registerPop(int codeOffset, {bool isEmpty = false}) {
    sourceLocations.addPop(codeOffset, isEmpty);
  }
}

/// A processor that associates [SourceInformation] with code position of
/// JavaScript [Node]s.
class SourceInformationProcessor extends CodePositionListener {
  const SourceInformationProcessor();

  /// Process the source information and code positions for the [node] and all
  /// its children.
  void process(Node node, BufferedCodeOutput code) {}
}
