@@ -336,6 +336,9 @@ module ts {
336
336
/** Emit detached comments of the node */
337
337
var emitDetachedComments = compilerOptions . removeComments ? ( node : TextRange ) => { } : emitDetachedCommentsAtPosition ;
338
338
339
+ /** Emits /// or pinned which is comment starting with /*! comments */
340
+ var emitPinnedOrTripleSlashComments = compilerOptions . removeComments ? ( node : Node ) => { } : emitPinnedOrTripleSlashCommentsOfNode ;
341
+
339
342
var writeComment = writeCommentRange ;
340
343
341
344
/** Emit a node */
@@ -1318,7 +1321,10 @@ module ts {
1318
1321
}
1319
1322
1320
1323
function emitFunctionDeclaration ( node : FunctionDeclaration ) {
1321
- if ( ! node . body ) return ;
1324
+ if ( ! node . body ) {
1325
+ return emitPinnedOrTripleSlashComments ( node ) ;
1326
+ }
1327
+
1322
1328
if ( node . kind !== SyntaxKind . Method ) {
1323
1329
// Methods will emit the comments as part of emitting method declaration
1324
1330
emitLeadingComments ( node ) ;
@@ -1488,7 +1494,10 @@ module ts {
1488
1494
function emitMemberFunctions ( node : ClassDeclaration ) {
1489
1495
forEach ( node . members , member => {
1490
1496
if ( member . kind === SyntaxKind . Method ) {
1491
- if ( ! ( < MethodDeclaration > member ) . body ) return ;
1497
+ if ( ! ( < MethodDeclaration > member ) . body ) {
1498
+ return emitPinnedOrTripleSlashComments ( member ) ;
1499
+ }
1500
+
1492
1501
writeLine ( ) ;
1493
1502
emitLeadingComments ( member ) ;
1494
1503
emitStart ( member ) ;
@@ -1611,6 +1620,13 @@ module ts {
1611
1620
emitTrailingComments ( node ) ;
1612
1621
1613
1622
function emitConstructorOfClass ( ) {
1623
+ // Emit the constructor overload pinned comments
1624
+ forEach ( node . members , member => {
1625
+ if ( member . kind === SyntaxKind . Constructor && ! ( < ConstructorDeclaration > member ) . body ) {
1626
+ emitPinnedOrTripleSlashComments ( member ) ;
1627
+ }
1628
+ } ) ;
1629
+
1614
1630
var ctor = getFirstConstructorWithBody ( node ) ;
1615
1631
if ( ctor ) {
1616
1632
emitLeadingComments ( ctor ) ;
@@ -2101,7 +2117,7 @@ module ts {
2101
2117
return leadingComments ;
2102
2118
}
2103
2119
2104
- function emitLeadingDeclarationComments ( node : Node ) {
2120
+ function getLeadingCommentsToEmit ( node : Node ) {
2105
2121
// Emit the leading comments only if the parent's pos doesnt match because parent should take care of emitting these comments
2106
2122
if ( node . parent . kind === SyntaxKind . SourceFile || node . pos !== node . parent . pos ) {
2107
2123
var leadingComments : Comment [ ] ;
@@ -2113,12 +2129,17 @@ module ts {
2113
2129
// get the leading comments from the node
2114
2130
leadingComments = getLeadingCommentsOfNode ( node , currentSourceFile ) ;
2115
2131
}
2116
- emitNewLineBeforeLeadingComments ( node , leadingComments , writer ) ;
2117
- // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
2118
- emitComments ( leadingComments , /*trailingSeparator*/ true , writer , writeComment ) ;
2132
+ return leadingComments ;
2119
2133
}
2120
2134
}
2121
2135
2136
+ function emitLeadingDeclarationComments ( node : Node ) {
2137
+ var leadingComments = getLeadingCommentsToEmit ( node ) ;
2138
+ emitNewLineBeforeLeadingComments ( node , leadingComments , writer ) ;
2139
+ // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
2140
+ emitComments ( leadingComments , /*trailingSeparator*/ true , writer , writeComment ) ;
2141
+ }
2142
+
2122
2143
function emitTrailingDeclarationComments ( node : Node ) {
2123
2144
// Emit the trailing comments only if the parent's end doesnt match
2124
2145
if ( node . parent . kind === SyntaxKind . SourceFile || node . end !== node . parent . end ) {
@@ -2166,7 +2187,7 @@ module ts {
2166
2187
lastComment = comment ;
2167
2188
} ) ;
2168
2189
2169
- if ( detachedComments && detachedComments . length ) {
2190
+ if ( detachedComments . length ) {
2170
2191
// All comments look like they could have been part of the copyright header. Make
2171
2192
// sure there is at least one blank line between it and the node. If not, it's not
2172
2193
// a copyright header.
@@ -2188,6 +2209,28 @@ module ts {
2188
2209
}
2189
2210
}
2190
2211
2212
+ function emitPinnedOrTripleSlashCommentsOfNode ( node : Node ) {
2213
+ var pinnedComments = ts . filter ( getLeadingCommentsToEmit ( node ) , isPinnedOrTripleSlashComment ) ;
2214
+
2215
+ function isPinnedOrTripleSlashComment ( comment : Comment ) {
2216
+ if ( currentSourceFile . text . charCodeAt ( comment . pos + 1 ) === CharacterCodes . asterisk ) {
2217
+ return currentSourceFile . text . charCodeAt ( comment . pos + 2 ) === CharacterCodes . exclamation ;
2218
+ }
2219
+ // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text
2220
+ // so that we dont end up computing comment string and doing match for all // comments
2221
+ else if ( currentSourceFile . text . charCodeAt ( comment . pos + 1 ) === CharacterCodes . slash &&
2222
+ comment . pos + 2 < comment . end &&
2223
+ currentSourceFile . text . charCodeAt ( comment . pos + 2 ) === CharacterCodes . slash &&
2224
+ currentSourceFile . text . substring ( comment . pos , comment . end ) . match ( fullTripleSlashReferencePathRegEx ) ) {
2225
+ return true ;
2226
+ }
2227
+ }
2228
+
2229
+ emitNewLineBeforeLeadingComments ( node , pinnedComments , writer ) ;
2230
+ // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
2231
+ emitComments ( pinnedComments , /*trailingSeparator*/ true , writer , writeComment ) ;
2232
+ }
2233
+
2191
2234
if ( compilerOptions . sourceMap ) {
2192
2235
initializeEmitterWithSourceMaps ( ) ;
2193
2236
}
0 commit comments