avm2: Implement `describeType(null)` stub (#16235)

This commit is contained in:
Jacob Greenfield 2024-05-10 18:06:56 -04:00 committed by GitHub
parent 636011e95e
commit 272c07ea3b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 100 additions and 1 deletions

View File

@ -15,9 +15,12 @@ pub fn describe_type_json<'gc>(
_this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let value = args[0].coerce_to_object(activation)?;
let flags = DescribeTypeFlags::from_bits(args.get_u32(activation, 1)?).expect("Invalid flags!");
if args[0] == Value::Null {
return describe_type_json_null(activation, flags);
}
let value = args[0].coerce_to_object(activation)?;
let class_obj = value.as_class_object().or_else(|| value.instance_of());
let object = activation
.avm2()
@ -80,6 +83,102 @@ bitflags::bitflags! {
}
}
fn describe_type_json_null<'gc>(
activation: &mut Activation<'_, 'gc>,
flags: DescribeTypeFlags,
) -> Result<Value<'gc>, Error<'gc>> {
if flags.contains(DescribeTypeFlags::USE_ITRAITS) {
return Ok(Value::Null);
}
let object = activation
.avm2()
.classes()
.object
.construct(activation, &[])?;
object.set_public_property("name", "null".into(), activation)?;
object.set_public_property("isDynamic", false.into(), activation)?;
object.set_public_property("isFinal", true.into(), activation)?;
object.set_public_property("isStatic", false.into(), activation)?;
let traits = activation
.avm2()
.classes()
.object
.construct(activation, &[])?;
if flags.contains(DescribeTypeFlags::INCLUDE_TRAITS) {
traits.set_public_property(
"bases",
if flags.contains(DescribeTypeFlags::INCLUDE_BASES) {
ArrayObject::empty(activation)?.into()
} else {
Value::Null
},
activation,
)?;
traits.set_public_property(
"interfaces",
if flags.contains(DescribeTypeFlags::INCLUDE_INTERFACES) {
ArrayObject::empty(activation)?.into()
} else {
Value::Null
},
activation,
)?;
traits.set_public_property(
"variables",
if flags.contains(DescribeTypeFlags::INCLUDE_VARIABLES) {
ArrayObject::empty(activation)?.into()
} else {
Value::Null
},
activation,
)?;
traits.set_public_property(
"accessors",
if flags.contains(DescribeTypeFlags::INCLUDE_ACCESSORS) {
ArrayObject::empty(activation)?.into()
} else {
Value::Null
},
activation,
)?;
traits.set_public_property(
"methods",
if flags.contains(DescribeTypeFlags::INCLUDE_METHODS) {
ArrayObject::empty(activation)?.into()
} else {
Value::Null
},
activation,
)?;
traits.set_public_property(
"metadata",
if flags.contains(DescribeTypeFlags::INCLUDE_METADATA) {
ArrayObject::empty(activation)?.into()
} else {
Value::Null
},
activation,
)?;
traits.set_public_property(
"constructor",
if flags.contains(DescribeTypeFlags::INCLUDE_CONSTRUCTOR) {
ArrayObject::empty(activation)?.into()
} else {
Value::Null
},
activation,
)?;
object.set_public_property("traits", traits.into(), activation)?;
} else {
object.set_public_property("traits", Value::Null, activation)?;
}
Ok(object.into())
}
fn describe_internal_body<'gc>(
activation: &mut Activation<'_, 'gc>,
class_obj: ClassObject<'gc>,