More types stuff (#5901)
* parse union and fancy array types Signed-off-by: Nick Cameron <nrc@ncameron.org> * type aliases Signed-off-by: Nick Cameron <nrc@ncameron.org> * Treat Helix and Face as primitive types Signed-off-by: Nick Cameron <nrc@ncameron.org> * code motion: factor our execution::types module Signed-off-by: Nick Cameron <nrc@ncameron.org> * Tests for type coercion and subtyping Signed-off-by: Nick Cameron <nrc@ncameron.org> * Add Point2D/3D to std Signed-off-by: Nick Cameron <nrc@ncameron.org> * Rebasing and fixes Signed-off-by: Nick Cameron <nrc@ncameron.org> --------- Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
@ -194,9 +194,21 @@ impl Type {
|
||||
hasher.update(b"FnArgType::Primitive");
|
||||
hasher.update(prim.compute_digest())
|
||||
}
|
||||
Type::Array(prim) => {
|
||||
Type::Array { ty, len } => {
|
||||
hasher.update(b"FnArgType::Array");
|
||||
hasher.update(prim.compute_digest())
|
||||
hasher.update(ty.compute_digest());
|
||||
match len {
|
||||
crate::execution::types::ArrayLen::None => {}
|
||||
crate::execution::types::ArrayLen::NonEmpty => hasher.update(usize::MAX.to_ne_bytes()),
|
||||
crate::execution::types::ArrayLen::Known(n) => hasher.update(n.to_ne_bytes()),
|
||||
}
|
||||
}
|
||||
Type::Union { tys } => {
|
||||
hasher.update(b"FnArgType::Union");
|
||||
hasher.update(tys.len().to_ne_bytes());
|
||||
for t in tys.iter_mut() {
|
||||
hasher.update(t.compute_digest());
|
||||
}
|
||||
}
|
||||
Type::Object { properties } => {
|
||||
hasher.update(b"FnArgType::Object");
|
||||
@ -300,6 +312,9 @@ impl TypeDeclaration {
|
||||
hasher.update(a.compute_digest());
|
||||
}
|
||||
}
|
||||
if let Some(alias) = &mut slf.alias {
|
||||
hasher.update(alias.compute_digest());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ pub use crate::parsing::ast::types::{
|
||||
use crate::{
|
||||
docs::StdLibFn,
|
||||
errors::KclError,
|
||||
execution::{annotations, KclValue, Metadata, TagIdentifier},
|
||||
execution::{annotations, types::ArrayLen, KclValue, Metadata, TagIdentifier},
|
||||
parsing::{ast::digest::Digest, token::NumericSuffix, PIPE_OPERATOR},
|
||||
source_range::SourceRange,
|
||||
ModuleId,
|
||||
@ -150,7 +150,7 @@ impl<T> Node<T> {
|
||||
self.start <= pos && pos <= self.end
|
||||
}
|
||||
|
||||
pub fn map<U>(self, f: fn(T) -> U) -> Node<U> {
|
||||
pub fn map<U>(self, f: impl Fn(T) -> U) -> Node<U> {
|
||||
Node {
|
||||
inner: f(self.inner),
|
||||
start: self.start,
|
||||
@ -1895,6 +1895,7 @@ pub struct TypeDeclaration {
|
||||
pub args: Option<NodeList<Identifier>>,
|
||||
#[serde(default, skip_serializing_if = "ItemVisibility::is_default")]
|
||||
pub visibility: ItemVisibility,
|
||||
pub alias: Option<Node<Type>>,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
@ -3024,7 +3025,14 @@ pub enum Type {
|
||||
/// A primitive type.
|
||||
Primitive(PrimitiveType),
|
||||
// An array of a primitive type.
|
||||
Array(PrimitiveType),
|
||||
Array {
|
||||
ty: PrimitiveType,
|
||||
len: ArrayLen,
|
||||
},
|
||||
// Union/enum types
|
||||
Union {
|
||||
tys: NodeList<PrimitiveType>,
|
||||
},
|
||||
// An object type.
|
||||
Object {
|
||||
properties: Vec<Parameter>,
|
||||
@ -3035,7 +3043,22 @@ impl fmt::Display for Type {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Type::Primitive(primitive_type) => primitive_type.fmt(f),
|
||||
Type::Array(primitive_type) => write!(f, "[{primitive_type}]"),
|
||||
Type::Array { ty, len } => {
|
||||
write!(f, "[{ty}")?;
|
||||
match len {
|
||||
ArrayLen::None => {}
|
||||
ArrayLen::NonEmpty => write!(f, "; 1+")?,
|
||||
ArrayLen::Known(n) => write!(f, "; {n}")?,
|
||||
}
|
||||
write!(f, "]")
|
||||
}
|
||||
Type::Union { tys } => {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
tys.iter().map(|t| t.to_string()).collect::<Vec<_>>().join(" | ")
|
||||
)
|
||||
}
|
||||
Type::Object { properties } => {
|
||||
write!(f, "{{")?;
|
||||
let mut first = true;
|
||||
@ -3624,11 +3647,17 @@ const cylinder = startSketchOn('-XZ')
|
||||
assert_eq!(params.len(), 3);
|
||||
assert_eq!(
|
||||
params[0].type_.as_ref().unwrap().inner,
|
||||
Type::Array(PrimitiveType::Number(NumericSuffix::None))
|
||||
Type::Array {
|
||||
ty: PrimitiveType::Number(NumericSuffix::None),
|
||||
len: ArrayLen::None
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
params[1].type_.as_ref().unwrap().inner,
|
||||
Type::Array(PrimitiveType::String)
|
||||
Type::Array {
|
||||
ty: PrimitiveType::String,
|
||||
len: ArrayLen::None
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
params[2].type_.as_ref().unwrap().inner,
|
||||
@ -3656,7 +3685,10 @@ const cylinder = startSketchOn('-XZ')
|
||||
assert_eq!(params.len(), 3);
|
||||
assert_eq!(
|
||||
params[0].type_.as_ref().unwrap().inner,
|
||||
Type::Array(PrimitiveType::Number(NumericSuffix::None))
|
||||
Type::Array {
|
||||
ty: PrimitiveType::Number(NumericSuffix::None),
|
||||
len: ArrayLen::None
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
params[1].type_.as_ref().unwrap().inner,
|
||||
@ -3692,7 +3724,15 @@ const cylinder = startSketchOn('-XZ')
|
||||
56,
|
||||
module_id,
|
||||
),
|
||||
type_: Some(Node::new(Type::Array(PrimitiveType::String), 59, 65, module_id)),
|
||||
type_: Some(Node::new(
|
||||
Type::Array {
|
||||
ty: PrimitiveType::String,
|
||||
len: ArrayLen::None
|
||||
},
|
||||
59,
|
||||
65,
|
||||
module_id
|
||||
)),
|
||||
default_value: None,
|
||||
labeled: true,
|
||||
digest: None
|
||||
@ -3773,7 +3813,15 @@ const cylinder = startSketchOn('-XZ')
|
||||
34,
|
||||
module_id,
|
||||
),
|
||||
type_: Some(Node::new(Type::Array(PrimitiveType::String), 37, 43, module_id)),
|
||||
type_: Some(Node::new(
|
||||
Type::Array {
|
||||
ty: PrimitiveType::String,
|
||||
len: ArrayLen::None
|
||||
},
|
||||
37,
|
||||
43,
|
||||
module_id
|
||||
)),
|
||||
default_value: None,
|
||||
labeled: true,
|
||||
digest: None
|
||||
@ -3946,7 +3994,7 @@ startSketchOn('XY')"#;
|
||||
|
||||
assert_eq!(
|
||||
meta_settings.default_length_units,
|
||||
crate::execution::kcl_value::UnitLen::Inches
|
||||
crate::execution::types::UnitLen::Inches
|
||||
);
|
||||
}
|
||||
|
||||
@ -3962,13 +4010,13 @@ startSketchOn('XY')"#;
|
||||
|
||||
assert_eq!(
|
||||
meta_settings.default_length_units,
|
||||
crate::execution::kcl_value::UnitLen::Inches
|
||||
crate::execution::types::UnitLen::Inches
|
||||
);
|
||||
|
||||
// Edit the ast.
|
||||
let new_program = program
|
||||
.change_meta_settings(crate::execution::MetaSettings {
|
||||
default_length_units: crate::execution::kcl_value::UnitLen::Mm,
|
||||
default_length_units: crate::execution::types::UnitLen::Mm,
|
||||
..Default::default()
|
||||
})
|
||||
.unwrap();
|
||||
@ -3977,10 +4025,7 @@ startSketchOn('XY')"#;
|
||||
assert!(result.is_some());
|
||||
let meta_settings = result.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
meta_settings.default_length_units,
|
||||
crate::execution::kcl_value::UnitLen::Mm
|
||||
);
|
||||
assert_eq!(meta_settings.default_length_units, crate::execution::types::UnitLen::Mm);
|
||||
|
||||
let formatted = new_program.recast(&Default::default(), 0);
|
||||
|
||||
@ -4003,7 +4048,7 @@ startSketchOn('XY')
|
||||
// Edit the ast.
|
||||
let new_program = program
|
||||
.change_meta_settings(crate::execution::MetaSettings {
|
||||
default_length_units: crate::execution::kcl_value::UnitLen::Mm,
|
||||
default_length_units: crate::execution::types::UnitLen::Mm,
|
||||
..Default::default()
|
||||
})
|
||||
.unwrap();
|
||||
@ -4012,10 +4057,7 @@ startSketchOn('XY')
|
||||
assert!(result.is_some());
|
||||
let meta_settings = result.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
meta_settings.default_length_units,
|
||||
crate::execution::kcl_value::UnitLen::Mm
|
||||
);
|
||||
assert_eq!(meta_settings.default_length_units, crate::execution::types::UnitLen::Mm);
|
||||
|
||||
let formatted = new_program.recast(&Default::default(), 0);
|
||||
|
||||
|
Reference in New Issue
Block a user