svlint/opt/rustwide/workdir/src/syntaxrules/
sequential_block_in_always_latch.rs

1use crate::config::ConfigOption;
2use crate::linter::{SyntaxRule, SyntaxRuleResult};
3use sv_parser::{unwrap_locate, unwrap_node, AlwaysKeyword, NodeEvent, RefNode, SyntaxTree};
4
5#[derive(Default)]
6pub struct SequentialBlockInAlwaysLatch;
7
8impl SyntaxRule for SequentialBlockInAlwaysLatch {
9    fn check(
10        &mut self,
11        _syntax_tree: &SyntaxTree,
12        event: &NodeEvent,
13        _option: &ConfigOption,
14    ) -> SyntaxRuleResult {
15        let node = match event {
16            NodeEvent::Enter(x) => x,
17            NodeEvent::Leave(_) => {
18                return SyntaxRuleResult::Pass;
19            }
20        };
21
22        match node {
23            RefNode::AlwaysConstruct(x) => {
24                let (t, x) = &x.nodes;
25                match t {
26                    AlwaysKeyword::AlwaysLatch(_) => {
27                        if let Some(x) = unwrap_node!(x, SeqBlock) {
28                            let loc = unwrap_locate!(x.clone()).unwrap();
29                            SyntaxRuleResult::FailLocate(*loc)
30                        } else {
31                            SyntaxRuleResult::Pass
32                        }
33                    }
34                    _ => SyntaxRuleResult::Pass,
35                }
36            }
37            _ => SyntaxRuleResult::Pass,
38        }
39    }
40
41    fn name(&self) -> String {
42        String::from("sequential_block_in_always_latch")
43    }
44
45    fn hint(&self, _option: &ConfigOption) -> String {
46        String::from("Keywords `begin` and `end` are forbidden within `always_latch`.")
47    }
48
49    fn reason(&self) -> String {
50        String::from("Sequential blocks within `always_latch` may encourage overly-complex code.")
51    }
52}