Compare commits
9 Commits
franknoiro
...
jtran/sket
Author | SHA1 | Date | |
---|---|---|---|
6e03cf61f4 | |||
2a24a4da82 | |||
3e186fbe6b | |||
0372f35ce1 | |||
219bc4c8a3 | |||
0130d19cfb | |||
a96a5fcba8 | |||
79374a3dc0 | |||
9563fb9a5e |
@ -228,6 +228,10 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
|||||||
cmd: &ModelingCmd,
|
cmd: &ModelingCmd,
|
||||||
) -> Result<(), crate::errors::KclError> {
|
) -> Result<(), crate::errors::KclError> {
|
||||||
// In isolated mode, we don't send the command to the engine.
|
// In isolated mode, we don't send the command to the engine.
|
||||||
|
//
|
||||||
|
// Note: It's important to allow commands through for the mock engine
|
||||||
|
// because it needs the commands to build the artifact graph in sketch
|
||||||
|
// mode.
|
||||||
if self.execution_kind().await.is_isolated() {
|
if self.execution_kind().await.is_isolated() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -253,6 +257,10 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
|||||||
cmd: &ModelingCmd,
|
cmd: &ModelingCmd,
|
||||||
) -> Result<(), crate::errors::KclError> {
|
) -> Result<(), crate::errors::KclError> {
|
||||||
// In isolated mode, we don't send the command to the engine.
|
// In isolated mode, we don't send the command to the engine.
|
||||||
|
//
|
||||||
|
// Note: It's important to allow commands through for the mock engine
|
||||||
|
// because it needs the commands to build the artifact graph in sketch
|
||||||
|
// mode.
|
||||||
if self.execution_kind().await.is_isolated() {
|
if self.execution_kind().await.is_isolated() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -488,6 +488,11 @@ impl ArtifactGraph {
|
|||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.map.len()
|
self.map.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn iter(&self) -> impl Iterator<Item = (&ArtifactId, &Artifact)> {
|
||||||
|
self.map.iter()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn build_artifact_graph(
|
pub(super) fn build_artifact_graph(
|
||||||
@ -622,10 +627,7 @@ fn artifacts_to_update(
|
|||||||
let uuid = artifact_command.cmd_id;
|
let uuid = artifact_command.cmd_id;
|
||||||
let id = ArtifactId::new(uuid);
|
let id = ArtifactId::new(uuid);
|
||||||
|
|
||||||
let Some(response) = responses.get(&uuid) else {
|
let response = responses.get(&uuid);
|
||||||
// Response not found or not successful.
|
|
||||||
return Ok(Vec::new());
|
|
||||||
};
|
|
||||||
|
|
||||||
let cmd = &artifact_command.command;
|
let cmd = &artifact_command.command;
|
||||||
|
|
||||||
@ -757,7 +759,7 @@ fn artifacts_to_update(
|
|||||||
new_path.seg_ids = vec![id];
|
new_path.seg_ids = vec![id];
|
||||||
return_arr.push(Artifact::Path(new_path));
|
return_arr.push(Artifact::Path(new_path));
|
||||||
}
|
}
|
||||||
if let OkModelingCmdResponse::ClosePath(close_path) = response {
|
if let Some(OkModelingCmdResponse::ClosePath(close_path)) = response {
|
||||||
return_arr.push(Artifact::Solid2d(Solid2d {
|
return_arr.push(Artifact::Solid2d(Solid2d {
|
||||||
id: close_path.face_id.into(),
|
id: close_path.face_id.into(),
|
||||||
path_id,
|
path_id,
|
||||||
@ -800,7 +802,7 @@ fn artifacts_to_update(
|
|||||||
return Ok(return_arr);
|
return Ok(return_arr);
|
||||||
}
|
}
|
||||||
ModelingCmd::Loft(loft_cmd) => {
|
ModelingCmd::Loft(loft_cmd) => {
|
||||||
let OkModelingCmdResponse::Loft(_) = response else {
|
let Some(OkModelingCmdResponse::Loft(_)) = response else {
|
||||||
return Ok(Vec::new());
|
return Ok(Vec::new());
|
||||||
};
|
};
|
||||||
let mut return_arr = Vec::new();
|
let mut return_arr = Vec::new();
|
||||||
@ -830,7 +832,7 @@ fn artifacts_to_update(
|
|||||||
return Ok(return_arr);
|
return Ok(return_arr);
|
||||||
}
|
}
|
||||||
ModelingCmd::Solid3dGetExtrusionFaceInfo(_) => {
|
ModelingCmd::Solid3dGetExtrusionFaceInfo(_) => {
|
||||||
let OkModelingCmdResponse::Solid3dGetExtrusionFaceInfo(face_info) = response else {
|
let Some(OkModelingCmdResponse::Solid3dGetExtrusionFaceInfo(face_info)) = response else {
|
||||||
return Ok(Vec::new());
|
return Ok(Vec::new());
|
||||||
};
|
};
|
||||||
let mut return_arr = Vec::new();
|
let mut return_arr = Vec::new();
|
||||||
@ -954,6 +956,11 @@ fn artifacts_to_update(
|
|||||||
ModelingCmd::Solid3dGetOppositeEdge(_) => SweepEdgeSubType::Opposite,
|
ModelingCmd::Solid3dGetOppositeEdge(_) => SweepEdgeSubType::Opposite,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
// We need a response to continue. If we're in sketch mode doing
|
||||||
|
// mock execution, we won't have one.
|
||||||
|
if response.is_none() {
|
||||||
|
return Ok(Vec::new());
|
||||||
|
}
|
||||||
let face_id = ArtifactId::new(*face_id);
|
let face_id = ArtifactId::new(*face_id);
|
||||||
let edge_id = ArtifactId::new(*edge_id);
|
let edge_id = ArtifactId::new(*edge_id);
|
||||||
let Some(Artifact::Wall(wall)) = artifacts.get(&face_id) else {
|
let Some(Artifact::Wall(wall)) = artifacts.get(&face_id) else {
|
||||||
@ -969,7 +976,7 @@ fn artifacts_to_update(
|
|||||||
return Ok(Vec::new());
|
return Ok(Vec::new());
|
||||||
};
|
};
|
||||||
let response_edge_id = match response {
|
let response_edge_id = match response {
|
||||||
OkModelingCmdResponse::Solid3dGetNextAdjacentEdge(r) => {
|
Some(OkModelingCmdResponse::Solid3dGetNextAdjacentEdge(r)) => {
|
||||||
let Some(edge_id) = r.edge else {
|
let Some(edge_id) = r.edge else {
|
||||||
return Err(KclError::Internal(KclErrorDetails {
|
return Err(KclError::Internal(KclErrorDetails {
|
||||||
message:format!(
|
message:format!(
|
||||||
@ -980,7 +987,7 @@ fn artifacts_to_update(
|
|||||||
};
|
};
|
||||||
edge_id.into()
|
edge_id.into()
|
||||||
}
|
}
|
||||||
OkModelingCmdResponse::Solid3dGetOppositeEdge(r) => r.edge.into(),
|
Some(OkModelingCmdResponse::Solid3dGetOppositeEdge(r)) => r.edge.into(),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(KclError::Internal(KclErrorDetails {
|
return Err(KclError::Internal(KclErrorDetails {
|
||||||
message:format!(
|
message:format!(
|
||||||
|
@ -5,6 +5,7 @@ use std::sync::Arc;
|
|||||||
use itertools::{EitherOrBoth, Itertools};
|
use itertools::{EitherOrBoth, Itertools};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
|
use super::IdGenerator;
|
||||||
use crate::{
|
use crate::{
|
||||||
execution::{annotations, memory::Stack, EnvironmentRef, ExecState, ExecutorSettings},
|
execution::{annotations, memory::Stack, EnvironmentRef, ExecState, ExecutorSettings},
|
||||||
parsing::ast::types::{Annotation, Node, Program},
|
parsing::ast::types::{Annotation, Node, Program},
|
||||||
@ -14,8 +15,10 @@ use crate::{
|
|||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
/// A static mutable lock for updating the last successful execution state for the cache.
|
/// A static mutable lock for updating the last successful execution state for the cache.
|
||||||
static ref OLD_AST: Arc<RwLock<Option<OldAstState>>> = Default::default();
|
static ref OLD_AST: Arc<RwLock<Option<OldAstState>>> = Default::default();
|
||||||
// The last successful run's memory. Not cleared after an unssuccessful run.
|
// The last successful run's memory. Not cleared after an unsuccessful run.
|
||||||
static ref PREV_MEMORY: Arc<RwLock<Option<Stack>>> = Default::default();
|
static ref PREV_MEMORY: Arc<RwLock<Option<Stack>>> = Default::default();
|
||||||
|
/// The ID generator for mock execution.
|
||||||
|
static ref MOCK_ID_GENERATOR: Arc<RwLock<Option<IdGenerator>>> = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the old ast memory from the lock.
|
/// Read the old ast memory from the lock.
|
||||||
@ -49,6 +52,21 @@ pub async fn clear_mem_cache() {
|
|||||||
*old_mem = None;
|
*old_mem = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn read_mock_ids() -> Option<IdGenerator> {
|
||||||
|
let cache = MOCK_ID_GENERATOR.read().await;
|
||||||
|
cache.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) async fn write_mock_ids(id_gen: IdGenerator) {
|
||||||
|
let mut cache = MOCK_ID_GENERATOR.write().await;
|
||||||
|
*cache = Some(id_gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn clear_mock_ids() {
|
||||||
|
let mut cache = MOCK_ID_GENERATOR.write().await;
|
||||||
|
*cache = None;
|
||||||
|
}
|
||||||
|
|
||||||
/// Information for the caching an AST and smartly re-executing it if we can.
|
/// Information for the caching an AST and smartly re-executing it if we can.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct CacheInformation<'a> {
|
pub struct CacheInformation<'a> {
|
||||||
|
@ -7,7 +7,7 @@ pub use artifact::{
|
|||||||
Artifact, ArtifactCommand, ArtifactGraph, ArtifactId, CodeRef, StartSketchOnFace, StartSketchOnPlane,
|
Artifact, ArtifactCommand, ArtifactGraph, ArtifactId, CodeRef, StartSketchOnFace, StartSketchOnPlane,
|
||||||
};
|
};
|
||||||
use cache::OldAstState;
|
use cache::OldAstState;
|
||||||
pub use cache::{bust_cache, clear_mem_cache};
|
pub use cache::{bust_cache, clear_mem_cache, clear_mock_ids};
|
||||||
pub use cad_op::Operation;
|
pub use cad_op::Operation;
|
||||||
pub use geometry::*;
|
pub use geometry::*;
|
||||||
pub(crate) use import::{
|
pub(crate) use import::{
|
||||||
@ -518,7 +518,9 @@ impl ExecutorContext {
|
|||||||
) -> Result<ExecOutcome, KclErrorWithOutputs> {
|
) -> Result<ExecOutcome, KclErrorWithOutputs> {
|
||||||
assert!(self.is_mock());
|
assert!(self.is_mock());
|
||||||
|
|
||||||
let mut exec_state = ExecState::new(&self.settings);
|
let mut id_generator = cache::read_mock_ids().await.unwrap_or_default();
|
||||||
|
id_generator.next_id = 0;
|
||||||
|
let mut exec_state = ExecState::with_ids(&self.settings, id_generator);
|
||||||
if use_prev_memory {
|
if use_prev_memory {
|
||||||
match cache::read_old_memory().await {
|
match cache::read_old_memory().await {
|
||||||
Some(mem) => *exec_state.mut_stack() = mem,
|
Some(mem) => *exec_state.mut_stack() = mem,
|
||||||
@ -534,6 +536,10 @@ impl ExecutorContext {
|
|||||||
|
|
||||||
let result = self.inner_run(&program, &mut exec_state, true).await?;
|
let result = self.inner_run(&program, &mut exec_state, true).await?;
|
||||||
|
|
||||||
|
// Mock execution has its own ID generator. Save it so that multiple executions get the
|
||||||
|
// same IDs.
|
||||||
|
cache::write_mock_ids(exec_state.global.id_generator.clone()).await;
|
||||||
|
|
||||||
// Restore any temporary variables, then save any newly created variables back to
|
// Restore any temporary variables, then save any newly created variables back to
|
||||||
// memory in case another run wants to use them. Note this is just saved to the preserved
|
// memory in case another run wants to use them. Note this is just saved to the preserved
|
||||||
// memory, not to the exec_state which is not cached for mock execution.
|
// memory, not to the exec_state which is not cached for mock execution.
|
||||||
@ -1990,4 +1996,22 @@ let w = f() + f()
|
|||||||
let result = ctx2.run_mock(program2, true).await.unwrap();
|
let result = ctx2.run_mock(program2, true).await.unwrap();
|
||||||
assert_eq!(result.variables.get("z").unwrap().as_f64().unwrap(), 3.0);
|
assert_eq!(result.variables.get("z").unwrap().as_f64().unwrap(), 3.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
|
async fn mock_has_stable_ids() {
|
||||||
|
let ctx = ExecutorContext::new_mock().await;
|
||||||
|
let code = "sk = startSketchOn(XY)
|
||||||
|
|> startProfileAt([0, 0], %)";
|
||||||
|
let program = crate::Program::parse_no_errs(code).unwrap();
|
||||||
|
let result = ctx.run_mock(program, false).await.unwrap();
|
||||||
|
let ids = result.artifact_graph.iter().map(|(k, _)| *k).collect::<Vec<_>>();
|
||||||
|
assert!(!ids.is_empty(), "IDs should not be empty");
|
||||||
|
|
||||||
|
let ctx2 = ExecutorContext::new_mock().await;
|
||||||
|
let program2 = crate::Program::parse_no_errs(code).unwrap();
|
||||||
|
let result = ctx2.run_mock(program2, false).await.unwrap();
|
||||||
|
let ids2 = result.artifact_graph.iter().map(|(k, _)| *k).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
assert_eq!(ids, ids2, "Generated IDs should match");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,8 +74,12 @@ pub(super) struct ModuleState {
|
|||||||
|
|
||||||
impl ExecState {
|
impl ExecState {
|
||||||
pub fn new(exec_settings: &ExecutorSettings) -> Self {
|
pub fn new(exec_settings: &ExecutorSettings) -> Self {
|
||||||
|
Self::with_ids(exec_settings, IdGenerator::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_ids(exec_settings: &ExecutorSettings, id_generator: IdGenerator) -> Self {
|
||||||
ExecState {
|
ExecState {
|
||||||
global: GlobalState::new(exec_settings),
|
global: GlobalState::new(exec_settings, id_generator),
|
||||||
mod_local: ModuleState::new(exec_settings, None, ProgramMemory::new()),
|
mod_local: ModuleState::new(exec_settings, None, ProgramMemory::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,8 +90,7 @@ impl ExecState {
|
|||||||
// This is for the front end to keep track of the ids.
|
// This is for the front end to keep track of the ids.
|
||||||
id_generator.next_id = 0;
|
id_generator.next_id = 0;
|
||||||
|
|
||||||
let mut global = GlobalState::new(exec_settings);
|
let global = GlobalState::new(exec_settings, id_generator);
|
||||||
global.id_generator = id_generator;
|
|
||||||
|
|
||||||
*self = ExecState {
|
*self = ExecState {
|
||||||
global,
|
global,
|
||||||
@ -145,8 +148,8 @@ impl ExecState {
|
|||||||
.map(|(k, v)| (k.clone(), v.clone()))
|
.map(|(k, v)| (k.clone(), v.clone()))
|
||||||
.collect(),
|
.collect(),
|
||||||
operations: Default::default(),
|
operations: Default::default(),
|
||||||
artifact_commands: Default::default(),
|
artifact_commands: self.global.artifact_commands,
|
||||||
artifact_graph: Default::default(),
|
artifact_graph: self.global.artifact_graph,
|
||||||
errors: self.global.errors,
|
errors: self.global.errors,
|
||||||
filenames: Default::default(),
|
filenames: Default::default(),
|
||||||
}
|
}
|
||||||
@ -239,9 +242,9 @@ impl ExecState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GlobalState {
|
impl GlobalState {
|
||||||
fn new(settings: &ExecutorSettings) -> Self {
|
fn new(settings: &ExecutorSettings, id_generator: IdGenerator) -> Self {
|
||||||
let mut global = GlobalState {
|
let mut global = GlobalState {
|
||||||
id_generator: Default::default(),
|
id_generator,
|
||||||
path_to_source_id: Default::default(),
|
path_to_source_id: Default::default(),
|
||||||
module_infos: Default::default(),
|
module_infos: Default::default(),
|
||||||
artifacts: Default::default(),
|
artifacts: Default::default(),
|
||||||
|
@ -86,7 +86,8 @@ pub use errors::{
|
|||||||
CompilationError, ConnectionError, ExecError, KclError, KclErrorWithOutputs, Report, ReportWithOutputs,
|
CompilationError, ConnectionError, ExecError, KclError, KclErrorWithOutputs, Report, ReportWithOutputs,
|
||||||
};
|
};
|
||||||
pub use execution::{
|
pub use execution::{
|
||||||
bust_cache, clear_mem_cache, ExecOutcome, ExecState, ExecutorContext, ExecutorSettings, MetaSettings, Point2d,
|
bust_cache, clear_mem_cache, clear_mock_ids, ExecOutcome, ExecState, ExecutorContext, ExecutorSettings,
|
||||||
|
MetaSettings, Point2d,
|
||||||
};
|
};
|
||||||
pub use lsp::{
|
pub use lsp::{
|
||||||
copilot::Backend as CopilotLspBackend,
|
copilot::Backend as CopilotLspBackend,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
source: kcl/src/simulation_tests.rs
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
description: Artifact graph flowchart basic_fillet_cube_next_adjacent.kcl
|
description: Artifact graph flowchart basic_fillet_cube_next_adjacent.kcl
|
||||||
extension: md
|
extension: md
|
||||||
snapshot_kind: binary
|
snapshot_kind: binary
|
||||||
|
@ -24,6 +24,7 @@ flowchart LR
|
|||||||
20["SweepEdge Adjacent"]
|
20["SweepEdge Adjacent"]
|
||||||
21["SweepEdge Opposite"]
|
21["SweepEdge Opposite"]
|
||||||
22["SweepEdge Adjacent"]
|
22["SweepEdge Adjacent"]
|
||||||
|
23["EdgeCut Fillet<br>[238, 294, 0]"]
|
||||||
1 --- 2
|
1 --- 2
|
||||||
2 --- 3
|
2 --- 3
|
||||||
2 --- 4
|
2 --- 4
|
||||||
@ -57,4 +58,5 @@ flowchart LR
|
|||||||
8 --- 20
|
8 --- 20
|
||||||
8 --- 21
|
8 --- 21
|
||||||
8 --- 22
|
8 --- 22
|
||||||
|
16 <--x 23
|
||||||
```
|
```
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
source: kcl/src/simulation_tests.rs
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
description: Artifact graph flowchart basic_fillet_cube_previous_adjacent.kcl
|
description: Artifact graph flowchart basic_fillet_cube_previous_adjacent.kcl
|
||||||
extension: md
|
extension: md
|
||||||
snapshot_kind: binary
|
snapshot_kind: binary
|
||||||
|
@ -24,6 +24,7 @@ flowchart LR
|
|||||||
20["SweepEdge Adjacent"]
|
20["SweepEdge Adjacent"]
|
||||||
21["SweepEdge Opposite"]
|
21["SweepEdge Opposite"]
|
||||||
22["SweepEdge Adjacent"]
|
22["SweepEdge Adjacent"]
|
||||||
|
23["EdgeCut Fillet<br>[238, 298, 0]"]
|
||||||
1 --- 2
|
1 --- 2
|
||||||
2 --- 3
|
2 --- 3
|
||||||
2 --- 4
|
2 --- 4
|
||||||
@ -57,4 +58,5 @@ flowchart LR
|
|||||||
8 --- 20
|
8 --- 20
|
||||||
8 --- 21
|
8 --- 21
|
||||||
8 --- 22
|
8 --- 22
|
||||||
|
18 <--x 23
|
||||||
```
|
```
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
source: kcl/src/simulation_tests.rs
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
description: Artifact graph flowchart multi-axis-robot.kcl
|
description: Artifact graph flowchart multi-axis-robot.kcl
|
||||||
extension: md
|
extension: md
|
||||||
snapshot_kind: binary
|
snapshot_kind: binary
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -5,8 +5,8 @@ use std::sync::Arc;
|
|||||||
use futures::stream::TryStreamExt;
|
use futures::stream::TryStreamExt;
|
||||||
use gloo_utils::format::JsValueSerdeExt;
|
use gloo_utils::format::JsValueSerdeExt;
|
||||||
use kcl_lib::{
|
use kcl_lib::{
|
||||||
bust_cache, clear_mem_cache, exec::IdGenerator, pretty::NumericSuffix, CoreDump, EngineManager, ModuleId, Point2d,
|
bust_cache, clear_mem_cache, clear_mock_ids, exec::IdGenerator, pretty::NumericSuffix, CoreDump, EngineManager,
|
||||||
Program,
|
ModuleId, Point2d, Program,
|
||||||
};
|
};
|
||||||
use tower_lsp::{LspService, Server};
|
use tower_lsp::{LspService, Server};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
@ -20,6 +20,7 @@ pub async fn clear_scene_and_bust_cache(
|
|||||||
|
|
||||||
bust_cache().await;
|
bust_cache().await;
|
||||||
clear_mem_cache().await;
|
clear_mem_cache().await;
|
||||||
|
clear_mock_ids().await;
|
||||||
|
|
||||||
let engine = kcl_lib::wasm_engine::EngineConnection::new(engine_manager)
|
let engine = kcl_lib::wasm_engine::EngineConnection::new(engine_manager)
|
||||||
.await
|
.await
|
||||||
|
@ -476,12 +476,12 @@ export class KclManager {
|
|||||||
})
|
})
|
||||||
|
|
||||||
this._logs = logs
|
this._logs = logs
|
||||||
this._execState = execState
|
this.execState = execState
|
||||||
this._variables = execState.variables
|
|
||||||
if (!errors.length) {
|
if (!errors.length) {
|
||||||
this.lastSuccessfulVariables = execState.variables
|
this.lastSuccessfulVariables = execState.variables
|
||||||
this.lastSuccessfulOperations = execState.operations
|
this.lastSuccessfulOperations = execState.operations
|
||||||
}
|
}
|
||||||
|
this.engineCommandManager.updateArtifactGraph(execState.artifactGraph)
|
||||||
}
|
}
|
||||||
cancelAllExecutions() {
|
cancelAllExecutions() {
|
||||||
this._cancelTokens.forEach((_, key) => {
|
this._cancelTokens.forEach((_, key) => {
|
||||||
|
@ -320,17 +320,10 @@ function execStateFromRust(
|
|||||||
execOutcome: RustExecOutcome,
|
execOutcome: RustExecOutcome,
|
||||||
program: Node<Program>
|
program: Node<Program>
|
||||||
): ExecState {
|
): ExecState {
|
||||||
const artifactGraph = rustArtifactGraphToMap(execOutcome.artifactGraph)
|
const artifactGraph = artifactGraphFromRust(
|
||||||
// We haven't ported pathToNode logic to Rust yet, so we need to fill it in.
|
execOutcome.artifactGraph,
|
||||||
for (const [id, artifact] of artifactGraph) {
|
program
|
||||||
if (!artifact) continue
|
)
|
||||||
if (!('codeRef' in artifact)) continue
|
|
||||||
const pathToNode = getNodePathFromSourceRange(
|
|
||||||
program,
|
|
||||||
sourceRangeFromRust(artifact.codeRef.range)
|
|
||||||
)
|
|
||||||
artifact.codeRef.pathToNode = pathToNode
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
variables: execOutcome.variables,
|
variables: execOutcome.variables,
|
||||||
@ -342,29 +335,30 @@ function execStateFromRust(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mockExecStateFromRust(execOutcome: RustExecOutcome): ExecState {
|
|
||||||
return {
|
|
||||||
variables: execOutcome.variables,
|
|
||||||
operations: execOutcome.operations,
|
|
||||||
artifactCommands: execOutcome.artifactCommands,
|
|
||||||
artifactGraph: new Map<ArtifactId, Artifact>(),
|
|
||||||
errors: execOutcome.errors,
|
|
||||||
filenames: execOutcome.filenames,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ArtifactGraph = Map<ArtifactId, Artifact>
|
export type ArtifactGraph = Map<ArtifactId, Artifact>
|
||||||
|
|
||||||
function rustArtifactGraphToMap(
|
function artifactGraphFromRust(
|
||||||
rustArtifactGraph: RustArtifactGraph
|
rustArtifactGraph: RustArtifactGraph,
|
||||||
|
program: Node<Program>
|
||||||
): ArtifactGraph {
|
): ArtifactGraph {
|
||||||
const map = new Map<ArtifactId, Artifact>()
|
const artifactGraph = new Map<ArtifactId, Artifact>()
|
||||||
|
// Convert to a Map.
|
||||||
for (const [id, artifact] of Object.entries(rustArtifactGraph.map)) {
|
for (const [id, artifact] of Object.entries(rustArtifactGraph.map)) {
|
||||||
if (!artifact) continue
|
if (!artifact) continue
|
||||||
map.set(id, artifact)
|
artifactGraph.set(id, artifact)
|
||||||
}
|
}
|
||||||
|
|
||||||
return map
|
// We haven't ported pathToNode logic to Rust yet, so we need to fill it in.
|
||||||
|
for (const [id, artifact] of artifactGraph) {
|
||||||
|
if (!artifact) continue
|
||||||
|
if (!('codeRef' in artifact)) continue
|
||||||
|
const pathToNode = getNodePathFromSourceRange(
|
||||||
|
program,
|
||||||
|
sourceRangeFromRust(artifact.codeRef.range)
|
||||||
|
)
|
||||||
|
artifact.codeRef.pathToNode = pathToNode
|
||||||
|
}
|
||||||
|
return artifactGraph
|
||||||
}
|
}
|
||||||
|
|
||||||
export function defaultArtifactGraph(): ArtifactGraph {
|
export function defaultArtifactGraph(): ArtifactGraph {
|
||||||
@ -427,9 +421,9 @@ export const executeMock = async (
|
|||||||
usePrevMemory,
|
usePrevMemory,
|
||||||
fileSystemManager
|
fileSystemManager
|
||||||
)
|
)
|
||||||
return mockExecStateFromRust(execOutcome)
|
return execStateFromRust(execOutcome, node)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
return Promise.reject(errFromErrWithOutputs(e))
|
return Promise.reject(errFromErrWithOutputs(e, node))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,7 +448,7 @@ export const executeWithEngine = async (
|
|||||||
)
|
)
|
||||||
return execStateFromRust(execOutcome, node)
|
return execStateFromRust(execOutcome, node)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
return Promise.reject(errFromErrWithOutputs(e))
|
return Promise.reject(errFromErrWithOutputs(e, node))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,7 +465,7 @@ const jsAppSettings = async () => {
|
|||||||
return jsAppSettings
|
return jsAppSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
const errFromErrWithOutputs = (e: any): KCLError => {
|
const errFromErrWithOutputs = (e: any, program: Node<Program>): KCLError => {
|
||||||
const parsed: KclErrorWithOutputs = JSON.parse(e.toString())
|
const parsed: KclErrorWithOutputs = JSON.parse(e.toString())
|
||||||
return new KCLError(
|
return new KCLError(
|
||||||
parsed.error.kind,
|
parsed.error.kind,
|
||||||
@ -479,7 +473,7 @@ const errFromErrWithOutputs = (e: any): KCLError => {
|
|||||||
firstSourceRange(parsed.error),
|
firstSourceRange(parsed.error),
|
||||||
parsed.operations,
|
parsed.operations,
|
||||||
parsed.artifactCommands,
|
parsed.artifactCommands,
|
||||||
rustArtifactGraphToMap(parsed.artifactGraph),
|
artifactGraphFromRust(parsed.artifactGraph, program),
|
||||||
parsed.filenames
|
parsed.filenames
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user