Emit export default in ES6

This commit is contained in:
Mohamed Hegazy
2015-03-12 17:14:33 -07:00
parent fe9fff506d
commit b3c8bcb319
48 changed files with 549 additions and 14 deletions

View File

@@ -9946,7 +9946,7 @@ module ts {
}
checkExternalModuleExports(container);
if (languageVersion >= ScriptTarget.ES6) {
if (node.isExportEquals && languageVersion >= ScriptTarget.ES6) {
// export assignment is deprecated in es6 or above
grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_export_default_instead);
}
@@ -9994,7 +9994,7 @@ module ts {
if (!links.exportsChecked) {
var defaultSymbol = getExportAssignmentSymbol(moduleSymbol);
if (defaultSymbol) {
if (hasExportedMembers(moduleSymbol)) {
if (languageVersion < ScriptTarget.ES6 && hasExportedMembers(moduleSymbol)) {
var declaration = getDeclarationOfAliasSymbol(defaultSymbol) || defaultSymbol.valueDeclaration;
error(declaration, Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements);
}

View File

@@ -4331,6 +4331,19 @@ module ts {
}
}
function shouldEmitFunctionName(node: Declaration): boolean {
// Emit a declaration name for the function iff:
// it is a function expression with a name provided
// it is a function declaration with a name provided
// it is a function declaration is not the default export, and is missing a name (emit a generated name for it)
if (node.kind === SyntaxKind.FunctionExpression) {
return !!node.name;
}
else if (node.kind === SyntaxKind.FunctionDeclaration) {
return !!node.name || (languageVersion >= ScriptTarget.ES6 && !(node.flags & NodeFlags.Default));
}
}
function emitFunctionDeclaration(node: FunctionLikeDeclaration) {
if (nodeIsMissing(node.body)) {
return emitPinnedOrTripleSlashComments(node);
@@ -4346,13 +4359,17 @@ module ts {
if (!shouldEmitAsArrowFunction(node)) {
if (isES6ModuleMemberDeclaration(node)) {
write("export ");
if (node.flags & NodeFlags.Default) {
write("default ");
}
}
write("function ");
}
if (node.kind === SyntaxKind.FunctionDeclaration || (node.kind === SyntaxKind.FunctionExpression && node.name)) {
if (shouldEmitFunctionName(node)) {
emitDeclarationName(node);
}
emitSignatureAndBody(node);
if (languageVersion < ScriptTarget.ES6 && node.kind === SyntaxKind.FunctionDeclaration && node.parent === currentSourceFile && node.name) {
emitExportMemberAssignments((<FunctionDeclaration>node).name);
@@ -5412,6 +5429,7 @@ module ts {
}
function emitES6Module(node: SourceFile, startIndex: number) {
createExternalModuleInfo(node);
externalImports = undefined;
exportSpecifiers = undefined;
emitCaptureThisForNodeIfNecessary(node);
@@ -5422,20 +5440,37 @@ module ts {
function emitExportDefault(sourceFile: SourceFile, emitAsReturn: boolean) {
if (exportDefault && resolver.hasExportDefaultValue(sourceFile)) {
writeLine();
emitStart(exportDefault);
write(emitAsReturn ? "return " : "module.exports = ");
if (exportDefault.kind === SyntaxKind.ExportAssignment) {
emit((<ExportAssignment>exportDefault).expression);
}
else if (exportDefault.kind === SyntaxKind.ExportSpecifier) {
emit((<ExportSpecifier>exportDefault).propertyName);
if (languageVersion >= ScriptTarget.ES6) {
Debug.assert(!emitAsReturn);
if (exportDefault.kind === SyntaxKind.ExportAssignment) {
writeLine();
emitStart(exportDefault);
write("export default ");
var expression = (<ExportAssignment>exportDefault).expression;
emit(expression);
if (expression.kind !== SyntaxKind.FunctionDeclaration &&
expression.kind !== SyntaxKind.ClassDeclaration) {
write(";");
}
emitEnd(exportDefault);
}
}
else {
emitDeclarationName(<Declaration>exportDefault);
writeLine();
emitStart(exportDefault);
write(emitAsReturn ? "return " : "module.exports = ");
if (exportDefault.kind === SyntaxKind.ExportAssignment) {
emit((<ExportAssignment>exportDefault).expression);
}
else if (exportDefault.kind === SyntaxKind.ExportSpecifier) {
emit((<ExportSpecifier>exportDefault).propertyName);
}
else {
emitDeclarationName(<Declaration>exportDefault);
}
write(";");
emitEnd(exportDefault);
}
write(";");
emitEnd(exportDefault);
}
}

View File

@@ -0,0 +1,22 @@
//// [es5ExportDefaultClassDeclaration.ts]
export default class C {
method() { }
}
//// [es5ExportDefaultClassDeclaration.js]
var C = (function () {
function C() {
}
C.prototype.method = function () {
};
return C;
})();
module.exports = C;
//// [es5ExportDefaultClassDeclaration.d.ts]
export declare class C {
method(): void;
}

View File

@@ -0,0 +1,9 @@
=== tests/cases/compiler/es5ExportDefaultClassDeclaration.ts ===
export default class C {
>C : C
method() { }
>method : () => void
}

View File

@@ -0,0 +1,52 @@
//// [es5ExportDefaultClassDeclaration2.ts]
export default class {
method() { }
}
//// [es5ExportDefaultClassDeclaration2.js]
var _default = (function () {
function _default() {
}
_default.prototype.method = function () {
};
return _default;
})();
module.exports = _default;
//// [es5ExportDefaultClassDeclaration2.d.ts]
export declare class {
method(): void;
}
//// [DtsFileErrors]
tests/cases/compiler/es5ExportDefaultClassDeclaration2.d.ts(1,1): error TS1128: Declaration or statement expected.
tests/cases/compiler/es5ExportDefaultClassDeclaration2.d.ts(1,8): error TS2304: Cannot find name 'declare'.
tests/cases/compiler/es5ExportDefaultClassDeclaration2.d.ts(1,16): error TS1005: ';' expected.
tests/cases/compiler/es5ExportDefaultClassDeclaration2.d.ts(2,5): error TS2304: Cannot find name 'method'.
tests/cases/compiler/es5ExportDefaultClassDeclaration2.d.ts(2,13): error TS1005: ';' expected.
tests/cases/compiler/es5ExportDefaultClassDeclaration2.d.ts(2,19): error TS1109: Expression expected.
==== tests/cases/compiler/es5ExportDefaultClassDeclaration2.d.ts (6 errors) ====
export declare class {
~~~~~~
!!! error TS1128: Declaration or statement expected.
~~~~~~~
!!! error TS2304: Cannot find name 'declare'.
~~~~~
!!! error TS1005: ';' expected.
method(): void;
~~~~~~
!!! error TS2304: Cannot find name 'method'.
~
!!! error TS1005: ';' expected.
~
!!! error TS1109: Expression expected.
}

View File

@@ -0,0 +1,7 @@
=== tests/cases/compiler/es5ExportDefaultClassDeclaration2.ts ===
export default class {
method() { }
>method : () => void
}

View File

@@ -0,0 +1,11 @@
//// [es5ExportDefaultExpression.ts]
export default (1 + 2);
//// [es5ExportDefaultExpression.js]
module.exports = (1 + 2);
//// [es5ExportDefaultExpression.d.ts]
export default (1 + 2);

View File

@@ -0,0 +1,6 @@
=== tests/cases/compiler/es5ExportDefaultExpression.ts ===
export default (1 + 2);
>(1 + 2) : number
>1 + 2 : number

View File

@@ -0,0 +1,13 @@
//// [es5ExportDefaultFunctionDeclaration.ts]
export default function f() { }
//// [es5ExportDefaultFunctionDeclaration.js]
function f() {
}
module.exports = f;
//// [es5ExportDefaultFunctionDeclaration.d.ts]
export declare function f(): void;

View File

@@ -0,0 +1,5 @@
=== tests/cases/compiler/es5ExportDefaultFunctionDeclaration.ts ===
export default function f() { }
>f : () => void

View File

@@ -0,0 +1,26 @@
//// [es5ExportDefaultFunctionDeclaration2.ts]
export default function () { }
//// [es5ExportDefaultFunctionDeclaration2.js]
function () {
}
module.exports = _default;
//// [es5ExportDefaultFunctionDeclaration2.d.ts]
export declare function (): void;
//// [DtsFileErrors]
tests/cases/compiler/es5ExportDefaultFunctionDeclaration2.d.ts(1,25): error TS1003: Identifier expected.
==== tests/cases/compiler/es5ExportDefaultFunctionDeclaration2.d.ts (1 errors) ====
export declare function (): void;
~
!!! error TS1003: Identifier expected.

View File

@@ -0,0 +1,5 @@
=== tests/cases/compiler/es5ExportDefaultFunctionDeclaration2.ts ===
No type information for this code.export default function () { }
No type information for this code.
No type information for this code.

View File

@@ -0,0 +1,11 @@
tests/cases/compiler/es5ExportDefaultIdentifier.ts(4,1): error TS2309: An export assignment cannot be used in a module with other exported elements.
==== tests/cases/compiler/es5ExportDefaultIdentifier.ts (1 errors) ====
export function f() { }
export default f;
~~~~~~~~~~~~~~~~~
!!! error TS2309: An export assignment cannot be used in a module with other exported elements.

View File

@@ -0,0 +1,17 @@
//// [es5ExportDefaultIdentifier.ts]
export function f() { }
export default f;
//// [es5ExportDefaultIdentifier.js]
function f() {
}
exports.f = f;
module.exports = f;
//// [es5ExportDefaultIdentifier.d.ts]
export declare function f(): void;
export default f;

View File

@@ -0,0 +1,11 @@
tests/cases/compiler/es5ExportEquals.ts(4,1): error TS2309: An export assignment cannot be used in a module with other exported elements.
==== tests/cases/compiler/es5ExportEquals.ts (1 errors) ====
export function f() { }
export = f;
~~~~~~~~~~~
!!! error TS2309: An export assignment cannot be used in a module with other exported elements.

View File

@@ -0,0 +1,17 @@
//// [es5ExportEquals.ts]
export function f() { }
export = f;
//// [es5ExportEquals.js]
function f() {
}
exports.f = f;
module.exports = f;
//// [es5ExportEquals.d.ts]
export declare function f(): void;
export = f;

View File

@@ -5,3 +5,4 @@ export = a;
//// [es6ExportAssignment.js]
var a = 10;
export default a;

View File

@@ -0,0 +1,22 @@
//// [es6ExportDefaultClassDeclaration.ts]
export default class C {
method() { }
}
//// [es6ExportDefaultClassDeclaration.js]
var C = (function () {
function C() {
}
C.prototype.method = function () {
};
return C;
})();
export { C };
//// [es6ExportDefaultClassDeclaration.d.ts]
export declare class C {
method(): void;
}

View File

@@ -0,0 +1,9 @@
=== tests/cases/compiler/es6ExportDefaultClassDeclaration.ts ===
export default class C {
>C : C
method() { }
>method : () => void
}

View File

@@ -0,0 +1,52 @@
//// [es6ExportDefaultClassDeclaration2.ts]
export default class {
method() { }
}
//// [es6ExportDefaultClassDeclaration2.js]
var _default = (function () {
function _default() {
}
_default.prototype.method = function () {
};
return _default;
})();
export { };
//// [es6ExportDefaultClassDeclaration2.d.ts]
export declare class {
method(): void;
}
//// [DtsFileErrors]
tests/cases/compiler/es6ExportDefaultClassDeclaration2.d.ts(1,1): error TS1128: Declaration or statement expected.
tests/cases/compiler/es6ExportDefaultClassDeclaration2.d.ts(1,8): error TS2304: Cannot find name 'declare'.
tests/cases/compiler/es6ExportDefaultClassDeclaration2.d.ts(1,16): error TS1005: ';' expected.
tests/cases/compiler/es6ExportDefaultClassDeclaration2.d.ts(2,5): error TS2304: Cannot find name 'method'.
tests/cases/compiler/es6ExportDefaultClassDeclaration2.d.ts(2,13): error TS1005: ';' expected.
tests/cases/compiler/es6ExportDefaultClassDeclaration2.d.ts(2,19): error TS1109: Expression expected.
==== tests/cases/compiler/es6ExportDefaultClassDeclaration2.d.ts (6 errors) ====
export declare class {
~~~~~~
!!! error TS1128: Declaration or statement expected.
~~~~~~~
!!! error TS2304: Cannot find name 'declare'.
~~~~~
!!! error TS1005: ';' expected.
method(): void;
~~~~~~
!!! error TS2304: Cannot find name 'method'.
~
!!! error TS1005: ';' expected.
~
!!! error TS1109: Expression expected.
}

View File

@@ -0,0 +1,7 @@
=== tests/cases/compiler/es6ExportDefaultClassDeclaration2.ts ===
export default class {
method() { }
>method : () => void
}

View File

@@ -0,0 +1,11 @@
//// [es6ExportDefaultExpression.ts]
export default (1 + 2);
//// [es6ExportDefaultExpression.js]
export default (1 + 2);
//// [es6ExportDefaultExpression.d.ts]
export default (1 + 2);

View File

@@ -0,0 +1,6 @@
=== tests/cases/compiler/es6ExportDefaultExpression.ts ===
export default (1 + 2);
>(1 + 2) : number
>1 + 2 : number

View File

@@ -0,0 +1,12 @@
//// [es6ExportDefaultFunctionDeclaration.ts]
export default function f() { }
//// [es6ExportDefaultFunctionDeclaration.js]
export default function f() {
}
//// [es6ExportDefaultFunctionDeclaration.d.ts]
export declare function f(): void;

View File

@@ -0,0 +1,5 @@
=== tests/cases/compiler/es6ExportDefaultFunctionDeclaration.ts ===
export default function f() { }
>f : () => void

View File

@@ -0,0 +1,25 @@
//// [es6ExportDefaultFunctionDeclaration2.ts]
export default function () { }
//// [es6ExportDefaultFunctionDeclaration2.js]
export default function () {
}
//// [es6ExportDefaultFunctionDeclaration2.d.ts]
export declare function (): void;
//// [DtsFileErrors]
tests/cases/compiler/es6ExportDefaultFunctionDeclaration2.d.ts(1,25): error TS1003: Identifier expected.
==== tests/cases/compiler/es6ExportDefaultFunctionDeclaration2.d.ts (1 errors) ====
export declare function (): void;
~
!!! error TS1003: Identifier expected.

View File

@@ -0,0 +1,5 @@
=== tests/cases/compiler/es6ExportDefaultFunctionDeclaration2.ts ===
No type information for this code.export default function () { }
No type information for this code.
No type information for this code.

View File

@@ -0,0 +1,16 @@
//// [es6ExportDefaultIdentifier.ts]
export function f() { }
export default f;
//// [es6ExportDefaultIdentifier.js]
export function f() {
}
export default f;
//// [es6ExportDefaultIdentifier.d.ts]
export declare function f(): void;
export default f;

View File

@@ -0,0 +1,8 @@
=== tests/cases/compiler/es6ExportDefaultIdentifier.ts ===
export function f() { }
>f : () => void
export default f;
>f : () => void

View File

@@ -0,0 +1,11 @@
tests/cases/compiler/es6ExportEquals.ts(4,1): error TS1201: Export assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'export default' instead.
==== tests/cases/compiler/es6ExportEquals.ts (1 errors) ====
export function f() { }
export = f;
~~~~~~~~~~~
!!! error TS1201: Export assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'export default' instead.

View File

@@ -0,0 +1,16 @@
//// [es6ExportEquals.ts]
export function f() { }
export = f;
//// [es6ExportEquals.js]
export function f() {
}
export default f;
//// [es6ExportEquals.d.ts]
export declare function f(): void;
export = f;

View File

@@ -22,6 +22,7 @@ var x1: number = defaultBinding6;
//// [es6ImportDefaultBindingFollowedWithNamedImport1_0.js]
var a = 10;
export default a;
//// [es6ImportDefaultBindingFollowedWithNamedImport1_1.js]
import defaultBinding1 from "es6ImportDefaultBindingFollowedWithNamedImport1_0";
var x1 = defaultBinding1;

View File

@@ -11,6 +11,7 @@ var x: number = defaultBinding;
//// [es6ImportDefaultBindingFollowedWithNamespaceBinding_0.js]
var a = 10;
export default a;
//// [es6ImportDefaultBindingFollowedWithNamespaceBinding_1.js]
import defaultBinding from "es6ImportDefaultBindingFollowedWithNamespaceBinding_0";
var x = defaultBinding;

View File

@@ -10,4 +10,5 @@ import a = require("server");
//// [server.js]
var a = 10;
export default a;
//// [client.js]

View File

@@ -0,0 +1,7 @@
// @target: es5
// @module: commonjs
// @declaration: true
export default class C {
method() { }
}

View File

@@ -0,0 +1,7 @@
// @target: es5
// @module: commonjs
// @declaration: true
export default class {
method() { }
}

View File

@@ -0,0 +1,5 @@
// @target: es5
// @module: commonjs
// @declaration: true
export default (1 + 2);

View File

@@ -0,0 +1,5 @@
// @target: es5
// @module: commonjs
// @declaration: true
export default function f() { }

View File

@@ -0,0 +1,5 @@
// @target: es5
// @module: commonjs
// @declaration: true
export default function () { }

View File

@@ -0,0 +1,7 @@
// @target: es5
// @module: commonjs
// @declaration: true
export function f() { }
export default f;

View File

@@ -0,0 +1,7 @@
// @target: es5
// @module: commonjs
// @declaration: true
export function f() { }
export = f;

View File

@@ -0,0 +1,6 @@
// @target: es6
// @declaration: true
export default class C {
method() { }
}

View File

@@ -0,0 +1,6 @@
// @target: es6
// @declaration: true
export default class {
method() { }
}

View File

@@ -0,0 +1,4 @@
// @target: es6
// @declaration: true
export default (1 + 2);

View File

@@ -0,0 +1,4 @@
// @target: es6
// @declaration: true
export default function f() { }

View File

@@ -0,0 +1,4 @@
// @target: es6
// @declaration: true
export default function () { }

View File

@@ -0,0 +1,6 @@
// @target: es6
// @declaration: true
export function f() { }
export default f;

View File

@@ -0,0 +1,6 @@
// @target: es6
// @declaration: true
export function f() { }
export = f;