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::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}