Skip to content

Commit ff05082

Browse files
authored
Bind non-expando property assignments at top-level (#26908)
* Bind non-expando property assignments at toplevel Previously, only property assignments with expando initialisers were bound in top-level statements. Now, all property assignments are bound. This requires a matching change in the checker to make sure that these assignments remain context sensitive if their valueDeclaration is a 'real' declaration (ie a non assignment-declaration). * Add baselines for new test
1 parent 6e31889 commit ff05082

File tree

42 files changed

+383
-304
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+383
-304
lines changed

src/compiler/binder.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2512,11 +2512,10 @@ namespace ts {
25122512

25132513
function bindPropertyAssignment(name: EntityNameExpression, propertyAccess: PropertyAccessEntityNameExpression, isPrototypeProperty: boolean) {
25142514
let namespaceSymbol = lookupSymbolForPropertyAccess(name);
2515-
const isToplevelNamespaceableInitializer = isBinaryExpression(propertyAccess.parent)
2516-
? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === SyntaxKind.SourceFile &&
2517-
!!getJavascriptInitializer(getInitializerOfBinaryExpression(propertyAccess.parent), isPrototypeAccess(propertyAccess.parent.left))
2515+
const isToplevel = isBinaryExpression(propertyAccess.parent)
2516+
? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === SyntaxKind.SourceFile
25182517
: propertyAccess.parent.parent.kind === SyntaxKind.SourceFile;
2519-
if (!isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & SymbolFlags.Namespace)) && isToplevelNamespaceableInitializer) {
2518+
if (!isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & SymbolFlags.Namespace)) && isToplevel) {
25202519
// make symbols or add declarations for intermediate containers
25212520
const flags = SymbolFlags.Module | SymbolFlags.JSContainer;
25222521
const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.JSContainer;
@@ -2573,7 +2572,7 @@ namespace ts {
25732572
return false;
25742573
}
25752574

2576-
function getParentOfBinaryExpression(expr: BinaryExpression) {
2575+
function getParentOfBinaryExpression(expr: Node) {
25772576
while (isBinaryExpression(expr.parent)) {
25782577
expr = expr.parent;
25792578
}

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16189,7 +16189,7 @@ namespace ts {
1618916189
else if (isIdentifier(lhs.expression)) {
1619016190
const id = lhs.expression;
1619116191
const parentSymbol = resolveName(id, id.escapedText, SymbolFlags.Value, undefined, id.escapedText, /*isUse*/ true);
16192-
if (parentSymbol && isFunctionSymbol(parentSymbol)) {
16192+
if (parentSymbol) {
1619316193
const annotated = getEffectiveTypeAnnotationNode(parentSymbol.valueDeclaration);
1619416194
if (annotated) {
1619516195
const type = getTypeOfPropertyOfContextualType(getTypeFromTypeNode(annotated), lhs.name.escapedText);

tests/baselines/reference/checkJsdocTypeTagOnObjectProperty1.symbols

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ var lol = "hello Lol"
44
>lol : Symbol(lol, Decl(0.js, 1, 3))
55

66
const obj = {
7-
>obj : Symbol(obj, Decl(0.js, 2, 5))
7+
>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1))
88

99
/** @type {string|undefined} */
1010
foo: undefined,
@@ -40,31 +40,31 @@ const obj = {
4040
}
4141
obj.foo = 'string'
4242
>obj.foo : Symbol(foo, Decl(0.js, 2, 13))
43-
>obj : Symbol(obj, Decl(0.js, 2, 5))
43+
>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1))
4444
>foo : Symbol(foo, Decl(0.js, 2, 13))
4545

4646
obj.lol
4747
>obj.lol : Symbol(lol, Decl(0.js, 10, 4))
48-
>obj : Symbol(obj, Decl(0.js, 2, 5))
48+
>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1))
4949
>lol : Symbol(lol, Decl(0.js, 10, 4))
5050

5151
obj.bar = undefined;
5252
>obj.bar : Symbol(bar, Decl(0.js, 4, 17))
53-
>obj : Symbol(obj, Decl(0.js, 2, 5))
53+
>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1))
5454
>bar : Symbol(bar, Decl(0.js, 4, 17))
5555
>undefined : Symbol(undefined)
5656

5757
var k = obj.method1(0);
5858
>k : Symbol(k, Decl(0.js, 21, 3))
5959
>obj.method1 : Symbol(method1, Decl(0.js, 6, 12))
60-
>obj : Symbol(obj, Decl(0.js, 2, 5))
60+
>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1))
6161
>method1 : Symbol(method1, Decl(0.js, 6, 12))
6262

6363
obj.bar1 = "42";
64-
>obj : Symbol(obj, Decl(0.js, 2, 5))
64+
>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1))
6565

6666
obj.arrowFunc(0);
6767
>obj.arrowFunc : Symbol(arrowFunc, Decl(0.js, 14, 20))
68-
>obj : Symbol(obj, Decl(0.js, 2, 5))
68+
>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1))
6969
>arrowFunc : Symbol(arrowFunc, Decl(0.js, 14, 20))
7070

tests/baselines/reference/classCanExtendConstructorFunction.symbols

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,15 @@ class Sql extends Wagon {
107107
}
108108
}
109109
var db = new Sql();
110-
>db : Symbol(db, Decl(first.js, 42, 3))
110+
>db : Symbol(db, Decl(first.js, 42, 3), Decl(first.js, 42, 19))
111111
>Sql : Symbol(Sql, Decl(first.js, 18, 1))
112112

113113
db.numberOxen = db.foonly
114114
>db.numberOxen : Symbol(Wagon.numberOxen, Decl(first.js, 4, 28))
115-
>db : Symbol(db, Decl(first.js, 42, 3))
115+
>db : Symbol(db, Decl(first.js, 42, 3), Decl(first.js, 42, 19))
116116
>numberOxen : Symbol(Wagon.numberOxen, Decl(first.js, 4, 28))
117117
>db.foonly : Symbol(Sql.foonly, Decl(first.js, 22, 16))
118-
>db : Symbol(db, Decl(first.js, 42, 3))
118+
>db : Symbol(db, Decl(first.js, 42, 3), Decl(first.js, 42, 19))
119119
>foonly : Symbol(Sql.foonly, Decl(first.js, 22, 16))
120120

121121
// error, can't extend a TS constructor function

tests/baselines/reference/constructorFunctions3.symbols

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,25 @@ i;
1616
>i : Symbol(i, Decl(a.js, 3, 3))
1717

1818
function StaticToo() {
19-
>StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2))
19+
>StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2), Decl(a.js, 9, 1))
2020

2121
this.i = 'more complex'
2222
>i : Symbol(StaticToo.i, Decl(a.js, 7, 22))
2323
}
2424
StaticToo.property = 'yep'
2525
>StaticToo.property : Symbol(StaticToo.property, Decl(a.js, 9, 1))
26-
>StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2))
26+
>StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2), Decl(a.js, 9, 1))
2727
>property : Symbol(StaticToo.property, Decl(a.js, 9, 1))
2828

2929
var s = new StaticToo();
3030
>s : Symbol(s, Decl(a.js, 11, 3))
31-
>StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2))
31+
>StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2), Decl(a.js, 9, 1))
3232

3333
s;
3434
>s : Symbol(s, Decl(a.js, 11, 3))
3535

3636
StaticToo;
37-
>StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2))
37+
>StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2), Decl(a.js, 9, 1))
3838

3939
// Both!
4040
function A () {
@@ -74,12 +74,12 @@ A.t = function g(m) {
7474
>m : Symbol(m, Decl(a.js, 26, 17))
7575
}
7676
var a = new A()
77-
>a : Symbol(a, Decl(a.js, 29, 3))
77+
>a : Symbol(a, Decl(a.js, 29, 3), Decl(a.js, 31, 6))
7878
>A : Symbol(A, Decl(a.js, 13, 10), Decl(a.js, 24, 1))
7979

8080
a.z(3)
8181
>a.z : Symbol(A.z, Decl(a.js, 20, 1))
82-
>a : Symbol(a, Decl(a.js, 29, 3))
82+
>a : Symbol(a, Decl(a.js, 29, 3), Decl(a.js, 31, 6))
8383
>z : Symbol(A.z, Decl(a.js, 20, 1))
8484

8585
A.t(2)
@@ -89,6 +89,6 @@ A.t(2)
8989

9090
a.second = 1
9191
>a.second : Symbol(A.second, Decl(a.js, 17, 14))
92-
>a : Symbol(a, Decl(a.js, 29, 3))
92+
>a : Symbol(a, Decl(a.js, 29, 3), Decl(a.js, 31, 6))
9393
>second : Symbol(A.second, Decl(a.js, 17, 14))
9494

tests/baselines/reference/constructorFunctionsStrict.symbols

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ C.prototype.m = function() {
2020
>y : Symbol(C.y, Decl(a.js, 4, 28))
2121
}
2222
var c = new C(1)
23-
>c : Symbol(c, Decl(a.js, 7, 3))
23+
>c : Symbol(c, Decl(a.js, 7, 3), Decl(a.js, 7, 16))
2424
>C : Symbol(C, Decl(a.js, 0, 0))
2525

2626
c.x = undefined // should error
2727
>c.x : Symbol(C.x, Decl(a.js, 1, 15))
28-
>c : Symbol(c, Decl(a.js, 7, 3))
28+
>c : Symbol(c, Decl(a.js, 7, 3), Decl(a.js, 7, 16))
2929
>x : Symbol(C.x, Decl(a.js, 1, 15))
3030
>undefined : Symbol(undefined)
3131

3232
c.y = undefined // ok
3333
>c.y : Symbol(C.y, Decl(a.js, 4, 28))
34-
>c : Symbol(c, Decl(a.js, 7, 3))
34+
>c : Symbol(c, Decl(a.js, 7, 3), Decl(a.js, 7, 16))
3535
>y : Symbol(C.y, Decl(a.js, 4, 28))
3636
>undefined : Symbol(undefined)
3737

tests/baselines/reference/contextualTypedSpecialAssignment.symbols

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66

77
// property assignment
88
var ns = {}
9-
>ns : Symbol(ns, Decl(test.js, 6, 3))
9+
>ns : Symbol(ns, Decl(test.js, 6, 3), Decl(test.js, 6, 11))
1010

1111
/** @type {DoneStatus} */
1212
ns.x = {
1313
>ns.x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1))
14-
>ns : Symbol(ns, Decl(test.js, 6, 3))
14+
>ns : Symbol(ns, Decl(test.js, 6, 3), Decl(test.js, 6, 11))
1515
>x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1))
1616

1717
status: 'done',
@@ -24,7 +24,7 @@ ns.x = {
2424

2525
ns.x = {
2626
>ns.x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1))
27-
>ns : Symbol(ns, Decl(test.js, 6, 3))
27+
>ns : Symbol(ns, Decl(test.js, 6, 3), Decl(test.js, 6, 11))
2828
>x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1))
2929

3030
status: 'done',
@@ -36,7 +36,7 @@ ns.x = {
3636
}
3737
ns.x
3838
>ns.x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1))
39-
>ns : Symbol(ns, Decl(test.js, 6, 3))
39+
>ns : Symbol(ns, Decl(test.js, 6, 3), Decl(test.js, 6, 11))
4040
>x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1))
4141

4242

tests/baselines/reference/contextualTypedSpecialAssignment.types

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66

77
// property assignment
88
var ns = {}
9-
>ns : { x: { status: "done"; m(n: number): void; }; }
9+
>ns : typeof ns
1010
>{} : {}
1111

1212
/** @type {DoneStatus} */
1313
ns.x = {
1414
>ns.x = { status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
1515
>ns.x : { status: "done"; m(n: number): void; }
16-
>ns : { x: { status: "done"; m(n: number): void; }; }
16+
>ns : typeof ns
1717
>x : { status: "done"; m(n: number): void; }
1818
>{ status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
1919

@@ -29,7 +29,7 @@ ns.x = {
2929
ns.x = {
3030
>ns.x = { status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
3131
>ns.x : { status: "done"; m(n: number): void; }
32-
>ns : { x: { status: "done"; m(n: number): void; }; }
32+
>ns : typeof ns
3333
>x : { status: "done"; m(n: number): void; }
3434
>{ status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
3535

@@ -43,7 +43,7 @@ ns.x = {
4343
}
4444
ns.x
4545
>ns.x : { status: "done"; m(n: number): void; }
46-
>ns : { x: { status: "done"; m(n: number): void; }; }
46+
>ns : typeof ns
4747
>x : { status: "done"; m(n: number): void; }
4848

4949

tests/baselines/reference/expandoFunctionContextualTypes.symbols

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ interface StatelessComponent<P> {
1818
}
1919

2020
const MyComponent: StatelessComponent<MyComponentProps> = () => null as any;
21-
>MyComponent : Symbol(MyComponent, Decl(expandoFunctionContextualTypes.ts, 9, 5))
21+
>MyComponent : Symbol(MyComponent, Decl(expandoFunctionContextualTypes.ts, 9, 5), Decl(expandoFunctionContextualTypes.ts, 9, 76))
2222
>StatelessComponent : Symbol(StatelessComponent, Decl(expandoFunctionContextualTypes.ts, 2, 1))
2323
>MyComponentProps : Symbol(MyComponentProps, Decl(expandoFunctionContextualTypes.ts, 0, 0))
2424

2525
MyComponent.defaultProps = {
2626
>MyComponent.defaultProps : Symbol(StatelessComponent.defaultProps, Decl(expandoFunctionContextualTypes.ts, 5, 12))
27-
>MyComponent : Symbol(MyComponent, Decl(expandoFunctionContextualTypes.ts, 9, 5))
27+
>MyComponent : Symbol(MyComponent, Decl(expandoFunctionContextualTypes.ts, 9, 5), Decl(expandoFunctionContextualTypes.ts, 9, 76))
2828
>defaultProps : Symbol(StatelessComponent.defaultProps, Decl(expandoFunctionContextualTypes.ts, 5, 12))
2929

3030
color: "red"

tests/baselines/reference/expandoFunctionContextualTypesJs.symbols

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
* @type {StatelessComponent<MyComponentProps>}
1010
*/
1111
const MyComponent = () => /* @type {any} */(null);
12-
>MyComponent : Symbol(MyComponent, Decl(input.js, 9, 5))
12+
>MyComponent : Symbol(MyComponent, Decl(input.js, 9, 5), Decl(input.js, 9, 50))
1313

1414
MyComponent.defaultProps = {
1515
>MyComponent.defaultProps : Symbol(defaultProps, Decl(input.js, 4, 23))
16-
>MyComponent : Symbol(MyComponent, Decl(input.js, 9, 5))
16+
>MyComponent : Symbol(MyComponent, Decl(input.js, 9, 5), Decl(input.js, 9, 50))
1717
>defaultProps : Symbol(defaultProps, Decl(input.js, 4, 23))
1818

1919
color: "red"
@@ -22,14 +22,14 @@ MyComponent.defaultProps = {
2222
};
2323

2424
const MyComponent2 = () => null;
25-
>MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5))
25+
>MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5), Decl(input.js, 15, 32))
2626

2727
/**
2828
* @type {MyComponentProps}
2929
*/
3030
MyComponent2.defaultProps = {
3131
>MyComponent2.defaultProps : Symbol(MyComponent2.defaultProps, Decl(input.js, 15, 32))
32-
>MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5))
32+
>MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5), Decl(input.js, 15, 32))
3333
>defaultProps : Symbol(MyComponent2.defaultProps, Decl(input.js, 15, 32))
3434

3535
color: "red"
@@ -41,7 +41,7 @@ MyComponent2.defaultProps = {
4141
*/
4242
const check = MyComponent2;
4343
>check : Symbol(check, Decl(input.js, 27, 5))
44-
>MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5))
44+
>MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5), Decl(input.js, 15, 32))
4545

4646
/**
4747
*

0 commit comments

Comments
 (0)