1- import { SetArray , put } from '@jridgewell/set-array ' ;
2- import { presortedDecodedMap , traceSegment , decodedMappings } from '@jridgewell/trace-mapping' ;
1+ import { GenMapping , addSegment , setSourceContent } from '@jridgewell/gen-mapping ' ;
2+ import { traceSegment , decodedMappings } from '@jridgewell/trace-mapping' ;
33
44import type { TraceMap } from '@jridgewell/trace-mapping' ;
5- import type { SourceMapSegment , SourceMapSegmentObject } from './types' ;
65
7- const INVALID_MAPPING = undefined ;
8- const SOURCELESS_MAPPING = null ;
6+ export type SourceMapSegmentObject =
7+ | {
8+ column : number ;
9+ line : number ;
10+ name : string ;
11+ source : string ;
12+ content : string | null ;
13+ }
14+ | {
15+ column : null ;
16+ line : null ;
17+ name : null ;
18+ source : null ;
19+ content : null ;
20+ } ;
21+
22+ const SOURCELESS_MAPPING = {
23+ source : null ,
24+ column : null ,
25+ line : null ,
26+ name : null ,
27+ content : null ,
28+ } ;
929const EMPTY_SOURCES : Sources [ ] = [ ] ;
1030
11- type MappingSource = SourceMapSegmentObject | typeof INVALID_MAPPING | typeof SOURCELESS_MAPPING ;
12-
13- type OriginalSource = {
31+ export type OriginalSource = {
1432 map : TraceMap ;
1533 sources : Sources [ ] ;
1634 source : string ;
1735 content : string | null ;
1836} ;
1937
20- type MapSource = {
38+ export type MapSource = {
2139 map : TraceMap ;
2240 sources : Sources [ ] ;
2341 source : string ;
@@ -60,28 +78,24 @@ export function OriginalSource(source: string, content: string | null): Original
6078 * traceMappings is only called on the root level SourceMapTree, and begins the process of
6179 * resolving each mapping in terms of the original source files.
6280 */
63- export function traceMappings ( tree : Sources ) : TraceMap {
64- const mappings : SourceMapSegment [ ] [ ] = [ ] ;
65- const names = new SetArray ( ) ;
66- const sources = new SetArray ( ) ;
67- const sourcesContent : ( string | null ) [ ] = [ ] ;
81+ export function traceMappings ( tree : MapSource ) : GenMapping {
82+ const gen = new GenMapping ( { file : tree . map . file } ) ;
6883 const { sources : rootSources , map } = tree ;
6984 const rootNames = map . names ;
7085 const rootMappings = decodedMappings ( map ) ;
7186
72- let lastLineWithSegment = - 1 ;
7387 for ( let i = 0 ; i < rootMappings . length ; i ++ ) {
7488 const segments = rootMappings [ i ] ;
75- const tracedSegments : SourceMapSegment [ ] = [ ] ;
7689
77- let lastSourcesIndex = - 1 ;
78- let lastSourceLine = - 1 ;
79- let lastSourceColumn = - 1 ;
90+ let lastSource = null ;
91+ let lastSourceLine = null ;
92+ let lastSourceColumn = null ;
8093
8194 for ( let j = 0 ; j < segments . length ; j ++ ) {
8295 const segment = segments [ j ] ;
96+ const genCol = segment [ 0 ] ;
97+ let traced : SourceMapSegmentObject | null = SOURCELESS_MAPPING ;
8398
84- let traced : MappingSource = SOURCELESS_MAPPING ;
8599 // 1-length segments only move the current generated column, there's no source information
86100 // to gather from it.
87101 if ( segment . length !== 1 ) {
@@ -95,71 +109,26 @@ export function traceMappings(tree: Sources): TraceMap {
95109
96110 // If the trace is invalid, then the trace ran into a sourcemap that doesn't contain a
97111 // respective segment into an original source.
98- if ( traced === INVALID_MAPPING ) continue ;
99- }
100-
101- const genCol = segment [ 0 ] ;
102- if ( traced === SOURCELESS_MAPPING ) {
103- if ( lastSourcesIndex === - 1 ) {
104- // This is a consecutive source-less segment, which doesn't carry any new information.
105- continue ;
106- }
107- lastSourcesIndex = lastSourceLine = lastSourceColumn = - 1 ;
108- tracedSegments . push ( [ genCol ] ) ;
109- continue ;
112+ if ( traced == null ) continue ;
110113 }
111114
112115 // So we traced a segment down into its original source file. Now push a
113116 // new segment pointing to this location.
114117 const { column, line, name, content, source } = traced ;
115-
116- // Store the source location, and ensure we keep sourcesContent up to
117- // date with the sources array.
118- const sourcesIndex = put ( sources , source ) ;
119- sourcesContent [ sourcesIndex ] = content ;
120-
121- if (
122- lastSourcesIndex === sourcesIndex &&
123- lastSourceLine === line &&
124- lastSourceColumn === column
125- ) {
126- // This is a duplicate mapping pointing at the exact same starting point in the source
127- // file. It doesn't carry any new information, and only bloats the sourcemap.
118+ if ( line === lastSourceLine && column === lastSourceColumn && source === lastSource ) {
128119 continue ;
129120 }
130- lastLineWithSegment = i ;
131- lastSourcesIndex = sourcesIndex ;
132121 lastSourceLine = line ;
133122 lastSourceColumn = column ;
123+ lastSource = source ;
134124
135- // This looks like unnecessary duplication, but it noticeably increases performance. If we
136- // were to push the nameIndex onto length-4 array, v8 would internally allocate 22 slots!
137- // That's 68 wasted bytes! Array literals have the same capacity as their length, saving
138- // memory.
139- tracedSegments . push (
140- name
141- ? [ genCol , sourcesIndex , line , column , put ( names , name ) ]
142- : [ genCol , sourcesIndex , line , column ]
143- ) ;
125+ // Sigh, TypeScript can't figure out source/line/column are either all null, or all non-null...
126+ ( addSegment as any ) ( gen , i , genCol , source , line , column , name ) ;
127+ if ( content != null ) setSourceContent ( gen , source , content ) ;
144128 }
145-
146- mappings . push ( tracedSegments ) ;
147129 }
148130
149- if ( mappings . length > lastLineWithSegment + 1 ) {
150- mappings . length = lastLineWithSegment + 1 ;
151- }
152-
153- return presortedDecodedMap (
154- Object . assign ( { } , tree . map , {
155- mappings,
156- // TODO: Make all sources relative to the sourceRoot.
157- sourceRoot : undefined ,
158- names : names . array ,
159- sources : sources . array ,
160- sourcesContent,
161- } )
162- ) ;
131+ return gen ;
163132}
164133
165134/**
@@ -171,15 +140,15 @@ export function originalPositionFor(
171140 line : number ,
172141 column : number ,
173142 name : string
174- ) : MappingSource {
143+ ) : SourceMapSegmentObject | null {
175144 if ( ! source . map ) {
176145 return { column, line, name, source : source . source , content : source . content } ;
177146 }
178147
179148 const segment = traceSegment ( source . map , line , column ) ;
180149
181150 // If we couldn't find a segment, then this doesn't exist in the sourcemap.
182- if ( segment == null ) return INVALID_MAPPING ;
151+ if ( segment == null ) return null ;
183152 // 1-length segments only move the current generated column, there's no source information
184153 // to gather from it.
185154 if ( segment . length === 1 ) return SOURCELESS_MAPPING ;
0 commit comments