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

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 new 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) {}
}
