scopegraphs_lib/resolve/
params.rs

1use crate::resolve::EdgeOrData;
2
3/// Unary predicate over `DATA`.
4///
5/// Used to select declarations that a query can resolve to.
6pub trait DataWellformedness<DATA> {
7    fn data_wf(&self, data: &DATA) -> bool;
8}
9
10impl<DATA, T> DataWellformedness<DATA> for T
11where
12    for<'sg> T: Fn(&'sg DATA) -> bool,
13{
14    fn data_wf(&self, data: &DATA) -> bool {
15        self(data)
16    }
17}
18
19#[derive(Default)]
20pub struct DefaultDataWellformedness {}
21
22impl<DATA> DataWellformedness<DATA> for DefaultDataWellformedness {
23    fn data_wf(&self, _data: &DATA) -> bool {
24        true // match all data by default
25    }
26}
27
28/// Strict partial order on labels. Used to perform shadowing.
29///
30/// For example, suppose that in some scope `s`, declarations for some query are reachable via an
31/// `Lex` edge and an `Imp` edge (for lexical parent and import, respectively). When the label order
32/// Indicates `Lex < Imp` (i.e., declarations from a lexically enclosing scope have higher priority),
33/// the declaration over the `Imp` edge is shadowed, and will thus not be included in the
34/// environment. If `Imp < Lex`, imports have higher priority, and that one will be included.
35/// Otherwise, paths to both declarations are included in the environment.
36pub trait LabelOrder<LABEL> {
37    fn less_than(&self, l1: &EdgeOrData<LABEL>, l2: &EdgeOrData<LABEL>) -> bool;
38}
39impl<LABEL, T> LabelOrder<LABEL> for T
40where
41    T: for<'a, 'b> Fn(&'a EdgeOrData<LABEL>, &'b EdgeOrData<LABEL>) -> bool,
42{
43    fn less_than(&self, l1: &EdgeOrData<LABEL>, l2: &EdgeOrData<LABEL>) -> bool {
44        self(l1, l2)
45    }
46}
47
48#[derive(Default)]
49pub struct DefaultLabelOrder {}
50
51impl<LABEL> LabelOrder<LABEL> for DefaultLabelOrder {
52    fn less_than(&self, _l1: &EdgeOrData<LABEL>, _l2: &EdgeOrData<LABEL>) -> bool {
53        false // no shadowing by default
54    }
55}
56
57/// Data equivalence relation.
58///
59/// Defines equivalence classes of declarations. Shadowing will only be applied with respect to
60/// declarations in the same equivalence class. That is, the shadowing explained in [`LabelOrder`]
61/// will only be applied if the declarations are equivalent.
62pub trait DataEquiv<DATA> {
63    fn data_equiv(&self, d1: &DATA, d2: &DATA) -> bool;
64
65    fn always_true(&self) -> bool {
66        false
67    }
68}
69
70impl<DATA, T> DataEquiv<DATA> for T
71where
72    for<'sg> T: Fn(&'sg DATA, &'sg DATA) -> bool,
73{
74    fn data_equiv(&self, d1: &DATA, d2: &DATA) -> bool {
75        self(d1, d2)
76    }
77}
78
79#[derive(Default)]
80pub struct DefaultDataEquiv {}
81
82impl<DATA> DataEquiv<DATA> for DefaultDataEquiv {
83    fn data_equiv(&self, _d1: &DATA, _d2: &DATA) -> bool {
84        true // all data in same equivalence class by default
85    }
86
87    fn always_true(&self) -> bool {
88        true
89    }
90}