Bug 1172785 - Adding StaticClassOverride routing for JS implemented WebIDL, r=peterv
authorMartin Thomson <martin.thomson@gmail.com>
Mon, 06 Jul 2015 10:40:03 -0700
changeset 251590 183db3d9071e1655648d85e0ed46fc8823795353
parent 251589 2b835d207c96031d3ffa953532a50390967a2bca
child 251591 0ab638279d6b3921abed81a441304564dad80512
push id29007
push userryanvm@gmail.com
push dateTue, 07 Jul 2015 18:38:06 +0000
treeherdermozilla-central@9340658848d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs1172785
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1172785 - Adding StaticClassOverride routing for JS implemented WebIDL, r=peterv
dom/bindings/Codegen.py
dom/bindings/parser/WebIDL.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1133,16 +1133,19 @@ class CGHeaders(CGWrapper):
                     return
 
                 if "::" in func:
                     # Strip out the function name and convert "::" to "/"
                     bindingHeaders.add("/".join(func.split("::")[:-1]) + ".h")
 
             for m in desc.interface.members:
                 addHeaderForFunc(PropertyDefiner.getStringAttr(m, "Func"))
+                staticTypeOverride = PropertyDefiner.getStringAttr(m, "StaticClassOverride")
+                if staticTypeOverride:
+                    bindingHeaders.add("/".join(staticTypeOverride.split("::")) + ".h")
             # getExtendedAttribute() returns a list, extract the entry.
             funcList = desc.interface.getExtendedAttribute("Func")
             if funcList is not None:
                 addHeaderForFunc(funcList[0])
 
         for desc in descriptors:
             if desc.interface.maplikeOrSetlike:
                 # We need ToJSValue.h for maplike/setlike type conversions
@@ -6766,18 +6769,21 @@ class CGPerSignatureCall(CGThing):
             if setter:
                 lenientFloatCode = "return true;\n"
             elif idlNode.isMethod():
                 lenientFloatCode = ("args.rval().setUndefined();\n"
                                     "return true;\n")
 
         argsPre = []
         if static:
-            nativeMethodName = "%s::%s" % (descriptor.nativeType,
-                                           nativeMethodName)
+            nativeType = descriptor.nativeType
+            staticTypeOverride = PropertyDefiner.getStringAttr(idlNode, "StaticClassOverride")
+            if (staticTypeOverride):
+                nativeType = staticTypeOverride
+            nativeMethodName = "%s::%s" % (nativeType, nativeMethodName)
             # If we're a constructor, "obj" may not be a function, so calling
             # XrayAwareCalleeGlobal() on it is not safe.  Of course in the
             # constructor case either "obj" is an Xray or we're already in the
             # content compartment, not the Xray compartment, so just
             # constructing the GlobalObject from "obj" is fine.
             if isConstructor:
                 objForGlobalObject = "obj"
             else:
@@ -6804,19 +6810,20 @@ class CGPerSignatureCall(CGThing):
 
         needsUnwrap = False
         argsPost = []
         if isConstructor:
             needsUnwrap = True
             needsUnwrappedVar = False
             unwrappedVar = "obj"
         elif descriptor.interface.isJSImplemented():
-            needsUnwrap = True
-            needsUnwrappedVar = True
-            argsPost.append("js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)")
+            if not idlNode.isStatic():
+                needsUnwrap = True
+                needsUnwrappedVar = True
+                argsPost.append("js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)")
         elif needScopeObject(returnType, arguments, self.extendedAttributes,
                              descriptor.wrapperCache, True,
                              idlNode.getExtendedAttribute("StoreInSlot")):
             needsUnwrap = True
             needsUnwrappedVar = True
             argsPre.append("unwrappedObj ? *unwrappedObj : obj")
 
         if needsUnwrap and needsUnwrappedVar:
@@ -13278,17 +13285,17 @@ class CGExampleSetter(CGNativeMember):
     def define(self, cgClass):
         return ''
 
 
 class CGBindingImplClass(CGClass):
     """
     Common codegen for generating a C++ implementation of a WebIDL interface
     """
-    def __init__(self, descriptor, cgMethod, cgGetter, cgSetter, wantGetParent=True, wrapMethodName="WrapObject"):
+    def __init__(self, descriptor, cgMethod, cgGetter, cgSetter, wantGetParent=True, wrapMethodName="WrapObject", skipStaticMethods=False):
         """
         cgMethod, cgGetter and cgSetter are classes used to codegen methods,
         getters and setters.
         """
         self.descriptor = descriptor
         self._deps = descriptor.interface.getDeps()
 
         iface = descriptor.interface
@@ -13309,17 +13316,18 @@ class CGBindingImplClass(CGClass):
         if iface.ctor():
             appendMethod(iface.ctor(), isConstructor=True)
         for n in iface.namedConstructors:
             appendMethod(n, isConstructor=True)
         for m in iface.members:
             if m.isMethod():
                 if m.isIdentifierLess():
                     continue
-                appendMethod(m)
+                if not m.isStatic() or not skipStaticMethods:
+                    appendMethod(m)
             elif m.isAttr():
                 self.methodDecls.append(cgGetter(descriptor, m))
                 if not m.readonly:
                     self.methodDecls.append(cgSetter(descriptor, m))
 
         # Now do the special operations
         def appendSpecialOperation(name, op):
             if op is None:
@@ -13804,17 +13812,17 @@ class CGJSImplSetter(CGJSImplMember):
                                                          [FakeArgument(self.member.type, self.member)])]
         return 'mImpl->%s(%s);\n' % (
             callbackSetterName(self.member, self.descriptorProvider),
             ", ".join(callbackArgs))
 
 
 class CGJSImplClass(CGBindingImplClass):
     def __init__(self, descriptor):
-        CGBindingImplClass.__init__(self, descriptor, CGJSImplMethod, CGJSImplGetter, CGJSImplSetter)
+        CGBindingImplClass.__init__(self, descriptor, CGJSImplMethod, CGJSImplGetter, CGJSImplSetter, skipStaticMethods=True)
 
         if descriptor.interface.parent:
             parentClass = descriptor.getDescriptor(
                 descriptor.interface.parent.identifier.name).jsImplParent
             baseClasses = [ClassBase(parentClass)]
             isupportsDecl = "NS_DECL_ISUPPORTS_INHERITED\n"
             ccDecl = ("NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(%s, %s)\n" %
                       (descriptor.name, parentClass))
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -3372,17 +3372,17 @@ class IDLInterfaceMember(IDLObjectWithId
             if self.affects == "Everything" and self.dependsOn != "Everything":
                 raise WebIDLError("Interface member is flagged as affecting "
                                   "everything but not depending on everything. "
                                   "That seems rather unlikely.",
                                   [self.location])
 
         if self.getExtendedAttribute("NewObject"):
             if self.dependsOn == "Nothing" or self.dependsOn == "DOMState":
-                raise WebIDLError("A [NewObject] method is not idempotent, " 
+                raise WebIDLError("A [NewObject] method is not idempotent, "
                                   "so it has to depend on something other than DOM state.",
                                   [self.location])
 
     def _setDependsOn(self, dependsOn):
         if self.dependsOn != "Everything":
             raise WebIDLError("Trying to specify multiple different DependsOn, "
                               "Pure, or Constant extended attributes for "
                               "attribute", [self.location])
@@ -4523,16 +4523,22 @@ class IDLMethod(IDLInterfaceMember, IDLS
                               [overloadWithPromiseReturnType.location,
                                overloadWithoutPromiseReturnType.location])
 
         if overloadWithPromiseReturnType and self._legacycaller:
             raise WebIDLError("May not have a Promise return type for a "
                               "legacycaller.",
                               [overloadWithPromiseReturnType.location])
 
+        if self.getExtendedAttribute("StaticClassOverride") and not \
+           (self.identifier.scope.isJSImplemented() and self.isStatic()):
+            raise WebIDLError("StaticClassOverride can be applied to static"
+                              " methods on JS-implemented classes only.",
+                              [self.location])
+
     def overloadsForArgCount(self, argc):
         return [overload for overload in self._overloads if
                 len(overload.arguments) == argc or
                 (len(overload.arguments) > argc and
                  all(arg.optional for arg in overload.arguments[argc:])) or
                 (len(overload.arguments) < argc and
                  len(overload.arguments) > 0 and
                  overload.arguments[-1].variadic)]
@@ -4640,17 +4646,18 @@ class IDLMethod(IDLInterfaceMember, IDLS
               identifier == "ChromeOnly" or
               identifier == "UnsafeInPrerendering" or
               identifier == "Pref" or
               identifier == "Deprecated" or
               identifier == "Func" or
               identifier == "AvailableIn" or
               identifier == "CheckPermissions" or
               identifier == "BinaryName" or
-              identifier == "MethodIdentityTestable"):
+              identifier == "MethodIdentityTestable" or
+              identifier == "StaticClassOverride"):
             # Known attributes that we don't need to do anything with here
             pass
         else:
             raise WebIDLError("Unknown extended attribute %s on method" % identifier,
                               [attr.location])
         IDLInterfaceMember.handleExtendedAttribute(self, attr)
 
     def returnsPromise(self):