Skip to content

Commit d17efe6

Browse files
authored
Fix microsoft#25954 - Always retain export modifier if default modifier is present (microsoft#25974)
* Fix microsoft#25954 - Always retain export modifier if default modifier is present * Also fix an issue with scope markers in ambient modules not affecting the modifiers required
1 parent 673ae74 commit d17efe6

12 files changed

+137
-4
lines changed

src/compiler/transformers/declarations.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,17 @@ namespace ts {
11641164
return false;
11651165
}
11661166

1167+
function isScopeMarker(node: Node) {
1168+
return isExportAssignment(node) || isExportDeclaration(node);
1169+
}
1170+
1171+
function hasScopeMarker(node: Node) {
1172+
if (isModuleBlock(node)) {
1173+
return some(node.statements, isScopeMarker);
1174+
}
1175+
return false;
1176+
}
1177+
11671178
function ensureModifiers(node: Node, privateDeclaration?: boolean): ReadonlyArray<Modifier> | undefined {
11681179
const currentFlags = getModifierFlags(node);
11691180
const newFlags = ensureModifierFlags(node, privateDeclaration);
@@ -1178,7 +1189,7 @@ namespace ts {
11781189
let additions = (needsDeclare && !isAlwaysType(node)) ? ModifierFlags.Ambient : ModifierFlags.None;
11791190
const parentIsFile = node.parent.kind === SyntaxKind.SourceFile;
11801191
if (!parentIsFile || (isBundledEmit && parentIsFile && isExternalModule(node.parent as SourceFile))) {
1181-
mask ^= ((privateDeclaration || (isBundledEmit && parentIsFile) ? 0 : ModifierFlags.Export) | ModifierFlags.Default | ModifierFlags.Ambient);
1192+
mask ^= ((privateDeclaration || (isBundledEmit && parentIsFile) || hasScopeMarker(node.parent) ? 0 : ModifierFlags.Export) | ModifierFlags.Ambient);
11821193
additions = ModifierFlags.None;
11831194
}
11841195
return maskModifierFlags(node, mask, additions);
@@ -1240,6 +1251,11 @@ namespace ts {
12401251

12411252
function maskModifierFlags(node: Node, modifierMask: ModifierFlags = ModifierFlags.All ^ ModifierFlags.Public, modifierAdditions: ModifierFlags = ModifierFlags.None): ModifierFlags {
12421253
let flags = (getModifierFlags(node) & modifierMask) | modifierAdditions;
1254+
if (flags & ModifierFlags.Default && !(flags & ModifierFlags.Export)) {
1255+
// A non-exported default is a nonsequitor - we usually try to remove all export modifiers
1256+
// from statements in ambient declarations; but a default export must retain its export modifier to be syntactically valid
1257+
flags ^= ModifierFlags.Export;
1258+
}
12431259
if (flags & ModifierFlags.Default && flags & ModifierFlags.Ambient) {
12441260
flags ^= ModifierFlags.Ambient; // `declare` is never required alongside `default` (and would be an error if printed)
12451261
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//// [declarationEmitAmdModuleDefault.ts]
2+
export default class DefaultClass { }
3+
4+
//// [file.js]
5+
define("declarationEmitAmdModuleDefault", ["require", "exports"], function (require, exports) {
6+
"use strict";
7+
exports.__esModule = true;
8+
var DefaultClass = /** @class */ (function () {
9+
function DefaultClass() {
10+
}
11+
return DefaultClass;
12+
}());
13+
exports["default"] = DefaultClass;
14+
});
15+
16+
17+
//// [file.d.ts]
18+
declare module "declarationEmitAmdModuleDefault" {
19+
export default class DefaultClass {
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
=== tests/cases/compiler/declarationEmitAmdModuleDefault.ts ===
2+
export default class DefaultClass { }
3+
>DefaultClass : Symbol(DefaultClass, Decl(declarationEmitAmdModuleDefault.ts, 0, 0))
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
=== tests/cases/compiler/declarationEmitAmdModuleDefault.ts ===
2+
export default class DefaultClass { }
3+
>DefaultClass : DefaultClass
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//// [declarationEmitModuleWithScopeMarker.ts]
2+
declare module "bar" {
3+
var before: typeof func;
4+
5+
export function normal(): void;
6+
7+
export default function func(): typeof func;
8+
9+
var after: typeof func;
10+
11+
export {}
12+
}
13+
14+
15+
//// [declarationEmitModuleWithScopeMarker.js]
16+
17+
18+
//// [declarationEmitModuleWithScopeMarker.d.ts]
19+
declare module "bar" {
20+
var before: typeof func;
21+
export function normal(): void;
22+
export default function func(): typeof func;
23+
var after: typeof func;
24+
export {};
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
=== tests/cases/compiler/declarationEmitModuleWithScopeMarker.ts ===
2+
declare module "bar" {
3+
>"bar" : Symbol("bar", Decl(declarationEmitModuleWithScopeMarker.ts, 0, 0))
4+
5+
var before: typeof func;
6+
>before : Symbol(before, Decl(declarationEmitModuleWithScopeMarker.ts, 1, 7))
7+
>func : Symbol(func, Decl(declarationEmitModuleWithScopeMarker.ts, 3, 35))
8+
9+
export function normal(): void;
10+
>normal : Symbol(normal, Decl(declarationEmitModuleWithScopeMarker.ts, 1, 28))
11+
12+
export default function func(): typeof func;
13+
>func : Symbol(func, Decl(declarationEmitModuleWithScopeMarker.ts, 3, 35))
14+
>func : Symbol(func, Decl(declarationEmitModuleWithScopeMarker.ts, 3, 35))
15+
16+
var after: typeof func;
17+
>after : Symbol(after, Decl(declarationEmitModuleWithScopeMarker.ts, 7, 7))
18+
>func : Symbol(func, Decl(declarationEmitModuleWithScopeMarker.ts, 3, 35))
19+
20+
export {}
21+
}
22+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
=== tests/cases/compiler/declarationEmitModuleWithScopeMarker.ts ===
2+
declare module "bar" {
3+
>"bar" : typeof import("bar")
4+
5+
var before: typeof func;
6+
>before : () => typeof func
7+
>func : () => typeof func
8+
9+
export function normal(): void;
10+
>normal : () => void
11+
12+
export default function func(): typeof func;
13+
>func : () => typeof func
14+
>func : () => typeof func
15+
16+
var after: typeof func;
17+
>after : () => typeof func
18+
>func : () => typeof func
19+
20+
export {}
21+
}
22+

tests/baselines/reference/es5ExportDefaultClassDeclaration4.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ declare module "foo" {
1919
//// [es5ExportDefaultClassDeclaration4.d.ts]
2020
declare module "foo" {
2121
var before: C;
22-
class C {
22+
export default class C {
2323
method(): C;
2424
}
2525
var after: C;

tests/baselines/reference/es5ExportDefaultFunctionDeclaration4.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ declare module "bar" {
1313
//// [es5ExportDefaultFunctionDeclaration4.d.ts]
1414
declare module "bar" {
1515
var before: typeof func;
16-
function func(): typeof func;
16+
export default function func(): typeof func;
1717
var after: typeof func;
1818
}

tests/baselines/reference/exportDeclarationInInternalModule.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ declare module Aaa {
7272
}
7373
}
7474
declare module Bbb {
75-
class SomeType {
75+
export class SomeType {
7676
}
7777
export * from Aaa;
7878
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// @declaration: true
2+
// @module: amd
3+
// @outFile: file.js
4+
export default class DefaultClass { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @target: es5
2+
// @module: commonjs
3+
// @declaration: true
4+
5+
declare module "bar" {
6+
var before: typeof func;
7+
8+
export function normal(): void;
9+
10+
export default function func(): typeof func;
11+
12+
var after: typeof func;
13+
14+
export {}
15+
}

0 commit comments

Comments
 (0)