Skip to content

Commit a53e254

Browse files
committed
Encode range definition
1 parent e713e19 commit a53e254

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

src/codec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export const enum OriginalScopeFlags {
2626

2727
export const enum GeneratedRangeFlags {
2828
HAS_LINE = 0x1,
29+
HAS_DEFINITION = 0x2,
2930
}
3031

3132
export const EmptyItem = Symbol("empty item");

src/encode/encode.test.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,19 @@ describe("encode", () => {
7171
assertThrows(() => encode(info));
7272
});
7373

74-
it("throws when a rangees' end precedes the ranges' start", () => {
74+
it("throws when a ranges' end precedes the ranges' start", () => {
7575
const info = builder.startRange(10, 0).endRange(0, 0).build();
7676

7777
assertThrows(() => encode(info));
7878
});
79+
80+
it("throws when a ranges' definition scope has not known to the encoder", () => {
81+
const scope = builder.startScope(0, 0).endScope(10, 0).lastScope()!;
82+
const info = builder.startRange(0, 10).endRange(0, 20).build();
83+
84+
// Set the range's definition as a copy of `scope`.
85+
info.ranges[0].originalScope = { ...scope };
86+
87+
assertThrows(() => encode(info));
88+
});
7989
});

src/encode/encoder.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ export class Encoder {
3333
readonly #scopeState = { ...DEFAULT_SCOPE_STATE };
3434
readonly #rangeState = { ...DEFAULT_RANGE_STATE };
3535
#encodedItems: string[] = [];
36-
3736
#currentItem: string = "";
3837

38+
#scopeToCount = new Map<OriginalScope, number>();
39+
#scopeCounter = 0;
40+
3941
constructor(info: ScopeInfo, names: string[]) {
4042
this.#info = info;
4143
this.#names = names;
@@ -98,6 +100,8 @@ export class Encoder {
98100
if (encodedName !== undefined) this.#encodeSigned(encodedName);
99101
if (encodedKind !== undefined) this.#encodeSigned(encodedKind);
100102
this.#finishItem();
103+
104+
this.#scopeToCount.set(scope, this.#scopeCounter++);
101105
}
102106

103107
#encodeOriginalScopeEnd(scope: OriginalScope) {
@@ -134,9 +138,24 @@ export class Encoder {
134138
this.#rangeState.line = line;
135139
this.#rangeState.column = column;
136140

141+
let encodedDefinition;
142+
if (range.originalScope) {
143+
const definitionIdx = this.#scopeToCount.get(range.originalScope);
144+
if (definitionIdx === undefined) {
145+
throw new Error("Unknown OriginalScope for definition!");
146+
}
147+
148+
flags |= GeneratedRangeFlags.HAS_DEFINITION;
149+
150+
encodedDefinition = definitionIdx - this.#rangeState.defScopeIdx;
151+
this.#rangeState.defScopeIdx = definitionIdx;
152+
}
153+
137154
this.#encodeTag(EncodedTag.GENERATED_RANGE_START).#encodeUnsigned(flags);
138155
if (encodedLine > 0) this.#encodeUnsigned(encodedLine);
139-
this.#encodeUnsigned(encodedColumn).#finishItem();
156+
this.#encodeUnsigned(encodedColumn);
157+
if (encodedDefinition !== undefined) this.#encodeSigned(encodedDefinition);
158+
this.#finishItem();
140159
}
141160

142161
#encodeGeneratedRangeEnd(range: GeneratedRange) {

0 commit comments

Comments
 (0)