Compare commits

...

6 Commits

Author SHA1 Message Date
42ed99fbf8 Merge branch 'main' into achalmers/morecleanup 2025-04-27 10:26:58 -05:00
15f6798262 More post-kwargs cleanup 2025-04-27 09:37:33 -05:00
c1a249d125 Another 2025-04-27 07:28:47 -05:00
58a13b8cfc More dead code 2025-04-27 07:20:27 -05:00
201a2d3bca Fix further 2025-04-27 07:13:43 -05:00
03997db387 Start cleaning up unneeded positional arg code 2025-04-27 07:06:55 -05:00
12 changed files with 113 additions and 334 deletions

View File

@ -23,7 +23,6 @@ import { getConstraintInfoKw } from '@src/lang/std/sketch'
import type { ConstrainInfo } from '@src/lang/std/stdTypes' import type { ConstrainInfo } from '@src/lang/std/stdTypes'
import { topLevelRange } from '@src/lang/util' import { topLevelRange } from '@src/lang/util'
import type { import type {
CallExpression,
CallExpressionKw, CallExpressionKw,
Expr, Expr,
PathToNode, PathToNode,
@ -530,10 +529,10 @@ const ConstraintSymbol = ({
if (trap(pResult) || !resultIsOk(pResult)) if (trap(pResult) || !resultIsOk(pResult))
return Promise.reject(pResult) return Promise.reject(pResult)
const _node1 = getNodeFromPath<CallExpression | CallExpressionKw>( const _node1 = getNodeFromPath<CallExpressionKw>(
pResult.program, pResult.program,
pathToNode, pathToNode,
['CallExpression', 'CallExpressionKw'], ['CallExpressionKw'],
true true
) )
if (trap(_node1)) return Promise.reject(_node1) if (trap(_node1)) return Promise.reject(_node1)

View File

@ -764,10 +764,10 @@ export class SceneEntities {
) )
let seg: Group let seg: Group
const _node1 = getNodeFromPath<Node<CallExpression | CallExpressionKw>>( const _node1 = getNodeFromPath<Node<CallExpressionKw>>(
maybeModdedAst, maybeModdedAst,
segPathToNode, segPathToNode,
['CallExpression', 'CallExpressionKw'] ['CallExpressionKw']
) )
if (err(_node1)) { if (err(_node1)) {
this.tearDownSketch({ removeAxis: false }) this.tearDownSketch({ removeAxis: false })
@ -2903,16 +2903,15 @@ export class SceneEntities {
Number(nodePathWithCorrectedIndexForTruncatedAst[1][0]) - Number(nodePathWithCorrectedIndexForTruncatedAst[1][0]) -
Number(sketchNodePaths[0][1][0]) Number(sketchNodePaths[0][1][0])
const _node = getNodeFromPath<Node<CallExpression | CallExpressionKw>>( const _node = getNodeFromPath<Node<CallExpressionKw>>(
modifiedAst, modifiedAst,
draftInfo ? nodePathWithCorrectedIndexForTruncatedAst : pathToNode, draftInfo ? nodePathWithCorrectedIndexForTruncatedAst : pathToNode,
['CallExpression', 'CallExpressionKw'] ['CallExpressionKw']
) )
if (trap(_node)) return if (trap(_node)) return
const node = _node.node const node = _node.node
if (node.type !== 'CallExpression' && node.type !== 'CallExpressionKw') if (node.type !== 'CallExpressionKw') return
return
let modded: let modded:
| { | {
@ -3335,12 +3334,11 @@ export class SceneEntities {
if (trap(pResult) || !resultIsOk(pResult)) if (trap(pResult) || !resultIsOk(pResult))
return Promise.reject(pResult) return Promise.reject(pResult)
const updatedAst = pResult.program const updatedAst = pResult.program
const _node = getNodeFromPath< const _node = getNodeFromPath<Node<CallExpressionKw>>(
Node<CallExpression | CallExpressionKw> updatedAst,
>(updatedAst, parent.userData.pathToNode, [ parent.userData.pathToNode,
'CallExpressionKw', ['CallExpressionKw', 'CallExpression']
'CallExpression', )
])
if (trap(_node, { suppress: true })) return if (trap(_node, { suppress: true })) return
const node = _node.node const node = _node.node
this.editorManager.setHighlightRange([ this.editorManager.setHighlightRange([

View File

@ -287,7 +287,7 @@ export function useEngineConnectionSubscriptions() {
>( >(
kclManager.ast, kclManager.ast,
chamferInfo?.segment.codeRef.pathToNode || [], chamferInfo?.segment.codeRef.pathToNode || [],
['CallExpression', 'CallExpressionKw'] ['CallExpressionKw']
) )
if (err(segmentCallExpr)) return null if (err(segmentCallExpr)) return null
if ( if (

View File

@ -427,10 +427,10 @@ export function giveSketchFnCallTag(
| Error { | Error {
const path = getNodePathFromSourceRange(ast, range) const path = getNodePathFromSourceRange(ast, range)
const maybeTag = (() => { const maybeTag = (() => {
const callNode = getNodeFromPath<CallExpression | CallExpressionKw>( const callNode = getNodeFromPath<CallExpressionKw>(
ast, ast,
path, path,
['CallExpression', 'CallExpressionKw'] ['CallExpressionKw']
) )
if (!err(callNode) && callNode.node.type === 'CallExpressionKw') { if (!err(callNode) && callNode.node.type === 'CallExpressionKw') {
const { node: primaryCallExp } = callNode const { node: primaryCallExp } = callNode

View File

@ -690,10 +690,10 @@ export function sketchOnExtrudedFace(
const { node: oldSketchNode } = _node1 const { node: oldSketchNode } = _node1
const oldSketchName = oldSketchNode.id.name const oldSketchName = oldSketchNode.id.name
const _node2 = getNodeFromPath<CallExpression | CallExpressionKw>( const _node2 = getNodeFromPath<CallExpressionKw>(
_node, _node,
sketchPathToNode, sketchPathToNode,
['CallExpression', 'CallExpressionKw'] ['CallExpressionKw']
) )
if (err(_node2)) return _node2 if (err(_node2)) return _node2
const { node: expression } = _node2 const { node: expression } = _node2

View File

@ -326,10 +326,10 @@ export function mutateAstWithTagForSketchSegment(
astClone: Node<Program>, astClone: Node<Program>,
pathToSegmentNode: PathToNode pathToSegmentNode: PathToNode
): { modifiedAst: Node<Program>; tag: string } | Error { ): { modifiedAst: Node<Program>; tag: string } | Error {
const segmentNode = getNodeFromPath<CallExpression | CallExpressionKw>( const segmentNode = getNodeFromPath<CallExpressionKw>(
astClone, astClone,
pathToSegmentNode, pathToSegmentNode,
['CallExpression', 'CallExpressionKw'] ['CallExpressionKw']
) )
if (err(segmentNode)) return segmentNode if (err(segmentNode)) return segmentNode
@ -588,21 +588,17 @@ export const hasValidEdgeTreatmentSelection = ({
// selection exists: // selection exists:
for (const selection of selectionRanges.graphSelections) { for (const selection of selectionRanges.graphSelections) {
// check if all selections are in sketchLineHelperMap // check if all selections are in sketchLineHelperMap
const segmentNode = getNodeFromPath< const segmentNode = getNodeFromPath<Node<CallExpressionKw>>(
Node<CallExpression | CallExpressionKw> ast,
>(ast, selection.codeRef.pathToNode, ['CallExpression', 'CallExpressionKw']) selection.codeRef.pathToNode,
['CallExpressionKw']
)
if (err(segmentNode)) return false if (err(segmentNode)) return false
if ( if (!(segmentNode.node.type === 'CallExpressionKw')) return false
!( if (!(segmentNode.node.callee.name.name in sketchLineHelperMapKw))
segmentNode.node.type === 'CallExpression' ||
segmentNode.node.type === 'CallExpressionKw'
)
) {
return false return false
} if (!(segmentNode.node.callee.name.name in sketchLineHelperMapKw))
if (!(segmentNode.node.callee.name.name in sketchLineHelperMapKw)) {
return false return false
}
// check if selection is extruded // check if selection is extruded
// TODO: option 1 : extrude is in the sketch pipe // TODO: option 1 : extrude is in the sketch pipe

View File

@ -20,7 +20,6 @@ import {
} from '@src/lang/std/artifactGraph' } from '@src/lang/std/artifactGraph'
import type { import type {
ArtifactGraph, ArtifactGraph,
CallExpression,
CallExpressionKw, CallExpressionKw,
ExpressionStatement, ExpressionStatement,
KclValue, KclValue,
@ -230,10 +229,10 @@ export async function deleteFromSelection(
varDec.node.type === 'CallExpression' || varDec.node.type === 'CallExpression' ||
varDec.node.type === 'CallExpressionKw' varDec.node.type === 'CallExpressionKw'
) { ) {
const callExp = getNodeFromPath<CallExpression | CallExpressionKw>( const callExp = getNodeFromPath<CallExpressionKw>(
astClone, astClone,
pathToNode, pathToNode,
['CallExpression', 'CallExpressionKw'] ['CallExpressionKw']
) )
if (err(callExp)) return callExp if (err(callExp)) return callExp
extrudeNameToDelete = callExp.node.callee.name.name extrudeNameToDelete = callExp.node.callee.name.name

View File

@ -4,6 +4,8 @@ import {
createArrayExpression, createArrayExpression,
createCallExpression, createCallExpression,
createCallExpressionStdLib, createCallExpressionStdLib,
createCallExpressionStdLibKw,
createLabeledArg,
createLiteral, createLiteral,
createPipeSubstitution, createPipeSubstitution,
} from '@src/lang/create' } from '@src/lang/create'
@ -28,6 +30,7 @@ import { assertParse, recast } from '@src/lang/wasm'
import { initPromise } from '@src/lang/wasmUtils' import { initPromise } from '@src/lang/wasmUtils'
import { enginelessExecutor } from '@src/lib/testHelpers' import { enginelessExecutor } from '@src/lib/testHelpers'
import { err } from '@src/lib/trap' import { err } from '@src/lib/trap'
import { ARG_END_ABSOLUTE } from '@src/lang/constants'
beforeAll(async () => { beforeAll(async () => {
await initPromise await initPromise
@ -721,9 +724,9 @@ describe('Testing specific sketch getNodeFromPath workflow', () => {
variables: {}, variables: {},
pathToNode: sketchPathToNode, pathToNode: sketchPathToNode,
expressions: [ expressions: [
createCallExpressionStdLib( createCallExpressionStdLibKw('line', null, [
'lineTo', // We are forcing lineTo! createLabeledArg(
[ ARG_END_ABSOLUTE,
createArrayExpression([ createArrayExpression([
createCallExpressionStdLib('profileStartX', [ createCallExpressionStdLib('profileStartX', [
createPipeSubstitution(), createPipeSubstitution(),
@ -731,10 +734,9 @@ describe('Testing specific sketch getNodeFromPath workflow', () => {
createCallExpressionStdLib('profileStartY', [ createCallExpressionStdLib('profileStartY', [
createPipeSubstitution(), createPipeSubstitution(),
]), ]),
]), ])
createPipeSubstitution(), ),
] ]),
),
], ],
}) })
if (err(modifiedAst)) throw modifiedAst if (err(modifiedAst)) throw modifiedAst
@ -748,7 +750,7 @@ describe('Testing specific sketch getNodeFromPath workflow', () => {
|> xLine(length = -0.15) |> xLine(length = -0.15)
|> line([-0.02, 0.21], %) |> line([-0.02, 0.21], %)
|> line([-0.08, 0.05], %) |> line([-0.08, 0.05], %)
|> lineTo([profileStartX(%), profileStartY(%)], %) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
` `
expect(recasted).toEqual(expectedCode) expect(recasted).toEqual(expectedCode)
}) })

View File

@ -9,7 +9,7 @@ import type { ToolTip } from '@src/lang/langHelpers'
import { splitPathAtLastIndex } from '@src/lang/modifyAst' import { splitPathAtLastIndex } from '@src/lang/modifyAst'
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils' import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
import { codeRefFromRange } from '@src/lang/std/artifactGraph' import { codeRefFromRange } from '@src/lang/std/artifactGraph'
import { getArgForEnd, getFirstArg } from '@src/lang/std/sketch' import { getArgForEnd } from '@src/lang/std/sketch'
import { getSketchSegmentFromSourceRange } from '@src/lang/std/sketchConstraints' import { getSketchSegmentFromSourceRange } from '@src/lang/std/sketchConstraints'
import { import {
getConstraintLevelFromSourceRange, getConstraintLevelFromSourceRange,
@ -521,10 +521,10 @@ export function isLinesParallelAndConstrained(
ast, ast,
secondaryLine?.codeRef?.range secondaryLine?.codeRef?.range
) )
const _secondaryNode = getNodeFromPath<CallExpression | CallExpressionKw>( const _secondaryNode = getNodeFromPath<CallExpressionKw>(
ast, ast,
secondaryPath, secondaryPath,
['CallExpression', 'CallExpressionKw'] ['CallExpressionKw']
) )
if (err(_secondaryNode)) return _secondaryNode if (err(_secondaryNode)) return _secondaryNode
const secondaryNode = _secondaryNode.node const secondaryNode = _secondaryNode.node
@ -565,10 +565,7 @@ export function isLinesParallelAndConstrained(
Math.abs(primaryAngle - secondaryAngleAlt) < EPSILON Math.abs(primaryAngle - secondaryAngleAlt) < EPSILON
// is secondary line fully constrain, or has constrain type of 'angle' // is secondary line fully constrain, or has constrain type of 'angle'
const secondaryFirstArg = const secondaryFirstArg = getArgForEnd(secondaryNode)
secondaryNode.type === 'CallExpression'
? getFirstArg(secondaryNode)
: getArgForEnd(secondaryNode)
if (err(secondaryFirstArg)) return secondaryFirstArg if (err(secondaryFirstArg)) return secondaryFirstArg
const isAbsolute = false // ADAM: TODO const isAbsolute = false // ADAM: TODO
@ -677,11 +674,9 @@ export function findUsesOfTagInPipe(
'segEndY', 'segEndY',
'segLen', 'segLen',
] ]
const nodeMeta = getNodeFromPath<CallExpression | CallExpressionKw>( const nodeMeta = getNodeFromPath<CallExpressionKw>(ast, pathToNode, [
ast, 'CallExpressionKw',
pathToNode, ])
['CallExpression', 'CallExpressionKw']
)
if (err(nodeMeta)) { if (err(nodeMeta)) {
console.error(nodeMeta) console.error(nodeMeta)
return [] return []
@ -689,11 +684,7 @@ export function findUsesOfTagInPipe(
const node = nodeMeta.node const node = nodeMeta.node
if (node.type !== 'CallExpressionKw' && node.type !== 'CallExpression') if (node.type !== 'CallExpressionKw' && node.type !== 'CallExpression')
return [] return []
const tagIndex = node.callee.name.name === 'close' ? 1 : 2 const tagParam = findKwArg(ARG_TAG, node)
const tagParam =
node.type === 'CallExpression'
? node.arguments[tagIndex]
: findKwArg(ARG_TAG, node)
if (!(tagParam?.type === 'TagDeclarator' || tagParam?.type === 'Name')) if (!(tagParam?.type === 'TagDeclarator' || tagParam?.type === 'Name'))
return [] return []
const tag = const tag =

View File

@ -33,7 +33,6 @@ import {
createPipeExpression, createPipeExpression,
createTagDeclarator, createTagDeclarator,
findUniqueName, findUniqueName,
nonCodeMetaEmpty,
} from '@src/lang/create' } from '@src/lang/create'
import type { ToolTip } from '@src/lang/langHelpers' import type { ToolTip } from '@src/lang/langHelpers'
import { toolTips } from '@src/lang/langHelpers' import { toolTips } from '@src/lang/langHelpers'
@ -3250,7 +3249,7 @@ export function addCallExpressionsToPipe({
node: Node<Program> node: Node<Program>
variables: VariableMap variables: VariableMap
pathToNode: PathToNode pathToNode: PathToNode
expressions: Node<CallExpression | CallExpressionKw>[] expressions: Node<CallExpressionKw>[]
}) { }) {
const _node: Node<Program> = structuredClone(node) const _node: Node<Program> = structuredClone(node)
const pipeExpression = getNodeFromPath<Node<PipeExpression>>( const pipeExpression = getNodeFromPath<Node<PipeExpression>>(
@ -3529,26 +3528,15 @@ function addTagKw(): addTagFn {
// is a keyword or positional call. // is a keyword or positional call.
// In fact, even something like `close(%)` could be either (because we allow 1 unlabeled // In fact, even something like `close(%)` could be either (because we allow 1 unlabeled
// starting param). // starting param).
const callExpr = getNodeFromPath<Node<CallExpressionKw | CallExpression>>( const callExpr = getNodeFromPath<Node<CallExpressionKw>>(
_node, _node,
pathToNode, pathToNode,
['CallExpressionKw', 'CallExpression'] ['CallExpressionKw']
) )
if (err(callExpr)) return callExpr if (err(callExpr)) return callExpr
// If the original node is a call expression, we'll need to change it to a call with keyword args. // If the original node is a call expression, we'll need to change it to a call with keyword args.
const primaryCallExp: CallExpressionKw = const primaryCallExp: CallExpressionKw = callExpr.node
callExpr.node.type === 'CallExpressionKw'
? callExpr.node
: {
type: 'CallExpressionKw',
callee: callExpr.node.callee,
unlabeled: callExpr.node.arguments.length
? callExpr.node.arguments[0]
: null,
nonCodeMeta: nonCodeMetaEmpty(),
arguments: [],
}
const tagArg = findKwArg(ARG_TAG, primaryCallExp) const tagArg = findKwArg(ARG_TAG, primaryCallExp)
const tagDeclarator = const tagDeclarator =
tagArg || createTagDeclarator(findUniqueName(_node, 'seg', 2)) tagArg || createTagDeclarator(findUniqueName(_node, 'seg', 2))
@ -3603,17 +3591,6 @@ export function getXComponent(
return [sign * xComponent, sign * yComponent] return [sign * xComponent, sign * yComponent]
} }
function getFirstArgValuesForXYFns(callExpression: CallExpression):
| {
val: [Expr, Expr]
tag?: Expr
}
| Error {
// used for lineTo, line
const firstArg = callExpression.arguments[0]
return getValuesForXYFns(firstArg)
}
function getValuesForXYFns(arg: Expr): function getValuesForXYFns(arg: Expr):
| { | {
val: [Expr, Expr] val: [Expr, Expr]
@ -3634,63 +3611,6 @@ function getValuesForXYFns(arg: Expr):
return new Error('expected ArrayExpression or ObjectExpression') return new Error('expected ArrayExpression or ObjectExpression')
} }
function getFirstArgValuesForAngleFns(callExpression: CallExpression):
| {
val: [Expr, Expr]
tag?: Expr
}
| Error {
// used for angledLine, angledLineOfXLength, angledLineToX, angledLineOfYLength, angledLineToY
const firstArg = callExpression.arguments[0]
if (firstArg.type === 'ArrayExpression') {
return { val: [firstArg.elements[0], firstArg.elements[1]] }
}
if (firstArg.type === 'ObjectExpression') {
const tag = firstArg.properties.find((p) => p.key.name === 'tag')?.value
const angle = firstArg.properties.find((p) => p.key.name === 'angle')?.value
const secondArgName = ['angledLineToX', 'angledLineToY'].includes(
callExpression?.callee?.name.name as ToolTip
)
? 'to'
: 'length'
const length = firstArg.properties.find(
(p) => p.key.name === secondArgName
)?.value
if (angle && length) {
return { val: [angle, length], tag }
}
}
return new Error('expected ArrayExpression or ObjectExpression')
}
function getFirstArgValuesForXYLineFns(callExpression: CallExpression): {
val: Expr
tag?: Expr
} {
// used for xLine, yLine, xLineTo, yLineTo
const firstArg = callExpression.arguments[0]
if (firstArg.type !== 'ObjectExpression') {
return { val: firstArg }
}
const tag = firstArg.properties.find((p) => p.key.name === 'tag')?.value
const secondArgName = ['xLineTo', 'yLineTo'].includes(
// const secondArgName = ['xLineTo', 'yLineTo', 'angledLineToX', 'angledLineToY'].includes(
callExpression?.callee?.name.name
)
? 'to'
: 'length'
const length = firstArg.properties.find(
(p) => p.key.name === secondArgName
)?.value
if (length) {
return { val: length, tag }
}
console.warn('expected ArrayExpression or ObjectExpression')
return {
val: createLiteral(1),
}
}
export const getAngledLine = ( export const getAngledLine = (
callExp: CallExpressionKw callExp: CallExpressionKw
): ):
@ -3890,34 +3810,6 @@ export function getArgForEnd(lineCall: CallExpressionKw):
} }
} }
export function getFirstArg(callExp: CallExpression):
| {
val: Expr | [Expr, Expr] | [Expr, Expr, Expr]
tag?: Expr
}
| Error {
const name = callExp?.callee?.name.name
if (
[
'angledLine',
'angledLineOfXLength',
'angledLineToX',
'angledLineOfYLength',
'angledLineToY',
].includes(name)
) {
return getFirstArgValuesForAngleFns(callExp)
}
if (['xLine', 'yLine', 'xLineTo', 'yLineTo'].includes(name)) {
return getFirstArgValuesForXYLineFns(callExp)
}
if (['tangentialArc'].includes(name)) {
// TODO probably needs it's own implementation
return getFirstArgValuesForXYFns(callExp)
}
return new Error('unexpected call expression: ' + name)
}
/** A determining arg is one that determines the line, e.g. for xLine it's either 'length' or 'endAbsolute' /** A determining arg is one that determines the line, e.g. for xLine it's either 'length' or 'endAbsolute'
*/ */
function removeDeterminingArgs(callExp: CallExpressionKw) { function removeDeterminingArgs(callExp: CallExpressionKw) {

View File

@ -43,7 +43,6 @@ import {
getArgForEnd, getArgForEnd,
getCircle, getCircle,
getConstraintInfoKw, getConstraintInfoKw,
getFirstArg,
isAbsoluteLine, isAbsoluteLine,
replaceSketchLine, replaceSketchLine,
tooltipToFnName, tooltipToFnName,
@ -1288,7 +1287,7 @@ const transformMap: TransformMap = {
} }
export function getRemoveConstraintsTransform( export function getRemoveConstraintsTransform(
sketchFnExp: CallExpression | CallExpressionKw, sketchFnExp: CallExpressionKw,
constraintType: ConstraintType constraintType: ConstraintType
): TransformInfo | false { ): TransformInfo | false {
let name = sketchFnExp.callee.name.name as ToolTip let name = sketchFnExp.callee.name.name as ToolTip
@ -1335,19 +1334,14 @@ export function getRemoveConstraintsTransform(
) { ) {
return false return false
} }
const isAbsolute = const isAbsolute = isAbsoluteLine(sketchFnExp)
// isAbsolute doesn't matter if the call is positional.
sketchFnExp.type === 'CallExpression' ? false : isAbsoluteLine(sketchFnExp)
if (err(isAbsolute)) { if (err(isAbsolute)) {
console.error(isAbsolute) console.error(isAbsolute)
return false return false
} }
// check if the function is locked down and so can't be transformed // check if the function is locked down and so can't be transformed
const firstArg = const firstArg = getArgForEnd(sketchFnExp)
sketchFnExp.type === 'CallExpression'
? getFirstArg(sketchFnExp)
: getArgForEnd(sketchFnExp)
if (err(firstArg)) { if (err(firstArg)) {
return false return false
} }
@ -1386,19 +1380,14 @@ export function removeSingleConstraint({
inputDetails: SimplifiedArgDetails inputDetails: SimplifiedArgDetails
ast: Program ast: Program
}): TransformInfo | false { }): TransformInfo | false {
const callExp = getNodeFromPath<CallExpression | CallExpressionKw>( const callExp = getNodeFromPath<CallExpressionKw>(ast, pathToCallExp, [
ast, 'CallExpressionKw',
pathToCallExp, ])
['CallExpression', 'CallExpressionKw']
)
if (err(callExp)) { if (err(callExp)) {
console.error(callExp) console.error(callExp)
return false return false
} }
if ( if (callExp.node.type !== 'CallExpressionKw') {
callExp.node.type !== 'CallExpression' &&
callExp.node.type !== 'CallExpressionKw'
) {
console.error(new Error('Invalid node type')) console.error(new Error('Invalid node type'))
return false return false
} }
@ -1474,30 +1463,22 @@ export function removeSingleConstraint({
const literal = rawArg?.overrideExpr ?? rawArg?.expr const literal = rawArg?.overrideExpr ?? rawArg?.expr
return (arg.index === inputToReplace.index && literal) || argExpr return (arg.index === inputToReplace.index && literal) || argExpr
}) })
if (callExp.node.type === 'CallExpression') { // It's a kw call.
return createStdlibCallExpression( const isAbsolute = callExp.node.callee.name.name == 'lineTo'
callExp.node.callee.name.name as any, if (isAbsolute) {
createArrayExpression(values), const args = [
createLabeledArg(ARG_END_ABSOLUTE, createArrayExpression(values)),
]
return createStdlibCallExpressionKw('line', args, tag)
} else {
const args = [
createLabeledArg(ARG_END, createArrayExpression(values)),
]
return createStdlibCallExpressionKw(
callExp.node.callee.name.name as ToolTip,
args,
tag tag
) )
} else {
// It's a kw call.
const isAbsolute = callExp.node.callee.name.name == 'lineTo'
if (isAbsolute) {
const args = [
createLabeledArg(ARG_END_ABSOLUTE, createArrayExpression(values)),
]
return createStdlibCallExpressionKw('line', args, tag)
} else {
const args = [
createLabeledArg(ARG_END, createArrayExpression(values)),
]
return createStdlibCallExpressionKw(
callExp.node.callee.name.name as ToolTip,
args,
tag
)
}
} }
} }
if ( if (
@ -1628,63 +1609,6 @@ export function removeSingleConstraint({
return transform return transform
} }
function getTransformMapPath(
sketchFnExp: CallExpression,
constraintType: ConstraintType
):
| {
toolTip: ToolTip
lineInputType: LineInputsType | 'free'
constraintType: ConstraintType
}
| false {
const name = sketchFnExp.callee.name.name as ToolTip
if (!toolTips.includes(name)) {
return false
}
if (name === 'arcTo') {
return false
}
// check if the function is locked down and so can't be transformed
const firstArg = getFirstArg(sketchFnExp)
if (err(firstArg)) {
console.error(firstArg)
return false
}
if (isNotLiteralArrayOrStatic(firstArg.val)) {
return false
}
// check if the function has no constraints
if (isLiteralArrayOrStatic(firstArg.val)) {
const info = transformMap?.[name]?.free?.[constraintType]
if (info)
return {
toolTip: name,
lineInputType: 'free',
constraintType,
}
// if (info) return info
}
// check what constraints the function has
const lineInputType = getConstraintType(firstArg.val, name, false)
if (lineInputType) {
const info = transformMap?.[name]?.[lineInputType]?.[constraintType]
if (info)
return {
toolTip: name,
lineInputType,
constraintType,
}
// if (info) return info
}
return false
}
function getTransformMapPathKw( function getTransformMapPathKw(
sketchFnExp: CallExpressionKw, sketchFnExp: CallExpressionKw,
constraintType: ConstraintType constraintType: ConstraintType
@ -1756,18 +1680,6 @@ function getTransformMapPathKw(
return false return false
} }
export function getTransformInfo(
sketchFnExp: CallExpression,
constraintType: ConstraintType
): TransformInfo | false {
const path = getTransformMapPath(sketchFnExp, constraintType)
if (!path) return false
const { toolTip, lineInputType, constraintType: _constraintType } = path
const info = transformMap?.[toolTip]?.[lineInputType]?.[_constraintType]
if (!info) return false
return info
}
export function getTransformInfoKw( export function getTransformInfoKw(
sketchFnExp: CallExpressionKw, sketchFnExp: CallExpressionKw,
constraintType: ConstraintType constraintType: ConstraintType
@ -1821,10 +1733,7 @@ export function getTransformInfos(
constraintType: ConstraintType constraintType: ConstraintType
): TransformInfo[] { ): TransformInfo[] {
const nodes = selectionRanges.graphSelections.map(({ codeRef }) => const nodes = selectionRanges.graphSelections.map(({ codeRef }) =>
getNodeFromPath<Expr>(ast, codeRef.pathToNode, [ getNodeFromPath<Expr>(ast, codeRef.pathToNode, ['CallExpressionKw'])
'CallExpression',
'CallExpressionKw',
])
) )
try { try {
@ -1835,9 +1744,6 @@ export function getTransformInfos(
} }
const node = nodeMeta.node const node = nodeMeta.node
if (node?.type === 'CallExpression') {
return getTransformInfo(node, constraintType)
}
if (node?.type === 'CallExpressionKw') { if (node?.type === 'CallExpressionKw') {
return getTransformInfoKw(node, constraintType) return getTransformInfoKw(node, constraintType)
@ -1870,7 +1776,7 @@ export function getRemoveConstraintsTransforms(
} }
const node = nodeMeta.node const node = nodeMeta.node
if (node?.type === 'CallExpression' || node?.type === 'CallExpressionKw') { if (node?.type === 'CallExpressionKw') {
return getRemoveConstraintsTransform(node, constraintType) return getRemoveConstraintsTransform(node, constraintType)
} }
@ -2208,52 +2114,49 @@ export function getConstraintLevelFromSourceRange(
if (err(ast)) return ast if (err(ast)) return ast
let partsOfCallNode = (() => { let partsOfCallNode = (() => {
const path = getNodePathFromSourceRange(ast, cursorRange) const path = getNodePathFromSourceRange(ast, cursorRange)
const nodeMeta = getNodeFromPath< const nodeMeta = getNodeFromPath<Node<CallExpressionKw>>(
Node<CallExpression> | Node<CallExpressionKw> ast,
>(ast, path, ['CallExpression', 'CallExpressionKw']) path,
'CallExpressionKw'
)
if (err(nodeMeta)) return nodeMeta if (err(nodeMeta)) return nodeMeta
const { node: sketchFnExp } = nodeMeta const { node: sketchFnExp } = nodeMeta
const name = sketchFnExp?.callee?.name.name as ToolTip const name = sketchFnExp?.callee?.name.name as ToolTip
const range: [number, number] = [sketchFnExp.start, sketchFnExp.end] const range: [number, number] = [sketchFnExp.start, sketchFnExp.end]
const firstArg = (() => { const firstArg = (() => {
switch (nodeMeta.node.type) { if (name === 'circle') {
case 'CallExpression': return getCircle(nodeMeta.node)
return getFirstArg(nodeMeta.node) }
case 'CallExpressionKw': if (
if (name === 'circle') { name === 'angledLine' ||
return getCircle(nodeMeta.node) name === 'angledLineOfXLength' ||
} name === 'angledLineOfYLength' ||
if ( name === 'angledLineToX' ||
name === 'angledLine' || name === 'angledLineToY'
name === 'angledLineOfXLength' || ) {
name === 'angledLineOfYLength' || return getAngledLine(nodeMeta.node)
name === 'angledLineToX' || }
name === 'angledLineToY' if (name === 'angledLineThatIntersects') {
) { return getAngledLineThatIntersects(nodeMeta.node)
return getAngledLine(nodeMeta.node) }
} if (name === 'arc') {
if (name === 'angledLineThatIntersects') { return getArc(nodeMeta.node)
return getAngledLineThatIntersects(nodeMeta.node) }
} const arg = findKwArgAny(DETERMINING_ARGS, nodeMeta.node)
if (name === 'arc') { if (arg === undefined) {
return getArc(nodeMeta.node) const argStr = nodeMeta.node.arguments.map((a) => a.label.name)
} return new Error(
const arg = findKwArgAny(DETERMINING_ARGS, nodeMeta.node) `call to expression ${name} has unexpected args: ${argStr} `
if (arg === undefined) { )
const argStr = nodeMeta.node.arguments.map((a) => a.label.name) }
return new Error( const val =
`call to expression ${name} has unexpected args: ${argStr} ` arg.type === 'ArrayExpression' && arg.elements.length === 2
) ? (arg.elements as [Expr, Expr])
} : arg
const val = return {
arg.type === 'ArrayExpression' && arg.elements.length === 2 val,
? (arg.elements as [Expr, Expr]) tag: findKwArg(ARG_TAG, nodeMeta.node),
: arg
return {
val,
tag: findKwArg(ARG_TAG, nodeMeta.node),
}
} }
})() })()
return { name, range, firstArg } return { name, range, firstArg }

View File

@ -19,7 +19,6 @@ import type { PathToNodeMap } from '@src/lang/std/sketchcombos'
import { isCursorInSketchCommandRange, topLevelRange } from '@src/lang/util' import { isCursorInSketchCommandRange, topLevelRange } from '@src/lang/util'
import type { import type {
ArtifactGraph, ArtifactGraph,
CallExpression,
CallExpressionKw, CallExpressionKw,
Expr, Expr,
Program, Program,
@ -353,10 +352,10 @@ function updateSceneObjectColors(codeBasedSelections: Selection[]) {
Object.values(sceneEntitiesManager.activeSegments).forEach((segmentGroup) => { Object.values(sceneEntitiesManager.activeSegments).forEach((segmentGroup) => {
if (!SEGMENT_BODIES_PLUS_PROFILE_START.includes(segmentGroup?.name)) return if (!SEGMENT_BODIES_PLUS_PROFILE_START.includes(segmentGroup?.name)) return
const nodeMeta = getNodeFromPath<Node<CallExpression | CallExpressionKw>>( const nodeMeta = getNodeFromPath<Node<CallExpressionKw>>(
updated, updated,
segmentGroup.userData.pathToNode, segmentGroup.userData.pathToNode,
['CallExpression', 'CallExpressionKw'] ['CallExpressionKw']
) )
if (err(nodeMeta)) return if (err(nodeMeta)) return
const node = nodeMeta.node const node = nodeMeta.node