diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4aefa16007..63772ad280 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1226,12 +1226,12 @@ namespace ts { if (token() === SyntaxKind.ExportKeyword) { nextToken(); if (token() === SyntaxKind.DefaultKeyword) { - return lookAhead(nextTokenIsClassOrFunctionOrAsync); + return lookAhead(nextTokenFollowsDefault); } return token() !== SyntaxKind.AsteriskToken && token() !== SyntaxKind.AsKeyword && token() !== SyntaxKind.OpenBraceToken && canFollowModifier(); } if (token() === SyntaxKind.DefaultKeyword) { - return nextTokenIsClassOrFunctionOrAsync(); + return nextTokenFollowsDefault(); } if (token() === SyntaxKind.StaticKeyword) { nextToken(); @@ -1253,9 +1253,15 @@ namespace ts { || isLiteralPropertyName(); } - function nextTokenIsClassOrFunctionOrAsync(): boolean { + /** Whether a token may follow the `default` keyword */ + function nextTokenFollowsDefault(): boolean { nextToken(); - return token() === SyntaxKind.ClassKeyword || token() === SyntaxKind.FunctionKeyword || + return token() === SyntaxKind.ClassKeyword || + token() === SyntaxKind.FunctionKeyword || + token() === SyntaxKind.InterfaceKeyword || + token() === SyntaxKind.TypeKeyword || + token() === SyntaxKind.EnumKeyword || + token() === SyntaxKind.ConstKeyword || // For `const enum` (token() === SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsFunctionKeywordOnSameLine)); } diff --git a/tests/baselines/reference/exportDefaultConstEnum.js b/tests/baselines/reference/exportDefaultConstEnum.js new file mode 100644 index 0000000000..1b23da0dd1 --- /dev/null +++ b/tests/baselines/reference/exportDefaultConstEnum.js @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/exportDefaultConstEnum.ts] //// + +//// [boolean.ts] +export default const enum Boolean { TRUE, FALSE, FILE_NOT_FOUND } + +//// [user.ts] +import Boolean from "./boolean"; +const b: Boolean = Boolean.FILE_NOT_FOUND; + + +//// [boolean.js] +"use strict"; +//// [user.js] +"use strict"; +var b = 2 /* FILE_NOT_FOUND */; diff --git a/tests/baselines/reference/exportDefaultConstEnum.symbols b/tests/baselines/reference/exportDefaultConstEnum.symbols new file mode 100644 index 0000000000..729ce2922f --- /dev/null +++ b/tests/baselines/reference/exportDefaultConstEnum.symbols @@ -0,0 +1,18 @@ +=== tests/cases/compiler/boolean.ts === +export default const enum Boolean { TRUE, FALSE, FILE_NOT_FOUND } +>Boolean : Symbol(Boolean, Decl(boolean.ts, 0, 0)) +>TRUE : Symbol(Boolean.TRUE, Decl(boolean.ts, 0, 35)) +>FALSE : Symbol(Boolean.FALSE, Decl(boolean.ts, 0, 41)) +>FILE_NOT_FOUND : Symbol(Boolean.FILE_NOT_FOUND, Decl(boolean.ts, 0, 48)) + +=== tests/cases/compiler/user.ts === +import Boolean from "./boolean"; +>Boolean : Symbol(Boolean, Decl(user.ts, 0, 6)) + +const b: Boolean = Boolean.FILE_NOT_FOUND; +>b : Symbol(b, Decl(user.ts, 1, 5)) +>Boolean : Symbol(Boolean, Decl(user.ts, 0, 6)) +>Boolean.FILE_NOT_FOUND : Symbol(Boolean.FILE_NOT_FOUND, Decl(boolean.ts, 0, 48)) +>Boolean : Symbol(Boolean, Decl(user.ts, 0, 6)) +>FILE_NOT_FOUND : Symbol(Boolean.FILE_NOT_FOUND, Decl(boolean.ts, 0, 48)) + diff --git a/tests/baselines/reference/exportDefaultConstEnum.types b/tests/baselines/reference/exportDefaultConstEnum.types new file mode 100644 index 0000000000..c31438e038 --- /dev/null +++ b/tests/baselines/reference/exportDefaultConstEnum.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/boolean.ts === +export default const enum Boolean { TRUE, FALSE, FILE_NOT_FOUND } +>Boolean : Boolean +>TRUE : Boolean.TRUE +>FALSE : Boolean.FALSE +>FILE_NOT_FOUND : Boolean.FILE_NOT_FOUND + +=== tests/cases/compiler/user.ts === +import Boolean from "./boolean"; +>Boolean : typeof Boolean + +const b: Boolean = Boolean.FILE_NOT_FOUND; +>b : Boolean +>Boolean : Boolean +>Boolean.FILE_NOT_FOUND : Boolean.FILE_NOT_FOUND +>Boolean : typeof Boolean +>FILE_NOT_FOUND : Boolean.FILE_NOT_FOUND + diff --git a/tests/baselines/reference/exportDefaultEnum.js b/tests/baselines/reference/exportDefaultEnum.js new file mode 100644 index 0000000000..1a5b4febfc --- /dev/null +++ b/tests/baselines/reference/exportDefaultEnum.js @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/exportDefaultEnum.ts] //// + +//// [boolean.ts] +export default enum Boolean { TRUE, FALSE, FILE_NOT_FOUND } + +//// [user.ts] +import Boolean from "./boolean"; +const b: Boolean = Boolean.FILE_NOT_FOUND; + + +//// [boolean.js] +"use strict"; +var Boolean; +(function (Boolean) { + Boolean[Boolean["TRUE"] = 0] = "TRUE"; + Boolean[Boolean["FALSE"] = 1] = "FALSE"; + Boolean[Boolean["FILE_NOT_FOUND"] = 2] = "FILE_NOT_FOUND"; +})(Boolean = exports.Boolean || (exports.Boolean = {})); +//// [user.js] +"use strict"; +var boolean_1 = require("./boolean"); +var b = boolean_1["default"].FILE_NOT_FOUND; diff --git a/tests/baselines/reference/exportDefaultEnum.symbols b/tests/baselines/reference/exportDefaultEnum.symbols new file mode 100644 index 0000000000..a670f63d80 --- /dev/null +++ b/tests/baselines/reference/exportDefaultEnum.symbols @@ -0,0 +1,18 @@ +=== tests/cases/compiler/boolean.ts === +export default enum Boolean { TRUE, FALSE, FILE_NOT_FOUND } +>Boolean : Symbol(Boolean, Decl(boolean.ts, 0, 0)) +>TRUE : Symbol(Boolean.TRUE, Decl(boolean.ts, 0, 29)) +>FALSE : Symbol(Boolean.FALSE, Decl(boolean.ts, 0, 35)) +>FILE_NOT_FOUND : Symbol(Boolean.FILE_NOT_FOUND, Decl(boolean.ts, 0, 42)) + +=== tests/cases/compiler/user.ts === +import Boolean from "./boolean"; +>Boolean : Symbol(Boolean, Decl(user.ts, 0, 6)) + +const b: Boolean = Boolean.FILE_NOT_FOUND; +>b : Symbol(b, Decl(user.ts, 1, 5)) +>Boolean : Symbol(Boolean, Decl(user.ts, 0, 6)) +>Boolean.FILE_NOT_FOUND : Symbol(Boolean.FILE_NOT_FOUND, Decl(boolean.ts, 0, 42)) +>Boolean : Symbol(Boolean, Decl(user.ts, 0, 6)) +>FILE_NOT_FOUND : Symbol(Boolean.FILE_NOT_FOUND, Decl(boolean.ts, 0, 42)) + diff --git a/tests/baselines/reference/exportDefaultEnum.types b/tests/baselines/reference/exportDefaultEnum.types new file mode 100644 index 0000000000..47047340d3 --- /dev/null +++ b/tests/baselines/reference/exportDefaultEnum.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/boolean.ts === +export default enum Boolean { TRUE, FALSE, FILE_NOT_FOUND } +>Boolean : Boolean +>TRUE : Boolean.TRUE +>FALSE : Boolean.FALSE +>FILE_NOT_FOUND : Boolean.FILE_NOT_FOUND + +=== tests/cases/compiler/user.ts === +import Boolean from "./boolean"; +>Boolean : typeof Boolean + +const b: Boolean = Boolean.FILE_NOT_FOUND; +>b : Boolean +>Boolean : Boolean +>Boolean.FILE_NOT_FOUND : Boolean.FILE_NOT_FOUND +>Boolean : typeof Boolean +>FILE_NOT_FOUND : Boolean.FILE_NOT_FOUND + diff --git a/tests/baselines/reference/exportDefaultInterface.js b/tests/baselines/reference/exportDefaultInterface.js new file mode 100644 index 0000000000..f42f14d823 --- /dev/null +++ b/tests/baselines/reference/exportDefaultInterface.js @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/exportDefaultInterface.ts] //// + +//// [interface.ts] +export default interface I { + x: number; +} + +//// [user.ts] +import I from "./interface"; +const x: I = { x: 0 }; + + +//// [interface.js] +"use strict"; +//// [user.js] +"use strict"; +var x = { x: 0 }; diff --git a/tests/baselines/reference/exportDefaultInterface.symbols b/tests/baselines/reference/exportDefaultInterface.symbols new file mode 100644 index 0000000000..20fe1121ec --- /dev/null +++ b/tests/baselines/reference/exportDefaultInterface.symbols @@ -0,0 +1,17 @@ +=== tests/cases/compiler/interface.ts === +export default interface I { +>I : Symbol(I, Decl(interface.ts, 0, 0)) + + x: number; +>x : Symbol(I.x, Decl(interface.ts, 0, 28)) +} + +=== tests/cases/compiler/user.ts === +import I from "./interface"; +>I : Symbol(I, Decl(user.ts, 0, 6)) + +const x: I = { x: 0 }; +>x : Symbol(x, Decl(user.ts, 1, 5)) +>I : Symbol(I, Decl(user.ts, 0, 6)) +>x : Symbol(x, Decl(user.ts, 1, 14)) + diff --git a/tests/baselines/reference/exportDefaultInterface.types b/tests/baselines/reference/exportDefaultInterface.types new file mode 100644 index 0000000000..5f8ec14ef7 --- /dev/null +++ b/tests/baselines/reference/exportDefaultInterface.types @@ -0,0 +1,19 @@ +=== tests/cases/compiler/interface.ts === +export default interface I { +>I : I + + x: number; +>x : number +} + +=== tests/cases/compiler/user.ts === +import I from "./interface"; +>I : any + +const x: I = { x: 0 }; +>x : I +>I : I +>{ x: 0 } : { x: number; } +>x : number +>0 : 0 + diff --git a/tests/baselines/reference/exportDefaultType.js b/tests/baselines/reference/exportDefaultType.js new file mode 100644 index 0000000000..a5d5975429 --- /dev/null +++ b/tests/baselines/reference/exportDefaultType.js @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/exportDefaultType.ts] //// + +//// [a.ts] +export default type T = number; + +//// [b.ts] +import T from "./a"; +const x: T = 0; + + +//// [a.js] +"use strict"; +//// [b.js] +"use strict"; +var x = 0; diff --git a/tests/baselines/reference/exportDefaultType.symbols b/tests/baselines/reference/exportDefaultType.symbols new file mode 100644 index 0000000000..accfe36db4 --- /dev/null +++ b/tests/baselines/reference/exportDefaultType.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/a.ts === +export default type T = number; +>T : Symbol(T, Decl(a.ts, 0, 0)) + +=== tests/cases/compiler/b.ts === +import T from "./a"; +>T : Symbol(T, Decl(b.ts, 0, 6)) + +const x: T = 0; +>x : Symbol(x, Decl(b.ts, 1, 5)) +>T : Symbol(T, Decl(b.ts, 0, 6)) + diff --git a/tests/baselines/reference/exportDefaultType.types b/tests/baselines/reference/exportDefaultType.types new file mode 100644 index 0000000000..2effbbfbeb --- /dev/null +++ b/tests/baselines/reference/exportDefaultType.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/a.ts === +export default type T = number; +>T : number + +=== tests/cases/compiler/b.ts === +import T from "./a"; +>T : any + +const x: T = 0; +>x : number +>T : number +>0 : 0 + diff --git a/tests/cases/compiler/exportDefaultConstEnum.ts b/tests/cases/compiler/exportDefaultConstEnum.ts new file mode 100644 index 0000000000..f5c033cbc1 --- /dev/null +++ b/tests/cases/compiler/exportDefaultConstEnum.ts @@ -0,0 +1,6 @@ +// @Filename: boolean.ts +export default const enum Boolean { TRUE, FALSE, FILE_NOT_FOUND } + +// @Filename: user.ts +import Boolean from "./boolean"; +const b: Boolean = Boolean.FILE_NOT_FOUND; diff --git a/tests/cases/compiler/exportDefaultEnum.ts b/tests/cases/compiler/exportDefaultEnum.ts new file mode 100644 index 0000000000..38a6f45fad --- /dev/null +++ b/tests/cases/compiler/exportDefaultEnum.ts @@ -0,0 +1,6 @@ +// @Filename: boolean.ts +export default enum Boolean { TRUE, FALSE, FILE_NOT_FOUND } + +// @Filename: user.ts +import Boolean from "./boolean"; +const b: Boolean = Boolean.FILE_NOT_FOUND; diff --git a/tests/cases/compiler/exportDefaultInterface.ts b/tests/cases/compiler/exportDefaultInterface.ts new file mode 100644 index 0000000000..1c611afa73 --- /dev/null +++ b/tests/cases/compiler/exportDefaultInterface.ts @@ -0,0 +1,8 @@ +// @Filename: interface.ts +export default interface I { + x: number; +} + +// @Filename: user.ts +import I from "./interface"; +const x: I = { x: 0 }; diff --git a/tests/cases/compiler/exportDefaultType.ts b/tests/cases/compiler/exportDefaultType.ts new file mode 100644 index 0000000000..3b7e895b73 --- /dev/null +++ b/tests/cases/compiler/exportDefaultType.ts @@ -0,0 +1,6 @@ +// @Filename: a.ts +export default type T = number; + +// @Filename: b.ts +import T from "./a"; +const x: T = 0;