| // Copyright (c) 2013, 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. | |
| /// Contains a builder object useful for creating source maps programatically. | |
| library; | |
| // TODO(sigmund): add a builder for multi-section mappings. | |
| import 'dart:convert'; | |
| import 'package:source_span/source_span.dart'; | |
| import 'parser.dart'; | |
| import 'src/source_map_span.dart'; | |
| /// Builds a source map given a set of mappings. | |
| class SourceMapBuilder { | |
| final List<Entry> _entries = <Entry>[]; | |
| /// Adds an entry mapping the [targetOffset] to [source]. | |
| void addFromOffset(SourceLocation source, SourceFile targetFile, | |
| int targetOffset, String identifier) { | |
| ArgumentError.checkNotNull(targetFile, 'targetFile'); | |
| _entries.add(Entry(source, targetFile.location(targetOffset), identifier)); | |
| } | |
| /// Adds an entry mapping [target] to [source]. | |
| /// | |
| /// If [isIdentifier] is true or if [target] is a [SourceMapSpan] with | |
| /// `isIdentifier` set to true, this entry is considered to represent an | |
| /// identifier whose value will be stored in the source map. [isIdentifier] | |
| /// takes precedence over [target]'s `isIdentifier` value. | |
| void addSpan(SourceSpan source, SourceSpan target, {bool? isIdentifier}) { | |
| isIdentifier ??= source is SourceMapSpan ? source.isIdentifier : false; | |
| var name = isIdentifier ? source.text : null; | |
| _entries.add(Entry(source.start, target.start, name)); | |
| } | |
| /// Adds an entry mapping [target] to [source]. | |
| void addLocation( | |
| SourceLocation source, SourceLocation target, String? identifier) { | |
| _entries.add(Entry(source, target, identifier)); | |
| } | |
| /// Encodes all mappings added to this builder as a json map. | |
| Map<String, dynamic> build(String fileUrl) { | |
| return SingleMapping.fromEntries(_entries, fileUrl).toJson(); | |
| } | |
| /// Encodes all mappings added to this builder as a json string. | |
| String toJson(String fileUrl) => jsonEncode(build(fileUrl)); | |
| } | |
| /// An entry in the source map builder. | |
| class Entry implements Comparable<Entry> { | |
| /// Span denoting the original location in the input source file | |
| final SourceLocation source; | |
| /// Span indicating the corresponding location in the target file. | |
| final SourceLocation target; | |
| /// An identifier name, when this location is the start of an identifier. | |
| final String? identifierName; | |
| /// Creates a new [Entry] mapping [target] to [source]. | |
| Entry(this.source, this.target, this.identifierName); | |
| /// Implements [Comparable] to ensure that entries are ordered by their | |
| /// location in the target file. We sort primarily by the target offset | |
| /// because source map files are encoded by printing each mapping in order as | |
| /// they appear in the target file. | |
| @override | |
| int compareTo(Entry other) { | |
| var res = target.compareTo(other.target); | |
| if (res != 0) return res; | |
| res = source.sourceUrl | |
| .toString() | |
| .compareTo(other.source.sourceUrl.toString()); | |
| if (res != 0) return res; | |
| return source.compareTo(other.source); | |
| } | |
| } |