From 34b1384152339fb42ddf6e80ce34cbf192b06ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Thu, 3 Jan 2019 11:19:02 +0800 Subject: [PATCH] add transformer for emit add property to default export --- src/compiler/transformers/declarations.ts | 40 ++++++++++++++++++- src/compiler/types.ts | 3 +- .../reference/exportDefaultNamespace.js | 24 +++++++++++ .../reference/exportDefaultNamespace.symbols | 12 ++++++ .../reference/exportDefaultNamespace.types | 15 +++++++ .../declarationEmit/exportDefaultNamespace.ts | 7 ++++ 6 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/exportDefaultNamespace.js create mode 100644 tests/baselines/reference/exportDefaultNamespace.symbols create mode 100644 tests/baselines/reference/exportDefaultNamespace.types create mode 100644 tests/cases/conformance/declarationEmit/exportDefaultNamespace.ts diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index b54cf5bb858..173bd4fb50c 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1008,7 +1008,43 @@ namespace ts { return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([varDecl])); }); const namespaceDecl = createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input, isPrivate), input.name!, createModuleBlock(declarations), NodeFlags.Namespace); - return [clean, namespaceDecl]; + + if (!hasModifier(clean, ModifierFlags.ExportDefault)) { + return [clean, namespaceDecl]; + } + + const modifierFlags = (getModifierFlags(clean) & ~ModifierFlags.ExportDefault) | ModifierFlags.Ambient; + const cleanDeclaration = updateFunctionDeclaration( + clean, + /*decorators*/ undefined, + createModifiersFromModifierFlags(modifierFlags), + /*asteriskToken*/ undefined, + clean.name, + clean.typeParameters, + clean.parameters, + clean.type, + /*body*/ undefined + ); + + const namespaceDeclaration = updateModuleDeclaration( + namespaceDecl, + /*decorators*/ undefined, + createModifiersFromModifierFlags(modifierFlags), + input.name!, + createModuleBlock(declarations) + ); + + const exportDefaultDeclaration = createExportAssignment( + /*decorators*/ undefined, + /*modifiers*/undefined, + /*isExportEquals*/false, + clean.name! + ); + + resultHasExternalModuleIndicator = true; + resultHasScopeMarker = true; + + return [cleanDeclaration, namespaceDeclaration, exportDefaultDeclaration]; } else { return clean; @@ -1153,6 +1189,8 @@ namespace ts { return preserveJsDoc(updateEnumMember(m, m.name, constValue !== undefined ? createLiteral(constValue) : undefined), m); })))); } + case SyntaxKind.ExportAssignment: + return; } // Anything left unhandled is an error, so this should be unreachable return Debug.assertNever(input, `Unhandled top-level node in declaration emit: ${(ts as any).SyntaxKind[(input as any).kind]}`); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5c42d3eb510..1587452a23e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3435,7 +3435,8 @@ namespace ts { | ModuleDeclaration | TypeAliasDeclaration | InterfaceDeclaration - | EnumDeclaration; + | EnumDeclaration + | ExportAssignment; /* @internal */ export interface SymbolVisibilityResult { diff --git a/tests/baselines/reference/exportDefaultNamespace.js b/tests/baselines/reference/exportDefaultNamespace.js new file mode 100644 index 00000000000..39a70d5e231 --- /dev/null +++ b/tests/baselines/reference/exportDefaultNamespace.js @@ -0,0 +1,24 @@ +//// [exportDefaultNamespace.ts] +export default function someFunc() { + return 'hello!'; +} + +someFunc.someProp = 'yo'; + + +//// [exportDefaultNamespace.js] +"use strict"; +exports.__esModule = true; +function someFunc() { + return 'hello!'; +} +exports["default"] = someFunc; +someFunc.someProp = 'yo'; + + +//// [exportDefaultNamespace.d.ts] +declare function someFunc(): string; +declare namespace someFunc { + var someProp: string; +} +export default someFunc; diff --git a/tests/baselines/reference/exportDefaultNamespace.symbols b/tests/baselines/reference/exportDefaultNamespace.symbols new file mode 100644 index 00000000000..eee14876894 --- /dev/null +++ b/tests/baselines/reference/exportDefaultNamespace.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/declarationEmit/exportDefaultNamespace.ts === +export default function someFunc() { +>someFunc : Symbol(someFunc, Decl(exportDefaultNamespace.ts, 0, 0), Decl(exportDefaultNamespace.ts, 2, 1)) + + return 'hello!'; +} + +someFunc.someProp = 'yo'; +>someFunc.someProp : Symbol(someFunc.someProp, Decl(exportDefaultNamespace.ts, 2, 1)) +>someFunc : Symbol(someFunc, Decl(exportDefaultNamespace.ts, 0, 0), Decl(exportDefaultNamespace.ts, 2, 1)) +>someProp : Symbol(someFunc.someProp, Decl(exportDefaultNamespace.ts, 2, 1)) + diff --git a/tests/baselines/reference/exportDefaultNamespace.types b/tests/baselines/reference/exportDefaultNamespace.types new file mode 100644 index 00000000000..eebf33f51f4 --- /dev/null +++ b/tests/baselines/reference/exportDefaultNamespace.types @@ -0,0 +1,15 @@ +=== tests/cases/conformance/declarationEmit/exportDefaultNamespace.ts === +export default function someFunc() { +>someFunc : typeof someFunc + + return 'hello!'; +>'hello!' : "hello!" +} + +someFunc.someProp = 'yo'; +>someFunc.someProp = 'yo' : "yo" +>someFunc.someProp : string +>someFunc : typeof someFunc +>someProp : string +>'yo' : "yo" + diff --git a/tests/cases/conformance/declarationEmit/exportDefaultNamespace.ts b/tests/cases/conformance/declarationEmit/exportDefaultNamespace.ts new file mode 100644 index 00000000000..4724bda727c --- /dev/null +++ b/tests/cases/conformance/declarationEmit/exportDefaultNamespace.ts @@ -0,0 +1,7 @@ +// @declaration: true + +export default function someFunc() { + return 'hello!'; +} + +someFunc.someProp = 'yo';