11/* @internal  */ 
22namespace  ts . codefix  { 
33    const  fixId  =  "disableJsDiagnostics" ; 
4-     const  errorCodes  =  mapDefined ( Object . keys ( Diagnostics ) ,  key  =>  { 
5-         const  diag  =  ( Diagnostics   as   MapLike < DiagnosticMessage > ) [ key ] ; 
4+     const  errorCodes  =  mapDefined ( Object . keys ( Diagnostics )   as   ReadonlyArray < keyof   typeof   Diagnostics > ,  key  =>  { 
5+         const  diag  =  Diagnostics [ key ] ; 
66        return  diag . category  ===  DiagnosticCategory . Error  ? diag . code  : undefined ; 
77    } ) ; 
88
@@ -19,7 +19,7 @@ namespace ts.codefix {
1919
2020            return  [ { 
2121                description : getLocaleSpecificMessage ( Diagnostics . Ignore_this_error_message ) , 
22-                 changes : [ createFileTextChanges ( sourceFile . fileName ,  [ getIgnoreCommentLocationForLocation ( sourceFile ,  span . start ,  newLineCharacter ) ] ) ] , 
22+                 changes : [ createFileTextChanges ( sourceFile . fileName ,  [ getIgnoreCommentLocationForLocation ( sourceFile ,  span . start ,  newLineCharacter ) . change ] ) ] , 
2323                fixId, 
2424            } , 
2525            { 
@@ -35,17 +35,23 @@ namespace ts.codefix {
3535                fixId : undefined , 
3636            } ] ; 
3737        } , 
38-         fixIds : [ fixId ] ,  // No point applying as a group, doing it once will fix all errors 
39-         getAllCodeActions : context  =>  codeFixAllWithTextChanges ( context ,  errorCodes ,  ( changes ,  err )  =>  { 
40-             if  ( err . start  !==  undefined )  { 
41-                 changes . push ( getIgnoreCommentLocationForLocation ( err . file ! ,  err . start ,  getNewLineOrDefaultFromHost ( context . host ,  context . formatContext . options ) ) ) ; 
42-             } 
43-         } ) , 
38+         fixIds : [ fixId ] , 
39+         getAllCodeActions : context  =>  { 
40+             const  seenLines  =  createMap < true > ( ) ;  // Only need to add `// @ts-ignore` for a line once. 
41+             return  codeFixAllWithTextChanges ( context ,  errorCodes ,  ( changes ,  err )  =>  { 
42+                 if  ( err . start  !==  undefined )  { 
43+                     const  {  lineNumber,  change }  =  getIgnoreCommentLocationForLocation ( err . file ! ,  err . start ,  getNewLineOrDefaultFromHost ( context . host ,  context . formatContext . options ) ) ; 
44+                     if  ( addToSeen ( seenLines ,  lineNumber ) )  { 
45+                         changes . push ( change ) ; 
46+                     } 
47+                 } 
48+             } ) ; 
49+         } , 
4450    } ) ; 
4551
46-     function  getIgnoreCommentLocationForLocation ( sourceFile : SourceFile ,  position : number ,  newLineCharacter : string ) : TextChange  { 
47-         const  {  line }  =  getLineAndCharacterOfPosition ( sourceFile ,  position ) ; 
48-         const  lineStartPosition  =  getStartPositionOfLine ( line ,  sourceFile ) ; 
52+     function  getIgnoreCommentLocationForLocation ( sourceFile : SourceFile ,  position : number ,  newLineCharacter : string ) : {   lineNumber :  number ,   change :  TextChange   }  { 
53+         const  {  line :  lineNumber  }  =  getLineAndCharacterOfPosition ( sourceFile ,  position ) ; 
54+         const  lineStartPosition  =  getStartPositionOfLine ( lineNumber ,  sourceFile ) ; 
4955        const  startPosition  =  getFirstNonSpaceCharacterPosition ( sourceFile . text ,  lineStartPosition ) ; 
5056
5157        // First try to see if we can put the '// @ts-ignore' on the previous line. 
@@ -54,19 +60,17 @@ namespace ts.codefix {
5460        // if so, we do not want to separate the node from its comment if we can. 
5561        if  ( ! isInComment ( sourceFile ,  startPosition )  &&  ! isInString ( sourceFile ,  startPosition )  &&  ! isInTemplateString ( sourceFile ,  startPosition ) )  { 
5662            const  token  =  getTouchingToken ( sourceFile ,  startPosition ,  /*includeJsDocComment*/  false ) ; 
57-             const  tokenLeadingCommnets  =  getLeadingCommentRangesOfNode ( token ,  sourceFile ) ; 
58-             if  ( ! tokenLeadingCommnets  ||  ! tokenLeadingCommnets . length  ||  tokenLeadingCommnets [ 0 ] . pos  >=  startPosition )  { 
59-                 return  { 
60-                     span : {  start : startPosition ,  length : 0  } , 
61-                     newText : `// @ts-ignore${ newLineCharacter }  ` 
62-                 } ; 
63+             const  tokenLeadingComments  =  getLeadingCommentRangesOfNode ( token ,  sourceFile ) ; 
64+             if  ( ! tokenLeadingComments  ||  ! tokenLeadingComments . length  ||  tokenLeadingComments [ 0 ] . pos  >=  startPosition )  { 
65+                 return  {  lineNumber,  change : createTextChange ( startPosition ,  0 ,  `// @ts-ignore${ newLineCharacter }  ` )  } ; 
6366            } 
6467        } 
6568
6669        // If all fails, add an extra new line immediately before the error span. 
67-         return  { 
68-             span : {  start : position ,  length : 0  } , 
69-             newText : `${ position  ===  startPosition  ? ""  : newLineCharacter }  // @ts-ignore${ newLineCharacter }  ` 
70-         } ; 
70+         return  {  lineNumber,  change : createTextChange ( position ,  0 ,  `${ position  ===  startPosition  ? ""  : newLineCharacter }  // @ts-ignore${ newLineCharacter }  ` )  } ; 
71+     } 
72+ 
73+     function  createTextChange ( start : number ,  length : number ,  newText : string ) : TextChange  { 
74+         return  {  span : {  start,  length } ,  newText } ; 
7175    } 
7276} 
0 commit comments