Skip to content

Commit 6ceea20

Browse files
committed
Start with strict/loose decode mode
1 parent aa197d8 commit 6ceea20

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

mod.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export type {
1414
} from "./src/scopes.d.ts";
1515

1616
export { encode } from "./src/encode/encode.ts";
17-
export { decode } from "./src/decode/decode.ts";
17+
export { decode, type DecodeMode } from "./src/decode/decode.ts";
1818

1919
export { ScopeInfoBuilder } from "./src/builder/builder.ts";
2020
export { SafeScopeInfoBuilder } from "./src/builder/safe_builder.ts";

src/decode/decode.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,30 @@ import type {
1818
} from "../scopes.d.ts";
1919
import { TokenIterator } from "../vlq.ts";
2020

21-
export function decode(sourceMap: SourceMapJson): ScopeInfo {
21+
/**
22+
* The mode decides how well-formed the encoded scopes have to be, to be accepted by the decoder.
23+
*
24+
* LOOSE is the default and is much more lenient. It's still best effort though and the decoder doesn't
25+
* implement any error recovery: e.g. superfluous "start" items can lead to whole trees being omitted.
26+
*
27+
* STRICT mode will throw in the following situations:
28+
*
29+
* - Encountering ORIGINAL_SCOPE_END, or GENERATED_RANGE_END items that don't have matching *_START items.
30+
* - Miss-matches between the number of variables in a scope vs the number of value expressions in the ranges.
31+
* - Out-of-bound indices into the "names" array.
32+
*/
33+
export const enum DecodeMode {
34+
STRICT = 1,
35+
LOOSE = 2,
36+
}
37+
38+
export function decode(
39+
sourceMap: SourceMapJson,
40+
options?: { mode: DecodeMode },
41+
): ScopeInfo {
2242
if (!sourceMap.scopes || !sourceMap.names) return { scopes: [], ranges: [] };
2343

24-
return new Decoder(sourceMap.scopes, sourceMap.names).decode();
44+
return new Decoder(sourceMap.scopes, sourceMap.names, options).decode();
2545
}
2646

2747
const DEFAULT_SCOPE_STATE = {
@@ -43,6 +63,7 @@ const DEFAULT_RANGE_STATE = {
4363
class Decoder {
4464
readonly #encodedScopes: string;
4565
readonly #names: string[];
66+
readonly #mode: DecodeMode;
4667

4768
#scopes: (OriginalScope | null)[] = [];
4869
#ranges: GeneratedRange[] = [];
@@ -56,9 +77,10 @@ class Decoder {
5677
readonly #countToScope = new Map<number, OriginalScope>();
5778
#scopeCounter = 0;
5879

59-
constructor(scopes: string, names: string[]) {
80+
constructor(scopes: string, names: string[], options?: { mode: DecodeMode }) {
6081
this.#encodedScopes = scopes;
6182
this.#names = names;
83+
this.#mode = options?.mode ?? DecodeMode.LOOSE;
6284
}
6385

6486
decode(): ScopeInfo {

0 commit comments

Comments
 (0)