slint/tools/updater/experiments/purity.rs
2023-01-11 18:27:47 +01:00

66 lines
2.4 KiB
Rust

// Copyright © SixtyFPS GmbH <info@slint-ui.com>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
use crate::Cli;
use i_slint_compiler::langtype::Type;
use i_slint_compiler::parser::{syntax_nodes, NodeOrToken, SyntaxKind, SyntaxNode};
use std::io::Write;
pub(crate) fn fold_node(
node: &SyntaxNode,
file: &mut impl Write,
state: &mut crate::State,
_args: &Cli,
) -> std::io::Result<bool> {
if let Some(s) = syntax_nodes::CallbackDeclaration::new(node.clone()) {
if state.current_elem.as_ref().map_or(false, |e| e.borrow().is_legacy_syntax)
&& s.child_text(SyntaxKind::Identifier).as_deref() != Some("pure")
{
if s.ReturnType().is_some() {
write!(file, "pure ")?;
} else if let Some(twb) = s.TwoWayBinding() {
let nr = super::lookup_changes::with_lookup_ctx(state, |lookup_ctx| {
lookup_ctx.property_type = Type::InferredCallback;
let r = i_slint_compiler::passes::resolving::resolve_two_way_binding(
twb, lookup_ctx,
);
r
})
.flatten();
if let Some(nr) = nr {
let lk = nr.element().borrow().lookup_property(nr.name());
if lk.declared_pure == Some(true) {
write!(file, "pure ")?;
} else if let Type::Callback { return_type, .. } = lk.property_type {
if return_type.is_some() {
write!(file, "pure ")?;
}
}
}
}
}
} else if let Some(s) = syntax_nodes::Function::new(node.clone()) {
if state.current_elem.as_ref().map_or(false, |e| e.borrow().is_legacy_syntax)
&& s.ReturnType().is_some()
{
let (mut pure, mut public) = (false, false);
for t in s
.children_with_tokens()
.filter_map(NodeOrToken::into_token)
.filter(|t| t.kind() == SyntaxKind::Identifier)
{
match t.text() {
"pure" => pure = true,
"public" => public = true,
_ => (),
}
}
if !pure && public {
write!(file, "pure ")?;
}
}
}
Ok(false)
}