@@ -9,60 +9,69 @@ namespace ts.codefix {
99 registerCodeFix ( {
1010 errorCodes,
1111 getCodeActions ( context ) {
12- const { sourceFile, program, span } = context ;
12+ const { sourceFile, program, span, host , formatContext } = context ;
1313
1414 if ( ! isInJavaScriptFile ( sourceFile ) || ! isCheckJsEnabledForFile ( sourceFile , program . getCompilerOptions ( ) ) ) {
1515 return undefined ;
1616 }
1717
18- const newLineCharacter = getNewLineOrDefaultFromHost ( context . host , context . formatContext . options ) ;
18+ const fixes : CodeFixAction [ ] = [
19+ {
20+ description : getLocaleSpecificMessage ( Diagnostics . Disable_checking_for_this_file ) ,
21+ changes : [ createFileTextChanges ( sourceFile . fileName , [
22+ createTextChange ( sourceFile . checkJsDirective
23+ ? createTextSpanFromBounds ( sourceFile . checkJsDirective . pos , sourceFile . checkJsDirective . end )
24+ : createTextSpan ( 0 , 0 ) , `// @ts-nocheck${ getNewLineOrDefaultFromHost ( host , formatContext . options ) } ` ) ,
25+ ] ) ] ,
26+ // fixId unnecessary because adding `// @ts-nocheck` even once will ignore every error in the file.
27+ fixId : undefined ,
28+ } ] ;
1929
20- return [ {
21- description : getLocaleSpecificMessage ( Diagnostics . Ignore_this_error_message ) ,
22- changes : [ createFileTextChanges ( sourceFile . fileName , [ getIgnoreCommentLocationForLocation ( sourceFile , span . start , newLineCharacter ) . change ] ) ] ,
23- fixId,
24- } ,
25- {
26- description : getLocaleSpecificMessage ( Diagnostics . Disable_checking_for_this_file ) ,
27- changes : [ createFileTextChanges ( sourceFile . fileName , [
28- createTextChange ( sourceFile . checkJsDirective ? createTextSpanFromBounds ( sourceFile . checkJsDirective . pos , sourceFile . checkJsDirective . end ) : createTextSpan ( 0 , 0 ) , `// @ts-nocheck${ newLineCharacter } ` ) ,
29- ] ) ] ,
30- // fixId unnecessary because adding `// @ts-nocheck` even once will ignore every error in the file.
31- fixId : undefined ,
32- } ] ;
30+ if ( isValidSuppressLocation ( sourceFile , span . start ) ) {
31+ fixes . unshift ( {
32+ description : getLocaleSpecificMessage ( Diagnostics . Ignore_this_error_message ) ,
33+ changes : textChanges . ChangeTracker . with ( context , t => makeChange ( t , sourceFile , span . start ) ) ,
34+ fixId,
35+ } ) ;
36+ }
37+
38+ return fixes ;
3339 } ,
3440 fixIds : [ fixId ] ,
3541 getAllCodeActions : context => {
36- const seenLines = createMap < true > ( ) ; // Only need to add `// @ts-ignore` for a line once.
37- return codeFixAllWithTextChanges ( context , errorCodes , ( changes , err ) => {
38- if ( err . start !== undefined ) {
39- const { lineNumber, change } = getIgnoreCommentLocationForLocation ( err . file ! , err . start , getNewLineOrDefaultFromHost ( context . host , context . formatContext . options ) ) ;
40- if ( addToSeen ( seenLines , lineNumber ) ) {
41- changes . push ( change ) ;
42- }
42+ const seenLines = createMap < true > ( ) ;
43+ return codeFixAll ( context , errorCodes , ( changes , diag ) => {
44+ if ( isValidSuppressLocation ( diag . file ! , diag . start ! ) ) {
45+ makeChange ( changes , diag . file ! , diag . start ! , seenLines ) ;
4346 }
4447 } ) ;
4548 } ,
4649 } ) ;
4750
48- function getIgnoreCommentLocationForLocation ( sourceFile : SourceFile , position : number , newLineCharacter : string ) : { lineNumber : number , change : TextChange } {
51+ function isValidSuppressLocation ( sourceFile : SourceFile , position : number ) {
52+ return ! isInComment ( sourceFile , position ) && ! isInString ( sourceFile , position ) && ! isInTemplateString ( sourceFile , position ) ;
53+ }
54+
55+ function makeChange ( changes : textChanges . ChangeTracker , sourceFile : SourceFile , position : number , seenLines ?: Map < true > ) {
4956 const { line : lineNumber } = getLineAndCharacterOfPosition ( sourceFile , position ) ;
57+
58+ // Only need to add `// @ts-ignore` for a line once.
59+ if ( seenLines && ! addToSeen ( seenLines , lineNumber ) ) {
60+ return ;
61+ }
62+
5063 const lineStartPosition = getStartPositionOfLine ( lineNumber , sourceFile ) ;
5164 const startPosition = getFirstNonSpaceCharacterPosition ( sourceFile . text , lineStartPosition ) ;
5265
5366 // First try to see if we can put the '// @ts-ignore' on the previous line.
5467 // We need to make sure that we are not in the middle of a string literal or a comment.
55- // We also want to check if the previous line holds a comment for a node on the next line
56- // if so, we do not want to separate the node from its comment if we can.
57- if ( ! isInComment ( sourceFile , startPosition ) && ! isInString ( sourceFile , startPosition ) && ! isInTemplateString ( sourceFile , startPosition ) ) {
58- const token = getTouchingToken ( sourceFile , startPosition , /*includeJsDocComment*/ false ) ;
59- const tokenLeadingComments = getLeadingCommentRangesOfNode ( token , sourceFile ) ;
60- if ( ! tokenLeadingComments || ! tokenLeadingComments . length || tokenLeadingComments [ 0 ] . pos >= startPosition ) {
61- return { lineNumber, change : createTextChangeFromStartLength ( startPosition , 0 , `// @ts-ignore${ newLineCharacter } ` ) } ;
62- }
63- }
68+ // If so, we do not want to separate the node from its comment if we can.
69+ // Otherwise, add an extra new line immediately before the error span.
70+ const insertAtLineStart = isValidSuppressLocation ( sourceFile , startPosition ) ;
6471
65- // If all fails, add an extra new line immediately before the error span.
66- return { lineNumber, change : createTextChangeFromStartLength ( position , 0 , `${ position === startPosition ? "" : newLineCharacter } // @ts-ignore${ newLineCharacter } ` ) } ;
72+ const token = getTouchingToken ( sourceFile , insertAtLineStart ? startPosition : position , /*includeJsDocComment*/ false ) ;
73+ const clone = setStartsOnNewLine ( getSynthesizedDeepClone ( token ) , true ) ;
74+ addSyntheticLeadingComment ( clone , SyntaxKind . SingleLineCommentTrivia , " @ts-ignore" ) ;
75+ changes . replaceNode ( sourceFile , token , clone , { preserveLeadingWhitespace : true , prefix : insertAtLineStart ? undefined : changes . newLineCharacter } ) ;
6776 }
6877}
0 commit comments