Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port to release-3.5: Fake up a namespace enclosing declaration when generating expando nam… #32032

Merged
merged 1 commit into from Jul 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/compiler/transformers/declarations.ts
Expand Up @@ -1036,19 +1036,25 @@ namespace ts {
/*body*/ undefined
));
if (clean && resolver.isExpandoFunctionDeclaration(input)) {
const declarations = mapDefined(resolver.getPropertiesOfContainerFunction(input), p => {
const props = resolver.getPropertiesOfContainerFunction(input);
const fakespace = createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, clean.name || createIdentifier("_default"), createModuleBlock([]), NodeFlags.Namespace);
fakespace.flags ^= NodeFlags.Synthesized; // unset synthesized so it is usable as an enclosing declaration
fakespace.parent = enclosingDeclaration as SourceFile | NamespaceDeclaration;
fakespace.locals = createSymbolTable(props);
fakespace.symbol = props[0].parent!;
const declarations = mapDefined(props, p => {
if (!isPropertyAccessExpression(p.valueDeclaration)) {
return undefined;
}
getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration);
const type = resolver.createTypeOfDeclaration(p.valueDeclaration, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker);
const type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace, declarationEmitNodeBuilderFlags, symbolTracker);
getSymbolAccessibilityDiagnostic = oldDiag;
const varDecl = createVariableDeclaration(unescapeLeadingUnderscores(p.escapedName), type, /*initializer*/ undefined);
return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([varDecl]));
});
const namespaceDecl = createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input, isPrivate), input.name!, createModuleBlock(declarations), NodeFlags.Namespace);

if (!hasModifier(clean, ModifierFlags.ExportDefault)) {
if (!hasModifier(clean, ModifierFlags.Default)) {
return [clean, namespaceDecl];
}

Expand Down
@@ -0,0 +1,114 @@
//// [tests/cases/compiler/declarationEmitDefaultExportWithStaticAssignment.ts] ////

//// [foo.ts]
export class Foo {}

//// [index1.ts]
import {Foo} from './foo';
export default function Example() {}
Example.Foo = Foo

//// [index2.ts]
import {Foo} from './foo';
export {Foo};
export default function Example() {}
Example.Foo = Foo

//// [index3.ts]
export class Bar {}
export default function Example() {}

Example.Bar = Bar

//// [index4.ts]
function A() { }

function B() { }

export function C() {
return null;
}

C.A = A;
C.B = B;

//// [foo.js]
"use strict";
exports.__esModule = true;
var Foo = /** @class */ (function () {
function Foo() {
}
return Foo;
}());
exports.Foo = Foo;
//// [index1.js]
"use strict";
exports.__esModule = true;
var foo_1 = require("./foo");
function Example() { }
exports["default"] = Example;
Example.Foo = foo_1.Foo;
//// [index2.js]
"use strict";
exports.__esModule = true;
var foo_1 = require("./foo");
exports.Foo = foo_1.Foo;
function Example() { }
exports["default"] = Example;
Example.Foo = foo_1.Foo;
//// [index3.js]
"use strict";
exports.__esModule = true;
var Bar = /** @class */ (function () {
function Bar() {
}
return Bar;
}());
exports.Bar = Bar;
function Example() { }
exports["default"] = Example;
Example.Bar = Bar;
//// [index4.js]
"use strict";
exports.__esModule = true;
function A() { }
function B() { }
function C() {
return null;
}
exports.C = C;
C.A = A;
C.B = B;


//// [foo.d.ts]
export declare class Foo {
}
//// [index1.d.ts]
declare function Example(): void;
declare namespace Example {
var Foo: typeof import("./foo").Foo;
}
export default Example;
//// [index2.d.ts]
import { Foo } from './foo';
export { Foo };
declare function Example(): void;
declare namespace Example {
var Foo: typeof import("./foo").Foo;
}
export default Example;
//// [index3.d.ts]
export declare class Bar {
}
declare function Example(): void;
declare namespace Example {
var Bar: typeof import("./index3").Bar;
}
export default Example;
//// [index4.d.ts]
export declare function C(): any;
export declare namespace C {
var A: () => void;
var B: () => void;
}
@@ -0,0 +1,71 @@
=== tests/cases/compiler/foo.ts ===
export class Foo {}
>Foo : Symbol(Foo, Decl(foo.ts, 0, 0))

=== tests/cases/compiler/index1.ts ===
import {Foo} from './foo';
>Foo : Symbol(Foo, Decl(index1.ts, 0, 8))

export default function Example() {}
>Example : Symbol(Example, Decl(index1.ts, 0, 26), Decl(index1.ts, 1, 36))

Example.Foo = Foo
>Example.Foo : Symbol(Example.Foo, Decl(index1.ts, 1, 36))
>Example : Symbol(Example, Decl(index1.ts, 0, 26), Decl(index1.ts, 1, 36))
>Foo : Symbol(Example.Foo, Decl(index1.ts, 1, 36))
>Foo : Symbol(Foo, Decl(index1.ts, 0, 8))

=== tests/cases/compiler/index2.ts ===
import {Foo} from './foo';
>Foo : Symbol(Foo, Decl(index2.ts, 0, 8))

export {Foo};
>Foo : Symbol(Foo, Decl(index2.ts, 1, 8))

export default function Example() {}
>Example : Symbol(Example, Decl(index2.ts, 1, 13), Decl(index2.ts, 2, 36))

Example.Foo = Foo
>Example.Foo : Symbol(Example.Foo, Decl(index2.ts, 2, 36))
>Example : Symbol(Example, Decl(index2.ts, 1, 13), Decl(index2.ts, 2, 36))
>Foo : Symbol(Example.Foo, Decl(index2.ts, 2, 36))
>Foo : Symbol(Foo, Decl(index2.ts, 0, 8))

=== tests/cases/compiler/index3.ts ===
export class Bar {}
>Bar : Symbol(Bar, Decl(index3.ts, 0, 0))

export default function Example() {}
>Example : Symbol(Example, Decl(index3.ts, 0, 19), Decl(index3.ts, 1, 36))

Example.Bar = Bar
>Example.Bar : Symbol(Example.Bar, Decl(index3.ts, 1, 36))
>Example : Symbol(Example, Decl(index3.ts, 0, 19), Decl(index3.ts, 1, 36))
>Bar : Symbol(Example.Bar, Decl(index3.ts, 1, 36))
>Bar : Symbol(Bar, Decl(index3.ts, 0, 0))

=== tests/cases/compiler/index4.ts ===
function A() { }
>A : Symbol(A, Decl(index4.ts, 0, 0))

function B() { }
>B : Symbol(B, Decl(index4.ts, 0, 17))

export function C() {
>C : Symbol(C, Decl(index4.ts, 2, 16), Decl(index4.ts, 6, 1))

return null;
}

C.A = A;
>C.A : Symbol(C.A, Decl(index4.ts, 6, 1))
>C : Symbol(C, Decl(index4.ts, 2, 16), Decl(index4.ts, 6, 1))
>A : Symbol(C.A, Decl(index4.ts, 6, 1))
>A : Symbol(A, Decl(index4.ts, 0, 0))

C.B = B;
>C.B : Symbol(C.B, Decl(index4.ts, 8, 8))
>C : Symbol(C, Decl(index4.ts, 2, 16), Decl(index4.ts, 6, 1))
>B : Symbol(C.B, Decl(index4.ts, 8, 8))
>B : Symbol(B, Decl(index4.ts, 0, 17))

@@ -0,0 +1,77 @@
=== tests/cases/compiler/foo.ts ===
export class Foo {}
>Foo : Foo

=== tests/cases/compiler/index1.ts ===
import {Foo} from './foo';
>Foo : typeof Foo

export default function Example() {}
>Example : typeof Example

Example.Foo = Foo
>Example.Foo = Foo : typeof Foo
>Example.Foo : typeof Foo
>Example : typeof Example
>Foo : typeof Foo
>Foo : typeof Foo

=== tests/cases/compiler/index2.ts ===
import {Foo} from './foo';
>Foo : typeof Foo

export {Foo};
>Foo : typeof Foo

export default function Example() {}
>Example : typeof Example

Example.Foo = Foo
>Example.Foo = Foo : typeof Foo
>Example.Foo : typeof Foo
>Example : typeof Example
>Foo : typeof Foo
>Foo : typeof Foo

=== tests/cases/compiler/index3.ts ===
export class Bar {}
>Bar : Bar

export default function Example() {}
>Example : typeof Example

Example.Bar = Bar
>Example.Bar = Bar : typeof Bar
>Example.Bar : typeof Bar
>Example : typeof Example
>Bar : typeof Bar
>Bar : typeof Bar

=== tests/cases/compiler/index4.ts ===
function A() { }
>A : () => void

function B() { }
>B : () => void

export function C() {
>C : typeof C

return null;
>null : null
}

C.A = A;
>C.A = A : () => void
>C.A : () => void
>C : typeof C
>A : () => void
>A : () => void

C.B = B;
>C.B = B : () => void
>C.B : () => void
>C : typeof C
>B : () => void
>B : () => void

@@ -0,0 +1,32 @@
// @declaration: true
// @filename: foo.ts
export class Foo {}

// @filename: index1.ts
import {Foo} from './foo';
export default function Example() {}
Example.Foo = Foo

// @filename: index2.ts
import {Foo} from './foo';
export {Foo};
export default function Example() {}
Example.Foo = Foo

// @filename: index3.ts
export class Bar {}
export default function Example() {}

Example.Bar = Bar

// @filename: index4.ts
function A() { }

function B() { }

export function C() {
return null;
}

C.A = A;
C.B = B;