b488bd1a75
This migrates js/js.dart which will unblock the {ConstantValue,OutputUnit} cycle.
Change-Id: I6d49c2c588ac3a58e7698228e1b276d4cfb931d0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/243531
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
123 lines
4.2 KiB
Dart
123 lines
4.2 KiB
Dart
// 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) {}
|
|
}
|