Merge pull request #5472 from MartyIX/issue-5183
Fix copyright comments are not preserved when generating d.ts files
This commit is contained in:
commit
f503169f8c
11 changed files with 435 additions and 64 deletions
|
@ -468,6 +468,7 @@ namespace ts {
|
|||
function emitSourceFile(node: SourceFile) {
|
||||
currentSourceFile = node;
|
||||
enclosingDeclaration = node;
|
||||
emitDetachedComments(currentSourceFile, writer, writeCommentRange, node, newLine, true /* remove comments */);
|
||||
emitLines(node.statements);
|
||||
}
|
||||
|
||||
|
|
|
@ -4899,7 +4899,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
|||
|
||||
increaseIndent();
|
||||
let outPos = writer.getTextPos();
|
||||
emitDetachedComments(node.body);
|
||||
emitDetachedCommentsAndUpdateCommentsInfo(node.body);
|
||||
emitFunctionBodyPreamble(node);
|
||||
let preambleEmitted = writer.getTextPos() !== outPos;
|
||||
decreaseIndent();
|
||||
|
@ -4944,7 +4944,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
|||
let initialTextPos = writer.getTextPos();
|
||||
|
||||
increaseIndent();
|
||||
emitDetachedComments(body.statements);
|
||||
emitDetachedCommentsAndUpdateCommentsInfo(body.statements);
|
||||
|
||||
// Emit all the directive prologues (like "use strict"). These have to come before
|
||||
// any other preamble code we write (like parameter initializers).
|
||||
|
@ -5266,7 +5266,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
|||
// Emit all the directive prologues (like "use strict"). These have to come before
|
||||
// any other preamble code we write (like parameter initializers).
|
||||
startIndex = emitDirectivePrologues(ctor.body.statements, /*startWithNewLine*/ true);
|
||||
emitDetachedComments(ctor.body.statements);
|
||||
emitDetachedCommentsAndUpdateCommentsInfo(ctor.body.statements);
|
||||
}
|
||||
emitCaptureThisForNodeIfNecessary(node);
|
||||
let superCall: ExpressionStatement;
|
||||
|
@ -7644,7 +7644,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
|||
// Start new file on new line
|
||||
writeLine();
|
||||
emitShebang();
|
||||
emitDetachedComments(node);
|
||||
emitDetachedCommentsAndUpdateCommentsInfo(node);
|
||||
|
||||
if (isExternalModule(node) || compilerOptions.isolatedModules) {
|
||||
let emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[ModuleKind.CommonJS];
|
||||
|
@ -7940,11 +7940,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
|||
return leadingComments;
|
||||
}
|
||||
|
||||
function isPinnedComments(comment: CommentRange) {
|
||||
return currentSourceFile.text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk &&
|
||||
currentSourceFile.text.charCodeAt(comment.pos + 2) === CharacterCodes.exclamation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given comment is a triple-slash
|
||||
*
|
||||
|
@ -8078,55 +8073,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
|||
emitComments(currentSourceFile, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
}
|
||||
|
||||
function emitDetachedComments(node: TextRange) {
|
||||
let leadingComments: CommentRange[];
|
||||
if (compilerOptions.removeComments) {
|
||||
// removeComments is true, only reserve pinned comment at the top of file
|
||||
// For example:
|
||||
// /*! Pinned Comment */
|
||||
//
|
||||
// var x = 10;
|
||||
if (node.pos === 0) {
|
||||
leadingComments = filter(getLeadingCommentRanges(currentSourceFile.text, node.pos), isPinnedComments);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// removeComments is false, just get detached as normal and bypass the process to filter comment
|
||||
leadingComments = getLeadingCommentRanges(currentSourceFile.text, node.pos);
|
||||
}
|
||||
function emitDetachedCommentsAndUpdateCommentsInfo(node: TextRange) {
|
||||
let currentDetachedCommentInfo = emitDetachedComments(currentSourceFile, writer, writeComment, node, newLine, compilerOptions.removeComments);
|
||||
|
||||
if (leadingComments) {
|
||||
let detachedComments: CommentRange[] = [];
|
||||
let lastComment: CommentRange;
|
||||
|
||||
forEach(leadingComments, comment => {
|
||||
if (lastComment) {
|
||||
let lastCommentLine = getLineOfLocalPosition(currentSourceFile, lastComment.end);
|
||||
let commentLine = getLineOfLocalPosition(currentSourceFile, comment.pos);
|
||||
|
||||
if (commentLine >= lastCommentLine + 2) {
|
||||
// There was a blank line between the last comment and this comment. This
|
||||
// comment is not part of the copyright comments. Return what we have so
|
||||
// far.
|
||||
return detachedComments;
|
||||
}
|
||||
}
|
||||
|
||||
detachedComments.push(comment);
|
||||
lastComment = comment;
|
||||
});
|
||||
|
||||
if (detachedComments.length) {
|
||||
// All comments look like they could have been part of the copyright header. Make
|
||||
// sure there is at least one blank line between it and the node. If not, it's not
|
||||
// a copyright header.
|
||||
let lastCommentLine = getLineOfLocalPosition(currentSourceFile, lastOrUndefined(detachedComments).end);
|
||||
let nodeLine = getLineOfLocalPosition(currentSourceFile, skipTrivia(currentSourceFile.text, node.pos));
|
||||
if (nodeLine >= lastCommentLine + 2) {
|
||||
// Valid detachedComments
|
||||
emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
|
||||
emitComments(currentSourceFile, writer, detachedComments, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
let currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: lastOrUndefined(detachedComments).end };
|
||||
if (currentDetachedCommentInfo) {
|
||||
if (detachedCommentsInfo) {
|
||||
detachedCommentsInfo.push(currentDetachedCommentInfo);
|
||||
}
|
||||
|
@ -8135,8 +8085,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitShebang() {
|
||||
let shebang = getShebang(currentSourceFile.text);
|
||||
|
|
|
@ -1912,6 +1912,74 @@ namespace ts {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Detached comment is a comment at the top of file or function body that is separated from
|
||||
* the next statement by space.
|
||||
*/
|
||||
export function emitDetachedComments(currentSourceFile: SourceFile, writer: EmitTextWriter,
|
||||
writeComment: (currentSourceFile: SourceFile, writer: EmitTextWriter, comment: CommentRange, newLine: string) => void,
|
||||
node: TextRange, newLine: string, removeComments: boolean) {
|
||||
let leadingComments: CommentRange[];
|
||||
let currentDetachedCommentInfo: {nodePos: number, detachedCommentEndPos: number};
|
||||
if (removeComments) {
|
||||
// removeComments is true, only reserve pinned comment at the top of file
|
||||
// For example:
|
||||
// /*! Pinned Comment */
|
||||
//
|
||||
// var x = 10;
|
||||
if (node.pos === 0) {
|
||||
leadingComments = filter(getLeadingCommentRanges(currentSourceFile.text, node.pos), isPinnedComment);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// removeComments is false, just get detached as normal and bypass the process to filter comment
|
||||
leadingComments = getLeadingCommentRanges(currentSourceFile.text, node.pos);
|
||||
}
|
||||
|
||||
if (leadingComments) {
|
||||
let detachedComments: CommentRange[] = [];
|
||||
let lastComment: CommentRange;
|
||||
|
||||
for (let comment of leadingComments) {
|
||||
if (lastComment) {
|
||||
let lastCommentLine = getLineOfLocalPosition(currentSourceFile, lastComment.end);
|
||||
let commentLine = getLineOfLocalPosition(currentSourceFile, comment.pos);
|
||||
|
||||
if (commentLine >= lastCommentLine + 2) {
|
||||
// There was a blank line between the last comment and this comment. This
|
||||
// comment is not part of the copyright comments. Return what we have so
|
||||
// far.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
detachedComments.push(comment);
|
||||
lastComment = comment;
|
||||
}
|
||||
|
||||
if (detachedComments.length) {
|
||||
// All comments look like they could have been part of the copyright header. Make
|
||||
// sure there is at least one blank line between it and the node. If not, it's not
|
||||
// a copyright header.
|
||||
let lastCommentLine = getLineOfLocalPosition(currentSourceFile, lastOrUndefined(detachedComments).end);
|
||||
let nodeLine = getLineOfLocalPosition(currentSourceFile, skipTrivia(currentSourceFile.text, node.pos));
|
||||
if (nodeLine >= lastCommentLine + 2) {
|
||||
// Valid detachedComments
|
||||
emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
|
||||
emitComments(currentSourceFile, writer, detachedComments, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: lastOrUndefined(detachedComments).end };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return currentDetachedCommentInfo;
|
||||
|
||||
function isPinnedComment(comment: CommentRange) {
|
||||
return currentSourceFile.text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk &&
|
||||
currentSourceFile.text.charCodeAt(comment.pos + 2) === CharacterCodes.exclamation;
|
||||
}
|
||||
}
|
||||
|
||||
export function writeCommentRange(currentSourceFile: SourceFile, writer: EmitTextWriter, comment: CommentRange, newLine: string) {
|
||||
if (currentSourceFile.text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk) {
|
||||
let firstCommentLineAndCharacter = getLineAndCharacterOfPosition(currentSourceFile, comment.pos);
|
||||
|
|
85
tests/baselines/reference/declarationEmitDetachedComment1.js
Normal file
85
tests/baselines/reference/declarationEmitDetachedComment1.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
//// [tests/cases/compiler/declarationEmitDetachedComment1.ts] ////
|
||||
|
||||
//// [test1.ts]
|
||||
|
||||
/*! Copyright 2015 MyCompany Inc. */
|
||||
|
||||
/**
|
||||
* Hello class
|
||||
*/
|
||||
class Hello {
|
||||
|
||||
}
|
||||
|
||||
//// [test2.ts]
|
||||
/* A comment at the top of the file. */
|
||||
|
||||
/**
|
||||
* Hi class
|
||||
*/
|
||||
class Hi {
|
||||
|
||||
}
|
||||
|
||||
//// [test3.ts]
|
||||
// A one-line comment at the top of the file.
|
||||
|
||||
/**
|
||||
* Hola class
|
||||
*/
|
||||
class Hola {
|
||||
|
||||
}
|
||||
|
||||
|
||||
//// [test1.js]
|
||||
/*! Copyright 2015 MyCompany Inc. */
|
||||
/**
|
||||
* Hello class
|
||||
*/
|
||||
var Hello = (function () {
|
||||
function Hello() {
|
||||
}
|
||||
return Hello;
|
||||
})();
|
||||
//// [test2.js]
|
||||
/* A comment at the top of the file. */
|
||||
/**
|
||||
* Hi class
|
||||
*/
|
||||
var Hi = (function () {
|
||||
function Hi() {
|
||||
}
|
||||
return Hi;
|
||||
})();
|
||||
//// [test3.js]
|
||||
// A one-line comment at the top of the file.
|
||||
/**
|
||||
* Hola class
|
||||
*/
|
||||
var Hola = (function () {
|
||||
function Hola() {
|
||||
}
|
||||
return Hola;
|
||||
})();
|
||||
|
||||
|
||||
//// [test1.d.ts]
|
||||
/*! Copyright 2015 MyCompany Inc. */
|
||||
/**
|
||||
* Hello class
|
||||
*/
|
||||
declare class Hello {
|
||||
}
|
||||
//// [test2.d.ts]
|
||||
/**
|
||||
* Hi class
|
||||
*/
|
||||
declare class Hi {
|
||||
}
|
||||
//// [test3.d.ts]
|
||||
/**
|
||||
* Hola class
|
||||
*/
|
||||
declare class Hola {
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
=== tests/cases/compiler/test1.ts ===
|
||||
|
||||
/*! Copyright 2015 MyCompany Inc. */
|
||||
|
||||
/**
|
||||
* Hello class
|
||||
*/
|
||||
class Hello {
|
||||
>Hello : Symbol(Hello, Decl(test1.ts, 0, 0))
|
||||
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/test2.ts ===
|
||||
/* A comment at the top of the file. */
|
||||
|
||||
/**
|
||||
* Hi class
|
||||
*/
|
||||
class Hi {
|
||||
>Hi : Symbol(Hi, Decl(test2.ts, 0, 0))
|
||||
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/test3.ts ===
|
||||
// A one-line comment at the top of the file.
|
||||
|
||||
/**
|
||||
* Hola class
|
||||
*/
|
||||
class Hola {
|
||||
>Hola : Symbol(Hola, Decl(test3.ts, 0, 0))
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
=== tests/cases/compiler/test1.ts ===
|
||||
|
||||
/*! Copyright 2015 MyCompany Inc. */
|
||||
|
||||
/**
|
||||
* Hello class
|
||||
*/
|
||||
class Hello {
|
||||
>Hello : Hello
|
||||
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/test2.ts ===
|
||||
/* A comment at the top of the file. */
|
||||
|
||||
/**
|
||||
* Hi class
|
||||
*/
|
||||
class Hi {
|
||||
>Hi : Hi
|
||||
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/test3.ts ===
|
||||
// A one-line comment at the top of the file.
|
||||
|
||||
/**
|
||||
* Hola class
|
||||
*/
|
||||
class Hola {
|
||||
>Hola : Hola
|
||||
|
||||
}
|
||||
|
65
tests/baselines/reference/declarationEmitDetachedComment2.js
Normal file
65
tests/baselines/reference/declarationEmitDetachedComment2.js
Normal file
|
@ -0,0 +1,65 @@
|
|||
//// [tests/cases/compiler/declarationEmitDetachedComment2.ts] ////
|
||||
|
||||
//// [test1.ts]
|
||||
|
||||
/*! Copyright 2015 MyCompany Inc. */
|
||||
|
||||
/**
|
||||
* Hello class
|
||||
*/
|
||||
class Hello {
|
||||
|
||||
}
|
||||
|
||||
//// [test2.ts]
|
||||
/* A comment at the top of the file. */
|
||||
|
||||
/**
|
||||
* Hi class
|
||||
*/
|
||||
class Hi {
|
||||
|
||||
}
|
||||
|
||||
//// [test3.ts]
|
||||
// A one-line comment at the top of the file.
|
||||
|
||||
/**
|
||||
* Hola class
|
||||
*/
|
||||
class Hola {
|
||||
|
||||
}
|
||||
|
||||
|
||||
//// [test1.js]
|
||||
/*! Copyright 2015 MyCompany Inc. */
|
||||
var Hello = (function () {
|
||||
function Hello() {
|
||||
}
|
||||
return Hello;
|
||||
})();
|
||||
//// [test2.js]
|
||||
var Hi = (function () {
|
||||
function Hi() {
|
||||
}
|
||||
return Hi;
|
||||
})();
|
||||
//// [test3.js]
|
||||
var Hola = (function () {
|
||||
function Hola() {
|
||||
}
|
||||
return Hola;
|
||||
})();
|
||||
|
||||
|
||||
//// [test1.d.ts]
|
||||
/*! Copyright 2015 MyCompany Inc. */
|
||||
declare class Hello {
|
||||
}
|
||||
//// [test2.d.ts]
|
||||
declare class Hi {
|
||||
}
|
||||
//// [test3.d.ts]
|
||||
declare class Hola {
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
=== tests/cases/compiler/test1.ts ===
|
||||
|
||||
/*! Copyright 2015 MyCompany Inc. */
|
||||
|
||||
/**
|
||||
* Hello class
|
||||
*/
|
||||
class Hello {
|
||||
>Hello : Symbol(Hello, Decl(test1.ts, 0, 0))
|
||||
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/test2.ts ===
|
||||
/* A comment at the top of the file. */
|
||||
|
||||
/**
|
||||
* Hi class
|
||||
*/
|
||||
class Hi {
|
||||
>Hi : Symbol(Hi, Decl(test2.ts, 0, 0))
|
||||
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/test3.ts ===
|
||||
// A one-line comment at the top of the file.
|
||||
|
||||
/**
|
||||
* Hola class
|
||||
*/
|
||||
class Hola {
|
||||
>Hola : Symbol(Hola, Decl(test3.ts, 0, 0))
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
=== tests/cases/compiler/test1.ts ===
|
||||
|
||||
/*! Copyright 2015 MyCompany Inc. */
|
||||
|
||||
/**
|
||||
* Hello class
|
||||
*/
|
||||
class Hello {
|
||||
>Hello : Hello
|
||||
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/test2.ts ===
|
||||
/* A comment at the top of the file. */
|
||||
|
||||
/**
|
||||
* Hi class
|
||||
*/
|
||||
class Hi {
|
||||
>Hi : Hi
|
||||
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/test3.ts ===
|
||||
// A one-line comment at the top of the file.
|
||||
|
||||
/**
|
||||
* Hola class
|
||||
*/
|
||||
class Hola {
|
||||
>Hola : Hola
|
||||
|
||||
}
|
||||
|
34
tests/cases/compiler/declarationEmitDetachedComment1.ts
Normal file
34
tests/cases/compiler/declarationEmitDetachedComment1.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
// @target: es5
|
||||
// @module: commonjs
|
||||
// @declaration: true
|
||||
// @removeComments: false
|
||||
|
||||
// @filename: test1.ts
|
||||
/*! Copyright 2015 MyCompany Inc. */
|
||||
|
||||
/**
|
||||
* Hello class
|
||||
*/
|
||||
class Hello {
|
||||
|
||||
}
|
||||
|
||||
// @filename: test2.ts
|
||||
/* A comment at the top of the file. */
|
||||
|
||||
/**
|
||||
* Hi class
|
||||
*/
|
||||
class Hi {
|
||||
|
||||
}
|
||||
|
||||
// @filename: test3.ts
|
||||
// A one-line comment at the top of the file.
|
||||
|
||||
/**
|
||||
* Hola class
|
||||
*/
|
||||
class Hola {
|
||||
|
||||
}
|
34
tests/cases/compiler/declarationEmitDetachedComment2.ts
Normal file
34
tests/cases/compiler/declarationEmitDetachedComment2.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
// @target: es5
|
||||
// @module: commonjs
|
||||
// @declaration: true
|
||||
// @removeComments: true
|
||||
|
||||
// @filename: test1.ts
|
||||
/*! Copyright 2015 MyCompany Inc. */
|
||||
|
||||
/**
|
||||
* Hello class
|
||||
*/
|
||||
class Hello {
|
||||
|
||||
}
|
||||
|
||||
// @filename: test2.ts
|
||||
/* A comment at the top of the file. */
|
||||
|
||||
/**
|
||||
* Hi class
|
||||
*/
|
||||
class Hi {
|
||||
|
||||
}
|
||||
|
||||
// @filename: test3.ts
|
||||
// A one-line comment at the top of the file.
|
||||
|
||||
/**
|
||||
* Hola class
|
||||
*/
|
||||
class Hola {
|
||||
|
||||
}
|
Loading…
Reference in a new issue