Merge pull request #2695 from Ms2ger/NativeProperties

Introduce a NativeProperties struct; r=jdm
This commit is contained in:
Ms2ger 2014-06-22 14:19:17 +02:00
commit 5e21e981ae
2 changed files with 51 additions and 36 deletions

View file

@ -1064,9 +1064,10 @@ class PropertyDefiner:
self.name = name self.name = name
def variableName(self): def variableName(self):
if len(self.regular) > 0: return "s" + self.name
return "s" + self.name
return "ptr::null()" def length(self):
return len(self.regular)
def __str__(self): def __str__(self):
# We only need to generate id arrays for things that will end # We only need to generate id arrays for things that will end
@ -1101,9 +1102,9 @@ class PropertyDefiner:
if specTerminator: if specTerminator:
specs.append(specTerminator) specs.append(specTerminator)
return (("static %s: [%s, ..%i] = [\n" + return (("static %s: &'static [%s] = &[\n" +
",\n".join(specs) + "\n" + ",\n".join(specs) + "\n" +
"];\n\n") % (name, specType, len(specs))) "];\n\n") % (name, specType))
# The length of a method is the maximum of the lengths of the # The length of a method is the maximum of the lengths of the
# argument lists of all its overloads. # argument lists of all its overloads.
@ -1853,6 +1854,31 @@ class PropertyArrays():
define += str(getattr(self, array)) define += str(getattr(self, array))
return define return define
class CGNativeProperties(CGThing):
def __init__(self, descriptor, properties):
CGThing.__init__(self)
self.properties = properties
def define(self):
def getField(array):
propertyArray = getattr(self.properties, array)
if propertyArray.length() > 0:
value = "Some(%s)" % propertyArray.variableName()
else:
value = "None"
return CGGeneric(string.Template('${name}: ${value},').substitute({
'name': array,
'value': value,
}))
nativeProps = CGList([getField(array) for array in self.properties.arrayNames()], '\n')
return CGWrapper(CGIndenter(nativeProps),
pre="static sNativeProperties: NativeProperties = NativeProperties {\n",
post="\n};\n").define()
class CGCreateInterfaceObjectsMethod(CGAbstractMethod): class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
""" """
Generate the CreateInterfaceObjects method for an interface descriptor. Generate the CreateInterfaceObjects method for an interface descriptor.
@ -1890,12 +1916,6 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
else: else:
domClass = "ptr::null()" domClass = "ptr::null()"
def arrayPtr(name):
val = ('%(' + name + ')s') % self.properties.variableNames()
if val == "ptr::null()":
return "None"
return "Some(%s.as_slice())" % val
if needInterfaceObject: if needInterfaceObject:
if self.descriptor.interface.ctor(): if self.descriptor.interface.ctor():
constructHook = CONSTRUCT_HOOK_NAME constructHook = CONSTRUCT_HOOK_NAME
@ -1913,14 +1933,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto, call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto,
&PrototypeClass, %s, &PrototypeClass, %s,
%s, %s,
%s, &sNativeProperties);""" % (constructor, domClass)
%s,
%s,
%s);""" % (
constructor,
domClass,
arrayPtr("methods"), arrayPtr("attrs"),
arrayPtr("consts"), arrayPtr("staticMethods"))
return CGList([ return CGList([
CGGeneric(getParentProto), CGGeneric(getParentProto),
@ -3863,6 +3876,7 @@ class CGDescriptor(CGThing):
properties = PropertyArrays(descriptor) properties = PropertyArrays(descriptor)
cgThings.append(CGGeneric(str(properties))) cgThings.append(CGGeneric(str(properties)))
cgThings.append(CGNativeProperties(descriptor, properties))
cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties)) cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties))
cgThings.append(CGNamespace.build([descriptor.name + "Constants"], cgThings.append(CGNamespace.build([descriptor.name + "Constants"],
@ -4233,6 +4247,7 @@ class CGBindingRoot(CGThing):
'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}', 'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}',
'dom::bindings::utils::VoidVal', 'dom::bindings::utils::VoidVal',
'dom::bindings::utils::get_dictionary_property', 'dom::bindings::utils::get_dictionary_property',
'dom::bindings::utils::NativeProperties',
'dom::bindings::trace::JSTraceable', 'dom::bindings::trace::JSTraceable',
'dom::bindings::callback::{CallbackContainer,CallbackInterface,CallbackFunction}', 'dom::bindings::callback::{CallbackContainer,CallbackInterface,CallbackFunction}',
'dom::bindings::callback::{CallSetup,ExceptionHandling}', 'dom::bindings::callback::{CallSetup,ExceptionHandling}',

View file

@ -215,6 +215,13 @@ pub fn GetProtoOrIfaceArray(global: *mut JSObject) -> *mut *mut JSObject {
} }
} }
pub struct NativeProperties {
pub methods: Option<&'static [JSFunctionSpec]>,
pub attrs: Option<&'static [JSPropertySpec]>,
pub consts: Option<&'static [ConstantSpec]>,
pub staticMethods: Option<&'static [JSFunctionSpec]>,
}
pub type NonNullJSNative = pub type NonNullJSNative =
unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> JSBool; unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> JSBool;
@ -223,13 +230,9 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv
protoClass: &'static JSClass, protoClass: &'static JSClass,
constructor: Option<(NonNullJSNative, &'static str, u32)>, constructor: Option<(NonNullJSNative, &'static str, u32)>,
domClass: *DOMClass, domClass: *DOMClass,
methods: Option<&'static [JSFunctionSpec]>, members: &'static NativeProperties) -> *mut JSObject {
properties: Option<&'static [JSPropertySpec]>,
constants: Option<&'static [ConstantSpec]>,
staticMethods: Option<&'static [JSFunctionSpec]>) -> *mut JSObject {
let proto = CreateInterfacePrototypeObject(cx, global, protoProto, let proto = CreateInterfacePrototypeObject(cx, global, protoProto,
protoClass, methods, protoClass, members);
properties, constants);
unsafe { unsafe {
JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT, JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
@ -241,7 +244,7 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv
name.to_c_str().with_ref(|s| { name.to_c_str().with_ref(|s| {
CreateInterfaceObject(cx, global, receiver, CreateInterfaceObject(cx, global, receiver,
native, nargs, proto, native, nargs, proto,
staticMethods, constants, s) members, s)
}) })
}, },
None => (), None => (),
@ -253,8 +256,7 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv
fn CreateInterfaceObject(cx: *mut JSContext, global: *mut JSObject, receiver: *mut JSObject, fn CreateInterfaceObject(cx: *mut JSContext, global: *mut JSObject, receiver: *mut JSObject,
constructorNative: NonNullJSNative, constructorNative: NonNullJSNative,
ctorNargs: u32, proto: *mut JSObject, ctorNargs: u32, proto: *mut JSObject,
staticMethods: Option<&'static [JSFunctionSpec]>, members: &'static NativeProperties,
constants: Option<&'static [ConstantSpec]>,
name: *libc::c_char) { name: *libc::c_char) {
unsafe { unsafe {
let fun = JS_NewFunction(cx, Some(constructorNative), ctorNargs, let fun = JS_NewFunction(cx, Some(constructorNative), ctorNargs,
@ -264,12 +266,12 @@ fn CreateInterfaceObject(cx: *mut JSContext, global: *mut JSObject, receiver: *m
let constructor = JS_GetFunctionObject(fun); let constructor = JS_GetFunctionObject(fun);
assert!(constructor.is_not_null()); assert!(constructor.is_not_null());
match staticMethods { match members.staticMethods {
Some(staticMethods) => DefineMethods(cx, constructor, staticMethods), Some(staticMethods) => DefineMethods(cx, constructor, staticMethods),
_ => (), _ => (),
} }
match constants { match members.consts {
Some(constants) => DefineConstants(cx, constructor, constants), Some(constants) => DefineConstants(cx, constructor, constants),
_ => (), _ => (),
} }
@ -323,24 +325,22 @@ fn DefineProperties(cx: *mut JSContext, obj: *mut JSObject, properties: &'static
fn CreateInterfacePrototypeObject(cx: *mut JSContext, global: *mut JSObject, fn CreateInterfacePrototypeObject(cx: *mut JSContext, global: *mut JSObject,
parentProto: *mut JSObject, parentProto: *mut JSObject,
protoClass: &'static JSClass, protoClass: &'static JSClass,
methods: Option<&'static [JSFunctionSpec]>, members: &'static NativeProperties) -> *mut JSObject {
properties: Option<&'static [JSPropertySpec]>,
constants: Option<&'static [ConstantSpec]>) -> *mut JSObject {
unsafe { unsafe {
let ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global); let ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global);
assert!(ourProto.is_not_null()); assert!(ourProto.is_not_null());
match methods { match members.methods {
Some(methods) => DefineMethods(cx, ourProto, methods), Some(methods) => DefineMethods(cx, ourProto, methods),
_ => (), _ => (),
} }
match properties { match members.attrs {
Some(properties) => DefineProperties(cx, ourProto, properties), Some(properties) => DefineProperties(cx, ourProto, properties),
_ => (), _ => (),
} }
match constants { match members.consts {
Some(constants) => DefineConstants(cx, ourProto, constants), Some(constants) => DefineConstants(cx, ourProto, constants),
_ => (), _ => (),
} }