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