diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--YZ-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--YZ-1-Google-Chrome-linux.png index e663484a3..12bd87671 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--YZ-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--YZ-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-YZ-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-YZ-1-Google-Chrome-linux.png index 7adaf7597..d314bd1b3 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-YZ-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-YZ-1-Google-Chrome-linux.png differ diff --git a/src/lang/queryAst.test.ts b/src/lang/queryAst.test.ts index a771d0284..f682fc095 100644 --- a/src/lang/queryAst.test.ts +++ b/src/lang/queryAst.test.ts @@ -5,7 +5,11 @@ import { PathToNode, Identifier, topLevelRange, + PipeExpression, + CallExpression, + VariableDeclarator, } from './wasm' +import { ProgramMemory } from 'lang/wasm' import { findAllPreviousVariables, isNodeSafeToReplace, @@ -25,9 +29,11 @@ import { createCallExpression, createLiteral, createPipeSubstitution, + createCallExpressionStdLib, } from './modifyAst' import { err } from 'lib/trap' import { codeRefFromRange } from './std/artifactGraph' +import { addCallExpressionsToPipe, addCloseToPipe } from 'lang/std/sketch' beforeAll(async () => { await initPromise @@ -680,3 +686,115 @@ myNestedVar = [ expect(pathToNode).toEqual(pathToNode2) }) }) + +describe('Testing specific sketch getNodeFromPath workflow', () => { + it('should parse the code', () => { + const openSketch = `sketch001 = startSketchOn('XZ') +|> startProfileAt([0.02, 0.22], %) +|> xLine(0.39, %) +|> line([0.02, -0.17], %) +|> yLine(-0.15, %) +|> line([-0.21, -0.02], %) +|> xLine(-0.15, %) +|> line([-0.02, 0.21], %) +|> line([-0.08, 0.05], %)` + const ast = assertParse(openSketch) + expect(ast.start).toEqual(0) + expect(ast.end).toEqual(227) + }) + it('should find the location to add new lineTo', () => { + const openSketch = `sketch001 = startSketchOn('XZ') +|> startProfileAt([0.02, 0.22], %) +|> xLine(0.39, %) +|> line([0.02, -0.17], %) +|> yLine(-0.15, %) +|> line([-0.21, -0.02], %) +|> xLine(-0.15, %) +|> line([-0.02, 0.21], %) +|> line([-0.08, 0.05], %)` + const ast = assertParse(openSketch) + + const sketchSnippet = `startProfileAt([0.02, 0.22], %)` + const sketchRange = topLevelRange( + openSketch.indexOf(sketchSnippet), + openSketch.indexOf(sketchSnippet) + sketchSnippet.length + ) + const sketchPathToNode = getNodePathFromSourceRange(ast, sketchRange) + const modifiedAst = addCallExpressionsToPipe({ + node: ast, + programMemory: ProgramMemory.empty(), + pathToNode: sketchPathToNode, + expressions: [ + createCallExpressionStdLib( + 'lineTo', // We are forcing lineTo! + [ + createArrayExpression([ + createCallExpressionStdLib('profileStartX', [ + createPipeSubstitution(), + ]), + createCallExpressionStdLib('profileStartY', [ + createPipeSubstitution(), + ]), + ]), + createPipeSubstitution(), + ] + ), + ], + }) + if (err(modifiedAst)) throw modifiedAst + const recasted = recast(modifiedAst) + const expectedCode = `sketch001 = startSketchOn('XZ') + |> startProfileAt([0.02, 0.22], %) + |> xLine(0.39, %) + |> line([0.02, -0.17], %) + |> yLine(-0.15, %) + |> line([-0.21, -0.02], %) + |> xLine(-0.15, %) + |> line([-0.02, 0.21], %) + |> line([-0.08, 0.05], %) + |> lineTo([profileStartX(%), profileStartY(%)], %) +` + expect(recasted).toEqual(expectedCode) + }) + it('it should find the location to add close', () => { + const openSketch = `sketch001 = startSketchOn('XZ') +|> startProfileAt([0.02, 0.22], %) +|> xLine(0.39, %) +|> line([0.02, -0.17], %) +|> yLine(-0.15, %) +|> line([-0.21, -0.02], %) +|> xLine(-0.15, %) +|> line([-0.02, 0.21], %) +|> line([-0.08, 0.05], %) +|> lineTo([profileStartX(%), profileStartY(%)], %) +` + const ast = assertParse(openSketch) + const sketchSnippet = `startProfileAt([0.02, 0.22], %)` + const sketchRange = topLevelRange( + openSketch.indexOf(sketchSnippet), + openSketch.indexOf(sketchSnippet) + sketchSnippet.length + ) + const sketchPathToNode = getNodePathFromSourceRange(ast, sketchRange) + const modifiedAst = addCloseToPipe({ + node: ast, + programMemory: ProgramMemory.empty(), + pathToNode: sketchPathToNode, + }) + + if (err(modifiedAst)) throw modifiedAst + const recasted = recast(modifiedAst) + const expectedCode = `sketch001 = startSketchOn('XZ') + |> startProfileAt([0.02, 0.22], %) + |> xLine(0.39, %) + |> line([0.02, -0.17], %) + |> yLine(-0.15, %) + |> line([-0.21, -0.02], %) + |> xLine(-0.15, %) + |> line([-0.02, 0.21], %) + |> line([-0.08, 0.05], %) + |> lineTo([profileStartX(%), profileStartY(%)], %) + |> close(%) +` + expect(recasted).toEqual(expectedCode) + }) +}) diff --git a/src/lang/queryAst.ts b/src/lang/queryAst.ts index 12b3f2f55..7f8c79d36 100644 --- a/src/lang/queryAst.ts +++ b/src/lang/queryAst.ts @@ -21,6 +21,7 @@ import { topLevelRange, VariableDeclaration, VariableDeclarator, + recast, } from './wasm' import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils' import { createIdentifier, splitPathAtLastIndex } from './modifyAst' @@ -68,7 +69,28 @@ export function getNodeFromPath( deepPath: successfulPaths, } } - return new Error('not an object') + const stackTraceError = new Error() + const sourceCode = recast(node) + const levels = stackTraceError.stack?.split('\n') + const aFewFunctionNames: string[] = [] + let tree = '' + levels?.forEach((val, index) => { + const fnName = val.trim().split(' ')[1] + const ending = index === levels.length - 1 ? ' ' : ' > ' + tree += fnName + ending + if (index < 3) { + aFewFunctionNames.push(fnName) + } + }) + const error = new Error( + `Failed to stopAt ${stopAt}, ${aFewFunctionNames + .filter((a) => a) + .join(' > ')}` + ) + console.error(tree) + console.error(sourceCode) + console.error(error.stack) + return error } currentNode = currentNode?.[pathItem[0]] successfulPaths.push(pathItem) diff --git a/src/machines/modelingMachine.ts b/src/machines/modelingMachine.ts index ccd1ec0f4..fe7905621 100644 --- a/src/machines/modelingMachine.ts +++ b/src/machines/modelingMachine.ts @@ -2561,7 +2561,7 @@ export const modelingMachine = setup({ 'Delete segment': { reenter: false, - actions: ['Delete segment', 'Set sketchDetails'], + actions: ['Delete segment', 'Set sketchDetails', 'reset selections'], }, 'code edit during sketch': '.clean slate', },