wit_parser/resolve/
clone.rs1use crate::*;
21use std::collections::HashMap;
22
23#[derive(Default)]
26pub struct CloneMaps {
27 pub(super) types: HashMap<TypeId, TypeId>,
28 pub(super) interfaces: HashMap<InterfaceId, InterfaceId>,
29}
30
31impl CloneMaps {
32 pub fn types(&self) -> &HashMap<TypeId, TypeId> {
36 &self.types
37 }
38
39 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 pub types: HashMap<TypeId, TypeId>,
56
57 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 }
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::Tuple(list) => {
148 for ty in list.types.iter_mut() {
149 self.ty(ty);
150 }
151 }
152 TypeDefKind::Record(r) => {
153 for field in r.fields.iter_mut() {
154 self.ty(&mut field.ty);
155 }
156 }
157 TypeDefKind::Variant(r) => {
158 for case in r.cases.iter_mut() {
159 if let Some(ty) = &mut case.ty {
160 self.ty(ty);
161 }
162 }
163 }
164 TypeDefKind::Result(r) => {
165 if let Some(ok) = &mut r.ok {
166 self.ty(ok);
167 }
168 if let Some(err) = &mut r.err {
169 self.ty(err);
170 }
171 }
172 TypeDefKind::Future(ty) | TypeDefKind::Stream(ty) => {
173 if let Some(ty) = ty {
174 self.ty(ty);
175 }
176 }
177 TypeDefKind::Unknown => {}
178 }
179 }
180
181 fn ty(&mut self, ty: &mut Type) {
182 match ty {
183 Type::Id(id) => self.type_id(id),
184 _ => {}
185 }
186 }
187
188 fn function(&mut self, func: &mut Function) {
189 if let Some(id) = func.kind.resource_mut() {
190 self.type_id(id);
191 }
192 for (_, ty) in func.params.iter_mut() {
193 self.ty(ty);
194 }
195 if let Some(ty) = &mut func.result {
196 self.ty(ty);
197 }
198 }
199
200 fn interface(&mut self, id: &mut InterfaceId, cloned_types: &mut HashMap<TypeId, TypeId>) {
201 let mut new = self.resolve.interfaces[*id].clone();
202 let next_id = self.resolve.interfaces.next_id();
203 let mut clone = Cloner::new(
204 self.resolve,
205 TypeOwner::Interface(*id),
206 TypeOwner::Interface(next_id),
207 );
208 for id in new.types.values_mut() {
209 clone.type_id(id);
210 }
211 for func in new.functions.values_mut() {
212 clone.function(func);
213 }
214 cloned_types.extend(clone.types);
215 new.package = Some(self.new_package.unwrap_or_else(|| match self.new_owner {
216 TypeOwner::Interface(id) => self.resolve.interfaces[id].package.unwrap(),
217 TypeOwner::World(id) => self.resolve.worlds[id].package.unwrap(),
218 TypeOwner::None => unreachable!(),
219 }));
220 *id = self.resolve.interfaces.alloc(new);
221 assert_eq!(*id, next_id);
222 }
223}