diff --git a/api/sixtyfps-node/native/lib.rs b/api/sixtyfps-node/native/lib.rs index b802395d3..64b56b19e 100644 --- a/api/sixtyfps-node/native/lib.rs +++ b/api/sixtyfps-node/native/lib.rs @@ -156,33 +156,46 @@ fn to_eval_value<'cx>( ) -> NeonResult { use sixtyfps_interpreter::Value; match ty { - Type::Float32 | Type::Int32 | Type::Duration | Type::Length | Type::LogicalLength | Type::Percent => { - Ok(Value::Number(val.downcast_or_throw::(cx)?.value())) - } + Type::Float32 + | Type::Int32 + | Type::Duration + | Type::Length + | Type::LogicalLength + | Type::Percent => Ok(Value::Number(val.downcast_or_throw::(cx)?.value())), Type::String => Ok(Value::String(val.to_string(cx)?.value().into())), Type::Color => { - let c = val.to_string(cx)?.value().parse::().or_else(|e| cx.throw_error(&e.to_string()))?; - Ok(Value::Color(sixtyfps_corelib::Color::from_argb_u8((c.a * 255.) as u8, c.r, c.g, c.b))) + let c = val + .to_string(cx)? + .value() + .parse::() + .or_else(|e| cx.throw_error(&e.to_string()))?; + Ok(Value::Color(sixtyfps_corelib::Color::from_argb_u8( + (c.a * 255.) as u8, + c.r, + c.g, + c.b, + ))) } - Type::Array(a) => { - match val.downcast::() { - Ok(arr) => { - let vec = arr.to_vec(cx)?; - Ok(Value::Array(vec.into_iter().map(|i| to_eval_value(i, (*a).clone(), cx, persistent_context)).collect::, _>>()?)) - } - Err(_) => { - let obj = val.downcast_or_throw::(cx)?; - obj.get(cx, "rowCount")?.downcast_or_throw::(cx)?; - obj.get(cx, "rowData")?.downcast_or_throw::(cx)?; - let m = js_model::JsModel::new(obj, *a, cx, persistent_context)?; - Ok(Value::Model(sixtyfps_interpreter::ModelPtr(m))) - } + Type::Array(a) => match val.downcast::() { + Ok(arr) => { + let vec = arr.to_vec(cx)?; + Ok(Value::Array( + vec.into_iter() + .map(|i| to_eval_value(i, (*a).clone(), cx, persistent_context)) + .collect::, _>>()?, + )) + } + Err(_) => { + let obj = val.downcast_or_throw::(cx)?; + obj.get(cx, "rowCount")?.downcast_or_throw::(cx)?; + obj.get(cx, "rowData")?.downcast_or_throw::(cx)?; + let m = js_model::JsModel::new(obj, *a, cx, persistent_context)?; + Ok(Value::Model(sixtyfps_interpreter::ModelPtr(m))) } - }, Type::Resource => Ok(Value::String(val.to_string(cx)?.value().into())), Type::Bool => Ok(Value::Bool(val.downcast_or_throw::(cx)?.value())), - Type::Object{fields, ..} => { + Type::Object { fields, .. } => { let obj = val.downcast_or_throw::(cx)?; Ok(Value::Object( fields @@ -194,28 +207,7 @@ fn to_eval_value<'cx>( obj.get(cx, pro_name.as_str())?, pro_ty.clone(), cx, - persistent_context - )?, - )) - }) - .collect::>()?, - )) - } - Type::Component(c) if c.root_element.borrow().base_type == Type::Void => { - let obj = val.downcast_or_throw::(cx)?; - Ok(Value::Object( - c.root_element - .borrow() - .property_declarations - .iter() - .map(|(pro_name, pro_decl)| { - Ok(( - pro_name.clone(), - to_eval_value( - obj.get(cx, pro_name.as_str())?, - pro_decl.property_type.clone(), - cx, - persistent_context + persistent_context, )?, )) }) @@ -232,7 +224,7 @@ fn to_eval_value<'cx>( | Type::Model | Type::Signal { .. } | Type::Easing - | Type::Component(_) // The struct case is handled before + | Type::Component(_) | Type::PathElements | Type::ElementReference => cx.throw_error("Cannot convert to a Sixtyfps property value"), } diff --git a/sixtyfps_compiler/generator/cpp.rs b/sixtyfps_compiler/generator/cpp.rs index c28fe880c..5193dafd7 100644 --- a/sixtyfps_compiler/generator/cpp.rs +++ b/sixtyfps_compiler/generator/cpp.rs @@ -220,9 +220,6 @@ impl CppType for Type { Type::Resource => Some("sixtyfps::Resource".to_owned()), Type::Builtin(elem) => elem.native_class.cpp_type.clone(), Type::Enumeration(enumeration) => Some(format!("sixtyfps::{}", enumeration.name)), - Type::Component(c) if c.root_element.borrow().base_type == Type::Void => { - Some(c.id.clone()) - } _ => None, } } @@ -1202,9 +1199,6 @@ fn compile_expression(e: &crate::expression_tree::Expression, component: &Rc { format!("{}.{}", compile_expression(base, component), name) } - Type::Component(c) if c.root_element.borrow().base_type == Type::Void => { - format!("{}.{}", compile_expression(base, component), name) - } _ => panic!("Expression::ObjectAccess's base expression is not an Object type"), }, Expression::Cast { from, to } => { @@ -1220,19 +1214,6 @@ fn compile_expression(e: &crate::expression_tree::Expression, component: &Rc { format!("sixtyfps::Color::from_argb_encoded({})", f) } - (Type::Object { .. }, Type::Component(c)) - if c.root_element.borrow().base_type == Type::Void => - { - format!( - "[&](const auto &o){{ {struct_name} s; auto& [{field_members}] = s; {fields}; return s; }}({obj})", - struct_name = component_id(c), - field_members = (0..c.root_element.borrow().property_declarations.len()).map(|idx| format!("f_{}", idx)).join(", "), - obj = f, - fields = (0..c.root_element.borrow().property_declarations.len()) - .map(|idx| format!("f_{} = std::get<{}>(o)", idx, idx)) - .join("; ") - ) - } (Type::Object { .. }, Type::Object{ fields, name: Some(n)}) => { format!( "[&](const auto &o){{ {struct_name} s; auto& [{field_members}] = s; {fields}; return s; }}({obj})", @@ -1404,9 +1385,6 @@ fn compile_assignment( format!("std::get<{}>({})", index, tmpobj) } Type::Object { .. } => format!("{}.{}", tmpobj, name), - Type::Component(c) if c.root_element.borrow().base_type == Type::Void => { - format!("{}.{}", tmpobj, name) - } _ => panic!("Expression::ObjectAccess's base expression is not an Object type"), }; let op = if op == '=' { ' ' } else { op }; diff --git a/sixtyfps_compiler/generator/rust.rs b/sixtyfps_compiler/generator/rust.rs index 9942475d1..c568e8c76 100644 --- a/sixtyfps_compiler/generator/rust.rs +++ b/sixtyfps_compiler/generator/rust.rs @@ -47,9 +47,6 @@ fn rust_type( let inner = rust_type(&o, span)?; Ok(quote!(sixtyfps::re_exports::ModelHandle<#inner>)) } - Type::Component(c) if c.root_element.borrow().base_type == Type::Void => { - Ok(c.id.parse().unwrap()) - } _ => Err(CompilerDiagnostic { message: format!("Cannot map property type {} to Rust", ty), span: span.clone(), @@ -1049,11 +1046,6 @@ fn compile_expression(e: &Expression, component: &Rc) -> TokenStream let base_e = compile_expression(base, component); quote!((#base_e).#name) } - Type::Component(c) if c.root_element.borrow().base_type == Type::Void => { - let base_e = compile_expression(base, component); - let name = format_ident!("{}", name); - quote!((#base_e).#name) - } _ => panic!("Expression::ObjectAccess's base expression is not an Object type"), }, Expression::CodeBlock(sub) => { @@ -1262,15 +1254,10 @@ fn compile_assignment( let index = proc_macro2::Literal::usize_unsuffixed(index); (quote!(#index), fields[name].clone()) } - Type::Object { fields, name: Some(_) } => { let n = format_ident!("{}", name); (quote!(#n), fields[name].clone()) } - Type::Component(c) if c.root_element.borrow().base_type == Type::Void => { - let n = format_ident!("{}", name); - (quote!(#n), c.root_element.borrow().lookup_property(name)) - } _ => panic!("Expression::ObjectAccess's base expression is not an Object type"), }; diff --git a/sixtyfps_compiler/langtype.rs b/sixtyfps_compiler/langtype.rs index c82dacade..9e5e5e6e3 100644 --- a/sixtyfps_compiler/langtype.rs +++ b/sixtyfps_compiler/langtype.rs @@ -20,7 +20,7 @@ pub enum Type { Invalid, /// The type of an expression that return nothing Void, - Component(Rc), + Component(Rc), Builtin(Rc), Native(Rc), @@ -185,7 +185,6 @@ impl Type { | Self::ElementReference | Self::Object { .. } | Self::Array(_) => true, - Self::Component(c) => c.root_element.borrow().base_type == Type::Void, _ => false, } } @@ -273,7 +272,7 @@ impl Type { } /// Assime it is a Component, panic if it isn't - pub fn as_component(&self) -> &Rc { + pub fn as_component(&self) -> &Rc { match self { Type::Component(c) => c, _ => panic!("should be a component because of the repeater_component pass"), @@ -300,19 +299,6 @@ impl Type { } true }; - let can_convert_object_to_component = |a: &BTreeMap, c: &Component| { - let root_element = c.root_element.borrow(); - if root_element.base_type != Type::Void { - //component is not a struct - return false; - } - for (k, v) in &root_element.property_declarations { - if !a.get(k).map_or(false, |t| t.can_convert(&v.property_type)) { - return false; - } - } - true - }; match (self, other) { (a, b) if a == b => true, @@ -328,15 +314,8 @@ impl Type { | (Type::Length, Type::LogicalLength) | (Type::LogicalLength, Type::Length) | (Type::Percent, Type::Float32) => true, - (Type::Object { fields: a, .. }, Type::Object { fields: b, .. }) - if can_convert_object(a, b) => - { - true - } - (Type::Object { fields, .. }, Type::Component(c)) - if can_convert_object_to_component(fields, c) => - { - true + (Type::Object { fields: a, .. }, Type::Object { fields: b, .. }) => { + can_convert_object(a, b) } _ => false, } diff --git a/sixtyfps_compiler/typeregister.rs b/sixtyfps_compiler/typeregister.rs index 0084fa9dc..019b8403d 100644 --- a/sixtyfps_compiler/typeregister.rs +++ b/sixtyfps_compiler/typeregister.rs @@ -12,7 +12,7 @@ use std::{cell::RefCell, rc::Rc}; use crate::expression_tree::{BuiltinFunction, Expression, Unit}; use crate::langtype::{BuiltinElement, Enumeration, NativeClass, Type}; -use crate::object_tree::{Component, Element}; +use crate::object_tree::Component; /// reserved property injected in every item pub fn reserved_property(name: &str) -> Type { @@ -390,18 +390,10 @@ impl TypeRegister { .for_each(|ty| ty.collect_contextual_types(&mut context_restricted_types)); register.context_restricted_types = context_restricted_types; - let standard_listview_item = Type::Component(Rc::new(Component { - id: "sixtyfps::StandardListViewItem".into(), - root_element: Rc::new(RefCell::new(Element { - base_type: Type::Void, - property_declarations: [("text".to_owned(), Type::String.into())] - .iter() - .cloned() - .collect(), - ..Element::default() - })), - ..Component::default() - })); + let standard_listview_item = Type::Object { + name: Some("sixtyfps::StandardListViewItem".into()), + fields: [("text".to_owned(), Type::String.into())].iter().cloned().collect(), + }; register.types.insert("StandardListViewItem".into(), standard_listview_item.clone()); // FIXME: should this be auto generated or placed somewhere else @@ -588,11 +580,11 @@ impl TypeRegister { self.lookup(qualified[0].as_ref()) } - pub fn add(&mut self, comp: Rc) { + pub fn add(&mut self, comp: Rc) { self.add_with_name(comp.id.clone(), comp); } - pub fn add_with_name(&mut self, name: String, comp: Rc) { + pub fn add_with_name(&mut self, name: String, comp: Rc) { self.types.insert(name, Type::Component(comp)); } diff --git a/sixtyfps_runtime/interpreter/dynamic_component.rs b/sixtyfps_runtime/interpreter/dynamic_component.rs index 1db1565a1..c28015897 100644 --- a/sixtyfps_runtime/interpreter/dynamic_component.rs +++ b/sixtyfps_runtime/interpreter/dynamic_component.rs @@ -601,9 +601,6 @@ fn generate_component<'id>( } Type::Object { .. } => property_info::(), Type::Array(_) => property_info::(), - Type::Component(ref c) if c.root_element.borrow().base_type == Type::Void => { - property_info::() - } Type::Percent => property_info::(), _ => panic!("bad type"), };