Make PerSignatureCall a CGThing
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 15 Feb 2012 18:22:30 -0500
changeset 86825 2e5d8644b9f49e20d9cd135e0eb33fce43f72c83
parent 86824 e8a0f580cbe86dc18dd9820b79983b06ba9d801a
child 86826 3780687308b494ce921f06cbef57da51c2ce1b98
push id127
push userbzbarsky@mozilla.com
push dateWed, 15 Feb 2012 23:22:40 +0000
milestone13.0a1
Make PerSignatureCall a CGThing
dom/bindings/Codegen.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -956,17 +956,17 @@ class CGCallGenerator(CGThing):
             self.cgRoot.prepend(CGGeneric("nsresult rv = NS_OK;"))
             self.cgRoot.append(CGGeneric("if (NS_FAILED(rv)) {"))
             self.cgRoot.append(CGIndenter(CGGeneric(errorReport)))
             self.cgRoot.append(CGGeneric("}"))
 
     def define(self):
         return self.cgRoot.define()
 
-class PerSignatureCall():
+class PerSignatureCall(CGThing):
     """
     This class handles the guts of generating code for a particular
     call signature.  A call signature consists of three things:
 
     1) A return type, which can be None to indicate that there is no
        actual return value (e.g. this is an attribute setter) or an
        IDLType if there's an IDL type involved (including |void|).
     2) An argument list, which is allowed to be empty.
@@ -987,33 +987,32 @@ class PerSignatureCall():
     #       as first element.  Methods with no args have length-0 arg
     #       lists as second element in signaure.
     # XXXbz if isInterface() true on a type, type.inner is the interface object
     # XXXbz is isPrimitive() true on a type, then .tag() will return an
     #       IDLType.Tags value.  So you can compare
     #       type.tag() == IDLType.Tags.int8 or whatever.
     def __init__(self, returnType, arguments, nativeMethodName,
                  descriptor, idlNode, extendedAttributes):
+        CGThing.__init__(self)
         self.returnType = returnType
-        self.arguments = arguments
-        self.nativeMethodName = nativeMethodName
         self.descriptor = descriptor
         self.idlNode = idlNode
         self.extendedAttributes = extendedAttributes
         # Default to already_AddRefed on the main thread, raw pointer in workers
         self.resultAlreadyAddRefed = not descriptor.workers
         
-        argCount = len(self.arguments)
-        cgThings = [CGArgumentConverter(self.arguments[i], i, self.getArgv(),
+        self.argCount = len(arguments)
+        cgThings = [CGArgumentConverter(arguments[i], i, self.getArgv(),
                                         self.getArgc(), self.descriptor) for
-                    i in range(argCount)]
+                    i in range(self.argCount)]
         cgThings.append(CGGeneric("\n"))
         cgThings.append(CGIndenter(CGCallGenerator(
                     self.getErrorReport() if self.isFallible() else None,
-                    argCount, returnType, self.resultAlreadyAddRefed,
+                    self.argCount, returnType, self.resultAlreadyAddRefed,
                     descriptor, nativeMethodName)))
         self.cgRoot = CGList(cgThings)
 
     def getArgv(self):
         assert(False) # Override me
     def getArgc(self):
         assert(False) # Override me
     def getErrorReport(self):
@@ -1028,17 +1027,17 @@ class PerSignatureCall():
             getWrapTemplateForType(self.returnType, self.descriptor,
                                    self.resultAlreadyAddRefed)
             ).substitute(resultTemplateValues)
 
     def getErrorReport(self):
         return 'return ThrowMethodFailedWithDetails(cx, rv, "%s", "%s");'\
                % (self.descriptor.name, self.idlNode.identifier.name)
 
-    def __str__(self):
+    def define(self):
         return (self.cgRoot.define() + self.wrap_return_value())
 
 class PerSignatureMethodCall(PerSignatureCall):
     def __init__(self, returnType, arguments, nativeMethodName, descriptor,
                  method, extendedAttributes):
         PerSignatureCall.__init__(self, returnType, arguments, nativeMethodName,
                                   descriptor, method, extendedAttributes)
 
@@ -1057,17 +1056,17 @@ class PerSignatureMethodCall(PerSignatur
             else:
                 argv = []
             argv.append(CGGeneric("JS::Value *argv = JS_ARGV(cx, vp);"))
             self.cgRoot.prepend(CGWrapper(CGIndenter(CGList(argv, "\n")),
                                           pre="\n",
                                           post="\n"))
 
     def getArgv(self):
-        return "argv" if len(self.arguments) > 0 else ""
+        return "argv" if self.argCount > 0 else ""
     def getArgc(self):
         return "argc"
 
 class GetterSetterCall(PerSignatureCall):
     def __init__(self, returnType, arguments, nativeMethodName, descriptor,
                  attr, extendedAttributes):
         PerSignatureCall.__init__(self, returnType, arguments, nativeMethodName,
                                   descriptor, attr, extendedAttributes)
@@ -1147,44 +1146,44 @@ class CGNativeMethod(CGNativeBindingMeth
         nativeName = MakeNativeName(self.method.identifier.name)
         callGenerators = [PerSignatureMethodCall(s[0], s[1], nativeName,
                                                  self.descriptor, self.method,
                                                  self.extendedAttributes)
                           for s in signatures]
         if len(callGenerators) != 1:
             raise TypeError("Don't know how to handle overloads yet.  Will need to generate code to pick the right overload based on the arguments, then jump to the right generated code")
 
-        return str(callGenerators[0]);
+        return callGenerators[0].define();
 
 class CGNativeGetter(CGNativeBindingMethod):
     def __init__(self, descriptor, attr):
         self.attr = attr
         baseName = attr.identifier.name
         args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'obj'),
                 Argument('jsid', 'id'), Argument('JS::Value*', 'vp')]
         CGNativeBindingMethod.__init__(self, descriptor, 'get_' + baseName,
                                        'JSBool', args, baseName)
     def generate_code(self):
         nativeMethodName = "Get" + MakeNativeName(self.attr.identifier.name)
-        return str(GetterCall(self.attr.type, nativeMethodName, self.descriptor,
-                              self.attr, self.extendedAttributes))
+        return GetterCall(self.attr.type, nativeMethodName, self.descriptor,
+                          self.attr, self.extendedAttributes).define()
 
 class CGNativeSetter(CGNativeBindingMethod):
     def __init__(self, descriptor, attr):
         self.attr = attr
         baseName = attr.identifier.name
         args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'obj'),
                 Argument('jsid', 'id'), Argument('JSBool', 'strict'),
                 Argument('JS::Value*', 'vp')]
         CGNativeBindingMethod.__init__(self, descriptor, 'set_' + baseName,
                                        'JSBool', args, baseName)
     def generate_code(self):
         nativeMethodName = "Set" + MakeNativeName(self.attr.identifier.name)
-        return str(SetterCall(self.attr.type, nativeMethodName, self.descriptor,
-                              self.attr, self.extendedAttributes))
+        return SetterCall(self.attr.type, nativeMethodName, self.descriptor,
+                          self.attr, self.extendedAttributes).define()
 
 def getEnumValueName(value):
     # Some enum values can be empty strings.  Others might have weird
     # characters in them.  Deal with the former by returning "_empty",
     # deal with possible name collisions from that by throwing if the
     # enum value is actually "_empty", and throw on any value
     # containing chars other than [a-z] for now.
     if value == "_empty":