@@ -16,19 +16,39 @@ enum IndentDocCommentState {
1616 /**
1717 * `indentDocComment` was not requested for this subtree.
1818 */
19- Inactive ,
19+ Inactive = 0 ,
2020 /**
2121 * `indentDocComment` was requested and we are looking for the opening `/` `*`
2222 */
23- AwaitingOpenDelimiter ,
23+ AwaitingOpenDelimiter = 1 ,
2424 /**
2525 * `indentDocComment` was requested and we are looking for the closing `*` `/`
2626 */
27- AwaitingCloseDelimiter ,
27+ AwaitingCloseDelimiter = 2 ,
2828 /**
2929 * `indentDocComment` was requested and we have finished indenting the comment.
3030 */
31- Done
31+ Done = 3
32+ }
33+
34+ /**
35+ * Choices for SpanModification.indentDocComment.
36+ */
37+ export enum IndentDocCommentScope {
38+ /**
39+ * Do not detect and indent comments.
40+ */
41+ None = 0 ,
42+
43+ /**
44+ * Look for one doc comment in the {@link Span.prefix} text only.
45+ */
46+ PrefixOnly = 1 ,
47+
48+ /**
49+ * Look for one doc comment potentially distributed across the Span and its children.
50+ */
51+ SpanAndChildren = 2
3252}
3353
3454/**
@@ -61,8 +81,13 @@ export class SpanModification {
6181
6282 /**
6383 * If true, then getModifiedText() will search for a "/*" doc comment in this span and indent it.
84+ *
85+ * @remarks
86+ * This feature is selectively enabled because (1) we do not want to accidentally `/*` appearing
87+ * in a string literal or other expression that is not a comment, and (2) parsing comments is potentially
88+ * expensive.
6489 */
65- public indentDocComment : boolean = false ;
90+ public indentDocComment : IndentDocCommentScope = IndentDocCommentScope . None ;
6691
6792 private readonly _span : Span ;
6893 private _prefix : string | undefined ;
@@ -105,7 +130,9 @@ export class SpanModification {
105130 this . sortKey = undefined ;
106131 this . _prefix = undefined ;
107132 this . _suffix = undefined ;
108- this . indentDocComment = this . _span . kind === ts . SyntaxKind . JSDocComment ;
133+ if ( this . _span . kind === ts . SyntaxKind . JSDocComment ) {
134+ this . indentDocComment = IndentDocCommentScope . SpanAndChildren ;
135+ }
109136 }
110137
111138 /**
@@ -450,36 +477,23 @@ export class Span {
450477 * Recursive implementation of `getModifiedText()` and `writeModifiedText()`.
451478 */
452479 private _writeModifiedText ( options : IWriteModifiedTextOptions ) : void {
453- if ( this . modification . indentDocComment ) {
454- if ( options . indentDocCommentState !== IndentDocCommentState . Inactive ) {
455- throw new InternalError ( 'indentDocComment cannot be nested' ) ;
456- }
457- options . indentDocCommentState = IndentDocCommentState . AwaitingOpenDelimiter ;
458- }
459-
480+ // Apply indentation based on "{" and "}"
460481 if ( this . prefix === '{' ) {
461482 options . writer . increaseIndent ( ) ;
462483 } else if ( this . prefix === '}' ) {
463484 options . writer . decreaseIndent ( ) ;
464485 }
465486
466- this . _writeModifiedTextContent ( options ) ;
467-
468- if ( this . modification . indentDocComment ) {
469- if ( options . indentDocCommentState === IndentDocCommentState . AwaitingCloseDelimiter ) {
470- throw new InternalError ( 'missing "*/" delimiter for comment block' ) ;
471- }
472- options . indentDocCommentState = IndentDocCommentState . Inactive ;
487+ if ( this . modification . indentDocComment !== IndentDocCommentScope . None ) {
488+ this . _beginIndentDocComment ( options ) ;
473489 }
474- }
475490
476- /**
477- * This is a helper for `_writeModifiedText()`. `_writeModifiedText()` configures indentation
478- * whereas `_writeModifiedTextContent()` does the actual writing.
479- */
480- private _writeModifiedTextContent ( options : IWriteModifiedTextOptions ) : void {
481491 this . _write ( this . modification . prefix , options ) ;
482492
493+ if ( this . modification . indentDocComment === IndentDocCommentScope . PrefixOnly ) {
494+ this . _endIndentDocComment ( options ) ;
495+ }
496+
483497 let sortedSubset : Span [ ] | undefined ;
484498
485499 if ( ! this . modification . omitChildren ) {
@@ -573,6 +587,24 @@ export class Span {
573587 }
574588 }
575589 }
590+
591+ if ( this . modification . indentDocComment === IndentDocCommentScope . SpanAndChildren ) {
592+ this . _endIndentDocComment ( options ) ;
593+ }
594+ }
595+
596+ private _beginIndentDocComment ( options : IWriteModifiedTextOptions ) : void {
597+ if ( options . indentDocCommentState !== IndentDocCommentState . Inactive ) {
598+ throw new InternalError ( 'indentDocComment cannot be nested' ) ;
599+ }
600+ options . indentDocCommentState = IndentDocCommentState . AwaitingOpenDelimiter ;
601+ }
602+
603+ private _endIndentDocComment ( options : IWriteModifiedTextOptions ) : void {
604+ if ( options . indentDocCommentState === IndentDocCommentState . AwaitingCloseDelimiter ) {
605+ throw new InternalError ( 'missing "*/" delimiter for comment block' ) ;
606+ }
607+ options . indentDocCommentState = IndentDocCommentState . Inactive ;
576608 }
577609
578610 /**
0 commit comments