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:
@ -6,8 +6,7 @@ use crate::parsing::{
|
||||
CallExpression, CallExpressionKw, CommentStyle, DefaultParamVal, Expr, FormatOptions, FunctionExpression,
|
||||
IfExpression, ImportSelector, ImportStatement, ItemVisibility, LabeledArg, Literal, LiteralIdentifier,
|
||||
LiteralValue, MemberExpression, MemberObject, Node, NonCodeNode, NonCodeValue, ObjectExpression, Parameter,
|
||||
PipeExpression, Program, TagDeclarator, Type, TypeDeclaration, UnaryExpression, VariableDeclaration,
|
||||
VariableKind,
|
||||
PipeExpression, Program, TagDeclarator, TypeDeclaration, UnaryExpression, VariableDeclaration, VariableKind,
|
||||
},
|
||||
token::NumericSuffix,
|
||||
PIPE_OPERATOR,
|
||||
@ -308,7 +307,7 @@ impl Expr {
|
||||
Expr::AscribedExpression(e) => {
|
||||
let mut result = e.expr.recast(options, indentation_level, ctxt);
|
||||
result += ": ";
|
||||
result += &e.ty.recast(options, indentation_level);
|
||||
result += &e.ty.to_string();
|
||||
result
|
||||
}
|
||||
Expr::None(_) => {
|
||||
@ -457,6 +456,10 @@ impl TypeDeclaration {
|
||||
}
|
||||
arg_str.push(')');
|
||||
}
|
||||
if let Some(alias) = &self.alias {
|
||||
arg_str.push_str(" = ");
|
||||
arg_str.push_str(&alias.to_string());
|
||||
}
|
||||
format!("{}type {}{}", vis, self.name.name, arg_str)
|
||||
}
|
||||
}
|
||||
@ -812,7 +815,7 @@ impl FunctionExpression {
|
||||
let tab0 = options.get_indentation(indentation_level);
|
||||
let tab1 = options.get_indentation(indentation_level + 1);
|
||||
let return_type = match &self.return_type {
|
||||
Some(rt) => format!(": {}", rt.recast(&new_options, indentation_level)),
|
||||
Some(rt) => format!(": {rt}"),
|
||||
None => String::new(),
|
||||
};
|
||||
let body = self.body.recast(&new_options, indentation_level + 1);
|
||||
@ -822,14 +825,14 @@ impl FunctionExpression {
|
||||
}
|
||||
|
||||
impl Parameter {
|
||||
pub fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String {
|
||||
pub fn recast(&self, _options: &FormatOptions, _indentation_level: usize) -> String {
|
||||
let at_sign = if self.labeled { "" } else { "@" };
|
||||
let identifier = &self.identifier.name;
|
||||
let question_mark = if self.default_value.is_some() { "?" } else { "" };
|
||||
let mut result = format!("{at_sign}{identifier}{question_mark}");
|
||||
if let Some(ty) = &self.type_ {
|
||||
result += ": ";
|
||||
result += &ty.recast(options, indentation_level);
|
||||
result += &ty.to_string();
|
||||
}
|
||||
if let Some(DefaultParamVal::Literal(ref literal)) = self.default_value {
|
||||
let lit = literal.recast();
|
||||
@ -840,31 +843,6 @@ impl Parameter {
|
||||
}
|
||||
}
|
||||
|
||||
impl Type {
|
||||
pub fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String {
|
||||
match self {
|
||||
Type::Primitive(t) => t.to_string(),
|
||||
Type::Array(t) => format!("[{t}]"),
|
||||
Type::Object { properties } => {
|
||||
let mut result = "{".to_owned();
|
||||
for p in properties {
|
||||
result += " ";
|
||||
result += &p.recast(options, indentation_level);
|
||||
result += ",";
|
||||
}
|
||||
|
||||
if result.ends_with(',') {
|
||||
result.pop();
|
||||
result += " ";
|
||||
}
|
||||
result += "}";
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Collect all the kcl files in a directory, recursively.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[async_recursion::async_recursion]
|
||||
@ -1414,6 +1392,21 @@ thing(1)
|
||||
assert_eq!(recasted, some_program_string);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_recast_typed_consts() {
|
||||
let some_program_string = r#"a = 42: number
|
||||
export b = 3.2: number(ft)
|
||||
c = "dsfds": A | B | C
|
||||
d = [1]: [number]
|
||||
e = foo: [number; 3]
|
||||
f = [1, 2, 3]: [number; 1+]
|
||||
"#;
|
||||
let program = crate::parsing::top_level_parse(some_program_string).unwrap();
|
||||
|
||||
let recasted = program.recast(&Default::default(), 0);
|
||||
assert_eq!(recasted, some_program_string);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_recast_object_fn_in_array_weird_bracket() {
|
||||
let some_program_string = r#"bing = { yo = 55 }
|
||||
@ -2438,6 +2431,7 @@ thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#;
|
||||
// A comment
|
||||
@(impl = primitive)
|
||||
export type bar(unit, baz)
|
||||
type baz = Foo | Bar
|
||||
"#;
|
||||
let program = crate::parsing::top_level_parse(some_program_string).unwrap();
|
||||
let recasted = program.recast(&Default::default(), 0);
|
||||
|
Reference in New Issue
Block a user