--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -80,17 +80,17 @@ class CycleCollectionUnsupported(TypeErr
def idlTypeNeedsCycleCollection(type):
type = type.unroll() # Takes care of sequences and nullables
if ((type.isPrimitive() and type.tag() in builtinNames) or
type.isEnum() or
type.isString() or
type.isAny() or
type.isObject() or
- type.isSpiderMonkeyInterface()):
+ type.isSpiderMonkeyInterface()):
return False
elif type.isCallback() or type.isPromise() or type.isGeckoInterface():
return True
elif type.isUnion():
return any(idlTypeNeedsCycleCollection(t) for t in type.flatMemberTypes)
elif type.isRecord():
if idlTypeNeedsCycleCollection(type.inner):
raise CycleCollectionUnsupported("Cycle collection for type %s is not supported" %
@@ -188,17 +188,18 @@ def compile_fill_template(template):
defined inside compile_fill_template().
"""
indentation, name, nl = match.groups()
depth = len(indentation)
# Check that $*{xyz} appears by itself on a line.
prev = match.string[:match.start()]
if (prev and not prev.endswith("\n")) or nl is None:
- raise ValueError("Invalid fill() template: $*{%s} must appear by itself on a line" % name)
+ raise ValueError(
+ "Invalid fill() template: $*{%s} must appear by itself on a line" % name)
# Now replace this whole line of template with the indented equivalent.
modified_name = name + "_" + str(depth)
argModList.append((name, modified_name, depth))
return "${" + modified_name + "}"
t = re.sub(fill_multiline_substitution_re, replace, t)
if not re.search(find_substitutions, t):
@@ -244,16 +245,17 @@ def fill(template, **args):
return t.substitute(args)
class CGThing():
"""
Abstract base class for things that spit out code.
"""
+
def __init__(self):
pass # Nothing for now
def declare(self):
"""Produce code for a header file."""
assert False # Override me!
def define(self):
@@ -279,16 +281,17 @@ class CGStringTable(CGThing):
const char *table[] = {
...
};
The uint16_t indices are smaller than the pointer equivalents, and the
string table requires no runtime relocations.
"""
+
def __init__(self, accessorName, strings, static=False):
CGThing.__init__(self)
self.accessorName = accessorName
self.strings = strings
self.static = static
def declare(self):
if self.static:
@@ -318,16 +321,17 @@ class CGStringTable(CGThing):
indices=", ".join("%d" % index for index in indices),
currentIndex=currentIndex)
class CGNativePropertyHooks(CGThing):
"""
Generate a NativePropertyHooks for a given descriptor
"""
+
def __init__(self, descriptor, properties):
CGThing.__init__(self)
self.descriptor = descriptor
self.properties = properties
def declare(self):
if not self.descriptor.wantsXrays:
return ""
@@ -413,17 +417,18 @@ def NativePropertyHooks(descriptor):
def DOMClass(descriptor):
protoList = ['prototypes::id::' + proto for proto in descriptor.prototypeNameChain]
# Pad out the list to the right length with _ID_Count so we
# guarantee that all the lists are the same length. _ID_Count
# is never the ID of any prototype, so it's safe to use as
# padding.
- protoList.extend(['prototypes::id::_ID_Count'] * (descriptor.config.maxProtoChainLength - len(protoList)))
+ protoList.extend(['prototypes::id::_ID_Count'] *
+ (descriptor.config.maxProtoChainLength - len(protoList)))
return fill(
"""
{ ${protoChain} },
IsBaseOf<nsISupports, ${nativeType} >::value,
${hooks},
FindAssociatedGlobalForNative<${nativeType}>::Get,
GetProtoObjectHandle,
@@ -437,16 +442,17 @@ def DOMClass(descriptor):
def InstanceReservedSlots(descriptor):
return INSTANCE_RESERVED_SLOTS + descriptor.interface.totalMembersInSlots
class CGDOMJSClass(CGThing):
"""
Generate a DOMJSClass for a given descriptor
"""
+
def __init__(self, descriptor):
CGThing.__init__(self)
self.descriptor = descriptor
def declare(self):
return ""
def define(self):
@@ -532,16 +538,17 @@ class CGDOMJSClass(CGThing):
reservedSlots=reservedSlots,
slotCount=slotCount)
class CGDOMProxyJSClass(CGThing):
"""
Generate a DOMJSClass for a given proxy descriptor
"""
+
def __init__(self, descriptor):
CGThing.__init__(self)
self.descriptor = descriptor
def declare(self):
return ""
def define(self):
@@ -568,22 +575,23 @@ class CGDOMProxyJSClass(CGThing):
class CGXrayExpandoJSClass(CGThing):
"""
Generate a JSClass for an Xray expando object. This is only
needed if we have members in slots (for [Cached] or [StoreInSlot]
stuff).
"""
+
def __init__(self, descriptor):
assert descriptor.interface.totalMembersInSlots != 0
assert descriptor.wantsXrays
assert descriptor.wantsXrayExpandoClass
CGThing.__init__(self)
- self.descriptor = descriptor;
+ self.descriptor = descriptor
def declare(self):
return ""
def define(self):
return fill(
"""
// This may allocate too many slots, because we only really need
@@ -649,17 +657,17 @@ class CGPrototypeJSClass(CGThing):
return ""
def define(self):
prototypeID, depth = PrototypeIDAndDepth(self.descriptor)
slotCount = "DOM_INTERFACE_PROTO_SLOTS_BASE"
# Globals handle unforgeables directly in Wrap() instead of
# via a holder.
if (self.descriptor.hasUnforgeableMembers and
- not self.descriptor.isGlobal()):
+ not self.descriptor.isGlobal()):
slotCount += " + 1 /* slot for the JSObject holding the unforgeable properties */"
(protoGetter, _) = InterfacePrototypeObjectProtoGetter(self.descriptor)
type = "eGlobalInterfacePrototype" if self.descriptor.isGlobal() else "eInterfacePrototype"
return fill(
"""
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"${name}Prototype",
@@ -703,17 +711,17 @@ def InterfaceObjectProtoGetter(descripto
assert not descriptor.interface.isNamespace()
parentIfaceName = parentInterface.identifier.name
parentDesc = descriptor.getDescriptor(parentIfaceName)
prefix = toBindingNamespace(parentDesc.name)
protoGetter = prefix + "::GetConstructorObject"
protoHandleGetter = prefix + "::GetConstructorObjectHandle"
elif descriptor.interface.isNamespace():
if (forXrays or
- not descriptor.interface.getExtendedAttribute("ProtoObjectHack")):
+ not descriptor.interface.getExtendedAttribute("ProtoObjectHack")):
protoGetter = "JS::GetRealmObjectPrototype"
else:
protoGetter = "GetHackedNamespaceProtoObject"
protoHandleGetter = None
else:
protoGetter = "JS::GetRealmFunctionPrototype"
protoHandleGetter = None
return (protoGetter, protoHandleGetter)
@@ -817,21 +825,23 @@ class CGInterfaceObjectJSClass(CGThing):
objectOps=objectOps,
needsHasInstance=toStringBool(needsHasInstance),
prototypeID=prototypeID,
depth=depth,
toStringResult=toStringResult,
protoGetter=protoGetter)
return ret
+
class CGList(CGThing):
"""
Generate code for a list of GCThings. Just concatenates them together, with
an optional joiner string. "\n" is a common joiner.
"""
+
def __init__(self, children, joiner=""):
CGThing.__init__(self)
# Make a copy of the kids into a list, because if someone passes in a
# generator we won't be able to both declare and define ourselves, or
# define ourselves more than once!
self.children = list(children)
self.joiner = joiner
@@ -865,16 +875,17 @@ class CGList(CGThing):
return len(self.children)
class CGGeneric(CGThing):
"""
A class that spits out a fixed string into the codegen. Can spit out a
separate string for the declaration too.
"""
+
def __init__(self, define="", declare=""):
self.declareText = declare
self.defineText = define
def declare(self):
return self.declareText
def define(self):
@@ -884,16 +895,17 @@ class CGGeneric(CGThing):
return set()
class CGIndenter(CGThing):
"""
A class that takes another CGThing and generates code that indents that
CGThing by some number of spaces. The default indent is two spaces.
"""
+
def __init__(self, child, indentLevel=2, declareOnly=False):
assert isinstance(child, CGThing)
CGThing.__init__(self)
self.child = child
self.indentLevel = indentLevel
self.declareOnly = declareOnly
def declare(self):
@@ -906,16 +918,17 @@ class CGIndenter(CGThing):
else:
return indent(defn, self.indentLevel)
class CGWrapper(CGThing):
"""
Generic CGThing that wraps other CGThings with pre and post text.
"""
+
def __init__(self, child, pre="", post="", declarePre=None,
declarePost=None, definePre=None, definePost=None,
declareOnly=False, defineOnly=False, reindent=False):
CGThing.__init__(self)
self.child = child
self.declarePre = declarePre or pre
self.declarePost = declarePost or post
self.definePre = definePre or pre
@@ -973,16 +986,17 @@ class CGIfElseWrapper(CGList):
CGGeneric("}\n")
])
class CGElseChain(CGThing):
"""
Concatenate if statements in an if-else-if-else chain.
"""
+
def __init__(self, children):
self.children = [c for c in children if c is not None]
def declare(self):
assert False
def define(self):
if not self.children:
@@ -1025,28 +1039,30 @@ class CGNamespace(CGWrapper):
inner = CGNamespace.build(namespaces[1:], child, declareOnly=declareOnly)
return CGNamespace(namespaces[0], inner, declareOnly=declareOnly)
class CGIncludeGuard(CGWrapper):
"""
Generates include guards for a header.
"""
+
def __init__(self, prefix, child):
"""|prefix| is the filename without the extension."""
define = 'mozilla_dom_%s_h' % prefix
CGWrapper.__init__(self, child,
declarePre='#ifndef %s\n#define %s\n\n' % (define, define),
declarePost='\n#endif // %s\n' % define)
class CGHeaders(CGWrapper):
"""
Generates the appropriate include statements.
"""
+
def __init__(self, descriptors, dictionaries, callbacks,
callbackDescriptors,
declareIncludes, defineIncludes, prefix, child,
config=None, jsImplementedDescriptors=[]):
"""
Builds a set of includes to cover |descriptors|.
Also includes the files in |declareIncludes| in the header
@@ -1411,17 +1427,18 @@ def UnionTypes(unionTypes, config):
addHeadersForType(f.inner)
implheaders.add(CGHeaders.getUnionDeclarationFilename(config, t))
for f in t.flatMemberTypes:
assert not f.nullable()
addHeadersForType(f)
if idlTypeNeedsCycleCollection(t):
- declarations.add(("mozilla::dom::%s" % CGUnionStruct.unionTypeName(t, True), False))
+ declarations.add(("mozilla::dom::%s" %
+ CGUnionStruct.unionTypeName(t, True), False))
traverseMethods[name] = CGCycleCollectionTraverseForOwningUnionMethod(t)
unlinkMethods[name] = CGCycleCollectionUnlinkForOwningUnionMethod(t)
# The order of items in CGList is important.
# Since the union structs friend the unlinkMethods, the forward-declaration
# for these methods should come before the class declaration. Otherwise
# some compilers treat the friend declaration as a forward-declaration in
# the class scope.
@@ -1492,16 +1509,17 @@ def UnionConversions(unionTypes, config)
CGWrapper(CGList(SortedDictValues(unionConversions), "\n"),
post="\n\n"))
class Argument():
"""
A class for outputting the type and name of an argument
"""
+
def __init__(self, argType, name, default=None):
self.argType = argType
self.name = name
self.default = default
def declare(self):
string = self.argType + ' ' + self.name
if self.default is not None:
@@ -1535,16 +1553,17 @@ class CGAbstractMethod(CGThing):
a definition.
If templateArgs is not None it should be a list of strings containing
template arguments, and the function will be templatized using those
arguments.
canRunScript should be True to generate a MOZ_CAN_RUN_SCRIPT annotation.
"""
+
def __init__(self, descriptor, name, returnType, args, inline=False,
alwaysInline=False, static=False, templateArgs=None,
canRunScript=False):
CGThing.__init__(self)
self.descriptor = descriptor
self.name = name
self.returnType = returnType
self.args = args
@@ -1560,17 +1579,17 @@ class CGAbstractMethod(CGThing):
def _template(self):
if self.templateArgs is None:
return ''
return 'template <%s>\n' % ', '.join(self.templateArgs)
def _decorators(self):
decorators = []
if self.canRunScript:
- decorators.append('MOZ_CAN_RUN_SCRIPT');
+ decorators.append('MOZ_CAN_RUN_SCRIPT')
if self.alwaysInline:
decorators.append('MOZ_ALWAYS_INLINE')
elif self.inline:
decorators.append('inline')
if self.static:
decorators.append('static')
decorators.append(self.returnType)
maybeNewline = " " if self.inline else "\n"
@@ -1617,39 +1636,43 @@ class CGAbstractMethod(CGThing):
def definition_body(self):
assert False # Override me!
"""
Override this method to return a pair of (descriptive string, name of a
JSContext* variable) in order to generate a profiler label for this method.
"""
+
def profiler_label_and_jscontext(self):
- return None # Override me!
+ return None # Override me!
+
class CGAbstractStaticMethod(CGAbstractMethod):
"""
Abstract base class for codegen of implementation-only (no
declaration) static methods.
"""
+
def __init__(self, descriptor, name, returnType, args, canRunScript=False):
CGAbstractMethod.__init__(self, descriptor, name, returnType, args,
inline=False, static=True,
canRunScript=canRunScript)
def declare(self):
# We only have implementation
return ""
class CGAbstractClassHook(CGAbstractStaticMethod):
"""
Meant for implementing JSClass hooks, like Finalize or Trace. Does very raw
'this' unwrapping as it assumes that the unwrapped type is always known.
"""
+
def __init__(self, descriptor, name, returnType, args):
CGAbstractStaticMethod.__init__(self, descriptor, name, returnType,
args)
def definition_body_prologue(self):
return ("%s* self = UnwrapPossiblyNotInitializedDOMObject<%s>(obj);\n" %
(self.descriptor.nativeType, self.descriptor.nativeType))
@@ -1668,16 +1691,17 @@ class CGGetJSClassMethod(CGAbstractMetho
def definition_body(self):
return "return sClass.ToJSClass();\n"
class CGAddPropertyHook(CGAbstractClassHook):
"""
A hook for addProperty, used to preserve our wrapper from GC.
"""
+
def __init__(self, descriptor):
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'obj'),
Argument('JS::Handle<jsid>', 'id'),
Argument('JS::Handle<JS::Value>', 'val')]
CGAbstractClassHook.__init__(self, descriptor, ADDPROPERTY_HOOK_NAME,
'bool', args)
@@ -1725,16 +1749,17 @@ def finalizeHook(descriptor, hookName, f
descriptor.nativeType)
return CGIfWrapper(CGGeneric(finalize), "self")
class CGClassFinalizeHook(CGAbstractClassHook):
"""
A hook for finalize, used to release our native object.
"""
+
def __init__(self, descriptor):
args = [Argument('js::FreeOp*', 'fop'), Argument('JSObject*', 'obj')]
CGAbstractClassHook.__init__(self, descriptor, FINALIZE_HOOK_NAME,
'void', args)
def generate_code(self):
return finalizeHook(self.descriptor, self.name,
self.args[0].name, self.args[1].name).define()
@@ -1753,16 +1778,17 @@ def objectMovedHook(descriptor, hookName
old=old)
class CGClassObjectMovedHook(CGAbstractClassHook):
"""
A hook for objectMovedOp, used to update the wrapper cache when an object it
is holding moves.
"""
+
def __init__(self, descriptor):
args = [Argument('JSObject*', 'obj'), Argument('JSObject*', 'old')]
CGAbstractClassHook.__init__(self, descriptor, OBJECT_MOVED_HOOK_NAME,
'size_t', args)
def generate_code(self):
return objectMovedHook(self.descriptor, self.name,
self.args[0].name, self.args[1].name)
@@ -1773,16 +1799,17 @@ def JSNativeArguments():
Argument('unsigned', 'argc'),
Argument('JS::Value*', 'vp')]
class CGClassConstructor(CGAbstractStaticMethod):
"""
JS-visible constructor for our objects
"""
+
def __init__(self, descriptor, ctor, name=CONSTRUCT_HOOK_NAME):
CGAbstractStaticMethod.__init__(self, descriptor, name, 'bool',
JSNativeArguments())
self._ctor = ctor
def define(self):
if not self._ctor:
return ""
@@ -1865,20 +1892,23 @@ class CGClassConstructor(CGAbstractStati
name = self._ctor.identifier.name
if name != "constructor":
ctorName = name
else:
ctorName = self.descriptor.interface.identifier.name
return ("%s constructor" % ctorName, "cx")
# Encapsulate the constructor in a helper method to share genConstructorBody with CGJSImplMethod.
+
+
class CGConstructNavigatorObject(CGAbstractMethod):
"""
Construct a new JS-implemented WebIDL DOM object, for use on navigator.
"""
+
def __init__(self, descriptor):
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'obj'),
Argument('ErrorResult&', 'aRv')]
rtype = 'already_AddRefed<%s>' % descriptor.name
CGAbstractMethod.__init__(self, descriptor, "ConstructNavigatorObject",
rtype, args)
@@ -1958,16 +1988,17 @@ class MemberCondition:
None, they should have the following types:
pref: The name of the preference.
func: The name of the function.
secureContext: A bool indicating whether a secure context is required.
nonExposedGlobals: A set of names of globals. Can be empty, in which case
it's treated the same way as None.
"""
+
def __init__(self, pref=None, func=None, secureContext=False,
nonExposedGlobals=None):
assert pref is None or isinstance(pref, str)
assert func is None or isinstance(func, str)
assert isinstance(secureContext, bool)
assert nonExposedGlobals is None or isinstance(nonExposedGlobals, set)
self.pref = pref
self.secureContext = secureContext
@@ -2005,16 +2036,17 @@ class PropertyDefiner:
"""
A common superclass for defining things on prototype objects.
Subclasses should implement generateArray to generate the actual arrays of
things we're defining. They should also set self.chrome to the list of
things only exposed to chrome and self.regular to the list of things exposed
to both chrome and web pages.
"""
+
def __init__(self, descriptor, name):
self.descriptor = descriptor
self.name = name
# self.prefCacheData will store an array of (prefname, bool*)
# pairs for our bool var caches. generateArray will fill it
# in as needed.
self.prefCacheData = []
@@ -2243,16 +2275,17 @@ def EnumerabilityFlags(member):
return "0"
return "JSPROP_ENUMERATE"
class MethodDefiner(PropertyDefiner):
"""
A class for defining methods on a prototype object.
"""
+
def __init__(self, descriptor, name, static, unforgeable=False):
assert not (static and unforgeable)
PropertyDefiner.__init__(self, descriptor, name)
# FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=772822
# We should be able to check for special operations without an
# identifier. For now we check if the name starts with __
@@ -2272,21 +2305,22 @@ class MethodDefiner(PropertyDefiner):
# impl we just call out directly to our shared one.
if m.isStatic():
raise TypeError("Legacy QueryInterface member shouldn't be static")
signatures = m.signatures()
def argTypeIsIID(arg):
return arg.type.inner.isExternal() and arg.type.inner.identifier.name == 'IID'
if len(signatures) > 1 or len(signatures[0][1]) > 1 or not argTypeIsIID(signatures[0][1][0]):
- raise TypeError("There should be only one QueryInterface method with 1 argument of type IID")
+ raise TypeError(
+ "There should be only one QueryInterface method with 1 argument of type IID")
# Make sure to not stick QueryInterface on abstract interfaces.
if (not self.descriptor.interface.hasInterfacePrototypeObject() or
- not self.descriptor.concrete):
+ not self.descriptor.concrete):
raise TypeError("QueryInterface is only supported on "
"interfaces that are concrete: " +
self.descriptor.name)
if not isChromeOnly(m):
raise TypeError("QueryInterface must be ChromeOnly")
self.chrome.append({
@@ -2305,17 +2339,18 @@ class MethodDefiner(PropertyDefiner):
"flags": EnumerabilityFlags(m),
"condition": PropertyDefiner.getControllingCondition(m, descriptor),
"allowCrossOriginThis": m.getExtendedAttribute("CrossOriginCallable"),
"returnsPromise": m.returnsPromise(),
"hasIteratorAlias": "@@iterator" in m.aliases
}
if m.isStatic():
- method["nativeName"] = CppKeywords.checkMethodName(IDLToCIdentifier(m.identifier.name))
+ method["nativeName"] = CppKeywords.checkMethodName(
+ IDLToCIdentifier(m.identifier.name))
if isChromeOnly(m):
self.chrome.append(method)
else:
self.regular.append(method)
# TODO: Once iterable is implemented, use tiebreak rules instead of
# failing. Also, may be more tiebreak rules to implement once spec bug
@@ -2326,39 +2361,39 @@ class MethodDefiner(PropertyDefiner):
any("@@iterator" == r["name"] for r in regular))
# Check whether we need to output an @@iterator due to having an indexed
# getter. We only do this while outputting non-static and
# non-unforgeable methods, since the @@iterator function will be
# neither.
if (not static and
not unforgeable and
- descriptor.supportsIndexedProperties()):
+ descriptor.supportsIndexedProperties()):
if hasIterator(methods, self.regular):
raise TypeError("Cannot have indexed getter/attr on "
"interface %s with other members "
"that generate @@iterator, such as "
"maplike/setlike or aliased functions." %
self.descriptor.interface.identifier.name)
self.regular.append({
"name": "@@iterator",
"methodInfo": False,
"selfHostedName": "ArrayValues",
"length": 0,
- "flags": "0", # Not enumerable, per spec.
+ "flags": "0", # Not enumerable, per spec.
"condition": MemberCondition()
})
# Generate the keys/values/entries aliases for value iterables.
maplikeOrSetlikeOrIterable = descriptor.interface.maplikeOrSetlikeOrIterable
if (not static and
not unforgeable and
maplikeOrSetlikeOrIterable and
maplikeOrSetlikeOrIterable.isIterable() and
- maplikeOrSetlikeOrIterable.isValueIterator()):
+ maplikeOrSetlikeOrIterable.isValueIterator()):
# Add our keys/values/entries/forEach
self.regular.append({
"name": "keys",
"methodInfo": False,
"selfHostedName": "ArrayKeys",
"length": 0,
"flags": "JSPROP_ENUMERATE",
"condition": PropertyDefiner.getControllingCondition(m,
@@ -2390,30 +2425,30 @@ class MethodDefiner(PropertyDefiner):
"flags": "JSPROP_ENUMERATE",
"condition": PropertyDefiner.getControllingCondition(m,
descriptor)
})
if not static:
stringifier = descriptor.operations['Stringifier']
if (stringifier and
- unforgeable == MemberIsUnforgeable(stringifier, descriptor)):
+ unforgeable == MemberIsUnforgeable(stringifier, descriptor)):
toStringDesc = {
"name": "toString",
"nativeName": stringifier.identifier.name,
"length": 0,
"flags": "JSPROP_ENUMERATE",
"condition": PropertyDefiner.getControllingCondition(stringifier, descriptor)
}
if isChromeOnly(stringifier):
self.chrome.append(toStringDesc)
else:
self.regular.append(toStringDesc)
if (unforgeable and
- descriptor.interface.getExtendedAttribute("Unforgeable")):
+ descriptor.interface.getExtendedAttribute("Unforgeable")):
# Synthesize our valueOf method
self.regular.append({
"name": 'valueOf',
"selfHostedName": "Object_valueOf",
"methodInfo": False,
"length": 0,
"flags": "0", # readonly/permanent added automatically.
"condition": MemberCondition()
@@ -2516,20 +2551,22 @@ def IsCrossOriginWritable(attr, descript
if not crossOriginWritable:
return False
if crossOriginWritable is True:
return True
assert (isinstance(crossOriginWritable, list) and
len(crossOriginWritable) == 1)
return crossOriginWritable[0] == descriptor.interface.identifier.name
+
def isNonExposedNavigatorObjectGetter(attr, descriptor):
return (attr.navigatorObjectGetter and
not descriptor.getDescriptor(attr.type.inner.identifier.name).register)
+
class AttrDefiner(PropertyDefiner):
def __init__(self, descriptor, name, static, unforgeable=False):
assert not (static and unforgeable)
PropertyDefiner.__init__(self, descriptor, name)
self.name = name
# Ignore non-static attributes for interfaces without a proto object
if descriptor.interface.hasInterfacePrototypeObject() or static:
attributes = [m for m in descriptor.interface.members if
@@ -2607,17 +2644,17 @@ class AttrDefiner(PropertyDefiner):
IDLToCIdentifier(attr.identifier.name))
return "%s, %s" % \
(accessor, jitinfo)
def setter(attr):
if (attr.readonly and
attr.getExtendedAttribute("PutForwards") is None and
attr.getExtendedAttribute("Replaceable") is None and
- attr.getExtendedAttribute("LenientSetter") is None):
+ attr.getExtendedAttribute("LenientSetter") is None):
return "nullptr, nullptr"
if self.static:
accessor = 'set_' + IDLToCIdentifier(attr.identifier.name)
jitinfo = "nullptr"
else:
if attr.hasLenientThis():
if IsCrossOriginWritable(attr, self.descriptor):
raise TypeError("Can't handle lenient cross-origin "
@@ -2646,16 +2683,17 @@ class AttrDefiner(PropertyDefiner):
'JSPropertySpec',
condition, specData)
class ConstDefiner(PropertyDefiner):
"""
A class for definining constants on the interface object
"""
+
def __init__(self, descriptor, name):
PropertyDefiner.__init__(self, descriptor, name)
self.name = name
constants = [m for m in descriptor.interface.members if m.isConst()]
self.chrome = [m for m in constants if isChromeOnly(m)]
self.regular = [m for m in constants if not isChromeOnly(m)]
def generateArray(self, array, name):
@@ -2707,16 +2745,17 @@ class PropertyArrays():
class CGConstDefinition(CGThing):
"""
Given a const member of an interface, return the C++ static const definition
for the member. Should be part of the interface namespace in the header
file.
"""
+
def __init__(self, member):
assert (member.isConst() and
member.value.type.isPrimitive() and
not member.value.type.nullable())
name = CppKeywords.checkMethodName(IDLToCIdentifier(member.identifier.name))
tag = member.value.type.tag()
value = member.value.value
@@ -2848,16 +2887,17 @@ class CGNativeProperties(CGList):
def define(self):
return CGList.define(self)
class CGCollectJSONAttributesMethod(CGAbstractMethod):
"""
Generate the CollectJSONAttributes method for an interface descriptor
"""
+
def __init__(self, descriptor, toJSONMethod):
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'obj'),
Argument('%s*' % descriptor.nativeType, 'self'),
Argument('JS::Rooted<JSObject*>&', 'result')]
CGAbstractMethod.__init__(self, descriptor, 'CollectJSONAttributes',
'bool', args, canRunScript=True)
self.toJSONMethod = toJSONMethod
@@ -2882,17 +2922,17 @@ class CGCollectJSONAttributesMethod(CGAb
""",
name=IDLToCIdentifier(m.identifier.name))
# Make sure we don't include things which are supposed to be
# disabled. Things that either don't have disablers or whose
# disablers match the disablers for our toJSON method can't
# possibly be disabled, but other things might be.
condition = PropertyDefiner.getControllingCondition(m, self.descriptor)
if condition.hasDisablers() and condition != toJSONCondition:
- needUnwrappedObj = True;
+ needUnwrappedObj = True
ret += fill(
"""
// This is unfortunately a linear scan through sAttributes, but we
// only do it for things which _might_ be disabled, which should
// help keep the performance problems down.
if (IsGetterEnabled(cx, unwrappedObj, (JSJitGetterOp)get_${name}, sAttributes)) {
$*{getAndDefine}
}
@@ -2905,38 +2945,39 @@ class CGCollectJSONAttributesMethod(CGAb
{ // scope for "temp"
$*{getAndDefine}
}
""",
getAndDefine=getAndDefine)
ret += 'return true;\n'
if needUnwrappedObj:
- ret= fill(
+ ret = fill(
"""
JS::Rooted<JSObject*> unwrappedObj(cx, js::CheckedUnwrap(obj));
if (!unwrappedObj) {
// How did that happen? We managed to get called with that
// object as "this"! Just give up on sanity.
return false;
}
$*{ret}
""",
- ret=ret);
+ ret=ret)
return ret
class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
"""
Generate the CreateInterfaceObjects method for an interface descriptor.
properties should be a PropertyArrays instance.
"""
+
def __init__(self, descriptor, properties, haveUnscopables):
args = [Argument('JSContext*', 'aCx'),
Argument('JS::Handle<JSObject*>', 'aGlobal'),
Argument('ProtoAndIfaceCache&', 'aProtoAndIfaceCache'),
Argument('bool', 'aDefineOnGlobal')]
CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'void', args)
self.properties = properties
self.haveUnscopables = haveUnscopables
@@ -3109,28 +3150,29 @@ class CGCreateInterfaceObjectsMethod(CGA
"""
*protoCache = nullptr;
if (interfaceCache) {
*interfaceCache = nullptr;
}
return;
""")
- aliasedMembers = [m for m in self.descriptor.interface.members if m.isMethod() and m.aliases]
+ aliasedMembers = [m for m in self.descriptor.interface.members if m.isMethod()
+ and m.aliases]
if aliasedMembers:
assert needInterfacePrototypeObject
def defineAlias(alias):
if alias == "@@iterator":
symbolJSID = "SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::iterator))"
getSymbolJSID = CGGeneric(fill("JS::Rooted<jsid> iteratorId(aCx, ${symbolJSID});",
symbolJSID=symbolJSID))
defineFn = "JS_DefinePropertyById"
prop = "iteratorId"
- enumFlags = "0" # Not enumerable, per spec.
+ enumFlags = "0" # Not enumerable, per spec.
elif alias.startswith("@@"):
raise TypeError("Can't handle any well-known Symbol other than @@iterator")
else:
getSymbolJSID = None
defineFn = "JS_DefineProperty"
prop = '"%s"' % alias
# XXX If we ever create non-enumerable properties that can
# be aliased, we should consider making the aliases
@@ -3166,17 +3208,17 @@ class CGCreateInterfaceObjectsMethod(CGA
CGGeneric(fill("""
// Set up aliases on the interface prototype object we just created.
JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx);
if (!proto) {
$*{failureCode}
}
""",
- failureCode=failureCode)),
+ failureCode=failureCode)),
CGGeneric("JS::Rooted<JS::Value> aliasedVal(aCx);\n\n")
] + [defineAliasesFor(m) for m in sorted(aliasedMembers)])
else:
defineAliases = None
# Globals handle unforgeables directly in Wrap() instead of
# via a holder.
if self.descriptor.hasUnforgeableMembers and not self.descriptor.isGlobal():
@@ -3223,17 +3265,17 @@ class CGCreateInterfaceObjectsMethod(CGA
"""))
unforgeableHolderSetup = CGList(
[createUnforgeableHolder, installUnforgeableHolder], "\n")
else:
unforgeableHolderSetup = None
if (self.descriptor.interface.isOnGlobalProtoChain() and
- needInterfacePrototypeObject):
+ needInterfacePrototypeObject):
makeProtoPrototypeImmutable = CGGeneric(fill(
"""
if (*${protoCache}) {
bool succeeded;
JS::Handle<JSObject*> prot = GetProtoObjectHandle(aCx);
if (!JS_SetImmutablePrototype(aCx, prot, &succeeded)) {
$*{failureCode}
}
@@ -3255,16 +3297,17 @@ class CGCreateInterfaceObjectsMethod(CGA
makeProtoPrototypeImmutable],
"\n").define()
class CGGetProtoObjectHandleMethod(CGAbstractMethod):
"""
A method for getting the interface prototype object.
"""
+
def __init__(self, descriptor):
CGAbstractMethod.__init__(
self, descriptor, "GetProtoObjectHandle",
'JS::Handle<JSObject*>',
[Argument('JSContext*', 'aCx')],
inline=True)
def definition_body(self):
@@ -3279,29 +3322,31 @@ class CGGetProtoObjectHandleMethod(CGAbs
""",
name=self.descriptor.name)
class CGGetProtoObjectMethod(CGAbstractMethod):
"""
A method for getting the interface prototype object.
"""
+
def __init__(self, descriptor):
CGAbstractMethod.__init__(
self, descriptor, "GetProtoObject", "JSObject*",
[Argument('JSContext*', 'aCx')])
def definition_body(self):
return "return GetProtoObjectHandle(aCx);\n"
class CGGetConstructorObjectHandleMethod(CGAbstractMethod):
"""
A method for getting the interface constructor object.
"""
+
def __init__(self, descriptor):
CGAbstractMethod.__init__(
self, descriptor, "GetConstructorObjectHandle",
'JS::Handle<JSObject*>',
[Argument('JSContext*', 'aCx'),
Argument('bool', 'aDefineOnGlobal', 'true')],
inline=True)
@@ -3317,16 +3362,17 @@ class CGGetConstructorObjectHandleMethod
""",
name=self.descriptor.name)
class CGGetConstructorObjectMethod(CGAbstractMethod):
"""
A method for getting the interface constructor object.
"""
+
def __init__(self, descriptor):
CGAbstractMethod.__init__(
self, descriptor, "GetConstructorObject", "JSObject*",
[Argument('JSContext*', 'aCx')])
def definition_body(self):
return "return GetConstructorObjectHandle(aCx);\n"
@@ -3418,28 +3464,30 @@ def getConditionList(idlobj, cxName, obj
conditions.append("sPrefValue")
if idlobj.getExtendedAttribute("ChromeOnly"):
conditions.append("nsContentUtils::ThreadsafeIsSystemCaller(%s)" % cxName)
func = idlobj.getExtendedAttribute("Func")
if func:
assert isinstance(func, list) and len(func) == 1
conditions.append("%s(%s, %s)" % (func[0], cxName, objName))
if idlobj.getExtendedAttribute("SecureContext"):
- conditions.append("mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(%s, %s)" % (cxName, objName))
+ conditions.append(
+ "mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(%s, %s)" % (cxName, objName))
return (CGList((CGGeneric(cond) for cond in conditions), " &&\n"),
conditionSetup)
class CGConstructorEnabled(CGAbstractMethod):
"""
A method for testing whether we should be exposing this interface
object or navigator property. This can perform various tests
depending on what conditions are specified on the interface.
"""
+
def __init__(self, descriptor):
CGAbstractMethod.__init__(self, descriptor,
'ConstructorEnabled', 'bool',
[Argument("JSContext*", "aCx"),
Argument("JS::Handle<JSObject*>", "aObj")])
def definition_body(self):
body = CGList([], "\n")
@@ -3472,17 +3520,17 @@ class CGConstructorEnabled(CGAbstractMet
(conditions, conditionsSetup) = getConditionList(iface, "aCx", "aObj")
# We should really have some conditions
assert len(body) or len(conditions)
conditionsWrapper = ""
if len(conditions):
- body.append(conditionsSetup);
+ body.append(conditionsSetup)
conditionsWrapper = CGWrapper(conditions,
pre="return ",
post=";\n",
reindent=True)
else:
conditionsWrapper = CGGeneric("return true;\n")
body.append(conditionsWrapper)
@@ -3585,17 +3633,17 @@ def InitUnforgeablePropertiesOnHolder(de
return CGWrapper(CGList(unforgeables), pre="\n")
def CopyUnforgeablePropertiesToInstance(descriptor, failureCode):
"""
Copy the unforgeable properties from the unforgeable holder for
this interface to the instance object we have.
"""
- assert not descriptor.isGlobal();
+ assert not descriptor.isGlobal()
if not descriptor.hasUnforgeableMembers:
return ""
copyCode = [
CGGeneric(dedent(
"""
// Important: do unforgeable property setup after we have handed
@@ -3716,16 +3764,17 @@ def DeclareProto():
class CGWrapWithCacheMethod(CGAbstractMethod):
"""
Create a wrapper JSObject for a given native that implements nsWrapperCache.
properties should be a PropertyArrays instance.
"""
+
def __init__(self, descriptor, properties):
assert descriptor.interface.hasInterfacePrototypeObject()
args = [Argument('JSContext*', 'aCx'),
Argument(descriptor.nativeType + '*', 'aObject'),
Argument('nsWrapperCache*', 'aCache'),
Argument('JS::Handle<JSObject*>', 'aGivenProto'),
Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
@@ -3824,16 +3873,17 @@ class CGWrapMethod(CGAbstractMethod):
class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
"""
Create a wrapper JSObject for a given native that does not implement
nsWrapperCache.
properties should be a PropertyArrays instance.
"""
+
def __init__(self, descriptor, properties):
# XXX can we wrap if we don't have an interface prototype object?
assert descriptor.interface.hasInterfacePrototypeObject()
args = [Argument('JSContext*', 'aCx'),
Argument(descriptor.nativeType + '*', 'aObject'),
Argument('JS::Handle<JSObject*>', 'aGivenProto'),
Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
@@ -3872,16 +3922,17 @@ class CGWrapNonWrapperCacheMethod(CGAbst
class CGWrapGlobalMethod(CGAbstractMethod):
"""
Create a wrapper JSObject for a global. The global must implement
nsWrapperCache.
properties should be a PropertyArrays instance.
"""
+
def __init__(self, descriptor, properties):
assert descriptor.interface.hasInterfacePrototypeObject()
args = [Argument('JSContext*', 'aCx'),
Argument(descriptor.nativeType + '*', 'aObject'),
Argument('nsWrapperCache*', 'aCache'),
Argument('JS::RealmOptions&', 'aOptions'),
Argument('JSPrincipals*', 'aPrincipal'),
Argument('bool', 'aInitStandardClasses'),
@@ -3900,22 +3951,22 @@ class CGWrapGlobalMethod(CGAbstractMetho
else:
chromeProperties = "nullptr"
failureCode = dedent(
"""
aCache->ReleaseWrapper(aObject);
aCache->ClearWrapper();
return false;
- """);
+ """)
if self.descriptor.hasUnforgeableMembers:
unforgeable = InitUnforgeablePropertiesOnHolder(
self.descriptor, self.properties, failureCode,
- "aReflector").define();
+ "aReflector").define()
else:
unforgeable = ""
return fill(
"""
$*{assertions}
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
@@ -3965,17 +4016,17 @@ class CGUpdateMemberSlotsMethod(CGAbstra
"JSJitGetterCallArgs args(&temp);\n")
for m in self.descriptor.interface.members:
if m.isAttr() and m.getExtendedAttribute("StoreInSlot"):
# Skip doing this for the "window" and "self" attributes on the
# Window interface, because those can't be gotten safely until
# we have hooked it up correctly to the outer window. The
# window code handles doing the get itself.
if (self.descriptor.interface.identifier.name == "Window" and
- (m.identifier.name == "window" or m.identifier.name == "self")):
+ (m.identifier.name == "window" or m.identifier.name == "self")):
continue
body += fill(
"""
static_assert(${slot} < js::shadow::Object::MAX_FIXED_SLOTS,
"Not enough fixed slots to fit '${interface}.${member}. Ion's visitGetDOMMemberV/visitGetDOMMemberT assume StoreInSlot things are all in fixed slots.");
if (!get_${member}(aCx, aWrapper, aObject, args)) {
return false;
@@ -4035,17 +4086,17 @@ class CGClearCachedValueMethod(CGAbstrac
if self.descriptor.wantsXrays:
clearXrayExpandoSlots = fill(
"""
xpc::ClearXrayExpandoSlots(obj, ${xraySlotIndex});
""",
xraySlotIndex=memberXrayExpandoReservedSlot(self.member,
self.descriptor))
- else :
+ else:
clearXrayExpandoSlots = ""
return fill(
"""
$*{declObj}
obj = aObject->GetWrapper();
if (!obj) {
return${noopRetval};
@@ -4062,16 +4113,17 @@ class CGClearCachedValueMethod(CGAbstrac
clearXrayExpandoSlots=clearXrayExpandoSlots,
regetMember=regetMember)
class CGIsPermittedMethod(CGAbstractMethod):
"""
crossOriginGetters/Setters/Methods are sets of names of the relevant members.
"""
+
def __init__(self, descriptor, crossOriginGetters, crossOriginSetters,
crossOriginMethods):
self.crossOriginGetters = crossOriginGetters
self.crossOriginSetters = crossOriginSetters
self.crossOriginMethods = crossOriginMethods
args = [Argument("JSFlatString*", "prop"),
Argument("char16_t", "propFirstChar"),
Argument("bool", "set")]
@@ -4104,16 +4156,17 @@ class CGIsPermittedMethod(CGAbstractMeth
switch = CGSwitch("propFirstChar", caseList)
return switch.define() + "\nreturn false;\n"
class CGCycleCollectionTraverseForOwningUnionMethod(CGAbstractMethod):
"""
ImplCycleCollectionUnlink for owning union type.
"""
+
def __init__(self, type):
self.type = type
args = [Argument("nsCycleCollectionTraversalCallback&", "aCallback"),
Argument("%s&" % CGUnionStruct.unionTypeName(type, True), "aUnion"),
Argument("const char*", "aName"),
Argument("uint32_t", "aFlags", "0")]
CGAbstractMethod.__init__(self, None, "ImplCycleCollectionTraverse", "void", args)
@@ -4135,16 +4188,17 @@ class CGCycleCollectionTraverseForOwning
return CGElseChain(ifStaments).define()
class CGCycleCollectionUnlinkForOwningUnionMethod(CGAbstractMethod):
"""
ImplCycleCollectionUnlink for owning union type.
"""
+
def __init__(self, type):
self.type = type
args = [Argument("%s&" % CGUnionStruct.unionTypeName(type, True), "aUnion")]
CGAbstractMethod.__init__(self, None, "ImplCycleCollectionUnlink", "void", args)
def deps(self):
return self.type.getDeps()
@@ -4181,17 +4235,17 @@ numericSuffixes = {
IDLType.Tags.float: 'F',
IDLType.Tags.unrestricted_double: '',
IDLType.Tags.double: ''
}
def numericValue(t, v):
if (t == IDLType.Tags.unrestricted_double or
- t == IDLType.Tags.unrestricted_float):
+ t == IDLType.Tags.unrestricted_float):
typeName = builtinNames[t]
if v == float("inf"):
return "mozilla::PositiveInfinity<%s>()" % typeName
if v == float("-inf"):
return "mozilla::NegativeInfinity<%s>()" % typeName
if math.isnan(v):
return "mozilla::UnspecifiedNaN<%s>()" % typeName
return "%s%s" % (v, numericSuffixes[t])
@@ -4207,29 +4261,30 @@ class CastableObjectUnwrapper():
"mutableSource" argument should be able to produce a MutableHandle<Value>
codeOnFailure is the code to run if unwrapping fails.
If isCallbackReturnValue is "JSImpl" and our descriptor is also
JS-implemented, fall back to just creating the right object if what we
have isn't one already.
"""
+
def __init__(self, descriptor, source, mutableSource, target, codeOnFailure,
exceptionCode=None, isCallbackReturnValue=False):
self.substitution = {
"type": descriptor.nativeType,
"protoID": "prototypes::id::" + descriptor.name,
"target": target,
"codeOnFailure": codeOnFailure,
"source": source,
"mutableSource": mutableSource,
}
if (isCallbackReturnValue == "JSImpl" and
- descriptor.interface.isJSImplemented()):
+ descriptor.interface.isJSImplemented()):
exceptionCode = exceptionCode or codeOnFailure
self.substitution["codeOnFailure"] = fill(
"""
// Be careful to not wrap random DOM objects here, even if
// they're wrapped in opaque security wrappers for some reason.
// XXXbz Wish we could check for a JS-implemented object
// that already has a content reflection...
if (!IsDOMObject(js::UncheckedUnwrap(&${source}.toObject()))) {
@@ -4266,16 +4321,17 @@ class CastableObjectUnwrapper():
""",
**substitution)
class FailureFatalCastableObjectUnwrapper(CastableObjectUnwrapper):
"""
As CastableObjectUnwrapper, but defaulting to throwing if unwrapping fails
"""
+
def __init__(self, descriptor, source, mutableSource, target, exceptionCode,
isCallbackReturnValue, sourceDescription):
CastableObjectUnwrapper.__init__(
self, descriptor, source, mutableSource, target,
'ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "%s", "%s");\n'
'%s' % (sourceDescription, descriptor.interface.identifier.name,
exceptionCode),
exceptionCode,
@@ -4326,16 +4382,17 @@ def getCallbackConversionInfo(type, idlO
argsPost=argsPost)
return (declType, declArgs, conversion)
class JSToNativeConversionInfo():
"""
An object representing information about a JS-to-native conversion.
"""
+
def __init__(self, template, declType=None, holderType=None,
dealWithOptional=False, declArgs=None,
holderArgs=None):
"""
template: A string representing the conversion code. This will have
template substitution performed on it as follows:
${val} is a handle to the JS::Value in question
@@ -4420,17 +4477,17 @@ def handleDefaultStringValue(defaultValu
defaultValue.type.isUSVString() or
defaultValue.type.isByteString())
return ("static const %(char_t)s data[] = { %(data)s };\n"
"%(method)s(data, ArrayLength(data) - 1)") % {
'char_t': "char" if defaultValue.type.isByteString() else "char16_t",
'method': method,
'data': ", ".join(["'" + char + "'" for char in
defaultValue.value] + ["0"])
- }
+ }
def recordKeyType(recordType):
assert recordType.keyType.isString()
if recordType.keyType.isByteString():
return "nsCString"
return "nsString"
@@ -5025,17 +5082,18 @@ def getJSToNativeConversionInfo(type, de
name = getUnionMemberName(memberType)
dateObject = CGGeneric("%s.SetTo%s(cx, ${val});\n"
"done = true;\n" % (unionArgumentObj, name))
dateObject = CGIfWrapper(dateObject, "JS_ObjectIsDate(cx, argObj)")
names.append(name)
else:
dateObject = None
- callbackMemberTypes = filter(lambda t: t.isCallback() or t.isCallbackInterface(), memberTypes)
+ callbackMemberTypes = filter(lambda t: t.isCallback()
+ or t.isCallbackInterface(), memberTypes)
if len(callbackMemberTypes) > 0:
assert len(callbackMemberTypes) == 1
memberType = callbackMemberTypes[0]
name = getUnionMemberName(memberType)
callbackObject = CGGeneric(
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
(unionArgumentObj, name))
names.append(name)
@@ -5076,17 +5134,18 @@ def getJSToNativeConversionInfo(type, de
"done = true;\n" % (unionArgumentObj, indent(exceptionCode)))
names.append(objectMemberTypes[0].name)
else:
object = None
hasObjectTypes = interfaceObject or sequenceObject or dateObject or callbackObject or object or recordObject
if hasObjectTypes:
# "object" is not distinguishable from other types
- assert not object or not (interfaceObject or sequenceObject or dateObject or callbackObject or recordObject)
+ assert not object or not (
+ interfaceObject or sequenceObject or dateObject or callbackObject or recordObject)
if sequenceObject or dateObject or callbackObject:
# An object can be both an sequence object and a callback or
# dictionary, but we shouldn't have both in the union's members
# because they are not distinguishable.
assert not (sequenceObject and callbackObject)
templateBody = CGElseChain([sequenceObject, dateObject, callbackObject])
else:
templateBody = None
@@ -5094,17 +5153,18 @@ def getJSToNativeConversionInfo(type, de
assert not object
if templateBody:
templateBody = CGIfWrapper(templateBody, "!done")
templateBody = CGList([interfaceObject, templateBody])
else:
templateBody = CGList([templateBody, object])
if dateObject:
- templateBody.prepend(CGGeneric("JS::Rooted<JSObject*> argObj(cx, &${val}.toObject());\n"))
+ templateBody.prepend(
+ CGGeneric("JS::Rooted<JSObject*> argObj(cx, &${val}.toObject());\n"))
if recordObject:
templateBody = CGList([templateBody,
CGIfWrapper(recordObject, "!done")])
templateBody = CGIfWrapper(templateBody, "${val}.isObject()")
else:
templateBody = CGGeneric()
@@ -5513,17 +5573,17 @@ def getJSToNativeConversionInfo(type, de
else:
declType = "NonNull<" + typeName + ">"
templateBody = ""
if forceOwningType:
templateBody += 'static_assert(IsRefcounted<%s>::value, "We can only store refcounted classes.");' % typeName
if (not descriptor.interface.isConsequential() and
- not descriptor.interface.isExternal()):
+ not descriptor.interface.isExternal()):
if failureCode is not None:
templateBody += str(CastableObjectUnwrapper(
descriptor,
"${val}",
"${maybeMutableVal}",
"${declName}",
failureCode))
else:
@@ -5652,23 +5712,22 @@ def getJSToNativeConversionInfo(type, de
if type.isUSVString():
normalizeCode = "NormalizeUSVString(%s);\n" % varName
conversionCode = fill("""
if (!ConvertJSValueToString(cx, $${val}, ${nullBehavior}, ${undefinedBehavior}, ${varName})) {
$*{exceptionCode}
}
$*{normalizeCode}
- """
- ,
- nullBehavior=nullBehavior,
- undefinedBehavior=undefinedBehavior,
- varName=varName,
- exceptionCode=exceptionCode,
- normalizeCode=normalizeCode)
+ """,
+ nullBehavior=nullBehavior,
+ undefinedBehavior=undefinedBehavior,
+ varName=varName,
+ exceptionCode=exceptionCode,
+ normalizeCode=normalizeCode)
if defaultValue is None:
return conversionCode
if isinstance(defaultValue, IDLNullValue):
assert(type.nullable())
defaultCode = "%s.SetIsVoid(true)" % varName
else:
@@ -5706,18 +5765,18 @@ def getJSToNativeConversionInfo(type, de
nullable = toStringBool(type.nullable())
conversionCode = fill("""
if (!ConvertJSValueToByteString(cx, $${val}, ${nullable}, $${declName})) {
$*{exceptionCode}
}
""",
- nullable=nullable,
- exceptionCode=exceptionCode)
+ nullable=nullable,
+ exceptionCode=exceptionCode)
if defaultValue is not None:
if isinstance(defaultValue, IDLNullValue):
assert(type.nullable())
defaultCode = "${declName}.SetIsVoid(true)"
else:
defaultCode = handleDefaultStringValue(defaultValue,
"${declName}.Rebind")
@@ -5923,35 +5982,35 @@ def getJSToNativeConversionInfo(type, de
declType = CGGeneric(typeName)
# We do manual default value handling here, because we
# actually do want a jsval, and we only handle null anyway
# NOTE: if isNullOrUndefined or isDefinitelyObject are true,
# we know we have a value, so we don't have to worry about the
# default value.
if (not isNullOrUndefined and not isDefinitelyObject and
- defaultValue is not None):
+ defaultValue is not None):
assert(isinstance(defaultValue, IDLNullValue))
val = "(${haveValue}) ? ${val} : JS::NullHandleValue"
else:
val = "${val}"
dictLoc = "${declName}"
if type.nullable():
dictLoc += ".SetValue()"
conversionCode = fill("""
if (!${dictLoc}.Init(cx, ${val}, "${desc}", $${passedToJSImpl})) {
$*{exceptionCode}
}
""",
- dictLoc=dictLoc,
- val=val,
- desc=firstCap(sourceDescription),
- exceptionCode=exceptionCode)
+ dictLoc=dictLoc,
+ val=val,
+ desc=firstCap(sourceDescription),
+ exceptionCode=exceptionCode)
if failureCode is not None:
# This means we're part of an overload or union conversion, and
# should simply skip stuff if our value is not convertible to
# dictionary, instead of trying and throwing. If we're either
# isDefinitelyObject or isNullOrUndefined then we're convertible to
# dictionary and don't need to check here.
if isDefinitelyObject or isNullOrUndefined:
@@ -6061,35 +6120,35 @@ def getJSToNativeConversionInfo(type, de
nullCondition = "!(${haveValue}) || " + nullCondition
template = fill("""
if (${nullCondition}) {
$${declName}.SetNull();
} else if (!ValueToPrimitive<${typeName}, ${conversionBehavior}>(cx, $${val}, &${writeLoc})) {
$*{exceptionCode}
}
""",
- nullCondition=nullCondition,
- typeName=typeName,
- conversionBehavior=conversionBehavior,
- writeLoc=writeLoc,
- exceptionCode=exceptionCode)
+ nullCondition=nullCondition,
+ typeName=typeName,
+ conversionBehavior=conversionBehavior,
+ writeLoc=writeLoc,
+ exceptionCode=exceptionCode)
else:
assert(defaultValue is None or
not isinstance(defaultValue, IDLNullValue))
writeLoc = "${declName}"
readLoc = writeLoc
template = fill("""
if (!ValueToPrimitive<${typeName}, ${conversionBehavior}>(cx, $${val}, &${writeLoc})) {
$*{exceptionCode}
}
""",
- typeName=typeName,
- conversionBehavior=conversionBehavior,
- writeLoc=writeLoc,
- exceptionCode=exceptionCode)
+ typeName=typeName,
+ conversionBehavior=conversionBehavior,
+ writeLoc=writeLoc,
+ exceptionCode=exceptionCode)
declType = CGGeneric(typeName)
if type.isFloat() and not type.isUnrestricted():
if lenientFloatCode is not None:
nonFiniteCode = lenientFloatCode
else:
nonFiniteCode = ('ThrowErrorMessage(cx, MSG_NOT_FINITE, "%s");\n'
"%s" % (firstCap(sourceDescription), exceptionCode))
@@ -6097,22 +6156,22 @@ def getJSToNativeConversionInfo(type, de
# We're appending to an if-block brace, so strip trailing whitespace
# and add an extra space before the else.
template = template.rstrip()
template += fill("""
else if (!mozilla::IsFinite(${readLoc})) {
$*{nonFiniteCode}
}
""",
- readLoc=readLoc,
- nonFiniteCode=nonFiniteCode)
+ readLoc=readLoc,
+ nonFiniteCode=nonFiniteCode)
if (defaultValue is not None and
# We already handled IDLNullValue, so just deal with the other ones
- not isinstance(defaultValue, IDLNullValue)):
+ not isinstance(defaultValue, IDLNullValue)):
tag = defaultValue.type.tag()
defaultStr = getHandleDefault(defaultValue)
template = CGIfElseWrapper(
"${haveValue}",
CGGeneric(template),
CGGeneric("%s = %s;\n" % (writeLoc, defaultStr))).define()
return JSToNativeConversionInfo(template, declType=declType,
@@ -6242,16 +6301,17 @@ class CGArgumentConverter(CGThing):
argument list and generates code to unwrap the argument to the
right native type.
argDescription is a description of the argument for error-reporting
purposes. Callers should assume that it might get placed in the middle of a
sentence. If it ends up at the beginning of a sentence, its first character
will be automatically uppercased.
"""
+
def __init__(self, argument, index, descriptorProvider,
argDescription, member,
invalidEnumValueFatal=True, lenientFloatCode=None):
CGThing.__init__(self)
self.argument = argument
self.argDescription = argDescription
assert(not argument.defaultValue or argument.optional)
@@ -7089,31 +7149,33 @@ def needScopeObject(returnType, argument
def callerTypeGetterForDescriptor(descriptor):
if descriptor.interface.isExposedInAnyWorker():
systemCallerGetter = "nsContentUtils::ThreadsafeIsSystemCaller"
else:
systemCallerGetter = "nsContentUtils::IsSystemCaller"
return "%s(cx) ? CallerType::System : CallerType::NonSystem" % systemCallerGetter
+
class CGCallGenerator(CGThing):
"""
A class to generate an actual call to a C++ object. Assumes that the C++
object is stored in a variable whose name is given by the |object| argument.
needsCallerType is a boolean indicating whether the call should receive
a PrincipalType for the caller.
isFallible is a boolean indicating whether the call should be fallible.
resultVar: If the returnType is not void, then the result of the call is
stored in a C++ variable named by resultVar. The caller is responsible for
declaring the result variable. If the caller doesn't care about the result
value, resultVar can be omitted.
"""
+
def __init__(self, isFallible, needsCallerType, isChromeOnly,
arguments, argsPre, returnType, extendedAttributes, descriptor,
nativeMethodName, static, object="self", argsPost=[],
resultVar=None):
CGThing.__init__(self)
result, resultOutParam, resultRooter, resultArgs, resultConversion = \
getRetvalDeclarationForType(returnType, descriptor)
@@ -7149,17 +7211,17 @@ class CGCallGenerator(CGThing):
return True
return False
if needsConst(a):
arg = CGWrapper(arg, pre="Constify(", post=")")
# And convert NonNull<T> to T&
if (((a.type.isGeckoInterface() or a.type.isCallback() or
a.type.isPromise()) and
not a.type.nullable()) or
- a.type.isDOMString()):
+ a.type.isDOMString()):
arg = CGWrapper(arg, pre="NonNullHelper(", post=")")
# If it's a refcounted object, let the static analysis know it's
# alive for the duration of the call.
if a.type.isGeckoInterface():
arg = CGWrapper(arg, pre="MOZ_KnownLive(", post=")")
args.append(arg)
@@ -7256,17 +7318,17 @@ class CGCallGenerator(CGThing):
if (NS_IsMainThread()) {
$*{getPrincipal}
subjectPrincipal.emplace(principal);
}
""",
getPrincipal=getPrincipal)))
else:
if needsNonSystemPrincipal:
- principalType = "nsIPrincipal*";
+ principalType = "nsIPrincipal*"
else:
principalType = "NonNull<nsIPrincipal>"
self.cgRoot.prepend(CGGeneric(fill(
"""
${principalType} subjectPrincipal;
{
$*{getPrincipal}
@@ -7305,16 +7367,17 @@ def getUnionMemberName(type):
return type.inner.identifier.name
return type.name
class MethodNotNewObjectError(Exception):
def __init__(self, typename):
self.typename = typename
+
# A counter for making sure that when we're wrapping up things in
# nested sequences we don't use the same variable name to iterate over
# different sequences.
sequenceWrapLevel = 0
recordWrapLevel = 0
def wrapTypeIntoCurrentCompartment(type, value, isMember=True):
@@ -7424,17 +7487,17 @@ def wrapTypeIntoCurrentCompartment(type,
if memberWrap:
memberWrap = CGIfWrapper(
memberWrap, "%s.Is%s()" % (value, memberName))
memberWraps.append(memberWrap)
return CGList(memberWraps, "else ") if len(memberWraps) != 0 else None
if (type.isString() or type.isPrimitive() or type.isEnum() or
type.isGeckoInterface() or type.isCallback() or type.isDate() or
- type.isPromise()):
+ type.isPromise()):
# All of these don't need wrapping.
return None
raise TypeError("Unknown type; we don't know how to wrap it in constructor "
"arguments: %s" % type)
def wrapArgIntoCurrentCompartment(arg, value, isMember=True):
@@ -7449,19 +7512,21 @@ def wrapArgIntoCurrentCompartment(arg, v
if wrap and isOptional:
wrap = CGIfWrapper(wrap, "%s.WasPassed()" % origValue)
return wrap
def needsContainsHack(m):
return m.getExtendedAttribute("ReturnValueNeedsContainsHack")
+
def needsCallerType(m):
return m.getExtendedAttribute("NeedsCallerType")
+
class CGPerSignatureCall(CGThing):
"""
This class handles the guts of generating code for a particular
call signature. A call signature consists of four 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|).
@@ -7508,17 +7573,17 @@ class CGPerSignatureCall(CGThing):
if deprecated:
cgThings.append(CGGeneric(dedent(
"""
DeprecationWarning(cx, obj, nsIDocument::e%s);
""" % deprecated[0])))
lenientFloatCode = None
if (idlNode.getExtendedAttribute('LenientFloat') is not None and
- (setter or idlNode.isMethod())):
+ (setter or idlNode.isMethod())):
cgThings.append(CGGeneric(dedent(
"""
bool foundNonFiniteFloat = false;
""")))
lenientFloatCode = "foundNonFiniteFloat = true;\n"
argsPre = []
if idlNode.isStatic():
@@ -7563,17 +7628,18 @@ class CGPerSignatureCall(CGThing):
if descriptor.interface.isJSImplemented():
# We need the desired proto in our constructor, because the
# constructor will actually construct our reflector.
argsPost.append("desiredProto")
elif descriptor.interface.isJSImplemented():
if not idlNode.isStatic():
needsUnwrap = True
needsUnwrappedVar = True
- argsPost.append("(unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx))")
+ argsPost.append(
+ "(unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx))")
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:
@@ -7673,17 +7739,17 @@ class CGPerSignatureCall(CGThing):
wrapArgIntoCurrentCompartment(arg, argname, isMember=False)
for arg, argname in self.getArguments())
cgThings.append(
CGIfWrapper(CGList(xraySteps),
"objIsXray"))
if (idlNode.getExtendedAttribute('CEReactions') is not None and
- not getter):
+ not getter):
cgThings.append(CGGeneric(fill(
"""
Maybe<AutoCEReaction> ceReaction;
if (CustomElementRegistry::IsCustomElementEnabled(cx, ${obj})) {
DocGroup* docGroup = self->GetDocGroup();
if (docGroup) {
ceReaction.emplace(docGroup->CustomElementReactionsStack(), cx);
}
@@ -7691,17 +7757,17 @@ class CGPerSignatureCall(CGThing):
""",
obj=objectName)))
# If this is a method that was generated by a maplike/setlike
# interface, use the maplike/setlike generator to fill in the body.
# Otherwise, use CGCallGenerator to call the native method.
if idlNode.isMethod() and idlNode.isMaplikeOrSetlikeOrIterableMethod():
if (idlNode.maplikeOrSetlikeOrIterable.isMaplike() or
- idlNode.maplikeOrSetlikeOrIterable.isSetlike()):
+ idlNode.maplikeOrSetlikeOrIterable.isSetlike()):
cgThings.append(CGMaplikeOrSetlikeMethodGenerator(descriptor,
idlNode.maplikeOrSetlikeOrIterable,
idlNode.identifier.name))
else:
cgThings.append(CGIterableMethodGenerator(descriptor,
idlNode.maplikeOrSetlikeOrIterable,
idlNode.identifier.name))
else:
@@ -7819,17 +7885,17 @@ class CGPerSignatureCall(CGThing):
"}\n")
if self.idlNode.type.nullable():
freezeValue = CGIfWrapper(freezeValue,
"args.rval().isObject()")
postConversionSteps += freezeValue.define()
# slotStorageSteps are steps that run once we have entered the
# slotStorage compartment.
- slotStorageSteps= fill(
+ slotStorageSteps = fill(
"""
// Make a copy so that we don't do unnecessary wrapping on args.rval().
JS::Rooted<JS::Value> storedVal(cx, args.rval());
if (!${maybeWrap}(cx, &storedVal)) {
return false;
}
js::SetReservedSlot(slotStorage, slotIndex, storedVal);
""",
@@ -7841,17 +7907,17 @@ class CGPerSignatureCall(CGThing):
# wrapper if needed. We need to do this because otherwise the
# wrapper could get garbage-collected and the cached value would
# suddenly disappear, but the whole premise of cached values is that
# they never change without explicit action on someone's part. We
# don't do this for StoreInSlot, since those get dealt with during
# wrapper setup, and failure would involve us trying to clear an
# already-preserved wrapper.
if (self.idlNode.getExtendedAttribute("Cached") and
- self.descriptor.wrapperCache):
+ self.descriptor.wrapperCache):
preserveWrapper = dedent(
"""
PreserveWrapper(self);
""")
if checkForXray:
preserveWrapper = fill(
"""
if (!isXray) {
@@ -7901,16 +7967,17 @@ class CGSwitch(CGList):
A class to generate code for a switch statement.
Takes three constructor arguments: an expression, a list of cases,
and an optional default.
Each case is a CGCase. The default is a CGThing for the body of
the default case, if any.
"""
+
def __init__(self, expression, cases, default=None):
CGList.__init__(self, [CGIndenter(c) for c in cases])
self.prepend(CGGeneric("switch (" + expression + ") {\n"))
if default is not None:
self.append(
CGIndenter(
CGWrapper(
CGIndenter(default),
@@ -7923,16 +7990,17 @@ class CGSwitch(CGList):
class CGCase(CGList):
"""
A class to generate code for a case statement.
Takes three constructor arguments: an expression, a CGThing for
the body (allowed to be None if there is no body), and an optional
argument (defaulting to False) for whether to fall through.
"""
+
def __init__(self, expression, body, fallThrough=False):
CGList.__init__(self, [])
self.append(CGGeneric("case " + expression + ": {\n"))
bodyList = CGList([body])
if fallThrough:
bodyList.append(CGGeneric("MOZ_FALLTHROUGH;\n"))
else:
bodyList.append(CGGeneric("break;\n"))
@@ -7940,16 +8008,17 @@ class CGCase(CGList):
self.append(CGGeneric("}\n"))
class CGMethodCall(CGThing):
"""
A class to generate selection of a method signature from a set of
signatures and generation of a call to that signature.
"""
+
def __init__(self, nativeMethodName, static, descriptor, method,
isConstructor=False, constructorName=None):
CGThing.__init__(self)
if isConstructor:
assert constructorName is not None
methodName = constructorName
else:
@@ -8016,17 +8085,18 @@ class CGMethodCall(CGThing):
argCountCases = []
for argCountIdx, argCount in enumerate(allowedArgCounts):
possibleSignatures = method.signaturesForArgCount(argCount)
# Try to optimize away cases when the next argCount in the list
# will have the same code as us; if it does, we can fall through to
# that case.
if argCountIdx+1 < len(allowedArgCounts):
- nextPossibleSignatures = method.signaturesForArgCount(allowedArgCounts[argCountIdx+1])
+ nextPossibleSignatures = method.signaturesForArgCount(
+ allowedArgCounts[argCountIdx+1])
else:
nextPossibleSignatures = None
if possibleSignatures == nextPossibleSignatures:
# Same set of signatures means we better have the same
# distinguishing index. So we can in fact just fall through to
# the next case here.
assert (len(possibleSignatures) == 1 or
(method.distinguishingIndexForArgCount(argCount) ==
@@ -8161,17 +8231,17 @@ class CGMethodCall(CGThing):
for t in distinguishingTypes)
return True
def needsNullOrUndefinedCase(type):
"""
Return true if the type needs a special isNullOrUndefined() case
"""
return ((type.nullable() and
- hasConditionalConversion(type)) or
+ hasConditionalConversion(type)) or
type.isDictionary())
# First check for undefined and optional distinguishing arguments
# and output a special branch for that case. Note that we don't
# use distinguishingArgument here because we actualy want to
# exclude variadic arguments. Also note that we skip this check if
# we plan to output a isNullOrUndefined() special case for this
# argument anyway, since that will subsume our isUndefined() check.
@@ -8322,17 +8392,17 @@ class CGMethodCall(CGThing):
if booleanSignature:
addCase(booleanSignature, booleanCondition)
if numericSignature:
addCase(numericSignature, numericCondition)
if stringSignature:
addCase(stringSignature, None)
if (not booleanSignature and not numericSignature and
- not stringSignature):
+ not stringSignature):
# Just throw; we have no idea what we're supposed to
# do with this.
caseBody.append(CGGeneric(
'return ThrowErrorMessage(cx, MSG_OVERLOAD_RESOLUTION_FAILED, "%d", "%d", "%s");\n' %
(distinguishingIndex + 1, argCount, methodName)))
argCountCases.append(CGCase(str(argCount), CGList(caseBody)))
@@ -8354,16 +8424,17 @@ class CGMethodCall(CGThing):
return self.cgRoot.define()
class CGGetterCall(CGPerSignatureCall):
"""
A class to generate a native object getter call for a particular IDL
getter.
"""
+
def __init__(self, returnType, nativeMethodName, descriptor, attr):
if attr.getExtendedAttribute("UseCounter"):
useCounterName = "%s_%s_getter" % (descriptor.interface.identifier.name,
attr.identifier.name)
else:
useCounterName = None
if attr.isStatic():
nativeMethodName = "%s::%s" % (descriptor.nativeType, nativeMethodName)
@@ -8372,18 +8443,20 @@ class CGGetterCall(CGPerSignatureCall):
getter=True, useCounterName=useCounterName)
class CGNavigatorGetterCall(CGPerSignatureCall):
"""
A class to generate a native object getter call for an IDL getter for a
property generated by NavigatorProperty.
"""
+
def __init__(self, returnType, _, descriptor, attr):
- nativeMethodName = "%s::ConstructNavigatorObject" % (toBindingNamespace(returnType.inner.identifier.name))
+ nativeMethodName = "%s::ConstructNavigatorObject" % (
+ toBindingNamespace(returnType.inner.identifier.name))
CGPerSignatureCall.__init__(self, returnType, [], nativeMethodName,
True, descriptor, attr, getter=True)
def getArguments(self):
# The navigator object should be associated with the global of
# the navigator it's coming from, which will be the global of
# the object whose slot it gets cached in. That's stored in
# "slotStorage".
@@ -8397,16 +8470,17 @@ class FakeIdentifier():
self.name = name
class FakeArgument():
"""
A class that quacks like an IDLArgument. This is used to make
setters look like method calls or for special operations.
"""
+
def __init__(self, type, interfaceMember, name="arg", allowTreatNonCallableAsNull=False):
self.type = type
self.optional = False
self.variadic = False
self.defaultValue = None
self._allowTreatNonCallableAsNull = allowTreatNonCallableAsNull
# For FakeArguments generated by maplike/setlike convenience functions,
# we won't have an interfaceMember to pass in.
@@ -8430,16 +8504,17 @@ class FakeArgument():
return False
class CGSetterCall(CGPerSignatureCall):
"""
A class to generate a native object setter call for a particular IDL
setter.
"""
+
def __init__(self, argType, nativeMethodName, descriptor, attr):
if attr.getExtendedAttribute("UseCounter"):
useCounterName = "%s_%s_setter" % (descriptor.interface.identifier.name,
attr.identifier.name)
else:
useCounterName = None
if attr.isStatic():
nativeMethodName = "%s::%s" % (descriptor.nativeType, nativeMethodName)
@@ -8477,17 +8552,18 @@ class CGAbstractBindingMethod(CGAbstract
getThisObj should be code for getting a JSObject* for the binding
object. "" can be passed in if the binding object is already stored in
'obj'.
callArgs should be code for getting a JS::CallArgs into a variable
called 'args'. This can be "" if there is already such a variable
around.
"""
- def __init__(self, descriptor, name, args, getThisObj,
+ def __init__(self, descriptor, name, args, unwrapFailureCode=None,
+ getThisObj=None,
callArgs="JS::CallArgs args = JS::CallArgsFromVp(argc, vp);\n"):
CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
self.unwrapFailureCode = 'return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "%s");\n' % descriptor.interface.identifier.name
if getThisObj == "":
self.getThisObj = None
else:
@@ -8525,16 +8601,17 @@ class CGAbstractBindingMethod(CGAbstract
class CGAbstractStaticBindingMethod(CGAbstractStaticMethod):
"""
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):
CGAbstractStaticMethod.__init__(self, descriptor, name, "bool",
JSNativeArguments())
def definition_body(self):
# Make sure that "obj" is in the same compartment as "cx", since we'll
# later use it to wrap return values.
unwrap = dedent("""
@@ -8548,28 +8625,29 @@ class CGAbstractStaticBindingMethod(CGAb
# Our args are JSNativeArguments() which contain a "JSContext* cx"
# argument. We let our subclasses choose the label.
return (self.profiler_label(), "cx")
def generate_code(self):
assert False # Override me
def profiler_label(self):
- assert False # Override me
+ assert False # Override me
def MakeNativeName(name):
return name[0].upper() + IDLToCIdentifier(name[1:])
class CGSpecializedMethod(CGAbstractStaticMethod):
"""
A class for generating the C++ code for a specialized method that the JIT
can call with lower overhead.
"""
+
def __init__(self, descriptor, method):
self.method = method
name = CppKeywords.checkMethodName(IDLToCIdentifier(method.identifier.name))
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'obj'),
Argument('%s*' % descriptor.nativeType, 'self'),
Argument('const JSJitMethodCallArgs&', 'args')]
CGAbstractStaticMethod.__init__(self, descriptor, name, 'bool', args,
@@ -8592,16 +8670,17 @@ class CGSpecializedMethod(CGAbstractStat
return MakeNativeName(descriptor.binaryNameFor(name))
class CGMethodPromiseWrapper(CGAbstractStaticMethod):
"""
A class for generating a wrapper around another method that will
convert exceptions to promises.
"""
+
def __init__(self, descriptor, methodToWrap):
self.method = methodToWrap
name = self.makeName(methodToWrap.name)
args = list(methodToWrap.args)
CGAbstractStaticMethod.__init__(self, descriptor, name, 'bool', args,
canRunScript=True)
def definition_body(self):
@@ -8646,26 +8725,27 @@ class CGDefaultToJSONMethod(CGSpecialize
for descriptor in jsonDescriptors[::-1]:
ret += fill(
"""
if (!${parentclass}::CollectJSONAttributes(cx, obj, self, result)) {
return false;
}
""",
parentclass=toBindingNamespace(descriptor.name)
- )
+ )
ret += ('args.rval().setObject(*result);\n'
'return true;\n')
return ret
class CGLegacyCallHook(CGAbstractBindingMethod):
"""
Call hook for our object
"""
+
def __init__(self, descriptor):
self._legacycaller = descriptor.operations["LegacyCaller"]
# Our "self" is actually the callee in this case, not the thisval.
CGAbstractBindingMethod.__init__(
self, descriptor, LEGACYCALLER_HOOK_NAME,
JSNativeArguments(), getThisObj="&args.callee()")
def define(self):
@@ -8679,16 +8759,17 @@ class CGLegacyCallHook(CGAbstractBinding
return CGMethodCall(nativeName, False, self.descriptor,
self._legacycaller)
class CGResolveHook(CGAbstractClassHook):
"""
Resolve hook for objects that have the NeedResolve extended attribute.
"""
+
def __init__(self, descriptor):
assert descriptor.interface.getExtendedAttribute("NeedResolve")
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'obj'),
Argument('JS::Handle<jsid>', 'id'),
Argument('bool*', 'resolvedp')]
CGAbstractClassHook.__init__(self, descriptor, RESOLVE_HOOK_NAME,
@@ -8732,16 +8813,17 @@ class CGResolveHook(CGAbstractClassHook)
prefix = ""
return prefix + CGAbstractClassHook.definition_body(self)
class CGMayResolveHook(CGAbstractStaticMethod):
"""
Resolve hook for objects that have the NeedResolve extended attribute.
"""
+
def __init__(self, descriptor):
assert descriptor.interface.getExtendedAttribute("NeedResolve")
args = [Argument('const JSAtomState&', 'names'),
Argument('jsid', 'id'),
Argument('JSObject*', 'maybeObj')]
CGAbstractStaticMethod.__init__(self, descriptor, MAY_RESOLVE_HOOK_NAME,
"bool", args)
@@ -8760,16 +8842,17 @@ class CGMayResolveHook(CGAbstractStaticM
return (prefix +
"return %s::MayResolve(id);\n" % self.descriptor.nativeType)
class CGEnumerateHook(CGAbstractBindingMethod):
"""
Enumerate hook for objects with custom hooks.
"""
+
def __init__(self, descriptor):
assert descriptor.interface.getExtendedAttribute("NeedResolve")
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'obj'),
Argument('JS::AutoIdVector&', 'properties'),
Argument('bool', 'enumerableOnly')]
# Our "self" is actually the "obj" argument in this case, not the thisval.
@@ -8826,16 +8909,17 @@ class CppKeywords():
name = '_' + name + '_'
return name
class CGStaticMethod(CGAbstractStaticBindingMethod):
"""
A class for generating the C++ code for an IDL static method.
"""
+
def __init__(self, descriptor, method):
self.method = method
name = CppKeywords.checkMethodName(IDLToCIdentifier(method.identifier.name))
CGAbstractStaticBindingMethod.__init__(self, descriptor, name)
def generate_code(self):
nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
self.method)
@@ -8847,16 +8931,17 @@ class CGStaticMethod(CGAbstractStaticBin
return "%s.%s" % (interface_name, method_name)
class CGSpecializedGetter(CGAbstractStaticMethod):
"""
A class for generating the code for a specialized attribute getter
that the JIT can call with lower overhead.
"""
+
def __init__(self, descriptor, attr):
self.attr = attr
name = 'get_' + IDLToCIdentifier(attr.identifier.name)
args = [
Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'obj'),
Argument('%s*' % descriptor.nativeType, 'self'),
Argument('JSJitGetterCallArgs', 'args')
@@ -8967,16 +9052,17 @@ class CGSpecializedGetter(CGAbstractStat
return nativeName
class CGGetterPromiseWrapper(CGAbstractStaticMethod):
"""
A class for generating a wrapper around another getter that will
convert exceptions to promises.
"""
+
def __init__(self, descriptor, getterToWrap):
self.getter = getterToWrap
name = self.makeName(getterToWrap.name)
args = list(getterToWrap.args)
CGAbstractStaticMethod.__init__(self, descriptor, name, 'bool', args,
canRunScript=True)
def definition_body(self):
@@ -8995,16 +9081,17 @@ class CGGetterPromiseWrapper(CGAbstractS
def makeName(getterName):
return getterName + "_promiseWrapper"
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_' + IDLToCIdentifier(attr.identifier.name)
CGAbstractStaticBindingMethod.__init__(self, descriptor, name)
def generate_code(self):
nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
self.attr)
@@ -9017,16 +9104,17 @@ class CGStaticGetter(CGAbstractStaticBin
return "get %s.%s" % (interface_name, attr_name)
class CGSpecializedSetter(CGAbstractStaticMethod):
"""
A class for generating the code for a specialized attribute setter
that the JIT can call with lower overhead.
"""
+
def __init__(self, descriptor, attr):
self.attr = attr
name = 'set_' + IDLToCIdentifier(attr.identifier.name)
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'obj'),
Argument('%s*' % descriptor.nativeType, 'self'),
Argument('JSJitSetterCallArgs', 'args')]
CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args,
@@ -9048,16 +9136,17 @@ class CGSpecializedSetter(CGAbstractStat
name = attr.identifier.name
return "Set" + MakeNativeName(descriptor.binaryNameFor(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_' + IDLToCIdentifier(attr.identifier.name)
CGAbstractStaticBindingMethod.__init__(self, descriptor, name)
def generate_code(self):
nativeName = CGSpecializedSetter.makeNativeName(self.descriptor,
self.attr)
@@ -9078,16 +9167,17 @@ class CGStaticSetter(CGAbstractStaticBin
return "set %s.%s" % (interface_name, attr_name)
class CGSpecializedForwardingSetter(CGSpecializedSetter):
"""
A class for generating the code for a specialized attribute setter with
PutForwards that the JIT can call with lower overhead.
"""
+
def __init__(self, descriptor, attr):
CGSpecializedSetter.__init__(self, descriptor, attr)
def definition_body(self):
attrName = self.attr.identifier.name
forwardToAttrName = self.attr.getExtendedAttribute("PutForwards")[0]
# JS_GetProperty and JS_SetProperty can only deal with ASCII
assert all(ord(c) < 128 for c in attrName)
@@ -9111,32 +9201,34 @@ class CGSpecializedForwardingSetter(CGSp
forwardToAttrName=forwardToAttrName)
class CGSpecializedReplaceableSetter(CGSpecializedSetter):
"""
A class for generating the code for a specialized attribute setter with
Replaceable that the JIT can call with lower overhead.
"""
+
def __init__(self, descriptor, attr):
CGSpecializedSetter.__init__(self, descriptor, attr)
def definition_body(self):
attrName = self.attr.identifier.name
# JS_DefineProperty can only deal with ASCII
assert all(ord(c) < 128 for c in attrName)
return ('return JS_DefineProperty(cx, obj, "%s", args[0], JSPROP_ENUMERATE);\n' %
attrName)
class CGSpecializedLenientSetter(CGSpecializedSetter):
"""
A class for generating the code for a specialized attribute setter with
LenientSetter that the JIT can call with lower overhead.
"""
+
def __init__(self, descriptor, attr):
CGSpecializedSetter.__init__(self, descriptor, attr)
def definition_body(self):
attrName = self.attr.identifier.name
# JS_DefineProperty can only deal with ASCII
assert all(ord(c) < 128 for c in attrName)
return dedent("""
@@ -9149,16 +9241,17 @@ def memberReturnsNewObject(member):
return member.getExtendedAttribute("NewObject") is not None
class CGMemberJITInfo(CGThing):
"""
A class for generating the JITInfo for a property that points to
our specialized getter and setter.
"""
+
def __init__(self, descriptor, member):
self.member = member
self.descriptor = descriptor
def declare(self):
return ""
def defineJitInfo(self, infoName, opName, opType, infallible, movable,
@@ -9168,18 +9261,20 @@ class CGMemberJITInfo(CGThing):
aliasSet is a JSJitInfo::AliasSet value, without the "JSJitInfo::" bit.
args is None if we don't want to output argTypes for some
reason (e.g. we have overloads or we're not a method) and
otherwise an iterable of the arguments for this method.
"""
assert(not movable or aliasSet != "AliasEverything") # Can't move write-aliasing things
assert(not alwaysInSlot or movable) # Things always in slots had better be movable
- assert(not eliminatable or aliasSet != "AliasEverything") # Can't eliminate write-aliasing things
- assert(not alwaysInSlot or eliminatable) # Things always in slots had better be eliminatable
+ # Can't eliminate write-aliasing things
+ assert(not eliminatable or aliasSet != "AliasEverything")
+ # Things always in slots had better be eliminatable
+ assert(not alwaysInSlot or eliminatable)
def jitInfoInitializer(isTypedMethod):
initializer = fill(
"""
{
{ ${opName} },
{ prototypes::id::${name} },
{ PrototypeTraits<prototypes::id::${name}>::Depth },
@@ -9293,17 +9388,17 @@ class CGMemberJITInfo(CGThing):
result = self.defineJitInfo(getterinfo, getter, "Getter",
getterinfal, movable, eliminatable,
aliasSet, isAlwaysInSlot,
isLazilyCachedInSlot, slotIndex,
[self.member.type], None)
if (not self.member.readonly or
self.member.getExtendedAttribute("PutForwards") is not None or
self.member.getExtendedAttribute("Replaceable") is not None or
- self.member.getExtendedAttribute("LenientSetter") is not None):
+ self.member.getExtendedAttribute("LenientSetter") is not None):
setterinfo = ("%s_setterinfo" %
IDLToCIdentifier(self.member.identifier.name))
# Actually a JSJitSetterOp, but JSJitGetterOp is first in the
# union.
setter = ("(JSJitGetterOp)set_%s" %
IDLToCIdentifier(self.member.identifier.name))
# Setters are always fallible, since they have to do a typed unwrap.
result += self.defineJitInfo(setterinfo, setter, "Setter",
@@ -9350,17 +9445,17 @@ class CGMemberJITInfo(CGThing):
# consistent for OOM thrown from the method itself and OOM
# thrown from the to-JS conversion of the return value (see the
# "canOOM" and "infallibleForMember" checks below).
movable = self.mayBeMovable() and hasInfallibleImpl
eliminatable = self.mayBeEliminatable() and hasInfallibleImpl
# XXXbz can we move the smarts about fallibility due to arg
# conversions into the JIT, using our new args stuff?
if (len(sig[1]) != 0 or
- not infallibleForMember(self.member, sig[0], self.descriptor)):
+ not infallibleForMember(self.member, sig[0], self.descriptor)):
# We have arguments or our return-value boxing can fail
methodInfal = False
else:
methodInfal = (hasInfallibleImpl and
"canOOM" not in extendedAttrs)
# For now, only bother to output args if we're side-effect-free.
if self.member.affects == "Nothing":
args = sig[1]
@@ -9578,16 +9673,17 @@ class CGMemberJITInfo(CGThing):
return existingType
return "%s | %s" % (existingType, type)
class CGStaticMethodJitinfo(CGGeneric):
"""
A class for generating the JITInfo for a promise-returning static method.
"""
+
def __init__(self, method):
CGGeneric.__init__(
self,
"\n"
"static const JSJitInfo %s_methodinfo = {\n"
" { (JSJitGetterOp)%s },\n"
" { prototypes::id::_ID_Count }, { 0 }, JSJitInfo::StaticMethod,\n"
" JSJitInfo::AliasEverything, JSVAL_TYPE_MISSING, false, false,\n"
@@ -9618,16 +9714,17 @@ def getEnumValueName(value):
return "_empty"
nativeName = MakeNativeName(value)
if nativeName == "EndGuard_":
raise SyntaxError('Enum value "' + value + '" cannot be used because it'
' collides with our internal EndGuard_ value. Please'
' rename our internal EndGuard_ to something else')
return nativeName
+
class CGEnumToJSValue(CGAbstractMethod):
def __init__(self, enum):
enumType = enum.identifier.name
self.stringsArray = enumType + "Values::" + ENUM_ENTRY_VARIABLE_NAME
CGAbstractMethod.__init__(self, None, "ToJSValue", "bool",
[Argument("JSContext*", "aCx"),
Argument(enumType, "aArgument"),
Argument("JS::MutableHandle<JS::Value>",
@@ -10158,17 +10255,18 @@ class CGUnionStruct(CGThing):
body=op_body.define()))
disallowCopyConstruction = False
else:
disallowCopyConstruction = True
else:
disallowCopyConstruction = True
if self.ownsMembers:
- friend = " friend void ImplCycleCollectionUnlink(%s& aUnion);\n" % CGUnionStruct.unionTypeName(self.type, True)
+ friend = " friend void ImplCycleCollectionUnlink(%s& aUnion);\n" % CGUnionStruct.unionTypeName(
+ self.type, True)
else:
friend = " friend class %sArgument;\n" % str(self.type)
bases = [ClassBase("AllOwningUnionBase")] if self.ownsMembers else []
return CGClass(selfName,
bases=bases,
members=members,
constructors=constructors,
@@ -10297,16 +10395,17 @@ class CGUnionConversionStruct(CGThing):
return ""
def deps(self):
return set()
class ClassItem:
""" Use with CGClass """
+
def __init__(self, name, visibility):
self.name = name
self.visibility = visibility
def declare(self, cgClass):
assert False
def define(self, cgClass):
@@ -10433,16 +10532,17 @@ class ClassUsingDeclaration(ClassItem):
baseClass is the name of the base class to import the name from
name is the name to import
visibility determines the visibility of the name (public,
protected, private), defaults to public.
"""
+
def __init__(self, baseClass, name, visibility='public'):
self.baseClass = baseClass
ClassItem.__init__(self, name, visibility)
def declare(self, cgClass):
return "using %s::%s;\n\n" % (self.baseClass, self.name)
def define(self, cgClass):
@@ -10466,16 +10566,17 @@ class ClassConstructor(ClassItem):
explicit should be True if the constructor should be marked explicit.
baseConstructors is a list of strings containing calls to base constructors,
defaults to None.
body contains a string with the code for the constructor, defaults to empty.
"""
+
def __init__(self, args, inline=False, bodyInHeader=False,
visibility="private", explicit=False, constexpr=False, baseConstructors=None,
body=""):
assert not (inline and constexpr)
assert not (bodyInHeader and constexpr)
self.args = args
self.inline = inline or bodyInHeader
self.bodyInHeader = bodyInHeader or constexpr
@@ -10556,16 +10657,17 @@ class ClassDestructor(ClassItem):
visibility determines the visibility of the destructor (public,
protected, private), defaults to private.
body contains a string with the code for the destructor, defaults to empty.
virtual determines whether the destructor is virtual, defaults to False.
"""
+
def __init__(self, inline=False, bodyInHeader=False,
visibility="private", body='', virtual=False):
self.inline = inline or bodyInHeader
self.bodyInHeader = bodyInHeader
self.body = body
self.virtual = virtual
ClassItem.__init__(self, None, visibility)
@@ -10611,17 +10713,17 @@ class ClassDestructor(ClassItem):
class ClassMember(ClassItem):
def __init__(self, name, type, visibility="private", static=False,
body=None, hasIgnoreInitCheckFlag=False):
self.type = type
self.static = static
self.body = body
- self.hasIgnoreInitCheckFlag = hasIgnoreInitCheckFlag;
+ self.hasIgnoreInitCheckFlag = hasIgnoreInitCheckFlag
ClassItem.__init__(self, name, visibility)
def declare(self, cgClass):
return '%s%s%s %s;\n' % ('static ' if self.static else '',
'MOZ_INIT_OUTSIDE_CTOR '
if self.hasIgnoreInitCheckFlag else '',
self.type, self.name)
@@ -10841,16 +10943,17 @@ class CGResolveOwnProperty(CGAbstractSta
return "return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc);\n"
class CGResolveOwnPropertyViaResolve(CGAbstractBindingMethod):
"""
An implementation of Xray ResolveOwnProperty stuff for things that have a
resolve hook.
"""
+
def __init__(self, descriptor):
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'wrapper'),
Argument('JS::Handle<JSObject*>', 'obj'),
Argument('JS::Handle<jsid>', 'id'),
Argument('JS::MutableHandle<JS::PropertyDescriptor>', 'desc')]
CGAbstractBindingMethod.__init__(self, descriptor,
"ResolveOwnPropertyViaResolve",
@@ -10898,16 +11001,17 @@ class CGEnumerateOwnProperties(CGAbstrac
return "return js::GetProxyHandler(obj)->ownPropertyKeys(cx, wrapper, props);\n"
class CGEnumerateOwnPropertiesViaGetOwnPropertyNames(CGAbstractBindingMethod):
"""
An implementation of Xray EnumerateOwnProperties stuff for things
that have a resolve hook.
"""
+
def __init__(self, descriptor):
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'wrapper'),
Argument('JS::Handle<JSObject*>', 'obj'),
Argument('JS::AutoIdVector&', 'props')]
CGAbstractBindingMethod.__init__(self, descriptor,
"EnumerateOwnPropertiesViaGetOwnPropertyNames",
args, getThisObj="",
@@ -10970,16 +11074,17 @@ class CGProxySpecialOperation(CGPerSigna
foundVar: For getters and deleters, the generated code can also set a bool
variable, declared by the caller, if the given indexed or named property
already existed. If the caller wants this, it should pass the name of the
bool variable as the foundVar keyword argument to the constructor. The
caller is responsible for declaring the variable and initializing it to
false.
"""
+
def __init__(self, descriptor, operation, checkFound=True,
argumentHandleValue=None, resultVar=None, foundVar=None):
self.checkFound = checkFound
self.foundVar = foundVar or "found"
nativeName = MakeNativeName(descriptor.binaryNameFor(operation))
operation = descriptor.operations[operation]
assert len(operation.signatures()) == 1
@@ -11003,17 +11108,17 @@ class CGProxySpecialOperation(CGPerSigna
sourceDescription=("value being assigned to %s setter" %
descriptor.interface.identifier.name))
if argumentHandleValue is None:
argumentHandleValue = "desc.value()"
rootedValue = fill(
"""
JS::Rooted<JS::Value> rootedValue(cx, ${argumentHandleValue});
""",
- argumentHandleValue = argumentHandleValue)
+ argumentHandleValue=argumentHandleValue)
templateValues = {
"declName": argument.identifier.name,
"holderName": argument.identifier.name + "_holder",
"val": argumentHandleValue,
"maybeMutableVal": "&rootedValue",
"obj": "obj",
"passedToJSImpl": "false"
}
@@ -11055,16 +11160,17 @@ class CGProxyIndexedOperation(CGProxySpe
If checkFound is False, will just assert that the prop is found instead of
checking that it is before wrapping the value.
resultVar: See the docstring for CGCallGenerator.
foundVar: See the docstring for CGProxySpecialOperation.
"""
+
def __init__(self, descriptor, name, doUnwrap=True, checkFound=True,
argumentHandleValue=None, resultVar=None, foundVar=None):
self.doUnwrap = doUnwrap
CGProxySpecialOperation.__init__(self, descriptor, name, checkFound,
argumentHandleValue=argumentHandleValue,
resultVar=resultVar,
foundVar=foundVar)
@@ -11093,56 +11199,60 @@ class CGProxyIndexedGetter(CGProxyIndexe
named 'self' holds the C++ object somewhere where the code we generate
will see it.
If checkFound is False, will just assert that the prop is found instead of
checking that it is before wrapping the value.
foundVar: See the docstring for CGProxySpecialOperation.
"""
+
def __init__(self, descriptor, templateValues=None, doUnwrap=True,
checkFound=True, foundVar=None):
self.templateValues = templateValues
CGProxyIndexedOperation.__init__(self, descriptor, 'IndexedGetter',
doUnwrap, checkFound, foundVar=foundVar)
class CGProxyIndexedPresenceChecker(CGProxyIndexedGetter):
"""
Class to generate a call that checks whether an indexed property exists.
For now, we just delegate to CGProxyIndexedGetter
foundVar: See the docstring for CGProxySpecialOperation.
"""
+
def __init__(self, descriptor, foundVar):
CGProxyIndexedGetter.__init__(self, descriptor, foundVar=foundVar)
self.cgRoot.append(CGGeneric("(void)result;\n"))
class CGProxyIndexedSetter(CGProxyIndexedOperation):
"""
Class to generate a call to an indexed setter.
"""
+
def __init__(self, descriptor, argumentHandleValue=None):
CGProxyIndexedOperation.__init__(self, descriptor, 'IndexedSetter',
argumentHandleValue=argumentHandleValue)
class CGProxyNamedOperation(CGProxySpecialOperation):
"""
Class to generate a call to a named operation.
'value' is the jsval to use for the name; None indicates that it should be
gotten from the property id.
resultVar: See the docstring for CGCallGenerator.
foundVar: See the docstring for CGProxySpecialOperation.
"""
+
def __init__(self, descriptor, name, value=None, argumentHandleValue=None,
resultVar=None, foundVar=None):
CGProxySpecialOperation.__init__(self, descriptor, name,
argumentHandleValue=argumentHandleValue,
resultVar=resultVar,
foundVar=foundVar)
self.value = value
@@ -11210,53 +11320,57 @@ class CGProxyNamedGetter(CGProxyNamedOpe
"""
Class to generate a call to an named getter. If templateValues is not None
the returned value will be wrapped with wrapForType using templateValues.
'value' is the jsval to use for the name; None indicates that it should be
gotten from the property id.
foundVar: See the docstring for CGProxySpecialOperation.
"""
+
def __init__(self, descriptor, templateValues=None, value=None,
foundVar=None):
self.templateValues = templateValues
CGProxyNamedOperation.__init__(self, descriptor, 'NamedGetter', value,
foundVar=foundVar)
class CGProxyNamedPresenceChecker(CGProxyNamedGetter):
"""
Class to generate a call that checks whether a named property exists.
For now, we just delegate to CGProxyNamedGetter
foundVar: See the docstring for CGProxySpecialOperation.
"""
+
def __init__(self, descriptor, foundVar=None):
CGProxyNamedGetter.__init__(self, descriptor, foundVar=foundVar)
self.cgRoot.append(CGGeneric("(void)result;\n"))
class CGProxyNamedSetter(CGProxyNamedOperation):
"""
Class to generate a call to a named setter.
"""
+
def __init__(self, descriptor, argumentHandleValue=None):
CGProxyNamedOperation.__init__(self, descriptor, 'NamedSetter',
argumentHandleValue=argumentHandleValue)
class CGProxyNamedDeleter(CGProxyNamedOperation):
"""
Class to generate a call to a named deleter.
resultVar: See the docstring for CGCallGenerator.
foundVar: See the docstring for CGProxySpecialOperation.
"""
+
def __init__(self, descriptor, resultVar=None, foundVar=None):
CGProxyNamedOperation.__init__(self, descriptor, 'NamedDeleter',
resultVar=resultVar,
foundVar=foundVar)
class CGProxyIsProxy(CGAbstractMethod):
def __init__(self, descriptor):
@@ -11268,17 +11382,18 @@ class CGProxyIsProxy(CGAbstractMethod):
def definition_body(self):
return "return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();\n"
class CGProxyUnwrap(CGAbstractMethod):
def __init__(self, descriptor):
args = [Argument('JSObject*', 'obj')]
- CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", descriptor.nativeType + '*', args, alwaysInline=True)
+ CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy",
+ descriptor.nativeType + '*', args, alwaysInline=True)
def declare(self):
return ""
def definition_body(self):
return fill(
"""
MOZ_ASSERT(js::IsProxy(obj));
@@ -11408,17 +11523,18 @@ class CGDOMJSProxyHandler_defineProperty
# The usual convention is to name the ObjectOpResult out-parameter
# `result`, but that name is a bit overloaded around here.
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'proxy'),
Argument('JS::Handle<jsid>', 'id'),
Argument('JS::Handle<JS::PropertyDescriptor>', 'desc'),
Argument('JS::ObjectOpResult&', 'opresult'),
Argument('bool*', 'defined')]
- ClassMethod.__init__(self, "defineProperty", "bool", args, virtual=True, override=True, const=True)
+ ClassMethod.__init__(self, "defineProperty", "bool", args,
+ virtual=True, override=True, const=True)
self.descriptor = descriptor
def getBody(self):
set = ""
indexedSetter = self.descriptor.operations['IndexedSetter']
if indexedSetter:
set += fill(
@@ -11908,28 +12024,29 @@ class CGDOMJSProxyHandler_get(ClassMetho
class CGDOMJSProxyHandler_setCustom(ClassMethod):
def __init__(self, descriptor):
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'proxy'),
Argument('JS::Handle<jsid>', 'id'),
Argument('JS::Handle<JS::Value>', 'v'),
Argument('bool*', 'done')]
- ClassMethod.__init__(self, "setCustom", "bool", args, virtual=True, override=True, const=True)
+ ClassMethod.__init__(self, "setCustom", "bool", args,
+ virtual=True, override=True, const=True)
self.descriptor = descriptor
def getBody(self):
assertion = ("MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),\n"
' "Should not have a XrayWrapper here");\n')
# Correctness first. If we have a NamedSetter and [OverrideBuiltins],
# always call the NamedSetter and never do anything else.
namedSetter = self.descriptor.operations['NamedSetter']
if (namedSetter is not None and
- self.descriptor.interface.getExtendedAttribute('OverrideBuiltins')):
+ self.descriptor.interface.getExtendedAttribute('OverrideBuiltins')):
# Check assumptions.
if self.descriptor.supportsIndexedProperties():
raise ValueError("In interface " + self.descriptor.name + ": " +
"Can't cope with [OverrideBuiltins] and an indexed getter")
if self.descriptor.hasUnforgeableMembers:
raise ValueError("In interface " + self.descriptor.name + ": " +
"Can't cope with [OverrideBuiltins] and unforgeable members")
@@ -12019,17 +12136,18 @@ class CGDOMJSProxyHandler_getElements(Cl
def __init__(self, descriptor):
assert descriptor.supportsIndexedProperties()
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'proxy'),
Argument('uint32_t', 'begin'),
Argument('uint32_t', 'end'),
Argument('js::ElementAdder*', 'adder')]
- ClassMethod.__init__(self, "getElements", "bool", args, virtual=True, override=True, const=True)
+ ClassMethod.__init__(self, "getElements", "bool", args,
+ virtual=True, override=True, const=True)
self.descriptor = descriptor
def getBody(self):
# Just like ownPropertyKeys we'll assume that we have no holes, so
# we have all properties from 0 to length. If that ever changes
# (unlikely), we'll need to do something a bit more clever with how we
# forward on to our ancestor.
@@ -12133,16 +12251,17 @@ class CGDOMJSProxyHandler_isCallable(Cla
""")
class CGDOMJSProxyHandler_canNurseryAllocate(ClassMethod):
"""
Override the default canNurseryAllocate in BaseProxyHandler, for cases when
we should be nursery-allocated.
"""
+
def __init__(self):
ClassMethod.__init__(self, "canNurseryAllocate", "bool",
[],
virtual=True, override=True, const=True)
def getBody(self):
return dedent("""
return true;
@@ -12203,31 +12322,33 @@ class CGDOMJSProxyHandler(CGClass):
constructors=constructors,
methods=methods)
class CGDOMJSProxyHandlerDeclarer(CGThing):
"""
A class for declaring a DOMProxyHandler.
"""
+
def __init__(self, handlerThing):
self.handlerThing = handlerThing
def declare(self):
# Our class declaration should happen when we're defining
return ""
def define(self):
return self.handlerThing.declare()
class CGDOMJSProxyHandlerDefiner(CGThing):
"""
A class for defining a DOMProxyHandler.
"""
+
def __init__(self, handlerThing):
self.handlerThing = handlerThing
def declare(self):
return ""
def define(self):
return self.handlerThing.define()
@@ -12357,17 +12478,17 @@ class CGDescriptor(CGThing):
cgThings.append(CGSpecializedForwardingSetter(descriptor, m))
if props.isCrossOriginSetter:
crossOriginSetters.add(m.identifier.name)
elif m.getExtendedAttribute("Replaceable"):
cgThings.append(CGSpecializedReplaceableSetter(descriptor, m))
elif m.getExtendedAttribute("LenientSetter"):
cgThings.append(CGSpecializedLenientSetter(descriptor, m))
if (not m.isStatic() and
- descriptor.interface.hasInterfacePrototypeObject()):
+ descriptor.interface.hasInterfacePrototypeObject()):
cgThings.append(CGMemberJITInfo(descriptor, m))
if m.isConst() and m.type.isPrimitive():
cgThings.append(CGConstDefinition(m))
if defaultToJSONMethod:
cgThings.append(CGDefaultToJSONMethod(descriptor, defaultToJSONMethod))
cgThings.append(CGMemberJITInfo(descriptor, defaultToJSONMethod))
if descriptor.interface.isNavigatorProperty():
@@ -12408,21 +12529,21 @@ class CGDescriptor(CGThing):
if descriptor.hasNamedPropertiesObject:
cgThings.append(CGGetNamedPropertiesObjectMethod(descriptor))
if descriptor.interface.hasInterfacePrototypeObject():
cgThings.append(CGPrototypeJSClass(descriptor, properties))
if ((descriptor.interface.hasInterfaceObject() or descriptor.interface.isNavigatorProperty()) and
not descriptor.interface.isExternal() and
- descriptor.isExposedConditionally()):
+ descriptor.isExposedConditionally()):
cgThings.append(CGConstructorEnabled(descriptor))
if (descriptor.interface.hasMembersInSlots() and
- descriptor.interface.hasChildInterfaces()):
+ descriptor.interface.hasChildInterfaces()):
raise TypeError("We don't support members in slots on "
"non-leaf interfaces like %s" %
descriptor.interface.identifier.name)
if descriptor.concrete:
if descriptor.proxy:
cgThings.append(CGGeneric(fill(
"""
@@ -12620,17 +12741,17 @@ class CGDictionary(CGThing):
# If we have a union member containing something in the same
# file as us, bail: the C++ includes won't work out.
for member in dictionary.members:
type = member.type.unroll()
if type.isUnion():
for t in type.flatMemberTypes:
if (t.isDictionary() and
CGHeaders.getDeclarationFilename(t.inner) ==
- CGHeaders.getDeclarationFilename(dictionary)):
+ CGHeaders.getDeclarationFilename(dictionary)):
raise TypeError(
"Dictionary contains a union that contains a "
"dictionary in the same WebIDL file. This won't "
"compile. Move the inner dictionary to a "
"different file.\n%s\n%s" %
(t.location, t.inner.location))
self.structs = self.getStructs()
@@ -12836,23 +12957,23 @@ class CGDictionary(CGThing):
def dictionaryNeedsCycleCollection(dictionary):
return (any(idlTypeNeedsCycleCollection(m.type) for m in dictionary.members) or
(dictionary.parent and
CGDictionary.dictionaryNeedsCycleCollection(dictionary.parent)))
def traverseForCCMethod(self):
body = ""
if (self.dictionary.parent and
- self.dictionaryNeedsCycleCollection(self.dictionary.parent)):
+ self.dictionaryNeedsCycleCollection(self.dictionary.parent)):
cls = self.makeClassName(self.dictionary.parent)
body += "%s::TraverseForCC(aCallback, aFlags);\n" % cls
for m, _ in self.memberInfo:
if idlTypeNeedsCycleCollection(m.type):
- memberName = self.makeMemberName(m.identifier.name);
+ memberName = self.makeMemberName(m.identifier.name)
body += ('ImplCycleCollectionTraverse(aCallback, %s, "%s", aFlags);\n' %
(memberName, memberName))
return ClassMethod(
"TraverseForCC", "void",
[
Argument("nsCycleCollectionTraversalCallback&", "aCallback"),
Argument("uint32_t", "aFlags"),
@@ -12861,23 +12982,23 @@ class CGDictionary(CGThing):
# Inline so we don't pay a codesize hit unless someone actually uses
# this traverse method.
inline=True,
bodyInHeader=True)
def unlinkForCCMethod(self):
body = ""
if (self.dictionary.parent and
- self.dictionaryNeedsCycleCollection(self.dictionary.parent)):
+ self.dictionaryNeedsCycleCollection(self.dictionary.parent)):
cls = self.makeClassName(self.dictionary.parent)
body += "%s::UnlinkForCC();\n" % cls
for m, _ in self.memberInfo:
if idlTypeNeedsCycleCollection(m.type):
- memberName = self.makeMemberName(m.identifier.name);
+ memberName = self.makeMemberName(m.identifier.name)
body += ('ImplCycleCollectionUnlink(%s);\n' % memberName)
return ClassMethod(
"UnlinkForCC", "void", [], body=body,
# Inline so we don't pay a codesize hit unless someone actually uses
# this unlink method.
inline=True,
bodyInHeader=True)
@@ -13310,17 +13431,17 @@ class CGDictionary(CGThing):
@staticmethod
def getNonInitializingCtorArg():
return "FastDictionaryInitializer()"
@staticmethod
def isDictionaryCopyConstructible(dictionary):
if (dictionary.parent and
- not CGDictionary.isDictionaryCopyConstructible(dictionary.parent)):
+ not CGDictionary.isDictionaryCopyConstructible(dictionary.parent)):
return False
return all(isTypeCopyConstructible(m.type) for m in dictionary.members)
@staticmethod
def typeSafeToJSONify(type):
"""
Determine whether the given type is safe to convert to JSON. The
restriction is that this needs to be safe while in a global controlled
@@ -13391,16 +13512,17 @@ class CGRegisterWorkerBindings(CGAbstrac
"%s::ConstructorEnabled(aCx, aObj) && " % bindingNS
+ condition)
conditions.append(condition)
lines = [CGIfWrapper(CGGeneric("return false;\n"), condition) for
condition in conditions]
lines.append(CGGeneric("return true;\n"))
return CGList(lines, "\n").define()
+
class CGRegisterWorkerDebuggerBindings(CGAbstractMethod):
def __init__(self, config):
CGAbstractMethod.__init__(self, None, 'RegisterWorkerDebuggerBindings', 'bool',
[Argument('JSContext*', 'aCx'),
Argument('JS::Handle<JSObject*>', 'aObj')])
self.config = config
def definition_body(self):
@@ -13416,16 +13538,17 @@ class CGRegisterWorkerDebuggerBindings(C
"%s::ConstructorEnabled(aCx, aObj) && " % bindingNS
+ condition)
conditions.append(condition)
lines = [CGIfWrapper(CGGeneric("return false;\n"), condition) for
condition in conditions]
lines.append(CGGeneric("return true;\n"))
return CGList(lines, "\n").define()
+
class CGRegisterWorkletBindings(CGAbstractMethod):
def __init__(self, config):
CGAbstractMethod.__init__(self, None, 'RegisterWorkletBindings', 'bool',
[Argument('JSContext*', 'aCx'),
Argument('JS::Handle<JSObject*>', 'aObj')])
self.config = config
def definition_body(self):
@@ -13564,33 +13687,34 @@ class CGGetSystemBindingNames(CGAbstract
def getGlobalNames(config):
names = []
for desc in config.getDescriptors(registersGlobalNamesOnWindow=True):
names.append((desc.name, desc))
names.extend((n.identifier.name, desc) for n in desc.interface.namedConstructors)
return names
+
class CGGlobalNamesString(CGGeneric):
def __init__(self, config):
globalNames = getGlobalNames(config)
currentOffset = 0
strings = []
for (name, _) in globalNames:
strings.append('/* %i */ "%s\\0"' % (currentOffset, name))
- currentOffset += len(name) + 1 # Add trailing null.
+ currentOffset += len(name) + 1 # Add trailing null.
define = fill("""
const uint32_t WebIDLGlobalNameHash::sCount = ${count};
const char WebIDLGlobalNameHash::sNames[] =
$*{strings}
""",
- count=len(globalNames),
- strings="\n".join(strings) + ";\n")
+ count=len(globalNames),
+ strings="\n".join(strings) + ";\n")
CGGeneric.__init__(self, define=define)
class CGRegisterGlobalNames(CGAbstractMethod):
def __init__(self, config):
CGAbstractMethod.__init__(self, None, 'RegisterWebIDLGlobalNames',
'void', [])
@@ -13603,17 +13727,17 @@ class CGRegisterGlobalNames(CGAbstractMe
return "%s_Binding::ConstructorEnabled" % desc.name
define = ""
currentOffset = 0
for (name, desc) in getGlobalNames(self.config):
length = len(name)
define += "WebIDLGlobalNameHash::Register(%i, %i, %s_Binding::CreateInterfaceObjects, %s, constructors::id::%s);\n" % (
currentOffset, length, desc.name, getCheck(desc), desc.name)
- currentOffset += length + 1 # Add trailing null.
+ currentOffset += length + 1 # Add trailing null.
return define
def dependencySortObjects(objects, dependencyGetter, nameGetter):
"""
Sort IDL objects with dependencies on each other such that if A
depends on B then B will come before A. This is needed for
declaring C++ classes in the right order, for example. Objects
@@ -13644,16 +13768,17 @@ def dependencySortObjects(objects, depen
return sortedObjects
class ForwardDeclarationBuilder:
"""
Create a canonical representation of a set of namespaced forward
declarations.
"""
+
def __init__(self):
"""
The set of declarations is represented as a tree of nested namespaces.
Each tree node has a set of declarations |decls| and a dict |children|.
Each declaration is a pair consisting of the class name and a boolean
that is true iff the class is really a struct. |children| maps the
names of inner namespaces to the declarations in that namespace.
"""
@@ -13682,25 +13807,25 @@ class ForwardDeclarationBuilder:
assert '::' not in name
self.decls.add((name, isStruct))
def addInMozillaDom(self, name, isStruct=False):
"""
Add a forward declaration to the mozilla::dom:: namespace. |name| should not
contain any other namespaces.
"""
- self._ensureNonTemplateType(name);
+ self._ensureNonTemplateType(name)
self._listAdd(["mozilla", "dom"], name, isStruct)
def add(self, nativeType, isStruct=False):
"""
Add a forward declaration, where |nativeType| is a string containing
the type and its namespaces, in the usual C++ way.
"""
- self._ensureNonTemplateType(nativeType);
+ self._ensureNonTemplateType(nativeType)
components = nativeType.split('::')
self._listAdd(components[:-1], components[-1], isStruct)
def _build(self, atTopLevel):
"""
Return a codegenerator for the forward declarations.
"""
decls = []
@@ -13751,16 +13876,17 @@ class ForwardDeclarationBuilder:
class CGForwardDeclarations(CGWrapper):
"""
Code generate the forward declarations for a header file.
additionalDeclarations is a list of tuples containing a classname and a
boolean. If the boolean is true we will declare a struct, otherwise we'll
declare a class.
"""
+
def __init__(self, config, descriptors, callbacks,
dictionaries, callbackInterfaces, additionalDeclarations=[]):
builder = ForwardDeclarationBuilder()
# Needed for at least Wrap.
for d in descriptors:
# If this is a generated iterator interface, we only create these
# in the generated bindings, and don't need to forward declare.
@@ -13818,27 +13944,28 @@ class CGForwardDeclarations(CGWrapper):
CGWrapper.__init__(self, builder.build())
class CGBindingRoot(CGThing):
"""
Root codegen class for binding generation. Instantiate the class, and call
declare or define to generate header or cpp code (respectively).
"""
+
def __init__(self, config, prefix, webIDLFile):
bindingHeaders = dict.fromkeys((
'mozilla/dom/NonRefcountedDOMObject.h',
- ),
+ ),
True)
bindingDeclareHeaders = dict.fromkeys((
'mozilla/dom/BindingDeclarations.h',
'mozilla/dom/Nullable.h',
'mozilla/ErrorResult.h',
'GeckoProfiler.h'
- ),
+ ),
True)
descriptors = config.getDescriptors(webIDLFile=webIDLFile,
hasInterfaceOrInterfacePrototypeObject=True)
unionTypes = UnionsForFile(config, webIDLFile)
(unionHeaders, unionImplheaders, unionDeclarations, traverseMethods,
@@ -13860,17 +13987,18 @@ class CGBindingRoot(CGThing):
def hasCrossOriginProperty(m):
props = memberProperties(m, desc)
return (props.isCrossOriginMethod or
props.isCrossOriginGetter or
props.isCrossOriginSetter)
return any(hasCrossOriginProperty(m) for m in desc.interface.members)
- bindingDeclareHeaders["jsapi.h"] = any(descriptorHasCrossOriginProperties(d) for d in descriptors)
+ bindingDeclareHeaders["jsapi.h"] = any(
+ descriptorHasCrossOriginProperties(d) for d in descriptors)
bindingDeclareHeaders["jspubtd.h"] = not bindingDeclareHeaders["jsapi.h"]
bindingDeclareHeaders["js/RootingAPI.h"] = not bindingDeclareHeaders["jsapi.h"]
def descriptorRequiresPreferences(desc):
iface = desc.interface
return any(m.getExtendedAttribute("Pref") for m in iface.members + [iface])
def descriptorDeprecated(desc):
@@ -14564,17 +14692,17 @@ class CGExampleMethod(CGNativeMember):
def declare(self, cgClass):
assert self.member.isMethod()
# We skip declaring ourselves if this is a maplike/setlike/iterable
# method, because those get implemented automatically by the binding
# machinery, so the implementor of the interface doesn't have to worry
# about it.
if self.member.isMaplikeOrSetlikeOrIterableMethod():
return ''
- return CGNativeMember.declare(self, cgClass);
+ return CGNativeMember.declare(self, cgClass)
def define(self, cgClass):
return ''
class CGExampleGetter(CGNativeMember):
def __init__(self, descriptor, attr):
CGNativeMember.__init__(self, descriptor, attr,
@@ -14587,17 +14715,17 @@ class CGExampleGetter(CGNativeMember):
def declare(self, cgClass):
assert self.member.isAttr()
# We skip declaring ourselves if this is a maplike/setlike attr (in
# practice, "size"), because those get implemented automatically by the
# binding machinery, so the implementor of the interface doesn't have to
# worry about it.
if self.member.isMaplikeOrSetlikeAttr():
return ''
- return CGNativeMember.declare(self, cgClass);
+ return CGNativeMember.declare(self, cgClass)
def define(self, cgClass):
return ''
class CGExampleSetter(CGNativeMember):
def __init__(self, descriptor, attr):
CGNativeMember.__init__(self, descriptor, attr,
@@ -14611,16 +14739,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", skipStaticMethods=False):
"""
cgMethod, cgGetter and cgSetter are classes used to codegen methods,
getters and setters.
"""
self.descriptor = descriptor
self._deps = descriptor.interface.getDeps()
@@ -14771,30 +14900,33 @@ class CGBindingImplClass(CGClass):
def deps(self):
return self._deps
class CGExampleClass(CGBindingImplClass):
"""
Codegen for the actual example class implementation for this descriptor
"""
+
def __init__(self, descriptor):
CGBindingImplClass.__init__(self, descriptor,
CGExampleMethod, CGExampleGetter, CGExampleSetter,
wantGetParent=descriptor.wrapperCache)
self.parentIface = descriptor.interface.parent
if self.parentIface:
self.parentDesc = descriptor.getDescriptor(
self.parentIface.identifier.name)
bases = [ClassBase(self.nativeLeafName(self.parentDesc))]
else:
- bases = [ClassBase("nsISupports /* or NonRefcountedDOMObject if this is a non-refcounted object */")]
+ bases = [
+ ClassBase("nsISupports /* or NonRefcountedDOMObject if this is a non-refcounted object */")]
if descriptor.wrapperCache:
- bases.append(ClassBase("nsWrapperCache /* Change wrapperCache in the binding configuration if you don't want this */"))
+ bases.append(ClassBase(
+ "nsWrapperCache /* Change wrapperCache in the binding configuration if you don't want this */"))
destructorVisibility = "protected"
if self.parentIface:
extradeclarations = (
"public:\n"
" NS_DECL_ISUPPORTS_INHERITED\n"
" NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(%s, %s)\n"
"\n" % (self.nativeLeafName(descriptor),
@@ -14893,16 +15025,17 @@ class CGExampleClass(CGBindingImplClass)
class CGExampleRoot(CGThing):
"""
Root codegen class for example implementation generation. Instantiate the
class and call declare or define to generate header or cpp code,
respectively.
"""
+
def __init__(self, config, interfaceName):
descriptor = config.getDescriptor(interfaceName)
self.root = CGWrapper(CGExampleClass(descriptor),
pre="\n", post="\n")
self.root = CGNamespace.build(["mozilla", "dom"], self.root)
@@ -14964,16 +15097,17 @@ def jsImplName(name):
return name + "JSImpl"
class CGJSImplMember(CGNativeMember):
"""
Base class for generating code for the members of the implementation class
for a JS-implemented WebIDL interface.
"""
+
def __init__(self, descriptorProvider, member, name, signature,
extendedAttrs, breakAfter=True, passJSBitsAsNeeded=True,
visibility="public", variadicIsSequence=False,
virtual=False, override=False):
CGNativeMember.__init__(self, descriptorProvider, member, name,
signature, extendedAttrs, breakAfter=breakAfter,
passJSBitsAsNeeded=passJSBitsAsNeeded,
visibility=visibility,
@@ -14988,16 +15122,17 @@ class CGJSImplMember(CGNativeMember):
return args
class CGJSImplMethod(CGJSImplMember):
"""
Class for generating code for the methods for a JS-implemented WebIDL
interface.
"""
+
def __init__(self, descriptor, method, signature, isConstructor, breakAfter=True):
self.signature = signature
self.descriptor = descriptor
self.isConstructor = isConstructor
CGJSImplMember.__init__(self, descriptor, method,
CGSpecializedMethod.makeNativeName(descriptor,
method),
signature,
@@ -15017,17 +15152,18 @@ class CGJSImplMethod(CGJSImplMember):
def getImpl(self):
args = self.getArgs(self.signature[0], self.signature[1])
if not self.isConstructor:
return 'return mImpl->%s(%s);\n' % (self.name, ", ".join(arg.name for arg in args))
assert self.descriptor.interface.isJSImplemented()
if self.name != 'Constructor':
- raise TypeError("Named constructors are not supported for JS implemented WebIDL. See bug 851287.")
+ raise TypeError(
+ "Named constructors are not supported for JS implemented WebIDL. See bug 851287.")
if len(self.signature[1]) != 0:
# The first two arguments to the constructor implementation are not
# arguments to the WebIDL constructor, so don't pass them to
# __Init(). The last argument is the prototype we're supposed to
# use, and shouldn't get passed to __Init() either.
assert args[0].argType == 'const GlobalObject&'
assert args[1].argType == 'JSContext*'
assert args[-1].argType == 'JS::Handle<JSObject*>'
@@ -15087,16 +15223,17 @@ def callbackSetterName(attr, descriptor)
descriptor.binaryNameFor(attr.identifier.name))
class CGJSImplGetter(CGJSImplMember):
"""
Class for generating code for the getters of attributes for a JS-implemented
WebIDL interface.
"""
+
def __init__(self, descriptor, attr):
CGJSImplMember.__init__(self, descriptor, attr,
CGSpecializedGetter.makeNativeName(descriptor,
attr),
(attr.type, []),
descriptor.getExtendedAttributes(attr,
getter=True),
passJSBitsAsNeeded=False)
@@ -15108,16 +15245,17 @@ class CGJSImplGetter(CGJSImplMember):
", ".join(callbackArgs))
class CGJSImplSetter(CGJSImplMember):
"""
Class for generating code for the setters of attributes for a JS-implemented
WebIDL interface.
"""
+
def __init__(self, descriptor, attr):
CGJSImplMember.__init__(self, descriptor, attr,
CGSpecializedSetter.makeNativeName(descriptor,
attr),
(BuiltinTypes[IDLBuiltinType.Types.void],
[FakeArgument(attr.type, attr)]),
descriptor.getExtendedAttributes(attr,
setter=True),
@@ -15128,17 +15266,18 @@ 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, skipStaticMethods=True)
+ 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))
@@ -15244,17 +15383,17 @@ class CGJSImplClass(CGBindingImplClass):
ClassMethod("_Create",
"bool",
JSNativeArguments(),
static=True,
body=self.getCreateFromExistingBody()))
if (descriptor.interface.isJSImplemented() and
descriptor.interface.maplikeOrSetlikeOrIterable and
- descriptor.interface.maplikeOrSetlikeOrIterable.isMaplike()):
+ descriptor.interface.maplikeOrSetlikeOrIterable.isMaplike()):
self.methodDecls.append(
ClassMethod("__OnGet",
"void",
[Argument("JS::Handle<JS::Value>", "aKey"),
Argument("JS::Handle<JS::Value>", "aValue"),
Argument("ErrorResult&", "aRv")],
body="mImpl->__OnGet(aKey, aValue, aRv);\n"))
@@ -15389,17 +15528,17 @@ class CGCallback(CGClass):
body=("return %s::operator==(aOther);\n" % baseName)))
CGClass.__init__(self, self.name,
bases=[ClassBase(baseName)],
constructors=self.getConstructors(),
methods=realMethods+getters+setters)
def getConstructors(self):
if (not self.idlObject.isInterface() and
- not self.idlObject._treatNonObjectAsNull):
+ not self.idlObject._treatNonObjectAsNull):
body = "MOZ_ASSERT(JS::IsCallable(mCallback));\n"
else:
# Not much we can assert about it, other than not being null, and
# CallbackObject does that already.
body = ""
return [
ClassConstructor(
[Argument("JSContext*", "aCx"),
@@ -15478,17 +15617,17 @@ class CGCallback(CGClass):
# exception.
args.append(Argument("JS::Realm*", "aRealm", "nullptr"))
# And now insert our template argument.
argsWithoutThis = list(args)
args.insert(0, Argument("const T&", "thisVal"))
argsWithoutRv.insert(0, Argument("const T&", "thisVal"))
argnamesWithoutThisAndRv = [arg.name for arg in argsWithoutThisAndRv]
- argnamesWithoutThisAndRv.insert(rvIndex, "IgnoreErrors()");
+ argnamesWithoutThisAndRv.insert(rvIndex, "IgnoreErrors()")
# If we just leave things like that, and have no actual arguments in the
# IDL, we will end up trying to call the templated "without rv" overload
# with "rv" as the thisVal. That's no good. So explicitly append the
# aExceptionHandling and aRealm values we need to end up matching the
# signature of our non-templated "with rv" overload.
argnamesWithoutThisAndRv.extend(["eReportExceptions", "nullptr"])
argnamesWithoutRv = [arg.name for arg in argsWithoutRv]
@@ -15650,30 +15789,30 @@ class CGCallbackInterface(CGCallback):
if len(sigs) != 1:
raise TypeError("We only handle one constructor. See bug 869268.")
methods.append(CGJSImplInitOperation(sigs[0], descriptor))
needInitId = True
needOnGetId = False
if (iface.isJSImplemented() and
iface.maplikeOrSetlikeOrIterable and
- iface.maplikeOrSetlikeOrIterable.isMaplike()):
+ iface.maplikeOrSetlikeOrIterable.isMaplike()):
methods.append(CGJSImplOnGetOperation(descriptor))
needOnGetId = True
idlist = [descriptor.binaryNameFor(m.identifier.name)
for m in iface.members
if m.isAttr() or m.isMethod()]
if needInitId:
idlist.append("__init")
if needOnGetId:
idlist.append("__onget")
if (iface.isJSImplemented() and
- iface.getExtendedAttribute("WantsEventListenerHooks")):
+ iface.getExtendedAttribute("WantsEventListenerHooks")):
methods.append(CGJSImplEventHookOperation(descriptor,
"eventListenerAdded"))
methods.append(CGJSImplEventHookOperation(descriptor,
"eventListenerRemoved"))
idlist.append("eventListenerAdded")
idlist.append("eventListenerRemoved")
if len(idlist) != 0:
@@ -16024,16 +16163,17 @@ class CallCallback(CallbackMethod):
return "JS::IsCallable(mCallback) && "
return ""
class CallbackOperationBase(CallbackMethod):
"""
Common class for implementing various callback operations.
"""
+
def __init__(self, signature, jsName, nativeName, descriptor,
singleOperation, rethrowContentException=False,
spiderMonkeyInterfacesAreStructs=False):
self.singleOperation = singleOperation
self.methodName = descriptor.binaryNameFor(jsName)
CallbackMethod.__init__(self, signature, nativeName, descriptor,
singleOperation, rethrowContentException,
spiderMonkeyInterfacesAreStructs=spiderMonkeyInterfacesAreStructs)
@@ -16082,16 +16222,17 @@ class CallbackOperationBase(CallbackMeth
def getCallGuard(self):
return ""
class CallbackOperation(CallbackOperationBase):
"""
Codegen actual WebIDL operations on callback interfaces.
"""
+
def __init__(self, method, signature, descriptor,
spiderMonkeyInterfacesAreStructs):
self.ensureASCIIName(method)
self.method = method
jsName = method.identifier.name
CallbackOperationBase.__init__(self, signature,
jsName,
MakeNativeName(descriptor.binaryNameFor(jsName)),
@@ -16103,16 +16244,17 @@ class CallbackOperation(CallbackOperatio
return "%s.%s" % (self.descriptorProvider.interface.identifier.name,
self.method.identifier.name)
class CallbackAccessor(CallbackMember):
"""
Shared superclass for CallbackGetter and CallbackSetter.
"""
+
def __init__(self, attr, sig, name, descriptor,
spiderMonkeyInterfacesAreStructs):
self.ensureASCIIName(attr)
self.attrName = attr.identifier.name
CallbackMember.__init__(self, sig, name, descriptor,
needThisHandling=False,
rethrowContentException=descriptor.interface.isJSImplemented(),
spiderMonkeyInterfacesAreStructs=spiderMonkeyInterfacesAreStructs)
@@ -16140,17 +16282,18 @@ class CallbackGetter(CallbackAccessor):
${atomCacheName}* atomsCache = GetAtomCache<${atomCacheName}>(cx);
if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
!JS_GetPropertyById(cx, callback, atomsCache->${attrAtomName}, &rval)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return${errorReturn};
}
""",
atomCacheName=self.descriptorProvider.interface.identifier.name + "Atoms",
- attrAtomName=CGDictionary.makeIdName(self.descriptorProvider.binaryNameFor(self.attrName)),
+ attrAtomName=CGDictionary.makeIdName(
+ self.descriptorProvider.binaryNameFor(self.attrName)),
errorReturn=self.getDefaultRetval())
class CallbackSetter(CallbackAccessor):
def __init__(self, attr, descriptor, spiderMonkeyInterfacesAreStructs):
CallbackAccessor.__init__(self, attr,
(BuiltinTypes[IDLBuiltinType.Types.void],
[FakeArgument(attr.type, attr)]),
@@ -16168,27 +16311,29 @@ class CallbackSetter(CallbackAccessor):
${atomCacheName}* atomsCache = GetAtomCache<${atomCacheName}>(cx);
if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
!JS_SetPropertyById(cx, CallbackKnownNotGray(), atomsCache->${attrAtomName}, argv[0])) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return${errorReturn};
}
""",
atomCacheName=self.descriptorProvider.interface.identifier.name + "Atoms",
- attrAtomName=CGDictionary.makeIdName(self.descriptorProvider.binaryNameFor(self.attrName)),
+ attrAtomName=CGDictionary.makeIdName(
+ self.descriptorProvider.binaryNameFor(self.attrName)),
errorReturn=self.getDefaultRetval())
def getArgcDecl(self):
return None
class CGJSImplInitOperation(CallbackOperationBase):
"""
Codegen the __Init() method used to pass along constructor arguments for JS-implemented WebIDL.
"""
+
def __init__(self, sig, descriptor):
assert sig in descriptor.interface.ctor().signatures()
CallbackOperationBase.__init__(self, (BuiltinTypes[IDLBuiltinType.Types.void], sig[1]),
"__init", "__Init", descriptor,
singleOperation=False,
rethrowContentException=True,
spiderMonkeyInterfacesAreStructs=True)
@@ -16197,16 +16342,17 @@ class CGJSImplInitOperation(CallbackOper
class CGJSImplOnGetOperation(CallbackOperationBase):
"""
Codegen the __OnGet() method used to notify the JS impl that a get() is
happening on a JS-implemented maplike. This method takes two arguments
(key and value) and returns nothing.
"""
+
def __init__(self, descriptor):
CallbackOperationBase.__init__(
self,
(BuiltinTypes[IDLBuiltinType.Types.void],
[FakeArgument(BuiltinTypes[IDLBuiltinType.Types.any],
None,
"key"),
FakeArgument(BuiltinTypes[IDLBuiltinType.Types.any],
@@ -16216,20 +16362,22 @@ class CGJSImplOnGetOperation(CallbackOpe
descriptor,
singleOperation=False,
rethrowContentException=True,
spiderMonkeyInterfacesAreStructs=True)
def getPrettyName(self):
return "__onget"
+
class CGJSImplEventHookOperation(CallbackOperationBase):
"""
Codegen the hooks on a JS impl for adding/removing event listeners.
"""
+
def __init__(self, descriptor, name):
self.name = name
CallbackOperationBase.__init__(
self,
(BuiltinTypes[IDLBuiltinType.Types.void],
[FakeArgument(BuiltinTypes[IDLBuiltinType.Types.domstring],
None,
@@ -16238,16 +16386,17 @@ class CGJSImplEventHookOperation(Callbac
descriptor,
singleOperation=False,
rethrowContentException=False,
spiderMonkeyInterfacesAreStructs=True)
def getPrettyName(self):
return self.name
+
def getMaplikeOrSetlikeErrorReturn(helperImpl):
"""
Generate return values based on whether a maplike or setlike generated
method is an interface method (which returns bool) or a helper function
(which uses ErrorResult).
"""
if helperImpl:
return dedent(
@@ -16305,16 +16454,17 @@ def getMaplikeOrSetlikeSizeGetterBody(de
class CGMaplikeOrSetlikeMethodGenerator(CGThing):
"""
Creates methods for maplike/setlike interfaces. It is expected that all
methods will be have a maplike/setlike object attached. Unwrapping/wrapping
will be taken care of by the usual method generation machinery in
CGMethodCall/CGPerSignatureCall. Functionality is filled in here instead of
using CGCallGenerator.
"""
+
def __init__(self, descriptor, maplikeOrSetlike, methodName,
helperImpl=None):
CGThing.__init__(self)
# True if this will be the body of a C++ helper function.
self.helperImpl = helperImpl
self.descriptor = descriptor
self.maplikeOrSetlike = maplikeOrSetlike
self.cgRoot = CGList([])
@@ -16607,16 +16757,17 @@ class CGMaplikeOrSetlikeHelperFunctionGe
"""
class HelperFunction(CGAbstractMethod):
"""
Generates context retrieval code and rooted JSObject for interface for
CGMaplikeOrSetlikeMethodGenerator to use
"""
+
def __init__(self, descriptor, name, args, code, needsBoolReturn=False):
self.code = code
CGAbstractMethod.__init__(self, descriptor, name,
"bool" if needsBoolReturn else "void",
args)
def definition_body(self):
return self.code
@@ -16709,23 +16860,25 @@ class CGMaplikeOrSetlikeHelperFunctionGe
class CGMaplikeOrSetlikeHelperGenerator(CGNamespace):
"""
Declares and defines convenience methods for accessing backing objects on
setlike/maplike interface. Generates function signatures, un/packs
backing objects from slot, etc.
"""
+
def __init__(self, descriptor, maplikeOrSetlike):
self.descriptor = descriptor
# Since iterables are folded in with maplike/setlike, make sure we've
# got the right type here.
assert maplikeOrSetlike.isMaplike() or maplikeOrSetlike.isSetlike()
self.maplikeOrSetlike = maplikeOrSetlike
- self.namespace = "%sHelpers" % (self.maplikeOrSetlike.maplikeOrSetlikeOrIterableType.title())
+ self.namespace = "%sHelpers" % (
+ self.maplikeOrSetlike.maplikeOrSetlikeOrIterableType.title())
self.helpers = [
CGMaplikeOrSetlikeHelperFunctionGenerator(descriptor,
maplikeOrSetlike,
"Clear"),
CGMaplikeOrSetlikeHelperFunctionGenerator(descriptor,
maplikeOrSetlike,
"Delete",
needsKeyArg=True,
@@ -16754,16 +16907,17 @@ class CGMaplikeOrSetlikeHelperGenerator(
class CGIterableMethodGenerator(CGGeneric):
"""
Creates methods for iterable interfaces. Unwrapping/wrapping
will be taken care of by the usual method generation machinery in
CGMethodCall/CGPerSignatureCall. Functionality is filled in here instead of
using CGCallGenerator.
"""
+
def __init__(self, descriptor, iterable, methodName):
if methodName == "forEach":
CGGeneric.__init__(self, fill(
"""
if (!JS::IsCallable(arg0)) {
ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 1 of ${ifaceName}.forEach");
return false;
}
@@ -16836,21 +16990,21 @@ class GlobalGenRoots():
for d in (config.getDescriptors(isJSImplemented=True) +
config.getDescriptors(isCallback=True)):
members = [m for m in d.interface.members if m.isAttr() or m.isMethod()]
if d.interface.isJSImplemented() and d.interface.ctor():
# We'll have an __init() method.
members.append(FakeMember('__init'))
if (d.interface.isJSImplemented() and
d.interface.maplikeOrSetlikeOrIterable and
- d.interface.maplikeOrSetlikeOrIterable.isMaplike()):
+ d.interface.maplikeOrSetlikeOrIterable.isMaplike()):
# We'll have an __onget() method.
members.append(FakeMember('__onget'))
if (d.interface.isJSImplemented() and
- d.interface.getExtendedAttribute("WantsEventListenerHooks")):
+ d.interface.getExtendedAttribute("WantsEventListenerHooks")):
members.append(FakeMember('eventListenerAdded'))
members.append(FakeMember('eventListenerRemoved'))
if len(members) == 0:
continue
structs.append(buildAtomCacheStructure(d.interface,
lambda x: d.binaryNameFor(x),
members))
@@ -16917,17 +17071,18 @@ class GlobalGenRoots():
curr = CGList([CGGeneric(define="#include <stdint.h>\n\n"),
CGGeneric(define='#include "jsfriendapi.h"\n\n'),
CGGeneric(define='#include "mozilla/dom/PrototypeList.h"\n\n'),
idEnum])
# Let things know the maximum length of the prototype chain.
maxMacroName = "MAX_PROTOTYPE_CHAIN_LENGTH"
- maxMacro = CGGeneric(declare="#define " + maxMacroName + " " + str(config.maxProtoChainLength))
+ maxMacro = CGGeneric(declare="#define " + maxMacroName +
+ " " + str(config.maxProtoChainLength))
curr.append(CGWrapper(maxMacro, post='\n\n'))
curr.append(fieldSizeAssert(maxMacroName, "depth",
"Some inheritance chain is too long!"))
# Constructor ID enum.
constructors = [d.name for d in config.getDescriptors(hasInterfaceObject=True)]
idEnum = CGNamespacedEnum('id', 'ID', ['_ID_Start'] + constructors,
['prototypes::id::_ID_Count', '_ID_Start'])
@@ -16935,17 +17090,18 @@ class GlobalGenRoots():
# Wrap all of that in our namespaces.
idEnum = CGNamespace.build(['mozilla', 'dom', 'constructors'],
CGWrapper(idEnum, pre='\n'))
idEnum = CGWrapper(idEnum, post='\n')
curr.append(idEnum)
# Named properties object enum.
- namedPropertiesObjects = [d.name for d in config.getDescriptors(hasNamedPropertiesObject=True)]
+ namedPropertiesObjects = [
+ d.name for d in config.getDescriptors(hasNamedPropertiesObject=True)]
idEnum = CGNamespacedEnum('id', 'ID', ['_ID_Start'] + namedPropertiesObjects,
['constructors::id::_ID_Count', '_ID_Start'])
# Wrap all of that in our namespaces.
idEnum = CGNamespace.build(['mozilla', 'dom', 'namedpropertiesobjects'],
CGWrapper(idEnum, pre='\n'))
idEnum = CGWrapper(idEnum, post='\n')
@@ -17109,17 +17265,17 @@ class GlobalGenRoots():
};
static SystemProperty properties[] = {
$*{init}
};
static bool idsInited = false;
""",
- init="".join(initValues))))
+ init="".join(initValues))))
curr.append(CGSystemBindingInitIds())
curr.append(CGResolveSystemBinding())
curr.append(CGMayResolveAsSystemBindingName())
curr.append(CGGetSystemBindingNames())
# Wrap all of that in our namespaces.
curr = CGNamespace.build(['mozilla', 'dom'],
@@ -17233,17 +17389,17 @@ class CGEventGetter(CGNativeMember):
return CGNativeMember.getArgs(self, returnType, argList)
def getMethodBody(self):
type = self.member.type
memberName = CGDictionary.makeMemberName(self.member.identifier.name)
if ((type.isPrimitive() and type.tag() in builtinNames) or
type.isEnum() or
type.isPromise() or
- type.isGeckoInterface()):
+ type.isGeckoInterface()):
return "return " + memberName + ";\n"
if type.isDOMString() or type.isByteString() or type.isUSVString():
return "aRetVal = " + memberName + ";\n"
if type.isSpiderMonkeyInterface() or type.isObject():
return fill(
"""
if (${memberName}) {
JS::ExposeObjectToActiveJS(${memberName});
@@ -17302,17 +17458,17 @@ class CGEventMethod(CGNativeMember):
# We could check the arg types but it's not worth the effort.
if (method.identifier.name == "init" + iface.identifier.name and
signature[1][0].type.isDOMString() and
signature[1][1].type.isBoolean() and
signature[1][2].type.isBoolean() and
# -3 on the left to ignore the type, bubbles, and cancelable parameters
# -1 on the right to ignore the .trusted property which bleeds through
# here because it is [Unforgeable].
- len(signature[1]) - 3 == len(filter(lambda x: x.isAttr(), iface.members)) - 1):
+ len(signature[1]) - 3 == len(filter(lambda x: x.isAttr(), iface.members)) - 1):
allowed = True
self.isInit = True
if not allowed:
raise TypeError("Event code generator does not support methods!")
def getArgs(self, returnType, argList):
args = [self.getArg(arg) for arg in argList]
@@ -17467,18 +17623,20 @@ class CGEventMethod(CGNativeMember):
self.args.append(Argument('ErrorResult&', 'aRv'))
return constructorForNativeCaller + CGNativeMember.define(self, cgClass)
class CGEventClass(CGBindingImplClass):
"""
Codegen for the actual Event class implementation for this descriptor
"""
+
def __init__(self, descriptor):
- CGBindingImplClass.__init__(self, descriptor, CGEventMethod, CGEventGetter, CGEventSetter, False, "WrapObjectInternal")
+ CGBindingImplClass.__init__(self, descriptor, CGEventMethod,
+ CGEventGetter, CGEventSetter, False, "WrapObjectInternal")
members = []
extraMethods = []
self.membersNeedingCC = []
self.membersNeedingTrace = []
for m in descriptor.interface.members:
if getattr(m, "originatingInterface",
descriptor.interface) != descriptor.interface:
@@ -17512,22 +17670,23 @@ class CGEventClass(CGBindingImplClass):
raise TypeError(
"Need to implement tracing for event member of type %s" %
m.type)
elif idlTypeNeedsCycleCollection(m.type):
self.membersNeedingCC.append(m)
nativeType = self.getNativeTypeForIDLType(m.type).define()
members.append(ClassMember(CGDictionary.makeMemberName(m.identifier.name),
- nativeType,
- visibility="private",
- body="body"))
+ nativeType,
+ visibility="private",
+ body="body"))
parent = self.descriptor.interface.parent
- self.parentType = self.descriptor.getDescriptor(parent.identifier.name).nativeType.split('::')[-1]
+ self.parentType = self.descriptor.getDescriptor(
+ parent.identifier.name).nativeType.split('::')[-1]
self.nativeType = self.descriptor.nativeType.split('::')[-1]
if self.needCC():
isupportsDecl = fill(
"""
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(${nativeType}, ${parentType})
""",
@@ -17711,17 +17870,17 @@ class CGEventClass(CGBindingImplClass):
nativeType = CGGeneric(CGUnionStruct.unionTypeDecl(type, True))
elif type.isSequence():
if type.nullable():
innerType = type.inner.inner
else:
innerType = type.inner
if (not innerType.isPrimitive() and not innerType.isEnum() and
not innerType.isDOMString() and not innerType.isByteString() and
- not innerType.isPromise() and not innerType.isGeckoInterface()):
+ not innerType.isPromise() and not innerType.isGeckoInterface()):
raise TypeError("Don't know how to properly manage GC/CC for "
"event member of type %s" %
type)
nativeType = CGTemplatedType(
"nsTArray",
self.getNativeTypeForIDLType(innerType))
if type.nullable():
nativeType = CGTemplatedType("Nullable", nativeType)
@@ -17752,17 +17911,17 @@ class CGEventRoot(CGThing):
[],
[],
[
config.getDescriptor(parent).headerFile,
"mozilla/Attributes.h",
"mozilla/ErrorResult.h",
"mozilla/dom/%sBinding.h" % interfaceName,
'mozilla/dom/BindingUtils.h',
- ],
+ ],
[
"%s.h" % interfaceName,
"js/GCAPI.h",
'mozilla/dom/Nullable.h',
],
"", self.root, config)
# And now some include guards
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -277,41 +277,41 @@ class IDLScope(IDLObject):
assert object
self._dict[identifier.name] = object
def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject):
if (isinstance(originalObject, IDLExternalInterface) and
isinstance(newObject, IDLExternalInterface) and
- originalObject.identifier.name == newObject.identifier.name):
+ originalObject.identifier.name == newObject.identifier.name):
return originalObject
if (isinstance(originalObject, IDLExternalInterface) or
- isinstance(newObject, IDLExternalInterface)):
+ isinstance(newObject, IDLExternalInterface)):
raise WebIDLError(
"Name collision between "
"interface declarations for identifier '%s' at '%s' and '%s'"
% (identifier.name,
originalObject.location, newObject.location), [])
if (isinstance(originalObject, IDLDictionary) or
- isinstance(newObject, IDLDictionary)):
+ isinstance(newObject, IDLDictionary)):
raise WebIDLError(
"Name collision between dictionary declarations for "
"identifier '%s'.\n%s\n%s"
% (identifier.name,
originalObject.location, newObject.location), [])
# We do the merging of overloads here as opposed to in IDLInterface
# because we need to merge overloads of NamedConstructors and we need to
# detect conflicts in those across interfaces. See also the comment in
# IDLInterface.addExtendedAttributes for "NamedConstructor".
if (isinstance(originalObject, IDLMethod) and
- isinstance(newObject, IDLMethod)):
+ isinstance(newObject, IDLMethod)):
return originalObject.addOverload(newObject)
# Default to throwing, derived classes can override.
conflictdesc = "\n\t%s at %s\n\t%s at %s" % (originalObject,
originalObject.location,
newObject,
newObject.location)
@@ -363,17 +363,17 @@ class IDLUnresolvedIdentifier(IDLObject)
raise WebIDLError("__noSuchMethod__ is deprecated", [location])
if name[:2] == "__" and name != "__content" and not allowDoubleUnderscore:
raise WebIDLError("Identifiers beginning with __ are reserved",
[location])
if name[0] == '_' and not allowDoubleUnderscore:
name = name[1:]
if (name in ["constructor", "toString"] and
- not allowForbidden):
+ not allowForbidden):
raise WebIDLError("Cannot use reserved identifier '%s'" % (name),
[location])
self.name = name
def __str__(self):
return self.QName()
@@ -642,17 +642,17 @@ class IDLPartialInterfaceOrNamespace(IDL
"interface" % identifier,
[attr.location])
def finish(self, scope):
if self._finished:
return
self._finished = True
if (not self._haveSecureContextExtendedAttribute and
- self._nonPartialInterfaceOrNamespace.getExtendedAttribute("SecureContext")):
+ self._nonPartialInterfaceOrNamespace.getExtendedAttribute("SecureContext")):
# This gets propagated to all our members.
for member in self.members:
if member.getExtendedAttribute("SecureContext"):
raise WebIDLError("[SecureContext] specified on both a "
"partial interface member and on the "
"non-partial interface",
[member.location,
self._nonPartialInterfaceOrNamespace.location])
@@ -843,17 +843,17 @@ class IDLInterfaceOrNamespace(IDLObjectW
self.parent.finish(scope)
self.parent._hasChildInterfaces = True
self.totalMembersInSlots = self.parent.totalMembersInSlots
# Interfaces with [Global] or [PrimaryGlobal] must not
# have anything inherit from them
if (self.parent.getExtendedAttribute("Global") or
- self.parent.getExtendedAttribute("PrimaryGlobal")):
+ self.parent.getExtendedAttribute("PrimaryGlobal")):
# Note: This is not a self.parent.isOnGlobalProtoChain() check
# because ancestors of a [Global] interface can have other
# descendants.
raise WebIDLError("[Global] interface has another interface "
"inheriting from it",
[self.location, self.parent.location])
# Make sure that we're not exposed in places where our parent is not
@@ -880,28 +880,28 @@ class IDLInterfaceOrNamespace(IDLObjectW
"callback interface %s" %
(self.identifier.name,
self.parent.identifier.name),
[self.location, self.parent.location])
# Interfaces which have interface objects can't inherit
# from [NoInterfaceObject] interfaces.
if (self.parent.getExtendedAttribute("NoInterfaceObject") and
- not self.getExtendedAttribute("NoInterfaceObject")):
+ not self.getExtendedAttribute("NoInterfaceObject")):
raise WebIDLError("Interface %s does not have "
"[NoInterfaceObject] but inherits from "
"interface %s which does" %
(self.identifier.name,
self.parent.identifier.name),
[self.location, self.parent.location])
# Interfaces that are not [SecureContext] can't inherit
# from [SecureContext] interfaces.
if (self.parent.getExtendedAttribute("SecureContext") and
- not self.getExtendedAttribute("SecureContext")):
+ not self.getExtendedAttribute("SecureContext")):
raise WebIDLError("Interface %s does not have "
"[SecureContext] but inherits from "
"interface %s which does" %
(self.identifier.name,
self.parent.identifier.name),
[self.location, self.parent.location])
for iface in self.implementedInterfaces:
@@ -989,17 +989,17 @@ class IDLInterfaceOrNamespace(IDLObjectW
(member.identifier.name, self),
[additionalMember.location, member.location])
self.members.extend(additionalMembers)
iface.interfacesImplementingSelf.add(self)
for ancestor in self.getInheritedInterfaces():
ancestor.interfacesBasedOnSelf.add(self)
if (ancestor.maplikeOrSetlikeOrIterable is not None and
- self.maplikeOrSetlikeOrIterable is not None):
+ self.maplikeOrSetlikeOrIterable is not None):
raise WebIDLError("Cannot have maplike/setlike on %s that "
"inherits %s, which is already "
"maplike/setlike" %
(self.identifier.name,
ancestor.identifier.name),
[self.maplikeOrSetlikeOrIterable.location,
ancestor.maplikeOrSetlikeOrIterable.location])
for ancestorConsequential in ancestor.getConsequentialInterfaces():
@@ -1029,17 +1029,17 @@ class IDLInterfaceOrNamespace(IDLObjectW
raise WebIDLError("Unforgeable interface %s has a valueOf "
"member so we won't be able to add one "
"ourselves" % self.identifier.name,
[self.location, m.location])
for member in self.members:
if ((member.isAttr() or member.isMethod()) and
member.isUnforgeable() and
- not hasattr(member, "originatingInterface")):
+ not hasattr(member, "originatingInterface")):
member.originatingInterface = self
# Compute slot indices for our members before we pull in unforgeable
# members from our parent. Also, maplike/setlike declarations get a
# slot to hold their backing object.
for member in self.members:
if ((member.isAttr() and
(member.getExtendedAttribute("StoreInSlot") or
@@ -1238,17 +1238,17 @@ class IDLInterfaceOrNamespace(IDLObjectW
self.identifier.name,
[self.location, member.location])
# Check that PutForwards refers to another attribute and that no
# cycles exist in forwarded assignments. Also check for a
# integer-typed "length" attribute.
if member.isAttr():
if (member.identifier.name == "length" and
- member.type.isInteger()):
+ member.type.isInteger()):
hasLengthAttribute = True
iface = self
attr = member
putForwards = attr.getExtendedAttribute("PutForwards")
if putForwards and self.isCallback():
raise WebIDLError("[PutForwards] used on an attribute "
"on interface %s which is a callback "
@@ -1256,17 +1256,17 @@ class IDLInterfaceOrNamespace(IDLObjectW
[self.location, member.location])
while putForwards is not None:
forwardIface = attr.type.unroll().inner
fowardAttr = None
for forwardedMember in forwardIface.members:
if (not forwardedMember.isAttr() or
- forwardedMember.identifier.name != putForwards[0]):
+ forwardedMember.identifier.name != putForwards[0]):
continue
if forwardedMember == member:
raise WebIDLError("Cycle detected in forwarded "
"assignments for attribute %s on "
"%s" %
(member.identifier.name, self),
[member.location])
fowardAttr = forwardedMember
@@ -1292,17 +1292,17 @@ class IDLInterfaceOrNamespace(IDLObjectW
if self.isOnGlobalProtoChain():
raise WebIDLError("[Alias] must not be used on a "
"[Global] interface operation",
[member.location])
if (member.getExtendedAttribute("Exposed") or
member.getExtendedAttribute("ChromeOnly") or
member.getExtendedAttribute("Pref") or
member.getExtendedAttribute("Func") or
- member.getExtendedAttribute("SecureContext")):
+ member.getExtendedAttribute("SecureContext")):
raise WebIDLError("[Alias] must not be used on a "
"conditionally exposed operation",
[member.location])
if member.isStatic():
raise WebIDLError("[Alias] must not be used on a "
"static operation",
[member.location])
if member.isIdentifierLess():
@@ -1317,30 +1317,29 @@ class IDLInterfaceOrNamespace(IDLObjectW
checkDuplicateNames(member, alias, "Alias")
# Check that the name of a [BindingAlias] doesn't conflict with an
# interface member.
if member.isAttr():
for bindingAlias in member.bindingAliases:
checkDuplicateNames(member, bindingAlias, "BindingAlias")
-
if (self.getExtendedAttribute("Pref") and
- self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
+ self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
raise WebIDLError("[Pref] used on an interface that is not %s-only" %
self.parentScope.primaryGlobalName,
[self.location])
# Conditional exposure makes no sense for interfaces with no
# interface object, unless they're navigator properties.
# And SecureContext makes sense for interfaces with no interface object,
# since it is also propagated to interface members.
if (self.isExposedConditionally(exclusions=["SecureContext"]) and
not self.hasInterfaceObject() and
- not self.isNavigatorProperty()):
+ not self.isNavigatorProperty()):
raise WebIDLError("Interface with no interface object is "
"exposed conditionally",
[self.location])
# Value iterators are only allowed on interfaces with indexed getters,
# and pair iterators are only allowed on interfaces without indexed
# getters.
if self.isIterable():
@@ -1538,30 +1537,34 @@ class IDLInterfaceOrNamespace(IDLObjectW
def getNavigatorProperty(self):
naviProp = self.getExtendedAttribute("NavigatorProperty")
if not naviProp:
return None
assert len(naviProp) == 1
assert isinstance(naviProp, list)
assert len(naviProp[0]) != 0
- conditionExtendedAttributes = self._extendedAttrDict.viewkeys() & IDLInterfaceOrNamespace.conditionExtendedAttributes
+ conditionExtendedAttributes = self._extendedAttrDict.viewkeys(
+ ) & IDLInterfaceOrNamespace.conditionExtendedAttributes
attr = IDLAttribute(self.location,
- IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), naviProp[0]),
- IDLUnresolvedType(self.location, IDLUnresolvedIdentifier(self.location, self.identifier.name)),
+ IDLUnresolvedIdentifier(BuiltinLocation(
+ "<auto-generated-identifier>"), naviProp[0]),
+ IDLUnresolvedType(self.location, IDLUnresolvedIdentifier(
+ self.location, self.identifier.name)),
True,
- extendedAttrDict={ a: self._extendedAttrDict[a] for a in conditionExtendedAttributes },
+ extendedAttrDict={a: self._extendedAttrDict[a]
+ for a in conditionExtendedAttributes},
navigatorObjectGetter=True)
attr._exposureGlobalNames = self._exposureGlobalNames
# We're abusing Constant a little bit here, because we need Cached. The
# getter will create a new object every time, but we're never going to
# clear the cached value.
- extendedAttrs = [ IDLExtendedAttribute(self.location, ("Throws", )),
- IDLExtendedAttribute(self.location, ("Cached", )),
- IDLExtendedAttribute(self.location, ("Constant", )) ]
+ extendedAttrs = [IDLExtendedAttribute(self.location, ("Throws", )),
+ IDLExtendedAttribute(self.location, ("Cached", )),
+ IDLExtendedAttribute(self.location, ("Constant", ))]
attr.addExtendedAttributes(extendedAttrs)
return attr
def hasChildInterfaces(self):
return self._hasChildInterfaces
def isOnGlobalProtoChain(self):
return self._isOnGlobalProtoChain
@@ -1571,21 +1574,23 @@ class IDLInterfaceOrNamespace(IDLObjectW
deps.update(self.implementedInterfaces)
if self.parent:
deps.add(self.parent)
return deps
def hasMembersInSlots(self):
return self._ownMembersInSlots != 0
- conditionExtendedAttributes = [ "Pref", "ChromeOnly", "Func",
- "SecureContext" ]
+ conditionExtendedAttributes = ["Pref", "ChromeOnly", "Func",
+ "SecureContext"]
+
def isExposedConditionally(self, exclusions=[]):
return any(((not a in exclusions) and self.getExtendedAttribute(a)) for a in self.conditionExtendedAttributes)
+
class IDLInterface(IDLInterfaceOrNamespace):
def __init__(self, location, parentScope, name, parent, members,
isKnownNonPartial, classNameOverride=None,
toStringTag=None):
IDLInterfaceOrNamespace.__init__(self, location, parentScope, name,
parent, members, isKnownNonPartial,
toStringTag)
self.classNameOverride = classNameOverride
@@ -1908,17 +1913,17 @@ class IDLDictionary(IDLObjectWithScope):
the memberType argument, to the dictionary being validated,
if the boolean value in the first element is True.
None, if the boolean value in the first element is False.
"""
if (memberType.nullable() or
memberType.isSequence() or
- memberType.isRecord()):
+ memberType.isRecord()):
return typeContainsDictionary(memberType.inner, dictionary)
if memberType.isDictionary():
if memberType.inner == dictionary:
return (True, [memberType.location])
(contains, locations) = dictionaryContainsDictionary(memberType.inner,
dictionary)
@@ -1938,17 +1943,18 @@ class IDLDictionary(IDLObjectWithScope):
(contains, locations) = typeContainsDictionary(member.type, dictionary)
if contains:
return (True, [member.location] + locations)
if dictMember.parent:
if dictMember.parent == dictionary:
return (True, [dictMember.location])
else:
- (contains, locations) = dictionaryContainsDictionary(dictMember.parent, dictionary)
+ (contains, locations) = dictionaryContainsDictionary(
+ dictMember.parent, dictionary)
if contains:
return (True, [dictMember.location] + locations)
return (False, None)
for member in self.members:
if member.type.isDictionary() and member.type.nullable():
raise WebIDLError("Dictionary %s has member with nullable "
@@ -2037,17 +2043,17 @@ class IDLType(IDLObject):
'interface',
'dictionary',
'enum',
'callback',
'union',
'sequence',
'record',
'promise',
- )
+ )
def __init__(self, location, name):
IDLObject.__init__(self, location)
self.name = name
self.builtin = False
def __eq__(self, other):
return other and self.builtin == other.builtin and self.name == other.name
@@ -2869,17 +2875,17 @@ class IDLWrapperType(IDLType):
assert self.isInterface() or self.isEnum() or self.isDictionary()
if self.isEnum():
return (other.isPrimitive() or other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
other.isSequence() or other.isRecord() or other.isDate())
if self.isDictionary() and other.nullable():
return False
if (other.isPrimitive() or other.isString() or other.isEnum() or
- other.isDate() or other.isSequence()):
+ other.isDate() or other.isSequence()):
return True
if self.isDictionary():
return other.isNonCallbackInterface()
assert self.isInterface()
if other.isInterface():
if other.isSpiderMonkeyInterface():
# Just let |other| handle things
@@ -2887,17 +2893,17 @@ class IDLWrapperType(IDLType):
assert self.isGeckoInterface() and other.isGeckoInterface()
if self.inner.isExternal() or other.unroll().inner.isExternal():
return self != other
return (len(self.inner.interfacesBasedOnSelf &
other.unroll().inner.interfacesBasedOnSelf) == 0 and
(self.isNonCallbackInterface() or
other.isNonCallbackInterface()))
if (other.isDictionary() or other.isCallback() or
- other.isRecord()):
+ other.isRecord()):
return self.isNonCallbackInterface()
# Not much else |other| can be
assert other.isObject()
return False
def isExposedInAllOf(self, exposureSet):
if not self.isInterface():
@@ -3009,17 +3015,17 @@ class IDLBuiltinType(IDLType):
'Uint8ClampedArray',
'Int16Array',
'Uint16Array',
'Int32Array',
'Uint32Array',
'Float32Array',
'Float64Array',
'ReadableStream',
- )
+ )
TagLookup = {
Types.byte: IDLType.Tags.int8,
Types.octet: IDLType.Tags.uint8,
Types.short: IDLType.Tags.int16,
Types.unsigned_short: IDLType.Tags.uint16,
Types.long: IDLType.Tags.int32,
Types.unsigned_long: IDLType.Tags.uint32,
@@ -3186,16 +3192,17 @@ class IDLBuiltinType(IDLType):
# except ArrayBufferView and the same type of typed
# array
(self.isTypedArray() and not other.isArrayBufferView() and not
(other.isTypedArray() and other.name == self.name)))))
def _getDependentObjects(self):
return set()
+
BuiltinTypes = {
IDLBuiltinType.Types.byte:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Byte",
IDLBuiltinType.Types.byte),
IDLBuiltinType.Types.octet:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Octet",
IDLBuiltinType.Types.octet),
IDLBuiltinType.Types.short:
@@ -3309,22 +3316,24 @@ integerTypeSizes = {
def matchIntegerValueToType(value):
for type, extremes in integerTypeSizes.items():
(min, max) = extremes
if value <= max and value >= min:
return BuiltinTypes[type]
return None
+
class NoCoercionFoundError(WebIDLError):
"""
A class we use to indicate generic coercion failures because none of the
types worked out in IDLValue.coerceToType.
"""
+
class IDLValue(IDLObject):
def __init__(self, location, type, value):
IDLObject.__init__(self, location)
self.type = type
assert isinstance(type, IDLType)
self.value = value
@@ -3350,17 +3359,17 @@ class IDLValue(IDLObject):
# Make sure to propagate out WebIDLErrors that are not the
# generic "hey, we could not coerce to this type at all"
# exception, because those are specific "coercion failed for
# reason X" exceptions. Note that we want to swallow
# non-WebIDLErrors here, because those can just happen if
# "type" is not something that can have a default value at
# all.
if (isinstance(e, WebIDLError) and
- not isinstance(e, NoCoercionFoundError)):
+ not isinstance(e, NoCoercionFoundError)):
raise e
# If the type allows null, rerun this matching on the inner type, except
# nullable enums. We handle those specially, because we want our
# default string values to stay strings even when assigned to a nullable
# enum.
elif type.nullable() and not type.isEnum():
innerValue = self.coerceToType(type.inner, location)
@@ -3432,17 +3441,17 @@ class IDLNullValue(IDLObject):
self.type = None
self.value = None
def coerceToType(self, type, location):
if (not isinstance(type, IDLNullableType) and
not (type.isUnion() and type.hasNullableType) and
not (type.isUnion() and type.hasDictionaryType()) and
not type.isDictionary() and
- not type.isAny()):
+ not type.isAny()):
raise WebIDLError("Cannot coerce null value to type %s." % type,
[location])
nullValue = IDLNullValue(self.location)
if type.isUnion() and not type.nullable() and type.hasDictionaryType():
# We're actually a default value for the union's dictionary member.
# Use its type.
for t in type.flatMemberTypes:
@@ -3563,17 +3572,17 @@ class IDLInterfaceMember(IDLObjectWithId
# 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._globalScope.primaryGlobalName])):
+ self.exposureSet != set([self._globalScope.primaryGlobalName])):
raise WebIDLError("[Pref] used on an interface member that is not "
"%s-only" % 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. "
@@ -3581,17 +3590,17 @@ class IDLInterfaceMember(IDLObjectWithId
[self.location])
if self.getExtendedAttribute("NewObject"):
if self.dependsOn == "Nothing" or self.dependsOn == "DOMState":
raise WebIDLError("A [NewObject] method is not idempotent, "
"so it has to depend on something other than DOM state.",
[self.location])
if (self.getExtendedAttribute("Cached") or
- self.getExtendedAttribute("StoreInSlot")):
+ self.getExtendedAttribute("StoreInSlot")):
raise WebIDLError("A [NewObject] attribute shouldnt be "
"[Cached] or [StoreInSlot], since the point "
"of those is to keep returning the same "
"thing across multiple calls, which is not "
"what [NewObject] does.",
[self.location])
def _setDependsOn(self, dependsOn):
@@ -3621,16 +3630,17 @@ class IDLInterfaceMember(IDLObjectWithId
self.aliases.append(alias)
def _addBindingAlias(self, bindingAlias):
if bindingAlias in self.bindingAliases:
raise WebIDLError("Duplicate [BindingAlias=%s] on attribute" % bindingAlias,
[self.location])
self.bindingAliases.append(bindingAlias)
+
class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
def __init__(self, location, identifier, ifaceType, keyType, valueType, ifaceKind):
IDLInterfaceMember.__init__(self, location, identifier, ifaceKind)
if keyType is not None:
assert isinstance(keyType, IDLType)
else:
assert valueType is not None
@@ -3668,17 +3678,17 @@ class IDLMaplikeOrSetlikeOrIterableBase(
"with reserved %s name." %
(member.identifier.name,
self.maplikeOrSetlikeOrIterableType),
[self.location, member.location])
# Check that there are no disallowed non-method members.
# Ancestor members are always disallowed here; own members
# are disallowed only if they're non-methods.
if ((isAncestor or member.isAttr() or member.isConst()) and
- member.identifier.name in self.disallowedNonMethodNames):
+ member.identifier.name in self.disallowedNonMethodNames):
raise WebIDLError("Member '%s' conflicts "
"with reserved %s method." %
(member.identifier.name,
self.maplikeOrSetlikeOrIterableType),
[self.location, member.location])
def addMethod(self, name, members, allowExistingOperations, returnType, args=[],
chromeOnly=False, isPure=False, affectsNothing=False, newObject=False,
@@ -3717,17 +3727,18 @@ class IDLMaplikeOrSetlikeOrIterableBase(
# maplike/setlike operation. However, if the operation is static,
# then fail by way of creating the function, which will cause a
# naming conflict, per the spec.
if allowExistingOperations:
for m in members:
if m.identifier.name == name and m.isMethod() and not m.isStatic():
return
method = IDLMethod(self.location,
- IDLUnresolvedIdentifier(self.location, name, allowDoubleUnderscore=chromeOnly),
+ IDLUnresolvedIdentifier(self.location, name,
+ allowDoubleUnderscore=chromeOnly),
returnType, args, maplikeOrSetlikeOrIterable=self)
# We need to be able to throw from declaration methods
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("Throws",))])
if chromeOnly:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("ChromeOnly",))])
if isPure:
@@ -3797,16 +3808,18 @@ class IDLMaplikeOrSetlikeOrIterableBase(
IDLArgument(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
"thisArg"),
BuiltinTypes[IDLBuiltinType.Types.any],
optional=True)]
# Iterable adds ES6 iterator style functions and traits
# (keys/values/entries/@@iterator) to an interface.
+
+
class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
def __init__(self, location, identifier, keyType, valueType=None, scope=None):
IDLMaplikeOrSetlikeOrIterableBase.__init__(self, location, identifier,
"iterable", keyType, valueType,
IDLInterfaceMember.Tags.Iterable)
self.iteratorType = None
@@ -3842,16 +3855,18 @@ class IDLIterable(IDLMaplikeOrSetlikeOrI
def isValueIterator(self):
return not self.isPairIterator()
def isPairIterator(self):
return self.hasKeyType()
# MaplikeOrSetlike adds ES6 map-or-set-like traits to an interface.
+
+
class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
def __init__(self, location, identifier, maplikeOrSetlikeType,
readonly, keyType, valueType):
IDLMaplikeOrSetlikeOrIterableBase.__init__(self, location, identifier, maplikeOrSetlikeType,
keyType, valueType, IDLInterfaceMember.Tags.MaplikeOrSetlike)
self.readonly = readonly
self.slotIndices = None
@@ -3869,23 +3884,24 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSe
def expand(self, members, isJSImplemented):
"""
In order to take advantage of all of the method machinery in Codegen,
we generate our functions as if they were part of the interface
specification during parsing.
"""
# Both maplike and setlike have a size attribute
sizeAttr = IDLAttribute(self.location,
- IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), "size"),
+ IDLUnresolvedIdentifier(BuiltinLocation(
+ "<auto-generated-identifier>"), "size"),
BuiltinTypes[IDLBuiltinType.Types.unsigned_long],
True,
maplikeOrSetlike=self)
# This should be non-enumerable.
sizeAttr.addExtendedAttributes(
- [IDLExtendedAttribute(self.location, ("NonEnumerable",))])
+ [IDLExtendedAttribute(self.location, ("NonEnumerable",))])
members.append(sizeAttr)
self.reserved_ro_names = ["size"]
self.disallowedMemberNames.append("size")
# object entries()
self.addMethod("entries", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True, isIteratorAlias=self.isMaplike())
# object keys()
@@ -3960,16 +3976,17 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSe
if not self.readonly:
self.addMethod("set", members, True, BuiltinTypes[IDLBuiltinType.Types.object],
[getKeyArg(), getValueArg()])
if isJSImplemented:
self.addMethod("set", members, True, BuiltinTypes[IDLBuiltinType.Types.object],
[getKeyArg(), getValueArg()], chromeOnly=True)
+
class IDLConst(IDLInterfaceMember):
def __init__(self, location, identifier, type, value):
IDLInterfaceMember.__init__(self, location, identifier,
IDLInterfaceMember.Tags.Const)
assert isinstance(type, IDLType)
if type.isDictionary():
raise WebIDLError("A constant cannot be of a dictionary type",
@@ -4114,29 +4131,29 @@ class IDLAttribute(IDLInterfaceMember):
"one of its member types's member "
"types, and so on) is a record "
"type", [self.location, f.location])
if not self.type.isInterface() and self.getExtendedAttribute("PutForwards"):
raise WebIDLError("An attribute with [PutForwards] must have an "
"interface type as its type", [self.location])
if (not self.type.isInterface() and
- self.getExtendedAttribute("SameObject")):
+ self.getExtendedAttribute("SameObject")):
raise WebIDLError("An attribute with [SameObject] must have an "
"interface type as its type", [self.location])
if self.type.isPromise() and not self.readonly:
raise WebIDLError("Promise-returning attributes must be readonly",
[self.location])
def validate(self):
def typeContainsChromeOnlyDictionaryMember(type):
if (type.nullable() or
type.isSequence() or
- type.isRecord()):
+ type.isRecord()):
return typeContainsChromeOnlyDictionaryMember(type.inner)
if type.isUnion():
for memberType in type.flatMemberTypes:
(contains, location) = typeContainsChromeOnlyDictionaryMember(memberType)
if contains:
return (True, location)
@@ -4157,32 +4174,32 @@ class IDLAttribute(IDLInterfaceMember):
(contains, location) = typeContainsChromeOnlyDictionaryMember(member.type)
if contains:
return (True, location)
return (False, None)
IDLInterfaceMember.validate(self)
if (self.getExtendedAttribute("Cached") or
- self.getExtendedAttribute("StoreInSlot")):
+ self.getExtendedAttribute("StoreInSlot")):
if not self.affects == "Nothing":
raise WebIDLError("Cached attributes and attributes stored in "
"slots must be Constant or Pure or "
"Affects=Nothing, since the getter won't always "
"be called.",
[self.location])
(contains, location) = typeContainsChromeOnlyDictionaryMember(self.type)
if contains:
raise WebIDLError("[Cached] and [StoreInSlot] must not be used "
"on an attribute whose type contains a "
"[ChromeOnly] dictionary member",
[self.location, location])
if self.getExtendedAttribute("Frozen"):
if (not self.type.isSequence() and not self.type.isDictionary() and
- not self.type.isRecord()):
+ not self.type.isRecord()):
raise WebIDLError("[Frozen] is only allowed on "
"sequence-valued, dictionary-valued, and "
"record-valued attributes",
[self.location])
if not self.type.unroll().isExposedInAllOf(self.exposureSet):
raise WebIDLError("Attribute returns a type that is not exposed "
"everywhere where the attribute is exposed",
[self.location])
@@ -4191,17 +4208,17 @@ class IDLAttribute(IDLInterfaceMember):
raise WebIDLError("[CEReactions] is not allowed on "
"readonly attributes",
[self.location])
def handleExtendedAttribute(self, attr):
identifier = attr.identifier()
if ((identifier == "SetterThrows" or identifier == "SetterCanOOM" or
identifier == "SetterNeedsSubjectPrincipal")
- and self.readonly):
+ and self.readonly):
raise WebIDLError("Readonly attributes must not be flagged as "
"[%s]" % identifier,
[self.location])
elif identifier == "BindingAlias":
if not attr.hasValue():
raise WebIDLError("[BindingAlias] takes an identifier or string",
[attr.location])
self._addBindingAlias(attr.value())
@@ -4360,17 +4377,17 @@ class IDLAttribute(IDLInterfaceMember):
raise WebIDLError("[Affects] takes an identifier",
[attr.location])
self._setAffects(attr.value())
elif identifier == "DependsOn":
if not attr.hasValue():
raise WebIDLError("[DependsOn] takes an identifier",
[attr.location])
if (attr.value() != "Everything" and attr.value() != "DOMState" and
- not self.readonly):
+ not self.readonly):
raise WebIDLError("[DependsOn=%s] only allowed on "
"readonly attributes" % attr.value(),
[attr.location, self.location])
self._setDependsOn(attr.value())
elif identifier == "UseCounter":
if self.stringifier:
raise WebIDLError("[UseCounter] must not be used on a "
"stringifier attribute",
@@ -4516,17 +4533,17 @@ class IDLArgument(IDLObjectWithIdentifie
type = self.type.complete(scope)
assert not isinstance(type, IDLUnresolvedType)
assert not isinstance(type, IDLTypedefType)
assert not isinstance(type.name, IDLUnresolvedIdentifier)
self.type = type
if ((self.type.isDictionary() or
self.type.isUnion() and self.type.unroll().hasDictionaryType()) and
- self.optional and not self.defaultValue and not self.variadic):
+ self.optional and not self.defaultValue and not self.variadic):
# Default optional non-variadic dictionaries to null,
# for simplicity, so the codegen doesn't have to special-case this.
self.defaultValue = IDLNullValue(self.location)
elif self.type.isAny():
assert (self.defaultValue is None or
isinstance(self.defaultValue, IDLNullValue))
# optional 'any' values always have a default value
if self.optional and not self.defaultValue and not self.variadic:
@@ -4648,16 +4665,17 @@ class IDLMethodOverload:
"""
A class that represents a single overload of a WebIDL method. This is not
quite the same as an element of the "effective overload set" in the spec,
because separate IDLMethodOverloads are not created based on arguments being
optional. Rather, when multiple methods have the same name, there is an
IDLMethodOverload for each one, all hanging off an IDLMethod representing
the full set of overloads.
"""
+
def __init__(self, returnType, arguments, location):
self.returnType = returnType
# Clone the list of arguments, just in case
self.arguments = list(arguments)
self.location = location
def _getDependentObjects(self):
deps = set(self.arguments)
@@ -4704,17 +4722,18 @@ class IDLMethod(IDLInterfaceMember, IDLS
assert isinstance(setter, bool)
self._setter = setter
assert isinstance(deleter, bool)
self._deleter = deleter
assert isinstance(legacycaller, bool)
self._legacycaller = legacycaller
assert isinstance(stringifier, bool)
self._stringifier = stringifier
- assert maplikeOrSetlikeOrIterable is None or isinstance(maplikeOrSetlikeOrIterable, IDLMaplikeOrSetlikeOrIterableBase)
+ assert maplikeOrSetlikeOrIterable is None or isinstance(
+ maplikeOrSetlikeOrIterable, IDLMaplikeOrSetlikeOrIterableBase)
self.maplikeOrSetlikeOrIterable = maplikeOrSetlikeOrIterable
assert isinstance(htmlConstructor, bool)
# The identifier of a HTMLConstructor must be 'constructor'.
assert not htmlConstructor or identifier.name == "constructor"
self._htmlConstructor = htmlConstructor
self._specialType = specialType
self._unforgeable = False
self.dependsOn = "Everything"
@@ -4933,17 +4952,17 @@ class IDLMethod(IDLInterfaceMember, IDLS
if ((argument.type.isDictionary() and
argument.type.inner.canBeEmpty())or
(argument.type.isUnion() and
argument.type.unroll().hasPossiblyEmptyDictionaryType())):
# Optional dictionaries and unions containing optional
# dictionaries at the end of the list or followed by
# optional arguments must be optional.
if (not argument.optional and
- all(arg.optional for arg in arguments[idx+1:])):
+ all(arg.optional for arg in arguments[idx+1:])):
raise WebIDLError("Dictionary argument without any "
"required fields or union argument "
"containing such dictionary not "
"followed by a required argument "
"must be optional",
[argument.location])
# An argument cannot be a Nullable Dictionary
@@ -5041,17 +5060,17 @@ class IDLMethod(IDLInterfaceMember, IDLS
def handleExtendedAttribute(self, attr):
identifier = attr.identifier()
if (identifier == "GetterThrows" or
identifier == "SetterThrows" or
identifier == "GetterCanOOM" or
identifier == "SetterCanOOM" or
identifier == "SetterNeedsSubjectPrincipal" or
- identifier == "GetterNeedsSubjectPrincipal"):
+ identifier == "GetterNeedsSubjectPrincipal"):
raise WebIDLError("Methods must not be flagged as "
"[%s]" % identifier,
[attr.location, self.location])
elif identifier == "Unforgeable":
if self.isStatic():
raise WebIDLError("[Unforgeable] is only allowed on non-static "
"methods", [attr.location, self.location])
self._unforgeable = True
@@ -5136,17 +5155,17 @@ class IDLMethod(IDLInterfaceMember, IDLS
if not self.isToJSON():
raise WebIDLError("[Default] is only allowed on toJSON operations",
[attr.location, self.location])
if self.signatures()[0][0] != BuiltinTypes[IDLBuiltinType.Types.object]:
raise WebIDLError("The return type of the default toJSON "
"operation must be 'object'",
- [attr.location, self.location]);
+ [attr.location, self.location])
elif (identifier == "Throws" or
identifier == "CanOOM" or
identifier == "NewObject" or
identifier == "ChromeOnly" or
identifier == "Pref" or
identifier == "Deprecated" or
identifier == "Func" or
identifier == "SecureContext" or
@@ -5221,16 +5240,17 @@ class IDLImplementsStatement(IDLObject):
"allowed on implements statements",
[attrs[0].location, self.location])
class IDLExtendedAttribute(IDLObject):
"""
A class to represent IDL extended attributes so we can give them locations
"""
+
def __init__(self, location, tuple):
IDLObject.__init__(self, location)
self._tuple = tuple
def identifier(self):
return self._tuple[0]
def noArguments(self):
@@ -5264,17 +5284,17 @@ class IDLExtendedAttribute(IDLObject):
class Tokenizer(object):
tokens = [
"INTEGER",
"FLOATLITERAL",
"IDENTIFIER",
"STRING",
"WHITESPACE",
"OTHER"
- ]
+ ]
def t_FLOATLITERAL(self, t):
r'(-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+|Infinity))|NaN'
t.value = float(t.value)
return t
def t_INTEGER(self, t):
r'-?(0([0-7]+|[Xx][0-9A-Fa-f]+)?|[1-9][0-9]*)'
@@ -5376,17 +5396,17 @@ class Tokenizer(object):
"ArrayBuffer": "ARRAYBUFFER",
"SharedArrayBuffer": "SHAREDARRAYBUFFER",
"or": "OR",
"maplike": "MAPLIKE",
"setlike": "SETLIKE",
"iterable": "ITERABLE",
"namespace": "NAMESPACE",
"ReadableStream": "READABLESTREAM",
- }
+ }
tokens.extend(keywords.values())
def t_error(self, t):
raise WebIDLError("Unrecognized Input",
[Location(lexer=self.lexer,
lineno=self.lexer.lineno,
lexpos=self.lexer.lexpos,
@@ -5413,17 +5433,17 @@ class SqueakyCleanLogger(object):
# ExtendedAttributeInner, which we don't use yet.
"Rule 'OtherOrComma' defined, but not used",
# And an unused rule
"There is 1 unused rule",
# And the OtherOrComma grammar symbol is unreachable.
"Symbol 'OtherOrComma' is unreachable",
# Which means the Other symbol is unreachable.
"Symbol 'Other' is unreachable",
- ]
+ ]
def __init__(self):
self.errors = []
def debug(self, msg, *args, **kwargs):
pass
info = debug
@@ -6099,35 +6119,35 @@ class Parser(Tokenizer):
specialType = IDLMethod.NamedOrIndexed.Named
elif argType == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]:
specialType = IDLMethod.NamedOrIndexed.Indexed
else:
raise WebIDLError("settter has wrong argument type (must be DOMString or UnsignedLong)",
[arguments[0].location])
if arguments[0].optional or arguments[0].variadic:
raise WebIDLError("setter cannot have %s argument" %
- ("optional" if arguments[0].optional else "variadic"),
+ ("optional" if arguments[0].optional else "variadic"),
[arguments[0].location])
if arguments[1].optional or arguments[1].variadic:
raise WebIDLError("setter cannot have %s argument" %
- ("optional" if arguments[1].optional else "variadic"),
+ ("optional" if arguments[1].optional else "variadic"),
[arguments[1].location])
if stringifier:
if len(arguments) != 0:
raise WebIDLError("stringifier has wrong number of arguments",
[self.getLocation(p, 2)])
if not returnType.isDOMString():
raise WebIDLError("stringifier must have DOMString return type",
[self.getLocation(p, 2)])
# identifier might be None. This is only permitted for special methods.
if not identifier:
if (not getter and not setter and
- not deleter and not legacycaller and not stringifier):
+ not deleter and not legacycaller and not stringifier):
raise WebIDLError("Identifier required for non-special methods",
[self.getLocation(p, 2)])
location = BuiltinLocation("<auto-generated-identifier>")
identifier = IDLUnresolvedIdentifier(
location,
"__%s%s%s%s%s%s" %
("named" if specialType == IDLMethod.NamedOrIndexed.Named else
@@ -6863,34 +6883,35 @@ class Parser(Tokenizer):
"""
p[0] = []
def p_error(self, p):
if not p:
raise WebIDLError("Syntax Error at end of file. Possibly due to missing semicolon(;), braces(}) or both",
[self._filename])
else:
- raise WebIDLError("invalid syntax", [Location(self.lexer, p.lineno, p.lexpos, self._filename)])
+ raise WebIDLError("invalid syntax", [Location(
+ self.lexer, p.lineno, p.lexpos, self._filename)])
def __init__(self, outputdir='', lexer=None):
Tokenizer.__init__(self, outputdir, lexer)
logger = SqueakyCleanLogger()
try:
self.parser = yacc.yacc(module=self,
outputdir=outputdir,
tabmodule='webidlyacc',
errorlog=logger
# Pickling the grammar is a speedup in
# some cases (older Python?) but a
# significant slowdown in others.
# We're not pickling for now, until it
# becomes a speedup again.
# , picklefile='WebIDLGrammar.pkl'
- )
+ )
finally:
logger.reportGrammarErrors()
self._globalScope = IDLScope(BuiltinLocation("<Global Scope>"), None, None)
# To make our test harness work, pretend like we have a primary global already.
# Note that we _don't_ set _globalScope.primaryGlobalAttr,
# so we'll still be able to detect multiple PrimaryGlobal extended attributes.
self._globalScope.primaryGlobalName = "FakeTestPrimaryGlobal"
@@ -6950,17 +6971,17 @@ class Parser(Tokenizer):
navigatorProperty = iface.getNavigatorProperty()
if navigatorProperty:
# We're generating a partial interface to add a readonly
# property to the Navigator interface for every interface
# annotated with NavigatorProperty.
partialInterface = IDLPartialInterfaceOrNamespace(
iface.location,
IDLUnresolvedIdentifier(iface.location, "Navigator"),
- [ navigatorProperty ],
+ [navigatorProperty],
navigatorInterface)
self._productions.append(partialInterface)
iterable = None
# We haven't run finish() on the interface yet, so we don't know
# whether our interface is maplike/setlike/iterable or not. This
# means we have to loop through the members to see if we have an
# iterable member.
@@ -7061,10 +7082,11 @@ def main():
parser.parse(''.join(lines), fullPath)
parser.finish()
except WebIDLError, e:
if options.verbose_errors:
traceback.print_exc()
else:
print e
+
if __name__ == '__main__':
main()