diff options
Diffstat (limited to 'components/script/dom/bindings/codegen/Configuration.py')
-rw-r--r-- | components/script/dom/bindings/codegen/Configuration.py | 138 |
1 files changed, 83 insertions, 55 deletions
diff --git a/components/script/dom/bindings/codegen/Configuration.py b/components/script/dom/bindings/codegen/Configuration.py index 0fe9bf6c004..b92f68af3b9 100644 --- a/components/script/dom/bindings/codegen/Configuration.py +++ b/components/script/dom/bindings/codegen/Configuration.py @@ -1,10 +1,11 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# file, You can obtain one at https://mozilla.org/MPL/2.0/. +import functools import os -from WebIDL import IDLExternalInterface, IDLWrapperType, WebIDLError +from WebIDL import IDLExternalInterface, IDLSequenceType, IDLWrapperType, WebIDLError class Configuration: @@ -15,7 +16,7 @@ class Configuration: def __init__(self, filename, parseData): # Read the configuration file. glbl = {} - execfile(filename, glbl) + exec(compile(open(filename).read(), filename, 'exec'), glbl) config = glbl['DOMInterfaces'] # Build descriptors for all the interfaces we have in the parse data. @@ -38,11 +39,6 @@ class Configuration: iface = thing self.interfaces[iface.identifier.name] = iface if iface.identifier.name not in config: - # Completely skip consequential interfaces with no descriptor - # if they have no interface object because chances are we - # don't need to do anything interesting with them. - if iface.isConsequential() and not iface.hasInterfaceObject(): - continue entry = {} else: entry = config[iface.identifier.name] @@ -67,7 +63,9 @@ class Configuration: c.isCallback() and not c.isInterface()] # Keep the descriptor list sorted for determinism. - self.descriptors.sort(lambda x, y: cmp(x.name, y.name)) + def cmp(x, y): + return (x > y) - (x < y) + self.descriptors.sort(key=functools.cmp_to_key(lambda x, y: cmp(x.name, y.name))) def getInterface(self, ifname): return self.interfaces[ifname] @@ -75,35 +73,45 @@ class Configuration: def getDescriptors(self, **filters): """Gets the descriptors that match the given filters.""" curr = self.descriptors - for key, val in filters.iteritems(): + for key, val in filters.items(): if key == 'webIDLFile': - getter = lambda x: x.interface.filename() + def getter(x): + return x.interface.filename() elif key == 'hasInterfaceObject': - getter = lambda x: x.interface.hasInterfaceObject() + def getter(x): + return x.interface.hasInterfaceObject() elif key == 'isCallback': - getter = lambda x: x.interface.isCallback() + def getter(x): + return x.interface.isCallback() elif key == 'isNamespace': - getter = lambda x: x.interface.isNamespace() + def getter(x): + return x.interface.isNamespace() elif key == 'isJSImplemented': - getter = lambda x: x.interface.isJSImplemented() + def getter(x): + return x.interface.isJSImplemented() elif key == 'isGlobal': - getter = lambda x: x.isGlobal() + def getter(x): + return x.isGlobal() elif key == 'isInline': - getter = lambda x: x.interface.getExtendedAttribute('Inline') is not None + def getter(x): + return x.interface.getExtendedAttribute('Inline') is not None elif key == 'isExposedConditionally': - getter = lambda x: x.interface.isExposedConditionally() + def getter(x): + return x.interface.isExposedConditionally() elif key == 'isIteratorInterface': - getter = lambda x: x.interface.isIteratorInterface() + def getter(x): + return x.interface.isIteratorInterface() else: - getter = lambda x: getattr(x, key) - curr = filter(lambda x: getter(x) == val, curr) + def getter(x): + return getattr(x, key) + curr = [x for x in curr if getter(x) == val] return curr def getEnums(self, webIDLFile): - return filter(lambda e: e.filename() == webIDLFile, self.enums) + return [e for e in self.enums if e.filename() == webIDLFile] def getTypedefs(self, webIDLFile): - return filter(lambda e: e.filename() == webIDLFile, self.typedefs) + return [e for e in self.typedefs if e.filename() == webIDLFile] @staticmethod def _filterForFile(items, webIDLFile=""): @@ -111,7 +119,7 @@ class Configuration: if not webIDLFile: return items - return filter(lambda x: x.filename() == webIDLFile, items) + return [x for x in items if x.filename() == webIDLFile] def getDictionaries(self, webIDLFile=""): return self._filterForFile(self.dictionaries, webIDLFile=webIDLFile) @@ -128,8 +136,8 @@ class Configuration: # We should have exactly one result. if len(descriptors) != 1: - raise NoSuchDescriptorError("For " + interfaceName + " found " + - str(len(descriptors)) + " matches") + raise NoSuchDescriptorError("For " + interfaceName + " found " + + str(len(descriptors)) + " matches") return descriptors[0] def getDescriptorProvider(self): @@ -160,10 +168,10 @@ class DescriptorProvider: def MemberIsUnforgeable(member, descriptor): - return ((member.isAttr() or member.isMethod()) and - not member.isStatic() and - (member.isUnforgeable() or - bool(descriptor.interface.getExtendedAttribute("Unforgeable")))) + return ((member.isAttr() or member.isMethod()) + and not member.isStatic() + and (member.isUnforgeable() + or bool(descriptor.interface.getExtendedAttribute("Unforgeable")))) class Descriptor(DescriptorProvider): @@ -204,40 +212,41 @@ class Descriptor(DescriptorProvider): self.returnType = 'Rc<%s>' % typeName self.argumentType = '&%s' % typeName self.nativeType = typeName - pathDefault = 'dom::types::%s' % typeName + pathDefault = 'crate::dom::types::%s' % typeName elif self.interface.isCallback(): - ty = 'dom::bindings::codegen::Bindings::%sBinding::%s' % (ifaceName, ifaceName) + ty = 'crate::dom::bindings::codegen::Bindings::%sBinding::%s' % (ifaceName, ifaceName) pathDefault = ty self.returnType = "Rc<%s>" % ty self.argumentType = "???" self.nativeType = ty else: - self.returnType = "Root<%s>" % typeName + self.returnType = "DomRoot<%s>" % typeName self.argumentType = "&%s" % typeName self.nativeType = "*const %s" % typeName if self.interface.isIteratorInterface(): - pathDefault = 'dom::bindings::iterable::IterableIterator' + pathDefault = 'crate::dom::bindings::iterable::IterableIterator' else: - pathDefault = 'dom::types::%s' % MakeNativeName(typeName) + pathDefault = 'crate::dom::types::%s' % MakeNativeName(typeName) self.concreteType = typeName self.register = desc.get('register', True) self.path = desc.get('path', pathDefault) - self.bindingPath = 'dom::bindings::codegen::Bindings::%s' % ('::'.join([ifaceName + 'Binding'] * 2)) + self.inRealmMethods = [name for name in desc.get('inRealms', [])] + self.bindingPath = 'crate::dom::bindings::codegen::Bindings::%s' % ('::'.join([ifaceName + 'Binding'] * 2)) self.outerObjectHook = desc.get('outerObjectHook', 'None') self.proxy = False self.weakReferenceable = desc.get('weakReferenceable', False) # If we're concrete, we need to crawl our ancestor interfaces and mark # them as having a concrete descendant. - self.concrete = (not self.interface.isCallback() and - not self.interface.isNamespace() and - not self.interface.getExtendedAttribute("Abstract") and - not self.interface.getExtendedAttribute("Inline") and - not spiderMonkeyInterface) - self.hasUnforgeableMembers = (self.concrete and - any(MemberIsUnforgeable(m, self) for m in - self.interface.members)) + self.concrete = (not self.interface.isCallback() + and not self.interface.isNamespace() + and not self.interface.getExtendedAttribute("Abstract") + and not self.interface.getExtendedAttribute("Inline") + and not spiderMonkeyInterface) + self.hasUnforgeableMembers = (self.concrete + and any(MemberIsUnforgeable(m, self) for m in + self.interface.members)) self.operations = { 'IndexedGetter': None, @@ -249,6 +258,8 @@ class Descriptor(DescriptorProvider): 'Stringifier': None, } + self.hasDefaultToJSON = False + def addOperation(operation, m): if not self.operations[operation]: self.operations[operation] = m @@ -258,6 +269,8 @@ class Descriptor(DescriptorProvider): for m in self.interface.members: if m.isMethod() and m.isStringifier(): addOperation('Stringifier', m) + if m.isMethod() and m.isDefaultToJSON(): + self.hasDefaultToJSON = True if self.concrete: iface = self.interface @@ -279,8 +292,6 @@ class Descriptor(DescriptorProvider): addIndexedOrNamedOperation('Getter', m) if m.isSetter(): addIndexedOrNamedOperation('Setter', m) - if m.isCreator(): - addIndexedOrNamedOperation('Creator', m) if m.isDeleter(): addIndexedOrNamedOperation('Deleter', m) @@ -316,7 +327,7 @@ class Descriptor(DescriptorProvider): if config == '*': iface = self.interface while iface: - add('all', map(lambda m: m.name, iface.members), attribute) + add('all', [m.name for m in iface.members], attribute) iface = iface.parent else: add('all', [config], attribute) @@ -390,15 +401,26 @@ class Descriptor(DescriptorProvider): parent = parent.parent return None + def supportsIndexedProperties(self): + return self.operations['IndexedGetter'] is not None + def hasDescendants(self): - return (self.interface.getUserData("hasConcreteDescendant", False) or - self.interface.getUserData("hasProxyDescendant", False)) + return (self.interface.getUserData("hasConcreteDescendant", False) + or self.interface.getUserData("hasProxyDescendant", False)) + + def hasHTMLConstructor(self): + ctor = self.interface.ctor() + return ctor and ctor.isHTMLConstructor() def shouldHaveGetConstructorObjectMethod(self): assert self.interface.hasInterfaceObject() if self.interface.getExtendedAttribute("Inline"): return False - return self.interface.isCallback() or self.interface.isNamespace() or self.hasDescendants() + return (self.interface.isCallback() or self.interface.isNamespace() + or self.hasDescendants() or self.hasHTMLConstructor()) + + def shouldCacheConstructor(self): + return self.hasDescendants() or self.hasHTMLConstructor() def isExposedConditionally(self): return self.interface.isExposedConditionally() @@ -408,8 +430,8 @@ class Descriptor(DescriptorProvider): Returns true if this is the primary interface for a global object of some sort. """ - return bool(self.interface.getExtendedAttribute("Global") or - self.interface.getExtendedAttribute("PrimaryGlobal")) + return bool(self.interface.getExtendedAttribute("Global") + or self.interface.getExtendedAttribute("PrimaryGlobal")) # Some utility methods @@ -420,8 +442,8 @@ def MakeNativeName(name): def getModuleFromObject(object): - return ('dom::bindings::codegen::Bindings::' + - os.path.basename(object.location.filename()).split('.webidl')[0] + 'Binding') + return ('crate::dom::bindings::codegen::Bindings::' + + os.path.basename(object.location.filename()).split('.webidl')[0] + 'Binding') def getTypesFromDescriptor(descriptor): @@ -453,7 +475,7 @@ def getTypesFromDictionary(dictionary): types = [] curDict = dictionary while curDict: - types.extend([m.type for m in curDict.members]) + types.extend([getUnwrappedType(m.type) for m in curDict.members]) curDict = curDict.parent return types @@ -469,6 +491,12 @@ def getTypesFromCallback(callback): return types +def getUnwrappedType(type): + while isinstance(type, IDLSequenceType): + type = type.inner + return type + + def iteratorNativeType(descriptor, infer=False): assert descriptor.interface.isIterable() iterableDecl = descriptor.interface.maplikeOrSetlikeOrIterable |