From 29c262ec2c84ea6de22cf3c8e8bbd3b7f2027cf8 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 18 Jun 2019 15:22:21 -0700 Subject: [PATCH] Fake up a namespace enclosing declaration when generating expando namespace members --- src/compiler/transformers/declarations.ts | 10 ++- ...onEmitDefaultExportWithStaticAssignment.js | 85 +++++++++++++++++++ ...tDefaultExportWithStaticAssignment.symbols | 46 ++++++++++ ...mitDefaultExportWithStaticAssignment.types | 49 +++++++++++ ...onEmitDefaultExportWithStaticAssignment.ts | 20 +++++ 5 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitDefaultExportWithStaticAssignment.js create mode 100644 tests/baselines/reference/declarationEmitDefaultExportWithStaticAssignment.symbols create mode 100644 tests/baselines/reference/declarationEmitDefaultExportWithStaticAssignment.types create mode 100644 tests/cases/compiler/declarationEmitDefaultExportWithStaticAssignment.ts diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 20aac7d4936e5..7d1d7b73c880e 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1036,12 +1036,18 @@ 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])); diff --git a/tests/baselines/reference/declarationEmitDefaultExportWithStaticAssignment.js b/tests/baselines/reference/declarationEmitDefaultExportWithStaticAssignment.js new file mode 100644 index 0000000000000..f4d8083eca843 --- /dev/null +++ b/tests/baselines/reference/declarationEmitDefaultExportWithStaticAssignment.js @@ -0,0 +1,85 @@ +//// [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 + +//// [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; + + +//// [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; diff --git a/tests/baselines/reference/declarationEmitDefaultExportWithStaticAssignment.symbols b/tests/baselines/reference/declarationEmitDefaultExportWithStaticAssignment.symbols new file mode 100644 index 0000000000000..e4588f35e888d --- /dev/null +++ b/tests/baselines/reference/declarationEmitDefaultExportWithStaticAssignment.symbols @@ -0,0 +1,46 @@ +=== 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)) + diff --git a/tests/baselines/reference/declarationEmitDefaultExportWithStaticAssignment.types b/tests/baselines/reference/declarationEmitDefaultExportWithStaticAssignment.types new file mode 100644 index 0000000000000..4c6636f26098e --- /dev/null +++ b/tests/baselines/reference/declarationEmitDefaultExportWithStaticAssignment.types @@ -0,0 +1,49 @@ +=== 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 + diff --git a/tests/cases/compiler/declarationEmitDefaultExportWithStaticAssignment.ts b/tests/cases/compiler/declarationEmitDefaultExportWithStaticAssignment.ts new file mode 100644 index 0000000000000..145db24086785 --- /dev/null +++ b/tests/cases/compiler/declarationEmitDefaultExportWithStaticAssignment.ts @@ -0,0 +1,20 @@ +// @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 \ No newline at end of file