Skip to content

Commit 7d4e0e6

Browse files
authored
Fix duplicated amd module comments in declaration bundle (#28451)
1 parent d6df82a commit 7d4e0e6

5 files changed

+108
-31
lines changed

src/compiler/emitter.ts

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ namespace ts {
431431
const moduleKind = getEmitModuleKind(printerOptions);
432432
const bundledHelpers = createMap<boolean>();
433433

434-
let currentSourceFile!: SourceFile;
434+
let currentSourceFile: SourceFile | undefined;
435435
let nodeIdToGeneratedName: string[]; // Map of generated names for specific nodes.
436436
let autoGeneratedIdToGeneratedName: string[]; // Map of generated names for temp and loop variables.
437437
let generatedNames: Map<true>; // Set of names generated by the NameGenerator.
@@ -604,11 +604,13 @@ namespace ts {
604604
pipelinePhase(hint, node);
605605
}
606606

607-
function setSourceFile(sourceFile: SourceFile) {
607+
function setSourceFile(sourceFile: SourceFile | undefined) {
608608
currentSourceFile = sourceFile;
609609
currentLineMap = undefined;
610610
detachedCommentsInfo = undefined;
611-
setSourceMapSource(sourceFile);
611+
if (sourceFile) {
612+
setSourceMapSource(sourceFile);
613+
}
612614
}
613615

614616
function setWriter(_writer: EmitTextWriter | undefined, _sourceMapGenerator: SourceMapGenerator | undefined) {
@@ -635,7 +637,7 @@ namespace ts {
635637
}
636638

637639
function getCurrentLineMap() {
638-
return currentLineMap || (currentLineMap = getLineStarts(currentSourceFile));
640+
return currentLineMap || (currentLineMap = getLineStarts(currentSourceFile!));
639641
}
640642

641643
function emit(node: Node | undefined) {
@@ -1130,7 +1132,7 @@ namespace ts {
11301132
const numNodes = bundle ? bundle.sourceFiles.length : 1;
11311133
for (let i = 0; i < numNodes; i++) {
11321134
const currentNode = bundle ? bundle.sourceFiles[i] : node;
1133-
const sourceFile = isSourceFile(currentNode) ? currentNode : currentSourceFile;
1135+
const sourceFile = isSourceFile(currentNode) ? currentNode : currentSourceFile!;
11341136
const shouldSkip = printerOptions.noEmitHelpers || getExternalHelpersModuleName(sourceFile) !== undefined;
11351137
const shouldBundle = isSourceFile(currentNode) && !isOwnFileEmit;
11361138
const helpers = getEmitHelpers(currentNode);
@@ -1638,7 +1640,7 @@ namespace ts {
16381640
}
16391641

16401642
const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None;
1641-
const allowTrailingComma = currentSourceFile.languageVersion >= ScriptTarget.ES5 && !isJsonSourceFile(currentSourceFile) ? ListFormat.AllowTrailingComma : ListFormat.None;
1643+
const allowTrailingComma = currentSourceFile!.languageVersion >= ScriptTarget.ES5 && !isJsonSourceFile(currentSourceFile!) ? ListFormat.AllowTrailingComma : ListFormat.None;
16421644
emitList(node, node.properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine);
16431645

16441646
if (indentedFlag) {
@@ -1651,7 +1653,7 @@ namespace ts {
16511653
let indentAfterDot = false;
16521654
if (!(getEmitFlags(node) & EmitFlags.NoIndentation)) {
16531655
const dotRangeStart = node.expression.end;
1654-
const dotRangeEnd = skipTrivia(currentSourceFile.text, node.expression.end) + 1;
1656+
const dotRangeEnd = skipTrivia(currentSourceFile!.text, node.expression.end) + 1;
16551657
const dotToken = createToken(SyntaxKind.DotToken);
16561658
dotToken.pos = dotRangeStart;
16571659
dotToken.end = dotRangeEnd;
@@ -1937,7 +1939,7 @@ namespace ts {
19371939
emitExpression(node.expression);
19381940
// Emit semicolon in non json files
19391941
// or if json file that created synthesized expression(eg.define expression statement when --out and amd code generation)
1940-
if (!isJsonSourceFile(currentSourceFile) || nodeIsSynthesized(node.expression)) {
1942+
if (!isJsonSourceFile(currentSourceFile!) || nodeIsSynthesized(node.expression)) {
19411943
writeTrailingSemicolon();
19421944
}
19431945
}
@@ -2057,10 +2059,10 @@ namespace ts {
20572059
const isSimilarNode = node && node.kind === contextNode.kind;
20582060
const startPos = pos;
20592061
if (isSimilarNode) {
2060-
pos = skipTrivia(currentSourceFile.text, pos);
2062+
pos = skipTrivia(currentSourceFile!.text, pos);
20612063
}
20622064
if (emitLeadingCommentsOfPosition && isSimilarNode && contextNode.pos !== startPos) {
2063-
const needsIndent = indentLeading && !positionsAreOnSameLine(startPos, pos, currentSourceFile);
2065+
const needsIndent = indentLeading && !positionsAreOnSameLine(startPos, pos, currentSourceFile!);
20642066
if (needsIndent) {
20652067
increaseIndent();
20662068
}
@@ -2231,7 +2233,7 @@ namespace ts {
22312233
return false;
22322234
}
22332235

2234-
if (!nodeIsSynthesized(body) && !rangeIsOnSingleLine(body, currentSourceFile)) {
2236+
if (!nodeIsSynthesized(body) && !rangeIsOnSingleLine(body, currentSourceFile!)) {
22352237
return false;
22362238
}
22372239

@@ -2644,7 +2646,7 @@ namespace ts {
26442646
// treat synthesized nodes as located on the same line for emit purposes
26452647
nodeIsSynthesized(parentNode) ||
26462648
nodeIsSynthesized(statements[0]) ||
2647-
rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile)
2649+
rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile!)
26482650
);
26492651

26502652
let format = ListFormat.CaseOrDefaultClauseStatements;
@@ -2998,6 +3000,7 @@ namespace ts {
29983000
setSourceFile(sourceFile);
29993001
emitPrologueDirectives(sourceFile.statements, /*startWithNewLine*/ true, seenPrologueDirectives);
30003002
}
3003+
setSourceFile(undefined);
30013004
}
30023005
}
30033006

@@ -3488,13 +3491,13 @@ namespace ts {
34883491

34893492
const firstChild = children[0];
34903493
if (firstChild === undefined) {
3491-
return !rangeIsOnSingleLine(parentNode, currentSourceFile);
3494+
return !rangeIsOnSingleLine(parentNode, currentSourceFile!);
34923495
}
34933496
else if (positionIsSynthesized(parentNode.pos) || nodeIsSynthesized(firstChild)) {
34943497
return synthesizedNodeStartsOnNewLine(firstChild, format);
34953498
}
34963499
else {
3497-
return !rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile);
3500+
return !rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile!);
34983501
}
34993502
}
35003503
else {
@@ -3514,7 +3517,7 @@ namespace ts {
35143517
return synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format);
35153518
}
35163519
else {
3517-
return !rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile);
3520+
return !rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile!);
35183521
}
35193522
}
35203523
else {
@@ -3533,13 +3536,13 @@ namespace ts {
35333536

35343537
const lastChild = lastOrUndefined(children);
35353538
if (lastChild === undefined) {
3536-
return !rangeIsOnSingleLine(parentNode, currentSourceFile);
3539+
return !rangeIsOnSingleLine(parentNode, currentSourceFile!);
35373540
}
35383541
else if (positionIsSynthesized(parentNode.pos) || nodeIsSynthesized(lastChild)) {
35393542
return synthesizedNodeStartsOnNewLine(lastChild, format);
35403543
}
35413544
else {
3542-
return !rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile);
3545+
return !rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile!);
35433546
}
35443547
}
35453548
else {
@@ -3573,12 +3576,12 @@ namespace ts {
35733576
return !nodeIsSynthesized(parent)
35743577
&& !nodeIsSynthesized(node1)
35753578
&& !nodeIsSynthesized(node2)
3576-
&& !rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile);
3579+
&& !rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile!);
35773580
}
35783581

35793582
function isEmptyBlock(block: BlockLike) {
35803583
return block.statements.length === 0
3581-
&& rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile);
3584+
&& rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile!);
35823585
}
35833586

35843587
function skipSynthesizedParentheses(node: Node) {
@@ -3603,7 +3606,7 @@ namespace ts {
36033606
return node.text;
36043607
}
36053608

3606-
return getSourceTextOfNodeFromSourceFile(currentSourceFile, node, includeTrivia);
3609+
return getSourceTextOfNodeFromSourceFile(currentSourceFile!, node, includeTrivia);
36073610
}
36083611

36093612
function getLiteralTextOfNode(node: LiteralLikeNode, neverAsciiEscape: boolean | undefined): string {
@@ -3619,7 +3622,7 @@ namespace ts {
36193622
}
36203623
}
36213624

3622-
return getLiteralText(node, currentSourceFile, neverAsciiEscape);
3625+
return getLiteralText(node, currentSourceFile!, neverAsciiEscape);
36233626
}
36243627

36253628
/**
@@ -4181,15 +4184,15 @@ namespace ts {
41814184
}
41824185

41834186
function emitLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) {
4184-
if (!shouldWriteComment(currentSourceFile.text, commentPos)) return;
4187+
if (!shouldWriteComment(currentSourceFile!.text, commentPos)) return;
41854188
if (!hasWrittenComment) {
41864189
emitNewLineBeforeLeadingCommentOfPosition(getCurrentLineMap(), writer, rangePos, commentPos);
41874190
hasWrittenComment = true;
41884191
}
41894192

41904193
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
41914194
emitPos(commentPos);
4192-
writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
4195+
writeCommentRange(currentSourceFile!.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
41934196
emitPos(commentEnd);
41944197

41954198
if (hasTrailingNewLine) {
@@ -4213,14 +4216,14 @@ namespace ts {
42134216
}
42144217

42154218
function emitTrailingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) {
4216-
if (!shouldWriteComment(currentSourceFile.text, commentPos)) return;
4219+
if (!shouldWriteComment(currentSourceFile!.text, commentPos)) return;
42174220
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/
42184221
if (!writer.isAtStartOfLine()) {
42194222
writer.writeSpace(" ");
42204223
}
42214224

42224225
emitPos(commentPos);
4223-
writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
4226+
writeCommentRange(currentSourceFile!.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
42244227
emitPos(commentEnd);
42254228

42264229
if (hasTrailingNewLine) {
@@ -4241,7 +4244,7 @@ namespace ts {
42414244
// trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
42424245

42434246
emitPos(commentPos);
4244-
writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
4247+
writeCommentRange(currentSourceFile!.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
42454248
emitPos(commentEnd);
42464249

42474250
if (hasTrailingNewLine) {
@@ -4285,11 +4288,11 @@ namespace ts {
42854288
detachedCommentsInfo = undefined;
42864289
}
42874290

4288-
forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos);
4291+
forEachLeadingCommentRange(currentSourceFile!.text, pos, cb, /*state*/ pos);
42894292
}
42904293

42914294
function emitDetachedCommentsAndUpdateCommentsInfo(range: TextRange) {
4292-
const currentDetachedCommentInfo = emitDetachedComments(currentSourceFile.text, getCurrentLineMap(), writer, emitComment, range, newLine, commentsDisabled);
4295+
const currentDetachedCommentInfo = emitDetachedComments(currentSourceFile!.text, getCurrentLineMap(), writer, emitComment, range, newLine, commentsDisabled);
42934296
if (currentDetachedCommentInfo) {
42944297
if (detachedCommentsInfo) {
42954298
detachedCommentsInfo.push(currentDetachedCommentInfo);
@@ -4301,7 +4304,7 @@ namespace ts {
43014304
}
43024305

43034306
function emitComment(text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) {
4304-
if (!shouldWriteComment(currentSourceFile.text, commentPos)) return;
4307+
if (!shouldWriteComment(currentSourceFile!.text, commentPos)) return;
43054308
emitPos(commentPos);
43064309
writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
43074310
emitPos(commentEnd);
@@ -4313,7 +4316,7 @@ namespace ts {
43134316
* @return true if the comment is a triple-slash comment else false
43144317
*/
43154318
function isTripleSlashComment(commentPos: number, commentEnd: number) {
4316-
return isRecognizedTripleSlashComment(currentSourceFile.text, commentPos, commentEnd);
4319+
return isRecognizedTripleSlashComment(currentSourceFile!.text, commentPos, commentEnd);
43174320
}
43184321

43194322
// Source Maps
@@ -4377,7 +4380,7 @@ namespace ts {
43774380
return;
43784381
}
43794382

4380-
const { line: sourceLine, character: sourceCharacter } = getLineAndCharacterOfPosition(currentSourceFile, pos);
4383+
const { line: sourceLine, character: sourceCharacter } = getLineAndCharacterOfPosition(currentSourceFile!, pos);
43814384
sourceMapGenerator!.addMapping(
43824385
writer.getLine(),
43834386
writer.getColumn(),
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//// [tests/cases/compiler/amdModuleBundleNoDuplicateDeclarationEmitComments.ts] ////
2+
3+
//// [file1.ts]
4+
/// <amd-module name="mynamespace::SomeModuleA" />
5+
export class Foo {}
6+
//// [file2.ts]
7+
/// <amd-module name="mynamespace::SomeModuleB" />
8+
export class Bar {}
9+
10+
//// [out.js]
11+
define("mynamespace::SomeModuleA", ["require", "exports"], function (require, exports) {
12+
"use strict";
13+
exports.__esModule = true;
14+
/// <amd-module name="mynamespace::SomeModuleA" />
15+
var Foo = /** @class */ (function () {
16+
function Foo() {
17+
}
18+
return Foo;
19+
}());
20+
exports.Foo = Foo;
21+
});
22+
define("mynamespace::SomeModuleB", ["require", "exports"], function (require, exports) {
23+
"use strict";
24+
exports.__esModule = true;
25+
/// <amd-module name="mynamespace::SomeModuleB" />
26+
var Bar = /** @class */ (function () {
27+
function Bar() {
28+
}
29+
return Bar;
30+
}());
31+
exports.Bar = Bar;
32+
});
33+
34+
35+
//// [out.d.ts]
36+
/// <amd-module name="mynamespace::SomeModuleA" />
37+
declare module "mynamespace::SomeModuleA" {
38+
export class Foo {
39+
}
40+
}
41+
/// <amd-module name="mynamespace::SomeModuleB" />
42+
declare module "mynamespace::SomeModuleB" {
43+
export class Bar {
44+
}
45+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/compiler/file1.ts ===
2+
/// <amd-module name="mynamespace::SomeModuleA" />
3+
export class Foo {}
4+
>Foo : Symbol(Foo, Decl(file1.ts, 0, 0))
5+
6+
=== tests/cases/compiler/file2.ts ===
7+
/// <amd-module name="mynamespace::SomeModuleB" />
8+
export class Bar {}
9+
>Bar : Symbol(Bar, Decl(file2.ts, 0, 0))
10+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/compiler/file1.ts ===
2+
/// <amd-module name="mynamespace::SomeModuleA" />
3+
export class Foo {}
4+
>Foo : Foo
5+
6+
=== tests/cases/compiler/file2.ts ===
7+
/// <amd-module name="mynamespace::SomeModuleB" />
8+
export class Bar {}
9+
>Bar : Bar
10+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//@module: amd
2+
// @declaration: true
3+
// @outFile: ./out.js
4+
// @filename: file1.ts
5+
/// <amd-module name="mynamespace::SomeModuleA" />
6+
export class Foo {}
7+
// @filename: file2.ts
8+
/// <amd-module name="mynamespace::SomeModuleB" />
9+
export class Bar {}

0 commit comments

Comments
 (0)