// 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' show Node;

/// [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 as 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) {}
}
