-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Do not emit /// comments when remove comments is specified #3883
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6fd267c
24eea03
87c1c65
675aa02
d11fc48
ed5bc31
880202d
deb6eee
7950cc7
248d857
5d15218
21ebc71
4b7e2b3
3f66968
8eff741
c851a60
eda9aea
c88908e
e36285c
40cbd33
cb8ad4f
666d8d4
1854adb
40f05b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -190,6 +190,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi | |
| /** Sourcemap data that will get encoded */ | ||
| let sourceMapData: SourceMapData; | ||
|
|
||
| /** If removeComments is true, no leading-comments needed to be emitted **/ | ||
| let emitLeadingCommentsOfPosition = compilerOptions.removeComments ? function (pos: number) { } : emitLeadingCommentsOfPositionWorker; | ||
|
|
||
| if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) { | ||
| initializeEmitterWithSourceMaps(); | ||
| } | ||
|
|
@@ -3664,7 +3667,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi | |
|
|
||
| function emitFunctionDeclaration(node: FunctionLikeDeclaration) { | ||
| if (nodeIsMissing(node.body)) { | ||
| return emitOnlyPinnedOrTripleSlashComments(node); | ||
| return emitCommentsOnNotEmittedNode(node); | ||
| } | ||
|
|
||
| // TODO (yuisu) : we should not have special cases to condition emitting comments | ||
|
|
@@ -4141,7 +4144,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi | |
| } | ||
| else if (member.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature) { | ||
| if (!(<MethodDeclaration>member).body) { | ||
| return emitOnlyPinnedOrTripleSlashComments(member); | ||
| return emitCommentsOnNotEmittedNode(member); | ||
| } | ||
|
|
||
| writeLine(); | ||
|
|
@@ -4208,7 +4211,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi | |
| function emitMemberFunctionsForES6AndHigher(node: ClassLikeDeclaration) { | ||
| for (let member of node.members) { | ||
| if ((member.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature) && !(<MethodDeclaration>member).body) { | ||
| emitOnlyPinnedOrTripleSlashComments(member); | ||
| emitCommentsOnNotEmittedNode(member); | ||
| } | ||
| else if (member.kind === SyntaxKind.MethodDeclaration || | ||
| member.kind === SyntaxKind.GetAccessor || | ||
|
|
@@ -4265,7 +4268,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi | |
| // Emit the constructor overload pinned comments | ||
| forEach(node.members, member => { | ||
| if (member.kind === SyntaxKind.Constructor && !(<ConstructorDeclaration>member).body) { | ||
| emitOnlyPinnedOrTripleSlashComments(member); | ||
| emitCommentsOnNotEmittedNode(member); | ||
| } | ||
| // Check if there is any non-static property assignment | ||
| if (member.kind === SyntaxKind.PropertyDeclaration && (<PropertyDeclaration>member).initializer && (member.flags & NodeFlags.Static) === 0) { | ||
|
|
@@ -5166,7 +5169,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi | |
| } | ||
|
|
||
| function emitInterfaceDeclaration(node: InterfaceDeclaration) { | ||
| emitOnlyPinnedOrTripleSlashComments(node); | ||
| emitCommentsOnNotEmittedNode(node); | ||
| } | ||
|
|
||
| function shouldEmitEnumDeclaration(node: EnumDeclaration) { | ||
|
|
@@ -5288,7 +5291,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi | |
| let shouldEmit = shouldEmitModuleDeclaration(node); | ||
|
|
||
| if (!shouldEmit) { | ||
| return emitOnlyPinnedOrTripleSlashComments(node); | ||
| return emitCommentsOnNotEmittedNode(node); | ||
| } | ||
| let hoistedInDeclarationScope = shouldHoistDeclarationInSystemJsModule(node); | ||
| let emitVarForModule = !hoistedInDeclarationScope && !isModuleMergedWithES6Class(node); | ||
|
|
@@ -6718,7 +6721,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi | |
| function emitNodeConsideringCommentsOption(node: Node, emitNodeConsideringSourcemap: (node: Node) => void): void { | ||
| if (node) { | ||
| if (node.flags & NodeFlags.Ambient) { | ||
| return emitOnlyPinnedOrTripleSlashComments(node); | ||
| return emitCommentsOnNotEmittedNode(node); | ||
| } | ||
|
|
||
| if (isSpecializedCommentHandling(node)) { | ||
|
|
@@ -6985,22 +6988,28 @@ 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; | ||
| } | ||
|
|
||
| /** | ||
| * Removes all but the pinned or triple slash comments. | ||
| * @param ranges The array to be filtered | ||
| * @param onlyPinnedOrTripleSlashComments whether the filtering should be performed. | ||
| */ | ||
| 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; | ||
| } | ||
| * Determine if the given comment is a triple-slash | ||
| * | ||
| * @return true if the comment is a triple-slash comment else false | ||
| **/ | ||
| function isTripleSlashComment(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 ranges; | ||
| return false; | ||
| } | ||
|
|
||
| function getLeadingCommentsToEmit(node: Node) { | ||
|
|
@@ -7028,28 +7037,53 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi | |
| } | ||
| } | ||
|
|
||
| function emitOnlyPinnedOrTripleSlashComments(node: Node) { | ||
| emitLeadingCommentsWorker(node, /*onlyPinnedOrTripleSlashComments:*/ true); | ||
| /** | ||
| * Emit comments associated with node that will not be emitted into JS file | ||
| */ | ||
| function emitCommentsOnNotEmittedNode(node: Node) { | ||
| emitLeadingCommentsWorker(node, /*isEmittedNode:*/ false); | ||
| } | ||
|
|
||
| function emitLeadingComments(node: Node) { | ||
| return emitLeadingCommentsWorker(node, /*onlyPinnedOrTripleSlashComments:*/ compilerOptions.removeComments); | ||
| return emitLeadingCommentsWorker(node, /*isEmittedNode:*/ true); | ||
| } | ||
|
|
||
| function emitLeadingCommentsWorker(node: Node, onlyPinnedOrTripleSlashComments: 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); | ||
| function emitLeadingCommentsWorker(node: Node, isEmittedNode: boolean) { | ||
| if (compilerOptions.removeComments) { | ||
| return; | ||
| } | ||
|
|
||
| let leadingComments: CommentRange[]; | ||
| if (isEmittedNode) { | ||
| leadingComments = getLeadingCommentsToEmit(node); | ||
| } | ||
| else { | ||
| // If the node will not be emitted in JS, remove all the comments(normal, pinned and ///) associated with the node, | ||
| // unless it is a triple slash comment at the top of the file. | ||
| // For Example: | ||
| // /// <reference-path ...> | ||
| // declare var x; | ||
| // /// <reference-path ...> | ||
| // interface F {} | ||
| // The first /// will NOT be removed while the second one will be removed eventhough both node will not be emitted | ||
| if (node.pos === 0) { | ||
| leadingComments = filter(getLeadingCommentsToEmit(node), isTripleSlashComment); | ||
| } | ||
| } | ||
|
|
||
| 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) { | ||
| if (compilerOptions.removeComments) { | ||
| return; | ||
| } | ||
|
|
||
| // Emit the trailing comments only if the parent's end doesn't match | ||
| let trailingComments = filterComments(getTrailingCommentsToEmit(node), /*onlyPinnedOrTripleSlashComments:*/ compilerOptions.removeComments); | ||
| let trailingComments = getTrailingCommentsToEmit(node); | ||
|
|
||
| // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/ | ||
| emitComments(currentSourceFile, writer, trailingComments, /*trailingSeparator*/ false, newLine, writeComment); | ||
|
|
@@ -7061,13 +7095,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi | |
| * ^ => pos; the function will emit "comment1" in the emitJS | ||
| */ | ||
| function emitTrailingCommentsOfPosition(pos: number) { | ||
| let trailingComments = filterComments(getTrailingCommentRanges(currentSourceFile.text, pos), /*onlyPinnedOrTripleSlashComments:*/ compilerOptions.removeComments); | ||
| if (compilerOptions.removeComments) { | ||
| return; | ||
| } | ||
|
|
||
| let trailingComments = getTrailingCommentRanges(currentSourceFile.text, pos); | ||
|
|
||
| // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/ | ||
| emitComments(currentSourceFile, writer, trailingComments, /*trailingSeparator*/ true, newLine, writeComment); | ||
| } | ||
|
|
||
| function emitLeadingCommentsOfPosition(pos: number) { | ||
| function emitLeadingCommentsOfPositionWorker(pos: number) { | ||
| if (compilerOptions.removeComments) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of doing this can you make emitLeadingCommentsOfPosition a function pointer. It helps with the perf since that check happens just once. Do this for other functions that do nothing when remove comments too. emitLeadingCommentsOfPosition = compilerOptions.removeComments ? function (pos: number) { } : emitLeadingOCmmentsOfPositionWorker |
||
| return; | ||
| } | ||
|
|
||
| let leadingComments: CommentRange[]; | ||
| if (hasDetachedComments(pos)) { | ||
| // get comments without detached comments | ||
|
|
@@ -7078,15 +7120,29 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi | |
| leadingComments = getLeadingCommentRanges(currentSourceFile.text, pos); | ||
| } | ||
|
|
||
| leadingComments = filterComments(leadingComments, compilerOptions.removeComments); | ||
| emitNewLineBeforeLeadingComments(currentSourceFile, writer, { pos: pos, end: pos }, leadingComments); | ||
|
|
||
| // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space | ||
| emitComments(currentSourceFile, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment); | ||
| } | ||
|
|
||
| function emitDetachedComments(node: TextRange) { | ||
| let leadingComments = getLeadingCommentRanges(currentSourceFile.text, node.pos); | ||
| let leadingComments: CommentRange[]; | ||
| if (compilerOptions.removeComments) { | ||
| // removeComments is true, only reserve pinned comment at the top of file | ||
| // For example: | ||
| // /*! Pinned Comment */ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems wrong (and seems like a very strange thing to explain to people using the product). "We will preserve pinned comments. But only at the very top of a file". It also seems like we'll be breaking people who use pinned comments today (a feature we added precisely for people that wanted to use --removeComments, but who wanted some comments to remain). |
||
| // | ||
| // 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); | ||
| } | ||
|
|
||
| if (leadingComments) { | ||
| let detachedComments: CommentRange[] = []; | ||
| let lastComment: CommentRange; | ||
|
|
@@ -7136,20 +7192,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi | |
| write(shebang); | ||
| } | ||
| } | ||
|
|
||
| function isPinnedOrTripleSlashComment(comment: CommentRange) { | ||
| if (currentSourceFile.text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk) { | ||
| return currentSourceFile.text.charCodeAt(comment.pos + 2) === CharacterCodes.exclamation; | ||
| } | ||
| // 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 | ||
| else if (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) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,12 @@ | ||
| //// [tests/cases/compiler/commentOnAmbientClass1.ts] //// | ||
|
|
||
| //// [a.ts] | ||
| /*! Keep this pinned comment */ | ||
| /*!========= | ||
| Keep this pinned comment | ||
| ========= | ||
| */ | ||
|
|
||
| /*! Don't keep this pinned comment */ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this looks interesting. probably needs to update the test.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What you mean by update the test?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the comment text in all tests says "Don't keep this comment" but it shows. is this intended?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But this is the ts file. The Js file below shows as expected
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would we not keep the pinned comment. The |
||
| declare class C { | ||
| } | ||
|
|
||
|
|
@@ -15,6 +20,9 @@ declare class E extends C { | |
| } | ||
|
|
||
| //// [a.js] | ||
| /*! Keep this pinned comment */ | ||
| /*!========= | ||
| Keep this pinned comment | ||
| ========= | ||
| */ | ||
| //// [b.js] | ||
| ///<reference path="a.ts"/> | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is concerning.