@@ -28,9 +28,12 @@ import { FlowStyleRewriter } from '../utils/flow-style-rewriter';
2828import { ASTNode } from '../jsonASTTypes' ;
2929import * as _ from 'lodash' ;
3030import { SourceToken } from 'yaml/dist/parse/cst' ;
31+ import { ErrorCode } from 'vscode-json-languageservice' ;
3132
3233interface YamlDiagnosticData {
3334 schemaUri : string [ ] ;
35+ values ?: string [ ] ;
36+ properties ?: string [ ] ;
3437}
3538export class YamlCodeActions {
3639 private indentation = ' ' ;
@@ -54,6 +57,7 @@ export class YamlCodeActions {
5457 result . push ( ...this . getUnusedAnchorsDelete ( params . context . diagnostics , document ) ) ;
5558 result . push ( ...this . getConvertToBlockStyleActions ( params . context . diagnostics , document ) ) ;
5659 result . push ( ...this . getKeyOrderActions ( params . context . diagnostics , document ) ) ;
60+ result . push ( ...this . getQuickFixForPropertyOrValueMismatch ( params . context . diagnostics , document ) ) ;
5761
5862 return result ;
5963 }
@@ -221,7 +225,7 @@ export class YamlCodeActions {
221225 const results : CodeAction [ ] = [ ] ;
222226 for ( const diagnostic of diagnostics ) {
223227 if ( diagnostic . code === 'flowMap' || diagnostic . code === 'flowSeq' ) {
224- const node = getNodeforDiagnostic ( document , diagnostic ) ;
228+ const node = getNodeForDiagnostic ( document , diagnostic ) ;
225229 if ( isMap ( node . internalNode ) || isSeq ( node . internalNode ) ) {
226230 const blockTypeDescription = isMap ( node . internalNode ) ? 'map' : 'sequence' ;
227231 const rewriter = new FlowStyleRewriter ( this . indentation ) ;
@@ -242,7 +246,7 @@ export class YamlCodeActions {
242246 const results : CodeAction [ ] = [ ] ;
243247 for ( const diagnostic of diagnostics ) {
244248 if ( diagnostic ?. code === 'mapKeyOrder' ) {
245- let node = getNodeforDiagnostic ( document , diagnostic ) ;
249+ let node = getNodeForDiagnostic ( document , diagnostic ) ;
246250 while ( node && node . type !== 'object' ) {
247251 node = node . parent ;
248252 }
@@ -292,8 +296,8 @@ export class YamlCodeActions {
292296 item . value . end . splice ( newLineIndex , 1 ) ;
293297 }
294298 } 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 ) {
297301 item . value . props . push ( { type : 'newline' , indent : 0 , offset : item . value . offset , source : '\n' } as SourceToken ) ;
298302 }
299303 }
@@ -312,9 +316,52 @@ export class YamlCodeActions {
312316 }
313317 return results ;
314318 }
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+ }
315362}
316363
317- function getNodeforDiagnostic ( document : TextDocument , diagnostic : Diagnostic ) : ASTNode {
364+ function getNodeForDiagnostic ( document : TextDocument , diagnostic : Diagnostic ) : ASTNode {
318365 const yamlDocuments = yamlDocumentsCache . getYamlDocument ( document ) ;
319366 const startOffset = document . offsetAt ( diagnostic . range . start ) ;
320367 const yamlDoc = matchOffsetToDocument ( startOffset , yamlDocuments ) ;
0 commit comments