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 PrivateMethods;

impl PrivateMethods {
    fn check_method(
        &self,
        method: &Node,
        message: &Node,
        analysis: &mut Analysis,
        diagnostics: &mut Vec<Diagnostic>,
    ) -> Option<()> {
        if !analysis.navigator.method_is_visible_from(method, message)? {
            let method_class = analysis.navigator.closest_class_upwards(method)?;
            diagnostics.push(Diagnostic::InvalidAccessToPrivateMethod(
                message.span.clone(),
                analysis.navigator.qualified_name_of(&method_class)?.0,
                analysis.navigator.method_selector(method)?,
            ));
        }
        None
    }

    fn check_message_send(
        &self,
        message_send: &Node,
        analysis: &mut Analysis,
        diagnostics: &mut Vec<Diagnostic>,
    ) -> Option<()> {
        if let MessageSendExpression { message, .. } = message_send.kind {
            let message = analysis.navigator.find_child(&message_send, message)?;
            let method = analysis
                .navigator
                .method_from_message(&message, &analysis.types)?;

            self.check_method(&method, &message, analysis, diagnostics)?;
        }
        None
    }
}

impl Checker for PrivateMethods {
    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(());
        }
    }
}