mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 18:58:36 +00:00
Merge the Callback and Function type
There is no need for two of these
This simplify some code
Amend efdecf0a13
This commit is contained in:
parent
dff19c52da
commit
6bb0e6038f
15 changed files with 72 additions and 135 deletions
|
@ -160,18 +160,13 @@ impl JsComponentInstance {
|
|||
}
|
||||
};
|
||||
|
||||
if let Some(return_type) = &return_type {
|
||||
if let Ok(value) = super::to_value(&env, result, return_type) {
|
||||
return value;
|
||||
} else {
|
||||
eprintln!(
|
||||
"Node.js: cannot convert return type of callback {}",
|
||||
callback_name
|
||||
);
|
||||
return slint_interpreter::default_value_for_type(return_type);
|
||||
}
|
||||
} else {
|
||||
if matches!(return_type, Type::Void) {
|
||||
Value::Void
|
||||
} else if let Ok(value) = super::to_value(&env, result, &return_type) {
|
||||
return value;
|
||||
} else {
|
||||
eprintln!("Node.js: cannot convert return type of callback {callback_name}");
|
||||
return slint_interpreter::default_value_for_type(&return_type);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -237,18 +232,13 @@ impl JsComponentInstance {
|
|||
}
|
||||
};
|
||||
|
||||
if let Some(return_type) = &return_type {
|
||||
if let Ok(value) = super::to_value(&env, result, return_type) {
|
||||
return value;
|
||||
} else {
|
||||
eprintln!(
|
||||
"Node.js: cannot convert return type of callback {}",
|
||||
callback_name
|
||||
);
|
||||
return slint_interpreter::default_value_for_type(return_type);
|
||||
}
|
||||
} else {
|
||||
if matches!(return_type, Type::Void) {
|
||||
Value::Void
|
||||
} else if let Ok(value) = super::to_value(&env, result, &return_type) {
|
||||
return value;
|
||||
} else {
|
||||
eprintln!("Node.js: cannot convert return type of callback {callback_name}");
|
||||
return slint_interpreter::default_value_for_type(&return_type);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -306,10 +296,7 @@ impl JsComponentInstance {
|
|||
})?;
|
||||
|
||||
let args = match ty {
|
||||
Type::Callback(callback) => {
|
||||
Self::invoke_args(env, &callback_name, arguments, &callback.args)?
|
||||
}
|
||||
Type::Function(function) => {
|
||||
Type::Callback(function) | Type::Function(function) => {
|
||||
Self::invoke_args(env, &callback_name, arguments, &function.args)?
|
||||
}
|
||||
_ => {
|
||||
|
@ -352,10 +339,7 @@ impl JsComponentInstance {
|
|||
})?;
|
||||
|
||||
let args = match ty {
|
||||
Type::Callback(callback) => {
|
||||
Self::invoke_args(env, &callback_name, arguments, &callback.args)?
|
||||
}
|
||||
Type::Function(function) => {
|
||||
Type::Callback(function) | Type::Function(function) => {
|
||||
Self::invoke_args(env, &callback_name, arguments, &function.args)?
|
||||
}
|
||||
_ => {
|
||||
|
|
|
@ -706,10 +706,7 @@ impl Expression {
|
|||
Expression::Cast { to, .. } => to.clone(),
|
||||
Expression::CodeBlock(sub) => sub.last().map_or(Type::Void, |e| e.ty()),
|
||||
Expression::FunctionCall { function, .. } => match function.ty() {
|
||||
Type::Function(function) => function.return_type.clone(),
|
||||
Type::Callback(callback) => {
|
||||
callback.return_type.as_ref().unwrap_or(&Type::Void).clone()
|
||||
}
|
||||
Type::Function(f) | Type::Callback(f) => f.return_type.clone(),
|
||||
_ => Type::Invalid,
|
||||
},
|
||||
Expression::SelfAssignment { .. } => Type::Void,
|
||||
|
|
|
@ -626,7 +626,7 @@ fn handle_property_init(
|
|||
code = return_compile_expression(
|
||||
&binding_expression.expression.borrow(),
|
||||
&ctx2,
|
||||
callback.return_type.as_ref()
|
||||
Some(&callback.return_type)
|
||||
)
|
||||
));
|
||||
} else {
|
||||
|
@ -1861,10 +1861,7 @@ fn generate_sub_component(
|
|||
let ty = if let Type::Callback(callback) = &property.ty {
|
||||
let param_types =
|
||||
callback.args.iter().map(|t| t.cpp_type().unwrap()).collect::<Vec<_>>();
|
||||
let return_type = callback
|
||||
.return_type
|
||||
.as_ref()
|
||||
.map_or(SmolStr::new_static("void"), |t| t.cpp_type().unwrap());
|
||||
let return_type = callback.return_type.cpp_type().unwrap();
|
||||
format_smolstr!(
|
||||
"slint::private_api::Callback<{}({})>",
|
||||
return_type,
|
||||
|
@ -2503,13 +2500,9 @@ fn generate_global(
|
|||
let ty = if let Type::Callback(callback) = &property.ty {
|
||||
let param_types =
|
||||
callback.args.iter().map(|t| t.cpp_type().unwrap()).collect::<Vec<_>>();
|
||||
let return_type = callback
|
||||
.return_type
|
||||
.as_ref()
|
||||
.map_or(SmolStr::new_static("void"), |t| t.cpp_type().unwrap());
|
||||
format_smolstr!(
|
||||
"slint::private_api::Callback<{}({})>",
|
||||
return_type,
|
||||
callback.return_type.cpp_type().unwrap(),
|
||||
param_types.join(", ")
|
||||
)
|
||||
} else {
|
||||
|
@ -2640,8 +2633,6 @@ fn generate_public_api_for_properties(
|
|||
if let Type::Callback(callback) = &p.ty {
|
||||
let param_types =
|
||||
callback.args.iter().map(|t| t.cpp_type().unwrap()).collect::<Vec<_>>();
|
||||
let return_type =
|
||||
callback.return_type.as_ref().map_or("void".into(), |t| t.cpp_type().unwrap());
|
||||
let callback_emitter = vec![
|
||||
"[[maybe_unused]] auto self = this;".into(),
|
||||
format!(
|
||||
|
@ -2661,7 +2652,7 @@ fn generate_public_api_for_properties(
|
|||
.enumerate()
|
||||
.map(|(i, ty)| format!("{} arg_{}", ty, i))
|
||||
.join(", "),
|
||||
return_type
|
||||
callback.return_type.cpp_type().unwrap()
|
||||
),
|
||||
statements: Some(callback_emitter),
|
||||
..Default::default()
|
||||
|
|
|
@ -466,11 +466,7 @@ fn handle_property_init(
|
|||
ctx2.argument_types = &callback.args;
|
||||
let tokens_for_expression =
|
||||
compile_expression(&binding_expression.expression.borrow(), &ctx2);
|
||||
let as_ = if callback.return_type.as_ref().map_or(true, |t| matches!(t, Type::Void)) {
|
||||
quote!(;)
|
||||
} else {
|
||||
quote!(as _)
|
||||
};
|
||||
let as_ = if matches!(callback.return_type, Type::Void) { quote!(;) } else { quote!(as _) };
|
||||
init.push(quote!({
|
||||
#[allow(unreachable_code, unused)]
|
||||
slint::private_unstable_api::set_callback_handler(#rust_property, &self_rc, {
|
||||
|
@ -553,10 +549,7 @@ fn public_api(
|
|||
if let Type::Callback(callback) = &p.ty {
|
||||
let callback_args =
|
||||
callback.args.iter().map(|a| rust_primitive_type(a).unwrap()).collect::<Vec<_>>();
|
||||
let return_type = callback
|
||||
.return_type
|
||||
.as_ref()
|
||||
.map_or(quote!(()), |a| rust_primitive_type(a).unwrap());
|
||||
let return_type = rust_primitive_type(&callback.return_type).unwrap();
|
||||
let args_name =
|
||||
(0..callback.args.len()).map(|i| format_ident!("arg_{}", i)).collect::<Vec<_>>();
|
||||
let caller_ident = format_ident!("invoke_{}", prop_ident);
|
||||
|
@ -684,10 +677,7 @@ fn generate_sub_component(
|
|||
if let Type::Callback(callback) = &property.ty {
|
||||
let callback_args =
|
||||
callback.args.iter().map(|a| rust_primitive_type(a).unwrap()).collect::<Vec<_>>();
|
||||
let return_type = callback
|
||||
.return_type
|
||||
.as_ref()
|
||||
.map_or(quote!(()), |a| rust_primitive_type(a).unwrap());
|
||||
let return_type = rust_primitive_type(&callback.return_type).unwrap();
|
||||
declared_callbacks.push(prop_ident.clone());
|
||||
declared_callbacks_types.push(callback_args);
|
||||
declared_callbacks_ret.push(return_type);
|
||||
|
@ -1312,10 +1302,7 @@ fn generate_global(global: &llr::GlobalComponent, root: &llr::CompilationUnit) -
|
|||
if let Type::Callback(callback) = &property.ty {
|
||||
let callback_args =
|
||||
callback.args.iter().map(|a| rust_primitive_type(a).unwrap()).collect::<Vec<_>>();
|
||||
let return_type = callback
|
||||
.return_type
|
||||
.as_ref()
|
||||
.map_or(quote!(()), |a| rust_primitive_type(a).unwrap());
|
||||
let return_type = rust_primitive_type(&callback.return_type);
|
||||
declared_callbacks.push(prop_ident.clone());
|
||||
declared_callbacks_types.push(callback_args);
|
||||
declared_callbacks_ret.push(return_type);
|
||||
|
|
|
@ -27,7 +27,7 @@ pub enum Type {
|
|||
/// The type of a callback alias whose type was not yet inferred
|
||||
InferredCallback,
|
||||
|
||||
Callback(Rc<Callback>),
|
||||
Callback(Rc<Function>),
|
||||
Function(Rc<Function>),
|
||||
|
||||
ComponentFactory,
|
||||
|
@ -127,9 +127,7 @@ impl Display for Type {
|
|||
}
|
||||
write!(f, ")")?
|
||||
}
|
||||
if let Some(rt) = &callback.return_type {
|
||||
write!(f, "-> {}", rt)?;
|
||||
}
|
||||
write!(f, "-> {}", callback.return_type)?;
|
||||
Ok(())
|
||||
}
|
||||
Type::ComponentFactory => write!(f, "component-factory"),
|
||||
|
@ -782,12 +780,6 @@ impl<'a> PropertyLookupResult<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Callback {
|
||||
pub return_type: Option<Type>,
|
||||
pub args: Vec<Type>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Function {
|
||||
pub return_type: Type,
|
||||
|
|
|
@ -273,7 +273,7 @@ impl Expression {
|
|||
},
|
||||
Self::CallBackCall { callback, .. } => {
|
||||
if let Type::Callback(callback) = ctx.property_ty(callback) {
|
||||
callback.return_type.as_ref().unwrap_or(&Type::Void).clone()
|
||||
callback.return_type.clone()
|
||||
} else {
|
||||
Type::Invalid
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@ use std::rc::Rc;
|
|||
|
||||
use crate::expression_tree::{BuiltinFunction, Expression};
|
||||
use crate::langtype::{
|
||||
BuiltinElement, BuiltinPropertyDefault, BuiltinPropertyInfo, Callback, DefaultSizeBinding,
|
||||
ElementType, NativeClass, Type,
|
||||
BuiltinElement, BuiltinPropertyDefault, BuiltinPropertyInfo, DefaultSizeBinding, ElementType,
|
||||
Function, NativeClass, Type,
|
||||
};
|
||||
use crate::object_tree::{self, *};
|
||||
use crate::parser::{identifier_text, syntax_nodes, SyntaxKind, SyntaxNode};
|
||||
|
@ -103,7 +103,7 @@ pub(crate) fn load_builtins(register: &mut TypeRegister) {
|
|||
.chain(e.CallbackDeclaration().map(|s| {
|
||||
(
|
||||
identifier_text(&s.DeclaredIdentifier()).unwrap(),
|
||||
BuiltinPropertyInfo::new(Type::Callback(Rc::new(Callback{
|
||||
BuiltinPropertyInfo::new(Type::Callback(Rc::new(Function{
|
||||
args: s
|
||||
.CallbackDeclarationParameter()
|
||||
.map(|a| {
|
||||
|
@ -116,7 +116,7 @@ pub(crate) fn load_builtins(register: &mut TypeRegister) {
|
|||
*diag.borrow_mut(),
|
||||
register,
|
||||
)
|
||||
}),
|
||||
}).unwrap_or(Type::Void),
|
||||
}))),
|
||||
)
|
||||
}))
|
||||
|
|
|
@ -65,8 +65,7 @@ impl<'a> LookupCtx<'a> {
|
|||
|
||||
pub fn return_type(&self) -> &Type {
|
||||
match &self.property_type {
|
||||
Type::Callback(callback) => callback.return_type.as_ref().unwrap_or(&Type::Void),
|
||||
Type::Function(function) => &function.return_type,
|
||||
Type::Callback(f) | Type::Function(f) => &f.return_type,
|
||||
_ => &self.property_type,
|
||||
}
|
||||
}
|
||||
|
@ -194,8 +193,7 @@ impl LookupObject for ArgumentsLookup {
|
|||
f: &mut impl FnMut(&str, LookupResult) -> Option<R>,
|
||||
) -> Option<R> {
|
||||
let args = match &ctx.property_type {
|
||||
Type::Callback(callback) => &callback.args,
|
||||
Type::Function(function) => &function.args,
|
||||
Type::Callback(f) | Type::Function(f) => &f.args,
|
||||
_ => return None,
|
||||
};
|
||||
for (index, (name, ty)) in ctx.arguments.iter().zip(args.iter()).enumerate() {
|
||||
|
|
|
@ -9,10 +9,9 @@
|
|||
|
||||
use crate::diagnostics::{BuildDiagnostics, SourceLocation, Spanned};
|
||||
use crate::expression_tree::{self, BindingExpression, Expression, Unit};
|
||||
use crate::langtype::EnumerationValue;
|
||||
use crate::langtype::{
|
||||
BuiltinElement, BuiltinPropertyDefault, Callback, Enumeration, Function, NativeClass, Struct,
|
||||
Type,
|
||||
BuiltinElement, BuiltinPropertyDefault, Enumeration, EnumerationValue, Function, NativeClass,
|
||||
Struct, Type,
|
||||
};
|
||||
use crate::langtype::{ElementType, PropertyLookupResult};
|
||||
use crate::layout::{LayoutConstraints, Orientation};
|
||||
|
@ -1156,12 +1155,14 @@ impl Element {
|
|||
}
|
||||
type_from_node(p.Type(), diag, tr)})
|
||||
.collect();
|
||||
let return_type =
|
||||
sig_decl.ReturnType().map(|ret_ty| type_from_node(ret_ty.Type(), diag, tr));
|
||||
let return_type = sig_decl
|
||||
.ReturnType()
|
||||
.map(|ret_ty| type_from_node(ret_ty.Type(), diag, tr))
|
||||
.unwrap_or(Type::Void);
|
||||
r.property_declarations.insert(
|
||||
name,
|
||||
PropertyDeclaration {
|
||||
property_type: Type::Callback(Rc::new(Callback { return_type, args })),
|
||||
property_type: Type::Callback(Rc::new(Function { return_type, args })),
|
||||
node: Some(sig_decl.into()),
|
||||
visibility: PropertyVisibility::InOut,
|
||||
pure,
|
||||
|
|
|
@ -91,15 +91,7 @@ fn visit_declared_type(ty: &Type, visitor: &mut impl FnMut(&SmolStr, &Type)) {
|
|||
}
|
||||
}
|
||||
Type::Array(x) => visit_declared_type(x, visitor),
|
||||
Type::Callback(callback) => {
|
||||
if let Some(rt) = &callback.return_type {
|
||||
visit_declared_type(rt, visitor);
|
||||
}
|
||||
for a in &callback.args {
|
||||
visit_declared_type(a, visitor);
|
||||
}
|
||||
}
|
||||
Type::Function(function) => {
|
||||
Type::Function(function) | Type::Callback(function) => {
|
||||
visit_declared_type(&function.return_type, visitor);
|
||||
for a in &function.args {
|
||||
visit_declared_type(a, visitor);
|
||||
|
|
|
@ -943,30 +943,26 @@ impl Expression {
|
|||
};
|
||||
arguments.extend(sub_expr);
|
||||
|
||||
let mut handle_args = |arguments: Vec<(Expression, Option<NodeOrToken>)>,
|
||||
args: &Vec<Type>| {
|
||||
if arguments.len() != args.len() {
|
||||
ctx.diag.push_error(
|
||||
format!(
|
||||
"The callback or function expects {} arguments, but {} are provided",
|
||||
args.len() - adjust_arg_count,
|
||||
arguments.len() - adjust_arg_count,
|
||||
),
|
||||
&node,
|
||||
);
|
||||
arguments.into_iter().map(|x| x.0).collect()
|
||||
} else {
|
||||
arguments
|
||||
.into_iter()
|
||||
.zip(args.iter())
|
||||
.map(|((e, node), ty)| e.maybe_convert_to(ty.clone(), &node, ctx.diag))
|
||||
.collect()
|
||||
}
|
||||
};
|
||||
|
||||
let arguments = match function.ty() {
|
||||
Type::Function(function) => handle_args(arguments, &function.args),
|
||||
Type::Callback(callback) => handle_args(arguments, &callback.args),
|
||||
Type::Function(function) | Type::Callback(function) => {
|
||||
if arguments.len() != function.args.len() {
|
||||
ctx.diag.push_error(
|
||||
format!(
|
||||
"The callback or function expects {} arguments, but {} are provided",
|
||||
function.args.len() - adjust_arg_count,
|
||||
arguments.len() - adjust_arg_count,
|
||||
),
|
||||
&node,
|
||||
);
|
||||
arguments.into_iter().map(|x| x.0).collect()
|
||||
} else {
|
||||
arguments
|
||||
.into_iter()
|
||||
.zip(function.args.iter())
|
||||
.map(|((e, node), ty)| e.maybe_convert_to(ty.clone(), &node, ctx.diag))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
Type::Invalid => {
|
||||
debug_assert!(ctx.diag.has_errors());
|
||||
arguments.into_iter().map(|x| x.0).collect()
|
||||
|
|
|
@ -10,8 +10,8 @@ use std::rc::Rc;
|
|||
|
||||
use crate::expression_tree::BuiltinFunction;
|
||||
use crate::langtype::{
|
||||
BuiltinElement, BuiltinPropertyDefault, BuiltinPropertyInfo, Callback, ElementType,
|
||||
Enumeration, PropertyLookupResult, Struct, Type,
|
||||
BuiltinElement, BuiltinPropertyDefault, BuiltinPropertyInfo, ElementType, Enumeration,
|
||||
Function, PropertyLookupResult, Struct, Type,
|
||||
};
|
||||
use crate::object_tree::{Component, PropertyVisibility};
|
||||
use crate::typeloader;
|
||||
|
@ -128,12 +128,12 @@ impl BuiltinTypes {
|
|||
node: None,
|
||||
rust_attributes: None,
|
||||
})),
|
||||
noarg_callback_type: Type::Callback(Rc::new(Callback {
|
||||
return_type: None,
|
||||
noarg_callback_type: Type::Callback(Rc::new(Function {
|
||||
return_type: Type::Void,
|
||||
args: vec![],
|
||||
})),
|
||||
strarg_callback_type: Type::Callback(Rc::new(Callback {
|
||||
return_type: None,
|
||||
strarg_callback_type: Type::Callback(Rc::new(Function {
|
||||
return_type: Type::Void,
|
||||
args: vec![Type::String],
|
||||
})),
|
||||
layout_info_type: layout_info_type.clone(),
|
||||
|
|
|
@ -1485,7 +1485,7 @@ pub(crate) fn invoke_callback(
|
|||
// If the callback was not set, the return value will be Value::Void, but we need
|
||||
// to make sure that the value is actually of the right type as returned by the
|
||||
// callback, otherwise we will get panics later
|
||||
default_value_for_type(callback.return_type.as_ref().unwrap_or(&Type::Void))
|
||||
default_value_for_type(&callback.return_type)
|
||||
} else {
|
||||
res
|
||||
});
|
||||
|
|
|
@ -52,17 +52,16 @@ pub fn get_tooltip(document_cache: &mut DocumentCache, token: SyntaxToken) -> Op
|
|||
}
|
||||
|
||||
fn from_prop_result(prop_info: PropertyLookupResult) -> Option<MarkupContent> {
|
||||
let ret_ty =
|
||||
|ty: &Type| if matches!(ty, Type::Void) { String::new() } else { format!(" -> {}", ty) };
|
||||
|
||||
let pure = if prop_info.declared_pure.is_some_and(|x| x) { "pure " } else { "" };
|
||||
if let Type::Callback(callback) = &prop_info.property_type {
|
||||
let ret = callback.return_type.as_ref().map(|x| format!(" -> {}", x)).unwrap_or_default();
|
||||
let ret = ret_ty(&callback.return_type);
|
||||
let args = callback.args.iter().map(|x| x.to_string()).join(", ");
|
||||
Some(from_slint_code(&format!("{pure}callback {}({args}){ret}", prop_info.resolved_name)))
|
||||
} else if let Type::Function(function) = &prop_info.property_type {
|
||||
let ret = if matches!(function.return_type, Type::Void) {
|
||||
String::new()
|
||||
} else {
|
||||
format!(" -> {}", function.return_type)
|
||||
};
|
||||
let ret = ret_ty(&function.return_type);
|
||||
let args = function.args.iter().map(|x| x.to_string()).join(", ");
|
||||
Some(from_slint_code(&format!("{pure}function {}({args}){ret}", prop_info.resolved_name)))
|
||||
} else if prop_info.property_type.is_property_type() {
|
||||
|
|
|
@ -34,7 +34,7 @@ pub(crate) fn fold_node(
|
|||
if lk.declared_pure == Some(true) {
|
||||
write!(file, "pure ")?;
|
||||
} else if let Type::Callback(callback) = lk.property_type {
|
||||
if callback.return_type.is_some() {
|
||||
if !matches!(callback.return_type, Type::Void) {
|
||||
write!(file, "pure ")?;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue