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::Keys(_) => true,
51 Expression::CodeBlock(expressions) => expressions.iter().all(without_side_effects),
52 Expression::FunctionParameterReference { .. } => true,
53 Expression::Invalid => false,
56 Expression::Uncompiled(_) => false,
57 Expression::PropertyReference(_) => false,
60 Expression::ElementReference(_) => false,
61 Expression::RepeaterIndexReference { .. } => true,
62 Expression::RepeaterModelReference { .. } => true,
63 Expression::StoreLocalVariable { .. } => false,
64 Expression::ReadLocalVariable { .. } => true,
65 Expression::StructFieldAccess { base, name: _ } => without_side_effects(base),
66 Expression::ArrayIndex { array, index } => {
67 without_side_effects(array) && without_side_effects(index)
68 }
69 Expression::Cast { from, to: _ } => without_side_effects(from),
72 Expression::FunctionCall { .. } => false,
76 Expression::SelfAssignment { .. } => false,
77 Expression::BinaryExpression { lhs, rhs, .. } => {
78 without_side_effects(lhs) && without_side_effects(rhs)
79 }
80 Expression::UnaryOp { sub, op: _ } => without_side_effects(sub),
81 Expression::ImageReference { .. } => true,
82 Expression::Array { element_ty: _, values } => values.iter().all(without_side_effects),
83 Expression::Struct { ty: _, values } => values.values().all(without_side_effects),
84 Expression::PathData(_) => true,
85 Expression::EasingCurve(_) => true,
86 Expression::LinearGradient { angle, stops } => {
87 without_side_effects(angle)
88 && stops
89 .iter()
90 .all(|(start, end)| without_side_effects(start) && without_side_effects(end))
91 }
92 Expression::RadialGradient { stops } => stops
93 .iter()
94 .all(|(start, end)| without_side_effects(start) && without_side_effects(end)),
95 Expression::ConicGradient { from_angle, stops } => {
96 without_side_effects(from_angle)
97 && stops
98 .iter()
99 .all(|(start, end)| without_side_effects(start) && without_side_effects(end))
100 }
101 Expression::EnumerationValue(_) => true,
102 Expression::ReturnStatement(_) => false,
105 Expression::LayoutCacheAccess { .. } => false,
106 Expression::GridRepeaterCacheAccess { .. } => false,
107 Expression::ComputeBoxLayoutInfo(_, _) => false,
108 Expression::ComputeGridLayoutInfo { .. } => false,
109 Expression::OrganizeGridLayout(_) => false,
110 Expression::SolveBoxLayout(_, _) => false,
111 Expression::SolveGridLayout { .. } => false,
112 Expression::SolveFlexboxLayout(..) => false,
113 Expression::ComputeFlexboxLayoutInfo(..) => false,
114 Expression::MinMax { ty: _, op: _, lhs, rhs } => {
115 without_side_effects(lhs) && without_side_effects(rhs)
116 }
117 Expression::DebugHook { .. } => false,
118 Expression::EmptyComponentFactory => false,
119 }
120}