diff --git a/e2e/playwright/testing-constraints.spec.ts b/e2e/playwright/testing-constraints.spec.ts index 87a2a6934..bf57948ac 100644 --- a/e2e/playwright/testing-constraints.spec.ts +++ b/e2e/playwright/testing-constraints.spec.ts @@ -1105,7 +1105,9 @@ part002 = startSketchOn('XZ') await pollEditorLinesSelectedLength(page, 1) activeLinesContent = await page.locator('.cm-activeLine').all() - await expect(activeLinesContent[0]).toHaveText(`|> xLine(length = length001)`) + await expect(activeLinesContent[0]).toHaveText( + `|> xLine(length = length001)` + ) // checking the count of the overlays is a good proxy check that the client sketch scene is in a good state await expect(page.getByTestId('segment-overlay')).toHaveCount(2) diff --git a/e2e/playwright/testing-selections.spec.ts b/e2e/playwright/testing-selections.spec.ts index 191f2cd55..2e210a8fb 100644 --- a/e2e/playwright/testing-selections.spec.ts +++ b/e2e/playwright/testing-selections.spec.ts @@ -158,7 +158,9 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => { // check the same selection again by putting cursor in code first then selecting axis await test.step(`Same selection but code selection then axis`, async () => { - await page.getByText(` |> xLine(length = ${commonPoints.num2 * -1})`).click() + await page + .getByText(` |> xLine(length = ${commonPoints.num2 * -1})`) + .click() await page.keyboard.down('Shift') await constrainButton.click() await expect(absXButton).toBeDisabled() @@ -182,7 +184,9 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => { process.platform === 'linux' ? 'Control' : 'Meta' ) await page.waitForTimeout(100) - await page.getByText(` |> xLine(length = ${commonPoints.num2 * -1})`).click() + await page + .getByText(` |> xLine(length = ${commonPoints.num2 * -1})`) + .click() await expect(page.locator('.cm-cursor')).toHaveCount(2) await page.waitForTimeout(500) diff --git a/src/lang/std/sketch.ts b/src/lang/std/sketch.ts index 89810b9f8..7cacbad54 100644 --- a/src/lang/std/sketch.ts +++ b/src/lang/std/sketch.ts @@ -125,12 +125,7 @@ export function createFirstArg( intersectTag: val[2], }) } else { - if ( - ['startSketchAt', 'xLine', 'xLineTo', 'yLine', 'yLineTo'].includes( - sketchFn - ) - ) - return val + if (['startSketchAt'].includes(sketchFn)) return val } return new Error('Missing sketch line type') } @@ -303,46 +298,6 @@ const commonConstraintInfoHelper = ( return constraints } -const horzVertConstraintInfoHelper = ( - callExp: CallExpression, - inputConstrainTypes: [ConstrainInfo['type'], ConstrainInfo['type']], - stdLibFnName: ConstrainInfo['stdLibFnName'], - abbreviatedInput: AbbreviatedInput, - code: string, - pathToNode: PathToNode, - filterValue?: string -) => { - if (callExp.type !== 'CallExpression') return [] - const firstArg = callExp.arguments?.[0] - const callee = callExp.callee - const pathToFirstArg: PathToNode = [ - ...pathToNode, - ['arguments', 'CallExpression'], - [0, 'index'], - ] - const pathToCallee: PathToNode = [...pathToNode, ['callee', 'CallExpression']] - return [ - constrainInfo( - inputConstrainTypes[0], - true, - callee.name, - stdLibFnName, - undefined, - topLevelRange(callee.start, callee.end), - pathToCallee - ), - constrainInfo( - inputConstrainTypes[1], - isNotLiteralArrayOrStatic(callExp.arguments?.[0]), - code.slice(firstArg.start, firstArg.end), - stdLibFnName, - abbreviatedInput, - topLevelRange(firstArg.start, firstArg.end), - pathToFirstArg - ), - ] -} - const horzVertConstraintInfoHelperKw = ( callExp: CallExpressionKw, inputConstrainTypes: [ConstrainInfo['type'], ConstrainInfo['type']], @@ -353,7 +308,6 @@ const horzVertConstraintInfoHelperKw = ( filterValue?: string ) => { if (callExp.type !== 'CallExpressionKw') return [] - const firstArg = callExp.arguments?.[0] const callee = callExp.callee const relevantArg = findKwArgAnyIndex( [ARG_END_ABSOLUTE, ARG_END, ARG_LENGTH], @@ -367,7 +321,10 @@ const horzVertConstraintInfoHelperKw = ( [argIndex, ARG_INDEX_FIELD], ['arg', LABELED_ARG_FIELD], ] - const pathToCallee: PathToNode = [...pathToNode, ['callee', 'CallExpression']] + const pathToCallee: PathToNode = [ + ...pathToNode, + ['callee', 'CallExpressionKw'], + ] return [ constrainInfo( inputConstrainTypes[0], @@ -766,7 +723,7 @@ export const xLineTo: SketchLineHelperKw = { ), } -export const yLineTo: SketchLineHelper = { +export const yLineTo: SketchLineHelperKw = { add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => { if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR const { to } = segmentInput @@ -796,9 +753,8 @@ export const yLineTo: SketchLineHelper = { valueUsedInTransform, } } - const callExp = createCallExpression('yLineTo', [ - newVal, - createPipeSubstitution(), + const callExp = createCallExpressionStdLibKw('yLine', newVal, [ + createLabeledArg(ARG_END_ABSOLUTE, newVal), ]) pipe.body = [...pipe.body, callExp] return { @@ -810,24 +766,20 @@ export const yLineTo: SketchLineHelper = { if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR const { to } = input const _node = { ...node } - const nodeMeta = getNodeFromPath(_node, pathToNode) + const nodeMeta = getNodeFromPath(_node, pathToNode) if (err(nodeMeta)) return nodeMeta const { node: callExpression } = nodeMeta const newY = createLiteral(roundOff(to[1], 2)) - if (isLiteralArrayOrStatic(callExpression.arguments?.[0])) { - callExpression.arguments[0] = newY - } else { - mutateObjExpProp(callExpression.arguments?.[0], newY, 'to') - } + mutateKwArg(ARG_END_ABSOLUTE, callExpression, newY) return { modifiedAst: _node, pathToNode, } }, - getTag: getTag(), - addTag: addTag(), + getTag: getTagKwArg(), + addTag: addTagKw(), getConstraintInfo: (callExp, ...args) => - horzVertConstraintInfoHelper( + horzVertConstraintInfoHelperKw( callExp, ['vertical', 'yAbsolute'], 'yLineTo', @@ -907,7 +859,7 @@ export const xLine: SketchLineHelperKw = { ), } -export const yLine: SketchLineHelper = { +export const yLine: SketchLineHelperKw = { add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => { if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR const { from, to } = segmentInput @@ -940,9 +892,8 @@ export const yLine: SketchLineHelper = { } } - const newLine = createCallExpression('yLine', [ - newVal, - createPipeSubstitution(), + const newLine = createCallExpressionStdLibKw('yLine', null, [ + createLabeledArg(ARG_LENGTH, newVal), ]) if (dec.init.type === 'PipeExpression') { dec.init.body = [...dec.init.body, newLine] @@ -955,24 +906,20 @@ export const yLine: SketchLineHelper = { if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR const { to, from } = input const _node = { ...node } - const nodeMeta = getNodeFromPath(_node, pathToNode) + const nodeMeta = getNodeFromPath(_node, pathToNode) if (err(nodeMeta)) return nodeMeta const { node: callExpression } = nodeMeta const newY = createLiteral(roundOff(to[1] - from[1], 2)) - if (isLiteralArrayOrStatic(callExpression.arguments?.[0])) { - callExpression.arguments[0] = newY - } else { - mutateObjExpProp(callExpression.arguments?.[0], newY, 'length') - } + mutateKwArg(ARG_LENGTH, callExpression, newY) return { modifiedAst: _node, pathToNode, } }, - getTag: getTag(), - addTag: addTag(), + getTag: getTagKwArg(), + addTag: addTagKw(), getConstraintInfo: (callExp, ...args) => - horzVertConstraintInfoHelper( + horzVertConstraintInfoHelperKw( callExp, ['vertical', 'yRelative'], 'yLine', @@ -2324,8 +2271,6 @@ export const updateStartProfileAtArgs: SketchLineHelper['updateArgs'] = ({ } export const sketchLineHelperMap: { [key: string]: SketchLineHelper } = { - yLine, - yLineTo, angledLine, angledLineOfXLength, angledLineOfYLength, @@ -2342,6 +2287,8 @@ export const sketchLineHelperMapKw: { [key: string]: SketchLineHelperKw } = { circleThreePoint, xLine, xLineTo, + yLine, + yLineTo, } as const export function changeSketchArguments( @@ -2505,13 +2452,14 @@ export function addNewSketchLn({ pathToNode, 'PipeExpression' ) - return add({ + const result = add({ node, variables, pathToNode, segmentInput, spliceBetween, }) + return result } export function addCallExpressionsToPipe({ @@ -2990,10 +2938,7 @@ function getFirstArgValuesForXYLineFns(callExpression: CallExpression): { return { val: firstArg } } const tag = firstArg.properties.find((p) => p.key.name === 'tag')?.value - const secondArgName = ['xLineTo', 'yLineTo', 'startSketchAt'].includes( - // const secondArgName = ['xLineTo', 'yLineTo', 'angledLineToX', 'angledLineToY'].includes( - callExpression?.callee?.name - ) + const secondArgName = ['startSketchAt'].includes(callExpression?.callee?.name) ? 'to' : 'length' const length = firstArg.properties.find( diff --git a/src/lang/std/sketchcombos.ts b/src/lang/std/sketchcombos.ts index 1c6827482..618a7c65b 100644 --- a/src/lang/std/sketchcombos.ts +++ b/src/lang/std/sketchcombos.ts @@ -139,7 +139,7 @@ function createCallWrapper( } if (tooltip === 'lineTo') { const labeledArgs = [ - createLabeledArg('endAbsolute', createArrayExpression(val)), + createLabeledArg(ARG_END_ABSOLUTE, createArrayExpression(val)), ] if (tag) { labeledArgs.push(createLabeledArg(ARG_TAG, tag)) @@ -153,6 +153,41 @@ function createCallWrapper( valueUsedInTransform, } } + } else { + // This else branch type narrows 'val' to a scalar. + if ( + 'xLine' === tooltip || + 'yLine' === tooltip || + 'xLineTo' === tooltip || + 'yLineTo' === tooltip + ) { + const [isAbsolute, callee] = (() => { + switch (tooltip) { + case 'xLine': + return [false, 'xLine'] + case 'yLine': + return [false, 'yLine'] + case 'xLineTo': + return [true, 'xLine'] + case 'yLineTo': + return [true, 'yLine'] + } + })() + const labeledArgs = [ + createLabeledArg(isAbsolute ? ARG_END_ABSOLUTE : ARG_LENGTH, val), + ] + if (tag) { + labeledArgs.push(createLabeledArg(ARG_TAG, tag)) + } + return { + callExp: createCallExpressionStdLibKw( + callee, + null, // Assumes this is being called in a pipeline, so the first arg is optional and if not given, will become pipeline substitution. + labeledArgs + ), + valueUsedInTransform, + } + } } const args = @@ -1642,6 +1677,8 @@ function getTransformMapPathKw( return 'lineTo' case 'xLine': return 'xLineTo' + case 'yLine': + return 'yLineTo' default: return name }