Emit detached comments for function body

This commit is contained in:
Sheetal Nandi 2014-08-19 12:06:52 -07:00
parent a11ad539c4
commit ebd00bd1bc
16 changed files with 129 additions and 37 deletions

View File

@ -203,7 +203,7 @@ module ts {
});
}
function emitNewLineBeforeLeadingComments(node: Node, leadingComments: Comment[], writer: EmitTextWriter) {
function emitNewLineBeforeLeadingComments(node: TextRange, leadingComments: Comment[], writer: EmitTextWriter) {
// If the leading comments start on different line than the start of node, write new line
if (leadingComments && leadingComments.length && node.pos !== leadingComments[0].pos &&
currentSourceFile.getLineAndCharacterFromPosition(node.pos).line !== currentSourceFile.getLineAndCharacterFromPosition(leadingComments[0].pos).line) {
@ -325,9 +325,9 @@ module ts {
/** Emit Trailing comments of the node */
var emitTrailingComments = compilerOptions.removeComments ? (node: Node) => { } : emitTrailingDeclarationComments;
var detachedCommentsEndPos: number;
var detachedCommentsInfo: { nodePos: number; detachedCommentEndPos: number }[];
/** Emit detached comments of the node */
var emitDetachedComments = compilerOptions.removeComments ? (node: Node) => { } : emitDetachedCommentsAtPosition;
var emitDetachedComments = compilerOptions.removeComments ? (node: TextRange) => { } : emitDetachedCommentsAtPosition;
var writeComment = writeCommentRange;
@ -1354,6 +1354,8 @@ module ts {
scopeEmitStart(node);
increaseIndent();
emitDetachedComments(node.body.kind === SyntaxKind.FunctionBlock ? (<Block>node.body).statements : node.body);
var startIndex = 0;
if (node.body.kind === SyntaxKind.FunctionBlock) {
startIndex = emitDirectivePrologues((<Block>node.body).statements, /*startWithNewLine*/ true);
@ -1380,9 +1382,11 @@ module ts {
}
else {
writeLine();
emitLeadingComments(node.body);
write("return ");
emit(node.body);
write(";");
emitTrailingComments(node.body);
}
decreaseIndent();
writeLine();
@ -2070,14 +2074,19 @@ module ts {
// Emit the leading comments only if the parent's pos doesnt match because parent should take care of emitting these comments
if (node.parent.kind === SyntaxKind.SourceFile || node.pos !== node.parent.pos) {
var leadingComments: Comment[];
if (detachedCommentsEndPos === undefined) {
if (detachedCommentsInfo === undefined || detachedCommentsInfo[detachedCommentsInfo.length - 1].nodePos !== node.pos) {
// get the leading comments from the node
leadingComments = getLeadingCommentsOfNode(node, currentSourceFile);
}
else {
// get the leading comments from detachedPos
leadingComments = getLeadingComments(currentSourceFile.text, detachedCommentsEndPos);
detachedCommentsEndPos = undefined;
leadingComments = getLeadingComments(currentSourceFile.text, detachedCommentsInfo[detachedCommentsInfo.length - 1].detachedCommentEndPos);
if (detachedCommentsInfo.length - 1) {
detachedCommentsInfo.pop();
}
else {
detachedCommentsInfo = undefined;
}
}
emitNewLineBeforeLeadingComments(node, leadingComments, writer);
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
@ -2094,7 +2103,7 @@ module ts {
}
}
function emitDetachedCommentsAtPosition(node: Node) {
function emitDetachedCommentsAtPosition(node: TextRange) {
var leadingComments = getLeadingComments(currentSourceFile.text, node.pos);
if (leadingComments) {
var detachedComments: Comment[] = [];
@ -2125,8 +2134,15 @@ module ts {
var astLine = currentSourceFile.getLineAndCharacterFromPosition(skipTrivia(currentSourceFile.text, node.pos)).line;
if (astLine >= lastCommentLine + 2) {
// Valid detachedComments
emitNewLineBeforeLeadingComments(node, leadingComments, writer);
emitComments(detachedComments, /*trailingSeparator*/ true, writer, writeComment);
detachedCommentsEndPos = detachedComments[detachedComments.length - 1].end;
var currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: detachedComments[detachedComments.length - 1].end };
if (detachedCommentsInfo) {
detachedCommentsInfo.push(currentDetachedCommentInfo);
}
else {
detachedCommentsInfo = [currentDetachedCommentInfo];
}
}
}
}

View File

@ -14,10 +14,10 @@ var TestFile = (function () {
function TestFile() {
}
TestFile.prototype.foo = function (message) {
var _this = this;
/// <summary>Test summary</summary>
/// <param name="message" type="String" />
/// <returns type="Function" />
var _this = this;
return function () { return message + _this.name; };
};
return TestFile;

View File

@ -0,0 +1,31 @@
//// [detachedCommentAtStartOfLambdaFunction1.ts]
class TestFile {
name: string;
foo(message: string): () => string {
return (...x: string[]) =>
/// <summary>Test summary</summary>
/// <param name="message" type="String" />
/// <returns type="Function" />
message + this.name;
}
}
//// [detachedCommentAtStartOfLambdaFunction1.js]
var TestFile = (function () {
function TestFile() {
}
TestFile.prototype.foo = function (message) {
var _this = this;
return function () {
var x = [];
for (var _i = 0; _i < arguments.length; _i++) {
x[_i - 0] = arguments[_i];
}
/// <summary>Test summary</summary>
/// <param name="message" type="String" />
/// <returns type="Function" />
return message + _this.name;
};
};
return TestFile;
})();

View File

@ -0,0 +1,32 @@
//// [detachedCommentAtStartOfLambdaFunction2.ts]
class TestFile {
name: string;
foo(message: string): () => string {
return (...x: string[]) =>
/// <summary>Test summary</summary>
/// <param name="message" type="String" />
/// <returns type="Function" />
message + this.name;
}
}
//// [detachedCommentAtStartOfLambdaFunction2.js]
var TestFile = (function () {
function TestFile() {
}
TestFile.prototype.foo = function (message) {
var _this = this;
return function () {
/// <summary>Test summary</summary>
/// <param name="message" type="String" />
/// <returns type="Function" />
var x = [];
for (var _i = 0; _i < arguments.length; _i++) {
x[_i - 0] = arguments[_i];
}
return message + _this.name;
};
};
return TestFile;
})();

View File

@ -80,7 +80,6 @@ module M {
//// [mergeThreeInterfaces.js]
// interfaces with the same root module should merge
// basic case
var a;
var r1 = a.foo;
var r2 = a.bar;

View File

@ -59,7 +59,6 @@ module M {
//// [mergeTwoInterfaces.js]
// two interfaces with the same root module should merge
// basic case
var a;
var r1 = a.foo;
var r2 = a.bar;

View File

@ -22,11 +22,4 @@ do {
do {
;
} while (false);
/**
* Check Do-While Statement for automatic semicolon insertion
*
* @path bestPractice/Sbp_7.9_A9_T3.js
* @description Execute do { \n ; \n }while(false) true
*/
//CHECK#1
true;

View File

@ -101,7 +101,6 @@ function f16<T extends String, U extends T>(x: any) { }
//// [stringLiteralTypeIsSubtypeOfString.js]
// string literal types are subtypes of string, any
// ok
function f1(x) {
}
function f2(x) {

View File

@ -75,6 +75,7 @@ module TwoLevels {
//// [subtypingWithObjectMembersOptionality.js]
// Derived member is not optional but base member is, should be ok
// object literal case
var a;
var b = { Foo: null };
var r = true ? a : b;

View File

@ -35,6 +35,7 @@ var r = true ? a : b; // error
//// [subtypingWithObjectMembersOptionality2.js]
// Derived member is optional but base member is not, should be an error
// object literal case
var a;
var b;
var r = true ? a : b; // error

View File

@ -35,6 +35,7 @@ var r = true ? a : b; // ok
//// [subtypingWithObjectMembersOptionality3.js]
// Base property is optional and derived type has no property of that name
// object literal case
var a;
var b;
var r = true ? a : b; // ok

View File

@ -35,6 +35,7 @@ var r = true ? a : b; // ok
//// [subtypingWithObjectMembersOptionality4.js]
// Base has required property, derived adds an optional property, no errors
// object literal case
var a;
var b;
var r = true ? a : b; // ok

File diff suppressed because one or more lines are too long

View File

@ -656,28 +656,26 @@ sourceFile:typeResolution.ts
---
>>> /** Exactly the same as above in AisIn1_1_1 **/
1->^^^^^^^^^^^^^^^^^^^^^^^^
2 >
3 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1->public BisIn1_1_1() {
> /** Exactly the same as above in AisIn1_1_1 **/
>
2 > /** Exactly the same as above in AisIn1_1_1 **/
1->Emitted(39, 25) Source(26, 21) + SourceIndex(0) name (TopLevelModule1.SubModule1.SubSubModule1.ClassB.BisIn1_1_1)
2 >Emitted(39, 72) Source(26, 68) + SourceIndex(0) name (TopLevelModule1.SubModule1.SubSubModule1.ClassB.BisIn1_1_1)
---
>>> // Try all qualified names of this type
1 >^^^^^^^^^^^^^^^^^^^^^^^^
2 >
3 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1 >
>
> // Try all qualified names of this type
>
2 >
3 > /** Exactly the same as above in AisIn1_1_1 **/
1->Emitted(39, 25) Source(29, 21) + SourceIndex(0) name (TopLevelModule1.SubModule1.SubSubModule1.ClassB.BisIn1_1_1)
2 >Emitted(39, 25) Source(26, 21) + SourceIndex(0) name (TopLevelModule1.SubModule1.SubSubModule1.ClassB.BisIn1_1_1)
3 >Emitted(39, 72) Source(26, 68) + SourceIndex(0) name (TopLevelModule1.SubModule1.SubSubModule1.ClassB.BisIn1_1_1)
---
>>> // Try all qualified names of this type
1 >^^^^^^^^^^^^^^^^^^^^^^^^
2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1 >
>
>
2 > // Try all qualified names of this type
1 >Emitted(40, 25) Source(28, 21) + SourceIndex(0) name (TopLevelModule1.SubModule1.SubSubModule1.ClassB.BisIn1_1_1)
2 >Emitted(40, 64) Source(28, 60) + SourceIndex(0) name (TopLevelModule1.SubModule1.SubSubModule1.ClassB.BisIn1_1_1)
3 > // Try all qualified names of this type
1 >Emitted(40, 25) Source(29, 21) + SourceIndex(0) name (TopLevelModule1.SubModule1.SubSubModule1.ClassB.BisIn1_1_1)
2 >Emitted(40, 25) Source(28, 21) + SourceIndex(0) name (TopLevelModule1.SubModule1.SubSubModule1.ClassB.BisIn1_1_1)
3 >Emitted(40, 64) Source(28, 60) + SourceIndex(0) name (TopLevelModule1.SubModule1.SubSubModule1.ClassB.BisIn1_1_1)
---
>>> var a1;
1 >^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -0,0 +1,10 @@
class TestFile {
name: string;
foo(message: string): () => string {
return (...x: string[]) =>
/// <summary>Test summary</summary>
/// <param name="message" type="String" />
/// <returns type="Function" />
message + this.name;
}
}

View File

@ -0,0 +1,11 @@
class TestFile {
name: string;
foo(message: string): () => string {
return (...x: string[]) =>
/// <summary>Test summary</summary>
/// <param name="message" type="String" />
/// <returns type="Function" />
message + this.name;
}
}