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
23pub struct Cloner<'a> {
24 resolve: &'a mut Resolve,
25 prev_owner: TypeOwner,
26 new_owner: TypeOwner,
27
28 /// This map keeps track, in the current scope of types, of all copied
29 /// types. This deduplicates copying types to ensure that they're only
30 /// copied at most once.
31 types: HashMap<TypeId, TypeId>,
32}
33
34impl<'a> Cloner<'a> {
35 pub fn new(
36 resolve: &'a mut Resolve,
37 prev_owner: TypeOwner,
38 new_owner: TypeOwner,
39 ) -> Cloner<'a> {
40 Cloner {
41 prev_owner,
42 new_owner,
43 resolve,
44 types: Default::default(),
45 }
46 }
47
48 pub fn register_world_type_overlap(&mut self, from: WorldId, into: WorldId) {
49 let into = &self.resolve.worlds[into];
50 let from = &self.resolve.worlds[from];
51 for (name, into_import) in into.imports.iter() {
52 let WorldKey::Name(_) = name else { continue };
53 let WorldItem::Type(into_id) = into_import else {
54 continue;
55 };
56 let Some(WorldItem::Type(from_id)) = from.imports.get(name) else {
57 continue;
58 };
59 self.types.insert(*from_id, *into_id);
60 }
61 }
62
63 pub fn world_item(&mut self, key: &WorldKey, item: &mut WorldItem) {
64 match key {
65 WorldKey::Name(_) => {}
66 WorldKey::Interface(_) => return,
67 }
68
69 match item {
70 WorldItem::Type(t) => {
71 self.type_id(t);
72 }
73 WorldItem::Function(f) => {
74 self.function(f);
75 }
76 WorldItem::Interface { id, .. } => {
77 self.interface(id);
78 }
79 }
80 }
81
82 fn type_id(&mut self, ty: &mut TypeId) {
83 if !self.types.contains_key(ty) {
84 let mut new = self.resolve.types[*ty].clone();
85 self.type_def(&mut new);
86 let id = self.resolve.types.alloc(new);
87 self.types.insert(*ty, id);
88 }
89 *ty = self.types[ty];
90 }
91
92 fn type_def(&mut self, def: &mut TypeDef) {
93 if def.owner != TypeOwner::None {
94 assert_eq!(def.owner, self.prev_owner);
95 def.owner = self.new_owner;
96 }
97 match &mut def.kind {
98 TypeDefKind::Type(Type::Id(id)) => {
99 if self.resolve.types[*id].owner == self.prev_owner {
100 self.type_id(id);
101 } else {
102 // ..
103 }
104 }
105 TypeDefKind::Type(_)
106 | TypeDefKind::Resource
107 | TypeDefKind::Flags(_)
108 | TypeDefKind::Enum(_)
109 | TypeDefKind::ErrorContext => {}
110 TypeDefKind::Handle(Handle::Own(ty) | Handle::Borrow(ty)) => {
111 self.type_id(ty);
112 }
113 TypeDefKind::Option(ty) | TypeDefKind::List(ty) | TypeDefKind::Stream(ty) => {
114 self.ty(ty);
115 }
116 TypeDefKind::Tuple(list) => {
117 for ty in list.types.iter_mut() {
118 self.ty(ty);
119 }
120 }
121 TypeDefKind::Record(r) => {
122 for field in r.fields.iter_mut() {
123 self.ty(&mut field.ty);
124 }
125 }
126 TypeDefKind::Variant(r) => {
127 for case in r.cases.iter_mut() {
128 if let Some(ty) = &mut case.ty {
129 self.ty(ty);
130 }
131 }
132 }
133 TypeDefKind::Result(r) => {
134 if let Some(ok) = &mut r.ok {
135 self.ty(ok);
136 }
137 if let Some(err) = &mut r.err {
138 self.ty(err);
139 }
140 }
141 TypeDefKind::Future(f) => {
142 if let Some(ty) = f {
143 self.ty(ty);
144 }
145 }
146 TypeDefKind::Unknown => {}
147 }
148 }
149
150 fn ty(&mut self, ty: &mut Type) {
151 match ty {
152 Type::Id(id) => self.type_id(id),
153 _ => {}
154 }
155 }
156
157 fn function(&mut self, func: &mut Function) {
158 match &mut func.kind {
159 FunctionKind::Freestanding => {}
160 FunctionKind::Method(id) | FunctionKind::Static(id) | FunctionKind::Constructor(id) => {
161 self.type_id(id)
162 }
163 }
164 for (_, ty) in func.params.iter_mut() {
165 self.ty(ty);
166 }
167 match &mut func.results {
168 Results::Named(named) => {
169 for (_, ty) in named {
170 self.ty(ty);
171 }
172 }
173 Results::Anon(ty) => self.ty(ty),
174 }
175 }
176
177 fn interface(&mut self, id: &mut InterfaceId) {
178 let mut new = self.resolve.interfaces[*id].clone();
179 let next_id = self.resolve.interfaces.next_id();
180 let mut clone = Cloner::new(
181 self.resolve,
182 TypeOwner::Interface(*id),
183 TypeOwner::Interface(next_id),
184 );
185 for id in new.types.values_mut() {
186 clone.type_id(id);
187 }
188 for func in new.functions.values_mut() {
189 clone.function(func);
190 }
191 new.package = Some(match self.new_owner {
192 TypeOwner::Interface(id) => self.resolve.interfaces[id].package.unwrap(),
193 TypeOwner::World(id) => self.resolve.worlds[id].package.unwrap(),
194 TypeOwner::None => unreachable!(),
195 });
196 *id = self.resolve.interfaces.alloc(new);
197 assert_eq!(*id, next_id);
198 }
199}
200