i_slint_compiler/passes/resolving/
remove_noop.rs1use crate::{diagnostics::BuildDiagnostics, expression_tree::Expression, parser::SyntaxNode};
5
6pub fn remove_from_codeblock(
12 code_block: &mut Vec<(SyntaxNode, Expression)>,
13 diagnostics: &mut BuildDiagnostics,
14) {
15 if code_block.len() > 1 {
16 for index in (0..(code_block.len() - 1)).rev() {
26 let (node, expression) = &code_block[index];
27 if without_side_effects(expression) {
28 diagnostics.push_warning("Expression has no effect!".to_owned(), node);
29 code_block.remove(index);
30 }
31 }
32 }
33}
34
35fn without_side_effects(expression: &Expression) -> bool {
41 match expression {
42 Expression::Condition { condition, true_expr, false_expr } => {
43 without_side_effects(condition)
44 && without_side_effects(true_expr)
45 && without_side_effects(false_expr)
46 }
47 Expression::NumberLiteral(_, _) => true,
48 Expression::StringLiteral(_) => true,
49 Expression::BoolLiteral(_) => true,
50 Expression::CodeBlock(expressions) => expressions.iter().all(without_side_effects),
51 Expression::FunctionParameterReference { .. } => true,
52 Expression::Invalid => false,
55 Expression::Uncompiled(_) => false,
56 Expression::PropertyReference(_) => false,
59 Expression::ElementReference(_) => false,
60 Expression::RepeaterIndexReference { .. } => true,
61 Expression::RepeaterModelReference { .. } => true,
62 Expression::StoreLocalVariable { .. } => false,
63 Expression::ReadLocalVariable { .. } => true,
64 Expression::StructFieldAccess { base, name: _ } => without_side_effects(&*base),
65 Expression::ArrayIndex { array, index } => {
66 without_side_effects(&*array) && without_side_effects(&*index)
67 }
68 Expression::Cast { from, to: _ } => without_side_effects(from),
71 Expression::FunctionCall { .. } => false,
75 Expression::SelfAssignment { .. } => false,
76 Expression::BinaryExpression { lhs, rhs, .. } => {
77 without_side_effects(&*lhs) && without_side_effects(&*rhs)
78 }
79 Expression::UnaryOp { sub, op: _ } => without_side_effects(&*sub),
80 Expression::ImageReference { .. } => true,
81 Expression::Array { element_ty: _, values } => values.iter().all(without_side_effects),
82 Expression::Struct { ty: _, values } => values.values().all(without_side_effects),
83 Expression::PathData(_) => true,
84 Expression::EasingCurve(_) => true,
85 Expression::LinearGradient { angle, stops } => {
86 without_side_effects(&angle)
87 && stops
88 .iter()
89 .all(|(start, end)| without_side_effects(start) && without_side_effects(end))
90 }
91 Expression::RadialGradient { stops } => stops
92 .iter()
93 .all(|(start, end)| without_side_effects(start) && without_side_effects(end)),
94 Expression::ConicGradient { stops } => stops
95 .iter()
96 .all(|(start, end)| without_side_effects(start) && without_side_effects(end)),
97 Expression::EnumerationValue(_) => true,
98 Expression::ReturnStatement(_) => false,
101 Expression::LayoutCacheAccess { .. } => false,
102 Expression::ComputeLayoutInfo(_, _) => false,
103 Expression::SolveLayout(_, _) => false,
104 Expression::MinMax { ty: _, op: _, lhs, rhs } => {
105 without_side_effects(lhs) && without_side_effects(rhs)
106 }
107 Expression::DebugHook { .. } => false,
108 Expression::EmptyComponentFactory => false,
109 }
110}