Skip to content

Commit 6e1e636

Browse files
committed
full scopes
1 parent ed6f5da commit 6e1e636

10 files changed

Lines changed: 80 additions & 73 deletions

src/ast.ts

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,19 +2157,40 @@ export class ScopeAnalyzer extends DiagnosticEmitter {
21572157
}
21582158
}
21592159

2160+
pushScope(scope: Map<string,Node> = new Map()): void {
2161+
this.blockScopes.push(scope);
2162+
}
2163+
2164+
popScope(): string[] {
2165+
var names = new Set<string>();
2166+
var functionScope = this.functionScope;
2167+
// TODO: for(let key of functionScope.keys()) {
2168+
for (let _keys = Map_keys(functionScope), i = 0, k = _keys.length; i < k; ++i) {
2169+
names.add(_keys[i]);
2170+
}
2171+
var blockScopes = this.blockScopes;
2172+
var blockDepth = assert(blockScopes.length);
2173+
for (let i = 0; i < blockDepth; ++i) {
2174+
let blockScope = blockScopes[i];
2175+
// TODO: for (let key of blockScope.keys()) {
2176+
for (let _keys = Map_keys(blockScope), j = 0, k = _keys.length; j < k; ++j) {
2177+
names.add(_keys[j]);
2178+
}
2179+
}
2180+
blockScopes.pop();
2181+
return Set_values(names);
2182+
}
2183+
21602184
visit(node: Node): void {
21612185
switch (node.kind) {
21622186
case NodeKind.BLOCK: {
21632187
let blockStatement = <BlockStatement>node;
2164-
let scope = new Map<string,Node>();
2165-
let blockScopes = this.blockScopes;
2166-
blockScopes.push(scope);
2188+
this.pushScope();
21672189
let statements = blockStatement.statements;
21682190
for (let i = 0, k = statements.length; i < k; ++i) {
21692191
this.visit(statements[i]);
21702192
}
2171-
blockScopes.pop();
2172-
blockStatement._scope = Map_keys(scope);
2193+
blockStatement._scope = this.popScope();
21732194
break;
21742195
}
21752196
case NodeKind.BREAK: break;
@@ -2188,26 +2209,20 @@ export class ScopeAnalyzer extends DiagnosticEmitter {
21882209
}
21892210
case NodeKind.FOR: {
21902211
let forStatement = <ForStatement>node;
2191-
let scope = new Map<string,Node>();
2192-
let blockScopes = this.blockScopes;
2193-
blockScopes.push(scope);
2212+
this.pushScope();
21942213
let initializer = forStatement.initializer;
21952214
if (initializer) this.visit(initializer);
21962215
this.visit(forStatement.statement);
2197-
blockScopes.pop();
2198-
forStatement._scope = Map_keys(scope);
2216+
forStatement._scope = this.popScope();
21992217
break;
22002218
}
22012219
case NodeKind.FOROF: {
22022220
let forOfStatement = <ForOfStatement>node;
2203-
let scope = new Map<string,Node>();
2204-
let blockScopes = this.blockScopes;
2205-
blockScopes.push(scope);
2221+
this.pushScope();
22062222
let variable = forOfStatement.variable;
22072223
if (variable) this.visit(variable);
22082224
this.visit(forOfStatement.statement);
2209-
blockScopes.pop();
2210-
forOfStatement._scope = Map_keys(scope);
2225+
forOfStatement._scope = this.popScope();
22112226
break;
22122227
}
22132228
case NodeKind.IF: {
@@ -2220,15 +2235,12 @@ export class ScopeAnalyzer extends DiagnosticEmitter {
22202235
case NodeKind.RETURN: break;
22212236
case NodeKind.SWITCH: {
22222237
let switchStatement = <SwitchStatement>node;
2223-
let scope = new Map<string,Node>();
2224-
let blockScopes = this.blockScopes;
2225-
blockScopes.push(scope);
2238+
this.pushScope();
22262239
let cases = switchStatement.cases;
22272240
for (let i = 0, k = cases.length; i < k; ++i) {
22282241
this.visit(cases[i]);
22292242
}
2230-
blockScopes.pop();
2231-
switchStatement._scope = Map_keys(scope);
2243+
switchStatement._scope = this.popScope();
22322244
break;
22332245
}
22342246
case NodeKind.THROW: break;
@@ -2241,28 +2253,23 @@ export class ScopeAnalyzer extends DiagnosticEmitter {
22412253
let catchStatements = tryStatement.catchStatements;
22422254
if (catchStatements) {
22432255
let scope = new Map<string,Node>();
2256+
this.pushScope(scope);
22442257
let catchVariable = tryStatement.catchVariable;
22452258
if (catchVariable) {
22462259
scope.set(catchVariable.text, catchVariable);
22472260
}
2248-
let blockScopes = this.blockScopes;
2249-
blockScopes.push(scope);
22502261
for (let i = 0, k = catchStatements.length; i < k; ++i) {
22512262
this.visit(catchStatements[i]);
22522263
}
2253-
blockScopes.pop();
2254-
tryStatement._catchScope = Map_keys(scope);
2264+
tryStatement._catchScope = this.popScope();
22552265
}
22562266
let finallyStatements = tryStatement.finallyStatements;
22572267
if (finallyStatements) {
2258-
let scope = new Map<string,Node>();
2259-
let blockScopes = this.blockScopes;
2260-
blockScopes.push(scope);
2268+
this.pushScope();
22612269
for (let i = 0, k = finallyStatements.length; i < k; ++i) {
22622270
this.visit(finallyStatements[i]);
22632271
}
2264-
blockScopes.pop();
2265-
tryStatement._finallyScope = Map_keys(scope);
2272+
tryStatement._finallyScope = this.popScope();
22662273
}
22672274
break;
22682275
}

tests/parser/class.ts.fixture.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export class Valid<T> {
33
instanceFunction(): void {}
44
static staticFunction(): void {}
55
get instanceGetter(): i32 {}
6-
static set staticSetter(v: i32) /* {v} */ {}
6+
static set staticSetter(v: i32) /* {v} */ {/* {v} */}
77
instanceField: i32;
88
static staticField: i32;
99
static void: i32;
@@ -12,7 +12,7 @@ export class Valid<T> {
1212
export class Invalid<T> {
1313
constructor<T>() {}
1414
instanceFunction() {}
15-
get instanceGetter<T>(a: i32) /* {a} */ {}
15+
get instanceGetter<T>(a: i32) /* {a} */ {/* {a} */}
1616
set instanceSetter<T>() {}
1717
}
1818
// ERROR 1092: "Type parameters cannot appear on a constructor declaration." in class.ts:15:14
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
class MyClass {
22
constructor() {}
3-
constructor(a: i32) /* {a} */ {}
4-
constructor(a: i32, b: i32) /* {a,b} */ {}
3+
constructor(a: i32) /* {a} */ {/* {a} */}
4+
constructor(a: i32, b: i32) /* {a,b} */ {/* {a,b} */}
55
}
66
class MyClassImplicit {
7-
constructor(public a: i32, private readonly b?: i32 = 2, c?: i32 = 3) /* {a,b,c} */ {}
7+
constructor(public a: i32, private readonly b?: i32 = 2, c?: i32 = 3) /* {a,b,c} */ {/* {a,b,c} */}
88
}

tests/parser/function-expression.ts.fixture.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ var a = function(): void {
44
var b = function someName(): void {
55
;
66
};
7-
var c = function(a: i32, b: i32): i32 /* {a,b} */ {
7+
var c = function(a: i32, b: i32): i32 /* {a,b} */ {/* {a,b} */
88
;
99
};
1010
var d = (): void => {
1111
;
1212
};
13-
var e = (a: i32, b: i32): i32 => /* {a,b} */ {
13+
var e = (a: i32, b: i32): i32 => /* {a,b} */ {/* {a,b} */
1414
;
1515
};
1616
var f = (a: i32): i32 => /* {a} */ a;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
function simple(): void {}
2-
function typeparams<T, V extends T>(a?: V | null = null): void /* {a} */ {}
2+
function typeparams<T, V extends T>(a?: V | null = null): void /* {a} */ {/* {a} */}
33
@decorator()
44
function withdecorator(): void {}
55
function withthis(this: i32): i32 {
66
return this;
77
}
8-
function withthisp(this: i32, a: f32, b: f64): i32 /* {a,b} */ {
8+
function withthisp(this: i32, a: f32, b: f64): i32 /* {a,b} */ {/* {a,b} */
99
return this;
1010
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
function restValid(a: i32, ...b: Array<i32>): void /* {a,b} */ {}
2-
function optionalValid(a: i32, b?: i32): void /* {a,b} */ {}
3-
function restParameterMustBeLast(...a: Array<i32>, b: i32): void /* {a,b} */ {}
4-
function optionalCannotPrecedeRequired(a?: i32, b: i32): void /* {a,b} */ {}
5-
function optionalWithInitializerCannotPrecedeRequired(a?: i32 = 1, b: i32): void /* {a,b} */ {}
1+
function restValid(a: i32, ...b: Array<i32>): void /* {a,b} */ {/* {a,b} */}
2+
function optionalValid(a: i32, b?: i32): void /* {a,b} */ {/* {a,b} */}
3+
function restParameterMustBeLast(...a: Array<i32>, b: i32): void /* {a,b} */ {/* {a,b} */}
4+
function optionalCannotPrecedeRequired(a?: i32, b: i32): void /* {a,b} */ {/* {a,b} */}
5+
function optionalWithInitializerCannotPrecedeRequired(a?: i32 = 1, b: i32): void /* {a,b} */ {/* {a,b} */}
66
// ERROR 1014: "A rest parameter must be last in a parameter list." in parameter-order.ts:5:37
77
// ERROR 1016: "A required parameter cannot follow an optional parameter." in parameter-order.ts:8:49
88
// ERROR 1016: "A required parameter cannot follow an optional parameter." in parameter-order.ts:11:67

tests/parser/reserved-keywords.ts.fixture.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
function alsoIdentifier(readonly: i32): void /* {readonly} */ {}
1+
function alsoIdentifier(readonly: i32): void /* {readonly} */ {/* {readonly} */}
22
class AClass {
3-
constructor(readonly: i32) /* {readonly} */ {}
4-
constructor(readonly readonly: i32) /* {readonly} */ {}
3+
constructor(readonly: i32) /* {readonly} */ {/* {readonly} */}
4+
constructor(readonly readonly: i32) /* {readonly} */ {/* {readonly} */}
55
}
66
type type = i32;
77
var type: i32;

tests/parser/scope.ts.fixture.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,59 @@
1-
function foo(a: i32): void /* {a,b,d,f,g,j,l,m,p,r,t,v} */ {/* {c} */
1+
function foo(a: i32): void /* {a,b,d,f,g,j,l,m,p,r,t,v} */ {/* {a,b,d,f,g,j,l,m,p,r,t,v,c} */
22
var b = 0;
33
let c = 0;
4-
{/* {e} */
4+
{/* {a,b,d,c,e} */
55
var d = 0;
66
let e = 0;
77
}
8-
for (var f = 0; f < 10; ++f) {/* {h} */
8+
for (var f = 0; f < 10; ++f) /* {a,b,d,f,g,c} */ {/* {a,b,d,f,g,c,h} */
99
var g = 0;
1010
let h = 0;
1111
}
12-
for (let i = 0; i < 10; ++i) /* {i} */ {/* {k} */
12+
for (let i = 0; i < 10; ++i) /* {a,b,d,f,g,j,c,i} */ {/* {a,b,d,f,g,j,c,i,k} */
1313
var j = 0;
1414
let k = 0;
1515
}
16-
for (var l of something) {/* {n} */
16+
for (var l of something) /* {a,b,d,f,g,j,l,m,c} */ {/* {a,b,d,f,g,j,l,m,c,n} */
1717
var m = 0;
1818
let n = 0;
1919
}
20-
for (let o of something) /* {o} */ {/* {q} */
20+
for (let o of something) /* {a,b,d,f,g,j,l,m,p,c,o} */ {/* {a,b,d,f,g,j,l,m,p,c,o,q} */
2121
var p = 0;
2222
let q = 0;
2323
}
24-
switch (something) /* {s} */ {
24+
switch (something) /* {a,b,d,f,g,j,l,m,p,r,t,c,s} */ {
2525
case 0:
2626
var r = 0;
2727
case 1:
2828
let s = 0;
2929
case 2:
30-
{/* {u} */
30+
{/* {a,b,d,f,g,j,l,m,p,r,t,c,s,u} */
3131
var t = 0;
3232
let u = 0;
3333
}
3434
}
35-
function v(): void /* {w} */ {/* {x} */
35+
function v(): void /* {w} */ {/* {w,x} */
3636
var w = 0;
3737
let x = 0;
3838
};
3939
var a = 1;
4040
let a = 1;
41-
{
41+
{/* {a,b,d,f,g,j,l,m,p,r,t,v,c} */
4242
var a = 1;
4343
}
4444
var b = 1;
4545
let b = 1;
46-
{
46+
{/* {a,b,d,f,g,j,l,m,p,r,t,v,c} */
4747
var b = 1;
4848
}
4949
var c = 1;
5050
let c = 1;
51-
{
51+
{/* {a,b,d,f,g,j,l,m,p,r,t,v,c} */
5252
var c = 1;
5353
}
5454
var v = 1;
5555
let v = 1;
56-
{
56+
{/* {a,b,d,f,g,j,l,m,p,r,t,v,c} */
5757
var v = 1;
5858
}
5959
}
Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,48 @@
11
@binding(BindingCall.NEW, [BindingType.STRING], BindingType.OBJECT_HANDLE)
22
export class ExternalString {
33
@binding(BindingCall.FUNCTION, [BindingType.U32, BindingType.U32], BindingType.OBJECT_HANDLE)
4-
static fromCharCode(char: u16, schar?: u16 = <u16>-1): String /* {char,schar} */ {
4+
static fromCharCode(char: u16, schar?: u16 = <u16>-1): String /* {char,schar} */ {/* {char,schar} */
55
return unreachable();
66
}
77
@binding(BindingCall.FUNCTION, [BindingType.U32], BindingType.OBJECT_HANDLE)
8-
static fromCodePoint(codepoint: u32): String /* {codepoint} */ {
8+
static fromCodePoint(codepoint: u32): String /* {codepoint} */ {/* {codepoint} */
99
return unreachable();
1010
}
1111
@binding(BindingCall.THIS, [BindingType.U32], BindingType.OBJECT_HANDLE)
12-
charAt(index: u32): String /* {index} */ {
12+
charAt(index: u32): String /* {index} */ {/* {index} */
1313
return unreachable();
1414
}
1515
@binding(BindingCall.THIS, [BindingType.U32], BindingType.PASS_THRU)
16-
charCodeAt(index: u32): u16 /* {index} */ {
16+
charCodeAt(index: u32): u16 /* {index} */ {/* {index} */
1717
return unreachable();
1818
}
1919
@binding(BindingCall.THIS, [BindingType.U32], BindingType.PASS_THRU)
20-
codePointAt(index: u32): u32 /* {index} */ {
20+
codePointAt(index: u32): u32 /* {index} */ {/* {index} */
2121
return unreachable();
2222
}
2323
@binding(BindingCall.THIS, [BindingType.OBJECT_HANDLE], BindingType.OBJECT_HANDLE)
2424
@operator("+")
25-
concat(other: String): String /* {other} */ {
25+
concat(other: String): String /* {other} */ {/* {other} */
2626
return unreachable();
2727
}
2828
@binding(BindingCall.THIS, [BindingType.OBJECT_HANDLE], BindingType.PASS_THRU)
29-
endsWith(other: String): bool /* {other} */ {
29+
endsWith(other: String): bool /* {other} */ {/* {other} */
3030
return unreachable();
3131
}
3232
@binding(BindingCall.THIS, [BindingType.OBJECT_HANDLE], BindingType.PASS_THRU)
33-
indexOf(other: String): i32 /* {other} */ {
33+
indexOf(other: String): i32 /* {other} */ {/* {other} */
3434
return unreachable();
3535
}
3636
@binding(BindingCall.THIS, [BindingType.OBJECT_HANDLE], BindingType.PASS_THRU)
37-
startsWith(other: String): bool /* {other} */ {
37+
startsWith(other: String): bool /* {other} */ {/* {other} */
3838
return unreachable();
3939
}
4040
@binding(BindingCall.THIS, [BindingType.U32, BindingType.U32], BindingType.OBJECT_HANDLE)
41-
substr(start: i32, length: i32): String /* {start,length} */ {
41+
substr(start: i32, length: i32): String /* {start,length} */ {/* {start,length} */
4242
return unreachable();
4343
}
4444
@binding(BindingCall.THIS, [BindingType.U32, BindingType.U32], BindingType.OBJECT_HANDLE)
45-
substring(start: i32, end: i32): String /* {start,end} */ {
45+
substring(start: i32, end: i32): String /* {start,end} */ {/* {start,end} */
4646
return unreachable();
4747
}
4848
@binding(BindingCall.THIS, [], BindingType.OBJECT_HANDLE)
@@ -59,7 +59,7 @@ export class ExternalString {
5959
}
6060
@binding(BindingCall.THIS, [BindingType.OBJECT_HANDLE], BindingType.PASS_THRU)
6161
@operator("==")
62-
equals(other: String): bool /* {other} */ {
62+
equals(other: String): bool /* {other} */ {/* {other} */
6363
return unreachable();
6464
}
6565
}

tests/parser/trailing-commas.ts.fixture.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ enum Foo {
66
A,
77
B
88
}
9-
function add(x: i32, y: i32): i32 /* {x,y} */ {
9+
function add(x: i32, y: i32): i32 /* {x,y} */ {/* {x,y} */
1010
return x + y;
1111
}
12-
function parameterized<A, B>(a: A, b: B): void /* {a,b} */ {}
12+
function parameterized<A, B>(a: A, b: B): void /* {a,b} */ {/* {a,b} */}
1313
export function compute(): i32 {/* {arr} */
1414
const arr: Array<i8> = [1, 2];
1515
parameterized<i8, i32>(0, 0);

0 commit comments

Comments
 (0)