diff options
author | Ms2ger <ms2ger@gmail.com> | 2014-06-22 15:55:10 +0200 |
---|---|---|
committer | Ms2ger <ms2ger@gmail.com> | 2014-06-22 15:55:10 +0200 |
commit | edba815cf5330294061c1f9a560785c6466f6f3f (patch) | |
tree | dd75ef063f959432c52613d7e3fc9730b02f8acc /src/components/script/dom/bindings/codegen/CodegenRust.py | |
parent | 927ae398170a9ab0e7692901a84100f6e580bb36 (diff) | |
parent | 4f0d6979e7c38abd1addb87c8f27ffeb52967feb (diff) | |
download | servo-edba815cf5330294061c1f9a560785c6466f6f3f.tar.gz servo-edba815cf5330294061c1f9a560785c6466f6f3f.zip |
Merge pull request #2699 from Ms2ger/static-methods
Implement static IDL members; r=jdm
Diffstat (limited to 'src/components/script/dom/bindings/codegen/CodegenRust.py')
-rw-r--r-- | src/components/script/dom/bindings/codegen/CodegenRust.py | 223 |
1 files changed, 179 insertions, 44 deletions
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 69bf5c87335..7e4af465f9e 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1126,6 +1126,7 @@ class MethodDefiner(PropertyDefiner): m.isMethod() and m.isStatic() == static and not m.isIdentifierLess()] self.regular = [{"name": m.identifier.name, + "methodInfo": not m.isStatic(), "length": methodLength(m), "flags": "JSPROP_ENUMERATE" } for m in methods] @@ -1164,10 +1165,15 @@ class MethodDefiner(PropertyDefiner): specData) class AttrDefiner(PropertyDefiner): - def __init__(self, descriptor, name): + def __init__(self, descriptor, name, static): PropertyDefiner.__init__(self, descriptor, name) self.name = name - self.regular = [m for m in descriptor.interface.members if m.isAttr()] + self.regular = [ + m + for m in descriptor.interface.members + if m.isAttr() and m.isStatic() == static + ] + self.static = static def generateArray(self, array, name): if len(array) == 0: @@ -1177,20 +1183,37 @@ class AttrDefiner(PropertyDefiner): return "JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS" def getter(attr): - native = ("genericLenientGetter" if attr.hasLenientThis() - else "genericGetter") - return ("JSPropertyOpWrapper {op: Some(%(native)s), info: &%(name)s_getterinfo as *JSJitInfo}" - % {"name" : attr.identifier.name, - "native" : native}) + if self.static: + accessor = 'get_' + attr.identifier.name + jitinfo = "0" + else: + if attr.hasLenientThis(): + accessor = "genericLenientGetter" + else: + accessor = "genericGetter" + jitinfo = "&%s_getterinfo" % attr.identifier.name + + return ("JSPropertyOpWrapper {op: Some(%(native)s), info: %(info)s as *JSJitInfo}" + % {"info" : jitinfo, + "native" : accessor}) def setter(attr): if attr.readonly: return "JSStrictPropertyOpWrapper {op: None, info: 0 as *JSJitInfo}" - native = ("genericLenientSetter" if attr.hasLenientThis() - else "genericSetter") - return ("JSStrictPropertyOpWrapper {op: Some(%(native)s), info: &%(name)s_setterinfo as *JSJitInfo}" - % {"name" : attr.identifier.name, - "native" : native}) + + if self.static: + accessor = 'set_' + attr.identifier.name + jitinfo = "0" + else: + if attr.hasLenientThis(): + accessor = "genericLenientSetter" + else: + accessor = "genericSetter" + jitinfo = "&%s_setterinfo" % attr.identifier.name + + return ("JSStrictPropertyOpWrapper {op: Some(%(native)s), info: %(info)s as *JSJitInfo}" + % {"info" : jitinfo, + "native" : accessor}) def specData(attr): return (attr.identifier.name, flags(attr), getter(attr), @@ -1833,15 +1856,18 @@ class CGAbstractExternMethod(CGAbstractMethod): class PropertyArrays(): def __init__(self, descriptor): - self.staticMethods = MethodDefiner(descriptor, "StaticMethods", True) - self.methods = MethodDefiner(descriptor, "Methods", False) - self.attrs = AttrDefiner(descriptor, "Attributes") + self.staticMethods = MethodDefiner(descriptor, "StaticMethods", + static=True) + self.staticAttrs = AttrDefiner(descriptor, "StaticAttributes", + static=True) + self.methods = MethodDefiner(descriptor, "Methods", static=False) + self.attrs = AttrDefiner(descriptor, "Attributes", static=False) self.consts = ConstDefiner(descriptor, "Constants") pass @staticmethod def arrayNames(): - return [ "staticMethods", "methods", "attrs", "consts" ] + return [ "staticMethods", "staticAttrs", "methods", "attrs", "consts" ] def variableNames(self): names = {} @@ -2292,7 +2318,7 @@ class CGGetterCall(CGPerSignatureCall): """ def __init__(self, argsPre, returnType, nativeMethodName, descriptor, attr): CGPerSignatureCall.__init__(self, returnType, argsPre, [], - nativeMethodName, False, descriptor, + nativeMethodName, attr.isStatic(), descriptor, attr, getter=True) class FakeArgument(): @@ -2321,7 +2347,7 @@ class CGSetterCall(CGPerSignatureCall): def __init__(self, argsPre, argType, nativeMethodName, descriptor, attr): CGPerSignatureCall.__init__(self, None, argsPre, [FakeArgument(argType, attr, allowTreatNonObjectAsNull=True)], - nativeMethodName, False, descriptor, attr, + nativeMethodName, attr.isStatic(), descriptor, attr, setter=True) def wrap_return_value(self): # We have no return value @@ -2368,6 +2394,30 @@ class CGAbstractBindingMethod(CGAbstractExternMethod): def generate_code(self): assert(False) # Override me + +class CGAbstractStaticBindingMethod(CGAbstractMethod): + """ + Common class to generate the JSNatives for all our static methods, getters + and setters. This will generate the function declaration and unwrap the + global object. Subclasses are expected to override the generate_code + function to do the rest of the work. This function should return a + CGThing which is already properly indented. + """ + def __init__(self, descriptor, name): + args = [ + Argument('*mut JSContext', 'cx'), + Argument('libc::c_uint', 'argc'), + Argument('*mut JSVal', 'vp'), + ] + CGAbstractMethod.__init__(self, descriptor, name, "JSBool", args, extern=True) + + def definition_body(self): + return self.generate_code() + + def generate_code(self): + assert False # Override me + + class CGGenericMethod(CGAbstractBindingMethod): """ A class for generating the C++ code for an IDL method.. @@ -2396,12 +2446,32 @@ class CGSpecializedMethod(CGAbstractExternMethod): CGAbstractExternMethod.__init__(self, descriptor, name, 'JSBool', args) def definition_body(self): - name = self.method.identifier.name - return CGWrapper(CGMethodCall([], MakeNativeName(name), self.method.isStatic(), + nativeName = CGSpecializedMethod.makeNativeName(self.descriptor, + self.method) + return CGWrapper(CGMethodCall([], nativeName, self.method.isStatic(), self.descriptor, self.method), pre="let this = JS::from_raw(this);\n" "let mut this = this.root();\n") + @staticmethod + def makeNativeName(descriptor, method): + return MakeNativeName(method.identifier.name) + +class CGStaticMethod(CGAbstractStaticBindingMethod): + """ + A class for generating the Rust code for an IDL static method. + """ + def __init__(self, descriptor, method): + self.method = method + name = method.identifier.name + CGAbstractStaticBindingMethod.__init__(self, descriptor, name) + + def generate_code(self): + nativeName = CGSpecializedMethod.makeNativeName(self.descriptor, + self.method) + return CGMethodCall([], nativeName, True, self.descriptor, self.method) + + class CGGenericGetter(CGAbstractBindingMethod): """ A class for generating the C++ code for an IDL attribute getter. @@ -2441,18 +2511,41 @@ class CGSpecializedGetter(CGAbstractExternMethod): CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args) def definition_body(self): - name = self.attr.identifier.name - nativeName = MakeNativeName(name) - infallible = ('infallible' in - self.descriptor.getExtendedAttributes(self.attr, - getter=True)) - if self.attr.type.nullable() or not infallible: - nativeName = "Get" + nativeName + nativeName = CGSpecializedGetter.makeNativeName(self.descriptor, + self.attr) + return CGWrapper(CGGetterCall([], self.attr.type, nativeName, self.descriptor, self.attr), pre="let this = JS::from_raw(this);\n" "let mut this = this.root();\n") + @staticmethod + def makeNativeName(descriptor, attr): + nativeName = MakeNativeName(attr.identifier.name) + infallible = ('infallible' in + descriptor.getExtendedAttributes(attr, getter=True)) + if attr.type.nullable() or not infallible: + return "Get" + nativeName + + return nativeName + + +class CGStaticGetter(CGAbstractStaticBindingMethod): + """ + A class for generating the C++ code for an IDL static attribute getter. + """ + def __init__(self, descriptor, attr): + self.attr = attr + name = 'get_' + attr.identifier.name + CGAbstractStaticBindingMethod.__init__(self, descriptor, name) + + def generate_code(self): + nativeName = CGSpecializedGetter.makeNativeName(self.descriptor, + self.attr) + return CGGetterCall([], self.attr.type, nativeName, self.descriptor, + self.attr) + + class CGGenericSetter(CGAbstractBindingMethod): """ A class for generating the Rust code for an IDL attribute setter. @@ -2497,13 +2590,40 @@ class CGSpecializedSetter(CGAbstractExternMethod): CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args) def definition_body(self): - name = self.attr.identifier.name - return CGWrapper(CGSetterCall([], self.attr.type, - "Set" + MakeNativeName(name), + nativeName = CGSpecializedSetter.makeNativeName(self.descriptor, + self.attr) + return CGWrapper(CGSetterCall([], self.attr.type, nativeName, self.descriptor, self.attr), pre="let this = JS::from_raw(this);\n" "let mut this = this.root();\n") + @staticmethod + def makeNativeName(descriptor, attr): + return "Set" + MakeNativeName(attr.identifier.name) + + +class CGStaticSetter(CGAbstractStaticBindingMethod): + """ + A class for generating the C++ code for an IDL static attribute setter. + """ + def __init__(self, descriptor, attr): + self.attr = attr + name = 'set_' + attr.identifier.name + CGAbstractStaticBindingMethod.__init__(self, descriptor, name) + + def generate_code(self): + nativeName = CGSpecializedSetter.makeNativeName(self.descriptor, + self.attr) + checkForArg = CGGeneric( + "let argv = JS_ARGV(cx, vp);\n" + "if (argc == 0) {\n" + " // XXXjdmreturn ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, \"%s setter\");\n" + " return 0;\n" + "}\n" % self.attr.identifier.name) + call = CGSetterCall([], self.attr.type, nativeName, self.descriptor, + self.attr) + return CGList([checkForArg, call]) + class CGMemberJITInfo(CGThing): """ @@ -3835,23 +3955,38 @@ class CGDescriptor(CGThing): (hasMethod, hasGetter, hasLenientGetter, hasSetter, hasLenientSetter) = False, False, False, False, False for m in descriptor.interface.members: - if m.isMethod() and not m.isStatic() and not m.isIdentifierLess(): - cgThings.append(CGSpecializedMethod(descriptor, m)) - cgThings.append(CGMemberJITInfo(descriptor, m)) - hasMethod = True + if m.isMethod() and not m.isIdentifierLess(): + if m.isStatic(): + assert descriptor.interface.hasInterfaceObject() + cgThings.append(CGStaticMethod(descriptor, m)) + elif descriptor.interface.hasInterfacePrototypeObject(): + cgThings.append(CGSpecializedMethod(descriptor, m)) + cgThings.append(CGMemberJITInfo(descriptor, m)) + hasMethod = True elif m.isAttr(): - cgThings.append(CGSpecializedGetter(descriptor, m)) - if m.hasLenientThis(): - hasLenientGetter = True - else: - hasGetter = True - if not m.readonly: - cgThings.append(CGSpecializedSetter(descriptor, m)) + if m.isStatic(): + assert descriptor.interface.hasInterfaceObject() + cgThings.append(CGStaticGetter(descriptor, m)) + elif descriptor.interface.hasInterfacePrototypeObject(): + cgThings.append(CGSpecializedGetter(descriptor, m)) if m.hasLenientThis(): - hasLenientSetter = True + hasLenientGetter = True else: - hasSetter = True - cgThings.append(CGMemberJITInfo(descriptor, m)) + hasGetter = True + + if not m.readonly: + if m.isStatic(): + assert descriptor.interface.hasInterfaceObject() + cgThings.append(CGStaticSetter(descriptor, m)) + elif descriptor.interface.hasInterfacePrototypeObject(): + cgThings.append(CGSpecializedSetter(descriptor, m)) + if m.hasLenientThis(): + hasLenientSetter = True + else: + hasSetter = True + + if not m.isStatic() and descriptor.interface.hasInterfacePrototypeObject(): + cgThings.append(CGMemberJITInfo(descriptor, m)) if hasMethod: cgThings.append(CGGenericMethod(descriptor)) if hasGetter: |