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
use crate::semantics::*;
use crate::syntax::*;
use crate::*;

pub struct UndefinedBehaviour;

impl UndefinedBehaviour {
    fn check_message_send(
        message_send: &Node,
        analysis: &mut Analysis,
        diagnostics: &mut Vec<Diagnostic>,
    ) -> Option<()> {
        if let MessageSendExpression {
            expression,
            message,
            ..
        } = message_send.kind
        {
            let expression = analysis.navigator.find_child(message_send, expression)?;
            let message = analysis.navigator.find_child(message_send, message)?;
            let selector = analysis.navigator.message_selector(&message)?;

            let receiver_type = analysis.types.get_type_of_expression(&expression);
            if receiver_type.is_unknown() {
                return None;
            }

            for behaviour in analysis.types.get_behaviours(&receiver_type) {
                if behaviour.selector() == selector {
                    return None;
                }
            }

            diagnostics.push(Diagnostic::UndefinedBehaviour(
                message.span,
                receiver_type,
                selector,
            ))
        }

        None
    }
}

impl Checker for UndefinedBehaviour {
    fn check(&self, analysis: &mut Analysis, diagnostics: &mut Vec<Diagnostic>) {
        for message_send in analysis.navigator.all_message_sends() {
            Self::check_message_send(&message_send, analysis, diagnostics).unwrap_or(());
        }
    }
}