duchess_reflect/
substitution.rs1use std::iter::FromIterator;
2use std::{collections::BTreeMap, sync::Arc};
3
4use crate::class_info::{ClassRef, Id, RefType, Type};
5
6pub struct Substitution<'s> {
7 map: BTreeMap<&'s Id, &'s RefType>,
8}
9
10impl<'s> FromIterator<(&'s Id, &'s RefType)> for Substitution<'s> {
11 fn from_iter<T: IntoIterator<Item = (&'s Id, &'s RefType)>>(iter: T) -> Self {
12 Substitution {
13 map: iter.into_iter().collect(),
14 }
15 }
16}
17
18pub trait Substitute {
19 fn substitute(&self, subst: &Substitution<'_>) -> Self;
20}
21
22impl Substitute for RefType {
23 fn substitute(&self, subst: &Substitution<'_>) -> Self {
24 match self {
25 RefType::Class(c) => RefType::Class(c.substitute(subst)),
26 RefType::Array(a) => RefType::Array(a.substitute(subst)),
27 RefType::TypeParameter(id) => match subst.map.get(&id) {
28 Some(v) => RefType::clone(v),
29 None => self.clone(),
30 },
31 RefType::Extends(e) => RefType::Extends(e.substitute(subst)),
32 RefType::Super(e) => RefType::Super(e.substitute(subst)),
33 RefType::Wildcard => RefType::Wildcard,
34 }
35 }
36}
37
38impl Substitute for Type {
39 fn substitute(&self, subst: &Substitution<'_>) -> Self {
40 match self {
41 Type::Ref(r) => Type::Ref(r.substitute(subst)),
42 Type::Scalar(_) => self.clone(),
43 Type::Repeat(r) => Type::Repeat(r.substitute(subst)),
44 }
45 }
46}
47
48impl Substitute for ClassRef {
49 fn substitute(&self, subst: &Substitution<'_>) -> Self {
50 let ClassRef { name, generics } = self;
51 ClassRef {
52 name: name.clone(),
53 generics: generics.substitute(subst),
54 }
55 }
56}
57
58impl<F> Substitute for Vec<F>
59where
60 F: Substitute,
61{
62 fn substitute(&self, subst: &Substitution<'_>) -> Self {
63 self.iter().map(|e| e.substitute(subst)).collect()
64 }
65}
66
67impl<F> Substitute for Arc<F>
68where
69 F: Substitute,
70{
71 fn substitute(&self, subst: &Substitution<'_>) -> Self {
72 Arc::new(F::substitute(self, subst))
73 }
74}