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 is_get && other.0.len() == 2 && other.0[1] == self.1
76 }
77 }
78}
79
80pub type Signatures = HashMap<String, Signature>;