diff options
Diffstat (limited to 'node_modules/@ampproject/remapping/dist/remapping.mjs')
-rw-r--r-- | node_modules/@ampproject/remapping/dist/remapping.mjs | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/node_modules/@ampproject/remapping/dist/remapping.mjs b/node_modules/@ampproject/remapping/dist/remapping.mjs new file mode 100644 index 0000000..4847e8a --- /dev/null +++ b/node_modules/@ampproject/remapping/dist/remapping.mjs @@ -0,0 +1,276 @@ +import { traceSegment, decodedMappings, presortedDecodedMap, TraceMap, encodedMappings } from '@jridgewell/trace-mapping'; + +/** + * A "leaf" node in the sourcemap tree, representing an original, unmodified + * source file. Recursive segment tracing ends at the `OriginalSource`. + */ +class OriginalSource { + constructor(source, content) { + this.source = source; + this.content = content; + } + /** + * Tracing a `SourceMapSegment` ends when we get to an `OriginalSource`, + * meaning this line/column location originated from this source file. + */ + originalPositionFor(line, column, name) { + return { column, line, name, source: this.source, content: this.content }; + } +} + +/** + * Puts `key` into the backing array, if it is not already present. Returns + * the index of the `key` in the backing array. + */ +let put; +/** + * FastStringArray acts like a `Set` (allowing only one occurrence of a string + * `key`), but provides the index of the `key` in the backing array. + * + * This is designed to allow synchronizing a second array with the contents of + * the backing array, like how `sourcesContent[i]` is the source content + * associated with `source[i]`, and there are never duplicates. + */ +class FastStringArray { + constructor() { + this.indexes = Object.create(null); + this.array = []; + } +} +(() => { + put = (strarr, key) => { + const { array, indexes } = strarr; + // The key may or may not be present. If it is present, it's a number. + let index = indexes[key]; + // If it's not yet present, we need to insert it and track the index in the + // indexes. + if (index === undefined) { + index = indexes[key] = array.length; + array.push(key); + } + return index; + }; +})(); + +const INVALID_MAPPING = undefined; +const SOURCELESS_MAPPING = null; +/** + * traceMappings is only called on the root level SourceMapTree, and begins the process of + * resolving each mapping in terms of the original source files. + */ +let traceMappings; +/** + * SourceMapTree represents a single sourcemap, with the ability to trace + * mappings into its child nodes (which may themselves be SourceMapTrees). + */ +class SourceMapTree { + constructor(map, sources) { + this.map = map; + this.sources = sources; + } + /** + * originalPositionFor is only called on children SourceMapTrees. It recurses down + * into its own child SourceMapTrees, until we find the original source map. + */ + originalPositionFor(line, column, name) { + const segment = traceSegment(this.map, line, column); + // If we couldn't find a segment, then this doesn't exist in the sourcemap. + if (segment == null) + return INVALID_MAPPING; + // 1-length segments only move the current generated column, there's no source information + // to gather from it. + if (segment.length === 1) + return SOURCELESS_MAPPING; + const source = this.sources[segment[1]]; + return source.originalPositionFor(segment[2], segment[3], segment.length === 5 ? this.map.names[segment[4]] : name); + } +} +(() => { + traceMappings = (tree) => { + const mappings = []; + const names = new FastStringArray(); + const sources = new FastStringArray(); + const sourcesContent = []; + const { sources: rootSources, map } = tree; + const rootNames = map.names; + const rootMappings = decodedMappings(map); + let lastLineWithSegment = -1; + for (let i = 0; i < rootMappings.length; i++) { + const segments = rootMappings[i]; + const tracedSegments = []; + let lastSourcesIndex = -1; + let lastSourceLine = -1; + let lastSourceColumn = -1; + for (let j = 0; j < segments.length; j++) { + const segment = segments[j]; + let traced = SOURCELESS_MAPPING; + // 1-length segments only move the current generated column, there's no source information + // to gather from it. + if (segment.length !== 1) { + const source = rootSources[segment[1]]; + traced = source.originalPositionFor(segment[2], segment[3], segment.length === 5 ? rootNames[segment[4]] : ''); + // If the trace is invalid, then the trace ran into a sourcemap that doesn't contain a + // respective segment into an original source. + if (traced === INVALID_MAPPING) + continue; + } + const genCol = segment[0]; + if (traced === SOURCELESS_MAPPING) { + if (lastSourcesIndex === -1) { + // This is a consecutive source-less segment, which doesn't carry any new information. + continue; + } + lastSourcesIndex = lastSourceLine = lastSourceColumn = -1; + tracedSegments.push([genCol]); + continue; + } + // So we traced a segment down into its original source file. Now push a + // new segment pointing to this location. + const { column, line, name, content, source } = traced; + // Store the source location, and ensure we keep sourcesContent up to + // date with the sources array. + const sourcesIndex = put(sources, source); + sourcesContent[sourcesIndex] = content; + if (lastSourcesIndex === sourcesIndex && + lastSourceLine === line && + lastSourceColumn === column) { + // This is a duplicate mapping pointing at the exact same starting point in the source + // file. It doesn't carry any new information, and only bloats the sourcemap. + continue; + } + lastLineWithSegment = i; + lastSourcesIndex = sourcesIndex; + lastSourceLine = line; + lastSourceColumn = column; + // This looks like unnecessary duplication, but it noticeably increases performance. If we + // were to push the nameIndex onto length-4 array, v8 would internally allocate 22 slots! + // That's 68 wasted bytes! Array literals have the same capacity as their length, saving + // memory. + tracedSegments.push(name + ? [genCol, sourcesIndex, line, column, put(names, name)] + : [genCol, sourcesIndex, line, column]); + } + mappings.push(tracedSegments); + } + if (mappings.length > lastLineWithSegment + 1) { + mappings.length = lastLineWithSegment + 1; + } + return presortedDecodedMap(Object.assign({}, tree.map, { + mappings, + // TODO: Make all sources relative to the sourceRoot. + sourceRoot: undefined, + names: names.array, + sources: sources.array, + sourcesContent, + })); + }; +})(); + +function asArray(value) { + if (Array.isArray(value)) + return value; + return [value]; +} +/** + * Recursively builds a tree structure out of sourcemap files, with each node + * being either an `OriginalSource` "leaf" or a `SourceMapTree` composed of + * `OriginalSource`s and `SourceMapTree`s. + * + * Every sourcemap is composed of a collection of source files and mappings + * into locations of those source files. When we generate a `SourceMapTree` for + * the sourcemap, we attempt to load each source file's own sourcemap. If it + * does not have an associated sourcemap, it is considered an original, + * unmodified source file. + */ +function buildSourceMapTree(input, loader) { + const maps = asArray(input).map((m) => new TraceMap(m, '')); + const map = maps.pop(); + for (let i = 0; i < maps.length; i++) { + if (maps[i].sources.length > 1) { + throw new Error(`Transformation map ${i} must have exactly one source file.\n` + + 'Did you specify these with the most recent transformation maps first?'); + } + } + let tree = build(map, loader, '', 0); + for (let i = maps.length - 1; i >= 0; i--) { + tree = new SourceMapTree(maps[i], [tree]); + } + return tree; +} +function build(map, loader, importer, importerDepth) { + const { resolvedSources, sourcesContent } = map; + const depth = importerDepth + 1; + const children = resolvedSources.map((sourceFile, i) => { + // The loading context gives the loader more information about why this file is being loaded + // (eg, from which importer). It also allows the loader to override the location of the loaded + // sourcemap/original source, or to override the content in the sourcesContent field if it's + // an unmodified source file. + const ctx = { + importer, + depth, + source: sourceFile || '', + content: undefined, + }; + // Use the provided loader callback to retrieve the file's sourcemap. + // TODO: We should eventually support async loading of sourcemap files. + const sourceMap = loader(ctx.source, ctx); + const { source, content } = ctx; + // If there is no sourcemap, then it is an unmodified source file. + if (!sourceMap) { + // The contents of this unmodified source file can be overridden via the loader context, + // allowing it to be explicitly null or a string. If it remains undefined, we fall back to + // the importing sourcemap's `sourcesContent` field. + const sourceContent = content !== undefined ? content : sourcesContent ? sourcesContent[i] : null; + return new OriginalSource(source, sourceContent); + } + // Else, it's a real sourcemap, and we need to recurse into it to load its + // source files. + return build(new TraceMap(sourceMap, source), loader, source, depth); + }); + return new SourceMapTree(map, children); +} + +/** + * A SourceMap v3 compatible sourcemap, which only includes fields that were + * provided to it. + */ +class SourceMap { + constructor(map, options) { + this.version = 3; // SourceMap spec says this should be first. + this.file = map.file; + this.mappings = options.decodedMappings ? decodedMappings(map) : encodedMappings(map); + this.names = map.names; + this.sourceRoot = map.sourceRoot; + this.sources = map.sources; + if (!options.excludeContent && 'sourcesContent' in map) { + this.sourcesContent = map.sourcesContent; + } + } + toString() { + return JSON.stringify(this); + } +} + +/** + * Traces through all the mappings in the root sourcemap, through the sources + * (and their sourcemaps), all the way back to the original source location. + * + * `loader` will be called every time we encounter a source file. If it returns + * a sourcemap, we will recurse into that sourcemap to continue the trace. If + * it returns a falsey value, that source file is treated as an original, + * unmodified source file. + * + * Pass `excludeContent` to exclude any self-containing source file content + * from the output sourcemap. + * + * Pass `decodedMappings` to receive a SourceMap with decoded (instead of + * VLQ encoded) mappings. + */ +function remapping(input, loader, options) { + const opts = typeof options === 'object' ? options : { excludeContent: !!options, decodedMappings: false }; + const tree = buildSourceMapTree(input, loader); + return new SourceMap(traceMappings(tree), opts); +} + +export { remapping as default }; +//# sourceMappingURL=remapping.mjs.map |