Fix id source range mapping with path_get_info (#517)
This commit is contained in:
@ -102,7 +102,7 @@ export function useCodeEval() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const { artifactMap, sourceRangeMap } =
|
const { artifactMap, sourceRangeMap } =
|
||||||
await engineCommandManager.waitForAllCommands()
|
await engineCommandManager.waitForAllCommands(_ast, programMemory)
|
||||||
setIsExecuting(false)
|
setIsExecuting(false)
|
||||||
if (programMemory !== undefined) {
|
if (programMemory !== undefined) {
|
||||||
setProgramMemory(programMemory)
|
setProgramMemory(programMemory)
|
||||||
|
@ -48,7 +48,7 @@ export const executor = async (
|
|||||||
engineCommandManager
|
engineCommandManager
|
||||||
)
|
)
|
||||||
const { artifactMap, sourceRangeMap } =
|
const { artifactMap, sourceRangeMap } =
|
||||||
await engineCommandManager.waitForAllCommands()
|
await engineCommandManager.waitForAllCommands(node, _programMemory)
|
||||||
tempMapCallback({ artifactMap, sourceRangeMap })
|
tempMapCallback({ artifactMap, sourceRangeMap })
|
||||||
|
|
||||||
engineCommandManager.endSession()
|
engineCommandManager.endSession()
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import { SourceRange } from 'lang/executor'
|
import { ProgramMemory, SourceRange } from 'lang/executor'
|
||||||
import { Selections } from 'useStore'
|
import { Selections } from 'useStore'
|
||||||
import { VITE_KC_API_WS_MODELING_URL, VITE_KC_CONNECTION_TIMEOUT_MS } from 'env'
|
import { VITE_KC_API_WS_MODELING_URL, VITE_KC_CONNECTION_TIMEOUT_MS } from 'env'
|
||||||
import { Models } from '@kittycad/lib'
|
import { Models } from '@kittycad/lib'
|
||||||
import { exportSave } from 'lib/exportSave'
|
import { exportSave } from 'lib/exportSave'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import * as Sentry from '@sentry/react'
|
import * as Sentry from '@sentry/react'
|
||||||
|
import { getNodeFromPath, getNodePathFromSourceRange } from 'lang/queryAst'
|
||||||
|
import { Program, VariableDeclarator } from 'lang/abstractSyntaxTreeTypes'
|
||||||
|
|
||||||
let lastMessage = ''
|
let lastMessage = ''
|
||||||
|
|
||||||
@ -883,7 +885,10 @@ export class EngineCommandManager {
|
|||||||
}
|
}
|
||||||
return command.promise
|
return command.promise
|
||||||
}
|
}
|
||||||
async waitForAllCommands(): Promise<{
|
async waitForAllCommands(
|
||||||
|
ast?: Program,
|
||||||
|
programMemory?: ProgramMemory
|
||||||
|
): Promise<{
|
||||||
artifactMap: ArtifactMap
|
artifactMap: ArtifactMap
|
||||||
sourceRangeMap: SourceRangeMap
|
sourceRangeMap: SourceRangeMap
|
||||||
}> {
|
}> {
|
||||||
@ -892,9 +897,94 @@ export class EngineCommandManager {
|
|||||||
) as PendingCommand[]
|
) as PendingCommand[]
|
||||||
const proms = pendingCommands.map(({ promise }) => promise)
|
const proms = pendingCommands.map(({ promise }) => promise)
|
||||||
await Promise.all(proms)
|
await Promise.all(proms)
|
||||||
|
if (ast && programMemory) {
|
||||||
|
await this.fixIdMappings(ast, programMemory)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
artifactMap: this.artifactMap,
|
artifactMap: this.artifactMap,
|
||||||
sourceRangeMap: this.sourceRangeMap,
|
sourceRangeMap: this.sourceRangeMap,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private async fixIdMappings(ast: Program, programMemory: ProgramMemory) {
|
||||||
|
/* This is a temporary solution since the cmd_ids that are sent through when
|
||||||
|
sending 'extend_path' ids are not used as the segment ids.
|
||||||
|
|
||||||
|
We have a way to back fill them with 'path_get_info', however this relies on one
|
||||||
|
the sketchGroup array and the segements array returned from the server to be in
|
||||||
|
the same length and order. plus it's super hacky, we first use the path_id to get
|
||||||
|
the source range of the pipe expression then use the name of the variable to get
|
||||||
|
the sketchGroup from programMemory.
|
||||||
|
|
||||||
|
I feel queezy about relying on all these steps to always line up.
|
||||||
|
We have also had to pollute this EngineCommandManager class with knowledge of both the ast and programMemory
|
||||||
|
We should get the cmd_ids to match with the segment ids and delete this method.
|
||||||
|
*/
|
||||||
|
const pathInfoProms = []
|
||||||
|
for (const [id, artifact] of Object.entries(this.artifactMap)) {
|
||||||
|
if (artifact.commandType === 'start_path') {
|
||||||
|
pathInfoProms.push(
|
||||||
|
this.sendSceneCommand({
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
cmd: {
|
||||||
|
type: 'path_get_info',
|
||||||
|
path_id: id,
|
||||||
|
},
|
||||||
|
}).then(({ data }) => ({
|
||||||
|
originalId: id,
|
||||||
|
segments: data?.data?.segments,
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathInfos = await Promise.all(pathInfoProms)
|
||||||
|
pathInfos.forEach(({ originalId, segments }) => {
|
||||||
|
const originalArtifact = this.artifactMap[originalId]
|
||||||
|
if (!originalArtifact || originalArtifact.type === 'pending') {
|
||||||
|
console.log('problem')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const pipeExpPath = getNodePathFromSourceRange(
|
||||||
|
ast,
|
||||||
|
originalArtifact.range
|
||||||
|
)
|
||||||
|
const pipeExp = getNodeFromPath<VariableDeclarator>(
|
||||||
|
ast,
|
||||||
|
pipeExpPath,
|
||||||
|
'VariableDeclarator'
|
||||||
|
).node
|
||||||
|
if (pipeExp.type !== 'VariableDeclarator') {
|
||||||
|
console.log('problem', pipeExp, pipeExpPath, ast)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const variableName = pipeExp.id.name
|
||||||
|
const memoryItem = programMemory.root[variableName]
|
||||||
|
if (!memoryItem) {
|
||||||
|
console.log('problem', variableName, programMemory)
|
||||||
|
return
|
||||||
|
} else if (memoryItem.type !== 'SketchGroup') {
|
||||||
|
console.log('problem', memoryItem, programMemory)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const relevantSegments = segments.filter(
|
||||||
|
({ command_id }: { command_id: string | null }) => command_id
|
||||||
|
)
|
||||||
|
if (memoryItem.value.length !== relevantSegments.length) {
|
||||||
|
console.log('problem', memoryItem.value, relevantSegments)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for (let i = 0; i < relevantSegments.length; i++) {
|
||||||
|
const engineSegment = relevantSegments[i]
|
||||||
|
const memorySegment = memoryItem.value[i]
|
||||||
|
const oldId = memorySegment.__geoMeta.id
|
||||||
|
const artifact = this.artifactMap[oldId]
|
||||||
|
delete this.artifactMap[oldId]
|
||||||
|
delete this.sourceRangeMap[oldId]
|
||||||
|
this.artifactMap[engineSegment.command_id] = artifact
|
||||||
|
this.sourceRangeMap[engineSegment.command_id] = artifact.range
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,6 @@ export async function executor(
|
|||||||
await engineCommandManager.waitForReady
|
await engineCommandManager.waitForReady
|
||||||
engineCommandManager.startNewSession()
|
engineCommandManager.startNewSession()
|
||||||
const programMemory = await _executor(ast, pm, engineCommandManager)
|
const programMemory = await _executor(ast, pm, engineCommandManager)
|
||||||
await engineCommandManager.waitForAllCommands()
|
await engineCommandManager.waitForAllCommands(ast, programMemory)
|
||||||
return programMemory
|
return programMemory
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user