Skip to content
This repository was archived by the owner on Jun 28, 2025. It is now read-only.

Commit 13c44eb

Browse files
committed
Update types to import trace-mapping's definitions
1 parent cd8b447 commit 13c44eb

File tree

6 files changed

+121
-142
lines changed

6 files changed

+121
-142
lines changed

src/remapping.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import SourceMap from './source-map';
55
import type { SourceMapInput, SourceMapLoader, Options } from './types';
66
export type {
77
SourceMapSegment,
8-
RawSourceMap,
8+
EncodedSourceMap,
9+
EncodedSourceMap as RawSourceMap,
910
DecodedSourceMap,
1011
SourceMapInput,
1112
SourceMapLoader,

src/source-map-tree.ts

Lines changed: 100 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,106 @@ type MappingSource = SourceMapSegmentObject | typeof INVALID_MAPPING | typeof SO
1515
* traceMappings is only called on the root level SourceMapTree, and begins the process of
1616
* resolving each mapping in terms of the original source files.
1717
*/
18-
export let traceMappings: (tree: SourceMapTree) => TraceMap;
18+
export function traceMappings(tree: SourceMapTree): TraceMap {
19+
const mappings: SourceMapSegment[][] = [];
20+
const names = new FastStringArray();
21+
const sources = new FastStringArray();
22+
const sourcesContent: (string | null)[] = [];
23+
const { sources: rootSources, map } = tree;
24+
const rootNames = map.names;
25+
const rootMappings = decodedMappings(map);
26+
27+
let lastLineWithSegment = -1;
28+
for (let i = 0; i < rootMappings.length; i++) {
29+
const segments = rootMappings[i];
30+
const tracedSegments: SourceMapSegment[] = [];
31+
32+
let lastSourcesIndex = -1;
33+
let lastSourceLine = -1;
34+
let lastSourceColumn = -1;
35+
36+
for (let j = 0; j < segments.length; j++) {
37+
const segment = segments[j];
38+
39+
let traced: MappingSource = SOURCELESS_MAPPING;
40+
// 1-length segments only move the current generated column, there's no source information
41+
// to gather from it.
42+
if (segment.length !== 1) {
43+
const source = rootSources[segment[1]];
44+
traced = source.originalPositionFor(
45+
segment[2],
46+
segment[3],
47+
segment.length === 5 ? rootNames[segment[4]] : ''
48+
);
49+
50+
// If the trace is invalid, then the trace ran into a sourcemap that doesn't contain a
51+
// respective segment into an original source.
52+
if (traced === INVALID_MAPPING) continue;
53+
}
54+
55+
const genCol = segment[0];
56+
if (traced === SOURCELESS_MAPPING) {
57+
if (lastSourcesIndex === -1) {
58+
// This is a consecutive source-less segment, which doesn't carry any new information.
59+
continue;
60+
}
61+
lastSourcesIndex = lastSourceLine = lastSourceColumn = -1;
62+
tracedSegments.push([genCol]);
63+
continue;
64+
}
65+
66+
// So we traced a segment down into its original source file. Now push a
67+
// new segment pointing to this location.
68+
const { column, line, name, content, source } = traced;
69+
70+
// Store the source location, and ensure we keep sourcesContent up to
71+
// date with the sources array.
72+
const sourcesIndex = put(sources, source);
73+
sourcesContent[sourcesIndex] = content;
74+
75+
if (
76+
lastSourcesIndex === sourcesIndex &&
77+
lastSourceLine === line &&
78+
lastSourceColumn === column
79+
) {
80+
// This is a duplicate mapping pointing at the exact same starting point in the source
81+
// file. It doesn't carry any new information, and only bloats the sourcemap.
82+
continue;
83+
}
84+
lastLineWithSegment = i;
85+
lastSourcesIndex = sourcesIndex;
86+
lastSourceLine = line;
87+
lastSourceColumn = column;
88+
89+
// This looks like unnecessary duplication, but it noticeably increases performance. If we
90+
// were to push the nameIndex onto length-4 array, v8 would internally allocate 22 slots!
91+
// That's 68 wasted bytes! Array literals have the same capacity as their length, saving
92+
// memory.
93+
tracedSegments.push(
94+
name
95+
? [genCol, sourcesIndex, line, column, put(names, name)]
96+
: [genCol, sourcesIndex, line, column]
97+
);
98+
}
99+
100+
mappings.push(tracedSegments);
101+
}
102+
103+
if (mappings.length > lastLineWithSegment + 1) {
104+
mappings.length = lastLineWithSegment + 1;
105+
}
106+
107+
return presortedDecodedMap(
108+
Object.assign({}, tree.map, {
109+
mappings,
110+
// TODO: Make all sources relative to the sourceRoot.
111+
sourceRoot: undefined,
112+
names: names.array,
113+
sources: sources.array,
114+
sourcesContent,
115+
})
116+
);
117+
}
19118

20119
/**
21120
* SourceMapTree represents a single sourcemap, with the ability to trace
@@ -30,109 +129,6 @@ export class SourceMapTree {
30129
this.sources = sources;
31130
}
32131

33-
static {
34-
traceMappings = (tree) => {
35-
const mappings: SourceMapSegment[][] = [];
36-
const names = new FastStringArray();
37-
const sources = new FastStringArray();
38-
const sourcesContent: (string | null)[] = [];
39-
const { sources: rootSources, map } = tree;
40-
const rootNames = map.names;
41-
const rootMappings = decodedMappings(map);
42-
43-
let lastLineWithSegment = -1;
44-
for (let i = 0; i < rootMappings.length; i++) {
45-
const segments = rootMappings[i];
46-
const tracedSegments: SourceMapSegment[] = [];
47-
48-
let lastSourcesIndex = -1;
49-
let lastSourceLine = -1;
50-
let lastSourceColumn = -1;
51-
52-
for (let j = 0; j < segments.length; j++) {
53-
const segment = segments[j];
54-
55-
let traced: MappingSource = SOURCELESS_MAPPING;
56-
// 1-length segments only move the current generated column, there's no source information
57-
// to gather from it.
58-
if (segment.length !== 1) {
59-
const source = rootSources[segment[1]];
60-
traced = source.originalPositionFor(
61-
segment[2],
62-
segment[3],
63-
segment.length === 5 ? rootNames[segment[4]] : ''
64-
);
65-
66-
// If the trace is invalid, then the trace ran into a sourcemap that doesn't contain a
67-
// respective segment into an original source.
68-
if (traced === INVALID_MAPPING) continue;
69-
}
70-
71-
const genCol = segment[0];
72-
if (traced === SOURCELESS_MAPPING) {
73-
if (lastSourcesIndex === -1) {
74-
// This is a consecutive source-less segment, which doesn't carry any new information.
75-
continue;
76-
}
77-
lastSourcesIndex = lastSourceLine = lastSourceColumn = -1;
78-
tracedSegments.push([genCol]);
79-
continue;
80-
}
81-
82-
// So we traced a segment down into its original source file. Now push a
83-
// new segment pointing to this location.
84-
const { column, line, name, content, source } = traced;
85-
86-
// Store the source location, and ensure we keep sourcesContent up to
87-
// date with the sources array.
88-
const sourcesIndex = put(sources, source);
89-
sourcesContent[sourcesIndex] = content;
90-
91-
if (
92-
lastSourcesIndex === sourcesIndex &&
93-
lastSourceLine === line &&
94-
lastSourceColumn === column
95-
) {
96-
// This is a duplicate mapping pointing at the exact same starting point in the source
97-
// file. It doesn't carry any new information, and only bloats the sourcemap.
98-
continue;
99-
}
100-
lastLineWithSegment = i;
101-
lastSourcesIndex = sourcesIndex;
102-
lastSourceLine = line;
103-
lastSourceColumn = column;
104-
105-
// This looks like unnecessary duplication, but it noticeably increases performance. If we
106-
// were to push the nameIndex onto length-4 array, v8 would internally allocate 22 slots!
107-
// That's 68 wasted bytes! Array literals have the same capacity as their length, saving
108-
// memory.
109-
tracedSegments.push(
110-
name
111-
? [genCol, sourcesIndex, line, column, put(names, name)]
112-
: [genCol, sourcesIndex, line, column]
113-
);
114-
}
115-
116-
mappings.push(tracedSegments);
117-
}
118-
119-
if (mappings.length > lastLineWithSegment + 1) {
120-
mappings.length = lastLineWithSegment + 1;
121-
}
122-
123-
return presortedDecodedMap(
124-
Object.assign({}, tree.map, {
125-
mappings,
126-
// TODO: Make all sources relative to the sourceRoot.
127-
sourceRoot: undefined,
128-
names: names.array,
129-
sources: sources.array,
130-
sourcesContent,
131-
})
132-
);
133-
};
134-
}
135-
136132
/**
137133
* originalPositionFor is only called on children SourceMapTrees. It recurses down
138134
* into its own child SourceMapTrees, until we find the original source map.

src/source-map.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { encodedMappings, decodedMappings } from '@jridgewell/trace-mapping';
22

33
import type { TraceMap } from '@jridgewell/trace-mapping';
4-
import type { DecodedSourceMap, RawSourceMap, Options } from './types';
4+
import type { DecodedSourceMap, EncodedSourceMap, Options } from './types';
55

66
/**
77
* A SourceMap v3 compatible sourcemap, which only includes fields that were
88
* provided to it.
99
*/
1010
export default class SourceMap {
1111
declare file?: string | null;
12-
declare mappings: RawSourceMap['mappings'] | DecodedSourceMap['mappings'];
12+
declare mappings: EncodedSourceMap['mappings'] | DecodedSourceMap['mappings'];
1313
declare sourceRoot?: string;
1414
declare names: string[];
1515
declare sources: (string | null)[];
@@ -19,7 +19,9 @@ export default class SourceMap {
1919
constructor(map: TraceMap, options: Options) {
2020
this.version = 3; // SourceMap spec says this should be first.
2121
this.file = map.file;
22-
this.mappings = options.decodedMappings ? decodedMappings(map) : encodedMappings(map);
22+
this.mappings = options.decodedMappings
23+
? (decodedMappings(map) as DecodedSourceMap['mappings'])
24+
: encodedMappings(map);
2325
this.names = map.names;
2426

2527
this.sourceRoot = map.sourceRoot;

src/types.ts

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,12 @@
1-
interface SourceMapV3 {
2-
file?: string | null;
3-
names: string[];
4-
sourceRoot?: string;
5-
sources: (string | null)[];
6-
sourcesContent?: (string | null)[];
7-
version: 3;
8-
}
9-
10-
type Column = number;
11-
type SourcesIndex = number;
12-
type SourceLine = number;
13-
type SourceColumn = number;
14-
type NamesIndex = number;
15-
16-
export type SourceMapSegment =
17-
| [Column]
18-
| [Column, SourcesIndex, SourceLine, SourceColumn]
19-
| [Column, SourcesIndex, SourceLine, SourceColumn, NamesIndex];
1+
import type { SourceMapInput } from '@jridgewell/trace-mapping';
202

21-
export interface RawSourceMap extends SourceMapV3 {
22-
mappings: string;
23-
}
3+
export type {
4+
SourceMapSegment,
5+
DecodedSourceMap,
6+
EncodedSourceMap,
7+
} from '@jridgewell/trace-mapping';
248

25-
export interface DecodedSourceMap extends SourceMapV3 {
26-
mappings: SourceMapSegment[][];
27-
}
9+
export type { SourceMapInput };
2810

2911
export interface SourceMapSegmentObject {
3012
column: number;
@@ -34,8 +16,6 @@ export interface SourceMapSegmentObject {
3416
content: string | null;
3517
}
3618

37-
export type SourceMapInput = string | RawSourceMap | DecodedSourceMap;
38-
3919
export type LoaderContext = {
4020
readonly importer: string;
4121
readonly depth: number;
@@ -46,7 +26,7 @@ export type LoaderContext = {
4626
export type SourceMapLoader = (
4727
file: string,
4828
ctx: LoaderContext
49-
) => SourceMapInput | null | undefined;
29+
) => SourceMapInput | null | undefined | void;
5030

5131
export type Options = {
5232
excludeContent?: boolean;

test/unit/build-source-map-tree.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import buildSourceMapTree from '../../src/build-source-map-tree';
2-
import type { DecodedSourceMap, RawSourceMap } from '../../src/types';
2+
import type { DecodedSourceMap, EncodedSourceMap } from '../../src/types';
33

44
describe('buildSourceMapTree', () => {
5-
const rawMap: RawSourceMap = {
5+
const rawMap: EncodedSourceMap = {
66
mappings: 'AAAA',
77
names: [],
88
sources: ['helloworld.js'],

test/unit/remapping.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import remapping from '../../src/remapping';
2-
import type { RawSourceMap } from '../../src/types';
2+
import type { EncodedSourceMap } from '../../src/types';
33

44
describe('remapping', () => {
5-
const rawMap: RawSourceMap = {
5+
const rawMap: EncodedSourceMap = {
66
file: 'transpiled.min.js',
77
// 0th column of 1st line of output file translates into the 1st source
88
// file, line 2, column 1, using 1st name.
@@ -12,7 +12,7 @@ describe('remapping', () => {
1212
sourcesContent: ['1+1'],
1313
version: 3,
1414
};
15-
const transpiledMap: RawSourceMap = {
15+
const transpiledMap: EncodedSourceMap = {
1616
// 1st column of 2nd line of output file translates into the 1st source
1717
// file, line 3, column 2
1818
mappings: ';CAEE',
@@ -21,7 +21,7 @@ describe('remapping', () => {
2121
sourcesContent: ['\n\n 1 + 1;'],
2222
version: 3,
2323
};
24-
const translatedMap: RawSourceMap = {
24+
const translatedMap: EncodedSourceMap = {
2525
file: 'transpiled.min.js',
2626
// 0th column of 1st line of output file translates into the 1st source
2727
// file, line 3, column 2, using first name

0 commit comments

Comments
 (0)