@volar/source-map 1.11.1 → 2.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # @volar/source-map
2
+
3
+ Provides functionality related to source maps.
4
+
5
+ ## API
6
+
7
+ This package exports a `SourceMap` class with the following methods:
8
+
9
+ - `getSourceOffset(generatedOffset: number)`: Returns the source offset for a given generated offset.
10
+
11
+ - `getGeneratedOffset(sourceOffset: number)`: Returns the generated offset for a given source offset.
12
+
13
+ - `getSourceOffsets(generatedOffset: number)`: Returns all source offsets for a given generated offset.
14
+
15
+ - `getGeneratedOffsets(sourceOffset: number)`: Returns all generated offsets for a given source offset.
16
+
17
+ ## Data Structures
18
+
19
+ ### `Mapping`
20
+
21
+ The `Mapping` is a tuple that represents a mapping in the source map. It consists of the following elements:
22
+
23
+ - `source`: A string representing the source file. This can be `undefined`.
24
+ - `sourceOffsets`: Offsets in the source code.
25
+ - `generatedOffsets`: Offsets in the generated code.
26
+ - `data`: The data associated with this mapping. The type of this data is generic and can be specified when creating a `SourceMap` instance.
27
+
28
+ Here is an example of a `Mapping`:
29
+
30
+ ```ts
31
+ let mapping: Mapping<MyDataType> = {
32
+ source: '.../sourceFile.ts',
33
+ sourceOffsets: [10],
34
+ generatedOffsets: [30],
35
+ lengths: [10],
36
+ data: myData,
37
+ };
38
+ ```
39
+
40
+ In this example, `myData` is of type `MyDataType`, which is the type specified for the SourceMap instance.
41
+
42
+ Remember to replace `MyDataType` and `myData` with actual types and data that are relevant to your project.
43
+
44
+ ## License
45
+
46
+ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.
package/index.d.ts CHANGED
@@ -1,28 +1,5 @@
1
- import { Segment, StackNode } from 'muggle-string';
2
1
  export * from 'muggle-string';
3
- export interface Mapping<T = any> {
4
- source?: string;
5
- sourceRange: [number, number];
6
- generatedRange: [number, number];
7
- data: T;
8
- }
9
- export interface Stack {
10
- source: string;
11
- range: [number, number];
12
- }
13
- export declare class SourceMap<Data = any> {
14
- readonly mappings: Mapping<Data>[];
15
- private _memo;
16
- private get memo();
17
- constructor(mappings: Mapping<Data>[]);
18
- toSourceOffset(start: number, baseOnRight?: boolean): readonly [number, Mapping<Data>] | undefined;
19
- toGeneratedOffset(start: number, baseOnRight?: boolean): readonly [number, Mapping<Data>] | undefined;
20
- toSourceOffsets(start: number, baseOnRight?: boolean): Generator<readonly [number, Mapping<Data>], void, unknown>;
21
- toGeneratedOffsets(start: number, baseOnRight?: boolean): Generator<readonly [number, Mapping<Data>], void, unknown>;
22
- matching(startOffset: number, from: 'sourceRange' | 'generatedRange', to: 'sourceRange' | 'generatedRange', baseOnRight: boolean): Generator<readonly [number, Mapping<Data>], void, unknown>;
23
- matchOffset(start: number, mappedFromRange: [number, number], mappedToRange: [number, number], baseOnRight: boolean): number | undefined;
24
- private binarySearchMemo;
25
- }
26
- export declare function buildMappings<T>(chunks: Segment<T>[]): Mapping<T>[];
27
- export declare function buildStacks<T>(chunks: Segment<T>[], stacks: StackNode[]): Stack[];
28
- //# sourceMappingURL=index.d.ts.map
2
+ export * from './lib/sourceMap';
3
+ export * from './lib/translateOffset';
4
+ export * from './lib/buildMappings';
5
+ export * from './lib/buildStacks';
package/index.js CHANGED
@@ -14,169 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.buildStacks = exports.buildMappings = exports.SourceMap = void 0;
18
17
  __exportStar(require("muggle-string"), exports);
19
- class SourceMap {
20
- get memo() {
21
- if (!this._memo) {
22
- const self = this;
23
- this._memo = {
24
- sourceRange: createMemo('sourceRange'),
25
- generatedRange: createMemo('generatedRange'),
26
- };
27
- function createMemo(key) {
28
- const offsets = new Set();
29
- for (const mapping of self.mappings) {
30
- offsets.add(mapping[key][0]);
31
- offsets.add(mapping[key][1]);
32
- }
33
- const arr = [...offsets].sort((a, b) => a - b).map(offset => ({ offset, mappings: new Set() }));
34
- for (const mapping of self.mappings) {
35
- const startIndex = binarySearch(mapping[key][0]);
36
- const endIndex = binarySearch(mapping[key][1]);
37
- for (let i = startIndex; i <= endIndex; i++) {
38
- arr[i].mappings.add(mapping);
39
- }
40
- }
41
- return arr;
42
- function binarySearch(start) {
43
- let low = 0;
44
- let high = arr.length - 1;
45
- while (low <= high) {
46
- const mid = Math.floor((low + high) / 2);
47
- const midValue = arr[mid];
48
- if (midValue.offset < start) {
49
- low = mid + 1;
50
- }
51
- else if (midValue.offset > start) {
52
- high = mid - 1;
53
- }
54
- else {
55
- return mid;
56
- }
57
- }
58
- }
59
- }
60
- }
61
- return this._memo;
62
- }
63
- constructor(mappings) {
64
- this.mappings = mappings;
65
- }
66
- toSourceOffset(start, baseOnRight = false) {
67
- for (const mapped of this.matching(start, 'generatedRange', 'sourceRange', baseOnRight)) {
68
- return mapped;
69
- }
70
- }
71
- toGeneratedOffset(start, baseOnRight = false) {
72
- for (const mapped of this.matching(start, 'sourceRange', 'generatedRange', baseOnRight)) {
73
- return mapped;
74
- }
75
- }
76
- toSourceOffsets(start, baseOnRight = false) {
77
- return this.matching(start, 'generatedRange', 'sourceRange', baseOnRight);
78
- }
79
- toGeneratedOffsets(start, baseOnRight = false) {
80
- return this.matching(start, 'sourceRange', 'generatedRange', baseOnRight);
81
- }
82
- *matching(startOffset, from, to, baseOnRight) {
83
- const memo = this.memo[from];
84
- if (memo.length === 0)
85
- return;
86
- const { low: start, high: end, } = this.binarySearchMemo(memo, startOffset);
87
- const skip = new Set();
88
- for (let i = start; i <= end; i++) {
89
- for (const mapping of memo[i].mappings) {
90
- if (skip.has(mapping)) {
91
- continue;
92
- }
93
- skip.add(mapping);
94
- const mapped = this.matchOffset(startOffset, mapping[from], mapping[to], baseOnRight);
95
- if (mapped !== undefined) {
96
- yield [mapped, mapping];
97
- }
98
- }
99
- }
100
- }
101
- matchOffset(start, mappedFromRange, mappedToRange, baseOnRight) {
102
- if (start >= mappedFromRange[0] && start <= mappedFromRange[1]) {
103
- let offset = mappedToRange[0] + start - mappedFromRange[0];
104
- if (baseOnRight) {
105
- offset += (mappedToRange[1] - mappedToRange[0]) - (mappedFromRange[1] - mappedFromRange[0]);
106
- }
107
- if (offset >= mappedToRange[0] && offset <= mappedToRange[1]) {
108
- return offset;
109
- }
110
- }
111
- }
112
- binarySearchMemo(array, start) {
113
- let low = 0;
114
- let high = array.length - 1;
115
- while (low <= high) {
116
- const mid = Math.floor((low + high) / 2);
117
- const midValue = array[mid];
118
- if (midValue.offset < start) {
119
- low = mid + 1;
120
- }
121
- else if (midValue.offset > start) {
122
- high = mid - 1;
123
- }
124
- else {
125
- low = mid;
126
- high = mid;
127
- break;
128
- }
129
- }
130
- return {
131
- low: Math.max(Math.min(low, high, array.length - 1), 0),
132
- high: Math.min(Math.max(low, high, 0), array.length - 1),
133
- };
134
- }
135
- }
136
- exports.SourceMap = SourceMap;
137
- function buildMappings(chunks) {
138
- let length = 0;
139
- const mappings = [];
140
- for (const segment of chunks) {
141
- if (typeof segment === 'string') {
142
- length += segment.length;
143
- }
144
- else {
145
- mappings.push({
146
- generatedRange: [length, length + segment[0].length],
147
- source: segment[1],
148
- sourceRange: typeof segment[2] === 'number' ? [segment[2], segment[2] + segment[0].length] : segment[2],
149
- // @ts-ignore
150
- data: segment[3],
151
- });
152
- length += segment[0].length;
153
- }
154
- }
155
- return mappings;
156
- }
157
- exports.buildMappings = buildMappings;
158
- function buildStacks(chunks, stacks) {
159
- let offset = 0;
160
- let index = 0;
161
- const result = [];
162
- for (const stack of stacks) {
163
- const start = offset;
164
- for (let i = 0; i < stack.length; i++) {
165
- const segment = chunks[index + i];
166
- if (typeof segment === 'string') {
167
- offset += segment.length;
168
- }
169
- else {
170
- offset += segment[0].length;
171
- }
172
- }
173
- index += stack.length;
174
- result.push({
175
- range: [start, offset],
176
- source: stack.stack,
177
- });
178
- }
179
- return result;
180
- }
181
- exports.buildStacks = buildStacks;
18
+ __exportStar(require("./lib/sourceMap"), exports);
19
+ __exportStar(require("./lib/translateOffset"), exports);
20
+ __exportStar(require("./lib/buildMappings"), exports);
21
+ __exportStar(require("./lib/buildStacks"), exports);
182
22
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,5 @@
1
+ export declare function binarySearch(values: number[], searchValue: number): {
2
+ low: number;
3
+ high: number;
4
+ match: number | undefined;
5
+ };
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.binarySearch = void 0;
4
+ function binarySearch(values, searchValue) {
5
+ let low = 0;
6
+ let high = values.length - 1;
7
+ let match;
8
+ while (low <= high) {
9
+ const mid = Math.floor((low + high) / 2);
10
+ const midValue = values[mid];
11
+ if (midValue < searchValue) {
12
+ low = mid + 1;
13
+ }
14
+ else if (midValue > searchValue) {
15
+ high = mid - 1;
16
+ }
17
+ else {
18
+ low = mid;
19
+ high = mid;
20
+ match = mid;
21
+ break;
22
+ }
23
+ }
24
+ const finalLow = Math.max(Math.min(low, high, values.length - 1), 0);
25
+ const finalHigh = Math.min(Math.max(low, high, 0), values.length - 1);
26
+ return { low: finalLow, high: finalHigh, match };
27
+ }
28
+ exports.binarySearch = binarySearch;
29
+ //# sourceMappingURL=binarySearch.js.map
@@ -0,0 +1,3 @@
1
+ import type { Segment } from 'muggle-string';
2
+ import type { Mapping } from './sourceMap';
3
+ export declare function buildMappings<T>(chunks: Segment<T>[]): Mapping<T>[];
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildMappings = void 0;
4
+ function buildMappings(chunks) {
5
+ let length = 0;
6
+ const mappings = [];
7
+ for (const segment of chunks) {
8
+ if (typeof segment === 'string') {
9
+ length += segment.length;
10
+ }
11
+ else {
12
+ mappings.push({
13
+ source: segment[1],
14
+ sourceOffsets: [segment[2]],
15
+ generatedOffsets: [length],
16
+ lengths: [segment[0].length],
17
+ data: segment[3],
18
+ });
19
+ length += segment[0].length;
20
+ }
21
+ }
22
+ return mappings;
23
+ }
24
+ exports.buildMappings = buildMappings;
25
+ //# sourceMappingURL=buildMappings.js.map
@@ -0,0 +1,6 @@
1
+ import type { Segment, StackNode } from 'muggle-string';
2
+ export interface Stack {
3
+ source: string;
4
+ range: [number, number];
5
+ }
6
+ export declare function buildStacks<T>(chunks: Segment<T>[], stacks: StackNode[]): Stack[];
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildStacks = void 0;
4
+ function buildStacks(chunks, stacks) {
5
+ let offset = 0;
6
+ let index = 0;
7
+ const result = [];
8
+ for (const stack of stacks) {
9
+ const start = offset;
10
+ for (let i = 0; i < stack.length; i++) {
11
+ const segment = chunks[index + i];
12
+ if (typeof segment === 'string') {
13
+ offset += segment.length;
14
+ }
15
+ else {
16
+ offset += segment[0].length;
17
+ }
18
+ }
19
+ index += stack.length;
20
+ result.push({
21
+ source: stack.stack,
22
+ range: [start, offset],
23
+ });
24
+ }
25
+ return result;
26
+ }
27
+ exports.buildStacks = buildStacks;
28
+ //# sourceMappingURL=buildStacks.js.map
@@ -0,0 +1,21 @@
1
+ export type CodeRangeKey = 'sourceOffsets' | 'generatedOffsets';
2
+ export interface Mapping<T = any> {
3
+ source?: string;
4
+ sourceOffsets: number[];
5
+ generatedOffsets: number[];
6
+ lengths: number[];
7
+ data: T;
8
+ }
9
+ export declare class SourceMap<Data = any> {
10
+ readonly mappings: Mapping<Data>[];
11
+ private sourceCodeOffsetsMemo;
12
+ private generatedCodeOffsetsMemo;
13
+ constructor(mappings: Mapping<Data>[]);
14
+ getSourceOffset(generatedOffset: number): readonly [number, Mapping<Data>] | undefined;
15
+ getGeneratedOffset(sourceOffset: number): readonly [number, Mapping<Data>] | undefined;
16
+ getSourceOffsets(generatedOffset: number): Generator<readonly [number, Mapping<Data>], void, unknown>;
17
+ getGeneratedOffsets(sourceOffset: number): Generator<readonly [number, Mapping<Data>], void, unknown>;
18
+ findMatching(offset: number, fromRange: CodeRangeKey, toRange: CodeRangeKey): Generator<readonly [number, Mapping<Data>], void, unknown>;
19
+ private getMemoBasedOnRange;
20
+ private createMemo;
21
+ }
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SourceMap = void 0;
4
+ const binarySearch_1 = require("./binarySearch");
5
+ const translateOffset_1 = require("./translateOffset");
6
+ class SourceMap {
7
+ constructor(mappings) {
8
+ this.mappings = mappings;
9
+ }
10
+ getSourceOffset(generatedOffset) {
11
+ for (const mapped of this.findMatching(generatedOffset, 'generatedOffsets', 'sourceOffsets')) {
12
+ return mapped;
13
+ }
14
+ }
15
+ getGeneratedOffset(sourceOffset) {
16
+ for (const mapped of this.findMatching(sourceOffset, 'sourceOffsets', 'generatedOffsets')) {
17
+ return mapped;
18
+ }
19
+ }
20
+ getSourceOffsets(generatedOffset) {
21
+ return this.findMatching(generatedOffset, 'generatedOffsets', 'sourceOffsets');
22
+ }
23
+ getGeneratedOffsets(sourceOffset) {
24
+ return this.findMatching(sourceOffset, 'sourceOffsets', 'generatedOffsets');
25
+ }
26
+ *findMatching(offset, fromRange, toRange) {
27
+ const memo = this.getMemoBasedOnRange(fromRange);
28
+ if (memo.offsets.length === 0)
29
+ return;
30
+ const { low: start, high: end } = (0, binarySearch_1.binarySearch)(memo.offsets, offset);
31
+ const skip = new Set();
32
+ for (let i = start; i <= end; i++) {
33
+ for (const mapping of memo.mappings[i]) {
34
+ if (skip.has(mapping))
35
+ continue;
36
+ skip.add(mapping);
37
+ const mapped = (0, translateOffset_1.translateOffset)(offset, mapping[fromRange], mapping[toRange], mapping.lengths);
38
+ if (mapped !== undefined)
39
+ yield [mapped, mapping];
40
+ }
41
+ }
42
+ }
43
+ getMemoBasedOnRange(fromRange) {
44
+ return fromRange === 'sourceOffsets'
45
+ ? this.sourceCodeOffsetsMemo ??= this.createMemo('sourceOffsets')
46
+ : this.generatedCodeOffsetsMemo ??= this.createMemo('generatedOffsets');
47
+ }
48
+ createMemo(key) {
49
+ const offsetsSet = new Set();
50
+ for (const mapping of this.mappings) {
51
+ for (let i = 0; i < mapping[key].length; i++) {
52
+ offsetsSet.add(mapping[key][i]);
53
+ offsetsSet.add(mapping[key][i] + mapping.lengths[i]);
54
+ }
55
+ }
56
+ const offsets = [...offsetsSet].sort((a, b) => a - b);
57
+ const mappings = offsets.map(() => new Set());
58
+ for (const mapping of this.mappings) {
59
+ for (let i = 0; i < mapping[key].length; i++) {
60
+ const startIndex = (0, binarySearch_1.binarySearch)(offsets, mapping[key][i]).match;
61
+ const endIndex = (0, binarySearch_1.binarySearch)(offsets, mapping[key][i] + mapping.lengths[i]).match;
62
+ for (let i = startIndex; i <= endIndex; i++) {
63
+ mappings[i].add(mapping);
64
+ }
65
+ }
66
+ }
67
+ return { offsets, mappings };
68
+ }
69
+ }
70
+ exports.SourceMap = SourceMap;
71
+ //# sourceMappingURL=sourceMap.js.map
@@ -0,0 +1 @@
1
+ export declare function translateOffset(start: number, fromOffsets: number[], toOffsets: number[], lengths: number[]): number | undefined;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.translateOffset = void 0;
4
+ function translateOffset(start, fromOffsets, toOffsets, lengths) {
5
+ for (let i = 0; i < fromOffsets.length; i++) {
6
+ const fromOffset = fromOffsets[i];
7
+ const toOffset = toOffsets[i];
8
+ const length = lengths[i];
9
+ if (start >= fromOffset && start <= fromOffset + length) {
10
+ return toOffset + start - fromOffset;
11
+ }
12
+ }
13
+ }
14
+ exports.translateOffset = translateOffset;
15
+ //# sourceMappingURL=translateOffset.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volar/source-map",
3
- "version": "1.11.1",
3
+ "version": "2.0.0-alpha.0",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "**/*.js",
@@ -12,7 +12,7 @@
12
12
  "directory": "packages/source-map"
13
13
  },
14
14
  "dependencies": {
15
- "muggle-string": "^0.3.1"
15
+ "muggle-string": "^0.4.0"
16
16
  },
17
- "gitHead": "188f49ee79bd2ea8e8fc32b80003c85f79868f9d"
17
+ "gitHead": "6a6be45a3b7983148d90541e7c68ef84c9155a7a"
18
18
  }