-
Notifications
You must be signed in to change notification settings - Fork 264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: quickFix for enum, const, property #900
base: main
Are you sure you want to change the base?
Changes from all commits
77bf8bc
5baa96e
e3e7687
be88cdc
ae9c4e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -28,9 +28,12 @@ import { FlowStyleRewriter } from '../utils/flow-style-rewriter'; | |||||
import { ASTNode } from '../jsonASTTypes'; | ||||||
import * as _ from 'lodash'; | ||||||
import { SourceToken } from 'yaml/dist/parse/cst'; | ||||||
import { ErrorCode } from 'vscode-json-languageservice'; | ||||||
|
||||||
interface YamlDiagnosticData { | ||||||
schemaUri: string[]; | ||||||
values?: string[]; | ||||||
properties?: string[]; | ||||||
} | ||||||
export class YamlCodeActions { | ||||||
private indentation = ' '; | ||||||
|
@@ -54,6 +57,7 @@ export class YamlCodeActions { | |||||
result.push(...this.getUnusedAnchorsDelete(params.context.diagnostics, document)); | ||||||
result.push(...this.getConvertToBlockStyleActions(params.context.diagnostics, document)); | ||||||
result.push(...this.getKeyOrderActions(params.context.diagnostics, document)); | ||||||
result.push(...this.getQuickFixForPropertyOrValueMismatch(params.context.diagnostics, document)); | ||||||
|
||||||
return result; | ||||||
} | ||||||
|
@@ -221,7 +225,7 @@ export class YamlCodeActions { | |||||
const results: CodeAction[] = []; | ||||||
for (const diagnostic of diagnostics) { | ||||||
if (diagnostic.code === 'flowMap' || diagnostic.code === 'flowSeq') { | ||||||
const node = getNodeforDiagnostic(document, diagnostic); | ||||||
const node = getNodeForDiagnostic(document, diagnostic); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just typo |
||||||
if (isMap(node.internalNode) || isSeq(node.internalNode)) { | ||||||
const blockTypeDescription = isMap(node.internalNode) ? 'map' : 'sequence'; | ||||||
const rewriter = new FlowStyleRewriter(this.indentation); | ||||||
|
@@ -242,7 +246,7 @@ export class YamlCodeActions { | |||||
const results: CodeAction[] = []; | ||||||
for (const diagnostic of diagnostics) { | ||||||
if (diagnostic?.code === 'mapKeyOrder') { | ||||||
let node = getNodeforDiagnostic(document, diagnostic); | ||||||
let node = getNodeForDiagnostic(document, diagnostic); | ||||||
while (node && node.type !== 'object') { | ||||||
node = node.parent; | ||||||
} | ||||||
|
@@ -292,8 +296,8 @@ export class YamlCodeActions { | |||||
item.value.end.splice(newLineIndex, 1); | ||||||
} | ||||||
} else if (item.value?.type === 'block-scalar') { | ||||||
const nwline = item.value.props.find((p) => p.type === 'newline'); | ||||||
if (!nwline) { | ||||||
const newline = item.value.props.find((p) => p.type === 'newline'); | ||||||
if (!newline) { | ||||||
item.value.props.push({ type: 'newline', indent: 0, offset: item.value.offset, source: '\n' } as SourceToken); | ||||||
} | ||||||
} | ||||||
|
@@ -312,9 +316,52 @@ export class YamlCodeActions { | |||||
} | ||||||
return results; | ||||||
} | ||||||
|
||||||
/** | ||||||
* Check if diagnostic contains info for quick fix | ||||||
* Supports Enum/Const/Property mismatch | ||||||
*/ | ||||||
private getPossibleQuickFixValues(diagnostic: Diagnostic): string[] | undefined { | ||||||
if (typeof diagnostic.data !== 'object') { | ||||||
return; | ||||||
} | ||||||
if ( | ||||||
diagnostic.code === ErrorCode.EnumValueMismatch && | ||||||
'values' in diagnostic.data && | ||||||
Array.isArray((diagnostic.data as YamlDiagnosticData).values) | ||||||
) { | ||||||
return (diagnostic.data as YamlDiagnosticData).values; | ||||||
} else if ( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this else really needed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean quickFix for properties? or can you explain your point further?
|
||||||
diagnostic.code === ErrorCode.PropertyExpected && | ||||||
'properties' in diagnostic.data && | ||||||
Array.isArray((diagnostic.data as YamlDiagnosticData).properties) | ||||||
) { | ||||||
return (diagnostic.data as YamlDiagnosticData).properties; | ||||||
} | ||||||
} | ||||||
|
||||||
private getQuickFixForPropertyOrValueMismatch(diagnostics: Diagnostic[], document: TextDocument): CodeAction[] { | ||||||
const results: CodeAction[] = []; | ||||||
for (const diagnostic of diagnostics) { | ||||||
const values = this.getPossibleQuickFixValues(diagnostic); | ||||||
if (!values?.length) { | ||||||
continue; | ||||||
} | ||||||
for (const value of values) { | ||||||
results.push( | ||||||
CodeAction.create( | ||||||
value, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This returns only the value which is not very descriptive of the operation. perhaps we can replace it with something like
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't have preferences here, I can remember that I tried a few combinations but I ended up with only small disadvantage of
so please make a decision |
||||||
createWorkspaceEdit(document.uri, [TextEdit.replace(diagnostic.range, value)]), | ||||||
CodeActionKind.QuickFix | ||||||
) | ||||||
); | ||||||
} | ||||||
} | ||||||
return results; | ||||||
} | ||||||
} | ||||||
|
||||||
function getNodeforDiagnostic(document: TextDocument, diagnostic: Diagnostic): ASTNode { | ||||||
function getNodeForDiagnostic(document: TextDocument, diagnostic: Diagnostic): ASTNode { | ||||||
const yamlDocuments = yamlDocumentsCache.getYamlDocument(document); | ||||||
const startOffset = document.offsetAt(diagnostic.range.start); | ||||||
const yamlDoc = matchOffsetToDocument(startOffset, yamlDocuments); | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,9 +39,19 @@ export function createDiagnosticWithData( | |
severity: DiagnosticSeverity = 1, | ||
source = 'YAML', | ||
schemaUri: string | string[], | ||
code: string | number = ErrorCode.Undefined, | ||
data: Record<string, unknown> = {} | ||
): Diagnostic { | ||
const diagnostic: Diagnostic = createExpectedError(message, startLine, startCharacter, endLine, endCharacter, severity, source); | ||
const diagnostic: Diagnostic = createExpectedError( | ||
message, | ||
startLine, | ||
startCharacter, | ||
endLine, | ||
endCharacter, | ||
severity, | ||
source, | ||
code | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just code added to parameters |
||
); | ||
diagnostic.data = { schemaUri: typeof schemaUri === 'string' ? [schemaUri] : schemaUri, ...data }; | ||
return diagnostic; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if it wouldn't be better to unify
data.properties
todata.values
for the incorrect property