Skip to content

Commit 9967946

Browse files
committed
Fake up a namespace enclosing declaration when generating expando namespace members (microsoft#31971)
* Fake up a namespace enclosing declaration when generating expando namespace members * Fix microsoft#31676
1 parent 7f47a08 commit 9967946

5 files changed

+303
-3
lines changed

src/compiler/transformers/declarations.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -1036,19 +1036,25 @@ namespace ts {
10361036
/*body*/ undefined
10371037
));
10381038
if (clean && resolver.isExpandoFunctionDeclaration(input)) {
1039-
const declarations = mapDefined(resolver.getPropertiesOfContainerFunction(input), p => {
1039+
const props = resolver.getPropertiesOfContainerFunction(input);
1040+
const fakespace = createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, clean.name || createIdentifier("_default"), createModuleBlock([]), NodeFlags.Namespace);
1041+
fakespace.flags ^= NodeFlags.Synthesized; // unset synthesized so it is usable as an enclosing declaration
1042+
fakespace.parent = enclosingDeclaration as SourceFile | NamespaceDeclaration;
1043+
fakespace.locals = createSymbolTable(props);
1044+
fakespace.symbol = props[0].parent!;
1045+
const declarations = mapDefined(props, p => {
10401046
if (!isPropertyAccessExpression(p.valueDeclaration)) {
10411047
return undefined;
10421048
}
10431049
getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration);
1044-
const type = resolver.createTypeOfDeclaration(p.valueDeclaration, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker);
1050+
const type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace, declarationEmitNodeBuilderFlags, symbolTracker);
10451051
getSymbolAccessibilityDiagnostic = oldDiag;
10461052
const varDecl = createVariableDeclaration(unescapeLeadingUnderscores(p.escapedName), type, /*initializer*/ undefined);
10471053
return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([varDecl]));
10481054
});
10491055
const namespaceDecl = createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input, isPrivate), input.name!, createModuleBlock(declarations), NodeFlags.Namespace);
10501056

1051-
if (!hasModifier(clean, ModifierFlags.ExportDefault)) {
1057+
if (!hasModifier(clean, ModifierFlags.Default)) {
10521058
return [clean, namespaceDecl];
10531059
}
10541060

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//// [tests/cases/compiler/declarationEmitDefaultExportWithStaticAssignment.ts] ////
2+
3+
//// [foo.ts]
4+
export class Foo {}
5+
6+
//// [index1.ts]
7+
import {Foo} from './foo';
8+
export default function Example() {}
9+
Example.Foo = Foo
10+
11+
//// [index2.ts]
12+
import {Foo} from './foo';
13+
export {Foo};
14+
export default function Example() {}
15+
Example.Foo = Foo
16+
17+
//// [index3.ts]
18+
export class Bar {}
19+
export default function Example() {}
20+
21+
Example.Bar = Bar
22+
23+
//// [index4.ts]
24+
function A() { }
25+
26+
function B() { }
27+
28+
export function C() {
29+
return null;
30+
}
31+
32+
C.A = A;
33+
C.B = B;
34+
35+
//// [foo.js]
36+
"use strict";
37+
exports.__esModule = true;
38+
var Foo = /** @class */ (function () {
39+
function Foo() {
40+
}
41+
return Foo;
42+
}());
43+
exports.Foo = Foo;
44+
//// [index1.js]
45+
"use strict";
46+
exports.__esModule = true;
47+
var foo_1 = require("./foo");
48+
function Example() { }
49+
exports["default"] = Example;
50+
Example.Foo = foo_1.Foo;
51+
//// [index2.js]
52+
"use strict";
53+
exports.__esModule = true;
54+
var foo_1 = require("./foo");
55+
exports.Foo = foo_1.Foo;
56+
function Example() { }
57+
exports["default"] = Example;
58+
Example.Foo = foo_1.Foo;
59+
//// [index3.js]
60+
"use strict";
61+
exports.__esModule = true;
62+
var Bar = /** @class */ (function () {
63+
function Bar() {
64+
}
65+
return Bar;
66+
}());
67+
exports.Bar = Bar;
68+
function Example() { }
69+
exports["default"] = Example;
70+
Example.Bar = Bar;
71+
//// [index4.js]
72+
"use strict";
73+
exports.__esModule = true;
74+
function A() { }
75+
function B() { }
76+
function C() {
77+
return null;
78+
}
79+
exports.C = C;
80+
C.A = A;
81+
C.B = B;
82+
83+
84+
//// [foo.d.ts]
85+
export declare class Foo {
86+
}
87+
//// [index1.d.ts]
88+
declare function Example(): void;
89+
declare namespace Example {
90+
var Foo: typeof import("./foo").Foo;
91+
}
92+
export default Example;
93+
//// [index2.d.ts]
94+
import { Foo } from './foo';
95+
export { Foo };
96+
declare function Example(): void;
97+
declare namespace Example {
98+
var Foo: typeof import("./foo").Foo;
99+
}
100+
export default Example;
101+
//// [index3.d.ts]
102+
export declare class Bar {
103+
}
104+
declare function Example(): void;
105+
declare namespace Example {
106+
var Bar: typeof import("./index3").Bar;
107+
}
108+
export default Example;
109+
//// [index4.d.ts]
110+
export declare function C(): any;
111+
export declare namespace C {
112+
var A: () => void;
113+
var B: () => void;
114+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
=== tests/cases/compiler/foo.ts ===
2+
export class Foo {}
3+
>Foo : Symbol(Foo, Decl(foo.ts, 0, 0))
4+
5+
=== tests/cases/compiler/index1.ts ===
6+
import {Foo} from './foo';
7+
>Foo : Symbol(Foo, Decl(index1.ts, 0, 8))
8+
9+
export default function Example() {}
10+
>Example : Symbol(Example, Decl(index1.ts, 0, 26), Decl(index1.ts, 1, 36))
11+
12+
Example.Foo = Foo
13+
>Example.Foo : Symbol(Example.Foo, Decl(index1.ts, 1, 36))
14+
>Example : Symbol(Example, Decl(index1.ts, 0, 26), Decl(index1.ts, 1, 36))
15+
>Foo : Symbol(Example.Foo, Decl(index1.ts, 1, 36))
16+
>Foo : Symbol(Foo, Decl(index1.ts, 0, 8))
17+
18+
=== tests/cases/compiler/index2.ts ===
19+
import {Foo} from './foo';
20+
>Foo : Symbol(Foo, Decl(index2.ts, 0, 8))
21+
22+
export {Foo};
23+
>Foo : Symbol(Foo, Decl(index2.ts, 1, 8))
24+
25+
export default function Example() {}
26+
>Example : Symbol(Example, Decl(index2.ts, 1, 13), Decl(index2.ts, 2, 36))
27+
28+
Example.Foo = Foo
29+
>Example.Foo : Symbol(Example.Foo, Decl(index2.ts, 2, 36))
30+
>Example : Symbol(Example, Decl(index2.ts, 1, 13), Decl(index2.ts, 2, 36))
31+
>Foo : Symbol(Example.Foo, Decl(index2.ts, 2, 36))
32+
>Foo : Symbol(Foo, Decl(index2.ts, 0, 8))
33+
34+
=== tests/cases/compiler/index3.ts ===
35+
export class Bar {}
36+
>Bar : Symbol(Bar, Decl(index3.ts, 0, 0))
37+
38+
export default function Example() {}
39+
>Example : Symbol(Example, Decl(index3.ts, 0, 19), Decl(index3.ts, 1, 36))
40+
41+
Example.Bar = Bar
42+
>Example.Bar : Symbol(Example.Bar, Decl(index3.ts, 1, 36))
43+
>Example : Symbol(Example, Decl(index3.ts, 0, 19), Decl(index3.ts, 1, 36))
44+
>Bar : Symbol(Example.Bar, Decl(index3.ts, 1, 36))
45+
>Bar : Symbol(Bar, Decl(index3.ts, 0, 0))
46+
47+
=== tests/cases/compiler/index4.ts ===
48+
function A() { }
49+
>A : Symbol(A, Decl(index4.ts, 0, 0))
50+
51+
function B() { }
52+
>B : Symbol(B, Decl(index4.ts, 0, 17))
53+
54+
export function C() {
55+
>C : Symbol(C, Decl(index4.ts, 2, 16), Decl(index4.ts, 6, 1))
56+
57+
return null;
58+
}
59+
60+
C.A = A;
61+
>C.A : Symbol(C.A, Decl(index4.ts, 6, 1))
62+
>C : Symbol(C, Decl(index4.ts, 2, 16), Decl(index4.ts, 6, 1))
63+
>A : Symbol(C.A, Decl(index4.ts, 6, 1))
64+
>A : Symbol(A, Decl(index4.ts, 0, 0))
65+
66+
C.B = B;
67+
>C.B : Symbol(C.B, Decl(index4.ts, 8, 8))
68+
>C : Symbol(C, Decl(index4.ts, 2, 16), Decl(index4.ts, 6, 1))
69+
>B : Symbol(C.B, Decl(index4.ts, 8, 8))
70+
>B : Symbol(B, Decl(index4.ts, 0, 17))
71+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
=== tests/cases/compiler/foo.ts ===
2+
export class Foo {}
3+
>Foo : Foo
4+
5+
=== tests/cases/compiler/index1.ts ===
6+
import {Foo} from './foo';
7+
>Foo : typeof Foo
8+
9+
export default function Example() {}
10+
>Example : typeof Example
11+
12+
Example.Foo = Foo
13+
>Example.Foo = Foo : typeof Foo
14+
>Example.Foo : typeof Foo
15+
>Example : typeof Example
16+
>Foo : typeof Foo
17+
>Foo : typeof Foo
18+
19+
=== tests/cases/compiler/index2.ts ===
20+
import {Foo} from './foo';
21+
>Foo : typeof Foo
22+
23+
export {Foo};
24+
>Foo : typeof Foo
25+
26+
export default function Example() {}
27+
>Example : typeof Example
28+
29+
Example.Foo = Foo
30+
>Example.Foo = Foo : typeof Foo
31+
>Example.Foo : typeof Foo
32+
>Example : typeof Example
33+
>Foo : typeof Foo
34+
>Foo : typeof Foo
35+
36+
=== tests/cases/compiler/index3.ts ===
37+
export class Bar {}
38+
>Bar : Bar
39+
40+
export default function Example() {}
41+
>Example : typeof Example
42+
43+
Example.Bar = Bar
44+
>Example.Bar = Bar : typeof Bar
45+
>Example.Bar : typeof Bar
46+
>Example : typeof Example
47+
>Bar : typeof Bar
48+
>Bar : typeof Bar
49+
50+
=== tests/cases/compiler/index4.ts ===
51+
function A() { }
52+
>A : () => void
53+
54+
function B() { }
55+
>B : () => void
56+
57+
export function C() {
58+
>C : typeof C
59+
60+
return null;
61+
>null : null
62+
}
63+
64+
C.A = A;
65+
>C.A = A : () => void
66+
>C.A : () => void
67+
>C : typeof C
68+
>A : () => void
69+
>A : () => void
70+
71+
C.B = B;
72+
>C.B = B : () => void
73+
>C.B : () => void
74+
>C : typeof C
75+
>B : () => void
76+
>B : () => void
77+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// @declaration: true
2+
// @filename: foo.ts
3+
export class Foo {}
4+
5+
// @filename: index1.ts
6+
import {Foo} from './foo';
7+
export default function Example() {}
8+
Example.Foo = Foo
9+
10+
// @filename: index2.ts
11+
import {Foo} from './foo';
12+
export {Foo};
13+
export default function Example() {}
14+
Example.Foo = Foo
15+
16+
// @filename: index3.ts
17+
export class Bar {}
18+
export default function Example() {}
19+
20+
Example.Bar = Bar
21+
22+
// @filename: index4.ts
23+
function A() { }
24+
25+
function B() { }
26+
27+
export function C() {
28+
return null;
29+
}
30+
31+
C.A = A;
32+
C.B = B;

0 commit comments

Comments
 (0)