wit_parser/resolve/
clone.rs1use 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 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 }
104 }
105 TypeDefKind::Type(_)
106 | TypeDefKind::Resource
107 | TypeDefKind::Flags(_)
108 | TypeDefKind::Enum(_) => {}
109 TypeDefKind::Handle(Handle::Own(ty) | Handle::Borrow(ty)) => {
110 self.type_id(ty);
111 }
112 TypeDefKind::Option(ty)
113 | TypeDefKind::List(ty)
114 | TypeDefKind::FixedSizeList(ty, ..) => {
115 self.ty(ty);
116 }
117 TypeDefKind::Tuple(list) => {
118 for ty in list.types.iter_mut() {
119 self.ty(ty);
120 }
121 }
122 TypeDefKind::Record(r) => {
123 for field in r.fields.iter_mut() {
124 self.ty(&mut field.ty);
125 }
126 }
127 TypeDefKind::Variant(r) => {
128 for case in r.cases.iter_mut() {
129 if let Some(ty) = &mut case.ty {
130 self.ty(ty);
131 }
132 }
133 }
134 TypeDefKind::Result(r) => {
135 if let Some(ok) = &mut r.ok {
136 self.ty(ok);
137 }
138 if let Some(err) = &mut r.err {
139 self.ty(err);
140 }
141 }
142 TypeDefKind::Future(ty) | TypeDefKind::Stream(ty) => {
143 if let Some(ty) = ty {
144 self.ty(ty);
145 }
146 }
147 TypeDefKind::Unknown => {}
148 }
149 }
150
151 fn ty(&mut self, ty: &mut Type) {
152 match ty {
153 Type::Id(id) => self.type_id(id),
154 _ => {}
155 }
156 }
157
158 fn function(&mut self, func: &mut Function) {
159 if let Some(id) = func.kind.resource_mut() {
160 self.type_id(id);
161 }
162 for (_, ty) in func.params.iter_mut() {
163 self.ty(ty);
164 }
165 if let Some(ty) = &mut func.result {
166 self.ty(ty);
167 }
168 }
169
170 fn interface(&mut self, id: &mut InterfaceId) {
171 let mut new = self.resolve.interfaces[*id].clone();
172 let next_id = self.resolve.interfaces.next_id();
173 let mut clone = Cloner::new(
174 self.resolve,
175 TypeOwner::Interface(*id),
176 TypeOwner::Interface(next_id),
177 );
178 for id in new.types.values_mut() {
179 clone.type_id(id);
180 }
181 for func in new.functions.values_mut() {
182 clone.function(func);
183 }
184 new.package = Some(match self.new_owner {
185 TypeOwner::Interface(id) => self.resolve.interfaces[id].package.unwrap(),
186 TypeOwner::World(id) => self.resolve.worlds[id].package.unwrap(),
187 TypeOwner::None => unreachable!(),
188 });
189 *id = self.resolve.interfaces.alloc(new);
190 assert_eq!(*id, next_id);
191 }
192}