@@ -28,9 +28,12 @@ import { FlowStyleRewriter } from '../utils/flow-style-rewriter';
28
28
import { ASTNode } from '../jsonASTTypes' ;
29
29
import * as _ from 'lodash' ;
30
30
import { SourceToken } from 'yaml/dist/parse/cst' ;
31
+ import { ErrorCode } from 'vscode-json-languageservice' ;
31
32
32
33
interface YamlDiagnosticData {
33
34
schemaUri : string [ ] ;
35
+ values ?: string [ ] ;
36
+ properties ?: string [ ] ;
34
37
}
35
38
export class YamlCodeActions {
36
39
private indentation = ' ' ;
@@ -54,6 +57,7 @@ export class YamlCodeActions {
54
57
result . push ( ...this . getUnusedAnchorsDelete ( params . context . diagnostics , document ) ) ;
55
58
result . push ( ...this . getConvertToBlockStyleActions ( params . context . diagnostics , document ) ) ;
56
59
result . push ( ...this . getKeyOrderActions ( params . context . diagnostics , document ) ) ;
60
+ result . push ( ...this . getQuickFixForPropertyOrValueMismatch ( params . context . diagnostics , document ) ) ;
57
61
58
62
return result ;
59
63
}
@@ -221,7 +225,7 @@ export class YamlCodeActions {
221
225
const results : CodeAction [ ] = [ ] ;
222
226
for ( const diagnostic of diagnostics ) {
223
227
if ( diagnostic . code === 'flowMap' || diagnostic . code === 'flowSeq' ) {
224
- const node = getNodeforDiagnostic ( document , diagnostic ) ;
228
+ const node = getNodeForDiagnostic ( document , diagnostic ) ;
225
229
if ( isMap ( node . internalNode ) || isSeq ( node . internalNode ) ) {
226
230
const blockTypeDescription = isMap ( node . internalNode ) ? 'map' : 'sequence' ;
227
231
const rewriter = new FlowStyleRewriter ( this . indentation ) ;
@@ -242,7 +246,7 @@ export class YamlCodeActions {
242
246
const results : CodeAction [ ] = [ ] ;
243
247
for ( const diagnostic of diagnostics ) {
244
248
if ( diagnostic ?. code === 'mapKeyOrder' ) {
245
- let node = getNodeforDiagnostic ( document , diagnostic ) ;
249
+ let node = getNodeForDiagnostic ( document , diagnostic ) ;
246
250
while ( node && node . type !== 'object' ) {
247
251
node = node . parent ;
248
252
}
@@ -292,8 +296,8 @@ export class YamlCodeActions {
292
296
item . value . end . splice ( newLineIndex , 1 ) ;
293
297
}
294
298
} else if ( item . value ?. type === 'block-scalar' ) {
295
- const nwline = item . value . props . find ( ( p ) => p . type === 'newline' ) ;
296
- if ( ! nwline ) {
299
+ const newline = item . value . props . find ( ( p ) => p . type === 'newline' ) ;
300
+ if ( ! newline ) {
297
301
item . value . props . push ( { type : 'newline' , indent : 0 , offset : item . value . offset , source : '\n' } as SourceToken ) ;
298
302
}
299
303
}
@@ -312,9 +316,52 @@ export class YamlCodeActions {
312
316
}
313
317
return results ;
314
318
}
319
+
320
+ /**
321
+ * Check if diagnostic contains info for quick fix
322
+ * Supports Enum/Const/Property mismatch
323
+ */
324
+ private getPossibleQuickFixValues ( diagnostic : Diagnostic ) : string [ ] | undefined {
325
+ if ( typeof diagnostic . data !== 'object' ) {
326
+ return ;
327
+ }
328
+ if (
329
+ diagnostic . code === ErrorCode . EnumValueMismatch &&
330
+ 'values' in diagnostic . data &&
331
+ Array . isArray ( ( diagnostic . data as YamlDiagnosticData ) . values )
332
+ ) {
333
+ return ( diagnostic . data as YamlDiagnosticData ) . values ;
334
+ } else if (
335
+ diagnostic . code === ErrorCode . PropertyExpected &&
336
+ 'properties' in diagnostic . data &&
337
+ Array . isArray ( ( diagnostic . data as YamlDiagnosticData ) . properties )
338
+ ) {
339
+ return ( diagnostic . data as YamlDiagnosticData ) . properties ;
340
+ }
341
+ }
342
+
343
+ private getQuickFixForPropertyOrValueMismatch ( diagnostics : Diagnostic [ ] , document : TextDocument ) : CodeAction [ ] {
344
+ const results : CodeAction [ ] = [ ] ;
345
+ for ( const diagnostic of diagnostics ) {
346
+ const values = this . getPossibleQuickFixValues ( diagnostic ) ;
347
+ if ( ! values ?. length ) {
348
+ continue ;
349
+ }
350
+ for ( const value of values ) {
351
+ results . push (
352
+ CodeAction . create (
353
+ value ,
354
+ createWorkspaceEdit ( document . uri , [ TextEdit . replace ( diagnostic . range , value ) ] ) ,
355
+ CodeActionKind . QuickFix
356
+ )
357
+ ) ;
358
+ }
359
+ }
360
+ return results ;
361
+ }
315
362
}
316
363
317
- function getNodeforDiagnostic ( document : TextDocument , diagnostic : Diagnostic ) : ASTNode {
364
+ function getNodeForDiagnostic ( document : TextDocument , diagnostic : Diagnostic ) : ASTNode {
318
365
const yamlDocuments = yamlDocumentsCache . getYamlDocument ( document ) ;
319
366
const startOffset = document . offsetAt ( diagnostic . range . start ) ;
320
367
const yamlDoc = matchOffsetToDocument ( startOffset , yamlDocuments ) ;
0 commit comments