libgir/analysis/
signatures.rs1use 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 is_get && other.0.len() == 2 && other.0[1] == self.1
74 }
75 }
76}
77
78pub type Signatures = HashMap<String, Signature>;