-
Notifications
You must be signed in to change notification settings - Fork 238
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[typespec-vscode] Make 'convert to object value' code fix recursive (#…
…5342) Fix : #4613 There will be two quick fixes for this issue, and only by clicking on the quick fix of the entire expression can you get the desired result; If you click on the quick fix for a partial expression, because there is no recursive part in the middle of the partial expression, you need to click twice to get the desired result --------- Co-authored-by: Rodge Fu <[email protected]> Co-authored-by: Timothee Guerin <[email protected]>
- Loading branch information
1 parent
0d157d4
commit a750945
Showing
8 changed files
with
217 additions
and
80 deletions.
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
.chronus/changes/make-convert-to-objval-codefix-recursive-2024-11-18-5-24-11.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking | ||
changeKind: feature | ||
packages: | ||
- "@typespec/compiler" | ||
--- | ||
|
||
Convert model/tuple expression to value code fix is applied to the entire value. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
packages/compiler/src/core/compiler-code-fixes/convert-to-value.codefix.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { defineCodeFix, getSourceLocation } from "../diagnostics.js"; | ||
import { | ||
SyntaxKind, | ||
type CodeFixEdit, | ||
type ModelExpressionNode, | ||
type TupleExpressionNode, | ||
} from "../types.js"; | ||
|
||
/** | ||
* Quick fix that convert a tuple to an array value. | ||
*/ | ||
export function createTupleToArrayValueCodeFix(node: TupleExpressionNode) { | ||
return defineCodeFix({ | ||
id: "tuple-to-array-value", | ||
label: `Convert to an array value \`#[]\``, | ||
fix: (context) => { | ||
const result: CodeFixEdit[] = []; | ||
|
||
addCreatedCodeFixResult(node); | ||
createChildTupleToArrValCodeFix(node, addCreatedCodeFixResult); | ||
|
||
return result; | ||
|
||
function addCreatedCodeFixResult(node: ModelExpressionNode | TupleExpressionNode) { | ||
const location = getSourceLocation(node); | ||
result.push(context.prependText(location, "#")); | ||
} | ||
}, | ||
}); | ||
} | ||
|
||
/** | ||
* Quick fix that convert a model expression to an object value. | ||
*/ | ||
export function createModelToObjectValueCodeFix(node: ModelExpressionNode) { | ||
return defineCodeFix({ | ||
id: "model-to-object-value", | ||
label: `Convert to an object value \`#{}\``, | ||
fix: (context) => { | ||
const result: CodeFixEdit[] = []; | ||
|
||
addCreatedCodeFixResult(node); | ||
createChildModelToObjValCodeFix(node, addCreatedCodeFixResult); | ||
|
||
return result; | ||
|
||
function addCreatedCodeFixResult(node: ModelExpressionNode | TupleExpressionNode) { | ||
const location = getSourceLocation(node); | ||
result.push(context.prependText(location, "#")); | ||
} | ||
}, | ||
}); | ||
} | ||
|
||
function createChildTupleToArrValCodeFix( | ||
node: TupleExpressionNode, | ||
addCreatedCodeFixResult: (node: ModelExpressionNode | TupleExpressionNode) => void, | ||
) { | ||
for (const childNode of node.values) { | ||
if (childNode.kind === SyntaxKind.ModelExpression) { | ||
addCreatedCodeFixResult(childNode); | ||
createChildModelToObjValCodeFix(childNode, addCreatedCodeFixResult); | ||
} else if (childNode.kind === SyntaxKind.TupleExpression) { | ||
addCreatedCodeFixResult(childNode); | ||
createChildTupleToArrValCodeFix(childNode, addCreatedCodeFixResult); | ||
} | ||
} | ||
} | ||
|
||
function createChildModelToObjValCodeFix( | ||
node: ModelExpressionNode, | ||
addCreatedCodeFixResult: (node: ModelExpressionNode | TupleExpressionNode) => void, | ||
) { | ||
for (const prop of node.properties.values()) { | ||
if (prop.kind === SyntaxKind.ModelProperty) { | ||
const childNode = prop.value; | ||
|
||
if (childNode.kind === SyntaxKind.ModelExpression) { | ||
addCreatedCodeFixResult(childNode); | ||
createChildModelToObjValCodeFix(childNode, addCreatedCodeFixResult); | ||
} else if (childNode.kind === SyntaxKind.TupleExpression) { | ||
addCreatedCodeFixResult(childNode); | ||
createChildTupleToArrValCodeFix(childNode, addCreatedCodeFixResult); | ||
} | ||
} | ||
} | ||
} |
16 changes: 0 additions & 16 deletions
16
packages/compiler/src/core/compiler-code-fixes/model-to-object-literal.codefix.ts
This file was deleted.
Oops, something went wrong.
16 changes: 0 additions & 16 deletions
16
packages/compiler/src/core/compiler-code-fixes/tuple-to-array-value.codefix.ts
This file was deleted.
Oops, something went wrong.
118 changes: 118 additions & 0 deletions
118
packages/compiler/test/core/compiler-code-fixes/conert-to-value.codefix.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { strictEqual } from "assert"; | ||
import { it } from "vitest"; | ||
import { | ||
createModelToObjectValueCodeFix, | ||
createTupleToArrayValueCodeFix, | ||
} from "../../../src/core/compiler-code-fixes/convert-to-value.codefix.js"; | ||
import { SyntaxKind } from "../../../src/index.js"; | ||
import { expectCodeFixOnAst } from "../../../src/testing/code-fix-testing.js"; | ||
|
||
it("it change model expression to an object value", async () => { | ||
await expectCodeFixOnAst( | ||
` | ||
model Foo { | ||
a: string[] = ┆{foo: "abc"}; | ||
} | ||
`, | ||
(node) => { | ||
strictEqual(node.kind, SyntaxKind.ModelExpression); | ||
return createModelToObjectValueCodeFix(node); | ||
}, | ||
).toChangeTo(` | ||
model Foo { | ||
a: string[] = #{foo: "abc"}; | ||
} | ||
`); | ||
}); | ||
|
||
it("it recursively changes the model expression to the corresponding object value", async () => { | ||
await expectCodeFixOnAst( | ||
` | ||
@example(┆{Bar : {Baz : "Hello"}}) | ||
model Foo { Bar : Bar; } | ||
model Bar { Baz : string } | ||
`, | ||
(node) => { | ||
strictEqual(node.kind, SyntaxKind.ModelExpression); | ||
return createModelToObjectValueCodeFix(node); | ||
}, | ||
).toChangeTo(` | ||
@example(#{Bar : #{Baz : "Hello"}}) | ||
model Foo { Bar : Bar; } | ||
model Bar { Baz : string } | ||
`); | ||
}); | ||
|
||
it("it recursively changes the complex model expression to the corresponding object value or array value", async () => { | ||
await expectCodeFixOnAst( | ||
` | ||
@example(┆{ Bar: [ {Baz: "Hello"}, [ "foo" ] ] }) | ||
model Foo { Bar : Array<Bar|Array<string>>; } | ||
model Bar { Baz : string } | ||
`, | ||
(node) => { | ||
strictEqual(node.kind, SyntaxKind.ModelExpression); | ||
return createModelToObjectValueCodeFix(node); | ||
}, | ||
).toChangeTo(` | ||
@example(#{ Bar: #[ #{Baz: "Hello"}, #[ "foo" ] ] }) | ||
model Foo { Bar : Array<Bar|Array<string>>; } | ||
model Bar { Baz : string } | ||
`); | ||
}); | ||
|
||
it("it change tuple to a array value", async () => { | ||
await expectCodeFixOnAst( | ||
` | ||
model Foo { | ||
a: string[] = ┆["abc"]; | ||
} | ||
`, | ||
(node) => { | ||
strictEqual(node.kind, SyntaxKind.TupleExpression); | ||
return createTupleToArrayValueCodeFix(node); | ||
}, | ||
).toChangeTo(` | ||
model Foo { | ||
a: string[] = #["abc"]; | ||
} | ||
`); | ||
}); | ||
|
||
it("it recursively changes tuple to the corresponding array value", async () => { | ||
await expectCodeFixOnAst( | ||
` | ||
model Tuple { | ||
tuple: [ string, [ string ]] = ┆["foo", ["bar"]]; | ||
} | ||
`, | ||
(node) => { | ||
strictEqual(node.kind, SyntaxKind.TupleExpression); | ||
return createTupleToArrayValueCodeFix(node); | ||
}, | ||
).toChangeTo(` | ||
model Tuple { | ||
tuple: [ string, [ string ]] = #["foo", #["bar"]]; | ||
} | ||
`); | ||
}); | ||
|
||
it("it recursively changes the complex tuple to the corresponding object value or array value", async () => { | ||
await expectCodeFixOnAst( | ||
` | ||
model Bar { Baz : string } | ||
model Tuple { | ||
tuple: [ string, [ string,Bar ]] = ┆["foo", ["bar",{Baz: "Hello"}]]; | ||
} | ||
`, | ||
(node) => { | ||
strictEqual(node.kind, SyntaxKind.TupleExpression); | ||
return createTupleToArrayValueCodeFix(node); | ||
}, | ||
).toChangeTo(` | ||
model Bar { Baz : string } | ||
model Tuple { | ||
tuple: [ string, [ string,Bar ]] = #["foo", #["bar",#{Baz: "Hello"}]]; | ||
} | ||
`); | ||
}); |
23 changes: 0 additions & 23 deletions
23
packages/compiler/test/core/compiler-code-fixes/model-to-literal.codefix.test.ts
This file was deleted.
Oops, something went wrong.
23 changes: 0 additions & 23 deletions
23
packages/compiler/test/core/compiler-code-fixes/tuple-to-literal.codefix.test.ts
This file was deleted.
Oops, something went wrong.