1use crate::ns::*;
2
3pub struct ThingyFactory<'a>(pub(crate) &'a SemanticHost);
4
5impl<'a> ThingyFactory<'a> {
6 pub fn create_public_ns(&self, parent: Option<Thingy>) -> Thingy {
7 SystemNamespace::new(&self.0.arena, SystemNamespaceKind::Public, parent).into()
8 }
9
10 pub fn create_private_ns(&self, parent: Option<Thingy>) -> Thingy {
11 SystemNamespace::new(&self.0.arena, SystemNamespaceKind::Private, parent).into()
12 }
13
14 pub fn create_protected_ns(&self, parent: Option<Thingy>) -> Thingy {
15 SystemNamespace::new(&self.0.arena, SystemNamespaceKind::Protected, parent).into()
16 }
17
18 pub fn create_static_protected_ns(&self, parent: Option<Thingy>) -> Thingy {
19 SystemNamespace::new(&self.0.arena, SystemNamespaceKind::StaticProtected, parent).into()
20 }
21
22 pub fn create_internal_ns(&self, parent: Option<Thingy>) -> Thingy {
23 SystemNamespace::new(&self.0.arena, SystemNamespaceKind::Internal, parent).into()
24 }
25
26 pub fn create_explicit_ns(&self, uri: String) -> Thingy {
27 let mut mappings = self.0.explicit_namespaces.borrow_mut();
28 if let Some(ns) = mappings.get(&uri) {
29 return ns.clone();
30 }
31 let ns: Thingy = ExplicitNamespace::new(&self.0.arena, uri.clone()).into();
32 mappings.insert(uri, ns.clone());
33 ns
34 }
35
36 pub fn create_user_ns(&self, uri: String) -> Thingy {
37 let mut mappings = self.0.user_namespaces.borrow_mut();
38 if let Some(ns) = mappings.get(&uri) {
39 return ns.clone();
40 }
41 let ns: Thingy = UserNamespace::new(&self.0.arena, uri.clone()).into();
42 mappings.insert(uri, ns.clone());
43 ns
44 }
45
46 pub fn create_qname(&self, namespace: &Thingy, local_name: String) -> QName {
47 let mut ns_mappings = self.0.qnames.borrow_mut();
48 if let Some(qn_mappings) = ns_mappings.get_mut(namespace) {
49 if let Some(qn) = qn_mappings.get(&local_name) {
50 return qn.clone();
51 }
52 let qn = QName(Rc::new(QName1 {
53 m_namespace: namespace.clone(),
54 m_local_name: local_name.clone(),
55 }));
56 qn_mappings.insert(local_name, qn.clone());
57 return qn;
58 }
59 let qn = QName(Rc::new(QName1 {
60 m_namespace: namespace.clone(),
61 m_local_name: local_name.clone(),
62 }));
63 let mut qn_mappings = HashMap::new();
64 qn_mappings.insert(local_name, qn.clone());
65 ns_mappings.insert(namespace.clone(), qn_mappings);
66 qn
67 }
68
69 pub fn create_package<'b>(&self, name: impl IntoIterator<Item = &'b str>) -> Thingy {
77 self.create_package_1(&name.into_iter().collect())
78 }
79
80 fn create_package_1(&self, name: &Vec<&str>) -> Thingy {
81 let mut result: Thingy = self.0.top_level_package.clone();
82 for name_1 in name {
83 let name_1 = (*name_1).to_owned();
84 let result_1 = result.subpackages().get(&name_1);
85 if let Some(result_1) = result_1 {
86 result = result_1;
87 } else {
88 let result_1 = Package::new(&self.0.arena, name_1.clone());
89 result_1.set_parent(Some(result.clone().into()));
90
91 result_1.set_public_ns(Some(self.create_public_ns(Some(result_1.clone().into()))));
93 result_1.set_internal_ns(Some(self.create_internal_ns(Some(result_1.clone().into()))));
94
95 result.subpackages().set(name_1, result_1.clone().into());
96 result = result_1.into();
97 }
98 }
99 result
100 }
101
102 pub fn create_alias(&self, name: QName, alias_of: Thingy) -> Thingy {
103 Alias::new(&self.0.arena, name, alias_of).into()
104 }
105
106 pub fn create_class_type(&self, name: QName, ns_for_prototype: &Thingy) -> Thingy {
111 let r = ClassType::new(&self.0.arena, name);
112 r.set_private_ns(Some(self.create_private_ns(Some(r.clone().into()))));
113 r.set_protected_ns(Some(self.create_protected_ns(Some(r.clone().into()))));
114 r.set_static_protected_ns(Some(self.create_static_protected_ns(Some(r.clone().into()))));
115
116 let prototype_name = self.create_qname(&ns_for_prototype, "prototype".into());
118 let prototype_slot = self.create_variable_slot(&prototype_name, true, &self.0.any_type());
119 prototype_slot.set_is_external(true);
120 r.properties(self.0).set(prototype_name.clone(), prototype_slot);
121
122 r.into()
123 }
124
125 pub fn create_enum_type(&self, name: QName, ns_for_prototype: &Thingy) -> Thingy {
126 let r = EnumType::new(&self.0.arena, name);
127 r.set_private_ns(Some(self.create_private_ns(Some(r.clone().into()))));
128
129 let prototype_name = self.create_qname(&ns_for_prototype, "prototype".into());
131 let prototype_slot = self.create_variable_slot(&prototype_name, true, &self.0.any_type());
132 prototype_slot.set_is_external(true);
133 r.properties(self.0).set(prototype_name.clone(), prototype_slot);
134
135 r.into()
136 }
137
138 pub fn create_interface_type(&self, name: QName) -> Thingy {
139 let r = InterfaceType::new(&self.0.arena, name);
140 r.into()
141 }
142
143 pub fn create_type_after_substitution(&self, origin: &Thingy, substitute_types: &SharedArray<Thingy>) -> Thingy {
145 let params = origin.type_params().unwrap();
147 let param_count = params.length();
148 assert_eq!(substitute_types.length(), param_count);
149
150 let mut tas_list = self.0.types_after_sub.borrow_mut();
151
152 let mut list = tas_list.get(&origin);
153 let empty_list = vec![];
154 if list.is_none() {
155 list = Some(&empty_list);
156 tas_list.insert(origin.clone(), vec![]);
157 }
158 'tas: for tas in list.unwrap() {
159 let mut substitute_types_1 = substitute_types.iter();
160 let substitute_types_2 = tas.substitute_types();
161 let mut substitute_types_2 = substitute_types_2.iter();
162 while let Some(substitute_type_1) = substitute_types_1.next() {
163 let substitute_type_2 = substitute_types_2.next().unwrap();
164 if substitute_type_1 != substitute_type_2 {
165 continue 'tas;
166 }
167 }
168 return tas.clone();
169 }
170
171 let tas = TypeAfterSubstitution::new(&self.0.arena, origin.clone(), substitute_types.clone());
172 let list = tas_list.get_mut(&origin).unwrap();
173 list.push(tas.clone().into());
174
175 tas.into()
176 }
177
178 pub fn create_tuple_type(&self, element_types: Vec<Thingy>) -> Thingy {
180 let element_count = element_types.len();
181 let mut tuple_types = self.0.tuple_types.borrow_mut();
182 let mut collection = tuple_types.get_mut(&element_count);
183 let mut empty_collection = vec![];
184 if collection.is_none() {
185 collection = Some(&mut empty_collection);
186 tuple_types.insert(element_count, vec![]);
187 }
188 'tt: for tt in collection.unwrap() {
189 let mut element_types_1 = element_types.iter();
190 let element_types_2 = tt.element_types();
191 let mut element_types_2 = element_types_2.iter();
192 while let Some(e_1) = element_types_1.next() {
193 let e_2 = element_types_2.next().unwrap();
194 if e_1 != &e_2 {
195 continue 'tt;
196 }
197 }
198 return tt.clone();
199 }
200 let tt = TupleType::new(&self.0.arena, SharedArray::from(element_types));
201
202 let collection = tuple_types.get_mut(&element_count);
203 collection.unwrap().push(tt.clone().into());
204
205 tt.into()
206 }
207
208 pub fn create_function_type(&self, params: Vec<Rc<SemanticFunctionTypeParameter>>, result_type: Thingy) -> Thingy {
210 let param_count = params.len();
211 let mut function_types = self.0.function_types.borrow_mut();
212 let mut collection = function_types.get_mut(¶m_count);
213 let mut empty_collection = vec![];
214 if collection.is_none() {
215 collection = Some(&mut empty_collection);
216 function_types.insert(params.len(), vec![]);
217 }
218 'ft: for ft in collection.unwrap() {
219 if result_type != ft.result_type() {
220 continue 'ft;
221 }
222 let mut params_1 = params.iter();
223 let params_2 = ft.params();
224 let mut params_2 = params_2.iter();
225 while let Some(param_1) = params_1.next() {
226 let param_2 = params_2.next().unwrap();
227 if !(param_1.kind == param_2.kind && && param_1.static_type == &¶m_2.static_type) {
228 continue 'ft;
229 }
230 }
231 return ft.clone();
232 }
233 let ft = FunctionType::new(&self.0.arena, SharedArray::from(params), result_type);
234
235 let collection = function_types.get_mut(¶m_count);
236 collection.unwrap().push(ft.clone().into());
237
238 ft.into()
239 }
240
241 pub fn create_nullable_type(&self, base: &Thingy) -> Thingy {
243 if base == &self.0.any_type() || base.is::<NullableType>() {
244 return base.clone();
245 }
246 if base.is::<NonNullableType>() {
247 return base.base();
248 }
249 let mut m = self.0.nullable_types.borrow_mut();
250 let nt = m.get(base);
251 if let Some(nt) = nt {
252 return nt.clone();
253 }
254 let nt = NullableType::new(&self.0.arena, base.clone());
255 m.insert(base.clone(), nt.clone().into());
256 nt.into()
257 }
258
259 pub fn create_non_nullable_type(&self, base: &Thingy) -> Thingy {
261 if base == &self.0.any_type() || base.is::<NonNullableType>() {
262 return base.clone();
263 }
264 let mut m = self.0.non_nullable_types.borrow_mut();
265 let nt = m.get(base);
266 if let Some(nt) = nt {
267 return nt.clone();
268 }
269 let nt = NonNullableType::new(&self.0.arena, base.clone());
270 m.insert(base.clone(), nt.clone().into());
271 nt.into()
272 }
273
274 pub fn create_type_parameter_type(&self, name: &QName) -> Thingy {
275 TypeParameterType::new(&self.0.arena, name.clone()).into()
276 }
277
278 pub fn create_variable_slot(&self, name: &QName, read_only: bool, static_type: &Thingy) -> Thingy {
279 OriginalVariableSlot::new(&self.0.arena, name, read_only, static_type).into()
280 }
281
282 pub fn create_variable_slot_after_substitution(&self, origin: &Thingy, indirect_type_params: &SharedArray<Thingy>, indirect_substitute_types: &SharedArray<Thingy>) -> Thingy {
284 assert_eq!(indirect_type_params.length(), indirect_substitute_types.length());
286
287 let mut vasub_list = self.0.vasub.borrow_mut();
288
289 let mut base_list = vasub_list.get_mut(origin);
290 let mut empty_base_list = HashMap::<SharedArray<Thingy>, Vec<Thingy>>::new();
291 if base_list.is_none() {
292 base_list = Some(&mut empty_base_list);
293 vasub_list.insert(origin.clone(), HashMap::new());
294 }
295 let base_list = base_list.unwrap();
296
297 let mut list = base_list.get(indirect_type_params);
298 let empty_list = vec![];
299 if list.is_none() {
300 list = Some(&empty_list);
301 base_list.insert(indirect_type_params.clone(), vec![]);
302 }
303 'vasub: for vasub in list.unwrap() {
304 let mut substitute_types_1 = indirect_substitute_types.iter();
305 let substitute_types_2 = vasub.indirect_substitute_types();
306 let mut substitute_types_2 = substitute_types_2.iter();
307 while let Some(substitute_type_1) = substitute_types_1.next() {
308 let substitute_type_2 = substitute_types_2.next().unwrap();
309 if substitute_type_1 != substitute_type_2 {
310 continue 'vasub;
311 }
312 }
313 return vasub.clone();
314 }
315
316 let vasub = VariableSlotAfterSubstitution::new(
317 &self.0.arena,
318 &origin,
319 &indirect_type_params,
320 &indirect_substitute_types.clone());
321
322 let list = vasub_list.get_mut(origin).unwrap().get_mut(&indirect_type_params).unwrap();
323 list.push(vasub.clone().into());
324
325 vasub.into()
326 }
327
328 pub fn create_virtual_slot(&self, name: &QName) -> Thingy {
329 OriginalVirtualSlot::new(&self.0.arena, name).into()
330 }
331
332 pub fn create_virtual_slot_after_substitution(&self, origin: &Thingy, indirect_type_params: &SharedArray<Thingy>, indirect_substitute_types: &SharedArray<Thingy>) -> Thingy {
334 assert_eq!(indirect_type_params.length(), indirect_substitute_types.length());
336
337 let mut visub_list = self.0.visub.borrow_mut();
338
339 let mut base_list = visub_list.get_mut(origin);
340 let mut empty_base_list = HashMap::<SharedArray<Thingy>, Vec<Thingy>>::new();
341 if base_list.is_none() {
342 base_list = Some(&mut empty_base_list);
343 visub_list.insert(origin.clone(), HashMap::new());
344 }
345 let base_list = base_list.unwrap();
346
347 let mut list = base_list.get(indirect_type_params);
348 let empty_list = vec![];
349 if list.is_none() {
350 list = Some(&empty_list);
351 base_list.insert(indirect_type_params.clone(), vec![]);
352 }
353 'visub: for visub in list.unwrap() {
354 let mut substitute_types_1 = indirect_substitute_types.iter();
355 let substitute_types_2 = visub.indirect_substitute_types();
356 let mut substitute_types_2 = substitute_types_2.iter();
357 while let Some(substitute_type_1) = substitute_types_1.next() {
358 let substitute_type_2 = substitute_types_2.next().unwrap();
359 if substitute_type_1 != substitute_type_2 {
360 continue 'visub;
361 }
362 }
363 return visub.clone();
364 }
365
366 let visub = VirtualSlotAfterSubstitution::new(
367 &self.0.arena,
368 &origin,
369 &indirect_type_params,
370 &indirect_substitute_types.clone());
371
372 let list = visub_list.get_mut(origin).unwrap().get_mut(&indirect_type_params).unwrap();
373 list.push(visub.clone().into());
374
375 visub.into()
376 }
377
378 pub fn create_method_slot(&self, name: &QName, signature: &Thingy) -> Thingy {
379 OriginalMethodSlot::new(&self.0.arena, name, signature).into()
380 }
381
382 pub fn create_method_slot_after_substitution(&self, origin: &Thingy, indirect_type_params: &SharedArray<Thingy>, indirect_substitute_types: &SharedArray<Thingy>) -> Thingy {
384 assert_eq!(indirect_type_params.length(), indirect_substitute_types.length());
386
387 let mut mssub_list = self.0.mssub.borrow_mut();
388
389 let mut base_list = mssub_list.get_mut(origin);
390 let mut empty_base_list = HashMap::<SharedArray<Thingy>, Vec<Thingy>>::new();
391 if base_list.is_none() {
392 base_list = Some(&mut empty_base_list);
393 mssub_list.insert(origin.clone(), HashMap::new());
394 }
395 let base_list = base_list.unwrap();
396
397 let mut list = base_list.get(indirect_type_params);
398 let empty_list = vec![];
399 if list.is_none() {
400 list = Some(&empty_list);
401 base_list.insert(indirect_type_params.clone(), vec![]);
402 }
403 'mssub: for mssub in list.unwrap() {
404 let mut substitute_types_1 = indirect_substitute_types.iter();
405 let substitute_types_2 = mssub.indirect_substitute_types();
406 let mut substitute_types_2 = substitute_types_2.iter();
407 while let Some(substitute_type_1) = substitute_types_1.next() {
408 let substitute_type_2 = substitute_types_2.next().unwrap();
409 if substitute_type_1 != substitute_type_2 {
410 continue 'mssub;
411 }
412 }
413 return mssub.clone();
414 }
415
416 let mssub = MethodSlotAfterSubstitution::new(
417 &self.0.arena,
418 &origin,
419 &indirect_type_params,
420 &indirect_substitute_types.clone());
421
422 let list = mssub_list.get_mut(origin).unwrap().get_mut(&indirect_type_params).unwrap();
423 list.push(mssub.clone().into());
424
425 mssub.into()
426 }
427
428 pub fn create_scope(&self) -> Thingy {
429 Scope::new(&self.0.arena).into()
430 }
431
432 pub fn create_with_scope(&self, object: &Thingy) -> Thingy {
433 WithScope::new(&self.0.arena, object).into()
434 }
435
436 pub fn create_filter_scope(&self, base: &Thingy) -> Thingy {
437 FilterScope::new(&self.0.arena, base).into()
438 }
439
440 pub fn create_activation(&self, of_method: &Thingy) -> Thingy {
441 Activation::new(&self.0.arena, of_method).into()
442 }
443
444 pub fn create_class_scope(&self, class: &Thingy) -> Thingy {
445 ClassScope::new(&self.0.arena, class).into()
446 }
447
448 pub fn create_enum_scope(&self, class: &Thingy) -> Thingy {
449 EnumScope::new(&self.0.arena, class).into()
450 }
451
452 pub fn create_interface_scope(&self, itrfc: &Thingy) -> Thingy {
453 InterfaceScope::new(&self.0.arena, itrfc).into()
454 }
455
456 pub fn create_package_scope(&self, pckg: &Thingy) -> Thingy {
457 PackageScope::new(&self.0.arena, pckg).into()
458 }
459
460 pub fn create_value(&self, static_type: &Thingy) -> Thingy {
461 Value::new(&self.0.arena, static_type).into()
462 }
463
464 pub fn create_package_property_import(&self, property: &Thingy, location: Option<Location>) -> Thingy {
465 PackagePropertyImport::new(&self.0.arena, property, location, &self.0.any_type()).into()
466 }
467
468 pub fn create_package_wildcard_import(&self, package: &Thingy, location: Option<Location>) -> Thingy {
469 PackageWildcardImport::new(&self.0.arena, package, location, &self.0.any_type()).into()
470 }
471
472 pub fn create_package_recursive_import(&self, package: &Thingy, location: Option<Location>) -> Thingy {
473 PackageRecursiveImport::new(&self.0.arena, package, location, &self.0.any_type()).into()
474 }
475
476 pub fn create_undefined_constant(&self, static_type: &Thingy) -> Thingy {
477 UndefinedConstant::new(&self.0.arena, static_type).into()
478 }
479
480 pub fn create_null_constant(&self, static_type: &Thingy) -> Thingy {
481 NullConstant::new(&self.0.arena, static_type).into()
482 }
483
484 pub fn create_number_constant(&self, value: NumberVariant, static_type: &Thingy) -> Thingy {
485 NumberConstant::new(&self.0.arena, value, static_type).into()
486 }
487
488 pub fn create_string_constant(&self, value: String, static_type: &Thingy) -> Thingy {
489 StringConstant::new(&self.0.arena, value, static_type).into()
490 }
491
492 pub fn create_boolean_constant(&self, value: bool, static_type: &Thingy) -> Thingy {
493 BooleanConstant::new(&self.0.arena, value, static_type).into()
494 }
495
496 pub fn create_this_object(&self, static_type: &Thingy) -> Thingy {
497 ThisObject::new(&self.0.arena, static_type).into()
498 }
499
500 pub fn create_type_as_reference_value(&self, referenced_type: &Thingy) -> Result<Thingy, DeferError> {
501 Ok(TypeAsReferenceValue::new(&self.0.arena, referenced_type, &self.0.class_type().defer()?).into())
502 }
503
504 pub fn create_namespace_as_reference_value(&self, referenced_ns: &Thingy) -> Result<Thingy, DeferError> {
505 Ok(NamespaceAsReferenceValue::new(&self.0.arena, referenced_ns, &self.0.namespace_type().defer()?).into())
506 }
507
508 pub fn create_xml_reference_value(&self, base: &Thingy, qualifier: Option<Thingy>, key: &Thingy) -> Thingy {
509 XmlReferenceValue::new(&self.0.arena, base, qualifier, key, &self.0.any_type()).into()
510 }
511
512 pub fn create_dynamic_reference_value(&self, base: &Thingy, qualifier: Option<Thingy>, key: &Thingy) -> Thingy {
513 DynamicReferenceValue::new(&self.0.arena, base, qualifier, key, &self.0.any_type()).into()
514 }
515
516 pub fn create_array_element_reference_value(&self, base: &Thingy, key: &Thingy) -> Result<Thingy, DeferError> {
517 let st = base.static_type(self.0).defer()?.escape_of_non_nullable().array_element_type(self.0)?.unwrap();
518 Ok(ArrayElementReferenceValue::new(&self.0.arena, base, key, &st).into())
519 }
520
521 pub fn create_vector_element_reference_value(&self, base: &Thingy, key: &Thingy) -> Result<Thingy, DeferError> {
522 let st = base.static_type(self.0).defer()?.escape_of_non_nullable().vector_element_type(self.0)?.unwrap();
523 Ok(VectorElementReferenceValue::new(&self.0.arena, base, key, &st).into())
524 }
525
526 pub fn create_static_reference_value(&self, base: &Thingy, property: &Thingy) -> Result<Thingy, DeferError> {
527 Ok(StaticReferenceValue::new(&self.0.arena, base, property, &property.property_static_type(self.0).defer()?).into())
528 }
529
530 pub fn create_static_dynamic_reference_value(&self, base: &Thingy, qualifier: Option<Thingy>, key: &Thingy) -> Thingy {
531 StaticDynamicReferenceValue::new(&self.0.arena, base, qualifier, key, &self.0.any_type()).into()
532 }
533
534 pub fn create_instance_reference_value(&self, base: &Thingy, property: &Thingy) -> Result<Thingy, DeferError> {
535 Ok(InstanceReferenceValue::new(&self.0.arena, base, property, &property.property_static_type(self.0).defer()?).into())
536 }
537
538 pub fn create_tuple_reference_value(&self, base: &Thingy, index: usize) -> Thingy {
539 let st = base.static_type(self.0).element_types().get(index).unwrap();
540 TupleReferenceValue::new(&self.0.arena, base, index, &st).into()
541 }
542
543 pub fn create_scope_reference_value(&self, base: &Thingy, property: &Thingy) -> Result<Thingy, DeferError> {
544 Ok(ScopeReferenceValue::new(&self.0.arena, base, property, &property.property_static_type(self.0).defer()?).into())
545 }
546
547 pub fn create_dynamic_scope_reference_value(&self, base: &Thingy, qualifier: Option<Thingy>, key: &Thingy) -> Thingy {
548 DynamicScopeReferenceValue::new(&self.0.arena, base, qualifier, key, &self.0.any_type()).into()
549 }
550
551 pub fn create_package_reference_value(&self, base: &Thingy, property: &Thingy) -> Result<Thingy, DeferError> {
552 Ok(PackageReferenceValue::new(&self.0.arena, base, property, &property.property_static_type(self.0).defer()?).into())
553 }
554
555 pub fn create_conversion_value(&self, base: &Thingy, variant: TypeConversionVariant, opt: bool, target: &Thingy) -> Result<Thingy, DeferError> {
556 let mut st = if opt && !target.includes_null(self.0)? {
557 if target.is::<NonNullableType>() {
558 target.base()
559 } else {
560 self.create_nullable_type(target)
561 }
562 } else { target.clone() };
563 if opt && !st.includes_null(self.0)? {
564 st = self.create_nullable_type(target);
565 }
566 Ok(ConversionValue::new(&self.0.arena, base, variant, opt, target, &st).into())
567 }
568
569 pub fn create_lambda_object(&self, activation: &Thingy) -> Result<Thingy, DeferError> {
570 Ok(LambdaObject::new(&self.0.arena, activation, &self.0.function_type().defer()?).into())
571 }
572}