wit_parser/resolve/
clone.rs1use crate::*;
21
22#[derive(Default)]
25pub struct CloneMaps {
26 pub(super) types: HashMap<TypeId, TypeId>,
27 pub(super) interfaces: HashMap<InterfaceId, InterfaceId>,
28}
29
30impl CloneMaps {
31 pub fn types(&self) -> &HashMap<TypeId, TypeId> {
35 &self.types
36 }
37
38 pub fn interfaces(&self) -> &HashMap<InterfaceId, InterfaceId> {
42 &self.interfaces
43 }
44}
45
46pub struct Cloner<'a> {
47 pub resolve: &'a mut Resolve,
48 pub maps: &'a mut CloneMaps,
49 prev_owner: TypeOwner,
50 new_owner: TypeOwner,
51
52 pub new_package: Option<PackageId>,
54}
55
56impl<'a> Cloner<'a> {
57 pub fn new(
58 resolve: &'a mut Resolve,
59 maps: &'a mut CloneMaps,
60 prev_owner: TypeOwner,
61 new_owner: TypeOwner,
62 ) -> Cloner<'a> {
63 Cloner {
64 prev_owner,
65 new_owner,
66 resolve,
67 maps,
68 new_package: None,
69 }
70 }
71
72 pub fn register_world_type_overlap(&mut self, from: WorldId, into: WorldId) {
73 let into = &self.resolve.worlds[into];
74 let from = &self.resolve.worlds[from];
75 for (name, into_import) in into.imports.iter() {
76 let WorldKey::Name(_) = name else { continue };
77 let WorldItem::Type { id: into_id, .. } = into_import else {
78 continue;
79 };
80 let Some(WorldItem::Type { id: from_id, .. }) = from.imports.get(name) else {
81 continue;
82 };
83 self.maps.types.insert(*from_id, *into_id);
84 }
85 }
86
87 pub fn world_item(&mut self, key: &WorldKey, item: &mut WorldItem) {
88 match key {
89 WorldKey::Name(_) => {}
90 WorldKey::Interface(_) => return,
91 }
92
93 match item {
94 WorldItem::Type { id, .. } => {
95 self.type_id(id);
96 }
97 WorldItem::Function(f) => {
98 self.function(f);
99 }
100 WorldItem::Interface { id, .. } => {
101 self.interface(id);
102 }
103 }
104 }
105
106 fn type_id(&mut self, ty: &mut TypeId) {
107 if !self.maps.types.contains_key(ty) {
108 let mut new = self.resolve.types[*ty].clone();
109 self.type_def(&mut new);
110 let id = self.resolve.types.alloc(new);
111 self.maps.types.insert(*ty, id);
112 }
113 *ty = self.maps.types[&*ty];
114 }
115
116 fn type_def(&mut self, def: &mut TypeDef) {
117 if def.owner != TypeOwner::None {
118 assert_eq!(def.owner, self.prev_owner);
119 def.owner = self.new_owner;
120 }
121 match &mut def.kind {
122 TypeDefKind::Type(Type::Id(id)) => {
123 if self.resolve.types[*id].owner == self.prev_owner {
124 self.type_id(id);
125 } else if let Some(new_id) = self.maps.types.get(id) {
126 *id = *new_id;
127 } else {
128 }
135 }
136 TypeDefKind::Type(_)
137 | TypeDefKind::Resource
138 | TypeDefKind::Flags(_)
139 | TypeDefKind::Enum(_) => {}
140 TypeDefKind::Handle(Handle::Own(ty) | Handle::Borrow(ty)) => {
141 self.type_id(ty);
142 }
143 TypeDefKind::Option(ty)
144 | TypeDefKind::List(ty)
145 | TypeDefKind::FixedLengthList(ty, ..) => {
146 self.ty(ty);
147 }
148 TypeDefKind::Map(k, v) => {
149 self.ty(k);
150 self.ty(v);
151 }
152 TypeDefKind::Tuple(list) => {
153 for ty in list.types.iter_mut() {
154 self.ty(ty);
155 }
156 }
157 TypeDefKind::Record(r) => {
158 for field in r.fields.iter_mut() {
159 self.ty(&mut field.ty);
160 }
161 }
162 TypeDefKind::Variant(r) => {
163 for case in r.cases.iter_mut() {
164 if let Some(ty) = &mut case.ty {
165 self.ty(ty);
166 }
167 }
168 }
169 TypeDefKind::Result(r) => {
170 if let Some(ok) = &mut r.ok {
171 self.ty(ok);
172 }
173 if let Some(err) = &mut r.err {
174 self.ty(err);
175 }
176 }
177 TypeDefKind::Future(ty) | TypeDefKind::Stream(ty) => {
178 if let Some(ty) = ty {
179 self.ty(ty);
180 }
181 }
182 TypeDefKind::Unknown => {}
183 }
184 }
185
186 fn ty(&mut self, ty: &mut Type) {
187 match ty {
188 Type::Id(id) => self.type_id(id),
189 _ => {}
190 }
191 }
192
193 fn function(&mut self, func: &mut Function) {
194 if let Some(id) = func.kind.resource_mut() {
195 self.type_id(id);
196 }
197 for param in func.params.iter_mut() {
198 self.ty(&mut param.ty);
199 }
200 if let Some(ty) = &mut func.result {
201 self.ty(ty);
202 }
203 }
204
205 pub fn interface(&mut self, id: &mut InterfaceId) {
206 let old_id = *id;
207 let mut new = self.resolve.interfaces[old_id].clone();
208 let next_id = self.resolve.interfaces.next_id();
209 let mut clone = Cloner::new(
210 self.resolve,
211 self.maps,
212 TypeOwner::Interface(old_id),
213 TypeOwner::Interface(next_id),
214 );
215 for id in new.types.values_mut() {
216 clone.type_id(id);
217 }
218 for func in new.functions.values_mut() {
219 clone.function(func);
220 }
221 new.package = Some(self.new_package.unwrap_or_else(|| match self.new_owner {
222 TypeOwner::Interface(id) => self.resolve.interfaces[id].package.unwrap(),
223 TypeOwner::World(id) => self.resolve.worlds[id].package.unwrap(),
224 TypeOwner::None => unreachable!(),
225 }));
226 new.clone_of = Some(old_id);
227 *id = self.resolve.interfaces.alloc(new);
228 let prev = self.maps.interfaces.insert(old_id, next_id);
229 assert!(prev.is_none());
230 assert_eq!(*id, next_id);
231 }
232}