use crate::ns::*; use bitflags::bitflags; use smodel::smodel; smodel! { type Arena = ThingyArena; /// Unified semantic data type representing /// one of several ActionScript 3 variants, /// such as classes, variable slots, and reference values. pub struct Thingy { pub fn defer(&self) -> Result { if self.is::() { Err(DeferError(None)) } else { Ok(self.clone()) } } pub fn location(&self) -> Option { panic!(); } pub fn set_location(&self, loc: Option) { panic!(); } pub fn qualifier(&self) -> Option { panic!(); } pub fn key(&self) -> Thingy { panic!(); } /// Returns the static type of a property, whether for a type, variable, virtual or method slot or namespace, /// or act as identity of a value's static type. /// Possibly `UnresolvedThingy`. pub fn property_static_type(&self, host: &SemanticHost) -> Thingy { panic!(); } pub fn is_dynamic_or_inherits_dynamic(&self, host: &SemanticHost) -> Result { Ok(false) } pub fn tuple_index(&self) -> usize { 0 } pub fn system_ns_kind(&self) -> Option { None } pub fn asdoc(&self) -> Option> { None } pub fn set_asdoc(&self, asdoc: Option>) {} pub fn metadata(&self) -> SharedArray> { panic!(); } /// Indicates whether a variable slot is optional for an object initializer /// applied to an `[Options]` class. pub fn is_opt_variable_for_options_class(&self, host: &SemanticHost) -> Result { let st = self.static_type(host).defer()?; Ok(st.includes_null(host)? || st.includes_undefined(host)?) } /// Escapes out of a nullable type layer. pub fn escape_of_nullable(&self) -> Thingy { self.clone() } /// Escapes out of a non nullable type layer. pub fn escape_of_non_nullable(&self) -> Thingy { self.clone() } /// Escapes out of a nullable or non nullable type layer. pub fn escape_of_nullable_or_non_nullable(&self) -> Thingy { self.clone() } pub fn object(&self) -> Thingy { panic!(); } pub fn uri(&self) -> String { "".into() } pub fn open_ns_set(&self) -> SharedArray { panic!(); } pub fn import_list(&self) -> SharedArray { panic!(); } pub fn is_class_or_equivalent(&self) -> bool { self.is_class_type_possibly_after_sub() || self.is::() || self.is::() || self.is::() } pub fn local_name(&self) -> String { "".into() } pub fn class(&self) -> Thingy { panic!(); } pub fn interface(&self) -> Thingy { panic!(); } pub fn package(&self) -> Thingy { panic!(); } pub fn of_method(&self) -> Thingy { panic!(); } pub fn search_activation(&self) -> Option { for scope in self.descending_scope_hierarchy() { if scope.is::() { return Some(scope); } } return None } pub fn this(&self) -> Option { panic!(); } pub fn set_this(&self, this: Option) { panic!(); } pub fn property_has_capture(&self, property: &Thingy) -> bool { panic!(); } pub fn set_property_has_capture(&self, property: &Thingy, value: bool) { panic!(); } pub fn concat_open_ns_set_of_scope_chain(&self) -> SharedArray { let mut open_ns_set = SharedArray::new(); open_ns_set.extend(self.open_ns_set().iter()); let mut p = self.parent(); while let Some(p1) = p { open_ns_set.extend(p1.open_ns_set().iter()); p = p1.parent(); } open_ns_set } pub fn referenced_type(&self) -> Thingy { panic!(); } pub fn referenced_ns(&self) -> Thingy { panic!(); } pub fn shorthand_resolution(&self) -> Option { panic!(); } pub fn set_shorthand_resolution(&self, value: Option) { panic!(); } pub fn field_slot(&self) -> Option { panic!(); } pub fn set_field_slot(&self, value: Option) { panic!(); } pub fn is_entity_after_substitution(&self) -> bool { self.is::() || self.is::() || self.is::() || self.is::() } pub fn parent(&self) -> Option { panic!(); } pub fn set_parent(&self, p: Option) { panic!(); } pub fn package_concats(&self) -> SharedArray { panic!(); } pub fn public_ns(&self) -> Option { panic!(); } pub fn set_public_ns(&self, ns: Option) { panic!(); } pub fn private_ns(&self) -> Option { panic!(); } pub fn set_private_ns(&self, ns: Option) { panic!(); } pub fn protected_ns(&self) -> Option { panic!(); } pub fn set_protected_ns(&self, ns: Option) { panic!(); } pub fn static_protected_ns(&self) -> Option { panic!(); } pub fn set_static_protected_ns(&self, ns: Option) { panic!(); } pub fn internal_ns(&self) -> Option { panic!(); } pub fn set_internal_ns(&self, ns: Option) { panic!(); } pub fn is_public_ns(&self) -> bool { false } pub fn is_private_ns(&self) -> bool { false } pub fn is_protected_ns(&self) -> bool { false } pub fn is_internal_ns(&self) -> bool { false } pub fn is_static_protected_ns(&self) -> bool { false } pub fn is_parameterized_type_or_type_after_sub(&self) -> bool { if self.is::() || self.is::() { self.type_params().is_some() } else { self.is::() } } pub fn is_package_self_referential(&self, pckg: &Thingy) -> bool { if self == pckg { return true; } let mut p = self.parent(); while let Some(p1) = p { if &p1 == pckg { return true; } p = p1.parent(); } false } pub fn is_global_initialization(&self) -> bool { panic!(); } pub fn set_is_global_initialization(&self, value: bool) { panic!(); } pub fn is_package_initialization(&self) -> bool { panic!(); } pub fn set_is_package_initialization(&self, value: bool) { panic!(); } pub fn number_value(&self) -> NumberVariant { panic!(); } pub fn string_value(&self) -> String { panic!(); } pub fn boolean_value(&self) -> bool { panic!(); } pub fn type_default_value(&self, host: &SemanticHost) -> Result, DeferError> { panic!(); } pub fn conversion_variant(&self) -> TypeConversionVariant { panic!(); } pub fn conversion_is_opt(&self) -> bool { panic!(); } pub fn conversion_target(&self) -> Thingy { panic!(); } /// Returns whether a type is a class, whether /// original or after substitution. pub fn is_class_type_possibly_after_sub(&self) -> bool { false } /// Returns whether a type is an interface, whether /// original or after substitution. pub fn is_interface_type_possibly_after_sub(&self) -> bool { false } /// Event mapping from `[Event(name="eventName", type="T")]` meta-data. pub fn flex_events(&self) -> SharedMap { panic!(); } pub fn bindable_event(&self) -> Option { panic!(); } pub fn set_bindable_event(&self, name: Option) { panic!(); } pub fn scope(&self) -> Thingy { panic!(); } pub fn getter(&self, host: &SemanticHost) -> Option { panic!(); } pub fn set_getter(&self, m: Option) { panic!(); } pub fn setter(&self, host: &SemanticHost) -> Option { panic!(); } pub fn set_setter(&self, m: Option) { panic!(); } pub fn static_type(&self, host: &SemanticHost) -> Thingy { panic!(); } pub fn set_static_type(&self, value: Thingy) { panic!(); } pub fn clone_constant(&self, host: &SemanticHost) -> Thingy { panic!(); } pub fn is_abstract(&self) -> bool { false } pub fn set_is_abstract(&self, value: bool) { } pub fn is_final(&self) -> bool { false } pub fn set_is_final(&self, value: bool) { } pub fn is_dynamic(&self) -> bool { false } pub fn set_is_dynamic(&self, value: bool) { } pub fn is_options_class(&self) -> bool { false } pub fn set_is_options_class(&self, value: bool) { } pub fn is_static(&self) -> bool { false } pub fn set_is_static(&self, value: bool) { } pub fn is_overriding(&self) -> bool { false } pub fn set_is_overriding(&self, value: bool) { } pub fn is_async(&self) -> bool { false } pub fn set_is_async(&self, value: bool) { } pub fn is_generator(&self) -> bool { false } pub fn set_is_generator(&self, value: bool) { } pub fn signature(&self, host: &SemanticHost) -> Thingy { panic!(); } pub fn set_signature(&self, signature: &Thingy) { panic!(); } /// If a type is `[T]`, returns `T`, either as an origin type parameter /// or as a substitute type. pub fn array_element_type(&self, host: &SemanticHost) -> Result, DeferError> { let array_type = host.array_type().defer()?; if self == &array_type { Ok(Some(array_type.type_params().unwrap().get(0).unwrap())) } else if self.type_after_sub_has_origin(&array_type) { Ok(Some(self.substitute_types().get(0).unwrap())) } else { Ok(None) } } /// If a type is `Vector.`, returns `T`, either as an origin type parameter /// or as a substitute type. pub fn vector_element_type(&self, host: &SemanticHost) -> Result, DeferError> { let vec_type = host.vector_type().defer()?; if self == &vec_type { Ok(Some(vec_type.type_params().unwrap().get(0).unwrap())) } else if self.type_after_sub_has_origin(&vec_type) { Ok(Some(self.substitute_types().get(0).unwrap())) } else { Ok(None) } } /// If a type is `Promise.`, returns `T`, either as an origin type parameter /// or as a substitute type. pub fn promise_result_type(&self, host: &SemanticHost) -> Result, DeferError> { let promise_type = host.promise_type().defer()?; if self == &promise_type { Ok(Some(promise_type.type_params().unwrap().get(0).unwrap())) } else if self.type_after_sub_has_origin(&promise_type) { Ok(Some(self.substitute_types().get(0).unwrap())) } else { Ok(None) } } pub fn type_after_sub_has_origin(&self, origin: &Thingy) -> bool { self.is::() && &self.origin() == origin } pub fn is_type_or_type_after_sub_has_origin(&self, type_or_origin: &Thingy) -> bool { self == type_or_origin || self.type_after_sub_has_origin(type_or_origin) } pub fn origin_or_parameterized_type_identity(&self) -> Option { if self.is::() { Some(self.origin()) } else if self.type_params().is_some() { Some(self.clone()) } else { None } } /// Iterator over a descending class hierarchy. pub fn descending_class_hierarchy<'a>(&self, host: &'a SemanticHost) -> DescendingClassHierarchy<'a> { DescendingClassHierarchy(Some(self.clone()), host, self.clone()) } /// Iterator over a descending scope hierarchy. pub fn descending_scope_hierarchy(&self) -> DescendingScopeHierarchy { DescendingScopeHierarchy(Some(self.clone())) } /// Iterator over a descending definition hierarchy. pub fn descending_definition_hierarchy(&self) -> DescendingDefinitionHierarchy { DescendingDefinitionHierarchy(Some(self.clone())) } pub fn is_namespace_or_ns_constant(&self) -> bool { false } pub fn wrap_property_reference(&self, host: &SemanticHost) -> Result { if self.is::() { return Ok(self.clone()); } if self.is::() && ( self.is::() || self.is::() || self.is::() || self.is::() || self.is::() || self.is::() || self.is::()) { return host.factory().create_type_constant(self); } if self.is::() { return host.factory().create_namespace_constant(self); } if self.is::() { return Ok(self.clone()); } let parent = self.parent().unwrap(); if parent.is::() || parent.is::() { return host.factory().create_static_reference_value(&parent, self); } if parent.is::() { return host.factory().create_package_reference_value(&parent, self); } assert!(parent.is::()); return host.factory().create_scope_reference_value(&parent, self); } pub fn activation(&self) -> Option { panic!(); } pub fn set_activation(&self, activation: Option) { panic!(); } pub fn of_virtual_slot(&self, host: &SemanticHost) -> Option { panic!(); } pub fn set_of_virtual_slot(&self, virtual_slot: Option) { panic!(); } pub fn overriden_by(&self, host: &SemanticHost) -> SharedArray { panic!(); } pub fn overrides_method(&self, host: &SemanticHost) -> Option { panic!(); } pub fn set_overrides_method(&self, method: Option) { panic!(); } pub fn is_constructor(&self) -> bool { false } pub fn set_is_constructor(&self, value: bool) { } pub fn constructor_method(&self, host: &SemanticHost) -> Option { panic!(); } pub fn set_constructor_method(&self, m: Option) {} pub fn known_subclasses(&self) -> SharedArray { panic!(); } /// Includes possibly unresolved. pub fn implements(&self, host: &SemanticHost) -> SharedArray { panic!(); } /// Possibly unresolved. pub fn extends_class(&self, host: &SemanticHost) -> Option { None } pub fn set_extends_class(&self, entity: Option) { panic!(); } pub fn prototype(&self, host: &SemanticHost) -> NameMap { panic!(); } pub fn properties(&self, host: &SemanticHost) -> NameMap { panic!(); } pub fn subpackages(&self) -> SharedMap { panic!(); } pub fn alias_of(&self) -> Thingy { panic!(); } pub fn set_alias_of(&self, value: &Thingy) { panic!(); } pub fn resolve_alias(&self) -> Thingy { self.clone() } pub fn property(&self) -> Thingy { panic!(); } pub fn set_property(&self, value: &Thingy) { panic!(); } pub fn includes_undefined(&self, host: &SemanticHost) -> Result { panic!(); } pub fn includes_null(&self, host: &SemanticHost) -> Result { panic!(); } pub fn name(&self) -> QName { panic!(); } pub fn fully_qualified_name(&self) -> String { self.fully_qualified_name_list().join(".").replace("__AS3__.vec.Vector", "Vector") } pub fn fully_qualified_name_list(&self) -> Vec { let mut r: Vec = vec![]; let mut p = Some(self.clone()); while let Some(p1) = p { let name = if p1.is::() { p1.local_name() } else { p1.name().to_string() }; if !name.is_empty() { r.insert(0, name); } p = p1.parent(); } r } pub fn type_params(&self) -> Option> { None } pub fn set_type_params(&self, list: Option>) { } pub fn enum_member_number_mapping(&self) -> SharedMap { panic!(); } pub fn enum_member_slot_mapping(&self) -> SharedMap { panic!(); } pub fn known_implementors(&self) -> SharedArray { panic!(); } /// Includes possibly unresolved. pub fn extends_interfaces(&self, host: &SemanticHost) -> SharedArray { panic!(); } pub fn origin(&self) -> Thingy { panic!(); } pub fn substitute_types(&self) -> SharedArray { panic!(); } pub fn indirect_type_params(&self) -> SharedArray { panic!(); } pub fn indirect_substitute_types(&self) -> SharedArray { panic!(); } pub fn element_types(&self) -> SharedArray { panic!(); } pub fn params(&self) -> SharedArray> { panic!(); } pub fn result_type(&self) -> Thingy { panic!(); } pub fn base(&self) -> Thingy { panic!(); } /// Performs type substitution. pub fn type_substitution(&self, host: &SemanticHost, type_params: &SharedArray, substitute_types: &SharedArray) -> Thingy { TypeSubstitution(host).exec(self, type_params, substitute_types) } pub fn read_only(&self, host: &SemanticHost) -> bool { true } pub fn set_read_only(&self, value: bool) { panic!(); } pub fn write_only(&self, host: &SemanticHost) -> bool { false } pub fn set_write_only(&self, value: bool) { panic!(); } pub fn deletable(&self, host: &SemanticHost) -> bool { false } pub fn var_constant(&self) -> Option { panic!(); } pub fn set_var_constant(&self, k: Option) { panic!(); } pub fn is_ascending_type_of(&self, possibly_subtype: &Thingy, host: &SemanticHost) -> Result { possibly_subtype.is_subtype_of(self, host) } pub fn is_subtype_of(&self, possibly_ascending_type: &Thingy, host: &SemanticHost) -> Result { if possibly_ascending_type.is::() { return Ok(true); } for t in self.all_ascending_types(host) { // Defer if unresolved t.defer()?; if &t == possibly_ascending_type { return Ok(true); } } Ok(false) } pub fn is_equals_or_subtype_of(&self, other: &Thingy, host: &SemanticHost) -> Result { Ok(self == other || self.is_subtype_of(other, host)?) } /// Returns all ascending types of a type in ascending type order, /// each possibly unresolved. pub fn all_ascending_types(&self, host: &SemanticHost) -> Vec { self.all_ascending_types_non_circular(host, self) } fn all_ascending_types_non_circular(&self, host: &SemanticHost, descending_most: &Thingy) -> Vec { let mut r = vec![]; let mut r2 = vec![]; for type_thing in self.direct_ascending_types(host) { if !type_thing.is::() { if &type_thing != descending_most { for type1 in type_thing.all_ascending_types(host) { if !r.contains(&type1) && &type1 != descending_most { r.push(type1.clone()); } } } } if !r.contains(&type_thing) && &type_thing != descending_most { r2.push(type_thing.clone()); } } r.extend(r2); r } /// Returns direct ascending types of a type, each possibly unresolved. pub fn direct_ascending_types(&self, host: &SemanticHost) -> Vec { if self.is::() { let mut r: Vec = self.implements(host).iter().collect(); if let Some(ascending_class) = self.extends_class(host) { r.push(ascending_class); } return r; } else if self.is::() { return vec![self.extends_class(host).unwrap()]; } else if self.is::() { return self.extends_interfaces(host).iter().collect(); } else if self.is::() { return vec![host.function_type()]; } else if self.is::() { return vec![host.array_type_of_any().unwrap_or(host.unresolved_thingy())]; } else if self.is::() { return vec![]; } return vec![]; } pub(crate) fn not_overriden_abstract_getter(&self, getter_from_base_class: &Thingy, subclass: &Thingy, host: &SemanticHost) -> bool { if getter_from_base_class.is_abstract() { let name = &getter_from_base_class.name(); let prop2 = if name.namespace().is::() { subclass.prototype(host).get_in_system_ns_kind(name.namespace().system_ns_kind().unwrap(), &name.local_name()).ok().unwrap_or(None) } else { subclass.prototype(host).get(name) }; prop2.is_none() || !prop2.clone().unwrap().is::() || prop2.unwrap().getter(host).is_none() } else { false } } pub(crate) fn not_overriden_abstract_setter(&self, setter_from_base_class: &Thingy, subclass: &Thingy, host: &SemanticHost) -> bool { if setter_from_base_class.is_abstract() { let name = &setter_from_base_class.name(); let prop2 = if name.namespace().is::() { subclass.prototype(host).get_in_system_ns_kind(name.namespace().system_ns_kind().unwrap(), &name.local_name()).ok().unwrap_or(None) } else { subclass.prototype(host).get(name) }; prop2.is_none() || !prop2.clone().unwrap().is::() || prop2.unwrap().setter(host).is_none() } else { false } } pub fn is_comparison_between_unrelated_types(&self, other: &Thingy, host: &SemanticHost) -> Result { let left = self.escape_of_nullable_or_non_nullable(); let right = other.escape_of_nullable_or_non_nullable(); if left == right || [left.clone(), right.clone()].contains(&host.any_type()) { return Ok(false); } let primitive_types = host.primitive_types()?; if primitive_types.contains(&left) || primitive_types.contains(&right) { return Ok(false); } if !(left.is_ascending_type_of(&right, host)? || left.is_subtype_of(&right, host)?) { return Ok(true); } Ok(false) } pub fn expect_type(&self) -> Result { if let Some(t) = self.as_type() { Ok(t) } else { Err(TypeExpectError()) } } pub fn as_type(&self) -> Option { if self.is::() { return Some(self.referenced_type()); } if self.is::() { return self.property().as_type(); } if self.is::() { Some(self.clone()) } else { None } } pub fn fixture_reference_value_equals(&self, other: &Thingy) -> bool { if other.is::() { if self.is::() { self.property() == other.property() } else { self == &other.property() } } else if self.is::() { &self.property() == other } else { self == other } } pub fn control_flow_graph(&self) -> ControlFlowGraph { panic!(); } /// Lookups property in an object. pub fn lookup_in_object(&self, host: &SemanticHost, open_ns_set: &SharedArray, qual: Option, key: &PropertyLookupKey) -> Result, PropertyLookupError> { PropertyLookup(host).lookup_in_object(self, open_ns_set, qual, key) } /// Lookups property in the scope chain. pub fn lookup_in_scope_chain(&self, host: &SemanticHost, qual: Option, key: &PropertyLookupKey) -> Result, PropertyLookupError> { PropertyLookup(host).lookup_in_scope_chain(self, qual, key) } pub fn search_system_ns_in_scope_chain(&self, ns: SystemNamespaceKind) -> Option { let mut scope = Some(self.clone()); while let Some(scope1) = scope { if scope1.is::() || scope1.is::() { if ns == SystemNamespaceKind::Public { return scope1.public_ns(); } if ns == SystemNamespaceKind::Internal { return scope1.internal_ns(); } } else if scope1.is::() { if ns == SystemNamespaceKind::Private { return scope1.private_ns(); } if ns == SystemNamespaceKind::Protected { return scope1.protected_ns(); } if ns == SystemNamespaceKind::StaticProtected { return scope1.static_protected_ns(); } } else if scope1.is::() { if ns == SystemNamespaceKind::Private { return scope1.private_ns(); } } scope = scope1.parent(); } None } pub fn field_reference(&self) -> Option { panic!(); } pub fn set_field_reference(&self, value: Option) { panic!(); } pub fn var_slot(&self) -> Option { panic!(); } pub fn set_var_slot(&self, value: Option) { panic!(); } pub fn target_reference(&self) -> Option { panic!(); } pub fn set_target_reference(&self, value: Option) { panic!(); } pub fn search_hoist_scope(&self) -> Thingy { let mut scope = Some(self.clone()); while let Some(scope1) = scope { if scope1.is::() || scope1.is::() { return scope1; } scope = scope1.parent(); } scope.unwrap() } pub fn is_empty_package(&self, host: &SemanticHost) -> bool { if self.properties(host).length() != 0 { return false; } for pckg in self.package_concats().iter() { if !pckg.is_empty_package(host) { return false; } } true } pub fn is_empty_package_recursive(&self, host: &SemanticHost) -> bool { if !self.is_empty_package(host) { return false; } for (_, pckg) in self.subpackages().borrow().iter() { if !pckg.is_empty_package_recursive(host) { return false; } } true } pub fn list_packages_recursively(&self) -> Vec { let mut r: Vec = vec![self.clone()]; for (_, pckg) in self.subpackages().borrow().iter() { r.extend(pckg.list_packages_recursively()); } r } fn to_string_1(&self) -> String { "".into() } } pub struct UnresolvedThingy: Thingy { pub(crate) fn UnresolvedThingy() { super(); } } /// Thingy used to indicate that an entity is invalidated. pub struct InvalidationThingy: Thingy { pub(crate) fn InvalidationThingy() { super(); } #[inheritdoc] pub override fn property_static_type(&self, host: &SemanticHost) -> Thingy { self.clone().into() } pub override fn static_type(&self, host: &SemanticHost) -> Thingy { self.clone().into() } pub override fn includes_undefined(&self, host: &SemanticHost) -> Result { Ok(true) } pub override fn includes_null(&self, host: &SemanticHost) -> Result { Ok(true) } override fn to_string_1(&self) -> String { "[unknown]".into() } } pub struct Namespace: Thingy { pub(crate) fn Namespace() { super(); } #[inheritdoc] pub override fn property_static_type(&self, host: &SemanticHost) -> Thingy { host.namespace_type() } pub override fn is_namespace_or_ns_constant(&self) -> bool { true } } pub struct SystemNamespace: Namespace { let m_kind: SystemNamespaceKind = SystemNamespaceKind::Public; let ref m_parent: Option = None; pub(crate) fn SystemNamespace(kind: SystemNamespaceKind, parent: Option) { super(); self.set_m_kind(kind); self.set_m_parent(parent); } pub override fn system_ns_kind(&self) -> Option { Some(self.m_kind()) } pub override fn is_public_ns(&self) -> bool { self.m_kind() == SystemNamespaceKind::Public } pub override fn is_private_ns(&self) -> bool { self.m_kind() == SystemNamespaceKind::Private } pub override fn is_protected_ns(&self) -> bool { self.m_kind() == SystemNamespaceKind::Protected } pub override fn is_internal_ns(&self) -> bool { self.m_kind() == SystemNamespaceKind::Internal } pub override fn is_static_protected_ns(&self) -> bool { self.m_kind() == SystemNamespaceKind::StaticProtected } pub override fn parent(&self) -> Option { self.m_parent() } override fn to_string_1(&self) -> String { self.m_kind().to_string() } } /// In the AVM2, this is equivalent to a `CONSTANT_Namespace` namespace. pub struct UserNamespace: Namespace { let ref m_uri: String = "".into(); pub(crate) fn UserNamespace(uri: String) { super(); self.set_m_uri(uri); } pub override fn uri(&self) -> String { self.m_uri() } override fn to_string_1(&self) -> String { self.m_uri() } } /// In the AVM2, this is equivalent to a `CONSTANT_ExplicitNamespace` namespace. pub struct ExplicitNamespace: Namespace { let ref m_uri: String = "".into(); pub(crate) fn ExplicitNamespace(uri: String) { super(); self.set_m_uri(uri); } pub override fn uri(&self) -> String { self.m_uri() } override fn to_string_1(&self) -> String { self.m_uri() } } /// A package consists of a local name, two namespaces, `public` and `internal`, /// and a mapping of subpackages. pub struct Package: Thingy { let ref m_name: String = "".into(); let ref m_parent: Option = None; let ref m_public_ns: Option = None; let ref m_internal_ns: Option = None; let ref m_properties: NameMap = NameMap::new(); let ref m_subpackages: SharedMap = SharedMap::new(); let ref m_package_concats: SharedArray = SharedArray::new(); let ref m_asdoc: Option> = None; pub(crate) fn Package(name: String) { super(); self.set_m_name(name); } /// The local name of the package. For the top-level package /// this is the empty string. pub override fn local_name(&self) -> String { self.m_name() } pub override fn parent(&self) -> Option { self.m_parent() } pub override fn set_parent(&self, p: Option) { self.set_m_parent(p); } /// Concatenated packages. pub override fn package_concats(&self) -> SharedArray { self.m_package_concats() } pub override fn public_ns(&self) -> Option { self.m_public_ns() } pub override fn set_public_ns(&self, ns: Option) { self.set_m_public_ns(ns); } pub override fn internal_ns(&self) -> Option { self.m_internal_ns() } pub override fn set_internal_ns(&self, ns: Option) { self.set_m_internal_ns(ns); } pub override fn properties(&self, host: &SemanticHost) -> NameMap { self.m_properties() } pub override fn subpackages(&self) -> SharedMap { self.m_subpackages() } pub override fn asdoc(&self) -> Option> { self.m_asdoc() } pub override fn set_asdoc(&self, asdoc: Option>) { self.set_m_asdoc(asdoc); } override fn to_string_1(&self) -> String { self.fully_qualified_name() } } pub struct Alias: Thingy { let ref m_name: Option = None; let ref m_alias_of: Option = None; let ref m_parent: Option = None; let ref m_location: Option = None; pub(crate) fn Alias(name: QName, alias_of: Thingy) { super(); self.set_m_name(Some(name)); self.set_m_alias_of(Some(alias_of)); } pub override fn name(&self) -> QName { self.m_name().unwrap() } pub override fn alias_of(&self) -> Thingy { self.m_alias_of().unwrap() } pub override fn set_alias_of(&self, value: &Thingy) { self.set_m_alias_of(Some(value.clone())); } pub override fn location(&self) -> Option { self.m_location() } pub override fn set_location(&self, loc: Option) { self.set_m_location(loc); } pub override fn resolve_alias(&self) -> Thingy { self.alias_of().resolve_alias() } pub override fn parent(&self) -> Option { self.m_parent() } pub override fn set_parent(&self, p: Option) { self.set_m_parent(p); } override fn to_string_1(&self) -> String { self.alias_of().to_string_1() } } pub struct Type: Thingy { pub override fn includes_undefined(&self, host: &SemanticHost) -> Result { Ok(true) } pub override fn includes_null(&self, host: &SemanticHost) -> Result { Ok(false) } #[inheritdoc] pub override fn property_static_type(&self, host: &SemanticHost) -> Thingy { host.class_type() } pub override fn type_default_value(&self, host: &SemanticHost) -> Result, DeferError> { if self.includes_undefined(host)? { Ok(Some(host.factory().create_undefined_constant(self))) } else if self.includes_null(host)? { Ok(Some(host.factory().create_null_constant(self))) } else if host.numeric_types()?.contains(self) { if host.floating_point_types()?.contains(self) { let v = NumberVariant::nan(self, host); return Ok(Some(host.factory().create_number_constant(v, self))); } let v = NumberVariant::zero(self, host); Ok(Some(host.factory().create_number_constant(v, self))) } else if >::into(self.clone()) == host.boolean_type().defer()? { Ok(Some(host.factory().create_boolean_constant(false, self))) } else { Ok(None) } } } pub struct AnyType : Type { pub(crate) fn AnyType() { super(); } pub override fn includes_undefined(&self, host: &SemanticHost) -> Result { Ok(true) } pub override fn includes_null(&self, host: &SemanticHost) -> Result { Ok(true) } override fn to_string_1(&self) -> String { "*".into() } } pub struct VoidType : Type { pub(crate) fn VoidType() { super(); } pub override fn includes_undefined(&self, host: &SemanticHost) -> Result { Ok(true) } pub override fn includes_null(&self, host: &SemanticHost) -> Result { Ok(false) } override fn to_string_1(&self) -> String { "void".into() } } pub struct ClassType: Type { let ref m_name: Option = None; let m_flags: ClassTypeFlags = ClassTypeFlags::empty(); let ref m_type_params: Option> = None; let ref m_extends_class: Option = None; let ref m_implements: SharedArray = SharedArray::new(); let ref m_known_subclasses: SharedArray = SharedArray::new(); let ref m_constructor_method: Option = None; let ref m_parent: Option = None; let ref m_private_ns: Option = None; let ref m_protected_ns: Option = None; let ref m_static_protected_ns: Option = None; let ref m_properties: NameMap = NameMap::new(); let ref m_prototype: NameMap = NameMap::new(); let ref m_flex_events: SharedMap = SharedMap::new(); let ref m_asdoc: Option> = None; let ref m_metadata: SharedArray> = SharedArray::new(); let ref m_location: Option = None; pub(crate) fn ClassType(name: QName) { super(); self.set_m_name(Some(name)); } pub override fn is_class_type_possibly_after_sub(&self) -> bool { true } pub override fn name(&self) -> QName { self.m_name().unwrap() } pub override fn location(&self) -> Option { self.m_location() } pub override fn set_location(&self, loc: Option) { self.set_m_location(loc); } #[inheritdoc] pub override fn flex_events(&self) -> SharedMap { self.m_flex_events() } pub override fn private_ns(&self) -> Option { self.m_private_ns() } pub override fn set_private_ns(&self, ns: Option) { self.set_m_private_ns(ns); } pub override fn protected_ns(&self) -> Option { self.m_protected_ns() } pub override fn set_protected_ns(&self, ns: Option) { self.set_m_protected_ns(ns); } pub override fn static_protected_ns(&self) -> Option { self.m_static_protected_ns() } pub override fn set_static_protected_ns(&self, ns: Option) { self.set_m_static_protected_ns(ns); } pub override fn type_params(&self) -> Option> { self.m_type_params() } pub override fn set_type_params(&self, list: Option>) { self.set_m_type_params(list); } pub override fn is_abstract(&self) -> bool { self.m_flags().contains(ClassTypeFlags::IS_ABSTRACT) } pub override fn set_is_abstract(&self, value: bool) { let mut v = self.m_flags(); v.set(ClassTypeFlags::IS_ABSTRACT, value); self.set_m_flags(v); } pub override fn is_final(&self) -> bool { self.m_flags().contains(ClassTypeFlags::IS_FINAL) } pub override fn set_is_final(&self, value: bool) { let mut v = self.m_flags(); v.set(ClassTypeFlags::IS_FINAL, value); self.set_m_flags(v); } pub override fn is_static(&self) -> bool { self.m_flags().contains(ClassTypeFlags::IS_STATIC) } pub override fn set_is_static(&self, value: bool) { let mut v = self.m_flags(); v.set(ClassTypeFlags::IS_STATIC, value); self.set_m_flags(v); } pub override fn is_dynamic(&self) -> bool { self.m_flags().contains(ClassTypeFlags::IS_DYNAMIC) } pub override fn set_is_dynamic(&self, value: bool) { let mut v = self.m_flags(); v.set(ClassTypeFlags::IS_DYNAMIC, value); self.set_m_flags(v); } pub override fn is_dynamic_or_inherits_dynamic(&self, host: &SemanticHost) -> Result { if self.is_dynamic() { return Ok(true); } if let Some(cb) = self.extends_class(host) { cb.is_dynamic_or_inherits_dynamic(host) } else { Ok(false) } } /// Whether the class is an `[Options]` class. pub override fn is_options_class(&self) -> bool { self.m_flags().contains(ClassTypeFlags::IS_OPTIONS_CLASS) } pub override fn set_is_options_class(&self, value: bool) { let mut v = self.m_flags(); v.set(ClassTypeFlags::IS_OPTIONS_CLASS, value); self.set_m_flags(v); } pub override fn known_subclasses(&self) -> SharedArray { self.m_known_subclasses() } #[inheritdoc] pub override fn implements(&self, host: &SemanticHost) -> SharedArray { self.m_implements() } #[inheritdoc] pub override fn extends_class(&self, host: &SemanticHost) -> Option { self.m_extends_class() } pub override fn set_extends_class(&self, entity: Option) { self.set_m_extends_class(entity); } pub override fn properties(&self, host: &SemanticHost) -> NameMap { self.m_properties() } pub override fn prototype(&self, host: &SemanticHost) -> NameMap { self.m_prototype() } pub override fn constructor_method(&self, host: &SemanticHost) -> Option { self.m_constructor_method() } pub override fn set_constructor_method(&self, m: Option) { self.set_m_constructor_method(m); } pub override fn parent(&self) -> Option { self.m_parent() } pub override fn set_parent(&self, p: Option) { self.set_m_parent(p); } pub override fn asdoc(&self) -> Option> { self.m_asdoc() } pub override fn set_asdoc(&self, asdoc: Option>) { self.set_m_asdoc(asdoc); } pub override fn metadata(&self) -> SharedArray> { self.m_metadata() } pub override fn includes_undefined(&self, host: &SemanticHost) -> Result { Ok(false) } pub override fn includes_null(&self, host: &SemanticHost) -> Result { Ok(!host.non_null_primitive_types()?.contains(&self.clone().into())) } override fn to_string_1(&self) -> String { let name_1 = self.fully_qualified_name(); let mut p = String::new(); if let Some(type_params) = self.type_params() { p = ".<".to_owned() + &type_params.iter().map(|p| p.to_string()).collect::>().join(", ") + ">"; } name_1 + &p } } pub struct EnumType: Type { let ref m_name: Option = None; let ref m_parent: Option = None; let ref m_private_ns: Option = None; let ref m_properties: NameMap = NameMap::new(); let ref m_prototype: NameMap = NameMap::new(); let ref m_number_mapping: SharedMap = SharedMap::new(); let ref m_slot_mapping: SharedMap = SharedMap::new(); let ref m_asdoc: Option> = None; let ref m_metadata: SharedArray> = SharedArray::new(); let ref m_location: Option = None; pub(crate) fn EnumType(name: QName) { super(); self.set_m_name(Some(name)); } pub override fn name(&self) -> QName { self.m_name().unwrap() } /// Mapping from member's String to Number. pub override fn enum_member_number_mapping(&self) -> SharedMap { self.m_number_mapping() } /// Mapping from member's String to the static variable slot /// used in `properties()`. pub override fn enum_member_slot_mapping(&self) -> SharedMap { self.m_slot_mapping() } pub override fn location(&self) -> Option { self.m_location() } pub override fn set_location(&self, loc: Option) { self.set_m_location(loc); } pub override fn private_ns(&self) -> Option { self.m_private_ns() } pub override fn set_private_ns(&self, ns: Option) { self.set_m_private_ns(ns); } pub override fn is_abstract(&self) -> bool { false } pub override fn is_final(&self) -> bool { true } pub override fn is_dynamic(&self) -> bool { false } pub override fn is_options_class(&self) -> bool { false } #[inheritdoc] pub override fn extends_class(&self, host: &SemanticHost) -> Option { Some(host.object_type()) } pub override fn properties(&self, host: &SemanticHost) -> NameMap { self.m_properties() } pub override fn prototype(&self, host: &SemanticHost) -> NameMap { self.m_prototype() } pub override fn parent(&self) -> Option { self.m_parent() } pub override fn set_parent(&self, p: Option) { self.set_m_parent(p); } pub override fn asdoc(&self) -> Option> { self.m_asdoc() } pub override fn set_asdoc(&self, asdoc: Option>) { self.set_m_asdoc(asdoc); } pub override fn metadata(&self) -> SharedArray> { self.m_metadata() } pub override fn includes_undefined(&self, host: &SemanticHost) -> Result { Ok(false) } pub override fn includes_null(&self, host: &SemanticHost) -> Result { Ok(true) } override fn to_string_1(&self) -> String { self.fully_qualified_name() } } pub struct InterfaceType: Type { let ref m_name: Option = None; let ref m_type_params: Option> = None; let ref m_flex_events: SharedMap = SharedMap::new(); let ref m_extends_interfaces: SharedArray = SharedArray::new(); let ref m_known_implementors: SharedArray = SharedArray::new(); let ref m_parent: Option = None; let ref m_prototype: NameMap = NameMap::new(); let ref m_asdoc: Option> = None; let ref m_metadata: SharedArray> = SharedArray::new(); let ref m_location: Option = None; pub(crate) fn InterfaceType(name: QName) { super(); self.set_m_name(Some(name)); } pub override fn is_interface_type_possibly_after_sub(&self) -> bool { true } pub override fn name(&self) -> QName { self.m_name().unwrap() } pub override fn location(&self) -> Option { self.m_location() } pub override fn set_location(&self, loc: Option) { self.set_m_location(loc); } pub override fn type_params(&self) -> Option> { self.m_type_params() } pub override fn set_type_params(&self, list: Option>) { self.set_m_type_params(list); } #[inheritdoc] pub override fn flex_events(&self) -> SharedMap { self.m_flex_events() } pub override fn known_implementors(&self) -> SharedArray { self.m_known_implementors() } #[inheritdoc] pub override fn extends_interfaces(&self, host: &SemanticHost) -> SharedArray { self.m_extends_interfaces() } pub override fn prototype(&self, host: &SemanticHost) -> NameMap { self.m_prototype() } pub override fn parent(&self) -> Option { self.m_parent() } pub override fn set_parent(&self, p: Option) { self.set_m_parent(p); } pub override fn asdoc(&self) -> Option> { self.m_asdoc() } pub override fn set_asdoc(&self, asdoc: Option>) { self.set_m_asdoc(asdoc); } pub override fn metadata(&self) -> SharedArray> { self.m_metadata() } pub override fn includes_undefined(&self, host: &SemanticHost) -> Result { Ok(false) } pub override fn includes_null(&self, host: &SemanticHost) -> Result { Ok(true) } override fn to_string_1(&self) -> String { let name_1 = self.fully_qualified_name(); let mut p = String::new(); if let Some(type_params) = self.type_params() { p = ".<".to_owned() + &type_params.iter().map(|p| p.to_string()).collect::>().join(", ") + ">"; } name_1 + &p } } /// Type after substitution, whose origin is either /// a class or an interface. Other types, after substitution, /// such as structural types, are represented by their /// same type with substitution in compound parts. pub struct TypeAfterSubstitution: Type { let ref m_origin: Option = None; let ref m_substitute_types: SharedArray = SharedArray::new(); let ref m_extends_class: Option = None; let ref m_implements: Option> = None; let ref m_extends_interfaces: Option> = None; let ref m_properties: Option = None; let ref m_prototype: Option = None; let ref m_constructor_method: Option = None; pub(crate) fn TypeAfterSubstitution(origin: Thingy, substitute_types: SharedArray) { super(); self.set_m_origin(Some(origin)); self.set_m_substitute_types(substitute_types); } pub override fn is_class_type_possibly_after_sub(&self) -> bool { self.origin().is_class_type_possibly_after_sub() } pub override fn is_interface_type_possibly_after_sub(&self) -> bool { self.origin().is_interface_type_possibly_after_sub() } pub override fn origin(&self) -> Thingy { self.m_origin().unwrap() } pub override fn substitute_types(&self) -> SharedArray { self.m_substitute_types() } pub override fn name(&self) -> QName { self.origin().name() } pub override fn flex_events(&self) -> SharedMap { self.origin().flex_events() } pub override fn is_abstract(&self) -> bool { self.origin().is_abstract() } pub override fn is_static(&self) -> bool { self.origin().is_static() } pub override fn is_final(&self) -> bool { self.origin().is_final() } pub override fn is_dynamic(&self) -> bool { self.origin().is_dynamic() } pub override fn is_dynamic_or_inherits_dynamic(&self, host: &SemanticHost) -> Result { self.origin().is_dynamic_or_inherits_dynamic(host) } pub override fn is_options_class(&self) -> bool { self.origin().is_options_class() } #[inheritdoc] pub override fn extends_class(&self, host: &SemanticHost) -> Option { if let Some(r) = self.m_extends_class() { return Some(r.clone()); } let origin = self.origin(); let r = origin.extends_class(host); if r.is_none() { return None; } let r = r.unwrap(); if r.is::() { return Some(r.clone()); } let r = TypeSubstitution(host).exec(&r, &origin.type_params().unwrap(), &self.m_substitute_types()); self.set_m_extends_class(Some(r.clone())); Some(r) } #[inheritdoc] pub override fn implements(&self, host: &SemanticHost) -> SharedArray { if let Some(r) = self.m_implements() { return r; } let origin = self.origin(); let r: SharedArray = origin.implements(host).iter().map(|t| TypeSubstitution(host).exec(&t, &origin.type_params().unwrap(), &self.m_substitute_types())).collect(); self.set_m_implements(Some(r.clone())); r } #[inheritdoc] pub override fn extends_interfaces(&self, host: &SemanticHost) -> SharedArray { if let Some(r) = self.m_extends_interfaces() { return r; } let origin = self.origin(); let r: SharedArray = origin.extends_interfaces(host).iter().map(|t| TypeSubstitution(host).exec(&t, &origin.type_params().unwrap(), &self.m_substitute_types())).collect(); self.set_m_extends_interfaces(Some(r.clone())); r } pub override fn prototype(&self, host: &SemanticHost) -> NameMap { if let Some(r) = self.m_prototype() { return r; } let origin = self.origin(); let mut r = NameMap::new(); for (name, thingy) in origin.prototype(host).borrow().iter() { let thingy = TypeSubstitution(host).exec(&thingy, &origin.type_params().unwrap(), &self.m_substitute_types()); r.set(name.clone(), thingy) } self.set_m_prototype(Some(r.clone())); r } pub override fn properties(&self, host: &SemanticHost) -> NameMap { if let Some(r) = self.m_properties() { return r; } let origin = self.origin(); let mut r = NameMap::new(); for (name, thingy) in origin.properties(host).borrow().iter() { let thingy = TypeSubstitution(host).exec(&thingy, &origin.type_params().unwrap(), &self.m_substitute_types()); r.set(name.clone(), thingy) } self.set_m_properties(Some(r.clone())); r } pub override fn constructor_method(&self, host: &SemanticHost) -> Option { if let Some(r) = self.m_constructor_method() { return Some(r.clone()); } let origin = self.origin(); let r = origin.constructor_method(host); if r.is_none() { return None; } let r = r.unwrap(); let r = TypeSubstitution(host).exec(&r, &origin.type_params().unwrap(), &self.m_substitute_types()); self.set_m_constructor_method(Some(r.clone())); Some(r) } pub override fn parent(&self) -> Option { self.origin().parent() } pub override fn asdoc(&self) -> Option> { self.origin().asdoc() } pub override fn metadata(&self) -> SharedArray> { self.origin().metadata() } pub override fn includes_undefined(&self, host: &SemanticHost) -> Result { Ok(false) } pub override fn includes_null(&self, host: &SemanticHost) -> Result { Ok(true) } pub override fn location(&self) -> Option { None } override fn to_string_1(&self) -> String { let name_1 = self.fully_qualified_name(); let a = self.m_substitute_types(); let p = ".<".to_owned() + &a.iter().map(|a| a.to_string()).collect::>().join(", ") + ">"; name_1 + &p } } /// Tuple type. The tuple type is equivalent to /// `Array` with type safety for its element types. pub struct TupleType: Type { let ref m_elements: SharedArray = SharedArray::new(); pub(crate) fn TupleType(elements: SharedArray) { super(); self.set_m_elements(elements); } pub override fn element_types(&self) -> SharedArray { self.m_elements() } pub override fn is_abstract(&self) -> bool { false } pub override fn is_final(&self) -> bool { true } pub override fn is_dynamic(&self) -> bool { true } pub override fn is_dynamic_or_inherits_dynamic(&self, host: &SemanticHost) -> Result { Ok(self.is_dynamic()) } pub override fn is_options_class(&self) -> bool { false } #[inheritdoc] pub override fn extends_class(&self, host: &SemanticHost) -> Option { Some(host.array_type_of_any().unwrap_or(host.unresolved_thingy())) } pub override fn includes_undefined(&self, host: &SemanticHost) -> Result { Ok(false) } pub override fn includes_null(&self, host: &SemanticHost) -> Result { Ok(true) } override fn to_string_1(&self) -> String { format!("[{}]", self.element_types().iter().map(|e| e.to_string()).collect::>().join(", ")) } } /// Structural function type. This type is equivalent to `Function` /// with type safety. pub struct FunctionType: Type { let ref m_params: SharedArray> = SharedArray::new(); let ref m_result_type: Option = None; pub(crate) fn FunctionType(params: SharedArray>, result_type: Thingy) { super(); self.set_m_params(params); self.set_m_result_type(Some(result_type)); } pub override fn params(&self) -> SharedArray> { self.m_params() } pub override fn result_type(&self) -> Thingy { self.m_result_type().unwrap() } pub override fn is_abstract(&self) -> bool { false } pub override fn is_final(&self) -> bool { true } pub override fn is_dynamic(&self) -> bool { false } pub override fn is_dynamic_or_inherits_dynamic(&self, host: &SemanticHost) -> Result { Ok(self.is_dynamic()) } pub override fn is_options_class(&self) -> bool { false } #[inheritdoc] pub override fn extends_class(&self, host: &SemanticHost) -> Option { Some(host.function_type()) } pub override fn includes_undefined(&self, host: &SemanticHost) -> Result { Ok(false) } pub override fn includes_null(&self, host: &SemanticHost) -> Result { Ok(true) } override fn to_string_1(&self) -> String { let mut p = Vec::::new(); for p1 in self.params().iter() { match p1.kind { ParameterKind::Required => { p.push(p1.static_type.to_string()); }, ParameterKind::Optional => { p.push(p1.static_type.to_string() + &"=".to_owned()); }, ParameterKind::Rest => { p.push("...".to_owned() + &p1.static_type.to_string()); }, } } format!("function({}) : {}", p.join(", "), self.result_type().to_string()) } } /// The nullable type `T?`. It is equivalent to either /// `T` or `*` (for all primitive types but String). pub struct NullableType: Type { let ref m_base: Option = None; pub(crate) fn NullableType(base: Thingy) { super(); self.set_m_base(Some(base)); } /// The type that is made nullable. pub override fn base(&self) -> Thingy { self.m_base().unwrap() } pub override fn includes_undefined(&self) -> Result { Ok(false) } pub override fn includes_null(&self) -> Result { Ok(true) } #[inheritdoc] pub override fn escape_of_nullable(&self) -> Thingy { self.base() } pub override fn escape_of_nullable_or_non_nullable(&self) -> Thingy { self.base() } override fn to_string_1(&self) -> String { if let Ok(ft) = self.base().to::() { format!("?{}", ft.to_string()) } else { format!("{}?", self.base().to_string()) } } } pub struct NonNullableType: Type { let ref m_base: Option = None; pub(crate) fn NonNullableType(base: Thingy) { super(); self.set_m_base(Some(base)); } /// The type that is made non-nullable. pub override fn base(&self) -> Thingy { self.m_base().unwrap() } pub override fn includes_undefined(&self) -> Result { Ok(false) } pub override fn includes_null(&self) -> Result { Ok(false) } #[inheritdoc] pub override fn escape_of_non_nullable(&self) -> Thingy { self.base() } pub override fn escape_of_nullable_or_non_nullable(&self) -> Thingy { self.base() } override fn to_string_1(&self) -> String { if let Ok(ft) = self.base().to::() { format!("({})!", ft.to_string()) } else { format!("{}!", self.base().to_string()) } } } pub struct TypeParameterType: Type { let ref m_name: Option = None; let ref m_location: Option = None; pub(crate) fn TypeParameterType(name: QName) { super(); self.set_m_name(Some(name)); } pub override fn name(&self) -> QName { self.m_name().unwrap() } pub override fn location(&self) -> Option { self.m_location() } pub override fn set_location(&self, loc: Option) { self.set_m_location(loc); } pub override fn includes_undefined(&self) -> Result { Ok(false) } pub override fn includes_null(&self) -> Result { Ok(false) } override fn to_string_1(&self) -> String { self.name().to_string() } } /// Either an *original* variable slot, or a variable slot after substitution. pub struct VariableSlot: Thingy { fn VariableSlot() { super(); } #[inheritdoc] pub override fn property_static_type(&self, host: &SemanticHost) -> Thingy { self.static_type(host) } } pub struct OriginalVariableSlot: VariableSlot { let ref m_name: Option = None; let ref m_location: Option = None; let ref m_asdoc: Option> = None; let ref m_metadata: SharedArray> = SharedArray::new(); let ref m_constant: Option = None; let ref m_static_type: Option = None; let ref m_parent: Option = None; let m_flags: VariableSlotFlags = VariableSlotFlags::empty(); let ref m_bindable_event: Option = None; pub(crate) fn OriginalVariableSlot(name: &QName, read_only: bool, static_type: &Thingy) { super(); self.set_m_name(Some(name.clone())); self.set_read_only(read_only); self.set_m_static_type(Some(static_type.clone())); } pub override fn name(&self) -> QName { self.m_name().unwrap() } /// The constant initially assigned to that variable slot. pub override fn var_constant(&self) -> Option { self.m_constant() } /// The constant initially assigned to that variable slot. pub override fn set_var_constant(&self, k: Option) { self.set_m_constant(k); } pub override fn read_only(&self, host: &SemanticHost) -> bool { self.m_flags().contains(VariableSlotFlags::READ_ONLY) } pub override fn set_read_only(&self, value: bool) { let mut v = self.m_flags(); v.set(VariableSlotFlags::READ_ONLY, value); self.set_m_flags(v); } pub override fn write_only(&self, host: &SemanticHost) -> bool { false } pub override fn static_type(&self, host: &SemanticHost) -> Thingy { self.m_static_type().unwrap() } pub override fn set_static_type(&self, value: Thingy) { self.set_m_static_type(Some(value)); } pub override fn location(&self) -> Option { self.m_location() } pub override fn set_location(&self, loc: Option) { self.set_m_location(loc); } /// The event name indicated by a `[Bindable]` meta-data tag. pub override fn bindable_event(&self) -> Option { self.m_bindable_event() } pub override fn set_bindable_event(&self, name: Option) { self.set_m_bindable_event(name); } pub override fn parent(&self) -> Option { self.m_parent() } pub override fn set_parent(&self, p: Option) { self.set_m_parent(p); } pub override fn asdoc(&self) -> Option> { self.m_asdoc() } pub override fn set_asdoc(&self, asdoc: Option>) { self.set_m_asdoc(asdoc); } pub override fn metadata(&self) -> SharedArray> { self.m_metadata() } override fn to_string_1(&self) -> String { self.fully_qualified_name() } } /// Variable slot after indirect substitution. pub struct VariableSlotAfterSubstitution: VariableSlot { let ref m_origin: Option = None; let ref m_indirect_type_params: SharedArray = SharedArray::new(); let ref m_indirect_substitute_types: SharedArray = SharedArray::new(); let ref m_static_type: Option = None; pub(crate) fn VariableSlotAfterSubstitution(origin: &Thingy, indirect_type_params: &SharedArray, indirect_substitute_types: &SharedArray) { super(); self.set_m_origin(Some(origin.clone())); self.set_m_indirect_type_params(indirect_type_params.clone()); self.set_m_indirect_substitute_types(indirect_substitute_types.clone()); } pub override fn origin(&self) -> Thingy { self.m_origin().unwrap() } pub override fn indirect_type_params(&self) -> SharedArray { self.m_indirect_type_params() } pub override fn indirect_substitute_types(&self) -> SharedArray { self.m_indirect_substitute_types() } pub override fn name(&self) -> QName { self.origin().name() } /// The constant initially assigned to that variable slot. pub override fn var_constant(&self) -> Option { None } pub override fn read_only(&self, host: &SemanticHost) -> bool { self.origin().read_only(host) } pub override fn write_only(&self, host: &SemanticHost) -> bool { false } pub override fn static_type(&self, host: &SemanticHost) -> Thingy { if let Some(r) = self.m_static_type() { return r.clone(); } let r = self.origin().static_type(host); if r.is::() { return r.clone(); } let r = TypeSubstitution(host).exec(&r, &self.m_indirect_type_params(), &self.m_indirect_substitute_types()); self.set_m_static_type(Some(r.clone())); r } pub override fn location(&self) -> Option { None } /// The event name indicated by a `[Bindable]` meta-data tag. pub override fn bindable_event(&self) -> Option { self.origin().bindable_event() } pub override fn parent(&self) -> Option { self.origin().parent() } pub override fn asdoc(&self) -> Option> { self.origin().asdoc() } pub override fn metadata(&self) -> SharedArray> { self.origin().metadata() } override fn to_string_1(&self) -> String { self.fully_qualified_name() } } /// Either an *original* virtual slot, or a virtual slot after substitution. pub struct VirtualSlot: Thingy { fn VirtualSlot() { super(); } #[inheritdoc] pub override fn property_static_type(&self, host: &SemanticHost) -> Thingy { self.static_type(host) } } pub struct OriginalVirtualSlot: VirtualSlot { let ref m_name: Option = None; let ref m_location: Option = None; let ref m_asdoc: Option> = None; let ref m_getter: Option = None; let ref m_setter: Option = None; let ref m_static_type: Option = None; let ref m_parent: Option = None; let m_flags: VirtualSlotFlags = VirtualSlotFlags::empty(); let ref m_bindable_event: Option = None; pub(crate) fn OriginalVirtualSlot(name: &QName) { super(); self.set_m_name(Some(name.clone())); } pub override fn name(&self) -> QName { self.m_name().unwrap() } pub override fn getter(&self, host: &SemanticHost) -> Option { self.m_getter() } pub override fn set_getter(&self, m: Option) { self.set_m_getter(m); } pub override fn setter(&self, host: &SemanticHost) -> Option { self.m_setter() } pub override fn set_setter(&self, m: Option) { self.set_m_setter(m); } pub override fn read_only(&self, host: &SemanticHost) -> bool { self.setter(host).is_none() } pub override fn write_only(&self, host: &SemanticHost) -> bool { self.getter(host).is_none() } pub override fn static_type(&self, host: &SemanticHost) -> Thingy { if let Some(r) = self.m_static_type() { return r.clone(); } let mut deduced_type: Option = None; // Deduce type from getter if let Some(getter) = self.m_getter() { let signature: Thingy = getter.signature(host); if !signature.is::() { deduced_type = Some(signature.result_type()); } } // Deduce type from setter if let Some(setter) = self.m_setter() { let signature: Thingy = setter.signature(host); if !signature.is::() { deduced_type = Some(signature.params().get(0).unwrap().static_type.clone()); } } if deduced_type.is_none() { return host.unresolved_thingy(); } self.set_m_static_type(deduced_type.clone()); deduced_type.unwrap() } pub override fn location(&self) -> Option { self.m_location() } pub override fn set_location(&self, loc: Option) { self.set_m_location(loc); } /// The event name indicated by a `[Bindable]` meta-data tag. pub override fn bindable_event(&self) -> Option { self.m_bindable_event() } pub override fn set_bindable_event(&self, name: Option) { self.set_m_bindable_event(name); } pub override fn parent(&self) -> Option { self.m_parent() } pub override fn set_parent(&self, p: Option) { self.set_m_parent(p); } pub override fn asdoc(&self) -> Option> { self.m_asdoc() } pub override fn set_asdoc(&self, asdoc: Option>) { self.set_m_asdoc(asdoc); } override fn to_string_1(&self) -> String { self.fully_qualified_name() } } pub struct VirtualSlotAfterSubstitution: VirtualSlot { let ref m_origin: Option = None; let ref m_indirect_type_params: SharedArray = SharedArray::new(); let ref m_indirect_substitute_types: SharedArray = SharedArray::new(); let ref m_getter: Option = None; let ref m_setter: Option = None; let ref m_static_type: Option = None; pub(crate) fn VirtualSlotAfterSubstitution(origin: &Thingy, indirect_type_params: &SharedArray, indirect_substitute_types: &SharedArray) { super(); self.set_m_origin(Some(origin.clone())); self.set_m_indirect_type_params(indirect_type_params.clone()); self.set_m_indirect_substitute_types(indirect_substitute_types.clone()); } pub override fn location(&self) -> Option { None } pub override fn origin(&self) -> Thingy { self.m_origin().unwrap() } pub override fn indirect_type_params(&self) -> SharedArray { self.m_indirect_type_params() } pub override fn indirect_substitute_types(&self) -> SharedArray { self.m_indirect_substitute_types() } pub override fn name(&self) -> QName { self.origin().name() } pub override fn getter(&self, host: &SemanticHost) -> Option { if let Some(r) = self.m_getter() { return Some(r); } let r = self.origin().getter(host); if r.is_none() { return r; } let r = TypeSubstitution(host).exec(&r.unwrap(), &self.indirect_type_params(), &self.indirect_substitute_types()); self.set_m_getter(Some(r.clone())); Some(r) } pub override fn setter(&self, host: &SemanticHost) -> Option { if let Some(r) = self.m_setter() { return Some(r); } let r = self.origin().setter(host); if r.is_none() { return r; } let r = TypeSubstitution(host).exec(&r.unwrap(), &self.indirect_type_params(), &self.indirect_substitute_types()); self.set_m_setter(Some(r.clone())); Some(r) } pub override fn read_only(&self, host: &SemanticHost) -> bool { self.origin().read_only(host) } pub override fn write_only(&self, host: &SemanticHost) -> bool { self.origin().write_only(host) } pub override fn static_type(&self, host: &SemanticHost) -> Thingy { if let Some(r) = self.m_static_type() { return r; } let r = self.origin().static_type(host); if r.is::() { return r; } let r = TypeSubstitution(host).exec(&r, &self.indirect_type_params(), &self.indirect_substitute_types()); self.set_m_static_type(Some(r.clone())); r } pub override fn bindable_event(&self) -> Option { self.origin().bindable_event() } pub override fn parent(&self) -> Option { self.origin().parent() } pub override fn asdoc(&self) -> Option> { self.origin().asdoc() } override fn to_string_1(&self) -> String { self.fully_qualified_name() } } /// Either an *original* method slot, or a method slot after substitution. pub struct MethodSlot: Thingy { fn MethodSlot() { super(); } #[inheritdoc] pub override fn property_static_type(&self, host: &SemanticHost) -> Thingy { host.function_type() } } pub struct OriginalMethodSlot: MethodSlot { let ref m_name: Option = None; let ref m_location: Option = None; let ref m_asdoc: Option> = None; let ref m_metadata: SharedArray> = SharedArray::new(); let ref m_activation: Option = None; let ref m_signature: Option = None; let ref m_parent: Option = None; let ref m_of_virtual_slot: Option = None; let ref m_overriden_by: SharedArray = SharedArray::new(); let ref m_overrides_method: Option = None; let m_flags: MethodSlotFlags = MethodSlotFlags::empty(); pub(crate) fn OriginalMethodSlot(name: &QName, signature: &Thingy) { super(); self.set_m_name(Some(name.clone())); self.set_m_signature(Some(signature.clone())); } pub override fn name(&self) -> QName { self.m_name().unwrap() } pub override fn is_final(&self) -> bool { self.m_flags().contains(MethodSlotFlags::IS_FINAL) } pub override fn set_is_final(&self, value: bool) { let mut v = self.m_flags(); v.set(MethodSlotFlags::IS_FINAL, value); self.set_m_flags(v); } pub override fn is_static(&self) -> bool { self.m_flags().contains(MethodSlotFlags::IS_STATIC) } pub override fn set_is_static(&self, value: bool) { let mut v = self.m_flags(); v.set(MethodSlotFlags::IS_STATIC, value); self.set_m_flags(v); } pub override fn is_abstract(&self) -> bool { self.m_flags().contains(MethodSlotFlags::IS_ABSTRACT) } pub override fn set_is_abstract(&self, value: bool) { let mut v = self.m_flags(); v.set(MethodSlotFlags::IS_ABSTRACT, value); self.set_m_flags(v); } pub override fn is_overriding(&self) -> bool { self.m_flags().contains(MethodSlotFlags::IS_OVERRIDING) } pub override fn set_is_overriding(&self, value: bool) { let mut v = self.m_flags(); v.set(MethodSlotFlags::IS_OVERRIDING, value); self.set_m_flags(v); } pub override fn is_async(&self) -> bool { self.m_flags().contains(MethodSlotFlags::IS_ASYNC) } pub override fn set_is_async(&self, value: bool) { let mut v = self.m_flags(); v.set(MethodSlotFlags::IS_ASYNC, value); self.set_m_flags(v); } pub override fn is_generator(&self) -> bool { self.m_flags().contains(MethodSlotFlags::IS_GENERATOR) } pub override fn set_is_generator(&self, value: bool) { let mut v = self.m_flags(); v.set(MethodSlotFlags::IS_GENERATOR, value); self.set_m_flags(v); } pub override fn is_constructor(&self) -> bool { self.m_flags().contains(MethodSlotFlags::IS_CONSTRUCTOR) } pub override fn set_is_constructor(&self, value: bool) { let mut v = self.m_flags(); v.set(MethodSlotFlags::IS_CONSTRUCTOR, value); self.set_m_flags(v); } pub override fn location(&self) -> Option { self.m_location() } pub override fn set_location(&self, loc: Option) { self.set_m_location(loc); } pub override fn parent(&self) -> Option { self.m_parent() } pub override fn set_parent(&self, p: Option) { self.set_m_parent(p); } pub override fn asdoc(&self) -> Option> { self.m_asdoc() } pub override fn set_asdoc(&self, asdoc: Option>) { self.set_m_asdoc(asdoc); } pub override fn metadata(&self) -> SharedArray> { self.m_metadata() } pub override fn signature(&self, host: &SemanticHost) -> Thingy { self.m_signature().unwrap() } pub override fn set_signature(&self, signature: &Thingy) { self.set_m_signature(Some(signature.clone())); } pub override fn activation(&self) -> Option { self.m_activation() } pub override fn set_activation(&self, activation: Option) { self.set_m_activation(activation); } pub override fn of_virtual_slot(&self, host: &SemanticHost) -> Option { self.m_of_virtual_slot() } pub override fn set_of_virtual_slot(&self, virtual_slot: Option) { self.set_m_of_virtual_slot(virtual_slot); } pub override fn overriden_by(&self, host: &SemanticHost) -> SharedArray { self.m_overriden_by() } pub override fn overrides_method(&self, host: &SemanticHost) -> Option { self.m_overrides_method() } pub override fn set_overrides_method(&self, method: Option) { self.set_m_overrides_method(method); } override fn to_string_1(&self) -> String { self.fully_qualified_name() } } pub struct MethodSlotAfterSubstitution: MethodSlot { let ref m_origin: Option = None; let ref m_indirect_type_params: SharedArray = SharedArray::new(); let ref m_indirect_substitute_types: SharedArray = SharedArray::new(); let ref m_signature: Option = None; let ref m_of_virtual_slot: Option = None; let ref m_overriden_by: Option> = None; let ref m_overrides_method: Option = None; let m_is_overriding: bool = false; pub fn MethodSlotAfterSubstitution(origin: &Thingy, indirect_type_params: &SharedArray, indirect_substitute_types: &SharedArray) { super(); self.set_m_origin(Some(origin.clone())); self.set_m_indirect_type_params(indirect_type_params.clone()); self.set_m_indirect_substitute_types(indirect_substitute_types.clone()); } pub override fn origin(&self) -> Thingy { self.m_origin().unwrap() } pub override fn indirect_type_params(&self) -> SharedArray { self.m_indirect_type_params() } pub override fn indirect_substitute_types(&self) -> SharedArray { self.m_indirect_substitute_types() } pub override fn name(&self) -> QName { self.origin().name() } pub override fn is_final(&self) -> bool { self.origin().is_final() } pub override fn is_static(&self) -> bool { self.origin().is_static() } pub override fn is_abstract(&self) -> bool { self.origin().is_abstract() } pub override fn is_overriding(&self) -> bool { self.m_is_overriding() } pub override fn set_is_overriding(&self, value: bool) { self.set_m_is_overriding(value); } pub override fn is_async(&self) -> bool { self.origin().is_async() } pub override fn is_generator(&self) -> bool { self.origin().is_generator() } pub override fn is_constructor(&self) -> bool { self.origin().is_constructor() } pub override fn location(&self) -> Option { None } pub override fn parent(&self) -> Option { self.origin().parent() } pub override fn asdoc(&self) -> Option> { self.origin().asdoc() } pub override fn metadata(&self) -> SharedArray> { self.origin().metadata() } pub override fn signature(&self, host: &SemanticHost) -> Thingy { if let Some(r) = self.m_signature() { return r; } let r = self.origin().signature(host); if r.is::() { return r.clone(); } let r = TypeSubstitution(host).exec(&r, &self.m_indirect_type_params(), &self.m_indirect_substitute_types()); self.set_m_signature(Some(r.clone())); r } pub override fn of_virtual_slot(&self, host: &SemanticHost) -> Option { if let Some(r) = self.m_of_virtual_slot() { return Some(r); } let r = self.origin().of_virtual_slot(host); if r.is_none() { return None; } let r = TypeSubstitution(host).exec(&r.unwrap(), &self.m_indirect_type_params(), &self.m_indirect_substitute_types()); self.set_m_of_virtual_slot(Some(r.clone())); Some(r) } pub override fn overriden_by(&self, host: &SemanticHost) -> SharedArray { if let Some(r) = self.m_overriden_by() { return r; } let r = self.origin().overriden_by(host); let r: SharedArray = r.iter().map(|r| TypeSubstitution(host).exec(&r, &self.m_indirect_type_params(), &self.indirect_substitute_types())).collect(); self.set_m_overriden_by(Some(r.clone())); r } pub override fn overrides_method(&self, host: &SemanticHost) -> Option { if let Some(r) = self.m_overrides_method() { return Some(r); } let r = self.origin().overrides_method(host); if r.is_none() { return None; } let r = TypeSubstitution(host).exec(&r.unwrap(), &self.m_indirect_type_params(), &self.m_indirect_substitute_types()); self.set_m_overrides_method(Some(r.clone())); Some(r) } pub override fn set_overrides_method(&self, method: Option) { self.set_m_overrides_method(method); } override fn to_string_1(&self) -> String { self.fully_qualified_name() } } pub struct Scope: Thingy { let ref m_parent: Option = None; let ref m_properties: NameMap = NameMap::new(); let ref m_open_ns_set: SharedArray = SharedArray::new(); let ref m_import_list: SharedArray = SharedArray::new(); pub(crate) fn Scope() { super(); } pub override fn parent(&self) -> Option { self.m_parent() } pub override fn set_parent(&self, p: Option) { self.set_m_parent(p); } pub override fn properties(&self, host: &SemanticHost) -> NameMap { self.m_properties() } pub override fn open_ns_set(&self) -> SharedArray { self.m_open_ns_set() } /// List of [`PackagePropertyImport`], [`PackageWildcardImport`], or [`PackageRecursiveImport`]. pub override fn import_list(&self) -> SharedArray { self.m_import_list() } } pub struct WithScope: Scope { let ref m_object: Option = None; pub(crate) fn WithScope(object: &Thingy) { super(); self.set_m_object(Some(object.clone())); } pub override fn object(&self) -> Thingy { self.m_object().unwrap() } } pub struct FilterScope: Scope { let ref m_base: Option = None; pub(crate) fn FilterScope(base: &Thingy) { super(); self.set_m_base(Some(base.clone())); } pub override fn base(&self) -> Thingy { self.m_base().unwrap() } } pub struct Activation: Scope { let m_kind: u8 = DEFAULT_ACTIVATION; let ref m_method: Option = None; let ref m_this: Option = None; let ref m_property_has_capture: Option> = None; let ref m_cfg: ControlFlowGraph = ControlFlowGraph::new(); let ref m_public_ns: Option = None; let ref m_internal_ns: Option = None; pub(crate) fn Activation(of_method: &Thingy) { super(); self.set_m_method(Some(of_method.clone())); } pub override fn of_method(&self) -> Thingy { self.m_method().unwrap() } /// An optional `ThisObject` value. pub override fn this(&self) -> Option { self.m_this() } /// Sets a `ThisObject` value. pub override fn set_this(&self, this: Option) { self.set_m_this(this); } /// Indicates whether an activation's property has been captured /// by a subsequent activation. Properties include, for example, the range from the /// activation to an inner most block scope. pub override fn property_has_capture(&self, property: &Thingy) -> bool { if let Some(set) = self.m_property_has_capture() { set.includes(property) } else { false } } pub override fn set_property_has_capture(&self, property: &Thingy, value: bool) { if let Some(mut set) = self.m_property_has_capture() { if value { if !set.includes(property) { set.push(property.clone()); } } else { let i = set.index_of(property); if let Some(i) = i { set.remove(i); } } } else if value { self.set_m_property_has_capture(Some(shared_array![property.clone()])); } } pub override fn control_flow_graph(&self) -> ControlFlowGraph { self.m_cfg() } pub override fn is_global_initialization(&self) -> bool { self.m_kind() == GLOBAL_INIT_ACTIVATION } pub override fn set_is_global_initialization(&self, value: bool) { self.set_m_kind(if value { GLOBAL_INIT_ACTIVATION } else { DEFAULT_ACTIVATION }); } pub override fn is_package_initialization(&self) -> bool { self.m_kind() == PACKAGE_INIT_ACTIVATION } pub override fn set_is_package_initialization(&self, value: bool) { self.set_m_kind(if value { PACKAGE_INIT_ACTIVATION } else { DEFAULT_ACTIVATION }); } pub override fn public_ns(&self) -> Option { self.m_public_ns() } pub override fn set_public_ns(&self, ns: Option) { self.set_m_public_ns(ns); } pub override fn internal_ns(&self) -> Option { self.m_internal_ns() } pub override fn set_internal_ns(&self, ns: Option) { self.set_m_internal_ns(ns); } } pub struct FixtureScope: Scope { pub(crate) fn FixtureScope() { super(); } } pub struct ClassScope: FixtureScope { let ref m_class: Option = None; pub(crate) fn ClassScope(class: &Thingy) { super(); self.set_m_class(Some(class.clone())); } pub override fn class(&self) -> Thingy { self.m_class().unwrap() } } pub struct EnumScope: FixtureScope { let ref m_class: Option = None; pub(crate) fn EnumScope(class: &Thingy) { super(); self.set_m_class(Some(class.clone())); } pub override fn class(&self) -> Thingy { self.m_class().unwrap() } } pub struct InterfaceScope: FixtureScope { let ref m_itrfc: Option = None; pub(crate) fn InterfaceScope(itrfc: &Thingy) { super(); self.set_m_itrfc(Some(itrfc.clone())); } pub override fn interface(&self) -> Thingy { self.m_itrfc().unwrap() } } pub struct PackageScope: FixtureScope { let ref m_pckg: Option = None; pub(crate) fn PackageScope(pckg: &Thingy) { super(); self.set_m_pckg(Some(pckg.clone())); } pub override fn package(&self) -> Thingy { self.m_pckg().unwrap() } } pub struct Value: Thingy { let ref m_static_type: Option = None; pub(crate) fn Value(static_type: &Thingy) { super(); self.set_m_static_type(Some(static_type.clone())); } pub override fn static_type(&self, host: &SemanticHost) -> Thingy { self.m_static_type().unwrap() } pub override fn set_static_type(&self, value: Thingy) { self.set_m_static_type(Some(value)); } #[inheritdoc] pub override fn property_static_type(&self, host: &SemanticHost) -> Thingy { self.static_type(host) } } pub struct PackagePropertyImport: Value { let ref m_property: Option = None; let ref m_location: Option = None; pub(crate) fn PackagePropertyImport(property: &Thingy, location: Option, static_type: &Thingy) { super(static_type); self.set_m_property(Some(property.clone())); self.set_m_location(location); } pub override fn property(&self) -> Thingy { self.m_property().unwrap() } pub override fn set_property(&self, value: &Thingy) { self.set_m_property(Some(value.clone())); } pub override fn location(&self) -> Option { self.m_location() } pub override fn set_location(&self, loc: Option) { self.set_m_location(loc); } } pub struct PackageWildcardImport: Value { let ref m_package: Option = None; let ref m_location: Option = None; pub(crate) fn PackageWildcardImport(package: &Thingy, location: Option, static_type: &Thingy) { super(static_type); self.set_m_package(Some(package.clone())); self.set_m_location(location); } pub override fn package(&self) -> Thingy { self.m_package().unwrap() } pub override fn location(&self) -> Option { self.m_location() } pub override fn set_location(&self, loc: Option) { self.set_m_location(loc); } } pub struct PackageRecursiveImport: Value { let ref m_package: Option = None; let ref m_location: Option = None; pub(crate) fn PackageRecursiveImport(package: &Thingy, location: Option, static_type: &Thingy) { super(static_type); self.set_m_package(Some(package.clone())); self.set_m_location(location); } pub override fn package(&self) -> Thingy { self.m_package().unwrap() } pub override fn location(&self) -> Option { self.m_location() } pub override fn set_location(&self, loc: Option) { self.set_m_location(loc); } } pub struct Constant: Value { pub(crate) fn Constant(static_type: &Thingy) { super(static_type); } } /// Constant with possible types being `*` or `Object`. pub struct UndefinedConstant: Constant { pub(crate) fn UndefinedConstant(static_type: &Thingy) { super(static_type); } pub override fn clone_constant(&self, host: &SemanticHost) -> Thingy { host.factory().create_undefined_constant(&self.static_type(host)) } } pub struct NullConstant: Constant { pub(crate) fn NullConstant(static_type: &Thingy) { super(static_type); } pub override fn clone_constant(&self, host: &SemanticHost) -> Thingy { host.factory().create_null_constant(&self.static_type(host)) } } pub struct NamespaceConstant: Constant { let ref m_ns: Option = None; pub(crate) fn NamespaceConstant(referenced_ns: &Thingy, static_type: &Thingy) { super(static_type); self.set_m_ns(Some(referenced_ns.clone())); } pub override fn referenced_ns(&self) -> Thingy { self.m_ns().unwrap() } pub override fn is_namespace_or_ns_constant(&self) -> bool { true } pub override fn clone_constant(&self, host: &SemanticHost) -> Thingy { host.factory().create_namespace_constant_with_static_type(&self.referenced_ns(), &self.static_type(host)) } } pub struct TypeConstant: Constant { let ref m_type: Option = None; pub(crate) fn TypeConstant(referenced_type: &Thingy, static_type: &Thingy) { super(static_type); self.set_m_type(Some(referenced_type.clone())); } pub override fn referenced_type(&self) -> Thingy { self.m_type().unwrap() } pub override fn clone_constant(&self, host: &SemanticHost) -> Thingy { host.factory().create_type_constant_with_static_type(&self.referenced_type(), &self.static_type(host)) } } pub struct NumberConstant: Constant { let ref m_value: NumberVariant = NumberVariant::Int(0); pub(crate) fn NumberConstant(value: NumberVariant, static_type: &Thingy) { super(static_type); self.set_m_value(value); } pub override fn number_value(&self) -> NumberVariant { self.m_value() } pub override fn clone_constant(&self, host: &SemanticHost) -> Thingy { host.factory().create_number_constant(self.m_value(), &self.static_type(host)) } } pub struct StringConstant: Constant { let ref m_value: String = String::new(); pub(crate) fn StringConstant(value: String, static_type: &Thingy) { super(static_type); self.set_m_value(value); } pub override fn string_value(&self) -> String { self.m_value() } pub override fn clone_constant(&self, host: &SemanticHost) -> Thingy { host.factory().create_string_constant(self.m_value(), &self.static_type(host)) } } pub struct BooleanConstant: Constant { let m_value: bool = true; pub(crate) fn BooleanConstant(value: bool, static_type: &Thingy) { super(static_type); self.set_m_value(value); } pub override fn boolean_value(&self) -> bool { self.m_value() } pub override fn clone_constant(&self, host: &SemanticHost) -> Thingy { host.factory().create_boolean_constant(self.m_value(), &self.static_type(host)) } } pub struct ThisObject: Value { pub(crate) fn ThisObject(static_type: &Thingy) { super(static_type); } } /// The `import.meta` value. pub struct MetaProperty: Value { pub(crate) fn MetaProperty(static_type: &Thingy) { super(static_type); } } /// The `import.meta.env` value. pub struct MetaEnvProperty: Value { pub(crate) fn MetaEnvProperty(static_type: &Thingy) { super(static_type); } } pub struct ReferenceValue: Value { pub(crate) fn ReferenceValue(static_type: &Thingy) { super(static_type); } } /// Possibly uses attribute. pub struct XmlReferenceValue: ReferenceValue { let ref m_base: Option = None; let ref m_qual: Option = None; let ref m_key: Option = None; pub(crate) fn XmlReferenceValue(base: &Thingy, qualifier: Option, key: &Thingy, static_type: &Thingy) { super(static_type); self.set_m_base(Some(base.clone())); self.set_m_qual(qualifier); self.set_m_key(Some(key.clone())); } pub override fn base(&self) -> Thingy { self.m_base().unwrap() } pub override fn qualifier(&self) -> Option { self.m_qual() } pub override fn key(&self) -> Thingy { self.m_key().unwrap() } pub override fn read_only(&self, host: &SemanticHost) -> bool { false } pub override fn write_only(&self, host: &SemanticHost) -> bool { false } pub override fn deletable(&self, host: &SemanticHost) -> bool { true } } /// Possibly uses attribute. pub struct DynamicReferenceValue: ReferenceValue { let ref m_base: Option = None; let ref m_qual: Option = None; let ref m_key: Option = None; pub(crate) fn DynamicReferenceValue(base: &Thingy, qualifier: Option, key: &Thingy, static_type: &Thingy) { super(static_type); self.set_m_base(Some(base.clone())); self.set_m_qual(qualifier); self.set_m_key(Some(key.clone())); } pub override fn base(&self) -> Thingy { self.m_base().unwrap() } pub override fn qualifier(&self) -> Option { self.m_qual() } pub override fn key(&self) -> Thingy { self.m_key().unwrap() } pub override fn read_only(&self, host: &SemanticHost) -> bool { false } pub override fn write_only(&self, host: &SemanticHost) -> bool { false } pub override fn deletable(&self, host: &SemanticHost) -> bool { true } } pub struct FixtureReferenceValue: ReferenceValue { let ref m_base: Option = None; let ref m_property: Option = None; pub(crate) fn FixtureReferenceValue(base: &Thingy, property: &Thingy, static_type: &Thingy) { super(static_type); self.set_m_base(Some(base.clone())); self.set_m_property(Some(property.clone())); } pub override fn base(&self) -> Thingy { self.m_base().unwrap() } pub override fn property(&self) -> Thingy { self.m_property().unwrap() } pub override fn read_only(&self, host: &SemanticHost) -> bool { self.property().read_only(host) } pub override fn write_only(&self, host: &SemanticHost) -> bool { self.property().write_only(host) } pub override fn deletable(&self, host: &SemanticHost) -> bool { false } } pub struct StaticReferenceValue: FixtureReferenceValue { pub(crate) fn StaticReferenceValue(base: &Thingy, property: &Thingy, static_type: &Thingy) { super(base, property, static_type); } } pub struct StaticDynamicReferenceValue: ReferenceValue { let ref m_base: Option = None; let ref m_qual: Option = None; let ref m_key: Option = None; pub(crate) fn StaticDynamicReferenceValue(base: &Thingy, qualifier: Option, key: &Thingy, static_type: &Thingy) { super(static_type); self.set_m_base(Some(base.clone())); self.set_m_qual(qualifier); self.set_m_key(Some(key.clone())); } pub override fn base(&self) -> Thingy { self.m_base().unwrap() } pub override fn qualifier(&self) -> Option { self.m_qual() } pub override fn key(&self) -> Thingy { self.m_key().unwrap() } pub override fn read_only(&self, host: &SemanticHost) -> bool { false } pub override fn write_only(&self, host: &SemanticHost) -> bool { false } pub override fn deletable(&self, host: &SemanticHost) -> bool { false } } /// Instance reference value in a possibly non nullable base. pub struct InstanceReferenceValue: FixtureReferenceValue { pub(crate) fn InstanceReferenceValue(base: &Thingy, property: &Thingy, static_type: &Thingy) { super(base, property, static_type); } } /// Tuple reference value in a possibly non nullable base. pub struct TupleReferenceValue: ReferenceValue { let ref m_base: Option = None; let ref m_index: usize = 0; pub(crate) fn TupleReferenceValue(base: &Thingy, index: usize, static_type: &Thingy) { super(static_type); self.set_m_base(Some(base.clone())); self.set_m_index(index); } pub override fn base(&self) -> Thingy { self.m_base().unwrap() } pub override fn tuple_index(&self) -> usize { self.m_index() } pub override fn read_only(&self, host: &SemanticHost) -> bool { false } pub override fn write_only(&self, host: &SemanticHost) -> bool { false } pub override fn deletable(&self, host: &SemanticHost) -> bool { false } } pub struct ScopeReferenceValue: FixtureReferenceValue { pub(crate) fn ScopeReferenceValue(base: &Thingy, property: &Thingy, static_type: &Thingy) { super(base, property, static_type); } } /// Possibly uses attribute. pub struct DynamicScopeReferenceValue: ReferenceValue { let ref m_base: Option = None; let ref m_qual: Option = None; let ref m_key: Option = None; pub(crate) fn DynamicScopeReferenceValue(base: &Thingy, qualifier: Option, key: &Thingy, static_type: &Thingy) { super(static_type); self.set_m_base(Some(base.clone())); self.set_m_qual(qualifier); self.set_m_key(Some(key.clone())); } pub override fn base(&self) -> Thingy { self.m_base().unwrap() } pub override fn qualifier(&self) -> Option { self.m_qual() } pub override fn key(&self) -> Thingy { self.m_key().unwrap() } pub override fn read_only(&self, host: &SemanticHost) -> bool { false } pub override fn write_only(&self, host: &SemanticHost) -> bool { false } pub override fn deletable(&self, host: &SemanticHost) -> bool { true } } pub struct PackageReferenceValue: FixtureReferenceValue { pub(crate) fn PackageReferenceValue(base: &Thingy, property: &Thingy, static_type: &Thingy) { super(base, property, static_type); } } /// Array element reference value with a possibly non-nullable base. /// The key is assumed to be of the `Number` data type. pub struct ArrayElementReferenceValue: ReferenceValue { let ref m_base: Option = None; let ref m_key: Option = None; pub(crate) fn ArrayElementReferenceValue(base: &Thingy, key: &Thingy, static_type: &Thingy) { super(static_type); self.set_m_base(Some(base.clone())); self.set_m_key(Some(key.clone())); } pub override fn base(&self) -> Thingy { self.m_base().unwrap() } pub override fn key(&self) -> Thingy { self.m_key().unwrap() } pub override fn read_only(&self, host: &SemanticHost) -> bool { false } pub override fn write_only(&self, host: &SemanticHost) -> bool { false } pub override fn deletable(&self, host: &SemanticHost) -> bool { true } } /// Vector element reference value with a possibly non-nullable base. /// The key is assumed to be of the `Number` data type. pub struct VectorElementReferenceValue: ReferenceValue { let ref m_base: Option = None; let ref m_key: Option = None; pub(crate) fn VectorElementReferenceValue(base: &Thingy, key: &Thingy, static_type: &Thingy) { super(static_type); self.set_m_base(Some(base.clone())); self.set_m_key(Some(key.clone())); } pub override fn base(&self) -> Thingy { self.m_base().unwrap() } pub override fn key(&self) -> Thingy { self.m_key().unwrap() } pub override fn read_only(&self, host: &SemanticHost) -> bool { false } pub override fn write_only(&self, host: &SemanticHost) -> bool { false } pub override fn deletable(&self, host: &SemanticHost) -> bool { false } } /// Represents the resulting value of a conversion, whether implicit or explicit. pub struct ConversionValue: Value { let ref m_base: Option = None; let m_variant: TypeConversionVariant = TypeConversionVariant::BetweenNumber; let m_opt: bool = true; let ref m_target: Option = None; pub(crate) fn ConversionValue(base: &Thingy, variant: TypeConversionVariant, opt: bool, target: &Thingy, static_type: &Thingy) { super(static_type); self.set_m_base(Some(base.clone())); self.set_m_variant(variant); self.set_m_opt(opt); self.set_m_target(Some(target.clone())); } /// Original value. pub override fn base(&self) -> Thingy { self.m_base().unwrap() } pub override fn conversion_variant(&self) -> TypeConversionVariant { self.m_variant() } /// Indicates whether the conversion has been performed by the `as` operator /// (rather than `T(v)` or implicit conversion) and the resulting type /// has been either escaped out of non nullable or made nullable. pub override fn conversion_is_opt(&self) -> bool { self.m_opt() } pub override fn conversion_target(&self) -> Thingy { self.m_target().unwrap() } } /// Non-null assertion value as part of fields from object destructuring. pub struct NonNullValue: Value { let ref m_base: Option = None; pub(crate) fn NonNullValue(base: &Thingy, static_type: &Thingy) { super(static_type); self.set_m_base(Some(base.clone())); } /// Original value. pub override fn base(&self) -> Thingy { self.m_base().unwrap() } } /// Represents the direct value of a `function` expression, holding back its activation. pub struct LambdaObject: Value { let ref m_activation: Option = None; pub(crate) fn LambdaObject(activation: &Thingy, static_type: &Thingy) { super(static_type); self.set_m_activation(Some(activation.clone())); } // Returns a `Some(activation)` value. pub override fn activation(&self) -> Option { self.m_activation() } } /// Represents the direct value of a filter expression, holding back its scope. pub struct FilterValue: Value { let ref m_scope: Option = None; pub(crate) fn FilterValue(scope: &Thingy, static_type: &Thingy) { super(static_type); self.set_m_scope(Some(scope.clone())); } pub override fn scope(&self) -> Thingy { self.m_scope().unwrap() } } /// Resolutions of a field in an object initializer, including shorthand resolution /// and the field slot. This is only assigned to a field where applicable. pub struct FieldResolution: Thingy { let ref m_shorthand_resolution: Option = None; let ref m_field_slot: Option = None; pub(crate) fn FieldResolution() { super(); } pub override fn shorthand_resolution(&self) -> Option { self.m_shorthand_resolution() } pub override fn set_shorthand_resolution(&self, value: Option) { self.set_m_shorthand_resolution(value); } pub override fn field_slot(&self) -> Option { self.m_field_slot() } pub override fn set_field_slot(&self, value: Option) { self.set_m_field_slot(value); } } /// Resolutions of a field in a declarative object destructuring pattern. pub struct DeclarativeFieldDestructuringResolution: Thingy { let ref m_field_reference: Option = None; let ref m_var_slot: Option = None; pub(crate) fn DeclarativeFieldDestructuringResolution() { super(); } /// Reference value, non-null value, or constant. pub override fn field_reference(&self) -> Option { self.m_field_reference() } /// Reference value, non-null value, or constant. pub override fn set_field_reference(&self, value: Option) { self.set_m_field_reference(value); } /// For fields without subpatterns, indicates /// the assigned variable slot. pub override fn var_slot(&self) -> Option { self.m_var_slot() } /// For fields without subpatterns, indicates /// the assigned variable slot. pub override fn set_var_slot(&self, value: Option) { self.set_m_var_slot(value); } } /// Resolutions of a field in an assignment object destructuring pattern. pub struct AssignmentFieldDestructuringResolution: Thingy { let ref m_field_reference: Option = None; let ref m_target_reference: Option = None; pub(crate) fn AssignmentFieldDestructuringResolution() { super(); } /// Reference value, non-null value, or constant. pub override fn field_reference(&self) -> Option { self.m_field_reference() } /// Reference value, non-null value, or constant. pub override fn set_field_reference(&self, value: Option) { self.set_m_field_reference(value); } /// For fields without subpatterns, indicates /// the target reference value. pub override fn target_reference(&self) -> Option { self.m_target_reference() } /// For fields without subpatterns, indicates /// the target reference value. pub override fn set_target_reference(&self, value: Option) { self.set_m_target_reference(value); } } } impl ToString for Thingy { fn to_string(&self) -> String { self.to_string_1() } } impl DiagnosticArgument for Thingy {} #[derive(Copy, Clone, PartialEq)] pub enum SystemNamespaceKind { Public, Private, Protected, Internal, StaticProtected, } impl ToString for SystemNamespaceKind { fn to_string(&self) -> String { match self { Self::Public => "public".into(), Self::Private => "private".into(), Self::Protected => "protected".into(), Self::Internal => "internal".into(), Self::StaticProtected => "static protected".into(), } } } /// A qualified name in ActionScript 3 consisting of /// a namespace and a local name. /// /// This structure is not intended for E4X, but for representing /// ActionScript 3 property names. /// /// # Representation /// /// `QName` in this codebase is a type managed by reference counting. /// Calling `.clone()` in it will clone by reference, not by content. #[derive(Clone)] pub struct QName(pub(crate) Rc); impl QName { pub fn in_public_or_protected_ns(&self) -> bool { let ns = self.namespace(); ns.is_public_ns() || ns.is_protected_ns() } pub fn namespace(&self) -> Thingy { self.0.m_namespace.clone() } pub fn local_name(&self) -> String { self.0.m_local_name.clone() } pub fn matches_in_ns_set_or_any_public_ns(&self, ns_set: &SharedArray, local_name: &str) -> bool { let ns1 = self.namespace(); if !ns1.is_public_ns() { let found_ns = ns_set.iter().find(|ns2| &ns1 == ns2).is_some(); if !found_ns { return false; } } self.local_name() == local_name } } impl std::hash::Hash for QName { fn hash(&self, state: &mut H) { Rc::as_ptr(&self.0).hash(state) } } impl PartialEq for QName { fn eq(&self, other: &Self) -> bool { Rc::ptr_eq(&self.0, &other.0) } } impl Eq for QName {} pub(crate) struct QName1 { pub(crate) m_namespace: Thingy, pub(crate) m_local_name: String, } impl ToString for QName { fn to_string(&self) -> String { let q = self.namespace(); let lname = self.local_name(); if q.is::() { return lname; } format!("{}::{lname}", q.uri()) } } impl DiagnosticArgument for QName {} bitflags! { #[derive(Copy, Clone, PartialEq, Eq)] struct ClassTypeFlags: u16 { const IS_FINAL = 0b00000001; const IS_STATIC = 0b00000010; const IS_ABSTRACT = 0b00000100; const IS_DYNAMIC = 0b00001000; const IS_OPTIONS_CLASS = 0b00010000; } } bitflags! { #[derive(Copy, Clone, PartialEq, Eq)] struct VariableSlotFlags: u16 { const READ_ONLY = 0b00000010; } } bitflags! { #[derive(Copy, Clone, PartialEq, Eq)] struct VirtualSlotFlags: u16 { } } bitflags! { #[derive(Copy, Clone, PartialEq, Eq)] struct MethodSlotFlags: u16 { const IS_FINAL = 0b000000001; const IS_STATIC = 0b000000010; const IS_ABSTRACT = 0b000000100; const IS_OVERRIDING = 0b000010000; const IS_ASYNC = 0b000100000; const IS_GENERATOR = 0b001000000; const IS_CONSTRUCTOR = 0b010000000; } } /// Parameter belonging to a function type in the semantic model. pub struct SemanticFunctionTypeParameter { pub kind: ParameterKind, /// Static type of the parameter. It is never `UnresolvedThingy` /// as function types are only created after all compound types /// are resolved. pub static_type: Thingy, } impl SemanticFunctionTypeParameter { /// Performs type substitution. pub fn type_substitution(&self, host: &SemanticHost, type_params: &SharedArray, substitute_types: &SharedArray) -> Self { Self { kind: self.kind, static_type: TypeSubstitution(host).exec(&self.static_type, type_params, substitute_types), } } } #[derive(Clone)] pub struct ControlFlowGraph(Rc); impl ControlFlowGraph { pub fn new() -> Self { Self(Rc::new(ControlFlowGraph1 { blocks: SharedArray::new(), edges: SharedArray::new(), })) } pub fn blocks(&self) -> SharedArray { self.0.blocks.clone() } pub fn edges(&self) -> SharedArray { self.0.edges.clone() } } impl std::hash::Hash for ControlFlowGraph { fn hash(&self, state: &mut H) { Rc::as_ptr(&self.0).hash(state) } } impl PartialEq for ControlFlowGraph { fn eq(&self, other: &Self) -> bool { Rc::ptr_eq(&self.0, &other.0) } } impl Eq for ControlFlowGraph {} struct ControlFlowGraph1 { blocks: SharedArray, edges: SharedArray, } #[derive(Clone)] pub struct ControlFlowBlock(Rc>>); impl ControlFlowBlock { pub fn new(lines: Vec>) -> Self { Self(Rc::new(lines)) } pub fn lines(&self) -> Rc>> { self.0.clone() } } impl std::hash::Hash for ControlFlowBlock { fn hash(&self, state: &mut H) { Rc::as_ptr(&self.0).hash(state) } } impl PartialEq for ControlFlowBlock { fn eq(&self, other: &Self) -> bool { Rc::ptr_eq(&self.0, &other.0) } } impl Eq for ControlFlowBlock {} #[derive(Clone)] pub struct ControlFlowEdge { pub from: ControlFlowBlock, pub to: ControlFlowBlock, } // The third element is the descending most type. pub struct DescendingClassHierarchy<'a>(Option, &'a SemanticHost, Thingy); impl<'a> Iterator for DescendingClassHierarchy<'a> { type Item = Thingy; fn next(&mut self) -> Option { if let Some(r) = self.0.clone() { if r.is::() { self.0 = None; } else { self.0 = r.extends_class(self.1); if self.0.as_ref().unwrap() == &self.2 { self.0 = None; } } Some(r) } else { None } } } pub struct DescendingScopeHierarchy(Option); impl Iterator for DescendingScopeHierarchy { type Item = Thingy; fn next(&mut self) -> Option { if let Some(r) = self.0.clone() { self.0 = r.parent(); Some(r) } else { None } } } pub struct DescendingDefinitionHierarchy(Option); impl Iterator for DescendingDefinitionHierarchy { type Item = Thingy; fn next(&mut self) -> Option { if let Some(r) = self.0.clone() { self.0 = r.parent(); Some(r) } else { None } } } const DEFAULT_ACTIVATION: u8 = 0; const PACKAGE_INIT_ACTIVATION: u8 = 1; const GLOBAL_INIT_ACTIVATION: u8 = 2;