@@ -126,19 +126,29 @@ class DiagnosticsSet {
126126 }
127127}
128128
129+ class VsCodeCodeAction extends vscode . CodeAction {
130+ constructor (
131+ public readonly tsAction : Proto . CodeFixAction ,
132+ title : string ,
133+ kind : vscode . CodeActionKind ,
134+ ) {
135+ super ( title , kind ) ;
136+ }
137+ }
138+
129139class CodeActionSet {
130- private readonly _actions = new Set < vscode . CodeAction > ( ) ;
131- private readonly _fixAllActions = new Map < { } , vscode . CodeAction > ( ) ;
140+ private readonly _actions = new Set < VsCodeCodeAction > ( ) ;
141+ private readonly _fixAllActions = new Map < { } , VsCodeCodeAction > ( ) ;
132142
133- public get values ( ) : Iterable < vscode . CodeAction > {
143+ public get values ( ) : Iterable < VsCodeCodeAction > {
134144 return this . _actions ;
135145 }
136146
137- public addAction ( action : vscode . CodeAction ) {
147+ public addAction ( action : VsCodeCodeAction ) {
138148 this . _actions . add ( action ) ;
139149 }
140150
141- public addFixAllAction ( fixId : { } , action : vscode . CodeAction ) {
151+ public addFixAllAction ( fixId : { } , action : VsCodeCodeAction ) {
142152 const existing = this . _fixAllActions . get ( fixId ) ;
143153 if ( existing ) {
144154 // reinsert action at back of actions list
@@ -219,7 +229,13 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider {
219229 for ( const diagnostic of fixableDiagnostics . values ) {
220230 await this . getFixesForDiagnostic ( document , file , diagnostic , results , token ) ;
221231 }
222- return Array . from ( results . values ) ;
232+
233+ const allActions = Array . from ( results . values ) ;
234+ const allTsActions = allActions . map ( x => x . tsAction ) ;
235+ for ( const action of allActions ) {
236+ action . isPreferred = isPreferredFix ( action . tsAction , allTsActions ) ;
237+ }
238+ return allActions ;
223239 }
224240
225241 private async getFixesForDiagnostic (
@@ -259,16 +275,15 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider {
259275 private getSingleFixForTsCodeAction (
260276 diagnostic : vscode . Diagnostic ,
261277 tsAction : Proto . CodeFixAction
262- ) : vscode . CodeAction {
263- const codeAction = new vscode . CodeAction ( tsAction . description , vscode . CodeActionKind . QuickFix ) ;
278+ ) : VsCodeCodeAction {
279+ const codeAction = new VsCodeCodeAction ( tsAction , tsAction . description , vscode . CodeActionKind . QuickFix ) ;
264280 codeAction . edit = getEditForCodeAction ( this . client , tsAction ) ;
265281 codeAction . diagnostics = [ diagnostic ] ;
266282 codeAction . command = {
267283 command : ApplyCodeActionCommand . ID ,
268284 arguments : [ tsAction ] ,
269285 title : ''
270286 } ;
271- codeAction . isPreferred = isPreferredFix ( tsAction ) ;
272287 return codeAction ;
273288 }
274289
@@ -294,7 +309,8 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider {
294309 return results ;
295310 }
296311
297- const action = new vscode . CodeAction (
312+ const action = new VsCodeCodeAction (
313+ tsAction ,
298314 tsAction . fixAllDescription || localize ( 'fixAllInFileLabel' , '{0} (Fix all in file)' , tsAction . description ) ,
299315 vscode . CodeActionKind . QuickFix ) ;
300316 action . diagnostics = [ diagnostic ] ;
@@ -317,20 +333,37 @@ const fixAllErrorCodes = new Map<number, number>([
317333] ) ;
318334
319335
320- const preferredFixes = new Set ( [
321- 'annotateWithTypeFromJSDoc' ,
322- 'constructorForDerivedNeedSuperCall' ,
323- 'extendsInterfaceBecomesImplements' ,
324- 'fixAwaitInSyncFunction' ,
325- 'fixClassIncorrectlyImplementsInterface' ,
326- 'fixUnreachableCode' ,
327- 'forgottenThisPropertyAccess' ,
328- 'spelling' ,
329- 'unusedIdentifier' ,
330- 'addMissingAwait' ,
336+ const preferredFixes = new Map < string , /* priorty */ number > ( [
337+ [ 'annotateWithTypeFromJSDoc' , 0 ] ,
338+ [ 'constructorForDerivedNeedSuperCall' , 0 ] ,
339+ [ 'extendsInterfaceBecomesImplements' , 0 ] ,
340+ [ 'fixAwaitInSyncFunction' , 0 ] ,
341+ [ 'fixClassIncorrectlyImplementsInterface' , 1 ] ,
342+ [ 'fixUnreachableCode' , 0 ] ,
343+ [ 'unusedIdentifier' , 0 ] ,
344+ [ 'forgottenThisPropertyAccess' , 0 ] ,
345+ [ 'spelling' , 1 ] ,
346+ [ 'addMissingAwait' , 0 ] ,
331347] ) ;
332- function isPreferredFix ( tsAction : Proto . CodeFixAction ) : boolean {
333- return preferredFixes . has ( tsAction . fixName ) ;
348+
349+ function isPreferredFix (
350+ tsAction : Proto . CodeFixAction ,
351+ allActions : readonly Proto . CodeFixAction [ ]
352+ ) : boolean {
353+ const priority = preferredFixes . get ( tsAction . fixName ) ;
354+ if ( typeof priority === 'undefined' ) {
355+ return false ;
356+ }
357+ return allActions . every ( otherAction => {
358+ if ( otherAction === tsAction ) {
359+ return true ;
360+ }
361+ const otherPriority = preferredFixes . get ( otherAction . fixName ) ;
362+ if ( typeof otherPriority === 'undefined' ) {
363+ return true ;
364+ }
365+ return priority >= otherPriority ;
366+ } ) ;
334367}
335368
336369export function register (
0 commit comments