diff options
Diffstat (limited to 'node_modules/@jridgewell/remapping/src')
5 files changed, 368 insertions, 0 deletions
diff --git a/node_modules/@jridgewell/remapping/src/build-source-map-tree.ts b/node_modules/@jridgewell/remapping/src/build-source-map-tree.ts new file mode 100644 index 0000000..3e0262b --- /dev/null +++ b/node_modules/@jridgewell/remapping/src/build-source-map-tree.ts @@ -0,0 +1,89 @@ +import { TraceMap } from '@jridgewell/trace-mapping'; + +import { OriginalSource, MapSource } from './source-map-tree'; + +import type { Sources, MapSource as MapSourceType } from './source-map-tree'; +import type { SourceMapInput, SourceMapLoader, LoaderContext } from './types'; + +function asArray<T>(value: T | T[]): T[] { + 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. + */ +export default function buildSourceMapTree( + input: SourceMapInput | SourceMapInput[], + loader: SourceMapLoader, +): MapSourceType { + 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 = MapSource(maps[i], [tree]); + } + return tree; +} + +function build( + map: TraceMap, + loader: SourceMapLoader, + importer: string, + importerDepth: number, +): MapSourceType { + const { resolvedSources, sourcesContent, ignoreList } = map; + + const depth = importerDepth + 1; + const children = resolvedSources.map((sourceFile: string | null, i: number): Sources => { + // 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: LoaderContext = { + importer, + depth, + source: sourceFile || '', + content: undefined, + ignore: 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, ignore } = ctx; + + // If there is a sourcemap, then we need to recurse into it to load its source files. + if (sourceMap) return build(new TraceMap(sourceMap, source), loader, source, depth); + + // Else, it's an unmodified source file. + // 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; + const ignored = ignore !== undefined ? ignore : ignoreList ? ignoreList.includes(i) : false; + return OriginalSource(source, sourceContent, ignored); + }); + + return MapSource(map, children); +} diff --git a/node_modules/@jridgewell/remapping/src/remapping.ts b/node_modules/@jridgewell/remapping/src/remapping.ts new file mode 100644 index 0000000..c0f8b0d --- /dev/null +++ b/node_modules/@jridgewell/remapping/src/remapping.ts @@ -0,0 +1,42 @@ +import buildSourceMapTree from './build-source-map-tree'; +import { traceMappings } from './source-map-tree'; +import SourceMap from './source-map'; + +import type { SourceMapInput, SourceMapLoader, Options } from './types'; +export type { + SourceMapSegment, + EncodedSourceMap, + EncodedSourceMap as RawSourceMap, + DecodedSourceMap, + SourceMapInput, + SourceMapLoader, + LoaderContext, + Options, +} from './types'; +export type { SourceMap }; + +/** + * 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. + */ +export default function remapping( + input: SourceMapInput | SourceMapInput[], + loader: SourceMapLoader, + options?: boolean | Options, +): SourceMap { + const opts = + typeof options === 'object' ? options : { excludeContent: !!options, decodedMappings: false }; + const tree = buildSourceMapTree(input, loader); + return new SourceMap(traceMappings(tree), opts); +} diff --git a/node_modules/@jridgewell/remapping/src/source-map-tree.ts b/node_modules/@jridgewell/remapping/src/source-map-tree.ts new file mode 100644 index 0000000..935240f --- /dev/null +++ b/node_modules/@jridgewell/remapping/src/source-map-tree.ts @@ -0,0 +1,172 @@ +import { GenMapping, maybeAddSegment, setIgnore, setSourceContent } from '@jridgewell/gen-mapping'; +import { traceSegment, decodedMappings } from '@jridgewell/trace-mapping'; + +import type { TraceMap } from '@jridgewell/trace-mapping'; + +export type SourceMapSegmentObject = { + column: number; + line: number; + name: string; + source: string; + content: string | null; + ignore: boolean; +}; + +export type OriginalSource = { + map: null; + sources: Sources[]; + source: string; + content: string | null; + ignore: boolean; +}; + +export type MapSource = { + map: TraceMap; + sources: Sources[]; + source: string; + content: null; + ignore: false; +}; + +export type Sources = OriginalSource | MapSource; + +const SOURCELESS_MAPPING = /* #__PURE__ */ SegmentObject('', -1, -1, '', null, false); +const EMPTY_SOURCES: Sources[] = []; + +function SegmentObject( + source: string, + line: number, + column: number, + name: string, + content: string | null, + ignore: boolean, +): SourceMapSegmentObject { + return { source, line, column, name, content, ignore }; +} + +function Source( + map: TraceMap, + sources: Sources[], + source: '', + content: null, + ignore: false, +): MapSource; +function Source( + map: null, + sources: Sources[], + source: string, + content: string | null, + ignore: boolean, +): OriginalSource; +function Source( + map: TraceMap | null, + sources: Sources[], + source: string | '', + content: string | null, + ignore: boolean, +): Sources { + return { + map, + sources, + source, + content, + ignore, + } as any; +} + +/** + * MapSource represents a single sourcemap, with the ability to trace mappings into its child nodes + * (which may themselves be SourceMapTrees). + */ +export function MapSource(map: TraceMap, sources: Sources[]): MapSource { + return Source(map, sources, '', null, false); +} + +/** + * A "leaf" node in the sourcemap tree, representing an original, unmodified source file. Recursive + * segment tracing ends at the `OriginalSource`. + */ +export function OriginalSource( + source: string, + content: string | null, + ignore: boolean, +): OriginalSource { + return Source(null, EMPTY_SOURCES, source, content, ignore); +} + +/** + * traceMappings is only called on the root level SourceMapTree, and begins the process of + * resolving each mapping in terms of the original source files. + */ +export function traceMappings(tree: MapSource): GenMapping { + // TODO: Eventually support sourceRoot, which has to be removed because the sources are already + // fully resolved. We'll need to make sources relative to the sourceRoot before adding them. + const gen = new GenMapping({ file: tree.map.file }); + const { sources: rootSources, map } = tree; + const rootNames = map.names; + const rootMappings = decodedMappings(map); + + for (let i = 0; i < rootMappings.length; i++) { + const segments = rootMappings[i]; + + for (let j = 0; j < segments.length; j++) { + const segment = segments[j]; + const genCol = segment[0]; + let traced: SourceMapSegmentObject | null = 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 = originalPositionFor( + source, + 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 == null) continue; + } + + const { column, line, name, content, source, ignore } = traced; + + maybeAddSegment(gen, i, genCol, source, line, column, name); + if (source && content != null) setSourceContent(gen, source, content); + if (ignore) setIgnore(gen, source, true); + } + } + + return gen; +} + +/** + * originalPositionFor is only called on children SourceMapTrees. It recurses down into its own + * child SourceMapTrees, until we find the original source map. + */ +export function originalPositionFor( + source: Sources, + line: number, + column: number, + name: string, +): SourceMapSegmentObject | null { + if (!source.map) { + return SegmentObject(source.source, line, column, name, source.content, source.ignore); + } + + const segment = traceSegment(source.map, line, column); + + // If we couldn't find a segment, then this doesn't exist in the sourcemap. + if (segment == null) return null; + // 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; + + return originalPositionFor( + source.sources[segment[1]], + segment[2], + segment[3], + segment.length === 5 ? source.map.names[segment[4]] : name, + ); +} diff --git a/node_modules/@jridgewell/remapping/src/source-map.ts b/node_modules/@jridgewell/remapping/src/source-map.ts new file mode 100644 index 0000000..5156086 --- /dev/null +++ b/node_modules/@jridgewell/remapping/src/source-map.ts @@ -0,0 +1,38 @@ +import { toDecodedMap, toEncodedMap } from '@jridgewell/gen-mapping'; + +import type { GenMapping } from '@jridgewell/gen-mapping'; +import type { DecodedSourceMap, EncodedSourceMap, Options } from './types'; + +/** + * A SourceMap v3 compatible sourcemap, which only includes fields that were + * provided to it. + */ +export default class SourceMap { + declare file?: string | null; + declare mappings: EncodedSourceMap['mappings'] | DecodedSourceMap['mappings']; + declare sourceRoot?: string; + declare names: string[]; + declare sources: (string | null)[]; + declare sourcesContent?: (string | null)[]; + declare version: 3; + declare ignoreList: number[] | undefined; + + constructor(map: GenMapping, options: Options) { + const out = options.decodedMappings ? toDecodedMap(map) : toEncodedMap(map); + this.version = out.version; // SourceMap spec says this should be first. + this.file = out.file; + this.mappings = out.mappings as SourceMap['mappings']; + this.names = out.names as SourceMap['names']; + this.ignoreList = out.ignoreList as SourceMap['ignoreList']; + this.sourceRoot = out.sourceRoot; + + this.sources = out.sources as SourceMap['sources']; + if (!options.excludeContent) { + this.sourcesContent = out.sourcesContent as SourceMap['sourcesContent']; + } + } + + toString(): string { + return JSON.stringify(this); + } +} diff --git a/node_modules/@jridgewell/remapping/src/types.ts b/node_modules/@jridgewell/remapping/src/types.ts new file mode 100644 index 0000000..384961d --- /dev/null +++ b/node_modules/@jridgewell/remapping/src/types.ts @@ -0,0 +1,27 @@ +import type { SourceMapInput } from '@jridgewell/trace-mapping'; + +export type { + SourceMapSegment, + DecodedSourceMap, + EncodedSourceMap, +} from '@jridgewell/trace-mapping'; + +export type { SourceMapInput }; + +export type LoaderContext = { + readonly importer: string; + readonly depth: number; + source: string; + content: string | null | undefined; + ignore: boolean | undefined; +}; + +export type SourceMapLoader = ( + file: string, + ctx: LoaderContext, +) => SourceMapInput | null | undefined | void; + +export type Options = { + excludeContent?: boolean; + decodedMappings?: boolean; +}; |
