Files
modeling-app/src/lang/util.ts
Jonathan Tran f7ee248a26 Fix to use more accurate types with custom isArray() and add lint (#5261)
* Fix to use more accurate types with custom isArray()

* Add lint against Array.isArray()
2025-02-05 09:01:45 -05:00

128 lines
3.1 KiB
TypeScript

import { Selections } from 'lib/selections'
import {
PathToNode,
CallExpression,
Literal,
ArrayExpression,
BinaryExpression,
ArtifactGraph,
CallExpressionKw,
Expr,
LiteralValue,
NumericSuffix,
} from './wasm'
import { filterArtifacts } from 'lang/std/artifactGraph'
import { isArray, isOverlap } from 'lib/utils'
export function updatePathToNodeFromMap(
oldPath: PathToNode,
pathToNodeMap: { [key: number]: PathToNode }
): PathToNode {
const updatedPathToNode = structuredClone(oldPath)
let max = 0
Object.values(pathToNodeMap).forEach((path) => {
const index = Number(path[1][0])
if (index > max) {
max = index
}
})
updatedPathToNode[1][0] = max
return updatedPathToNode
}
export function isCursorInSketchCommandRange(
artifactGraph: ArtifactGraph,
selectionRanges: Selections
): string | false {
const overlappingEntries = filterArtifacts(
{
types: ['segment', 'path'],
predicate: (artifact) => {
return selectionRanges.graphSelections.some(
(selection) =>
isArray(selection?.codeRef?.range) &&
isArray(artifact?.codeRef?.range) &&
isOverlap(selection?.codeRef?.range, artifact.codeRef.range)
)
},
},
artifactGraph
)
const firstEntry = [...overlappingEntries.values()]?.[0]
const parentId = firstEntry?.type === 'segment' ? firstEntry.pathId : false
return parentId
? parentId
: [...overlappingEntries].find(
([, artifact]) => artifact.type === 'path'
)?.[0] || false
}
export function isCallExpression(e: any): e is CallExpression {
return e && e.type === 'CallExpression'
}
export function isArrayExpression(e: any): e is ArrayExpression {
return e && e.type === 'ArrayExpression'
}
export function isLiteral(e: any): e is Literal {
return e && e.type === 'Literal'
}
export function isBinaryExpression(e: any): e is BinaryExpression {
return e && e.type === 'BinaryExpression'
}
/**
Search the keyword arguments from a call for an argument with this label.
*/
export function findKwArg(
label: string,
call: CallExpressionKw
): Expr | undefined {
return call.arguments.find((arg) => {
return arg.label.name === label
})?.arg
}
/**
Search the keyword arguments from a call for an argument with one of these labels.
*/
export function findKwArgAny(
labels: string[],
call: CallExpressionKw
): Expr | undefined {
return call.arguments.find((arg) => {
return labels.includes(arg.label.name)
})?.arg
}
/**
Search the keyword arguments from a call for an argument with one of these labels.
*/
export function findKwArgAnyIndex(
labels: string[],
call: CallExpressionKw
): number | undefined {
return call.arguments.findIndex((arg) => {
return labels.includes(arg.label.name)
})
}
export function isAbsolute(call: CallExpressionKw): boolean {
return findKwArgAny(['endAbsolute'], call) !== undefined
}
export function isLiteralValueNumber(
e: LiteralValue
): e is { value: number; suffix: NumericSuffix } {
return (
typeof e === 'object' &&
'value' in e &&
typeof e.value === 'number' &&
'suffix' in e &&
typeof e.suffix === 'string'
)
}