From d11fc480665ada08f13767c2d5e8939a570feb88 Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 20 Jul 2015 09:55:04 -0700 Subject: [PATCH] Only remove triple-slash if it is not at top of file --- src/compiler/emitter.ts | 80 +++++++++++++++++++++++---------------- src/compiler/scanner.ts | 8 ++-- src/compiler/utilities.ts | 1 + 3 files changed, 54 insertions(+), 35 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index ba781f4b060..16ad4e2e206 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -6759,17 +6759,48 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi return leadingComments; } - function filterComments(ranges: CommentRange[], onlyPinnedOrTripleSlashComments: boolean): CommentRange[] { - // If we're removing comments, then we want to strip out all but the pinned or - // triple slash comments. - if (ranges && onlyPinnedOrTripleSlashComments) { - ranges = filter(ranges, isPinnedOrTripleSlashComment); - if (ranges.length === 0) { - return undefined; - } - } + function filterComments(ranges: CommentRange[], removeComments: boolean, isTopOfFileComments: boolean): CommentRange[] { + // If removeComments flag is false, then do not filter out any comment + if (!removeComments || !ranges) return ranges; - return ranges; + // IF removeComments flag is true, then filter out comment by following: + // - Pinned comments : keep all + // - /// comments : keep it if the comments are at the top of the file otherwise remove + // - normal comments: remove all + if (removeComments) { + if (isTopOfFileComments) { + ranges = filter(ranges, isTripleSlashOrPinnedComments); + } + else { + ranges = filter(ranges, isPinnedComments); + } + return ranges.length === 0 ? undefined : ranges; + } + } + + function isPinnedComments(comment: CommentRange) { + if (currentSourceFile.text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk) { + return currentSourceFile.text.charCodeAt(comment.pos + 2) === CharacterCodes.exclamation; + } + } + + /** + * Determine if the given comment is a triple-slash or pinned comment + * + * @return true if the comment is a triple-slash comment at the top of the file or a pinned comment else false + **/ + function isTripleSlashOrPinnedComments(comment: CommentRange) { + // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text + // so that we don't end up computing comment string and doing match for all // comments + if (currentSourceFile.text.charCodeAt(comment.pos + 1) === CharacterCodes.slash && + comment.pos + 2 < comment.end && + currentSourceFile.text.charCodeAt(comment.pos + 2) === CharacterCodes.slash) { + let textSubStr = currentSourceFile.text.substring(comment.pos, comment.end); + return textSubStr.match(fullTripleSlashReferencePathRegEx) || + textSubStr.match(fullTripleSlashAMDReferencePathRegEx) ? + true : false; + } + return isPinnedComments(comment); } function getLeadingCommentsToEmit(node: Node) { @@ -6798,27 +6829,27 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } function emitOnlyPinnedOrTripleSlashComments(node: Node) { - emitLeadingCommentsWorker(node, /*onlyPinnedOrTripleSlashComments:*/ true); + emitLeadingCommentsWorker(node, /*removeComments:*/ true); } function emitLeadingComments(node: Node) { - return emitLeadingCommentsWorker(node, /*onlyPinnedOrTripleSlashComments:*/ compilerOptions.removeComments); + return emitLeadingCommentsWorker(node, compilerOptions.removeComments); } - function emitLeadingCommentsWorker(node: Node, onlyPinnedOrTripleSlashComments: boolean) { + function emitLeadingCommentsWorker(node: Node, removeComments: boolean) { // If the caller only wants pinned or triple slash comments, then always filter // down to that set. Otherwise, filter based on the current compiler options. - let leadingComments = filterComments(getLeadingCommentsToEmit(node), onlyPinnedOrTripleSlashComments); + let leadingComments = filterComments(getLeadingCommentsToEmit(node), /*removeComments:*/ removeComments, /*isTopOfFileComments:*/ node.pos === 0); emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments); // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space - emitComments(currentSourceFile, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment); + emitComments(currentSourceFile, writer, leadingComments, /*trailingSeparator:*/ true, newLine, writeComment); } function emitTrailingComments(node: Node) { // Emit the trailing comments only if the parent's end doesn't match - let trailingComments = filterComments(getTrailingCommentsToEmit(node), /*onlyPinnedOrTripleSlashComments:*/ compilerOptions.removeComments); + let trailingComments = filterComments(getTrailingCommentsToEmit(node), /*removeComments*/ compilerOptions.removeComments, /*isTopOfFileComments:*/ node.pos === 0); // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/ emitComments(currentSourceFile, writer, trailingComments, /*trailingSeparator*/ false, newLine, writeComment); @@ -6835,7 +6866,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi leadingComments = getLeadingCommentRanges(currentSourceFile.text, pos); } - leadingComments = filterComments(leadingComments, compilerOptions.removeComments); + leadingComments = filterComments(leadingComments, /*removeComments:*/ compilerOptions.removeComments, pos === 0); emitNewLineBeforeLeadingComments(currentSourceFile, writer, { pos: pos, end: pos }, leadingComments); // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space @@ -6886,21 +6917,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } } } - - function isPinnedOrTripleSlashComment(comment: CommentRange) { - if (currentSourceFile.text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk) { - return currentSourceFile.text.charCodeAt(comment.pos + 2) === CharacterCodes.exclamation; - } - // Omit /// comment if compilerOptions.removeComments is true. - // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text - // so that we don't end up computing comment string and doing match for all // comments - if (!compilerOptions.removeComments && (currentSourceFile.text.charCodeAt(comment.pos + 1) === CharacterCodes.slash && - comment.pos + 2 < comment.end && - currentSourceFile.text.charCodeAt(comment.pos + 2) === CharacterCodes.slash && - currentSourceFile.text.substring(comment.pos, comment.end).match(fullTripleSlashReferencePathRegEx))) { - return true; - } - } } function emitFile(jsFilePath: string, sourceFile?: SourceFile) { diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index a30e23f6170..69090f7bf7f 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -532,9 +532,11 @@ namespace ts { // false, whitespace is skipped until the first line break and comments between that location // and the next token are returned.If trailing is true, comments occurring between the given // position and the next line break are returned.The return value is an array containing a - // TextRange for each comment. Single-line comment ranges include the beginning '//' characters - // but not the ending line break. Multi - line comment ranges include the beginning '/* and - // ending '*/' characters.The return value is undefined if no comments were found. + // TextRange for each comment. + // + // Single - line comment ranges include the beginning '//' characters but not the ending line break. + // Multi - line comment ranges include the beginning '/* and ending '*/' characters. + // The return value is undefined if no comments were found. function getCommentRanges(text: string, pos: number, trailing: boolean): CommentRange[] { let result: CommentRange[]; let collecting = trailing || pos === 0; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 5174589cdcf..437b6ecaf81 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -409,6 +409,7 @@ namespace ts { } export let fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; + export let fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/; export function isTypeNode(node: Node): boolean { if (SyntaxKind.FirstTypeNode <= node.kind && node.kind <= SyntaxKind.LastTypeNode) {