mirror of
https://github.com/slint-ui/slint.git
synced 2025-07-24 05:26:29 +00:00
Split Expression::CallbackReference and Expresison::FunctionReference
This commit is contained in:
parent
4672e54f5e
commit
dfdbc942f6
14 changed files with 74 additions and 49 deletions
|
@ -346,9 +346,12 @@ pub enum Expression {
|
|||
/// Note: if we are to separate expression and statement, we probably do not need to have callback reference within expressions
|
||||
CallbackReference(NamedReference),
|
||||
|
||||
/// Reference to the callback `<name>` in the `<element>`
|
||||
/// Reference to the property
|
||||
PropertyReference(NamedReference),
|
||||
|
||||
/// Reference to a Function
|
||||
FunctionReference(NamedReference),
|
||||
|
||||
/// Reference to a function built into the run-time, implemented natively
|
||||
BuiltinFunctionReference(BuiltinFunction, Option<SourceLocation>),
|
||||
|
||||
|
@ -516,6 +519,7 @@ impl Expression {
|
|||
Expression::NumberLiteral(_, unit) => unit.ty(),
|
||||
Expression::BoolLiteral(_) => Type::Bool,
|
||||
Expression::CallbackReference(nr) => nr.ty(),
|
||||
Expression::FunctionReference(nr) => nr.ty(),
|
||||
Expression::PropertyReference(nr) => nr.ty(),
|
||||
Expression::BuiltinFunctionReference(funcref, _) => funcref.ty(),
|
||||
Expression::MemberFunction { member, .. } => member.ty(),
|
||||
|
@ -653,6 +657,7 @@ impl Expression {
|
|||
Expression::BoolLiteral(_) => {}
|
||||
Expression::CallbackReference { .. } => {}
|
||||
Expression::PropertyReference { .. } => {}
|
||||
Expression::FunctionReference { .. } => {}
|
||||
Expression::FunctionParameterReference { .. } => {}
|
||||
Expression::BuiltinFunctionReference { .. } => {}
|
||||
Expression::MemberFunction { base, member, .. } => {
|
||||
|
@ -749,6 +754,7 @@ impl Expression {
|
|||
Expression::BoolLiteral(_) => {}
|
||||
Expression::CallbackReference { .. } => {}
|
||||
Expression::PropertyReference { .. } => {}
|
||||
Expression::FunctionReference { .. } => {}
|
||||
Expression::FunctionParameterReference { .. } => {}
|
||||
Expression::BuiltinFunctionReference { .. } => {}
|
||||
Expression::MemberFunction { base, member, .. } => {
|
||||
|
@ -859,6 +865,7 @@ impl Expression {
|
|||
Expression::NumberLiteral(_, _) => true,
|
||||
Expression::BoolLiteral(_) => true,
|
||||
Expression::CallbackReference { .. } => false,
|
||||
Expression::FunctionReference(nr) => nr.is_constant(),
|
||||
Expression::PropertyReference(nr) => nr.is_constant(),
|
||||
Expression::BuiltinFunctionReference(func, _) => func.is_pure(),
|
||||
Expression::MemberFunction { .. } => false,
|
||||
|
@ -1364,6 +1371,7 @@ pub fn pretty_print(f: &mut dyn std::fmt::Write, expression: &Expression) -> std
|
|||
Expression::BoolLiteral(b) => write!(f, "{:?}", b),
|
||||
Expression::CallbackReference(a) => write!(f, "{:?}", a),
|
||||
Expression::PropertyReference(a) => write!(f, "{:?}", a),
|
||||
Expression::FunctionReference(a) => write!(f, "{:?}", a),
|
||||
Expression::BuiltinFunctionReference(a, _) => write!(f, "{:?}", a),
|
||||
Expression::MemberFunction { base, base_node: _, member } => {
|
||||
pretty_print(f, base)?;
|
||||
|
|
|
@ -68,10 +68,9 @@ pub fn lower_expression(
|
|||
llr_Expression::NumberLiteral(unit.normalize(*n))
|
||||
}
|
||||
tree_Expression::BoolLiteral(b) => llr_Expression::BoolLiteral(*b),
|
||||
tree_Expression::CallbackReference(nr) => {
|
||||
llr_Expression::PropertyReference(ctx.map_property_reference(nr))
|
||||
}
|
||||
tree_Expression::PropertyReference(nr) => {
|
||||
tree_Expression::CallbackReference(nr)
|
||||
| tree_Expression::PropertyReference(nr)
|
||||
| tree_Expression::FunctionReference(nr) => {
|
||||
llr_Expression::PropertyReference(ctx.map_property_reference(nr))
|
||||
}
|
||||
tree_Expression::BuiltinFunctionReference(_, _) => panic!(),
|
||||
|
@ -123,17 +122,11 @@ pub fn lower_expression(
|
|||
}
|
||||
tree_Expression::CallbackReference(nr) => {
|
||||
let arguments = arguments.iter().map(|e| lower_expression(e, ctx)).collect::<_>();
|
||||
if matches!(nr.ty(), Type::Function { .. }) {
|
||||
llr_Expression::FunctionCall {
|
||||
function: ctx.map_property_reference(nr),
|
||||
arguments,
|
||||
}
|
||||
} else {
|
||||
llr_Expression::CallBackCall {
|
||||
callback: ctx.map_property_reference(nr),
|
||||
arguments,
|
||||
}
|
||||
}
|
||||
llr_Expression::CallBackCall { callback: ctx.map_property_reference(nr), arguments }
|
||||
}
|
||||
tree_Expression::FunctionReference(nr) => {
|
||||
let arguments = arguments.iter().map(|e| lower_expression(e, ctx)).collect::<_>();
|
||||
llr_Expression::FunctionCall { function: ctx.map_property_reference(nr), arguments }
|
||||
}
|
||||
_ => panic!("not calling a function"),
|
||||
},
|
||||
|
|
|
@ -421,10 +421,10 @@ impl LookupObject for ElementRc {
|
|||
}
|
||||
|
||||
fn expression_from_reference(n: NamedReference, ty: &Type) -> Expression {
|
||||
if matches!(ty, Type::Callback { .. } | Type::Function { .. }) {
|
||||
Expression::CallbackReference(n)
|
||||
} else {
|
||||
Expression::PropertyReference(n)
|
||||
match ty {
|
||||
Type::Callback { .. } => Expression::CallbackReference(n),
|
||||
Type::Function { .. } => Expression::FunctionReference(n),
|
||||
_ => Expression::PropertyReference(n),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1878,7 +1878,9 @@ pub fn visit_named_references_in_expression(
|
|||
) {
|
||||
expr.visit_mut(|sub| visit_named_references_in_expression(sub, vis));
|
||||
match expr {
|
||||
Expression::PropertyReference(r) | Expression::CallbackReference(r) => vis(r),
|
||||
Expression::PropertyReference(r)
|
||||
| Expression::CallbackReference(r)
|
||||
| Expression::FunctionReference(r) => vis(r),
|
||||
Expression::LayoutCacheAccess { layout_cache_prop, .. } => vis(layout_cache_prop),
|
||||
Expression::SolveLayout(l, _) => l.visit_named_references(vis),
|
||||
Expression::ComputeLayoutInfo(l, _) => l.visit_named_references(vis),
|
||||
|
|
|
@ -334,9 +334,9 @@ fn process_property(
|
|||
fn recurse_expression(expr: &Expression, vis: &mut impl FnMut(&PropertyPath)) {
|
||||
expr.visit(|sub| recurse_expression(sub, vis));
|
||||
match expr {
|
||||
Expression::PropertyReference(r) | Expression::CallbackReference(r) => {
|
||||
vis(&r.clone().into())
|
||||
}
|
||||
Expression::PropertyReference(r)
|
||||
| Expression::CallbackReference(r)
|
||||
| Expression::FunctionReference(r) => vis(&r.clone().into()),
|
||||
Expression::LayoutCacheAccess { layout_cache_prop, .. } => {
|
||||
vis(&layout_cache_prop.clone().into())
|
||||
}
|
||||
|
|
|
@ -119,6 +119,7 @@ fn simplify_expression(expr: &mut Expression) -> bool {
|
|||
Expression::CallbackReference { .. } => false,
|
||||
Expression::ElementReference { .. } => false,
|
||||
// FIXME
|
||||
Expression::FunctionReference { .. } => false,
|
||||
Expression::LayoutCacheAccess { .. } => false,
|
||||
Expression::SolveLayout { .. } => false,
|
||||
Expression::ComputeLayoutInfo { .. } => false,
|
||||
|
|
|
@ -215,7 +215,9 @@ fn expression_for_property(element: &ElementRc, name: &str) -> ExpressionForProp
|
|||
// Check that the expresison is valid in the new scope
|
||||
let mut has_invalid = false;
|
||||
e.expression.visit_recursive(&mut |ex| match ex {
|
||||
Expression::CallbackReference(nr) | Expression::PropertyReference(nr) => {
|
||||
Expression::CallbackReference(nr)
|
||||
| Expression::PropertyReference(nr)
|
||||
| Expression::FunctionReference(nr) => {
|
||||
let e = nr.element();
|
||||
if !Rc::ptr_eq(&e, &element)
|
||||
&& Weak::ptr_eq(
|
||||
|
|
|
@ -570,11 +570,15 @@ impl Expression {
|
|||
expression: r @ Expression::CallbackReference(..), ..
|
||||
} => {
|
||||
if let Some(x) = it.next() {
|
||||
if matches!(r.ty(), Type::Function { .. }) {
|
||||
ctx.diag.push_error("Cannot access fields of a function".into(), &x)
|
||||
} else {
|
||||
ctx.diag.push_error("Cannot access fields of callback".into(), &x)
|
||||
}
|
||||
ctx.diag.push_error("Cannot access fields of callback".into(), &x)
|
||||
}
|
||||
r
|
||||
}
|
||||
LookupResult::Expression {
|
||||
expression: r @ Expression::FunctionReference(..), ..
|
||||
} => {
|
||||
if let Some(x) = it.next() {
|
||||
ctx.diag.push_error("Cannot access fields of a function".into(), &x)
|
||||
}
|
||||
r
|
||||
}
|
||||
|
@ -1073,7 +1077,7 @@ fn continue_lookup_within_element(
|
|||
member: Box::new(member),
|
||||
}
|
||||
} else {
|
||||
Expression::CallbackReference(NamedReference::new(elem, &lookup_result.resolved_name))
|
||||
Expression::FunctionReference(NamedReference::new(elem, &lookup_result.resolved_name))
|
||||
}
|
||||
} else {
|
||||
let mut err = |extra: &str| {
|
||||
|
@ -1293,6 +1297,10 @@ pub fn resolve_two_way_binding(
|
|||
Some(n)
|
||||
}
|
||||
}
|
||||
Expression::FunctionReference(..) => {
|
||||
ctx.diag.push_error("Cannot bind to a function".into(), &node);
|
||||
None
|
||||
}
|
||||
_ => {
|
||||
ctx.diag.push_error(
|
||||
"The expression in a two way binding must be a property reference".into(),
|
||||
|
|
|
@ -41,6 +41,10 @@ Xxx := Rectangle {
|
|||
|
||||
Abc { par => {} }
|
||||
// ^error{'par' is not a callback in Abc}
|
||||
aa := Abc { par: 42; }
|
||||
// ^error{Cannot assign to par in Abc because it does not have a valid property type}
|
||||
Abc { par <=> aa.par; }
|
||||
// ^error{Cannot assign to par in Abc because it does not have a valid property type}
|
||||
fooo => {}
|
||||
// ^error{'fooo' is not a callback in Rectangle}
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@ Xxx := Rectangle {
|
|||
|
||||
root.foo.hello(45);
|
||||
// ^error{Cannot access fields of a function}
|
||||
|
||||
|
||||
}
|
||||
|
||||
callback xx <=> foo;
|
||||
// ^error{Cannot bind to a function}
|
||||
}
|
||||
|
|
|
@ -142,6 +142,7 @@ pub fn eval_expression(expression: &Expression, local_context: &mut EvalLocalCon
|
|||
Expression::NumberLiteral(n, unit) => Value::Number(unit.normalize(*n)),
|
||||
Expression::BoolLiteral(b) => Value::Bool(*b),
|
||||
Expression::CallbackReference { .. } => panic!("callback in expression"),
|
||||
Expression::FunctionReference { .. } => panic!("function in expression"),
|
||||
Expression::BuiltinFunctionReference(..) => panic!(
|
||||
"naked builtin function reference not allowed, should be handled by function call"
|
||||
),
|
||||
|
@ -211,22 +212,22 @@ pub fn eval_expression(expression: &Expression, local_context: &mut EvalLocalCon
|
|||
v
|
||||
}
|
||||
Expression::FunctionCall { function, arguments, source_location: _ } => match &**function {
|
||||
Expression::FunctionReference(nr) => {
|
||||
let args = arguments.iter().map(|e| eval_expression(e, local_context)).collect::<Vec<_>>();
|
||||
generativity::make_guard!(guard);
|
||||
match enclosing_component_instance_for_element(&nr.element(), local_context.component_instance, guard) {
|
||||
ComponentInstance::InstanceRef(c) => {
|
||||
let mut ctx = EvalLocalContext::from_function_arguments(c, args);
|
||||
eval_expression(&nr.element().borrow().bindings.get(nr.name()).unwrap().borrow().expression, &mut ctx)
|
||||
}
|
||||
ComponentInstance::GlobalComponent(g) => {
|
||||
g.as_ref().eval_function(nr.name(), args).unwrap()
|
||||
},
|
||||
}
|
||||
}
|
||||
Expression::CallbackReference(nr) => {
|
||||
let args = arguments.iter().map(|e| eval_expression(e, local_context)).collect::<Vec<_>>();
|
||||
if matches!(nr.ty(), Type::Function { .. }) {
|
||||
generativity::make_guard!(guard);
|
||||
match enclosing_component_instance_for_element(&nr.element(), local_context.component_instance, guard) {
|
||||
ComponentInstance::InstanceRef(c) => {
|
||||
let mut ctx = EvalLocalContext::from_function_arguments(c, args);
|
||||
eval_expression(&nr.element().borrow().bindings.get(nr.name()).unwrap().borrow().expression, &mut ctx)
|
||||
}
|
||||
ComponentInstance::GlobalComponent(g) => {
|
||||
g.as_ref().eval_function(nr.name(), args).unwrap()
|
||||
},
|
||||
}
|
||||
} else {
|
||||
invoke_callback(local_context.component_instance, &nr.element(), nr.name(), &args).unwrap()
|
||||
}
|
||||
invoke_callback(local_context.component_instance, &nr.element(), nr.name(), &args).unwrap()
|
||||
}
|
||||
Expression::BuiltinFunctionReference(f, _) => call_builtin_function(*f, arguments, local_context),
|
||||
_ => panic!("call of something not a callback: {function:?}"),
|
||||
|
|
|
@ -454,6 +454,7 @@ fn completion_item_from_expression(str: &str, lookup_result: LookupResult) -> Co
|
|||
c.kind = match expression {
|
||||
Expression::BoolLiteral(_) => Some(CompletionItemKind::CONSTANT),
|
||||
Expression::CallbackReference(_) => Some(CompletionItemKind::METHOD),
|
||||
Expression::FunctionReference(_) => Some(CompletionItemKind::FUNCTION),
|
||||
Expression::PropertyReference(_) => Some(CompletionItemKind::PROPERTY),
|
||||
Expression::BuiltinFunctionReference(..) => Some(CompletionItemKind::FUNCTION),
|
||||
Expression::BuiltinMacroReference(..) => Some(CompletionItemKind::FUNCTION),
|
||||
|
|
|
@ -71,7 +71,9 @@ pub fn goto_definition(
|
|||
} => e.upgrade()?.borrow().node.clone()?.into(),
|
||||
LookupResult::Expression {
|
||||
expression:
|
||||
Expression::CallbackReference(nr) | Expression::PropertyReference(nr),
|
||||
Expression::CallbackReference(nr)
|
||||
| Expression::PropertyReference(nr)
|
||||
| Expression::FunctionReference(nr),
|
||||
..
|
||||
} => {
|
||||
let mut el = nr.element();
|
||||
|
|
|
@ -125,7 +125,10 @@ fn fully_qualify_property_access(
|
|||
let global_lookup = i_slint_compiler::lookup::global_lookup();
|
||||
match global_lookup.lookup(ctx, &first_str) {
|
||||
Some(LookupResult::Expression {
|
||||
expression: Expression::PropertyReference(nr) | Expression::CallbackReference(nr),
|
||||
expression:
|
||||
Expression::PropertyReference(nr)
|
||||
| Expression::CallbackReference(nr)
|
||||
| Expression::FunctionReference(nr),
|
||||
..
|
||||
}) => {
|
||||
if let Some(new_name) = state.lookup_change.property_mappings.get(&nr) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue