Skip to content

Commit ebd00bd

Browse files
committed
Emit detached comments for function body
1 parent a11ad53 commit ebd00bd

16 files changed

+126
-34
lines changed

src/compiler/emitter.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ module ts {
203203
});
204204
}
205205

206-
function emitNewLineBeforeLeadingComments(node: Node, leadingComments: Comment[], writer: EmitTextWriter) {
206+
function emitNewLineBeforeLeadingComments(node: TextRange, leadingComments: Comment[], writer: EmitTextWriter) {
207207
// If the leading comments start on different line than the start of node, write new line
208208
if (leadingComments && leadingComments.length && node.pos !== leadingComments[0].pos &&
209209
currentSourceFile.getLineAndCharacterFromPosition(node.pos).line !== currentSourceFile.getLineAndCharacterFromPosition(leadingComments[0].pos).line) {
@@ -325,9 +325,9 @@ module ts {
325325
/** Emit Trailing comments of the node */
326326
var emitTrailingComments = compilerOptions.removeComments ? (node: Node) => { } : emitTrailingDeclarationComments;
327327

328-
var detachedCommentsEndPos: number;
328+
var detachedCommentsInfo: { nodePos: number; detachedCommentEndPos: number }[];
329329
/** Emit detached comments of the node */
330-
var emitDetachedComments = compilerOptions.removeComments ? (node: Node) => { } : emitDetachedCommentsAtPosition;
330+
var emitDetachedComments = compilerOptions.removeComments ? (node: TextRange) => { } : emitDetachedCommentsAtPosition;
331331

332332
var writeComment = writeCommentRange;
333333

@@ -1354,6 +1354,8 @@ module ts {
13541354
scopeEmitStart(node);
13551355
increaseIndent();
13561356

1357+
emitDetachedComments(node.body.kind === SyntaxKind.FunctionBlock ? (<Block>node.body).statements : node.body);
1358+
13571359
var startIndex = 0;
13581360
if (node.body.kind === SyntaxKind.FunctionBlock) {
13591361
startIndex = emitDirectivePrologues((<Block>node.body).statements, /*startWithNewLine*/ true);
@@ -1380,9 +1382,11 @@ module ts {
13801382
}
13811383
else {
13821384
writeLine();
1385+
emitLeadingComments(node.body);
13831386
write("return ");
13841387
emit(node.body);
13851388
write(";");
1389+
emitTrailingComments(node.body);
13861390
}
13871391
decreaseIndent();
13881392
writeLine();
@@ -2070,14 +2074,19 @@ module ts {
20702074
// Emit the leading comments only if the parent's pos doesnt match because parent should take care of emitting these comments
20712075
if (node.parent.kind === SyntaxKind.SourceFile || node.pos !== node.parent.pos) {
20722076
var leadingComments: Comment[];
2073-
if (detachedCommentsEndPos === undefined) {
2077+
if (detachedCommentsInfo === undefined || detachedCommentsInfo[detachedCommentsInfo.length - 1].nodePos !== node.pos) {
20742078
// get the leading comments from the node
20752079
leadingComments = getLeadingCommentsOfNode(node, currentSourceFile);
20762080
}
20772081
else {
20782082
// get the leading comments from detachedPos
2079-
leadingComments = getLeadingComments(currentSourceFile.text, detachedCommentsEndPos);
2080-
detachedCommentsEndPos = undefined;
2083+
leadingComments = getLeadingComments(currentSourceFile.text, detachedCommentsInfo[detachedCommentsInfo.length - 1].detachedCommentEndPos);
2084+
if (detachedCommentsInfo.length - 1) {
2085+
detachedCommentsInfo.pop();
2086+
}
2087+
else {
2088+
detachedCommentsInfo = undefined;
2089+
}
20812090
}
20822091
emitNewLineBeforeLeadingComments(node, leadingComments, writer);
20832092
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
@@ -2094,7 +2103,7 @@ module ts {
20942103
}
20952104
}
20962105

2097-
function emitDetachedCommentsAtPosition(node: Node) {
2106+
function emitDetachedCommentsAtPosition(node: TextRange) {
20982107
var leadingComments = getLeadingComments(currentSourceFile.text, node.pos);
20992108
if (leadingComments) {
21002109
var detachedComments: Comment[] = [];
@@ -2125,8 +2134,15 @@ module ts {
21252134
var astLine = currentSourceFile.getLineAndCharacterFromPosition(skipTrivia(currentSourceFile.text, node.pos)).line;
21262135
if (astLine >= lastCommentLine + 2) {
21272136
// Valid detachedComments
2137+
emitNewLineBeforeLeadingComments(node, leadingComments, writer);
21282138
emitComments(detachedComments, /*trailingSeparator*/ true, writer, writeComment);
2129-
detachedCommentsEndPos = detachedComments[detachedComments.length - 1].end;
2139+
var currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: detachedComments[detachedComments.length - 1].end };
2140+
if (detachedCommentsInfo) {
2141+
detachedCommentsInfo.push(currentDetachedCommentInfo);
2142+
}
2143+
else {
2144+
detachedCommentsInfo = [currentDetachedCommentInfo];
2145+
}
21302146
}
21312147
}
21322148
}

tests/baselines/reference/detachedCommentAtStartOfFunctionBody2.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ var TestFile = (function () {
1414
function TestFile() {
1515
}
1616
TestFile.prototype.foo = function (message) {
17-
var _this = this;
1817
/// <summary>Test summary</summary>
1918
/// <param name="message" type="String" />
2019
/// <returns type="Function" />
20+
var _this = this;
2121
return function () { return message + _this.name; };
2222
};
2323
return TestFile;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//// [detachedCommentAtStartOfLambdaFunction1.ts]
2+
class TestFile {
3+
name: string;
4+
foo(message: string): () => string {
5+
return (...x: string[]) =>
6+
/// <summary>Test summary</summary>
7+
/// <param name="message" type="String" />
8+
/// <returns type="Function" />
9+
message + this.name;
10+
}
11+
}
12+
13+
//// [detachedCommentAtStartOfLambdaFunction1.js]
14+
var TestFile = (function () {
15+
function TestFile() {
16+
}
17+
TestFile.prototype.foo = function (message) {
18+
var _this = this;
19+
return function () {
20+
var x = [];
21+
for (var _i = 0; _i < arguments.length; _i++) {
22+
x[_i - 0] = arguments[_i];
23+
}
24+
/// <summary>Test summary</summary>
25+
/// <param name="message" type="String" />
26+
/// <returns type="Function" />
27+
return message + _this.name;
28+
};
29+
};
30+
return TestFile;
31+
})();
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//// [detachedCommentAtStartOfLambdaFunction2.ts]
2+
class TestFile {
3+
name: string;
4+
foo(message: string): () => string {
5+
return (...x: string[]) =>
6+
/// <summary>Test summary</summary>
7+
/// <param name="message" type="String" />
8+
/// <returns type="Function" />
9+
10+
message + this.name;
11+
}
12+
}
13+
14+
//// [detachedCommentAtStartOfLambdaFunction2.js]
15+
var TestFile = (function () {
16+
function TestFile() {
17+
}
18+
TestFile.prototype.foo = function (message) {
19+
var _this = this;
20+
return function () {
21+
/// <summary>Test summary</summary>
22+
/// <param name="message" type="String" />
23+
/// <returns type="Function" />
24+
var x = [];
25+
for (var _i = 0; _i < arguments.length; _i++) {
26+
x[_i - 0] = arguments[_i];
27+
}
28+
return message + _this.name;
29+
};
30+
};
31+
return TestFile;
32+
})();

tests/baselines/reference/mergeThreeInterfaces.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ module M {
8080

8181
//// [mergeThreeInterfaces.js]
8282
// interfaces with the same root module should merge
83-
// basic case
8483
var a;
8584
var r1 = a.foo;
8685
var r2 = a.bar;

tests/baselines/reference/mergeTwoInterfaces.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ module M {
5959

6060
//// [mergeTwoInterfaces.js]
6161
// two interfaces with the same root module should merge
62-
// basic case
6362
var a;
6463
var r1 = a.foo;
6564
var r2 = a.bar;

tests/baselines/reference/parserSbp_7.9_A9_T3.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,4 @@ do {
2222
do {
2323
;
2424
} while (false);
25-
/**
26-
* Check Do-While Statement for automatic semicolon insertion
27-
*
28-
* @path bestPractice/Sbp_7.9_A9_T3.js
29-
* @description Execute do { \n ; \n }while(false) true
30-
*/
31-
//CHECK#1
3225
true;

tests/baselines/reference/stringLiteralTypeIsSubtypeOfString.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ function f16<T extends String, U extends T>(x: any) { }
101101

102102
//// [stringLiteralTypeIsSubtypeOfString.js]
103103
// string literal types are subtypes of string, any
104-
// ok
105104
function f1(x) {
106105
}
107106
function f2(x) {

tests/baselines/reference/subtypingWithObjectMembersOptionality.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ module TwoLevels {
7575

7676
//// [subtypingWithObjectMembersOptionality.js]
7777
// Derived member is not optional but base member is, should be ok
78+
// object literal case
7879
var a;
7980
var b = { Foo: null };
8081
var r = true ? a : b;

tests/baselines/reference/subtypingWithObjectMembersOptionality2.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ var r = true ? a : b; // error
3535

3636
//// [subtypingWithObjectMembersOptionality2.js]
3737
// Derived member is optional but base member is not, should be an error
38+
// object literal case
3839
var a;
3940
var b;
4041
var r = true ? a : b; // error

0 commit comments

Comments
 (0)