Skip to content

Commit 2916385

Browse files
committed
Add original scope variables to builder
1 parent 49d302e commit 2916385

File tree

4 files changed

+94
-19
lines changed

4 files changed

+94
-19
lines changed

src/builder/builder.test.ts

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,47 @@ describe("ScopeInfoBuilder", () => {
4141
assertStrictEquals(info.scopes[0], info.scopes[0].children[0].parent);
4242
});
4343

44-
it("can set the name via option", () => {
45-
const info = builder.startScope(0, 0, { name: "foo" }).endScope(5, 0)
46-
.build();
44+
describe("startScope", () => {
45+
it("can set the name via option", () => {
46+
const info = builder.startScope(0, 0, { name: "foo" }).endScope(5, 0)
47+
.build();
4748

48-
assertStrictEquals(info.scopes[0]?.name, "foo");
49-
});
49+
assertStrictEquals(info.scopes[0]?.name, "foo");
50+
});
5051

51-
it("can set kind via option", () => {
52-
const info = builder.startScope(0, 0, { kind: "Global" }).endScope(10, 0)
53-
.build();
52+
it("can set kind via option", () => {
53+
const info = builder.startScope(0, 0, { kind: "Global" }).endScope(10, 0)
54+
.build();
5455

55-
assertStrictEquals(info.scopes[0]?.kind, "Global");
56-
});
56+
assertStrictEquals(info.scopes[0]?.kind, "Global");
57+
});
5758

58-
it("can set isStackFrame via option", () => {
59-
const info = builder.startScope(0, 0, { isStackFrame: true }).endScope(
60-
10,
61-
0,
62-
).build();
59+
it("can set isStackFrame via option", () => {
60+
const info = builder.startScope(0, 0, { isStackFrame: true }).endScope(
61+
10,
62+
0,
63+
).build();
6364

64-
assertStrictEquals(info.scopes[0]?.isStackFrame, true);
65+
assertStrictEquals(info.scopes[0]?.isStackFrame, true);
66+
});
67+
68+
it("can set variables via option", () => {
69+
const info = builder.startScope(0, 0, { variables: ["a", "b"] }).endScope(
70+
10,
71+
0,
72+
).build();
73+
74+
assertEquals(info.scopes[0]?.variables, ["a", "b"]);
75+
});
76+
77+
it("copies the variables passed via options", () => {
78+
const variables = ["a", "b"];
79+
const info = builder.startScope(0, 0, { variables }).endScope(10, 0)
80+
.build();
81+
variables.push("c");
82+
83+
assertEquals(info.scopes[0]?.variables, ["a", "b"]);
84+
});
6585
});
6686

6787
describe("setScopeName", () => {
@@ -104,6 +124,24 @@ describe("ScopeInfoBuilder", () => {
104124
});
105125
});
106126

127+
describe("setScopeVariables", () => {
128+
it("sets variables", () => {
129+
const info = builder.startScope(0, 0).setScopeVariables(["a", "b"])
130+
.endScope(10, 0).build();
131+
132+
assertEquals(info.scopes[0]?.variables, ["a", "b"]);
133+
});
134+
135+
it("creates a copy of the variables", () => {
136+
const variables = ["a", "b"];
137+
const info = builder.startScope(0, 0).setScopeVariables(variables)
138+
.endScope(10, 0).build();
139+
variables.push("c");
140+
141+
assertEquals(info.scopes[0]?.variables, ["a", "b"]);
142+
});
143+
});
144+
107145
describe("endScope", () => {
108146
it("does nothing when no scope is open", () => {
109147
builder.endScope(10, 0);

src/builder/builder.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,17 @@ export class ScopeInfoBuilder {
3434
startScope(
3535
line: number,
3636
column: number,
37-
options?: { name?: string; kind?: string; isStackFrame?: boolean },
37+
options?: {
38+
name?: string;
39+
kind?: string;
40+
isStackFrame?: boolean;
41+
variables?: string[];
42+
},
3843
): this {
3944
const scope: OriginalScope = {
4045
start: { line, column },
4146
end: { line, column },
42-
variables: [],
47+
variables: options?.variables?.slice(0) ?? [],
4348
children: [],
4449
isStackFrame: Boolean(options?.isStackFrame),
4550
};
@@ -75,6 +80,13 @@ export class ScopeInfoBuilder {
7580
return this;
7681
}
7782

83+
setScopeVariables(variables: string[]): this {
84+
const scope = this.#scopeStack.at(-1);
85+
if (scope) scope.variables = variables.slice(0);
86+
87+
return this;
88+
}
89+
7890
endScope(line: number, column: number): this {
7991
const scope = this.#scopeStack.pop();
8092
if (!scope) return this;

src/builder/safe_builder.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,18 @@ describe("SafeScopeInfoBuilder", () => {
9999
});
100100
});
101101

102+
describe("setScopeVariables", () => {
103+
it("throws when no scope is on open", () => {
104+
assertThrows(() => builder.setScopeVariables(["foo"]));
105+
});
106+
107+
it("throws while building a range", () => {
108+
builder.startRange(0, 0);
109+
110+
assertThrows(() => builder.setScopeVariables(["foo"]));
111+
});
112+
});
113+
102114
describe("endScope", () => {
103115
it("throws when the scope stack is empty", () => {
104116
assertThrows(() => builder.endScope(5, 0));

src/builder/safe_builder.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ export class SafeScopeInfoBuilder extends ScopeInfoBuilder {
2222
override startScope(
2323
line: number,
2424
column: number,
25-
options?: { name?: string; kind?: string; isStackFrame?: boolean },
25+
options?: {
26+
name?: string;
27+
kind?: string;
28+
isStackFrame?: boolean;
29+
variables?: string[];
30+
},
2631
): this {
2732
this.#verifyEmptyRangeStack("start scope");
2833

@@ -74,6 +79,14 @@ export class SafeScopeInfoBuilder extends ScopeInfoBuilder {
7479
return this;
7580
}
7681

82+
override setScopeVariables(variables: string[]): this {
83+
this.#verifyScopePresent("setScopeVariables");
84+
this.#verifyEmptyRangeStack("setScopeVariables");
85+
86+
super.setScopeVariables(variables);
87+
return this;
88+
}
89+
7790
override endScope(line: number, column: number): this {
7891
this.#verifyEmptyRangeStack("end scope");
7992

0 commit comments

Comments
 (0)