diff --git a/docs/kcl-std/std.json b/docs/kcl-std/std.json index be8d3fc15..bfbc78b38 100644 --- a/docs/kcl-std/std.json +++ b/docs/kcl-std/std.json @@ -126685,7 +126685,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -126693,6 +126694,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -128804,6 +128808,9 @@ } } }, + "FunctionSource": { + "type": "null" + }, "ModuleId": { "description": "Identifier of a source file. Uses a u32 to keep the size small.", "type": "integer", @@ -129165,7 +129172,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -129173,6 +129181,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -131284,6 +131295,9 @@ } } }, + "FunctionSource": { + "type": "null" + }, "ModuleId": { "description": "Identifier of a source file. Uses a u32 to keep the size small.", "type": "integer", @@ -131649,7 +131663,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -131657,6 +131672,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -133768,6 +133786,9 @@ } } }, + "FunctionSource": { + "type": "null" + }, "ModuleId": { "description": "Identifier of a source file. Uses a u32 to keep the size small.", "type": "integer", @@ -203436,7 +203457,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -203444,6 +203466,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -205555,6 +205580,9 @@ } } }, + "FunctionSource": { + "type": "null" + }, "ModuleId": { "description": "Identifier of a source file. Uses a u32 to keep the size small.", "type": "integer", @@ -205914,7 +205942,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -205922,6 +205951,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -206708,7 +206740,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -206716,6 +206749,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -208419,6 +208455,9 @@ } } }, + "FunctionSource": { + "type": "null" + }, "ModuleId": { "description": "Identifier of a source file. Uses a u32 to keep the size small.", "type": "integer", @@ -213896,7 +213935,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -213904,6 +213944,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -216015,6 +216058,9 @@ } } }, + "FunctionSource": { + "type": "null" + }, "ModuleId": { "description": "Identifier of a source file. Uses a u32 to keep the size small.", "type": "integer", @@ -216373,7 +216419,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -216381,6 +216428,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -216759,7 +216809,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -216767,6 +216818,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -218878,6 +218932,9 @@ } } }, + "FunctionSource": { + "type": "null" + }, "ModuleId": { "description": "Identifier of a source file. Uses a u32 to keep the size small.", "type": "integer", @@ -219237,7 +219294,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -219245,6 +219303,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -220031,7 +220092,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -220039,6 +220101,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -221742,6 +221807,9 @@ } } }, + "FunctionSource": { + "type": "null" + }, "ModuleId": { "description": "Identifier of a source file. Uses a u32 to keep the size small.", "type": "integer", @@ -222123,7 +222191,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -222131,6 +222200,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -224242,6 +224314,9 @@ } } }, + "FunctionSource": { + "type": "null" + }, "ModuleId": { "description": "Identifier of a source file. Uses a u32 to keep the size small.", "type": "integer", @@ -224600,7 +224675,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -224608,6 +224684,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -224986,7 +225065,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -224994,6 +225074,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -227105,6 +227188,9 @@ } } }, + "FunctionSource": { + "type": "null" + }, "ModuleId": { "description": "Identifier of a source file. Uses a u32 to keep the size small.", "type": "integer", @@ -227466,7 +227552,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -227474,6 +227561,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -229585,6 +229675,9 @@ } } }, + "FunctionSource": { + "type": "null" + }, "ModuleId": { "description": "Identifier of a source file. Uses a u32 to keep the size small.", "type": "integer", @@ -229944,7 +230037,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -229952,6 +230046,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -230738,7 +230835,8 @@ { "type": "object", "required": [ - "type" + "type", + "value" ], "properties": { "type": { @@ -230746,6 +230844,9 @@ "enum": [ "Function" ] + }, + "value": { + "$ref": "#/components/schemas/FunctionSource" } } }, @@ -232449,6 +232550,9 @@ } } }, + "FunctionSource": { + "type": "null" + }, "ModuleId": { "description": "Identifier of a source file. Uses a u32 to keep the size small.", "type": "integer", diff --git a/e2e/playwright/regression-tests.spec.ts b/e2e/playwright/regression-tests.spec.ts index d60a0d6b9..c7835fcf4 100644 --- a/e2e/playwright/regression-tests.spec.ts +++ b/e2e/playwright/regression-tests.spec.ts @@ -170,7 +170,9 @@ extrude001 = extrude(sketch001, length = 50) await variablesTabButton.click() // expect to see "myVar:5" await expect( - page.locator('.pretty-json-container >> text=myVar:5') + // There's a double quote before the number value since the units are + // formatted into a string. + page.locator('.pretty-json-container >> text=myVar:"5') ).toBeVisible() // change 5 to 67 @@ -180,7 +182,7 @@ extrude001 = extrude(sketch001, length = 50) await page.keyboard.type('67') await expect( - page.locator('.pretty-json-container >> text=myVar:67') + page.locator('.pretty-json-container >> text=myVar:"67') ).toBeVisible() }) test('ProgramMemory can be serialised', async ({ page, homePage }) => { diff --git a/rust/kcl-lib/src/execution/kcl_value.rs b/rust/kcl-lib/src/execution/kcl_value.rs index cb388210e..c7f275fec 100644 --- a/rust/kcl-lib/src/execution/kcl_value.rs +++ b/rust/kcl-lib/src/execution/kcl_value.rs @@ -83,9 +83,9 @@ pub enum KclValue { value: Box, }, ImportedGeometry(ImportedGeometry), - #[ts(skip)] Function { - #[serde(skip)] + #[serde(serialize_with = "function_value_stub")] + #[ts(type = "null")] value: FunctionSource, #[serde(skip)] meta: Vec, @@ -109,6 +109,13 @@ pub enum KclValue { }, } +fn function_value_stub(_value: &FunctionSource, serializer: S) -> Result +where + S: serde::Serializer, +{ + serializer.serialize_unit() +} + #[derive(Debug, Clone, PartialEq, Default)] pub enum FunctionSource { #[default] diff --git a/rust/kcl-lib/src/execution/types.rs b/rust/kcl-lib/src/execution/types.rs index c49719531..0485e992e 100644 --- a/rust/kcl-lib/src/execution/types.rs +++ b/rust/kcl-lib/src/execution/types.rs @@ -399,7 +399,7 @@ impl fmt::Display for PrimitiveType { } } -#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, ts_rs::TS, JsonSchema)] #[ts(export)] #[serde(tag = "type")] pub enum NumericType { diff --git a/rust/kcl-lib/src/fmt.rs b/rust/kcl-lib/src/fmt.rs new file mode 100644 index 000000000..a7a20fa20 --- /dev/null +++ b/rust/kcl-lib/src/fmt.rs @@ -0,0 +1,137 @@ +use serde::Serialize; + +use crate::{execution::types::NumericType, pretty::NumericSuffix}; + +/// For the UI, display a number and its type for debugging purposes. This is +/// used by TS. +pub fn human_display_number(value: f64, ty: NumericType) -> String { + match ty { + NumericType::Known(unit_type) => format!("{value}: number({unit_type})"), + NumericType::Default { len, angle } => format!("{value} (no units, defaulting to {len} or {angle})"), + NumericType::Unknown => format!("{value} (number with unknown units)"), + NumericType::Any => format!("{value} (number with any units)"), + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, thiserror::Error)] +#[serde(tag = "type")] +pub enum FormatNumericSuffixError { + #[error("Invalid numeric suffix: {0}")] + Invalid(NumericSuffix), +} + +/// For UI code generation, format a number with a suffix. The result must parse +/// as a literal. If it can't be done, returns an error. +/// +/// This is used by TS. +pub fn format_number_literal(value: f64, suffix: NumericSuffix) -> Result { + match suffix { + // There isn't a syntactic suffix for these. For unknown, we don't want + // to ever generate the unknown suffix. We currently warn on it, and we + // may remove it in the future. + NumericSuffix::Length | NumericSuffix::Angle | NumericSuffix::Unknown => { + Err(FormatNumericSuffixError::Invalid(suffix)) + } + NumericSuffix::None + | NumericSuffix::Count + | NumericSuffix::Mm + | NumericSuffix::Cm + | NumericSuffix::M + | NumericSuffix::Inch + | NumericSuffix::Ft + | NumericSuffix::Yd + | NumericSuffix::Deg + | NumericSuffix::Rad => Ok(format!("{value}{suffix}")), + } +} + +#[cfg(test)] +mod tests { + use pretty_assertions::assert_eq; + + use super::*; + use crate::execution::types::{UnitAngle, UnitLen, UnitType}; + + #[test] + fn test_human_display_number() { + assert_eq!( + human_display_number(1.0, NumericType::Known(UnitType::Count)), + "1: number(Count)" + ); + assert_eq!( + human_display_number(1.0, NumericType::Known(UnitType::Length(UnitLen::M))), + "1: number(m)" + ); + assert_eq!( + human_display_number(1.0, NumericType::Known(UnitType::Length(UnitLen::Mm))), + "1: number(mm)" + ); + assert_eq!( + human_display_number(1.0, NumericType::Known(UnitType::Length(UnitLen::Inches))), + "1: number(in)" + ); + assert_eq!( + human_display_number(1.0, NumericType::Known(UnitType::Length(UnitLen::Feet))), + "1: number(ft)" + ); + assert_eq!( + human_display_number(1.0, NumericType::Known(UnitType::Angle(UnitAngle::Degrees))), + "1: number(deg)" + ); + assert_eq!( + human_display_number(1.0, NumericType::Known(UnitType::Angle(UnitAngle::Radians))), + "1: number(rad)" + ); + assert_eq!( + human_display_number( + 1.0, + NumericType::Default { + len: UnitLen::Mm, + angle: UnitAngle::Degrees, + } + ), + "1 (no units, defaulting to mm or deg)" + ); + assert_eq!( + human_display_number( + 1.0, + NumericType::Default { + len: UnitLen::Feet, + angle: UnitAngle::Radians, + } + ), + "1 (no units, defaulting to ft or rad)" + ); + assert_eq!( + human_display_number(1.0, NumericType::Unknown), + "1 (number with unknown units)" + ); + assert_eq!(human_display_number(1.0, NumericType::Any), "1 (number with any units)"); + } + + #[test] + fn test_format_number_literal() { + assert_eq!( + format_number_literal(1.0, NumericSuffix::Length), + Err(FormatNumericSuffixError::Invalid(NumericSuffix::Length)) + ); + assert_eq!( + format_number_literal(1.0, NumericSuffix::Angle), + Err(FormatNumericSuffixError::Invalid(NumericSuffix::Angle)) + ); + assert_eq!(format_number_literal(1.0, NumericSuffix::None), Ok("1".to_owned())); + assert_eq!(format_number_literal(1.0, NumericSuffix::Count), Ok("1_".to_owned())); + assert_eq!(format_number_literal(1.0, NumericSuffix::Mm), Ok("1mm".to_owned())); + assert_eq!(format_number_literal(1.0, NumericSuffix::Cm), Ok("1cm".to_owned())); + assert_eq!(format_number_literal(1.0, NumericSuffix::M), Ok("1m".to_owned())); + assert_eq!(format_number_literal(1.0, NumericSuffix::Inch), Ok("1in".to_owned())); + assert_eq!(format_number_literal(1.0, NumericSuffix::Ft), Ok("1ft".to_owned())); + assert_eq!(format_number_literal(1.0, NumericSuffix::Yd), Ok("1yd".to_owned())); + assert_eq!(format_number_literal(1.0, NumericSuffix::Deg), Ok("1deg".to_owned())); + assert_eq!(format_number_literal(1.0, NumericSuffix::Rad), Ok("1rad".to_owned())); + assert_eq!( + format_number_literal(1.0, NumericSuffix::Unknown), + Err(FormatNumericSuffixError::Invalid(NumericSuffix::Unknown)) + ); + } +} diff --git a/rust/kcl-lib/src/lib.rs b/rust/kcl-lib/src/lib.rs index 4415cb05d..7e0948178 100644 --- a/rust/kcl-lib/src/lib.rs +++ b/rust/kcl-lib/src/lib.rs @@ -61,6 +61,7 @@ mod docs; mod engine; mod errors; mod execution; +mod fmt; mod fs; pub mod lint; mod log; @@ -108,7 +109,10 @@ pub use unparser::{recast_dir, walk_dir}; pub mod exec { #[cfg(feature = "artifact-graph")] pub use crate::execution::ArtifactCommand; - pub use crate::execution::{DefaultPlanes, IdGenerator, KclValue, PlaneType, Sketch}; + pub use crate::execution::{ + types::{NumericType, UnitAngle, UnitLen, UnitType}, + DefaultPlanes, IdGenerator, KclValue, PlaneType, Sketch, + }; } #[cfg(target_arch = "wasm32")] @@ -134,7 +138,10 @@ pub mod std_utils { } pub mod pretty { - pub use crate::{parsing::token::NumericSuffix, unparser::format_number}; + pub use crate::{ + fmt::{format_number_literal, human_display_number}, + parsing::token::NumericSuffix, + }; } #[cfg(feature = "cli")] diff --git a/rust/kcl-lib/src/unparser.rs b/rust/kcl-lib/src/unparser.rs index 776ba4767..0d8197326 100644 --- a/rust/kcl-lib/src/unparser.rs +++ b/rust/kcl-lib/src/unparser.rs @@ -8,9 +8,7 @@ use crate::parsing::{ MemberExpression, MemberObject, Node, NonCodeNode, NonCodeValue, ObjectExpression, Parameter, PipeExpression, Program, TagDeclarator, TypeDeclaration, UnaryExpression, VariableDeclaration, VariableKind, }, - deprecation, - token::NumericSuffix, - DeprecationKind, PIPE_OPERATOR, + deprecation, DeprecationKind, PIPE_OPERATOR, }; impl Program { @@ -465,11 +463,6 @@ impl TypeDeclaration { } } -// Used by TS. -pub fn format_number(value: f64, suffix: NumericSuffix) -> String { - format!("{value}{suffix}") -} - impl Literal { fn recast(&self) -> String { match self.value { diff --git a/rust/kcl-lib/tests/add_lots/program_memory.snap b/rust/kcl-lib/tests/add_lots/program_memory.snap index 5de5bb1ed..dc0ae3f7b 100644 --- a/rust/kcl-lib/tests/add_lots/program_memory.snap +++ b/rust/kcl-lib/tests/add_lots/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing add_lots.kcl --- { "f": { - "type": "Function" + "type": "Function", + "value": null }, "x": { "type": "Number", diff --git a/rust/kcl-lib/tests/cube/program_memory.snap b/rust/kcl-lib/tests/cube/program_memory.snap index c58fc1b7b..55c3391a7 100644 --- a/rust/kcl-lib/tests/cube/program_memory.snap +++ b/rust/kcl-lib/tests/cube/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing cube.kcl --- { "cube": { - "type": "Function" + "type": "Function", + "value": null }, "myCube": { "type": "Solid", diff --git a/rust/kcl-lib/tests/double_map_fn/program_memory.snap b/rust/kcl-lib/tests/double_map_fn/program_memory.snap index 50403fd91..7299c9c27 100644 --- a/rust/kcl-lib/tests/double_map_fn/program_memory.snap +++ b/rust/kcl-lib/tests/double_map_fn/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing double_map_fn.kcl --- { "increment": { - "type": "Function" + "type": "Function", + "value": null }, "xs": { "type": "MixedArray", diff --git a/rust/kcl-lib/tests/fillet-and-shell/program_memory.snap b/rust/kcl-lib/tests/fillet-and-shell/program_memory.snap index 91395f3bf..bfbe2d604 100644 --- a/rust/kcl-lib/tests/fillet-and-shell/program_memory.snap +++ b/rust/kcl-lib/tests/fillet-and-shell/program_memory.snap @@ -435,7 +435,8 @@ description: Variables in memory after executing fillet-and-shell.kcl } }, "m25Screw": { - "type": "Function" + "type": "Function", + "value": null }, "microUsb1Distance": { "type": "Number", diff --git a/rust/kcl-lib/tests/function_sketch/program_memory.snap b/rust/kcl-lib/tests/function_sketch/program_memory.snap index 484edb0bd..bc68ac3f5 100644 --- a/rust/kcl-lib/tests/function_sketch/program_memory.snap +++ b/rust/kcl-lib/tests/function_sketch/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing function_sketch.kcl --- { "box": { - "type": "Function" + "type": "Function", + "value": null }, "fnBox": { "type": "Solid", diff --git a/rust/kcl-lib/tests/function_sketch_with_position/program_memory.snap b/rust/kcl-lib/tests/function_sketch_with_position/program_memory.snap index 8e6154537..b4a3294e9 100644 --- a/rust/kcl-lib/tests/function_sketch_with_position/program_memory.snap +++ b/rust/kcl-lib/tests/function_sketch_with_position/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing function_sketch_with_position.k --- { "box": { - "type": "Function" + "type": "Function", + "value": null }, "thing": { "type": "Solid", diff --git a/rust/kcl-lib/tests/import_async/program_memory.snap b/rust/kcl-lib/tests/import_async/program_memory.snap index 2963e3040..2a6c3b753 100644 --- a/rust/kcl-lib/tests/import_async/program_memory.snap +++ b/rust/kcl-lib/tests/import_async/program_memory.snap @@ -2201,7 +2201,8 @@ description: Variables in memory after executing import_async.kcl } }, "leftInvolute": { - "type": "Function" + "type": "Function", + "value": null }, "module": { "type": "Number", @@ -2263,7 +2264,8 @@ description: Variables in memory after executing import_async.kcl } }, "rightInvolute": { - "type": "Function" + "type": "Function", + "value": null }, "rs": { "type": "MixedArray", diff --git a/rust/kcl-lib/tests/import_function_not_sketch/program_memory.snap b/rust/kcl-lib/tests/import_function_not_sketch/program_memory.snap index ad2d1f8d1..50fe8de4d 100644 --- a/rust/kcl-lib/tests/import_function_not_sketch/program_memory.snap +++ b/rust/kcl-lib/tests/import_function_not_sketch/program_memory.snap @@ -4,9 +4,11 @@ description: Variables in memory after executing import_function_not_sketch.kcl --- { "one": { - "type": "Function" + "type": "Function", + "value": null }, "two": { - "type": "Function" + "type": "Function", + "value": null } } diff --git a/rust/kcl-lib/tests/import_glob/program_memory.snap b/rust/kcl-lib/tests/import_glob/program_memory.snap index ef4a21ae6..2c7a52068 100644 --- a/rust/kcl-lib/tests/import_glob/program_memory.snap +++ b/rust/kcl-lib/tests/import_glob/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing import_glob.kcl --- { "foo": { - "type": "Function" + "type": "Function", + "value": null }, "three": { "type": "Number", diff --git a/rust/kcl-lib/tests/import_side_effect/program_memory.snap b/rust/kcl-lib/tests/import_side_effect/program_memory.snap index b8a840c41..c14969da6 100644 --- a/rust/kcl-lib/tests/import_side_effect/program_memory.snap +++ b/rust/kcl-lib/tests/import_side_effect/program_memory.snap @@ -4,6 +4,7 @@ description: Variables in memory after executing import_side_effect.kcl --- { "foo": { - "type": "Function" + "type": "Function", + "value": null } } diff --git a/rust/kcl-lib/tests/intersect_cubes/program_memory.snap b/rust/kcl-lib/tests/intersect_cubes/program_memory.snap index c58cb412e..db11100fd 100644 --- a/rust/kcl-lib/tests/intersect_cubes/program_memory.snap +++ b/rust/kcl-lib/tests/intersect_cubes/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing intersect_cubes.kcl --- { "cube": { - "type": "Function" + "type": "Function", + "value": null }, "fullPart": { "type": "Solid", diff --git a/rust/kcl-lib/tests/kcl_samples/80-20-rail/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/80-20-rail/program_memory.snap index 03274c9a0..57c2e747c 100644 --- a/rust/kcl-lib/tests/kcl_samples/80-20-rail/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/80-20-rail/program_memory.snap @@ -4,6 +4,7 @@ description: Variables in memory after executing 80-20-rail.kcl --- { "rail8020": { - "type": "Function" + "type": "Function", + "value": null } } diff --git a/rust/kcl-lib/tests/kcl_samples/bench/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/bench/program_memory.snap index 0adcca0d4..80865cdae 100644 --- a/rust/kcl-lib/tests/kcl_samples/bench/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/bench/program_memory.snap @@ -4,10 +4,12 @@ description: Variables in memory after executing bench.kcl --- { "armRest": { - "type": "Function" + "type": "Function", + "value": null }, "backSlats": { - "type": "Function" + "type": "Function", + "value": null }, "benchLength": { "type": "Number", @@ -23,10 +25,12 @@ description: Variables in memory after executing bench.kcl } }, "connector": { - "type": "Function" + "type": "Function", + "value": null }, "divider": { - "type": "Function" + "type": "Function", + "value": null }, "dividerThickness": { "type": "Number", @@ -42,6 +46,7 @@ description: Variables in memory after executing bench.kcl } }, "seatSlats": { - "type": "Function" + "type": "Function", + "value": null } } diff --git a/rust/kcl-lib/tests/kcl_samples/color-cube/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/color-cube/program_memory.snap index 1902f7a85..d1b4ed21c 100644 --- a/rust/kcl-lib/tests/kcl_samples/color-cube/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/color-cube/program_memory.snap @@ -197,7 +197,8 @@ description: Variables in memory after executing color-cube.kcl } }, "sketchRectangle": { - "type": "Function" + "type": "Function", + "value": null }, "tealPlane": { "type": "Plane", diff --git a/rust/kcl-lib/tests/kcl_samples/cycloidal-gear/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/cycloidal-gear/program_memory.snap index 6913f82b6..8aa3b3df1 100644 --- a/rust/kcl-lib/tests/kcl_samples/cycloidal-gear/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/cycloidal-gear/program_memory.snap @@ -4,6 +4,7 @@ description: Variables in memory after executing cycloidal-gear.kcl --- { "cycloidalGear": { - "type": "Function" + "type": "Function", + "value": null } } diff --git a/rust/kcl-lib/tests/kcl_samples/dodecahedron/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/dodecahedron/program_memory.snap index a8b30279d..a98320e40 100644 --- a/rust/kcl-lib/tests/kcl_samples/dodecahedron/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/dodecahedron/program_memory.snap @@ -4,13 +4,16 @@ description: Variables in memory after executing dodecahedron.kcl --- { "calculateArrayLength": { - "type": "Function" + "type": "Function", + "value": null }, "createFaceTemplate": { - "type": "Function" + "type": "Function", + "value": null }, "createIntersection": { - "type": "Function" + "type": "Function", + "value": null }, "dihedral": { "type": "Number", diff --git a/rust/kcl-lib/tests/kcl_samples/enclosure/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/enclosure/program_memory.snap index 439f2c1e3..6e6421d4a 100644 --- a/rust/kcl-lib/tests/kcl_samples/enclosure/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/enclosure/program_memory.snap @@ -1352,7 +1352,8 @@ description: Variables in memory after executing enclosure.kcl } }, "function001": { - "type": "Function" + "type": "Function", + "value": null }, "height": { "type": "Number", diff --git a/rust/kcl-lib/tests/kcl_samples/exhaust-manifold/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/exhaust-manifold/program_memory.snap index 36f77bda9..570343551 100644 --- a/rust/kcl-lib/tests/kcl_samples/exhaust-manifold/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/exhaust-manifold/program_memory.snap @@ -774,7 +774,8 @@ description: Variables in memory after executing exhaust-manifold.kcl } }, "primaryTube": { - "type": "Function" + "type": "Function", + "value": null }, "primaryTubeDiameter": { "type": "Number", diff --git a/rust/kcl-lib/tests/kcl_samples/focusrite-scarlett-mounting-bracket/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/focusrite-scarlett-mounting-bracket/program_memory.snap index 1d558484e..4218a00f3 100644 --- a/rust/kcl-lib/tests/kcl_samples/focusrite-scarlett-mounting-bracket/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/focusrite-scarlett-mounting-bracket/program_memory.snap @@ -673,7 +673,8 @@ description: Variables in memory after executing focusrite-scarlett-mounting-bra } }, "bracketSketch": { - "type": "Function" + "type": "Function", + "value": null }, "bs": { "type": "Sketch", diff --git a/rust/kcl-lib/tests/kcl_samples/food-service-spatula/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/food-service-spatula/program_memory.snap index 5ae66b3cf..6aaf50c8c 100644 --- a/rust/kcl-lib/tests/kcl_samples/food-service-spatula/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/food-service-spatula/program_memory.snap @@ -2832,7 +2832,8 @@ description: Variables in memory after executing food-service-spatula.kcl } }, "slot": { - "type": "Function" + "type": "Function", + "value": null }, "slotProfile000": { "type": "Sketch", diff --git a/rust/kcl-lib/tests/kcl_samples/gear-rack/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/gear-rack/program_memory.snap index 5334de8cc..eca0a9aef 100644 --- a/rust/kcl-lib/tests/kcl_samples/gear-rack/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/gear-rack/program_memory.snap @@ -19763,7 +19763,8 @@ description: Variables in memory after executing gear-rack.kcl ] }, "tooth": { - "type": "Function" + "type": "Function", + "value": null }, "width": { "type": "Number", diff --git a/rust/kcl-lib/tests/kcl_samples/gear/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/gear/program_memory.snap index ffe6bb873..a2d960653 100644 --- a/rust/kcl-lib/tests/kcl_samples/gear/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/gear/program_memory.snap @@ -2201,7 +2201,8 @@ description: Variables in memory after executing gear.kcl } }, "leftInvolute": { - "type": "Function" + "type": "Function", + "value": null }, "module": { "type": "Number", @@ -2256,7 +2257,8 @@ description: Variables in memory after executing gear.kcl } }, "rightInvolute": { - "type": "Function" + "type": "Function", + "value": null }, "rs": { "type": "MixedArray", diff --git a/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate-magnets/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate-magnets/program_memory.snap index c4062f6a4..df6e68058 100644 --- a/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate-magnets/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate-magnets/program_memory.snap @@ -10850,7 +10850,8 @@ description: Variables in memory after executing gridfinity-baseplate-magnets.kc } }, "face": { - "type": "Function" + "type": "Function", + "value": null }, "firstStep": { "type": "Number", @@ -10938,10 +10939,12 @@ description: Variables in memory after executing gridfinity-baseplate-magnets.kc } }, "magnetBase": { - "type": "Function" + "type": "Function", + "value": null }, "magnetCenterCutout": { - "type": "Function" + "type": "Function", + "value": null }, "magnetCutoutExtrude": { "type": "Solid", diff --git a/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate/program_memory.snap index bc8d1b8e7..e0380b253 100644 --- a/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate/program_memory.snap @@ -10850,7 +10850,8 @@ description: Variables in memory after executing gridfinity-baseplate.kcl } }, "face": { - "type": "Function" + "type": "Function", + "value": null }, "firstStep": { "type": "Number", diff --git a/rust/kcl-lib/tests/kcl_samples/gridfinity-bins-stacking-lip/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/gridfinity-bins-stacking-lip/program_memory.snap index 98b589037..6d8aa610a 100644 --- a/rust/kcl-lib/tests/kcl_samples/gridfinity-bins-stacking-lip/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/gridfinity-bins-stacking-lip/program_memory.snap @@ -14220,7 +14220,8 @@ description: Variables in memory after executing gridfinity-bins-stacking-lip.kc } }, "face": { - "type": "Function" + "type": "Function", + "value": null }, "firstStep": { "type": "Number", @@ -15659,7 +15660,8 @@ description: Variables in memory after executing gridfinity-bins-stacking-lip.kc ] }, "lipFace": { - "type": "Function" + "type": "Function", + "value": null }, "lipHeight": { "type": "Number", diff --git a/rust/kcl-lib/tests/kcl_samples/gridfinity-bins/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/gridfinity-bins/program_memory.snap index 3235cdb13..5f286c298 100644 --- a/rust/kcl-lib/tests/kcl_samples/gridfinity-bins/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/gridfinity-bins/program_memory.snap @@ -14148,7 +14148,8 @@ description: Variables in memory after executing gridfinity-bins.kcl } }, "face": { - "type": "Function" + "type": "Function", + "value": null }, "firstStep": { "type": "Number", diff --git a/rust/kcl-lib/tests/kcl_samples/hex-nut/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/hex-nut/program_memory.snap index 2fcd974a4..dcd50f0d4 100644 --- a/rust/kcl-lib/tests/kcl_samples/hex-nut/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/hex-nut/program_memory.snap @@ -17,7 +17,8 @@ description: Variables in memory after executing hex-nut.kcl } }, "hexNut": { - "type": "Function" + "type": "Function", + "value": null }, "thickness": { "type": "Number", diff --git a/rust/kcl-lib/tests/kcl_samples/keyboard/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/keyboard/program_memory.snap index ed98df63d..e1aade092 100644 --- a/rust/kcl-lib/tests/kcl_samples/keyboard/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/keyboard/program_memory.snap @@ -29,7 +29,8 @@ description: Variables in memory after executing keyboard.kcl } }, "keyFn": { - "type": "Function" + "type": "Function", + "value": null }, "keyHeight": { "type": "Number", @@ -45,7 +46,8 @@ description: Variables in memory after executing keyboard.kcl } }, "o": { - "type": "Function" + "type": "Function", + "value": null }, "plane001": { "type": "Object", @@ -2885,6 +2887,7 @@ description: Variables in memory after executing keyboard.kcl } }, "z": { - "type": "Function" + "type": "Function", + "value": null } } diff --git a/rust/kcl-lib/tests/kcl_samples/kitt/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/kitt/program_memory.snap index 2e66ddb34..683ffa83f 100644 --- a/rust/kcl-lib/tests/kcl_samples/kitt/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/kitt/program_memory.snap @@ -6262,7 +6262,8 @@ description: Variables in memory after executing kitt.kcl } }, "kitEar": { - "type": "Function" + "type": "Function", + "value": null }, "kitEarDepth": { "type": "Number", @@ -13308,7 +13309,8 @@ description: Variables in memory after executing kitt.kcl } }, "kitLeg": { - "type": "Function" + "type": "Function", + "value": null }, "kitLegOffset": { "type": "Number", @@ -22321,7 +22323,8 @@ description: Variables in memory after executing kitt.kcl } }, "pixelBox": { - "type": "Function" + "type": "Function", + "value": null }, "seg01": { "type": "TagIdentifier", diff --git a/rust/kcl-lib/tests/kcl_samples/makeup-mirror/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/makeup-mirror/program_memory.snap index 3abe76f1b..749487eb3 100644 --- a/rust/kcl-lib/tests/kcl_samples/makeup-mirror/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/makeup-mirror/program_memory.snap @@ -43,7 +43,8 @@ description: Variables in memory after executing makeup-mirror.kcl } }, "armFn": { - "type": "Function" + "type": "Function", + "value": null }, "armLength": { "type": "Number", @@ -288,7 +289,8 @@ description: Variables in memory after executing makeup-mirror.kcl } }, "hingeFn": { - "type": "Function" + "type": "Function", + "value": null }, "hingeGap": { "type": "Number", @@ -1194,7 +1196,8 @@ description: Variables in memory after executing makeup-mirror.kcl } }, "mirrorFn": { - "type": "Function" + "type": "Function", + "value": null }, "mirrorRadius": { "type": "Number", diff --git a/rust/kcl-lib/tests/kcl_samples/mounting-plate/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/mounting-plate/program_memory.snap index bd73aab5a..7e98a02ab 100644 --- a/rust/kcl-lib/tests/kcl_samples/mounting-plate/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/mounting-plate/program_memory.snap @@ -435,7 +435,8 @@ description: Variables in memory after executing mounting-plate.kcl } }, "rectShape": { - "type": "Function" + "type": "Function", + "value": null }, "rs": { "type": "Sketch", diff --git a/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/program_memory.snap index d7b163cd8..8cdd12719 100644 --- a/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing pipe-flange-assembly.kcl --- { "bolt": { - "type": "Function" + "type": "Function", + "value": null }, "boltDiameter": { "type": "Number", @@ -103,7 +104,8 @@ description: Variables in memory after executing pipe-flange-assembly.kcl "value": "filletEdge" }, "flange": { - "type": "Function" + "type": "Function", + "value": null }, "flangeBackDiameter": { "type": "Number", @@ -240,7 +242,8 @@ description: Variables in memory after executing pipe-flange-assembly.kcl } }, "hexNut": { - "type": "Function" + "type": "Function", + "value": null }, "hexNutDiameter": { "type": "Number", @@ -321,7 +324,8 @@ description: Variables in memory after executing pipe-flange-assembly.kcl } }, "pipe": { - "type": "Function" + "type": "Function", + "value": null }, "pipeDiameter": { "type": "Number", @@ -376,7 +380,8 @@ description: Variables in memory after executing pipe-flange-assembly.kcl } }, "washer": { - "type": "Function" + "type": "Function", + "value": null }, "washerInnerDia": { "type": "Number", diff --git a/rust/kcl-lib/tests/kcl_samples/walkie-talkie/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/walkie-talkie/program_memory.snap index e696507a8..3ec605c89 100644 --- a/rust/kcl-lib/tests/kcl_samples/walkie-talkie/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/walkie-talkie/program_memory.snap @@ -77,7 +77,8 @@ description: Variables in memory after executing walkie-talkie.kcl "value": 2 }, "button": { - "type": "Function" + "type": "Function", + "value": null }, "buttonHeight": { "type": "Number", diff --git a/rust/kcl-lib/tests/kw_fn/program_memory.snap b/rust/kcl-lib/tests/kw_fn/program_memory.snap index b07d1d288..77bf9b7cb 100644 --- a/rust/kcl-lib/tests/kw_fn/program_memory.snap +++ b/rust/kcl-lib/tests/kw_fn/program_memory.snap @@ -4,10 +4,12 @@ description: Variables in memory after executing kw_fn.kcl --- { "add": { - "type": "Function" + "type": "Function", + "value": null }, "increment": { - "type": "Function" + "type": "Function", + "value": null }, "three": { "type": "Number", diff --git a/rust/kcl-lib/tests/kw_fn_with_defaults/program_memory.snap b/rust/kcl-lib/tests/kw_fn_with_defaults/program_memory.snap index cabbe1049..6f66f706b 100644 --- a/rust/kcl-lib/tests/kw_fn_with_defaults/program_memory.snap +++ b/rust/kcl-lib/tests/kw_fn_with_defaults/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing kw_fn_with_defaults.kcl --- { "increment": { - "type": "Function" + "type": "Function", + "value": null }, "twentyOne": { "type": "Number", diff --git a/rust/kcl-lib/tests/loop_tag/program_memory.snap b/rust/kcl-lib/tests/loop_tag/program_memory.snap index 8d588bce1..db23231e2 100644 --- a/rust/kcl-lib/tests/loop_tag/program_memory.snap +++ b/rust/kcl-lib/tests/loop_tag/program_memory.snap @@ -17,7 +17,8 @@ description: Variables in memory after executing loop_tag.kcl } }, "calculatePoint": { - "type": "Function" + "type": "Function", + "value": null }, "closedSketch": { "type": "Sketch", diff --git a/rust/kcl-lib/tests/multi_transform/program_memory.snap b/rust/kcl-lib/tests/multi_transform/program_memory.snap index 5a0600561..adf7296a3 100644 --- a/rust/kcl-lib/tests/multi_transform/program_memory.snap +++ b/rust/kcl-lib/tests/multi_transform/program_memory.snap @@ -4,6 +4,7 @@ description: Variables in memory after executing multi_transform.kcl --- { "transform": { - "type": "Function" + "type": "Function", + "value": null } } diff --git a/rust/kcl-lib/tests/pattern_circular_in_module/program_memory.snap b/rust/kcl-lib/tests/pattern_circular_in_module/program_memory.snap index e4265fe09..5e85e05db 100644 --- a/rust/kcl-lib/tests/pattern_circular_in_module/program_memory.snap +++ b/rust/kcl-lib/tests/pattern_circular_in_module/program_memory.snap @@ -4,6 +4,7 @@ description: Variables in memory after executing pattern_circular_in_module.kcl --- { "thing": { - "type": "Function" + "type": "Function", + "value": null } } diff --git a/rust/kcl-lib/tests/pattern_linear_in_module/program_memory.snap b/rust/kcl-lib/tests/pattern_linear_in_module/program_memory.snap index 77112d383..1a783a8a0 100644 --- a/rust/kcl-lib/tests/pattern_linear_in_module/program_memory.snap +++ b/rust/kcl-lib/tests/pattern_linear_in_module/program_memory.snap @@ -4,6 +4,7 @@ description: Variables in memory after executing pattern_linear_in_module.kcl --- { "thing": { - "type": "Function" + "type": "Function", + "value": null } } diff --git a/rust/kcl-lib/tests/pentagon_fillet_sugar/program_memory.snap b/rust/kcl-lib/tests/pentagon_fillet_sugar/program_memory.snap index a42f32da2..e474f85b4 100644 --- a/rust/kcl-lib/tests/pentagon_fillet_sugar/program_memory.snap +++ b/rust/kcl-lib/tests/pentagon_fillet_sugar/program_memory.snap @@ -652,7 +652,8 @@ description: Variables in memory after executing pentagon_fillet_sugar.kcl } }, "circl": { - "type": "Function" + "type": "Function", + "value": null }, "p": { "type": "Solid", diff --git a/rust/kcl-lib/tests/pipe_as_arg/program_memory.snap b/rust/kcl-lib/tests/pipe_as_arg/program_memory.snap index 4aba2f8a9..5cea65986 100644 --- a/rust/kcl-lib/tests/pipe_as_arg/program_memory.snap +++ b/rust/kcl-lib/tests/pipe_as_arg/program_memory.snap @@ -4,10 +4,12 @@ description: Variables in memory after executing pipe_as_arg.kcl --- { "cube": { - "type": "Function" + "type": "Function", + "value": null }, "double": { - "type": "Function" + "type": "Function", + "value": null }, "myCube": { "type": "Number", @@ -23,6 +25,7 @@ description: Variables in memory after executing pipe_as_arg.kcl } }, "width": { - "type": "Function" + "type": "Function", + "value": null } } diff --git a/rust/kcl-lib/tests/riddle_small/program_memory.snap b/rust/kcl-lib/tests/riddle_small/program_memory.snap index 63e4f605a..7efa12b97 100644 --- a/rust/kcl-lib/tests/riddle_small/program_memory.snap +++ b/rust/kcl-lib/tests/riddle_small/program_memory.snap @@ -223,7 +223,8 @@ description: Variables in memory after executing riddle_small.kcl } }, "t": { - "type": "Function" + "type": "Function", + "value": null }, "xs": { "type": "Number", diff --git a/rust/kcl-lib/tests/rotate_after_fillet/program_memory.snap b/rust/kcl-lib/tests/rotate_after_fillet/program_memory.snap index 8176dc7b8..38ed2a5b3 100644 --- a/rust/kcl-lib/tests/rotate_after_fillet/program_memory.snap +++ b/rust/kcl-lib/tests/rotate_after_fillet/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing rotate_after_fillet.kcl --- { "bolt": { - "type": "Function" + "type": "Function", + "value": null }, "boltDiameter": { "type": "Number", diff --git a/rust/kcl-lib/tests/scale_after_fillet/program_memory.snap b/rust/kcl-lib/tests/scale_after_fillet/program_memory.snap index faefbe5f1..0ee955ff4 100644 --- a/rust/kcl-lib/tests/scale_after_fillet/program_memory.snap +++ b/rust/kcl-lib/tests/scale_after_fillet/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing scale_after_fillet.kcl --- { "bolt": { - "type": "Function" + "type": "Function", + "value": null }, "boltDiameter": { "type": "Number", diff --git a/rust/kcl-lib/tests/sketch_in_object/program_memory.snap b/rust/kcl-lib/tests/sketch_in_object/program_memory.snap index 2ff0050a4..fe42d22f3 100644 --- a/rust/kcl-lib/tests/sketch_in_object/program_memory.snap +++ b/rust/kcl-lib/tests/sketch_in_object/program_memory.snap @@ -4,10 +4,12 @@ description: Variables in memory after executing sketch_in_object.kcl --- { "test": { - "type": "Function" + "type": "Function", + "value": null }, "test2": { - "type": "Function" + "type": "Function", + "value": null }, "x": { "type": "Sketch", diff --git a/rust/kcl-lib/tests/sketch_on_face_circle_tagged/program_memory.snap b/rust/kcl-lib/tests/sketch_on_face_circle_tagged/program_memory.snap index 1db537253..f0e00a7bd 100644 --- a/rust/kcl-lib/tests/sketch_on_face_circle_tagged/program_memory.snap +++ b/rust/kcl-lib/tests/sketch_on_face_circle_tagged/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing sketch_on_face_circle_tagged.kc --- { "cube": { - "type": "Function" + "type": "Function", + "value": null }, "myCircle": { "type": "TagIdentifier", diff --git a/rust/kcl-lib/tests/sketch_on_face_end/program_memory.snap b/rust/kcl-lib/tests/sketch_on_face_end/program_memory.snap index 7907e9c2a..7fb413618 100644 --- a/rust/kcl-lib/tests/sketch_on_face_end/program_memory.snap +++ b/rust/kcl-lib/tests/sketch_on_face_end/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing sketch_on_face_end.kcl --- { "cube": { - "type": "Function" + "type": "Function", + "value": null }, "part001": { "type": "Solid", diff --git a/rust/kcl-lib/tests/sketch_on_face_end_negative_extrude/program_memory.snap b/rust/kcl-lib/tests/sketch_on_face_end_negative_extrude/program_memory.snap index fb3e322e5..ed8ccc19e 100644 --- a/rust/kcl-lib/tests/sketch_on_face_end_negative_extrude/program_memory.snap +++ b/rust/kcl-lib/tests/sketch_on_face_end_negative_extrude/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing sketch_on_face_end_negative_ext --- { "cube": { - "type": "Function" + "type": "Function", + "value": null }, "part001": { "type": "Solid", diff --git a/rust/kcl-lib/tests/sketch_on_face_start/program_memory.snap b/rust/kcl-lib/tests/sketch_on_face_start/program_memory.snap index e7f3c1617..6feb4d2c1 100644 --- a/rust/kcl-lib/tests/sketch_on_face_start/program_memory.snap +++ b/rust/kcl-lib/tests/sketch_on_face_start/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing sketch_on_face_start.kcl --- { "cube": { - "type": "Function" + "type": "Function", + "value": null }, "foo": { "type": "Solid", diff --git a/rust/kcl-lib/tests/subtract_cylinder_from_cube/program_memory.snap b/rust/kcl-lib/tests/subtract_cylinder_from_cube/program_memory.snap index 6358289a3..5c00e79db 100644 --- a/rust/kcl-lib/tests/subtract_cylinder_from_cube/program_memory.snap +++ b/rust/kcl-lib/tests/subtract_cylinder_from_cube/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing subtract_cylinder_from_cube.kcl --- { "cube": { - "type": "Function" + "type": "Function", + "value": null }, "fullPart": { "type": "Solid", diff --git a/rust/kcl-lib/tests/subtract_doesnt_need_brackets/program_memory.snap b/rust/kcl-lib/tests/subtract_doesnt_need_brackets/program_memory.snap index 26463d461..0e3f4bc1a 100644 --- a/rust/kcl-lib/tests/subtract_doesnt_need_brackets/program_memory.snap +++ b/rust/kcl-lib/tests/subtract_doesnt_need_brackets/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing subtract_doesnt_need_brackets.k --- { "cube": { - "type": "Function" + "type": "Function", + "value": null }, "part001": { "type": "Solid", diff --git a/rust/kcl-lib/tests/translate_after_fillet/program_memory.snap b/rust/kcl-lib/tests/translate_after_fillet/program_memory.snap index 4cf278276..5901c5527 100644 --- a/rust/kcl-lib/tests/translate_after_fillet/program_memory.snap +++ b/rust/kcl-lib/tests/translate_after_fillet/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing translate_after_fillet.kcl --- { "bolt": { - "type": "Function" + "type": "Function", + "value": null }, "boltDiameter": { "type": "Number", diff --git a/rust/kcl-lib/tests/union_cubes/program_memory.snap b/rust/kcl-lib/tests/union_cubes/program_memory.snap index 74edcabfe..26218ec27 100644 --- a/rust/kcl-lib/tests/union_cubes/program_memory.snap +++ b/rust/kcl-lib/tests/union_cubes/program_memory.snap @@ -4,7 +4,8 @@ description: Variables in memory after executing union_cubes.kcl --- { "cube": { - "type": "Function" + "type": "Function", + "value": null }, "fullPart": { "type": "Solid", diff --git a/rust/kcl-wasm-lib/src/wasm.rs b/rust/kcl-wasm-lib/src/wasm.rs index c466768e0..81fb21771 100644 --- a/rust/kcl-wasm-lib/src/wasm.rs +++ b/rust/kcl-wasm-lib/src/wasm.rs @@ -1,7 +1,11 @@ //! Wasm bindings for `kcl`. use gloo_utils::format::JsValueSerdeExt; -use kcl_lib::{pretty::NumericSuffix, CoreDump, Program, SourceRange}; +use kcl_lib::{ + exec::{NumericType, UnitAngle, UnitLen, UnitType}, + pretty::NumericSuffix, + CoreDump, Program, SourceRange, +}; use wasm_bindgen::prelude::*; // wasm_bindgen wrapper for lint @@ -50,11 +54,34 @@ pub fn recast_wasm(json_str: &str) -> Result { } #[wasm_bindgen] -pub fn format_number(value: f64, suffix_json: &str) -> Result { +pub fn format_number_literal(value: f64, suffix_json: &str) -> Result { console_error_panic_hook::set_once(); let suffix: NumericSuffix = serde_json::from_str(suffix_json).map_err(JsError::from)?; - Ok(kcl_lib::pretty::format_number(value, suffix)) + kcl_lib::pretty::format_number_literal(value, suffix).map_err(JsError::from) +} + +#[wasm_bindgen] +pub fn human_display_number(value: f64, ty_json: &str) -> Result { + console_error_panic_hook::set_once(); + + // ts-rs can't handle tuple types, so it mashes all of these types together. + if let Ok(ty) = serde_json::from_str::(ty_json) { + return Ok(kcl_lib::pretty::human_display_number(value, ty)); + } + if let Ok(unit_type) = serde_json::from_str::(ty_json) { + let ty = NumericType::Known(unit_type); + return Ok(kcl_lib::pretty::human_display_number(value, ty)); + } + if let Ok(unit_len) = serde_json::from_str::(ty_json) { + let ty = NumericType::Known(UnitType::Length(unit_len)); + return Ok(kcl_lib::pretty::human_display_number(value, ty)); + } + if let Ok(unit_angle) = serde_json::from_str::(ty_json) { + let ty = NumericType::Known(UnitType::Angle(unit_angle)); + return Ok(kcl_lib::pretty::human_display_number(value, ty)); + } + Err(format!("Invalid type: {ty_json}")) } #[wasm_bindgen] diff --git a/src/components/ModelingSidebar/ModelingPanes/MemoryPane.test.tsx b/src/components/ModelingSidebar/ModelingPanes/MemoryPane.test.tsx index b846068fe..50418cf2a 100644 --- a/src/components/ModelingSidebar/ModelingPanes/MemoryPane.test.tsx +++ b/src/components/ModelingSidebar/ModelingPanes/MemoryPane.test.tsx @@ -16,6 +16,13 @@ describe('processMemory', () => { return a - 2 } otherVar = myFn(5) + nFeet = 2ft + nInches = 2in + nMm = 2mm + nDegrees = 2deg + nRadians = 2rad + nCount = 2_ + nUnknown = 1rad * PI theExtrude = startSketchOn(XY) |> startProfile(at = [0, 0]) @@ -32,8 +39,17 @@ describe('processMemory', () => { const ast = assertParse(code) const execState = await enginelessExecutor(ast) const output = processMemory(execState.variables) - expect(output.myVar).toEqual(5) - expect(output.otherVar).toEqual(3) + expect(output.nFeet).toEqual('2: number(ft)') + expect(output.nInches).toEqual('2: number(in)') + expect(output.nMm).toEqual('2: number(mm)') + expect(output.nDegrees).toEqual('2: number(deg)') + expect(output.nRadians).toEqual('2: number(rad)') + expect(output.nCount).toEqual('2: number(Count)') + expect(output.nUnknown).toEqual( + '3.141592653589793 (number with unknown units)' + ) + expect(output.myVar).toEqual('5 (no units, defaulting to mm or deg)') + expect(output.otherVar).toEqual('3 (no units, defaulting to mm or deg)') expect(output.myFn).toEqual('__function__') expect(output.theExtrude).toEqual([ { diff --git a/src/components/ModelingSidebar/ModelingPanes/MemoryPane.tsx b/src/components/ModelingSidebar/ModelingPanes/MemoryPane.tsx index 7e5f4d001..85fe1b2d9 100644 --- a/src/components/ModelingSidebar/ModelingPanes/MemoryPane.tsx +++ b/src/components/ModelingSidebar/ModelingPanes/MemoryPane.tsx @@ -11,7 +11,7 @@ import { useModelingContext } from '@src/hooks/useModelingContext' import { useResolvedTheme } from '@src/hooks/useResolvedTheme' import { useKclContext } from '@src/lang/KclProvider' import type { VariableMap } from '@src/lang/wasm' -import { sketchFromKclValueOptional } from '@src/lang/wasm' +import { humanDisplayNumber, sketchFromKclValueOptional } from '@src/lang/wasm' import { Reason, trap } from '@src/lib/trap' export const MemoryPaneMenu = () => { @@ -81,31 +81,29 @@ export const MemoryPane = () => { } export const processMemory = (variables: VariableMap) => { - const processedMemory: any = {} + const processedMemory: Record< + string, + string | number | boolean | object | undefined + > = {} for (const [key, val] of Object.entries(variables)) { if (val === undefined) continue - if ( - val.type === 'Sketch' || - // @ts-ignore - val.type !== 'Function' - ) { - const sk = sketchFromKclValueOptional(val, key) - if (val.type === 'Solid') { - processedMemory[key] = val.value.value.map( - ({ ...rest }: ExtrudeSurface) => { - return rest - } - ) - } else if (!(sk instanceof Reason)) { - processedMemory[key] = sk.paths.map(({ __geoMeta, ...rest }: Path) => { + const sk = sketchFromKclValueOptional(val, key) + if (val.type === 'Solid') { + processedMemory[key] = val.value.value.map( + ({ ...rest }: ExtrudeSurface) => { return rest - }) - } else { - processedMemory[key] = val.value - } - //@ts-ignore + } + ) + } else if (!(sk instanceof Reason)) { + processedMemory[key] = sk.paths.map(({ __geoMeta, ...rest }: Path) => { + return rest + }) } else if (val.type === 'Function') { - processedMemory[key] = `__function__` + processedMemory[key] = '__function__' + } else if (val.type === 'Number') { + processedMemory[key] = humanDisplayNumber(val.value, val.ty) + } else { + processedMemory[key] = val.value } } return processedMemory diff --git a/src/lang/create.ts b/src/lang/create.ts index a1a2b6df9..c020b4fd5 100644 --- a/src/lang/create.ts +++ b/src/lang/create.ts @@ -31,28 +31,48 @@ import type { VariableDeclaration, VariableDeclarator, } from '@src/lang/wasm' -import { formatNumber } from '@src/lang/wasm' +import { formatNumberLiteral } from '@src/lang/wasm' import { err } from '@src/lib/trap' +export function createLiteral(value: number | string | boolean): Node { + // TODO: Should we handle string escape sequences? + return { + type: 'Literal', + start: 0, + end: 0, + moduleId: 0, + value: typeof value === 'number' ? { value, suffix: 'None' } : value, + raw: `${value}`, + outerAttrs: [], + preComments: [], + commentStart: 0, + } +} + /** * Note: This depends on WASM, but it's not async. Callers are responsible for * awaiting init of the WASM module. */ -export function createLiteral(value: LiteralValue | number): Node { - if (typeof value === 'number') { - value = { value, suffix: 'None' } +export function createLiteralMaybeSuffix( + value: LiteralValue +): Node | Error { + if (typeof value === 'string' || typeof value === 'boolean') { + return createLiteral(value) } + let raw: string - if (typeof value === 'string') { - // TODO: Should we handle escape sequences? - raw = `${value}` - } else if (typeof value === 'boolean') { - raw = `${value}` - } else if (typeof value.value === 'number' && value.suffix === 'None') { + if (typeof value.value === 'number' && value.suffix === 'None') { // Fast path for numbers when there are no units. raw = `${value.value}` } else { - raw = formatNumber(value.value, value.suffix) + const formatted = formatNumberLiteral(value.value, value.suffix) + if (err(formatted)) { + return new Error( + `Invalid number literal: value=${value.value}, suffix=${value.suffix}`, + { cause: formatted } + ) + } + raw = formatted } return { type: 'Literal', diff --git a/src/lang/modifyAst.test.ts b/src/lang/modifyAst.test.ts index 252a16212..12b3d33fb 100644 --- a/src/lang/modifyAst.test.ts +++ b/src/lang/modifyAst.test.ts @@ -4,6 +4,7 @@ import { createArrayExpression, createIdentifier, createLiteral, + createLiteralMaybeSuffix, createObjectExpression, createPipeExpression, createPipeSubstitution, @@ -35,6 +36,7 @@ import { initPromise } from '@src/lang/wasmUtils' import { enginelessExecutor } from '@src/lib/testHelpers' import { err } from '@src/lib/trap' import { deleteFromSelection } from '@src/lang/modifyAst/deleteFromSelection' +import { assertNotErr } from '@src/unitTestUtils' beforeAll(async () => { await initPromise @@ -50,7 +52,8 @@ describe('Testing createLiteral', () => { }) it('should create a literal number with units', () => { const lit: LiteralValue = { value: 5, suffix: 'Mm' } - const result = createLiteral(lit) + const result = createLiteralMaybeSuffix(lit) + assertNotErr(result) expect(result.type).toBe('Literal') expect((result as any).value.value).toBe(5) expect((result as any).value.suffix).toBe('Mm') diff --git a/src/lang/wasm.test.ts b/src/lang/wasm.test.ts index bfef3e9f3..9462e19df 100644 --- a/src/lang/wasm.test.ts +++ b/src/lang/wasm.test.ts @@ -3,7 +3,7 @@ import type { Program } from '@rust/kcl-lib/bindings/Program' import type { ParseResult } from '@src/lang/wasm' import { - formatNumber, + formatNumberLiteral, parse, errFromErrWithOutputs, rustImplPathToNode, @@ -33,12 +33,15 @@ it('can execute parsed AST', async () => { }) it('formats numbers with units', () => { - expect(formatNumber(1, 'None')).toEqual('1') - expect(formatNumber(1, 'Count')).toEqual('1_') - expect(formatNumber(1, 'Mm')).toEqual('1mm') - expect(formatNumber(1, 'Inch')).toEqual('1in') - expect(formatNumber(0.5, 'Mm')).toEqual('0.5mm') - expect(formatNumber(-0.5, 'Mm')).toEqual('-0.5mm') + expect(formatNumberLiteral(1, 'None')).toEqual('1') + expect(formatNumberLiteral(1, 'Count')).toEqual('1_') + expect(formatNumberLiteral(1, 'Mm')).toEqual('1mm') + expect(formatNumberLiteral(1, 'Inch')).toEqual('1in') + expect(formatNumberLiteral(0.5, 'Mm')).toEqual('0.5mm') + expect(formatNumberLiteral(-0.5, 'Mm')).toEqual('-0.5mm') + expect(formatNumberLiteral(1, 'Unknown')).toEqual( + new Error('Error formatting number literal: value=1, suffix=Unknown') + ) }) describe('test errFromErrWithOutputs', () => { diff --git a/src/lang/wasm.ts b/src/lang/wasm.ts index 42cbe4b36..284aee966 100644 --- a/src/lang/wasm.ts +++ b/src/lang/wasm.ts @@ -47,9 +47,10 @@ import { coredump, default_app_settings, default_project_settings, - format_number, + format_number_literal, get_kcl_version, get_tangential_arc_to_info, + human_display_number, is_kcl_empty_or_only_settings, is_points_ccw, kcl_lint, @@ -67,6 +68,7 @@ import { LABELED_ARG_FIELD, UNLABELED_ARG, } from '@src/lang/queryAstConstants' +import type { NumericType } from '@rust/kcl-lib/bindings/NumericType' export type { ArrayExpression } from '@rust/kcl-lib/bindings/ArrayExpression' export type { @@ -440,8 +442,35 @@ export const recast = (ast: Program): string | Error => { /** * Format a number with suffix as KCL. */ -export function formatNumber(value: number, suffix: NumericSuffix): string { - return format_number(value, JSON.stringify(suffix)) +export function formatNumberLiteral( + value: number, + suffix: NumericSuffix +): string | Error { + try { + return format_number_literal(value, JSON.stringify(suffix)) + } catch (e) { + return new Error( + `Error formatting number literal: value=${value}, suffix=${suffix}`, + { cause: e } + ) + } +} + +/** + * Debug display a number with suffix, for human consumption only. + */ +export function humanDisplayNumber( + value: number, + ty: NumericType +): string | Error { + try { + return human_display_number(value, JSON.stringify(ty)) + } catch (e) { + return new Error( + `Error formatting number for human display: value=${value}, ty=${JSON.stringify(ty)}`, + { cause: e } + ) + } } export function isPointsCCW(points: Coords2d[]): number { diff --git a/src/lib/wasm_lib_wrapper.ts b/src/lib/wasm_lib_wrapper.ts index e36b086b1..1af4c9d97 100644 --- a/src/lib/wasm_lib_wrapper.ts +++ b/src/lib/wasm_lib_wrapper.ts @@ -12,7 +12,8 @@ import type { coredump as CoreDump, default_app_settings as DefaultAppSettings, default_project_settings as DefaultProjectSettings, - format_number as FormatNumber, + format_number_literal as FormatNumberLiteral, + human_display_number as HumanDisplayNumber, get_kcl_version as GetKclVersion, get_tangential_arc_to_info as GetTangentialArcToInfo, import_file_extensions as ImportFileExtensions, @@ -55,8 +56,11 @@ export const parse_wasm: typeof ParseWasm = (...args) => { export const recast_wasm: typeof RecastWasm = (...args) => { return getModule().recast_wasm(...args) } -export const format_number: typeof FormatNumber = (...args) => { - return getModule().format_number(...args) +export const format_number_literal: typeof FormatNumberLiteral = (...args) => { + return getModule().format_number_literal(...args) +} +export const human_display_number: typeof HumanDisplayNumber = (...args) => { + return getModule().human_display_number(...args) } export const kcl_lint: typeof KclLint = (...args) => { return getModule().kcl_lint(...args) diff --git a/src/unitTestUtils.ts b/src/unitTestUtils.ts index 45c31a78a..c44ed86a3 100644 --- a/src/unitTestUtils.ts +++ b/src/unitTestUtils.ts @@ -10,6 +10,16 @@ import { createArrayExpression } from '@src/lang/create' import { findKwArg, findKwArgAny } from '@src/lang/util' import type { CallExpressionKw, Expr } from '@src/lang/wasm' +/** + * Throw x if it's an Error. Only use this in tests. + */ +export function assertNotErr(x: T): asserts x is Exclude { + if (x instanceof Error) { + // eslint-disable-next-line suggest-no-throw/suggest-no-throw + throw x + } +} + /** Find the angle and some sort of length parameter from an angledLine-ish call. E.g. finds the (angle, length) in angledLine or the (angle, endAbsoluteX) in angledLineToX