avm2: Add the ability to fork a `Class` to one that holds it's type arguments.

This commit is contained in:
David Wendt 2020-10-02 20:22:44 -04:00 committed by kmeisthax
parent 9dafddc1ae
commit fe8373739d
1 changed files with 31 additions and 0 deletions

View File

@ -29,6 +29,9 @@ bitflags! {
/// Class is an interface.
const INTERFACE = 1 << 2;
/// Class accepts type parameters.
const GENERIC = 1 << 3;
}
}
@ -71,6 +74,9 @@ pub struct Class<'gc> {
/// The name of the class.
name: QName<'gc>,
/// The type parameters for this class.
params: Vec<GcCell<'gc, Class<'gc>>>,
/// The name of this class's superclass.
super_class: Option<Multiname<'gc>>,
@ -214,6 +220,7 @@ impl<'gc> Class<'gc> {
mc,
Self {
name,
params: Vec::new(),
super_class,
attributes: ClassAttributes::empty(),
protected_namespace: None,
@ -230,6 +237,23 @@ impl<'gc> Class<'gc> {
)
}
/// Apply type parameters to an existing class.
///
/// This is used to parameterize a generic type. The returned class will no
/// longer be generic.
pub fn with_type_params(
&self,
params: &[GcCell<'gc, Class<'gc>>],
mc: MutationContext<'gc, '_>,
) -> GcCell<'gc, Class<'gc>> {
let mut new_class = self.clone();
new_class.params = params.to_vec();
new_class.attributes.remove(ClassAttributes::GENERIC);
GcCell::allocate(mc, new_class)
}
/// Set the attributes of the class (sealed/final/interface status).
pub fn set_attributes(&mut self, attributes: ClassAttributes) {
self.attributes = attributes;
@ -310,6 +334,7 @@ impl<'gc> Class<'gc> {
activation.context.gc_context,
Self {
name,
params: Vec::new(),
super_class,
attributes,
protected_namespace,
@ -392,6 +417,7 @@ impl<'gc> Class<'gc> {
activation.context.gc_context,
Self {
name: QName::dynamic_name(name),
params: Vec::new(),
super_class: None,
attributes: ClassAttributes::empty(),
protected_namespace: None,
@ -758,4 +784,9 @@ impl<'gc> Class<'gc> {
pub fn is_interface(&self) -> bool {
self.attributes.contains(ClassAttributes::INTERFACE)
}
/// Determine if this class is generic (can be specialized)
pub fn is_generic(&self) -> bool {
self.attributes.contains(ClassAttributes::GENERIC)
}
}