libgir/analysis/
signatures.rs

1use std::collections::HashMap;
2
3use crate::{env::Env, library, version::Version};
4
5#[derive(Debug)]
6pub struct Signature(Vec<library::TypeId>, library::TypeId, Option<Version>);
7
8impl Signature {
9    pub fn new(func: &library::Function) -> Self {
10        let params = func.parameters.iter().map(|p| p.typ).collect();
11        Self(params, func.ret.typ, func.version)
12    }
13
14    fn from_property(is_get: bool, typ: library::TypeId) -> Self {
15        if is_get {
16            Self(vec![Default::default()], typ, None)
17        } else {
18            Self(vec![Default::default(), typ], Default::default(), None)
19        }
20    }
21
22    pub fn has_in_deps(
23        &self,
24        env: &Env,
25        name: &str,
26        deps: &[library::TypeId],
27    ) -> (bool, Option<Version>) {
28        for tid in deps {
29            let full_name = tid.full_name(&env.library);
30            if let Some(info) = env.analysis.objects.get(&full_name)
31                && let Some(signature) = info.signatures.get(name)
32                && self.eq(signature)
33            {
34                return (true, signature.2);
35            }
36        }
37        (false, None)
38    }
39
40    pub fn has_for_property(
41        env: &Env,
42        name: &str,
43        is_get: bool,
44        typ: library::TypeId,
45        signatures: &Signatures,
46        deps: &[library::TypeId],
47    ) -> (bool, Option<Version>) {
48        if let Some(params) = signatures.get(name) {
49            return (true, params.2);
50        }
51        let this = Signature::from_property(is_get, typ);
52        for tid in deps {
53            let full_name = tid.full_name(&env.library);
54            if let Some(info) = env.analysis.objects.get(&full_name)
55                && let Some(signature) = info.signatures.get(name)
56                && this.property_eq(signature, is_get)
57            {
58                return (true, signature.2);
59            }
60        }
61        (false, None)
62    }
63
64    fn eq(&self, other: &Signature) -> bool {
65        other.1 == self.1 && other.0[1..] == self.0[1..]
66    }
67
68    fn property_eq(&self, other: &Signature, is_get: bool) -> bool {
69        if self.eq(other) {
70            true
71        } else {
72            // For getters for types like GdkRGBA
73            is_get && other.0.len() == 2 && other.0[1] == self.1
74        }
75    }
76}
77
78pub type Signatures = HashMap<String, Signature>;