wit_parser/resolve/
clone.rs

1//! A helper, non public, module to assist with cloning items within a
2//! `Resolve`.
3//!
4//! Cloning items is not as simple as calling `Clone` due to the nature of how
5//! `TypeId` tracks relationships between interfaces and types. A full deep
6//! clone requires walking the full structure and allocating new id links. This
7//! is akin to, for example, creating a deep copy of an `Rc<T>` by calling
8//! `Clone for T`.
9//!
10//! This is currently used when merging worlds together to help copy anonymously
11//! named items from one world to another.
12//!
13//! The general structure of this module is that each method takes a mutable
14//! reference to an AST item and updates it as necessary internally, delegating
15//! to other methods for internal AST items.
16//!
17//! This module does not at the time of this writing have full support for
18//! cloning everything within a `Resolve`.
19
20use crate::*;
21use std::collections::HashMap;
22
23/// Represents the results of cloning types and/or interfaces as part of a
24/// `Resolve::merge_worlds` operation.
25#[derive(Default)]
26pub struct CloneMaps {
27    pub(super) types: HashMap<TypeId, TypeId>,
28    pub(super) interfaces: HashMap<InterfaceId, InterfaceId>,
29}
30
31impl CloneMaps {
32    /// The types cloned during a `Resolve::merge_worlds` operation.
33    ///
34    /// The key is the original type, and the value is the clone.
35    pub fn types(&self) -> &HashMap<TypeId, TypeId> {
36        &self.types
37    }
38
39    /// The interfaces cloned during a `Resolve::merge_worlds` operation.
40    ///
41    /// The key is the original interface, and the value is the clone.
42    pub fn interfaces(&self) -> &HashMap<InterfaceId, InterfaceId> {
43        &self.interfaces
44    }
45}
46
47pub struct Cloner<'a> {
48    pub resolve: &'a mut Resolve,
49    prev_owner: TypeOwner,
50    new_owner: TypeOwner,
51
52    /// This map keeps track, in the current scope of types, of all copied
53    /// types. This deduplicates copying types to ensure that they're only
54    /// copied at most once.
55    pub types: HashMap<TypeId, TypeId>,
56
57    /// If `None` then it's inferred from `self.new_owner`.
58    pub new_package: Option<PackageId>,
59}
60
61impl<'a> Cloner<'a> {
62    pub fn new(
63        resolve: &'a mut Resolve,
64        prev_owner: TypeOwner,
65        new_owner: TypeOwner,
66    ) -> Cloner<'a> {
67        Cloner {
68            prev_owner,
69            new_owner,
70            resolve,
71            types: Default::default(),
72            new_package: None,
73        }
74    }
75
76    pub fn register_world_type_overlap(&mut self, from: WorldId, into: WorldId) {
77        let into = &self.resolve.worlds[into];
78        let from = &self.resolve.worlds[from];
79        for (name, into_import) in into.imports.iter() {
80            let WorldKey::Name(_) = name else { continue };
81            let WorldItem::Type(into_id) = into_import else {
82                continue;
83            };
84            let Some(WorldItem::Type(from_id)) = from.imports.get(name) else {
85                continue;
86            };
87            self.types.insert(*from_id, *into_id);
88        }
89    }
90
91    pub fn world_item(&mut self, key: &WorldKey, item: &mut WorldItem, clone_maps: &mut CloneMaps) {
92        match key {
93            WorldKey::Name(_) => {}
94            WorldKey::Interface(_) => return,
95        }
96
97        match item {
98            WorldItem::Type(t) => {
99                self.type_id(t);
100            }
101            WorldItem::Function(f) => {
102                self.function(f);
103            }
104            WorldItem::Interface { id, .. } => {
105                let old = *id;
106                self.interface(id, &mut clone_maps.types);
107                clone_maps.interfaces.insert(old, *id);
108            }
109        }
110    }
111
112    fn type_id(&mut self, ty: &mut TypeId) {
113        if !self.types.contains_key(ty) {
114            let mut new = self.resolve.types[*ty].clone();
115            self.type_def(&mut new);
116            let id = self.resolve.types.alloc(new);
117            self.types.insert(*ty, id);
118        }
119        *ty = self.types[ty];
120    }
121
122    fn type_def(&mut self, def: &mut TypeDef) {
123        if def.owner != TypeOwner::None {
124            assert_eq!(def.owner, self.prev_owner);
125            def.owner = self.new_owner;
126        }
127        match &mut def.kind {
128            TypeDefKind::Type(Type::Id(id)) => {
129                if self.resolve.types[*id].owner == self.prev_owner {
130                    self.type_id(id);
131                } else {
132                    // ..
133                }
134            }
135            TypeDefKind::Type(_)
136            | TypeDefKind::Resource
137            | TypeDefKind::Flags(_)
138            | TypeDefKind::Enum(_) => {}
139            TypeDefKind::Handle(Handle::Own(ty) | Handle::Borrow(ty)) => {
140                self.type_id(ty);
141            }
142            TypeDefKind::Option(ty)
143            | TypeDefKind::List(ty)
144            | TypeDefKind::FixedSizeList(ty, ..) => {
145                self.ty(ty);
146            }
147            TypeDefKind::Map(k, v) => {
148                self.ty(k);
149                self.ty(v);
150            }
151            TypeDefKind::Tuple(list) => {
152                for ty in list.types.iter_mut() {
153                    self.ty(ty);
154                }
155            }
156            TypeDefKind::Record(r) => {
157                for field in r.fields.iter_mut() {
158                    self.ty(&mut field.ty);
159                }
160            }
161            TypeDefKind::Variant(r) => {
162                for case in r.cases.iter_mut() {
163                    if let Some(ty) = &mut case.ty {
164                        self.ty(ty);
165                    }
166                }
167            }
168            TypeDefKind::Result(r) => {
169                if let Some(ok) = &mut r.ok {
170                    self.ty(ok);
171                }
172                if let Some(err) = &mut r.err {
173                    self.ty(err);
174                }
175            }
176            TypeDefKind::Future(ty) | TypeDefKind::Stream(ty) => {
177                if let Some(ty) = ty {
178                    self.ty(ty);
179                }
180            }
181            TypeDefKind::Unknown => {}
182        }
183    }
184
185    fn ty(&mut self, ty: &mut Type) {
186        match ty {
187            Type::Id(id) => self.type_id(id),
188            _ => {}
189        }
190    }
191
192    fn function(&mut self, func: &mut Function) {
193        if let Some(id) = func.kind.resource_mut() {
194            self.type_id(id);
195        }
196        for (_, ty) in func.params.iter_mut() {
197            self.ty(ty);
198        }
199        if let Some(ty) = &mut func.result {
200            self.ty(ty);
201        }
202    }
203
204    fn interface(&mut self, id: &mut InterfaceId, cloned_types: &mut HashMap<TypeId, TypeId>) {
205        let mut new = self.resolve.interfaces[*id].clone();
206        let next_id = self.resolve.interfaces.next_id();
207        let mut clone = Cloner::new(
208            self.resolve,
209            TypeOwner::Interface(*id),
210            TypeOwner::Interface(next_id),
211        );
212        for id in new.types.values_mut() {
213            clone.type_id(id);
214        }
215        for func in new.functions.values_mut() {
216            clone.function(func);
217        }
218        cloned_types.extend(clone.types);
219        new.package = Some(self.new_package.unwrap_or_else(|| match self.new_owner {
220            TypeOwner::Interface(id) => self.resolve.interfaces[id].package.unwrap(),
221            TypeOwner::World(id) => self.resolve.worlds[id].package.unwrap(),
222            TypeOwner::None => unreachable!(),
223        }));
224        *id = self.resolve.interfaces.alloc(new);
225        assert_eq!(*id, next_id);
226    }
227}