1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use crate::analyzer_error::AnalyzerError;
use crate::unsafe_table;
use veryl_parser::veryl_grammar_trait::*;
use veryl_parser::veryl_walker::{Handler, HandlerPoint};
use veryl_parser::ParolError;

pub struct CheckUnsafe<'a> {
    pub errors: Vec<AnalyzerError>,
    text: &'a str,
    point: HandlerPoint,
}

impl<'a> CheckUnsafe<'a> {
    pub fn new(text: &'a str) -> Self {
        Self {
            errors: Vec::new(),
            text,
            point: HandlerPoint::Before,
        }
    }
}

impl<'a> Handler for CheckUnsafe<'a> {
    fn set_point(&mut self, p: HandlerPoint) {
        self.point = p;
    }
}

impl<'a> VerylGrammarTrait for CheckUnsafe<'a> {
    fn unsafe_block(&mut self, arg: &UnsafeBlock) -> Result<(), ParolError> {
        match self.point {
            HandlerPoint::Before => {
                let value: Result<crate::r#unsafe::Unsafe, crate::r#unsafe::UnsafeError> =
                    arg.try_into();

                match value {
                    Ok(value) => {
                        unsafe_table::begin(arg.r#unsafe.unsafe_token.token, Some(value));
                    }
                    Err(err) => {
                        unsafe_table::begin(arg.r#unsafe.unsafe_token.token, None);
                        match err {
                            crate::r#unsafe::UnsafeError::UnknownUnsafe => {
                                self.errors.push(AnalyzerError::unknown_unsafe(
                                    &arg.identifier.identifier_token.to_string(),
                                    self.text,
                                    &arg.identifier.as_ref().into(),
                                ));
                            }
                        }
                    }
                }
            }
            HandlerPoint::After => {
                unsafe_table::end(arg.r_brace.r_brace_token.token);
            }
        }
        Ok(())
    }
}