@@ -186,6 +186,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
186186 /** Sourcemap data that will get encoded */
187187 let sourceMapData : SourceMapData ;
188188
189+ /** If removeComments is true, no leading-comments needed to be emitted **/
190+ let emitLeadingCommentsOfPosition = compilerOptions . removeComments ? function ( pos : number ) { } : emitLeadingCommentsOfPositionWorker ;
191+
189192 if ( compilerOptions . sourceMap || compilerOptions . inlineSourceMap ) {
190193 initializeEmitterWithSourceMaps ( ) ;
191194 }
@@ -3669,7 +3672,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
36693672
36703673 function emitFunctionDeclaration ( node : FunctionLikeDeclaration ) {
36713674 if ( nodeIsMissing ( node . body ) ) {
3672- return emitOnlyPinnedOrTripleSlashComments ( node ) ;
3675+ return emitCommentsOnNotEmittedNode ( node ) ;
36733676 }
36743677
36753678 // TODO (yuisu) : we should not have special cases to condition emitting comments
@@ -4146,7 +4149,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
41464149 }
41474150 else if ( member . kind === SyntaxKind . MethodDeclaration || node . kind === SyntaxKind . MethodSignature ) {
41484151 if ( ! ( < MethodDeclaration > member ) . body ) {
4149- return emitOnlyPinnedOrTripleSlashComments ( member ) ;
4152+ return emitCommentsOnNotEmittedNode ( member ) ;
41504153 }
41514154
41524155 writeLine ( ) ;
@@ -4213,7 +4216,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
42134216 function emitMemberFunctionsForES6AndHigher ( node : ClassLikeDeclaration ) {
42144217 for ( let member of node . members ) {
42154218 if ( ( member . kind === SyntaxKind . MethodDeclaration || node . kind === SyntaxKind . MethodSignature ) && ! ( < MethodDeclaration > member ) . body ) {
4216- emitOnlyPinnedOrTripleSlashComments ( member ) ;
4219+ emitCommentsOnNotEmittedNode ( member ) ;
42174220 }
42184221 else if ( member . kind === SyntaxKind . MethodDeclaration ||
42194222 member . kind === SyntaxKind . GetAccessor ||
@@ -4270,7 +4273,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
42704273 // Emit the constructor overload pinned comments
42714274 forEach ( node . members , member => {
42724275 if ( member . kind === SyntaxKind . Constructor && ! ( < ConstructorDeclaration > member ) . body ) {
4273- emitOnlyPinnedOrTripleSlashComments ( member ) ;
4276+ emitCommentsOnNotEmittedNode ( member ) ;
42744277 }
42754278 // Check if there is any non-static property assignment
42764279 if ( member . kind === SyntaxKind . PropertyDeclaration && ( < PropertyDeclaration > member ) . initializer && ( member . flags & NodeFlags . Static ) === 0 ) {
@@ -5169,7 +5172,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
51695172 }
51705173
51715174 function emitInterfaceDeclaration ( node : InterfaceDeclaration ) {
5172- emitOnlyPinnedOrTripleSlashComments ( node ) ;
5175+ emitCommentsOnNotEmittedNode ( node ) ;
51735176 }
51745177
51755178 function shouldEmitEnumDeclaration ( node : EnumDeclaration ) {
@@ -5291,7 +5294,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
52915294 let shouldEmit = shouldEmitModuleDeclaration ( node ) ;
52925295
52935296 if ( ! shouldEmit ) {
5294- return emitOnlyPinnedOrTripleSlashComments ( node ) ;
5297+ return emitCommentsOnNotEmittedNode ( node ) ;
52955298 }
52965299 let hoistedInDeclarationScope = shouldHoistDeclarationInSystemJsModule ( node ) ;
52975300 let emitVarForModule = ! hoistedInDeclarationScope && ! isModuleMergedWithES6Class ( node ) ;
@@ -6721,7 +6724,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
67216724 function emitNodeConsideringCommentsOption ( node : Node , emitNodeConsideringSourcemap : ( node : Node ) => void ) : void {
67226725 if ( node ) {
67236726 if ( node . flags & NodeFlags . Ambient ) {
6724- return emitOnlyPinnedOrTripleSlashComments ( node ) ;
6727+ return emitCommentsOnNotEmittedNode ( node ) ;
67256728 }
67266729
67276730 if ( isSpecializedCommentHandling ( node ) ) {
@@ -6988,22 +6991,28 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
69886991 return leadingComments ;
69896992 }
69906993
6994+ function isPinnedComments ( comment : CommentRange ) {
6995+ return currentSourceFile . text . charCodeAt ( comment . pos + 1 ) === CharacterCodes . asterisk &&
6996+ currentSourceFile . text . charCodeAt ( comment . pos + 2 ) === CharacterCodes . exclamation ;
6997+ }
6998+
69916999 /**
6992- * Removes all but the pinned or triple slash comments.
6993- * @param ranges The array to be filtered
6994- * @param onlyPinnedOrTripleSlashComments whether the filtering should be performed.
6995- */
6996- function filterComments ( ranges : CommentRange [ ] , onlyPinnedOrTripleSlashComments : boolean ) : CommentRange [ ] {
6997- // If we're removing comments, then we want to strip out all but the pinned or
6998- // triple slash comments.
6999- if ( ranges && onlyPinnedOrTripleSlashComments ) {
7000- ranges = filter ( ranges , isPinnedOrTripleSlashComment ) ;
7001- if ( ranges . length === 0 ) {
7002- return undefined ;
7003- }
7000+ * Determine if the given comment is a triple-slash
7001+ *
7002+ * @return true if the comment is a triple-slash comment else false
7003+ **/
7004+ function isTripleSlashComment ( comment : CommentRange ) {
7005+ // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text
7006+ // so that we don't end up computing comment string and doing match for all // comments
7007+ if ( currentSourceFile . text . charCodeAt ( comment . pos + 1 ) === CharacterCodes . slash &&
7008+ comment . pos + 2 < comment . end &&
7009+ currentSourceFile . text . charCodeAt ( comment . pos + 2 ) === CharacterCodes . slash ) {
7010+ let textSubStr = currentSourceFile . text . substring ( comment . pos , comment . end ) ;
7011+ return textSubStr . match ( fullTripleSlashReferencePathRegEx ) ||
7012+ textSubStr . match ( fullTripleSlashAMDReferencePathRegEx ) ?
7013+ true : false ;
70047014 }
7005-
7006- return ranges ;
7015+ return false ;
70077016 }
70087017
70097018 function getLeadingCommentsToEmit ( node : Node ) {
@@ -7031,28 +7040,53 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
70317040 }
70327041 }
70337042
7034- function emitOnlyPinnedOrTripleSlashComments ( node : Node ) {
7035- emitLeadingCommentsWorker ( node , /*onlyPinnedOrTripleSlashComments:*/ true ) ;
7043+ /**
7044+ * Emit comments associated with node that will not be emitted into JS file
7045+ */
7046+ function emitCommentsOnNotEmittedNode ( node : Node ) {
7047+ emitLeadingCommentsWorker ( node , /*isEmittedNode:*/ false ) ;
70367048 }
70377049
70387050 function emitLeadingComments ( node : Node ) {
7039- return emitLeadingCommentsWorker ( node , /*onlyPinnedOrTripleSlashComments :*/ compilerOptions . removeComments ) ;
7051+ return emitLeadingCommentsWorker ( node , /*isEmittedNode :*/ true ) ;
70407052 }
70417053
7042- function emitLeadingCommentsWorker ( node : Node , onlyPinnedOrTripleSlashComments : boolean ) {
7043- // If the caller only wants pinned or triple slash comments, then always filter
7044- // down to that set. Otherwise, filter based on the current compiler options.
7045- let leadingComments = filterComments ( getLeadingCommentsToEmit ( node ) , onlyPinnedOrTripleSlashComments ) ;
7054+ function emitLeadingCommentsWorker ( node : Node , isEmittedNode : boolean ) {
7055+ if ( compilerOptions . removeComments ) {
7056+ return ;
7057+ }
7058+
7059+ let leadingComments : CommentRange [ ] ;
7060+ if ( isEmittedNode ) {
7061+ leadingComments = getLeadingCommentsToEmit ( node ) ;
7062+ }
7063+ else {
7064+ // If the node will not be emitted in JS, remove all the comments(normal, pinned and ///) associated with the node,
7065+ // unless it is a triple slash comment at the top of the file.
7066+ // For Example:
7067+ // /// <reference-path ...>
7068+ // declare var x;
7069+ // /// <reference-path ...>
7070+ // interface F {}
7071+ // The first /// will NOT be removed while the second one will be removed eventhough both node will not be emitted
7072+ if ( node . pos === 0 ) {
7073+ leadingComments = filter ( getLeadingCommentsToEmit ( node ) , isTripleSlashComment ) ;
7074+ }
7075+ }
70467076
70477077 emitNewLineBeforeLeadingComments ( currentSourceFile , writer , node , leadingComments ) ;
70487078
70497079 // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
7050- emitComments ( currentSourceFile , writer , leadingComments , /*trailingSeparator*/ true , newLine , writeComment ) ;
7080+ emitComments ( currentSourceFile , writer , leadingComments , /*trailingSeparator: */ true , newLine , writeComment ) ;
70517081 }
70527082
70537083 function emitTrailingComments ( node : Node ) {
7084+ if ( compilerOptions . removeComments ) {
7085+ return ;
7086+ }
7087+
70547088 // Emit the trailing comments only if the parent's end doesn't match
7055- let trailingComments = filterComments ( getTrailingCommentsToEmit ( node ) , /*onlyPinnedOrTripleSlashComments:*/ compilerOptions . removeComments ) ;
7089+ let trailingComments = getTrailingCommentsToEmit ( node ) ;
70567090
70577091 // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
70587092 emitComments ( currentSourceFile , writer , trailingComments , /*trailingSeparator*/ false , newLine , writeComment ) ;
@@ -7064,13 +7098,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
70647098 * ^ => pos; the function will emit "comment1" in the emitJS
70657099 */
70667100 function emitTrailingCommentsOfPosition ( pos : number ) {
7067- let trailingComments = filterComments ( getTrailingCommentRanges ( currentSourceFile . text , pos ) , /*onlyPinnedOrTripleSlashComments:*/ compilerOptions . removeComments ) ;
7101+ if ( compilerOptions . removeComments ) {
7102+ return ;
7103+ }
7104+
7105+ let trailingComments = getTrailingCommentRanges ( currentSourceFile . text , pos ) ;
70687106
70697107 // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
70707108 emitComments ( currentSourceFile , writer , trailingComments , /*trailingSeparator*/ true , newLine , writeComment ) ;
70717109 }
70727110
7073- function emitLeadingCommentsOfPosition ( pos : number ) {
7111+ function emitLeadingCommentsOfPositionWorker ( pos : number ) {
7112+ if ( compilerOptions . removeComments ) {
7113+ return ;
7114+ }
7115+
70747116 let leadingComments : CommentRange [ ] ;
70757117 if ( hasDetachedComments ( pos ) ) {
70767118 // get comments without detached comments
@@ -7081,15 +7123,29 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
70817123 leadingComments = getLeadingCommentRanges ( currentSourceFile . text , pos ) ;
70827124 }
70837125
7084- leadingComments = filterComments ( leadingComments , compilerOptions . removeComments ) ;
70857126 emitNewLineBeforeLeadingComments ( currentSourceFile , writer , { pos : pos , end : pos } , leadingComments ) ;
70867127
70877128 // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
70887129 emitComments ( currentSourceFile , writer , leadingComments , /*trailingSeparator*/ true , newLine , writeComment ) ;
70897130 }
70907131
70917132 function emitDetachedComments ( node : TextRange ) {
7092- let leadingComments = getLeadingCommentRanges ( currentSourceFile . text , node . pos ) ;
7133+ let leadingComments : CommentRange [ ] ;
7134+ if ( compilerOptions . removeComments ) {
7135+ // removeComments is true, only reserve pinned comment at the top of file
7136+ // For example:
7137+ // /*! Pinned Comment */
7138+ //
7139+ // var x = 10;
7140+ if ( node . pos === 0 ) {
7141+ leadingComments = filter ( getLeadingCommentRanges ( currentSourceFile . text , node . pos ) , isPinnedComments ) ;
7142+ }
7143+ }
7144+ else {
7145+ // removeComments is false, just get detached as normal and bypass the process to filter comment
7146+ leadingComments = getLeadingCommentRanges ( currentSourceFile . text , node . pos ) ;
7147+ }
7148+
70937149 if ( leadingComments ) {
70947150 let detachedComments : CommentRange [ ] = [ ] ;
70957151 let lastComment : CommentRange ;
@@ -7139,20 +7195,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
71397195 write ( shebang ) ;
71407196 }
71417197 }
7142-
7143- function isPinnedOrTripleSlashComment ( comment : CommentRange ) {
7144- if ( currentSourceFile . text . charCodeAt ( comment . pos + 1 ) === CharacterCodes . asterisk ) {
7145- return currentSourceFile . text . charCodeAt ( comment . pos + 2 ) === CharacterCodes . exclamation ;
7146- }
7147- // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text
7148- // so that we don't end up computing comment string and doing match for all // comments
7149- else if ( currentSourceFile . text . charCodeAt ( comment . pos + 1 ) === CharacterCodes . slash &&
7150- comment . pos + 2 < comment . end &&
7151- currentSourceFile . text . charCodeAt ( comment . pos + 2 ) === CharacterCodes . slash &&
7152- currentSourceFile . text . substring ( comment . pos , comment . end ) . match ( fullTripleSlashReferencePathRegEx ) ) {
7153- return true ;
7154- }
7155- }
71567198 }
71577199
71587200 function emitFile ( jsFilePath : string , sourceFile ?: SourceFile ) {
0 commit comments