Skip to content

Commit de4a69c

Browse files
authored
In source files and blocks, bind function declarations before other statements (microsoft#22766)
* Add test case and temporarily disable inference (Inference of class members from this-assignments inside a prototype-assigned function.) * Update baselines * In blocks and source files, bind functions first * Add tests from other bugs * Remove temporary failsafe * Update tests to restore intent and clean up errors * Restore intent even better * Restore intent even better x2 * Add missed baselines
1 parent ee546fb commit de4a69c

File tree

69 files changed

+1336
-994
lines changed

Some content is hidden

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

69 files changed

+1336
-994
lines changed

src/compiler/binder.ts

+18-4
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ namespace ts {
487487
// Depending on what kind of node this is, we may have to adjust the current container
488488
// and block-container. If the current node is a container, then it is automatically
489489
// considered the current block-container as well. Also, for containers that we know
490-
// may contain locals, we proactively initialize the .locals field. We do this because
490+
// may contain locals, we eagerly initialize the .locals field. We do this because
491491
// it's highly likely that the .locals will be needed to place some child in (for example,
492492
// a parameter, or variable declaration).
493493
//
@@ -593,20 +593,25 @@ namespace ts {
593593
}
594594
}
595595

596-
function bindEach(nodes: NodeArray<Node>) {
596+
function bindEachFunctionsFirst(nodes: NodeArray<Node>) {
597+
bindEach(nodes, n => n.kind === SyntaxKind.FunctionDeclaration ? bind(n) : undefined);
598+
bindEach(nodes, n => n.kind !== SyntaxKind.FunctionDeclaration ? bind(n) : undefined);
599+
}
600+
601+
function bindEach(nodes: NodeArray<Node>, bindFunction = bind) {
597602
if (nodes === undefined) {
598603
return;
599604
}
600605

601606
if (skipTransformFlagAggregation) {
602-
forEach(nodes, bind);
607+
forEach(nodes, bindFunction);
603608
}
604609
else {
605610
const savedSubtreeTransformFlags = subtreeTransformFlags;
606611
subtreeTransformFlags = TransformFlags.None;
607612
let nodeArrayFlags = TransformFlags.None;
608613
for (const node of nodes) {
609-
bind(node);
614+
bindFunction(node);
610615
nodeArrayFlags |= node.transformFlags & ~TransformFlags.HasComputedFlags;
611616
}
612617
nodes.transformFlags = nodeArrayFlags | TransformFlags.HasComputedFlags;
@@ -706,6 +711,15 @@ namespace ts {
706711
case SyntaxKind.JSDocTypedefTag:
707712
bindJSDocTypedefTag(<JSDocTypedefTag>node);
708713
break;
714+
// In source files and blocks, bind functions first to match hoisting that occurs at runtime
715+
case SyntaxKind.SourceFile:
716+
bindEachFunctionsFirst((node as SourceFile).statements);
717+
bind((node as SourceFile).endOfFileToken);
718+
break;
719+
case SyntaxKind.Block:
720+
case SyntaxKind.ModuleBlock:
721+
bindEachFunctionsFirst((node as Block).statements);
722+
break;
709723
default:
710724
bindEachChild(node);
711725
break;

tests/baselines/reference/ModuleAndFunctionWithSameNameAndCommonRoot.symbols

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ module B {
3131
>B : Symbol(B, Decl(simple.ts, 0, 0))
3232

3333
export module Point {
34-
>Point : Symbol(Point, Decl(simple.ts, 0, 10), Decl(simple.ts, 4, 5))
34+
>Point : Symbol(Point, Decl(simple.ts, 4, 5), Decl(simple.ts, 0, 10))
3535

3636
export var Origin = { x: 0, y: 0 };
3737
>Origin : Symbol(Origin, Decl(simple.ts, 3, 18))
@@ -41,7 +41,7 @@ module B {
4141

4242
// duplicate identifier error
4343
export function Point() {
44-
>Point : Symbol(Point, Decl(simple.ts, 0, 10), Decl(simple.ts, 4, 5))
44+
>Point : Symbol(Point, Decl(simple.ts, 4, 5), Decl(simple.ts, 0, 10))
4545

4646
return { x: 0, y: 0 };
4747
>x : Symbol(x, Decl(simple.ts, 8, 16))
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
=== tests/cases/compiler/ambientFundule.ts ===
22
declare function f();
3-
>f : Symbol(f, Decl(ambientFundule.ts, 0, 0), Decl(ambientFundule.ts, 0, 21), Decl(ambientFundule.ts, 1, 26))
3+
>f : Symbol(f, Decl(ambientFundule.ts, 0, 0), Decl(ambientFundule.ts, 1, 26), Decl(ambientFundule.ts, 0, 21))
44

55
declare module f { var x }
6-
>f : Symbol(f, Decl(ambientFundule.ts, 0, 0), Decl(ambientFundule.ts, 0, 21), Decl(ambientFundule.ts, 1, 26))
6+
>f : Symbol(f, Decl(ambientFundule.ts, 0, 0), Decl(ambientFundule.ts, 1, 26), Decl(ambientFundule.ts, 0, 21))
77
>x : Symbol(x, Decl(ambientFundule.ts, 1, 22))
88

99
declare function f(x);
10-
>f : Symbol(f, Decl(ambientFundule.ts, 0, 0), Decl(ambientFundule.ts, 0, 21), Decl(ambientFundule.ts, 1, 26))
10+
>f : Symbol(f, Decl(ambientFundule.ts, 0, 0), Decl(ambientFundule.ts, 1, 26), Decl(ambientFundule.ts, 0, 21))
1111
>x : Symbol(x, Decl(ambientFundule.ts, 2, 19))
1212

tests/baselines/reference/augmentedTypesModules.symbols

+8-8
Original file line numberDiff line numberDiff line change
@@ -42,24 +42,24 @@ var m1d = 1; // error
4242

4343
// module then function
4444
module m2 { }
45-
>m2 : Symbol(m2, Decl(augmentedTypesModules.ts, 18, 12), Decl(augmentedTypesModules.ts, 21, 13))
45+
>m2 : Symbol(m2, Decl(augmentedTypesModules.ts, 21, 13), Decl(augmentedTypesModules.ts, 18, 12))
4646

4747
function m2() { }; // ok since the module is not instantiated
48-
>m2 : Symbol(m2, Decl(augmentedTypesModules.ts, 18, 12), Decl(augmentedTypesModules.ts, 21, 13))
48+
>m2 : Symbol(m2, Decl(augmentedTypesModules.ts, 21, 13), Decl(augmentedTypesModules.ts, 18, 12))
4949

5050
module m2a { var y = 2; }
51-
>m2a : Symbol(m2a, Decl(augmentedTypesModules.ts, 22, 18), Decl(augmentedTypesModules.ts, 24, 25))
51+
>m2a : Symbol(m2a, Decl(augmentedTypesModules.ts, 24, 25), Decl(augmentedTypesModules.ts, 22, 18))
5252
>y : Symbol(y, Decl(augmentedTypesModules.ts, 24, 16))
5353

5454
function m2a() { }; // error since the module is instantiated
55-
>m2a : Symbol(m2a, Decl(augmentedTypesModules.ts, 22, 18), Decl(augmentedTypesModules.ts, 24, 25))
55+
>m2a : Symbol(m2a, Decl(augmentedTypesModules.ts, 24, 25), Decl(augmentedTypesModules.ts, 22, 18))
5656

5757
module m2b { export var y = 2; }
58-
>m2b : Symbol(m2b, Decl(augmentedTypesModules.ts, 25, 19), Decl(augmentedTypesModules.ts, 27, 32))
58+
>m2b : Symbol(m2b, Decl(augmentedTypesModules.ts, 27, 32), Decl(augmentedTypesModules.ts, 25, 19))
5959
>y : Symbol(y, Decl(augmentedTypesModules.ts, 27, 23))
6060

6161
function m2b() { }; // error since the module is instantiated
62-
>m2b : Symbol(m2b, Decl(augmentedTypesModules.ts, 25, 19), Decl(augmentedTypesModules.ts, 27, 32))
62+
>m2b : Symbol(m2b, Decl(augmentedTypesModules.ts, 27, 32), Decl(augmentedTypesModules.ts, 25, 19))
6363

6464
// should be errors to have function first
6565
function m2c() { };
@@ -70,10 +70,10 @@ module m2c { export var y = 2; }
7070
>y : Symbol(y, Decl(augmentedTypesModules.ts, 32, 23))
7171

7272
module m2d { }
73-
>m2d : Symbol(m2d, Decl(augmentedTypesModules.ts, 32, 32), Decl(augmentedTypesModules.ts, 34, 14))
73+
>m2d : Symbol(m2d, Decl(augmentedTypesModules.ts, 34, 14), Decl(augmentedTypesModules.ts, 32, 32))
7474

7575
declare function m2d(): void;
76-
>m2d : Symbol(m2d, Decl(augmentedTypesModules.ts, 32, 32), Decl(augmentedTypesModules.ts, 34, 14))
76+
>m2d : Symbol(m2d, Decl(augmentedTypesModules.ts, 34, 14), Decl(augmentedTypesModules.ts, 32, 32))
7777

7878
declare function m2e(): void;
7979
>m2e : Symbol(m2e, Decl(augmentedTypesModules.ts, 35, 29), Decl(augmentedTypesModules.ts, 37, 29))

tests/baselines/reference/augmentedTypesModules2.symbols

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
=== tests/cases/compiler/augmentedTypesModules2.ts ===
22
// module then function
33
module m2 { }
4-
>m2 : Symbol(m2, Decl(augmentedTypesModules2.ts, 0, 0), Decl(augmentedTypesModules2.ts, 1, 13))
4+
>m2 : Symbol(m2, Decl(augmentedTypesModules2.ts, 1, 13), Decl(augmentedTypesModules2.ts, 0, 0))
55

66
function m2() { }; // ok since the module is not instantiated
7-
>m2 : Symbol(m2, Decl(augmentedTypesModules2.ts, 0, 0), Decl(augmentedTypesModules2.ts, 1, 13))
7+
>m2 : Symbol(m2, Decl(augmentedTypesModules2.ts, 1, 13), Decl(augmentedTypesModules2.ts, 0, 0))
88

99
module m2a { var y = 2; }
10-
>m2a : Symbol(m2a, Decl(augmentedTypesModules2.ts, 2, 18), Decl(augmentedTypesModules2.ts, 4, 25))
10+
>m2a : Symbol(m2a, Decl(augmentedTypesModules2.ts, 4, 25), Decl(augmentedTypesModules2.ts, 2, 18))
1111
>y : Symbol(y, Decl(augmentedTypesModules2.ts, 4, 16))
1212

1313
function m2a() { }; // error since the module is instantiated
14-
>m2a : Symbol(m2a, Decl(augmentedTypesModules2.ts, 2, 18), Decl(augmentedTypesModules2.ts, 4, 25))
14+
>m2a : Symbol(m2a, Decl(augmentedTypesModules2.ts, 4, 25), Decl(augmentedTypesModules2.ts, 2, 18))
1515

1616
module m2b { export var y = 2; }
17-
>m2b : Symbol(m2b, Decl(augmentedTypesModules2.ts, 5, 19), Decl(augmentedTypesModules2.ts, 7, 32))
17+
>m2b : Symbol(m2b, Decl(augmentedTypesModules2.ts, 7, 32), Decl(augmentedTypesModules2.ts, 5, 19))
1818
>y : Symbol(y, Decl(augmentedTypesModules2.ts, 7, 23))
1919

2020
function m2b() { }; // error since the module is instantiated
21-
>m2b : Symbol(m2b, Decl(augmentedTypesModules2.ts, 5, 19), Decl(augmentedTypesModules2.ts, 7, 32))
21+
>m2b : Symbol(m2b, Decl(augmentedTypesModules2.ts, 7, 32), Decl(augmentedTypesModules2.ts, 5, 19))
2222

2323
function m2c() { };
2424
>m2c : Symbol(m2c, Decl(augmentedTypesModules2.ts, 8, 19), Decl(augmentedTypesModules2.ts, 10, 19))
@@ -28,17 +28,17 @@ module m2c { export var y = 2; }
2828
>y : Symbol(y, Decl(augmentedTypesModules2.ts, 11, 23))
2929

3030
module m2cc { export var y = 2; }
31-
>m2cc : Symbol(m2cc, Decl(augmentedTypesModules2.ts, 11, 32), Decl(augmentedTypesModules2.ts, 13, 33))
31+
>m2cc : Symbol(m2cc, Decl(augmentedTypesModules2.ts, 13, 33), Decl(augmentedTypesModules2.ts, 11, 32))
3232
>y : Symbol(y, Decl(augmentedTypesModules2.ts, 13, 24))
3333

3434
function m2cc() { }; // error to have module first
35-
>m2cc : Symbol(m2cc, Decl(augmentedTypesModules2.ts, 11, 32), Decl(augmentedTypesModules2.ts, 13, 33))
35+
>m2cc : Symbol(m2cc, Decl(augmentedTypesModules2.ts, 13, 33), Decl(augmentedTypesModules2.ts, 11, 32))
3636

3737
module m2d { }
38-
>m2d : Symbol(m2d, Decl(augmentedTypesModules2.ts, 14, 20), Decl(augmentedTypesModules2.ts, 16, 14))
38+
>m2d : Symbol(m2d, Decl(augmentedTypesModules2.ts, 16, 14), Decl(augmentedTypesModules2.ts, 14, 20))
3939

4040
declare function m2d(): void;
41-
>m2d : Symbol(m2d, Decl(augmentedTypesModules2.ts, 14, 20), Decl(augmentedTypesModules2.ts, 16, 14))
41+
>m2d : Symbol(m2d, Decl(augmentedTypesModules2.ts, 16, 14), Decl(augmentedTypesModules2.ts, 14, 20))
4242

4343
declare function m2e(): void;
4444
>m2e : Symbol(m2e, Decl(augmentedTypesModules2.ts, 17, 29), Decl(augmentedTypesModules2.ts, 19, 29))

tests/baselines/reference/callOverloads1.errors.txt

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
tests/cases/compiler/callOverloads1.ts(1,7): error TS2300: Duplicate identifier 'Foo'.
22
tests/cases/compiler/callOverloads1.ts(9,10): error TS2300: Duplicate identifier 'Foo'.
33
tests/cases/compiler/callOverloads1.ts(9,10): error TS2391: Function implementation is missing or not immediately following the declaration.
4-
tests/cases/compiler/callOverloads1.ts(17,1): error TS2348: Value of type 'typeof Foo' is not callable. Did you mean to include 'new'?
4+
tests/cases/compiler/callOverloads1.ts(13,10): error TS2350: Only a void function can be called with the 'new' keyword.
5+
tests/cases/compiler/callOverloads1.ts(13,10): error TS2554: Expected 0 arguments, but got 1.
56

67

7-
==== tests/cases/compiler/callOverloads1.ts (4 errors) ====
8+
==== tests/cases/compiler/callOverloads1.ts (5 errors) ====
89
class Foo { // error
910
~~~
1011
!!! error TS2300: Duplicate identifier 'Foo'.
@@ -24,9 +25,11 @@ tests/cases/compiler/callOverloads1.ts(17,1): error TS2348: Value of type 'typeo
2425
function F1(a:any) { return a;}
2526

2627
var f1 = new Foo("hey");
28+
~~~~~~~~~~~~~~
29+
!!! error TS2350: Only a void function can be called with the 'new' keyword.
30+
~~~~~~~~~~~~~~
31+
!!! error TS2554: Expected 0 arguments, but got 1.
2732

2833

2934
f1.bar1();
30-
Foo();
31-
~~~~~
32-
!!! error TS2348: Value of type 'typeof Foo' is not callable. Did you mean to include 'new'?
35+
Foo();

tests/baselines/reference/callOverloads1.symbols

+2-4
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,12 @@ function F1(a:any) { return a;}
2626

2727
var f1 = new Foo("hey");
2828
>f1 : Symbol(f1, Decl(callOverloads1.ts, 12, 3))
29-
>Foo : Symbol(Foo, Decl(callOverloads1.ts, 0, 0))
29+
>Foo : Symbol(Foo, Decl(callOverloads1.ts, 6, 1))
3030

3131

3232
f1.bar1();
33-
>f1.bar1 : Symbol(Foo.bar1, Decl(callOverloads1.ts, 0, 11))
3433
>f1 : Symbol(f1, Decl(callOverloads1.ts, 12, 3))
35-
>bar1 : Symbol(Foo.bar1, Decl(callOverloads1.ts, 0, 11))
3634

3735
Foo();
38-
>Foo : Symbol(Foo, Decl(callOverloads1.ts, 0, 0))
36+
>Foo : Symbol(Foo, Decl(callOverloads1.ts, 6, 1))
3937

tests/baselines/reference/callOverloads1.types

+8-8
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,19 @@ function F1(a:any) { return a;}
2525
>a : any
2626

2727
var f1 = new Foo("hey");
28-
>f1 : Foo
29-
>new Foo("hey") : Foo
30-
>Foo : typeof Foo
28+
>f1 : any
29+
>new Foo("hey") : any
30+
>Foo : () => any
3131
>"hey" : "hey"
3232

3333

3434
f1.bar1();
35-
>f1.bar1() : void
36-
>f1.bar1 : () => void
37-
>f1 : Foo
38-
>bar1 : () => void
35+
>f1.bar1() : any
36+
>f1.bar1 : any
37+
>f1 : any
38+
>bar1 : any
3939

4040
Foo();
4141
>Foo() : any
42-
>Foo : typeof Foo
42+
>Foo : () => any
4343

tests/baselines/reference/callOverloads2.errors.txt

+7-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ tests/cases/compiler/callOverloads2.ts(11,10): error TS2389: Function implementa
44
tests/cases/compiler/callOverloads2.ts(11,10): error TS2393: Duplicate function implementation.
55
tests/cases/compiler/callOverloads2.ts(12,10): error TS2393: Duplicate function implementation.
66
tests/cases/compiler/callOverloads2.ts(14,10): error TS2391: Function implementation is missing or not immediately following the declaration.
7-
tests/cases/compiler/callOverloads2.ts(22,1): error TS2348: Value of type 'typeof Foo' is not callable. Did you mean to include 'new'?
7+
tests/cases/compiler/callOverloads2.ts(18,10): error TS2350: Only a void function can be called with the 'new' keyword.
8+
tests/cases/compiler/callOverloads2.ts(18,10): error TS2554: Expected 0 arguments, but got 1.
89

910

10-
==== tests/cases/compiler/callOverloads2.ts (7 errors) ====
11+
==== tests/cases/compiler/callOverloads2.ts (8 errors) ====
1112
class Foo { // error
1213
~~~
1314
!!! error TS2300: Duplicate identifier 'Foo'.
@@ -38,10 +39,12 @@ tests/cases/compiler/callOverloads2.ts(22,1): error TS2348: Value of type 'typeo
3839
declare function Gar(s:String); // expect no error
3940

4041
var f1 = new Foo("hey");
42+
~~~~~~~~~~~~~~
43+
!!! error TS2350: Only a void function can be called with the 'new' keyword.
44+
~~~~~~~~~~~~~~
45+
!!! error TS2554: Expected 0 arguments, but got 1.
4146

4247

4348
f1.bar1();
4449
Foo();
45-
~~~~~
46-
!!! error TS2348: Value of type 'typeof Foo' is not callable. Did you mean to include 'new'?
4750

tests/baselines/reference/callOverloads2.symbols

+2-4
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,12 @@ declare function Gar(s:String); // expect no error
3636

3737
var f1 = new Foo("hey");
3838
>f1 : Symbol(f1, Decl(callOverloads2.ts, 17, 3))
39-
>Foo : Symbol(Foo, Decl(callOverloads2.ts, 0, 0))
39+
>Foo : Symbol(Foo, Decl(callOverloads2.ts, 6, 1))
4040

4141

4242
f1.bar1();
43-
>f1.bar1 : Symbol(Foo.bar1, Decl(callOverloads2.ts, 0, 11))
4443
>f1 : Symbol(f1, Decl(callOverloads2.ts, 17, 3))
45-
>bar1 : Symbol(Foo.bar1, Decl(callOverloads2.ts, 0, 11))
4644

4745
Foo();
48-
>Foo : Symbol(Foo, Decl(callOverloads2.ts, 0, 0))
46+
>Foo : Symbol(Foo, Decl(callOverloads2.ts, 6, 1))
4947

tests/baselines/reference/callOverloads2.types

+8-8
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,19 @@ declare function Gar(s:String); // expect no error
3535
>String : String
3636

3737
var f1 = new Foo("hey");
38-
>f1 : Foo
39-
>new Foo("hey") : Foo
40-
>Foo : typeof Foo
38+
>f1 : any
39+
>new Foo("hey") : any
40+
>Foo : () => any
4141
>"hey" : "hey"
4242

4343

4444
f1.bar1();
45-
>f1.bar1() : void
46-
>f1.bar1 : () => void
47-
>f1 : Foo
48-
>bar1 : () => void
45+
>f1.bar1() : any
46+
>f1.bar1 : any
47+
>f1 : any
48+
>bar1 : any
4949

5050
Foo();
5151
>Foo() : any
52-
>Foo : typeof Foo
52+
>Foo : () => any
5353

0 commit comments

Comments
 (0)