few more tweaks and a failing js test
This commit is contained in:
@ -1,8 +1,14 @@
|
||||
import fs from 'node:fs'
|
||||
|
||||
import { parse, ProgramMemory, SketchGroup, initPromise } from './wasm'
|
||||
import { enginelessExecutor } from '../lib/testHelpers'
|
||||
import { parse, ProgramMemory, SketchGroup, initPromise, Program } from './wasm'
|
||||
import {
|
||||
MockEngineCommandManager,
|
||||
enginelessExecutor,
|
||||
} from '../lib/testHelpers'
|
||||
import { KCLError } from './errors'
|
||||
import { executeAst } from './langHelpers'
|
||||
import { EngineCommandManager } from './std/engineConnection'
|
||||
import { getNodePathFromSourceRange } from './queryAst'
|
||||
|
||||
beforeAll(async () => {
|
||||
await initPromise
|
||||
@ -108,32 +114,6 @@ const newVar = myVar + 1`
|
||||
expect(root.myVar.value).toBe(7)
|
||||
})
|
||||
|
||||
// Enable rotations #152
|
||||
// it('rotated sketch', async () => {
|
||||
// const code = [
|
||||
// 'const mySk1 = startSketchAt([0,0])',
|
||||
// ' |> lineTo([1,1], %)',
|
||||
// ' |> lineTo([0, 1], %, "myPath")',
|
||||
// ' |> lineTo([1, 1], %)',
|
||||
// 'const rotated = rx(90, mySk1)',
|
||||
// ].join('\n')
|
||||
// const { root } = await exe(code)
|
||||
// expect(root.mySk1.value).toHaveLength(3)
|
||||
// expect(root?.rotated?.type).toBe('SketchGroup')
|
||||
// if (
|
||||
// root?.mySk1?.type !== 'SketchGroup' ||
|
||||
// root?.rotated?.type !== 'SketchGroup'
|
||||
// )
|
||||
// throw new Error('not a sketch group')
|
||||
// expect(root.mySk1.rotation).toEqual([0, 0, 0, 1])
|
||||
// expect(root.rotated.rotation.map((a) => a.toFixed(4))).toEqual([
|
||||
// '0.7071',
|
||||
// '0.0000',
|
||||
// '0.0000',
|
||||
// '0.7071',
|
||||
// ])
|
||||
// })
|
||||
|
||||
it('execute pipe sketch into call expression', async () => {
|
||||
// Enable rotations #152
|
||||
const code = [
|
||||
@ -417,6 +397,75 @@ const theExtrude = startSketchOn('XY')
|
||||
})
|
||||
})
|
||||
|
||||
describe('trying pathToNodeStuff', () => {
|
||||
it('source range should agree with path to node', async () => {
|
||||
const code = `const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([7.72, 4.13], %)
|
||||
|> line([7.11, 3.48], %)
|
||||
|> line([-3.29, -13.86], %)
|
||||
|> close(%)
|
||||
const sketch002 = startSketchOn('XY')
|
||||
|> startProfileAt([8.57, 5.92], %)
|
||||
|> line([13.28, 4], %)`
|
||||
const manager = new MockEngineCommandManager({
|
||||
setIsStreamReady: () => {},
|
||||
setMediaStream: () => {},
|
||||
}) as any as EngineCommandManager
|
||||
const ast = parse(code) as Program
|
||||
const yo = await executeAst({
|
||||
ast,
|
||||
engineCommandManager: manager,
|
||||
useFakeExecutor: true,
|
||||
})
|
||||
const sketch001 = yo.programMemory.root.sketch001 as SketchGroup
|
||||
let derivedPaths: [any, any, any][] = sketch001.value.map(
|
||||
({ __geoMeta }) => {
|
||||
return [
|
||||
getNodePathFromSourceRange(ast, __geoMeta.sourceRange).map((a) => [
|
||||
String(a[0]),
|
||||
a[1],
|
||||
]),
|
||||
__geoMeta.pathToNode,
|
||||
__geoMeta.sourceRange,
|
||||
]
|
||||
}
|
||||
)
|
||||
let snippets = [
|
||||
'line([7.11, 3.48], %)',
|
||||
'line([-3.29, -13.86], %)',
|
||||
'close(%)',
|
||||
]
|
||||
for (const [
|
||||
index,
|
||||
[sourcePath, wasmPath, range],
|
||||
] of derivedPaths.entries()) {
|
||||
expect(sourcePath).toEqual(wasmPath)
|
||||
const codeSlice = code.slice(range[0], range[1])
|
||||
expect(snippets[index]).toBe(codeSlice)
|
||||
}
|
||||
const sketch002 = yo.programMemory.root.sketch002 as SketchGroup
|
||||
derivedPaths = sketch002.value.map(({ __geoMeta }) => {
|
||||
return [
|
||||
getNodePathFromSourceRange(ast, __geoMeta.sourceRange).map((a) => [
|
||||
String(a[0]),
|
||||
a[1],
|
||||
]),
|
||||
__geoMeta.pathToNode,
|
||||
__geoMeta.sourceRange,
|
||||
]
|
||||
})
|
||||
snippets = ['line([13.28, 4], %)']
|
||||
for (const [
|
||||
index,
|
||||
[sourcePath, wasmPath, range],
|
||||
] of derivedPaths.entries()) {
|
||||
expect(sourcePath).toEqual(wasmPath)
|
||||
const codeSlice = code.slice(range[0], range[1])
|
||||
expect(snippets[index]).toBe(codeSlice)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// helpers
|
||||
|
||||
async function exe(
|
||||
|
||||
@ -5,7 +5,6 @@ import {
|
||||
programMemoryInit,
|
||||
kclLint,
|
||||
} from 'lang/wasm'
|
||||
import { enginelessExecutor } from 'lib/testHelpers'
|
||||
import { EngineCommandManager } from 'lang/std/engineConnection'
|
||||
import { KCLError } from 'lang/errors'
|
||||
import { Diagnostic } from '@codemirror/lint'
|
||||
@ -65,7 +64,7 @@ export async function executeAst({
|
||||
engineCommandManager.startNewSession()
|
||||
}
|
||||
const programMemory = await (useFakeExecutor
|
||||
? enginelessExecutor(ast, programMemoryOverride || programMemoryInit())
|
||||
? _executor(ast, programMemoryInit(), engineCommandManager, true)
|
||||
: _executor(ast, programMemoryInit(), engineCommandManager, false))
|
||||
|
||||
await engineCommandManager.waitForAllCommands()
|
||||
|
||||
@ -1809,7 +1809,7 @@ export class EngineCommandManager extends EventTarget {
|
||||
range: SourceRange
|
||||
command: EngineCommand
|
||||
ast: Program
|
||||
idToRangeMap?: { [key: string]: SourceRange }
|
||||
idToRangeMap?: { [key: string]: [SourceRange, PathToNode] }
|
||||
}): Promise<ResolveCommand | void> {
|
||||
if (this.engineConnection === undefined) {
|
||||
return Promise.resolve()
|
||||
@ -1878,7 +1878,8 @@ export class EngineCommandManager extends EventTarget {
|
||||
id: string,
|
||||
command: Models['ModelingCmd_type'],
|
||||
ast?: Program,
|
||||
range?: SourceRange
|
||||
range?: SourceRange,
|
||||
_pathToNode?: PathToNode
|
||||
): Promise<ResolveCommand | void> {
|
||||
let resolve: (val: any) => void = () => {}
|
||||
const promise: Promise<ResolveCommand | void> = new Promise(
|
||||
@ -1899,7 +1900,9 @@ export class EngineCommandManager extends EventTarget {
|
||||
if (command.type === 'extrude') return command.target
|
||||
// handle other commands that have a parent here
|
||||
}
|
||||
const pathToNode = ast
|
||||
const pathToNode = _pathToNode
|
||||
? _pathToNode
|
||||
: ast
|
||||
? getNodePathFromSourceRange(ast, range || [0, 0])
|
||||
: []
|
||||
this.artifactMap[id] = {
|
||||
@ -1945,7 +1948,7 @@ export class EngineCommandManager extends EventTarget {
|
||||
async handlePendingBatchCommand(
|
||||
id: string,
|
||||
commands: Models['ModelingCmdReq_type'][],
|
||||
idToRangeMap?: { [key: string]: SourceRange },
|
||||
idToRangeMap?: { [key: string]: [SourceRange, PathToNode] },
|
||||
ast?: Program,
|
||||
range?: SourceRange
|
||||
): Promise<ResolveCommand | void> {
|
||||
@ -1978,7 +1981,12 @@ export class EngineCommandManager extends EventTarget {
|
||||
|
||||
Promise.all(
|
||||
commands.map((c) =>
|
||||
this.handlePendingCommand(c.cmd_id, c.cmd, ast, idToRangeMap[c.cmd_id])
|
||||
this.handlePendingCommand(
|
||||
c.cmd_id,
|
||||
c.cmd,
|
||||
ast,
|
||||
...idToRangeMap[c.cmd_id]
|
||||
)
|
||||
)
|
||||
)
|
||||
return promise
|
||||
@ -1990,11 +1998,6 @@ export class EngineCommandManager extends EventTarget {
|
||||
commandStr: string,
|
||||
idToRangeStr: string
|
||||
): Promise<string | void> {
|
||||
// console.log('yoo', id,
|
||||
// rangeStr,
|
||||
// pathToNodeStr,
|
||||
// commandStr,
|
||||
// idToRangeStr)
|
||||
console.log(
|
||||
'pathToNodeStr',
|
||||
pathToNodeStr,
|
||||
@ -2017,7 +2020,7 @@ export class EngineCommandManager extends EventTarget {
|
||||
return Promise.reject(new Error('commandStr is undefined'))
|
||||
}
|
||||
const range: SourceRange = JSON.parse(rangeStr)
|
||||
const idToRangeMap: { [key: string]: SourceRange } =
|
||||
const idToRangeMap: { [key: string]: [SourceRange, PathToNode] } =
|
||||
JSON.parse(idToRangeStr)
|
||||
|
||||
const command: EngineCommand = JSON.parse(commandStr)
|
||||
|
||||
@ -19,7 +19,7 @@ const defaultPlanes: DefaultPlanes = {
|
||||
negYz: uuidv4(),
|
||||
}
|
||||
|
||||
class MockEngineCommandManager {
|
||||
export class MockEngineCommandManager {
|
||||
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
||||
constructor(mockParams: {
|
||||
setIsStreamReady: (isReady: boolean) => void
|
||||
@ -37,6 +37,7 @@ class MockEngineCommandManager {
|
||||
range: SourceRange
|
||||
command: EngineCommand
|
||||
}): Promise<any> {
|
||||
console.log('YOYOYOYOY!!!!!!')
|
||||
const response: WebSocketResponse = {
|
||||
success: true,
|
||||
resp: {
|
||||
@ -51,11 +52,18 @@ class MockEngineCommandManager {
|
||||
async wasmGetDefaultPlanes(): Promise<string> {
|
||||
return JSON.stringify(defaultPlanes)
|
||||
}
|
||||
sendModelingCommandFromWasm(
|
||||
yo: any[] = []
|
||||
async sendModelingCommandFromWasm(
|
||||
id: string,
|
||||
rangeStr: string,
|
||||
commandStr: string
|
||||
pathToNodeStr: string,
|
||||
commandStr: string,
|
||||
idToRangeStr: string
|
||||
): Promise<any> {
|
||||
console.log('YOYOYOYOYO<')
|
||||
if (idToRangeStr) {
|
||||
this.yo.push(idToRangeStr)
|
||||
}
|
||||
if (id === undefined) {
|
||||
return Promise.reject(new Error('id is undefined'))
|
||||
}
|
||||
@ -71,6 +79,7 @@ class MockEngineCommandManager {
|
||||
return this.sendModelingCommand({ id, range, command })
|
||||
}
|
||||
sendSceneCommand() {}
|
||||
clearDefaultPlanes() {}
|
||||
}
|
||||
|
||||
export async function enginelessExecutor(
|
||||
@ -88,6 +97,7 @@ export async function enginelessExecutor(
|
||||
mockEngineCommandManager.startNewSession()
|
||||
const programMemory = await _executor(ast, pm, mockEngineCommandManager, true)
|
||||
await mockEngineCommandManager.waitForAllCommands()
|
||||
console.log('hey', (mockEngineCommandManager as any).yo)
|
||||
return programMemory
|
||||
}
|
||||
|
||||
|
||||
@ -3278,7 +3278,10 @@ impl PipeExpression {
|
||||
pipe_info: &PipeInfo,
|
||||
ctx: &ExecutorContext,
|
||||
) -> Result<MemoryItem, KclError> {
|
||||
execute_pipe_body(memory, &self.body, pipe_info, self.into(), ctx).await
|
||||
memory.path_to_node.push(("body".to_string(), "PipeExpression".to_string()));
|
||||
let result = execute_pipe_body(memory, &self.body, pipe_info, self.into(), ctx).await;
|
||||
// memory.path_to_node.pop();
|
||||
result
|
||||
}
|
||||
|
||||
/// Rename all identifiers that have the old name to the new given name.
|
||||
@ -3321,13 +3324,16 @@ async fn execute_pipe_body(
|
||||
let mut new_pipe_info = PipeInfo::new();
|
||||
new_pipe_info.previous_results = Some(output);
|
||||
// Evaluate remaining elements.
|
||||
for expression in body {
|
||||
for (indexYo, expression) in body.enumerate() {
|
||||
let mut _memory = memory.clone();
|
||||
_memory.path_to_node.push(((indexYo+1).to_string(), "index".to_string()));
|
||||
|
||||
let output = match expression {
|
||||
Value::BinaryExpression(binary_expression) => {
|
||||
binary_expression.get_result(memory, &new_pipe_info, ctx).await?
|
||||
binary_expression.get_result(&mut _memory, &new_pipe_info, ctx).await?
|
||||
}
|
||||
Value::CallExpression(call_expression) => call_expression.execute(memory, &new_pipe_info, ctx).await?,
|
||||
Value::Identifier(identifier) => memory.get(&identifier.name, identifier.into())?.clone(),
|
||||
Value::CallExpression(call_expression) => call_expression.execute(&mut _memory, &new_pipe_info, ctx).await?,
|
||||
Value::Identifier(identifier) => _memory.get(&identifier.name, identifier.into())?.clone(),
|
||||
_ => {
|
||||
// Return an error this should not happen.
|
||||
return Err(KclError::Semantic(KclErrorDetails {
|
||||
@ -3337,6 +3343,7 @@ async fn execute_pipe_body(
|
||||
}
|
||||
};
|
||||
new_pipe_info.previous_results = Some(output);
|
||||
// memory.path_to_node.pop();
|
||||
}
|
||||
// Safe to unwrap here, because `newpipe_info` always has something pushed in when the `match first` executes.
|
||||
let final_output = new_pipe_info.previous_results.unwrap();
|
||||
|
||||
@ -1628,6 +1628,7 @@ impl ExecutorContext {
|
||||
memory.path_to_node.push(("declarations".to_string(), "VariableDeclaration".to_string()));
|
||||
for (index, declaration) in variable_declaration.declarations.iter().enumerate() {
|
||||
memory.path_to_node.push((index.to_string(), "index".to_string()));
|
||||
memory.path_to_node.push(("init".to_string(), "".to_string()));
|
||||
let var_name = declaration.id.name.to_string();
|
||||
let source_range: SourceRange = declaration.init.clone().into();
|
||||
let metadata = Metadata { source_range, path_to_node: Some(memory.path_to_node.clone())};
|
||||
@ -1643,6 +1644,7 @@ impl ExecutorContext {
|
||||
.await?;
|
||||
memory.add(&var_name, memory_item, source_range)?;
|
||||
// _memory.path_to_node.pop();
|
||||
// _memory.path_to_node.pop();
|
||||
}
|
||||
// _memory.path_to_node.pop();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user