Add Point-and-Click Deletion for Fillets and Chamfers (#5098)
* ast mod * point and click test * tsc * test test * unit test edit * topLevelRange * disable unit test * remove bad imports * fix typo * Fix cyclic dependency hell with getNodePathFromSourceRange * tsc * fix ImportStatement * fix isValueZero * pre-emptively ==> preemptively * yarn fmt-check * reenable the unit test * fmt * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Trigger CI * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Trigger CI * add test * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Trigger CI * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Trigger CI * several treatments * consolidate * typos * fix imports, consolidate * consolidate import * fix imports * add tests * stress test CI * fix test * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Trigger CI * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Trigger CI * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Trigger CI * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Trigger CI * fix tests * clean test for fillets * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Trigger CI * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * test chamfers * comments * simplify main tests * typo * typo2 * remove import * clean up comments --------- Co-authored-by: 49lf <ircsurfer33@gmail.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -5,6 +5,7 @@ import {
|
||||
Identifier,
|
||||
ObjectExpression,
|
||||
PathToNode,
|
||||
PipeExpression,
|
||||
Program,
|
||||
VariableDeclaration,
|
||||
VariableDeclarator,
|
||||
@ -722,3 +723,148 @@ export const isTagUsedInEdgeTreatment = ({
|
||||
|
||||
return edges
|
||||
}
|
||||
|
||||
// Delete Edge Treatment
|
||||
export async function deleteEdgeTreatment(
|
||||
ast: Node<Program>,
|
||||
selection: Selection
|
||||
): Promise<Node<Program> | Error> {
|
||||
/**
|
||||
* Deletes an edge treatment (fillet or chamfer)
|
||||
* from the AST based on the selection.
|
||||
* Handles both standalone treatments
|
||||
* and those within a PipeExpression.
|
||||
*
|
||||
* Supported cases:
|
||||
* [+] fillet and chamfer
|
||||
* [+] piped and non-piped edge treatments
|
||||
* [-] delete single tag from array of tags (currently whole expression is deleted)
|
||||
* [-] multiple selections with different edge treatments (currently single selection is supported)
|
||||
*/
|
||||
|
||||
// 1. Validate Selection Type
|
||||
const { artifact } = selection
|
||||
if (!artifact || artifact.type !== 'edgeCut') {
|
||||
return new Error('Selection is not an edge cut')
|
||||
}
|
||||
|
||||
const { subType: edgeTreatmentType } = artifact
|
||||
if (
|
||||
!edgeTreatmentType ||
|
||||
!['fillet', 'chamfer'].includes(edgeTreatmentType)
|
||||
) {
|
||||
return new Error('Unsupported or missing edge treatment type')
|
||||
}
|
||||
|
||||
// 2. Clone ast and retrieve the VariableDeclarator
|
||||
const astClone = structuredClone(ast)
|
||||
const varDec = getNodeFromPath<VariableDeclarator>(
|
||||
ast,
|
||||
selection?.codeRef?.pathToNode,
|
||||
'VariableDeclarator'
|
||||
)
|
||||
if (err(varDec)) return varDec
|
||||
|
||||
// 3: Check if edge treatment is in a pipe
|
||||
const inPipe = varDec.node.init.type === 'PipeExpression'
|
||||
|
||||
// 4A. Handle standalone edge treatment
|
||||
if (!inPipe) {
|
||||
const varDecPathStep = varDec.shallowPath[1]
|
||||
|
||||
if (
|
||||
!Array.isArray(varDecPathStep) ||
|
||||
typeof varDecPathStep[0] !== 'number'
|
||||
) {
|
||||
return new Error(
|
||||
'Invalid shallowPath structure: expected a number at shallowPath[1][0]'
|
||||
)
|
||||
}
|
||||
|
||||
const varDecIndex: number = varDecPathStep[0]
|
||||
|
||||
// Remove entire VariableDeclarator from the ast
|
||||
astClone.body.splice(varDecIndex, 1)
|
||||
return astClone
|
||||
}
|
||||
|
||||
// 4B. Handle edge treatment within pipe
|
||||
if (inPipe) {
|
||||
// Retrieve the CallExpression path
|
||||
const callExp =
|
||||
getNodeFromPath<CallExpression>(
|
||||
ast,
|
||||
selection?.codeRef?.pathToNode,
|
||||
'CallExpression'
|
||||
) ?? null
|
||||
if (err(callExp)) return callExp
|
||||
|
||||
const shallowPath = callExp.shallowPath
|
||||
|
||||
// Initialize variables to hold the PipeExpression path and callIndex
|
||||
let pipeExpressionPath: PathToNode | null = null
|
||||
let callIndex: number | null = null
|
||||
|
||||
// Iterate through the shallowPath to find the PipeExpression and callIndex
|
||||
for (let i = 0; i < shallowPath.length - 1; i++) {
|
||||
const [key, value] = shallowPath[i]
|
||||
|
||||
if (key === 'body' && value === 'PipeExpression') {
|
||||
pipeExpressionPath = shallowPath.slice(0, i + 1)
|
||||
|
||||
const nextStep = shallowPath[i + 1]
|
||||
if (
|
||||
nextStep &&
|
||||
nextStep[1] === 'index' &&
|
||||
typeof nextStep[0] === 'number'
|
||||
) {
|
||||
callIndex = nextStep[0]
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (!pipeExpressionPath) {
|
||||
return new Error('PipeExpression not found in path')
|
||||
}
|
||||
|
||||
if (callIndex === null) {
|
||||
return new Error('Failed to extract CallExpression index')
|
||||
}
|
||||
// Retrieve the PipeExpression node
|
||||
const pipeExpressionNode = getNodeFromPath<PipeExpression>(
|
||||
astClone,
|
||||
pipeExpressionPath,
|
||||
'PipeExpression'
|
||||
)
|
||||
if (err(pipeExpressionNode)) return pipeExpressionNode
|
||||
|
||||
// Ensure that the PipeExpression.body is an array
|
||||
if (!Array.isArray(pipeExpressionNode.node.body)) {
|
||||
return new Error('PipeExpression body is not an array')
|
||||
}
|
||||
|
||||
// Remove the CallExpression at the specified index
|
||||
pipeExpressionNode.node.body.splice(callIndex, 1)
|
||||
|
||||
// Remove VariableDeclarator if PipeExpression.body is empty
|
||||
if (pipeExpressionNode.node.body.length === 0) {
|
||||
const varDecPathStep = varDec.shallowPath[1]
|
||||
if (
|
||||
!Array.isArray(varDecPathStep) ||
|
||||
typeof varDecPathStep[0] !== 'number'
|
||||
) {
|
||||
return new Error(
|
||||
'Invalid shallowPath structure: expected a number at shallowPath[1][0]'
|
||||
)
|
||||
}
|
||||
const varDecIndex: number = varDecPathStep[0]
|
||||
astClone.body.splice(varDecIndex, 1)
|
||||
}
|
||||
|
||||
return astClone
|
||||
}
|
||||
|
||||
return Error('Delete fillets not implemented')
|
||||
}
|
||||
|
Reference in New Issue
Block a user