fix: updated the LiteralValue dereferencing and added some type narrowing helpers
This commit is contained in:
@ -612,8 +612,8 @@ export class SceneEntities {
|
|||||||
segment.type === 'TangentialArcTo'
|
segment.type === 'TangentialArcTo'
|
||||||
? segmentUtils.tangentialArcTo.init
|
? segmentUtils.tangentialArcTo.init
|
||||||
: segment.type === 'Circle'
|
: segment.type === 'Circle'
|
||||||
? segmentUtils.circle.init
|
? segmentUtils.circle.init
|
||||||
: segmentUtils.straight.init
|
: segmentUtils.straight.init
|
||||||
const input: SegmentInputs =
|
const input: SegmentInputs =
|
||||||
segment.type === 'Circle'
|
segment.type === 'Circle'
|
||||||
? {
|
? {
|
||||||
|
@ -6,6 +6,8 @@ import {
|
|||||||
ArrayExpression,
|
ArrayExpression,
|
||||||
BinaryExpression,
|
BinaryExpression,
|
||||||
ArtifactGraph,
|
ArtifactGraph,
|
||||||
|
LiteralValue,
|
||||||
|
NumericSuffix,
|
||||||
} from './wasm'
|
} from './wasm'
|
||||||
import { filterArtifacts } from 'lang/std/artifactGraph'
|
import { filterArtifacts } from 'lang/std/artifactGraph'
|
||||||
import { isOverlap } from 'lib/utils'
|
import { isOverlap } from 'lib/utils'
|
||||||
@ -69,3 +71,9 @@ export function isLiteral(e: any): e is Literal {
|
|||||||
export function isBinaryExpression(e: any): e is BinaryExpression {
|
export function isBinaryExpression(e: any): e is BinaryExpression {
|
||||||
return e && e.type === 'BinaryExpression'
|
return e && e.type === 'BinaryExpression'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isLiteralValueNotStringAndBoolean(
|
||||||
|
e: any
|
||||||
|
): e is { value: number; suffix: NumericSuffix } {
|
||||||
|
return e && 'value' in e && 'suffix' in e
|
||||||
|
}
|
||||||
|
@ -90,6 +90,7 @@ export type { Literal } from '../wasm-lib/kcl/bindings/Literal'
|
|||||||
export type { LiteralValue } from '../wasm-lib/kcl/bindings/LiteralValue'
|
export type { LiteralValue } from '../wasm-lib/kcl/bindings/LiteralValue'
|
||||||
export type { ArrayExpression } from '../wasm-lib/kcl/bindings/ArrayExpression'
|
export type { ArrayExpression } from '../wasm-lib/kcl/bindings/ArrayExpression'
|
||||||
export type { SourceRange } from 'wasm-lib/kcl/bindings/SourceRange'
|
export type { SourceRange } from 'wasm-lib/kcl/bindings/SourceRange'
|
||||||
|
export type { NumericSuffix } from 'wasm-lib/kcl/bindings/NumericSuffix'
|
||||||
|
|
||||||
export type SyntaxType =
|
export type SyntaxType =
|
||||||
| 'Program'
|
| 'Program'
|
||||||
|
87
src/lib/rectangleTool.test.ts
Normal file
87
src/lib/rectangleTool.test.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import { expect } from 'vitest'
|
||||||
|
import {
|
||||||
|
recast,
|
||||||
|
assertParse,
|
||||||
|
topLevelRange,
|
||||||
|
VariableDeclaration,
|
||||||
|
} from 'lang/wasm'
|
||||||
|
import { updateCenterRectangleSketch } from './rectangleTool'
|
||||||
|
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
|
||||||
|
import { getNodeFromPath } from 'lang/queryAst'
|
||||||
|
import { findUniqueName } from 'lang/modifyAst'
|
||||||
|
import { err, trap } from './trap'
|
||||||
|
|
||||||
|
describe('library rectangleTool helper functions', () => {
|
||||||
|
describe('updateCenterRectangleSketch', () => {
|
||||||
|
// regression test for https://github.com/KittyCAD/modeling-app/issues/5157
|
||||||
|
test('should update AST and source code', async () => {
|
||||||
|
// Base source code that will be edited in place
|
||||||
|
const sourceCode = `sketch001 = startSketchOn('XZ')
|
||||||
|
|> startProfileAt([120.37, 162.76], %)
|
||||||
|
|> angledLine([0, 0], %, $rectangleSegmentA001)
|
||||||
|
|> angledLine([segAng(rectangleSegmentA001) + 90, 0], %, $rectangleSegmentB001)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA001),
|
||||||
|
-segLen(rectangleSegmentA001)
|
||||||
|
], %, $rectangleSegmentC001)
|
||||||
|
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||||
|
|> close(%)
|
||||||
|
`
|
||||||
|
// Create ast
|
||||||
|
const _ast = assertParse(sourceCode)
|
||||||
|
let ast = structuredClone(_ast)
|
||||||
|
|
||||||
|
// Find some nodes and paths to reference
|
||||||
|
const sketchSnippet = `startProfileAt([120.37, 162.76], %)`
|
||||||
|
const sketchRange = topLevelRange(
|
||||||
|
sourceCode.indexOf(sketchSnippet),
|
||||||
|
sourceCode.indexOf(sketchSnippet) + sketchSnippet.length
|
||||||
|
)
|
||||||
|
const sketchPathToNode = getNodePathFromSourceRange(ast, sketchRange)
|
||||||
|
const _node = getNodeFromPath<VariableDeclaration>(
|
||||||
|
ast,
|
||||||
|
sketchPathToNode || [],
|
||||||
|
'VariableDeclaration'
|
||||||
|
)
|
||||||
|
if (trap(_node)) return
|
||||||
|
const sketchInit = _node.node?.declaration.init
|
||||||
|
|
||||||
|
// Hard code inputs that a user would have taken with their mouse
|
||||||
|
const x = 40
|
||||||
|
const y = 60
|
||||||
|
const rectangleOrigin = [120, 180]
|
||||||
|
const tags: [string, string, string] = [
|
||||||
|
'rectangleSegmentA001',
|
||||||
|
'rectangleSegmentB001',
|
||||||
|
'rectangleSegmentC001',
|
||||||
|
]
|
||||||
|
|
||||||
|
// Update the ast
|
||||||
|
if (sketchInit.type === 'PipeExpression') {
|
||||||
|
updateCenterRectangleSketch(
|
||||||
|
sketchInit,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
tags[0],
|
||||||
|
rectangleOrigin[0],
|
||||||
|
rectangleOrigin[1]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ast is edited in place from the updateCenterRectangleSketch
|
||||||
|
const expectedSourceCode = `sketch001 = startSketchOn('XZ')
|
||||||
|
|> startProfileAt([80, 120], %)
|
||||||
|
|> angledLine([0, 80], %, $rectangleSegmentA001)
|
||||||
|
|> angledLine([segAng(rectangleSegmentA001) + 90, 120], %, $rectangleSegmentB001)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA001),
|
||||||
|
-segLen(rectangleSegmentA001)
|
||||||
|
], %, $rectangleSegmentC001)
|
||||||
|
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||||
|
|> close(%)
|
||||||
|
`
|
||||||
|
const recasted = recast(ast)
|
||||||
|
expect(recasted).toEqual(expectedSourceCode)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
@ -8,13 +8,19 @@ import {
|
|||||||
createTagDeclarator,
|
createTagDeclarator,
|
||||||
createUnaryExpression,
|
createUnaryExpression,
|
||||||
} from 'lang/modifyAst'
|
} from 'lang/modifyAst'
|
||||||
import { ArrayExpression, CallExpression, PipeExpression } from 'lang/wasm'
|
import {
|
||||||
|
ArrayExpression,
|
||||||
|
CallExpression,
|
||||||
|
PipeExpression,
|
||||||
|
recast,
|
||||||
|
} from 'lang/wasm'
|
||||||
import { roundOff } from 'lib/utils'
|
import { roundOff } from 'lib/utils'
|
||||||
import {
|
import {
|
||||||
isCallExpression,
|
isCallExpression,
|
||||||
isArrayExpression,
|
isArrayExpression,
|
||||||
isLiteral,
|
isLiteral,
|
||||||
isBinaryExpression,
|
isBinaryExpression,
|
||||||
|
isLiteralValueNotStringAndBoolean,
|
||||||
} from 'lang/util'
|
} from 'lang/util'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -140,10 +146,12 @@ export function updateCenterRectangleSketch(
|
|||||||
if (isArrayExpression(arrayExpression)) {
|
if (isArrayExpression(arrayExpression)) {
|
||||||
const literal = arrayExpression.elements[0]
|
const literal = arrayExpression.elements[0]
|
||||||
if (isLiteral(literal)) {
|
if (isLiteral(literal)) {
|
||||||
callExpression.arguments[0] = createArrayExpression([
|
if (isLiteralValueNotStringAndBoolean(literal.value)) {
|
||||||
createLiteral(literal.value.value),
|
callExpression.arguments[0] = createArrayExpression([
|
||||||
createLiteral(Math.abs(twoX)),
|
createLiteral(literal.value.value),
|
||||||
])
|
createLiteral(Math.abs(twoX)),
|
||||||
|
])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user