Skip to content

Commit 6d07bff

Browse files
committed
Implement rudimentary CallSite encoding/decoding
1 parent 239f899 commit 6d07bff

File tree

4 files changed

+88
-0
lines changed

4 files changed

+88
-0
lines changed

src/codec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const enum Tag {
99
GENERATED_RANGE_START = 0x5,
1010
GENERATED_RANGE_END = 0x6,
1111
GENERATED_RANGE_BINDINGS = 0x7,
12+
GENERATED_RANGE_CALL_SITE = 0x9,
1213
}
1314

1415
export const enum EncodedTag {
@@ -18,6 +19,7 @@ export const enum EncodedTag {
1819
GENERATED_RANGE_START = "F", // 0x5
1920
GENERATED_RANGE_END = "G", // 0x6
2021
GENERATED_RANGE_BINDINGS = "H", // 0x7
22+
GENERATED_RANGE_CALL_SITE = "J", // 0x9
2123
}
2224

2325
export const enum OriginalScopeFlags {

src/decode/decode.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ class Decoder {
171171
this.#handleGeneratedRangeBindingsItem(valueIdxs);
172172
break;
173173
}
174+
case Tag.GENERATED_RANGE_CALL_SITE: {
175+
this.#handleGeneratedRangeCallSite(
176+
iter.nextSignedVLQ(),
177+
iter.nextSignedVLQ(),
178+
iter.nextSignedVLQ(),
179+
);
180+
break;
181+
}
174182
}
175183

176184
// Consume any trailing VLQ and the the ","
@@ -331,6 +339,35 @@ class Decoder {
331339
}
332340
}
333341

342+
#handleGeneratedRangeCallSite(
343+
sourceIndex: number,
344+
line: number,
345+
column: number,
346+
) {
347+
const range = this.#rangeStack.at(-1);
348+
if (!range) {
349+
// TODO: Throw in strict mode.
350+
return;
351+
}
352+
353+
if (sourceIndex === 0 && line === 0) {
354+
this.#rangeState.callsiteColumn += column;
355+
} else if (sourceIndex === 0) {
356+
this.#rangeState.callsiteLine += line;
357+
this.#rangeState.callsiteColumn = column;
358+
} else {
359+
this.#rangeState.callsiteSourceIdx += sourceIndex;
360+
this.#rangeState.callsiteLine = line;
361+
this.#rangeState.callsiteColumn = column;
362+
}
363+
364+
range.callSite = {
365+
sourceIndex: this.#rangeState.callsiteSourceIdx,
366+
line: this.#rangeState.callsiteLine,
367+
column: this.#rangeState.callsiteColumn,
368+
};
369+
}
370+
334371
#handleGeneratedRangeEndItem(line: number, column: number) {
335372
if (line !== 0) {
336373
this.#rangeState.line += line;

src/encode/encoder.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ export class Encoder {
144144
#encodeGeneratedRange(range: GeneratedRange): void {
145145
this.#encodeGeneratedRangeStart(range);
146146
this.#encodeGeneratedRangeBindings(range);
147+
this.#encodeGeneratedRangeCallSite(range);
147148
range.children.forEach((child) => this.#encodeGeneratedRange(child));
148149
this.#encodeGeneratedRangeEnd(range);
149150
}
@@ -210,6 +211,29 @@ export class Encoder {
210211
this.#finishItem();
211212
}
212213

214+
#encodeGeneratedRangeCallSite(range: GeneratedRange) {
215+
if (!range.callSite) return;
216+
const { sourceIndex, line, column } = range.callSite;
217+
218+
// TODO: Throw if stackFrame flag is set or OriginalScope index is invalid or no generated range is here.
219+
220+
const encodedSourceIndex = sourceIndex - this.#rangeState.callsiteSourceIdx;
221+
const encodedLine = encodedSourceIndex == 0
222+
? line - this.#rangeState.callsiteLine
223+
: line;
224+
const encodedColumn = encodedLine == 0
225+
? column - this.#rangeState.callsiteColumn
226+
: column;
227+
228+
this.#rangeState.callsiteSourceIdx = sourceIndex;
229+
this.#rangeState.callsiteLine = line;
230+
this.#rangeState.callsiteColumn = column;
231+
232+
this.#encodeTag(EncodedTag.GENERATED_RANGE_CALL_SITE).#encodeSigned(
233+
encodedSourceIndex,
234+
).#encodeSigned(encodedLine).#encodeSigned(encodedColumn).#finishItem();
235+
}
236+
213237
#encodeGeneratedRangeEnd(range: GeneratedRange) {
214238
const { line, column } = range.end;
215239
this.#verifyPositionWithRangeState(line, column);

src/roundtrip.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,29 @@ describe("round trip", () => {
157157

158158
assertCodec(builder.build());
159159
});
160+
161+
it("handles callSites for inlined ranges", () => {
162+
builder.startScope(0, 0, { key: "global" }).startScope(10, 0, {
163+
key: "function",
164+
}).endScope(20, 0).endScope(30, 0)
165+
.startRange(0, 0, { scopeKey: "global" })
166+
.startRange(0, 10, {
167+
scopeKey: "function",
168+
callSite: { sourceIndex: 0, line: 30, column: 5 },
169+
})
170+
.endRange(0, 20)
171+
.startRange(0, 30, {
172+
scopeKey: "function",
173+
callSite: { sourceIndex: 0, line: 30, column: 20 },
174+
})
175+
.endRange(0, 40)
176+
.startRange(0, 50, {
177+
scopeKey: "function",
178+
callSite: { sourceIndex: 0, line: 40, column: 2 },
179+
})
180+
.endRange(0, 60)
181+
.endRange(0, 70);
182+
183+
assertCodec(builder.build());
184+
});
160185
});

0 commit comments

Comments
 (0)