Bug 1131096. Use IDLExposureMixins for IDLInterfaceMember. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 13 Feb 2015 14:34:54 -0500
changeset 256336 36cbb1efffb3c827cad4e50ff8d57e2efcd4c93b
parent 256335 92ab79b20f61c617acf628feda416e81caebe484
child 256337 951df5de4aa1031ca4e1392908a216719e5f27b8
push id4610
push userjlund@mozilla.com
push dateMon, 30 Mar 2015 18:32:55 +0000
treeherdermozilla-beta@4df54044d9ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs1131096
milestone38.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 1131096. Use IDLExposureMixins for IDLInterfaceMember. r=peterv
dom/bindings/Codegen.py
dom/bindings/parser/WebIDL.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -2091,18 +2091,18 @@ def overloadLength(arguments):
 
 def methodLength(method):
     signatures = method.signatures()
     return min(overloadLength(arguments) for retType, arguments in signatures)
 
 
 def isMaybeExposedIn(member, descriptor):
     # All we can say for sure is that if this is a worker descriptor
-    # and member is only exposed in windows, then it's not exposed.
-    return not descriptor.workers or member.exposureSet != set(["Window"])
+    # and member is not exposed in any worker, then it's not exposed.
+    return not descriptor.workers or member.isExposedInAnyWorker()
 
 def clearableCachedAttrs(descriptor):
     return (m for m in descriptor.interface.members if
             m.isAttr() and
             # Constants should never need clearing!
             m.dependsOn != "Nothing" and
             m.slotIndex is not None)
 
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -451,18 +451,22 @@ class IDLIdentifierPlaceholder(IDLObject
 class IDLExposureMixins():
     def __init__(self, location):
         # _exposureGlobalNames are the global names listed in our [Exposed]
         # extended attribute.  exposureSet is the exposure set as defined in the
         # Web IDL spec: it contains interface names.
         self._exposureGlobalNames = set()
         self.exposureSet = set()
         self._location = location
+        self._globalScope = None
 
     def finish(self, scope):
+        assert scope.parentScope is None
+        self._globalScope = scope
+
         # Verify that our [Exposed] value, if any, makes sense.
         for globalName in self._exposureGlobalNames:
             if globalName not in scope.globalNames:
                 raise WebIDLError("Unknown [Exposed] value %s" % globalName,
                                   [self._location])
 
         if len(self._exposureGlobalNames) == 0:
             self._exposureGlobalNames.add(scope.primaryGlobalName)
@@ -487,18 +491,18 @@ class IDLExposureMixins():
         globals.
         """
         if not self.isExposedInAnyWorker():
             return False
         workerScopes = self.parentScope.globalNameMapping["Worker"]
         return len(workerScopes.difference(self.exposureSet)) > 0
 
     def getWorkerExposureSet(self):
-        # Subclasses that might be exposed in workers should override as needed
-        return set()
+        workerScopes = self._globalScope.globalNameMapping["Worker"]
+        return workerScopes.intersection(self.exposureSet)
 
 
 class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
     def __init__(self, location, parentScope, identifier):
         assert isinstance(identifier, IDLUnresolvedIdentifier)
         assert isinstance(parentScope, IDLScope)
         self.parent = None
         IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier)
@@ -796,19 +800,23 @@ class IDLInterface(IDLObjectWithScope, I
         for member in self.members:
             if not member.exposureSet.issubset(self.exposureSet):
                 raise WebIDLError("Interface member has larger exposure set "
                                   "than the interface itself",
                                   [member.location, self.location])
 
         ctor = self.ctor()
         if ctor is not None:
+            assert len(ctor._exposureGlobalNames) == 0
+            ctor._exposureGlobalNames.update(self._exposureGlobalNames)
             ctor.finish(scope)
 
         for ctor in self.namedConstructors:
+            assert len(ctor._exposureGlobalNames) == 0
+            ctor._exposureGlobalNames.update(self._exposureGlobalNames)
             ctor.finish(scope)
 
         # Make a copy of our member list, so things that implement us
         # can get those without all the stuff we implement ourselves
         # admixed.
         self.originalMembers = list(self.members)
 
         # Import everything from our consequential interfaces into
@@ -1105,20 +1113,16 @@ class IDLInterface(IDLObjectWithScope, I
             len(self.getConsequentialInterfaces()) == 0 and
             # No attributes of any kinds
             not any(m.isAttr() for m in self.members) and
             # There is at least one regular operation, and all regular
             # operations have the same identifier
             len(set(m.identifier.name for m in self.members if
                     m.isMethod() and not m.isStatic())) == 1)
 
-    def getWorkerExposureSet(self):
-        workerScopes = self.parentScope.globalNameMapping["Worker"]
-        return workerScopes.intersection(self.exposureSet)
-
     def inheritanceDepth(self):
         depth = 0
         parent = self.parent
         while parent:
             depth = depth + 1
             parent = parent.parent
         return depth
 
@@ -3051,17 +3055,17 @@ class IDLUndefinedValue(IDLObject):
 
         undefinedValue = IDLUndefinedValue(self.location)
         undefinedValue.type = type
         return undefinedValue
 
     def _getDependentObjects(self):
         return set()
 
-class IDLInterfaceMember(IDLObjectWithIdentifier):
+class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
 
     Tags = enum(
         'Const',
         'Attr',
         'Method'
     )
 
     Special = enum(
@@ -3069,23 +3073,19 @@ class IDLInterfaceMember(IDLObjectWithId
         'Stringifier'
     )
 
     AffectsValues = ("Nothing", "Everything")
     DependsOnValues = ("Nothing", "DOMState", "DeviceState", "Everything")
 
     def __init__(self, location, identifier, tag):
         IDLObjectWithIdentifier.__init__(self, location, None, identifier)
+        IDLExposureMixins.__init__(self, location)
         self.tag = tag
         self._extendedAttrDict = {}
-        # _exposureGlobalNames are the global names listed in our [Exposed]
-        # extended attribute.  exposureSet is the exposure set as defined in the
-        # Web IDL spec: it contains interface names.
-        self._exposureGlobalNames = set()
-        self.exposureSet = set()
 
     def isMethod(self):
         return self.tag == IDLInterfaceMember.Tags.Method
 
     def isAttr(self):
         return self.tag == IDLInterfaceMember.Tags.Attr
 
     def isConst(self):
@@ -3099,36 +3099,34 @@ class IDLInterfaceMember(IDLObjectWithId
 
     def handleExtendedAttribute(self, attr):
         pass
 
     def getExtendedAttribute(self, name):
         return self._extendedAttrDict.get(name, None)
 
     def finish(self, scope):
-        for globalName in self._exposureGlobalNames:
-            if globalName not in scope.globalNames:
-                raise WebIDLError("Unknown [Exposed] value %s" % globalName,
-                                  [self.location])
-        globalNameSetToExposureSet(scope, self._exposureGlobalNames,
-                                   self.exposureSet)
-        self._scope = scope
+        # We better be exposed _somewhere_.
+        if (len(self._exposureGlobalNames) == 0):
+            print self.identifier.name
+        assert len(self._exposureGlobalNames) != 0
+        IDLExposureMixins.finish(self, scope)
 
     def validate(self):
         if (self.getExtendedAttribute("Pref") and
-            self.exposureSet != set([self._scope.primaryGlobalName])):
+            self.exposureSet != set([self._globalScope.primaryGlobalName])):
             raise WebIDLError("[Pref] used on an interface member that is not "
-                              "%s-only" % self._scope.primaryGlobalName,
+                              "%s-only" % self._globalScope.primaryGlobalName,
                               [self.location])
 
         if (self.getExtendedAttribute("CheckPermissions") and
-            self.exposureSet != set([self._scope.primaryGlobalName])):
+            self.exposureSet != set([self._globalScope.primaryGlobalName])):
             raise WebIDLError("[CheckPermissions] used on an interface member "
                               "that is not %s-only" %
-                              self._scope.primaryGlobalName,
+                              self._globalScope.primaryGlobalName,
                               [self.location])
 
         if self.isAttr() or self.isMethod():
             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])