Skip to content

Commit

Permalink
fix export * as default syntax (#39803)
Browse files Browse the repository at this point in the history
* fix export * as default syntax

* update comments
  • Loading branch information
Kingwl committed Aug 10, 2020
1 parent 1ec71f0 commit a80f60c
Show file tree
Hide file tree
Showing 24 changed files with 1,137 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/compiler/factory/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ namespace ts {
*/
export function getLocalNameForExternalImport(factory: NodeFactory, node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile): Identifier | undefined {
const namespaceDeclaration = getNamespaceDeclarationNode(node);
if (namespaceDeclaration && !isDefaultImport(node)) {
if (namespaceDeclaration && !isDefaultImport(node) && !isExportNamespaceAsDefaultDeclaration(node)) {
const name = namespaceDeclaration.name;
return isGeneratedIdentifier(name) ? name : factory.createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, name) || idText(name));
}
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6996,7 +6996,7 @@ namespace ts {
}

function parseNamespaceExport(pos: number): NamespaceExport {
return finishNode(factory.createNamespaceExport(parseIdentifier()), pos);
return finishNode(factory.createNamespaceExport(parseIdentifierName()), pos);
}

function parseExportDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray<Decorator> | undefined, modifiers: NodeArray<Modifier> | undefined): ExportDeclaration {
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/transformers/module/esnextAnd2015.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ namespace ts {
);
setOriginalNode(importDecl, node.exportClause);

const exportDecl = factory.createExportDeclaration(
const exportDecl = isExportNamespaceAsDefaultDeclaration(node) ? factory.createExportDefault(synthName) : factory.createExportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*isTypeOnly*/ false,
Expand Down
4 changes: 3 additions & 1 deletion src/compiler/transformers/module/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,7 @@ namespace ts {
else if (node.exportClause) {
const statements: Statement[] = [];
// export * as ns from "mod";
// export * as default from "mod";
statements.push(
setOriginalNode(
setTextRange(
Expand All @@ -1051,7 +1052,8 @@ namespace ts {
factory.cloneNode(node.exportClause.name),
getHelperExpressionForExport(node, moduleKind !== ModuleKind.AMD ?
createRequireCall(node) :
factory.createIdentifier(idText(node.exportClause.name)))
isExportNamespaceAsDefaultDeclaration(node) ? generatedName :
factory.createIdentifier(idText(node.exportClause.name)))
)
),
node
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,10 @@ namespace ts {
return !!findAncestor(node, isJSDocTypeExpression);
}

export function isExportNamespaceAsDefaultDeclaration(node: Node): boolean {
return !!(isExportDeclaration(node) && node.exportClause && isNamespaceExport(node.exportClause) && node.exportClause.name.escapedText === "default");
}

export function getTextOfNodeFromSourceText(sourceText: string, node: Node, includeTrivia = false): string {
if (nodeIsMissing(node)) {
return "";
Expand Down
109 changes: 109 additions & 0 deletions tests/baselines/reference/exportAsNamespace4(module=amd).js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
//// [tests/cases/conformance/es2020/modules/exportAsNamespace4.ts] ////

//// [0.ts]
export const a = 1;
export const b = 2;

//// [1.ts]
export * as default from './0';

//// [11.ts]
import * as ns from './0';
export default ns;

//// [2.ts]
import foo from './1'
import foo1 from './11'

foo.a;
foo1.a;

foo.b;
foo1.b;

//// [0.js]
define(["require", "exports"], function (require, exports) {
"use strict";
exports.__esModule = true;
exports.b = exports.a = void 0;
exports.a = 1;
exports.b = 2;
});
//// [1.js]
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
define(["require", "exports", "./0"], function (require, exports, _0_1) {
"use strict";
exports.__esModule = true;
exports["default"] = void 0;
exports["default"] = __importStar(_0_1);
});
//// [11.js]
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
define(["require", "exports", "./0"], function (require, exports, ns) {
"use strict";
exports.__esModule = true;
ns = __importStar(ns);
exports["default"] = ns;
});
//// [2.js]
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
define(["require", "exports", "./1", "./11"], function (require, exports, _1_1, _11_1) {
"use strict";
exports.__esModule = true;
_1_1 = __importDefault(_1_1);
_11_1 = __importDefault(_11_1);
_1_1["default"].a;
_11_1["default"].a;
_1_1["default"].b;
_11_1["default"].b;
});


//// [0.d.ts]
export declare const a = 1;
export declare const b = 2;
//// [1.d.ts]
export * as default from './0';
//// [11.d.ts]
import * as ns from './0';
export default ns;
//// [2.d.ts]
export {};
45 changes: 45 additions & 0 deletions tests/baselines/reference/exportAsNamespace4(module=amd).symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
=== tests/cases/conformance/es2020/modules/0.ts ===
export const a = 1;
>a : Symbol(a, Decl(0.ts, 0, 12))

export const b = 2;
>b : Symbol(b, Decl(0.ts, 1, 12))

=== tests/cases/conformance/es2020/modules/1.ts ===
export * as default from './0';
>default : Symbol(default, Decl(1.ts, 0, 6))

=== tests/cases/conformance/es2020/modules/11.ts ===
import * as ns from './0';
>ns : Symbol(ns, Decl(11.ts, 0, 6))

export default ns;
>ns : Symbol(ns, Decl(11.ts, 0, 6))

=== tests/cases/conformance/es2020/modules/2.ts ===
import foo from './1'
>foo : Symbol(foo, Decl(2.ts, 0, 6))

import foo1 from './11'
>foo1 : Symbol(foo1, Decl(2.ts, 1, 6))

foo.a;
>foo.a : Symbol(foo.a, Decl(0.ts, 0, 12))
>foo : Symbol(foo, Decl(2.ts, 0, 6))
>a : Symbol(foo.a, Decl(0.ts, 0, 12))

foo1.a;
>foo1.a : Symbol(foo.a, Decl(0.ts, 0, 12))
>foo1 : Symbol(foo1, Decl(2.ts, 1, 6))
>a : Symbol(foo.a, Decl(0.ts, 0, 12))

foo.b;
>foo.b : Symbol(foo.b, Decl(0.ts, 1, 12))
>foo : Symbol(foo, Decl(2.ts, 0, 6))
>b : Symbol(foo.b, Decl(0.ts, 1, 12))

foo1.b;
>foo1.b : Symbol(foo.b, Decl(0.ts, 1, 12))
>foo1 : Symbol(foo1, Decl(2.ts, 1, 6))
>b : Symbol(foo.b, Decl(0.ts, 1, 12))

47 changes: 47 additions & 0 deletions tests/baselines/reference/exportAsNamespace4(module=amd).types
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
=== tests/cases/conformance/es2020/modules/0.ts ===
export const a = 1;
>a : 1
>1 : 1

export const b = 2;
>b : 2
>2 : 2

=== tests/cases/conformance/es2020/modules/1.ts ===
export * as default from './0';
>default : typeof import("tests/cases/conformance/es2020/modules/0")

=== tests/cases/conformance/es2020/modules/11.ts ===
import * as ns from './0';
>ns : typeof ns

export default ns;
>ns : typeof ns

=== tests/cases/conformance/es2020/modules/2.ts ===
import foo from './1'
>foo : typeof foo

import foo1 from './11'
>foo1 : typeof foo

foo.a;
>foo.a : 1
>foo : typeof foo
>a : 1

foo1.a;
>foo1.a : 1
>foo1 : typeof foo
>a : 1

foo.b;
>foo.b : 2
>foo : typeof foo
>b : 2

foo1.b;
>foo1.b : 2
>foo1 : typeof foo
>b : 2

101 changes: 101 additions & 0 deletions tests/baselines/reference/exportAsNamespace4(module=commonjs).js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//// [tests/cases/conformance/es2020/modules/exportAsNamespace4.ts] ////

//// [0.ts]
export const a = 1;
export const b = 2;

//// [1.ts]
export * as default from './0';

//// [11.ts]
import * as ns from './0';
export default ns;

//// [2.ts]
import foo from './1'
import foo1 from './11'

foo.a;
foo1.a;

foo.b;
foo1.b;

//// [0.js]
"use strict";
exports.__esModule = true;
exports.b = exports.a = void 0;
exports.a = 1;
exports.b = 2;
//// [1.js]
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
exports.__esModule = true;
exports["default"] = void 0;
exports["default"] = __importStar(require("./0"));
//// [11.js]
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
exports.__esModule = true;
var ns = __importStar(require("./0"));
exports["default"] = ns;
//// [2.js]
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var _1_1 = __importDefault(require("./1"));
var _11_1 = __importDefault(require("./11"));
_1_1["default"].a;
_11_1["default"].a;
_1_1["default"].b;
_11_1["default"].b;


//// [0.d.ts]
export declare const a = 1;
export declare const b = 2;
//// [1.d.ts]
export * as default from './0';
//// [11.d.ts]
import * as ns from './0';
export default ns;
//// [2.d.ts]
export {};

0 comments on commit a80f60c

Please sign in to comment.