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                if let Some(signature) = info.signatures.get(name) {
32                    if self.eq(signature) {
33                        return (true, signature.2);
34                    }
35                }
36            }
37        }
38        (false, None)
39    }
40
41    pub fn has_for_property(
42        env: &Env,
43        name: &str,
44        is_get: bool,
45        typ: library::TypeId,
46        signatures: &Signatures,
47        deps: &[library::TypeId],
48    ) -> (bool, Option<Version>) {
49        if let Some(params) = signatures.get(name) {
50            return (true, params.2);
51        }
52        let this = Signature::from_property(is_get, typ);
53        for tid in deps {
54            let full_name = tid.full_name(&env.library);
55            if let Some(info) = env.analysis.objects.get(&full_name) {
56                if let Some(signature) = info.signatures.get(name) {
57                    if this.property_eq(signature, is_get) {
58                        return (true, signature.2);
59                    }
60                }
61            }
62        }
63        (false, None)
64    }
65
66    fn eq(&self, other: &Signature) -> bool {
67        other.1 == self.1 && other.0[1..] == self.0[1..]
68    }
69
70    fn property_eq(&self, other: &Signature, is_get: bool) -> bool {
71        if self.eq(other) {
72            true
73        } else {
74            // For getters for types like GdkRGBA
75            is_get && other.0.len() == 2 && other.0[1] == self.1
76        }
77    }
78}
79
80pub type Signatures = HashMap<String, Signature>;