|
|
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 = 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; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function MapSource(map: TraceMap, sources: Sources[]): MapSource { |
|
|
return Source(map, sources, '', null, false); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function OriginalSource( |
|
|
source: string, |
|
|
content: string | null, |
|
|
ignore: boolean, |
|
|
): OriginalSource { |
|
|
return Source(null, EMPTY_SOURCES, source, content, ignore); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function traceMappings(tree: MapSource): GenMapping { |
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
|
|
|
|
if (segment.length !== 1) { |
|
|
const source = rootSources[segment[1]]; |
|
|
traced = originalPositionFor( |
|
|
source, |
|
|
segment[2], |
|
|
segment[3], |
|
|
segment.length === 5 ? rootNames[segment[4]] : '', |
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 (segment == null) return null; |
|
|
|
|
|
|
|
|
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, |
|
|
); |
|
|
} |
|
|
|