diff options
author | Corey Farwell <coreyf@rwell.org> | 2015-07-05 12:10:53 -0700 |
---|---|---|
committer | Corey Farwell <coreyf@rwell.org> | 2015-07-09 19:42:31 +0900 |
commit | 0ec2375cabb69abbfd1014bfb68136fdea6edadb (patch) | |
tree | 8a24a61ae92605810bdd7163aad10204833e9a99 | |
parent | fe17067d6a30b85a0346fd1ccb2b95e2081e6962 (diff) | |
download | servo-0ec2375cabb69abbfd1014bfb68136fdea6edadb.tar.gz servo-0ec2375cabb69abbfd1014bfb68136fdea6edadb.zip |
Remove tidy blacklist for 'script/dom/bindings/*'
Recently, I found myself reading through the Python codegen scripts that
live in 'components/script/dom/bindings/*' and noticed that there were
many tidy violations: unnecessary semicolons, weird spacing, unused
variables, lack of license headers, etc. Considering these files are now
living in our tree and mostly maintained directly by contributors of
Servo (as opposed to being from upstream), I feel these files should not
be excluded from our normal tidy process. This commit removes the
blacklist on these files and fixes all tidy violations.
I added these subdirectories to the blacklist because they appear to be
maintained upstream somewhere else:
* "components/script/dom/bindings/codegen/parser/*",
* "components/script/dom/bindings/codegen/ply/*",
Also, I added a '# noqa' comment which tells us to ignore the
flake8 errors for that line. I chose to ignore this (instead of fixing
it) to make the work for this commit simpler for me.
8 files changed, 477 insertions, 262 deletions
diff --git a/components/script/dom/bindings/codegen/BindingGen.py b/components/script/dom/bindings/codegen/BindingGen.py index 408280dacfb..f4d4fcdae2a 100644 --- a/components/script/dom/bindings/codegen/BindingGen.py +++ b/components/script/dom/bindings/codegen/BindingGen.py @@ -1,16 +1,16 @@ # This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this file, -# You can obtain one at http://mozilla.org/MPL/2.0/. +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. import sys sys.path.append("./parser/") sys.path.append("./ply/") import os import cPickle -import WebIDL -from Configuration import * +from Configuration import Configuration from CodegenRust import CGBindingRoot, replaceFileIfChanged + def generate_binding_rs(config, outputprefix, webidlfile): """ |config| Is the configuration object. @@ -22,6 +22,7 @@ def generate_binding_rs(config, outputprefix, webidlfile): if replaceFileIfChanged(filename, root.define()): print "Generating binding implementation: %s" % (filename) + def main(): # Parse arguments. from optparse import OptionParser @@ -46,7 +47,7 @@ def main(): config = Configuration(configFile, parserData) # Generate the prototype classes. - generate_binding_rs(config, outputPrefix, webIDLFile); + generate_binding_rs(config, outputPrefix, webIDLFile) if __name__ == '__main__': main() diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 46be7290187..8b7b427f689 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -1,6 +1,6 @@ # This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this file, -# You can obtain one at http://mozilla.org/MPL/2.0/. +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. # Common codegen classes. @@ -30,26 +30,27 @@ TRACE_HOOK_NAME = '_trace' CONSTRUCT_HOOK_NAME = '_constructor' HASINSTANCE_HOOK_NAME = '_hasInstance' + def replaceFileIfChanged(filename, newContents): """ Read a copy of the old file, so that we don't touch it if it hasn't changed. Returns True if the file was updated, false otherwise. """ - #XXXjdm This doesn't play well with make right now. + # XXXjdm This doesn't play well with make right now. # Force the file to always be updated, or else changing CodegenRust.py # will cause many autogenerated bindings to be regenerated perpetually # until the result is actually different. - #oldFileContents = "" - #try: - # oldFile = open(filename, 'rb') - # oldFileContents = ''.join(oldFile.readlines()) - # oldFile.close() - #except: - # pass + # oldFileContents = "" + # try: + # oldFile = open(filename, 'rb') + # oldFileContents = ''.join(oldFile.readlines()) + # oldFile.close() + # except: + # pass - #if newContents == oldFileContents: - # return False + # if newContents == oldFileContents: + # return False f = open(filename, 'wb') f.write(newContents) @@ -57,11 +58,14 @@ def replaceFileIfChanged(filename, newContents): return True + def toStringBool(arg): return str(not not arg).lower() + def toBindingNamespace(arg): - return re.sub("((_workers)?$)", "Binding\\1", arg); + return re.sub("((_workers)?$)", "Binding\\1", arg) + def stripTrailingWhitespace(text): tail = '\n' if text.endswith('\n') else '' @@ -70,6 +74,7 @@ def stripTrailingWhitespace(text): lines[i] = lines[i].rstrip() return '\n'.join(lines) + tail + def MakeNativeName(name): return name[0].upper() + name[1:] @@ -96,7 +101,8 @@ numericTags = [ IDLType.Tags.int64, IDLType.Tags.uint64, IDLType.Tags.unrestricted_float, IDLType.Tags.float, IDLType.Tags.unrestricted_double, IDLType.Tags.double - ] +] + class CastableObjectUnwrapper(): """ @@ -150,6 +156,7 @@ def memoize(fn): grows without bound. """ cache = {} + @functools.wraps(fn) def wrapper(arg): retval = cache.get(arg) @@ -158,6 +165,7 @@ def memoize(fn): return retval return wrapper + @memoize def dedent(s): """ @@ -215,6 +223,7 @@ def compile_fill_template(template): t = re.sub(fill_multiline_substitution_re, replace, t) return (string.Template(t), argModList) + def fill(template, **args): """ Convenience function for filling in a multiline template. @@ -253,16 +262,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 + pass # Nothing for now def define(self): """Produce code for a Rust file.""" - assert(False) # Override me! + assert(False) # Override me! class CGNativePropertyHooks(CGThing): @@ -277,7 +287,8 @@ class CGNativePropertyHooks(CGThing): def define(self): parent = self.descriptor.interface.parent if parent: - parentHooks = "Some(&::dom::bindings::codegen::Bindings::%sBinding::sNativePropertyHooks)" % parent.identifier.name + parentHooks = ("Some(&::dom::bindings::codegen::Bindings::%sBinding::sNativePropertyHooks)" + % parent.identifier.name) else: parentHooks = "None" @@ -307,16 +318,16 @@ class CGMethodCall(CGThing): if len(arguments) == 0: return 0 requiredArgs = len(arguments) - while requiredArgs and arguments[requiredArgs-1].optional: + while requiredArgs and arguments[requiredArgs - 1].optional: requiredArgs -= 1 return requiredArgs - signatures = method.signatures() + def getPerSignatureCall(signature, argConversionStartsAt=0): signatureIndex = signatures.index(signature) return CGPerSignatureCall(signature[0], argsPre, signature[1], - nativeMethodName + '_'*signatureIndex, + nativeMethodName + '_' * signatureIndex, static, descriptor, method, argConversionStartsAt) @@ -328,7 +339,6 @@ class CGMethodCall(CGThing): self.cgRoot = CGList([getPerSignatureCall(signature)]) requiredArgs = requiredArgCount(signature) - if requiredArgs > 0: code = ( "if argc < %d {\n" @@ -366,10 +376,10 @@ class CGMethodCall(CGThing): # Doesn't matter which of the possible signatures we use, since # they all have the same types up to that point; just use # possibleSignatures[0] - caseBody = [ CGArgumentConverter(possibleSignatures[0][1][i], - i, "args", "argc", - descriptor) for i in - range(0, distinguishingIndex) ] + caseBody = [ + CGArgumentConverter(possibleSignatures[0][1][i], + i, "args", "argc", descriptor) + for i in range(0, distinguishingIndex)] # Select the right overload from our set. distinguishingArg = "args.get(%d)" % distinguishingIndex @@ -399,7 +409,7 @@ class CGMethodCall(CGThing): interfacesSigs = [ s for s in possibleSignatures if (s[1][distinguishingIndex].type.isObject() or - s[1][distinguishingIndex].type.isNonCallbackInterface()) ] + s[1][distinguishingIndex].type.isNonCallbackInterface())] # There might be more than one of these; we need to check # which ones we unwrap to. @@ -418,7 +428,7 @@ class CGMethodCall(CGThing): caseBody.append(CGGeneric("if %s.get().is_object() {" % (distinguishingArg))) for idx, sig in enumerate(interfacesSigs): - caseBody.append(CGIndenter(CGGeneric("loop {"))); + caseBody.append(CGIndenter(CGGeneric("loop {"))) type = sig[1][distinguishingIndex].type # The argument at index distinguishingIndex can't possibly @@ -438,13 +448,13 @@ class CGMethodCall(CGThing): needsRooting) # Indent by 4, since we need to indent further than our "do" statement - caseBody.append(CGIndenter(testCode, 4)); + caseBody.append(CGIndenter(testCode, 4)) # If we got this far, we know we unwrapped to the right # interface, so just do the call. Start conversion with # distinguishingIndex + 1, since we already converted # distinguishingIndex. caseBody.append(CGIndenter( - getPerSignatureCall(sig, distinguishingIndex + 1), 4)) + getPerSignatureCall(sig, distinguishingIndex + 1), 4)) caseBody.append(CGIndenter(CGGeneric("}"))) caseBody.append(CGGeneric("}")) @@ -507,31 +517,35 @@ class CGMethodCall(CGThing): argCountCases, CGGeneric("throw_type_error(cx, \"Not enough arguments to %s.\");\n" "return 0;" % methodName))) - #XXXjdm Avoid unreachable statement warnings - #overloadCGThings.append( - # CGGeneric('panic!("We have an always-returning default case");\n' - # 'return 0;')) + # XXXjdm Avoid unreachable statement warnings + # overloadCGThings.append( + # CGGeneric('panic!("We have an always-returning default case");\n' + # 'return 0;')) self.cgRoot = CGWrapper(CGList(overloadCGThings, "\n"), pre="\n") def define(self): return self.cgRoot.define() + class FakeCastableDescriptor(): def __init__(self, descriptor): self.nativeType = "*const %s" % descriptor.concreteType self.name = descriptor.name + class FakeInterface: def inheritanceDepth(self): return descriptor.interface.inheritanceDepth() self.interface = FakeInterface() + def dictionaryHasSequenceMember(dictionary): return (any(typeIsSequenceOrHasSequenceMember(m.type) for m in dictionary.members) or (dictionary.parent and dictionaryHasSequenceMember(dictionary.parent))) + def typeIsSequenceOrHasSequenceMember(type): if type.nullable(): type = type.inner @@ -547,6 +561,7 @@ def typeIsSequenceOrHasSequenceMember(type): type.flatMemberTypes) return False + def typeNeedsRooting(type, descriptorProvider): return (type.isGeckoInterface() and descriptorProvider.getDescriptor(type.unroll().inner.identifier.name).needsRooting) @@ -679,6 +694,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, ('throw_type_error(cx, "%s is not an object.");\n' '%s' % (firstCap(sourceDescription), exceptionCode))), post="\n") + def onFailureBadType(failureCode, typeName): return CGWrapper( CGGeneric( @@ -687,6 +703,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, '%s' % (firstCap(sourceDescription), typeName, exceptionCode))), post="\n") + def onFailureNotCallable(failureCode): return CGWrapper( CGGeneric( @@ -726,7 +743,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, "}") return templateBody - assert not (isEnforceRange and isClamp) # These are mutually exclusive + assert not (isEnforceRange and isClamp) # These are mutually exclusive if type.isArray(): raise TypeError("Can't handle array arguments yet") @@ -789,11 +806,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, else: unwrapFailureCode = failureCode - templateBody = str(CastableObjectUnwrapper( - descriptor, - "${val}", - unwrapFailureCode, - "value")) + templateBody = str( + CastableObjectUnwrapper(descriptor, "${val}", unwrapFailureCode, "value")) declType = CGGeneric(descriptorType) if type.nullable(): @@ -906,9 +920,9 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, " //XXXjdm need some range checks up in here.\n" " unsafe { mem::transmute(index) }\n" " },\n" - "}" % { "values" : enum + "Values::strings", - "exceptionCode" : exceptionCode, -"handleInvalidEnumValueCode" : handleInvalidEnumValueCode }) + "}" % {"values": enum + "Values::strings", + "exceptionCode": exceptionCode, + "handleInvalidEnumValueCode": handleInvalidEnumValueCode}) if defaultValue is not None: assert(defaultValue.type.tag() == IDLType.Tags.domstring) @@ -1041,7 +1055,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, if type.nullable(): declType = CGWrapper(declType, pre="Option<", post=">") - #XXXjdm support conversionBehavior here + # XXXjdm support conversionBehavior here template = ( "match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n" " Ok(v) => v,\n" @@ -1067,6 +1081,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, return handleOptional(template, declType, defaultStr) + def instantiateJSToNativeConversionTemplate(templateBody, replacements, declType, declName, needsRooting): """ @@ -1077,9 +1092,7 @@ def instantiateJSToNativeConversionTemplate(templateBody, replacements, """ result = CGList([], "\n") - conversion = CGGeneric( - string.Template(templateBody).substitute(replacements) - ) + conversion = CGGeneric(string.Template(templateBody).substitute(replacements)) if declType is not None: newDecl = [ @@ -1099,7 +1112,8 @@ def instantiateJSToNativeConversionTemplate(templateBody, replacements, # conversion. result.append(CGGeneric("")) - return result; + return result + def convertConstIDLValueToJSVal(value): if isinstance(value, IDLNullValue): @@ -1119,6 +1133,7 @@ def convertConstIDLValueToJSVal(value): return "DoubleVal(%s)" % (value.value) raise TypeError("Const value of unhandled type: " + value.type) + class CGArgumentConverter(CGThing): """ A class that takes an IDL argument object, its index in the @@ -1241,6 +1256,7 @@ def typeNeedsCx(type, retVal=False): return True return type.isAny() or type.isObject() + def typeRetValNeedsRooting(type): if type is None: return False @@ -1248,9 +1264,11 @@ def typeRetValNeedsRooting(type): type = type.inner return type.isGeckoInterface() and not type.isCallback() and not type.isCallbackInterface() + def memberIsCreator(member): return member.getExtendedAttribute("Creator") is not None + # Returns a CGThing containing the type of the return value. def getRetvalDeclarationForType(returnType, descriptorProvider): if returnType is None or returnType.isVoid(): @@ -1320,6 +1338,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider): raise TypeError("Don't know how to declare return value for %s" % returnType) + class PropertyDefiner: """ A common superclass for defining things on prototype objects. @@ -1375,11 +1394,15 @@ class PropertyDefiner: ",\n".join(specs) + "\n" + "];\n") % (name, specType)) + # The length of a method is the minimum of the lengths of the # argument lists of all its overloads. def methodLength(method): signatures = method.signatures() - return min(len([arg for arg in arguments if not arg.optional and not arg.variadic]) for (_, arguments) in signatures) + return min( + len([arg for arg in arguments if not arg.optional and not arg.variadic]) + for (_, arguments) in signatures) + class MethodDefiner(PropertyDefiner): """ @@ -1402,8 +1425,7 @@ class MethodDefiner(PropertyDefiner): self.regular = [{"name": m.identifier.name, "methodInfo": not m.isStatic(), "length": methodLength(m), - "flags": "JSPROP_ENUMERATE" } - for m in methods] + "flags": "JSPROP_ENUMERATE"} for m in methods] # FIXME Check for an existing iterator on the interface first. if any(m.isGetter() and m.isIndexed() for m in methods): @@ -1411,7 +1433,7 @@ class MethodDefiner(PropertyDefiner): "methodInfo": False, "selfHostedName": "ArrayValues", "length": 0, - "flags": "JSPROP_ENUMERATE" }) + "flags": "JSPROP_ENUMERATE"}) if not static: stringifier = descriptor.operations['Stringifier'] @@ -1423,7 +1445,6 @@ class MethodDefiner(PropertyDefiner): "flags": "JSPROP_ENUMERATE" }) - def generateArray(self, array, name): if len(array) == 0: return "" @@ -1446,17 +1467,30 @@ class MethodDefiner(PropertyDefiner): jitinfo = "0 as *const JSJitInfo" accessor = 'Some(%s)' % m.get("nativeName", m["name"]) if m["name"].startswith("@@"): - return ('(SymbolCode::%s as i32 + 1)' % m["name"][2:], accessor, jitinfo, m["length"], m["flags"], selfHostedName) + return ('(SymbolCode::%s as i32 + 1)' + % m["name"][2:], accessor, jitinfo, m["length"], m["flags"], selfHostedName) return (str_to_const_array(m["name"]), accessor, jitinfo, m["length"], m["flags"], selfHostedName) - return self.generatePrefableArray( array, name, - ' JSFunctionSpec { name: %s as *const u8 as *const libc::c_char, call: JSNativeWrapper {op: %s, info: %s}, nargs: %s, flags: %s as u16, selfHostedName: %s }', - ' JSFunctionSpec { name: 0 as *const i8, call: JSNativeWrapper { op: None, info: 0 as *const JSJitInfo }, nargs: 0, flags: 0, selfHostedName: 0 as *const i8 }', + ' JSFunctionSpec {\n' + ' name: %s as *const u8 as *const libc::c_char,\n' + ' call: JSNativeWrapper {op: %s, info: %s},\n' + ' nargs: %s,\n' + ' flags: %s as u16,\n' + ' selfHostedName: %s\n' + ' }', + ' JSFunctionSpec {\n' + ' name: 0 as *const i8,\n' + ' call: JSNativeWrapper { op: None, info: 0 as *const JSJitInfo },\n' + ' nargs: 0,\n' + ' flags: 0,\n' + ' selfHostedName: 0 as *const i8\n' + ' }', 'JSFunctionSpec', specData) + class AttrDefiner(PropertyDefiner): def __init__(self, descriptor, name, static): PropertyDefiner.__init__(self, descriptor, name) @@ -1487,8 +1521,8 @@ class AttrDefiner(PropertyDefiner): jitinfo = "&%s_getterinfo" % attr.identifier.name return ("JSNativeWrapper { op: Some(%(native)s), info: %(info)s }" - % {"info" : jitinfo, - "native" : accessor}) + % {"info": jitinfo, + "native": accessor}) def setter(attr): if attr.readonly and not attr.getExtendedAttribute("PutForwards"): @@ -1505,8 +1539,8 @@ class AttrDefiner(PropertyDefiner): jitinfo = "&%s_setterinfo" % attr.identifier.name return ("JSNativeWrapper { op: Some(%(native)s), info: %(info)s }" - % {"info" : jitinfo, - "native" : accessor}) + % {"info": jitinfo, + "native": accessor}) def specData(attr): return (str_to_const_array(attr.identifier.name), flags(attr), getter(attr), @@ -1514,11 +1548,22 @@ class AttrDefiner(PropertyDefiner): return self.generatePrefableArray( array, name, - ' JSPropertySpec { name: %s as *const u8 as *const libc::c_char, flags: ((%s) & 0xFF) as u8, getter: %s, setter: %s }', - ' JSPropertySpec { name: 0 as *const i8, flags: 0, getter: JSNativeWrapper { op: None, info: 0 as *const JSJitInfo }, setter: JSNativeWrapper { op: None, info: 0 as *const JSJitInfo } }', + ' JSPropertySpec {\n' + ' name: %s as *const u8 as *const libc::c_char,\n' + ' flags: ((%s) & 0xFF) as u8,\n' + ' getter: %s,\n' + ' setter: %s\n' + ' }', + ' JSPropertySpec {\n' + ' name: 0 as *const i8,\n' + ' flags: 0,\n' + ' getter: JSNativeWrapper { op: None, info: 0 as *const JSJitInfo },\n' + ' setter: JSNativeWrapper { op: None, info: 0 as *const JSJitInfo }\n' + ' }', 'JSPropertySpec', specData) + class ConstDefiner(PropertyDefiner): """ A class for definining constants on the interface object @@ -1547,6 +1592,8 @@ class ConstDefiner(PropertyDefiner): # don't want to indent empty lines. So only indent lines that have a # non-newline character on them. lineStartDetector = re.compile("^(?=[^\n])", re.MULTILINE) + + class CGIndenter(CGThing): """ A class that takes another CGThing and generates code that indents that @@ -1564,6 +1611,7 @@ class CGIndenter(CGThing): else: return defn + class CGWrapper(CGThing): """ Generic CGThing that wraps other CGThings with pre and post text. @@ -1584,6 +1632,7 @@ class CGWrapper(CGThing): defn.replace("\n", "\n" + (" " * len(self.pre)))) return self.pre + defn + self.post + class CGImports(CGWrapper): """ Generates the appropriate import/use statements. @@ -1674,6 +1723,7 @@ class CGImports(CGWrapper): basename = os.path.basename(decl.filename()) return basename.replace('.webidl', 'Binding.rs') + class CGIfWrapper(CGWrapper): def __init__(self, child, condition): pre = CGWrapper(CGGeneric(condition), pre="if ", post=" {\n", @@ -1681,10 +1731,12 @@ class CGIfWrapper(CGWrapper): CGWrapper.__init__(self, CGIndenter(child), pre=pre.define(), post="\n}") + class CGTemplatedType(CGWrapper): def __init__(self, templateName, child): CGWrapper.__init__(self, child, pre=templateName + "<", post=">") + class CGNamespace(CGWrapper): def __init__(self, namespace, child, public=False): pre = "%smod %s {\n" % ("pub " if public else "", namespace) @@ -1701,6 +1753,7 @@ class CGNamespace(CGWrapper): inner = CGNamespace.build(namespaces[1:], child, public=public) return CGNamespace(namespaces[0], inner, public=public) + def DOMClass(descriptor): protoList = ['PrototypeList::ID::' + proto for proto in descriptor.prototypeChain] # Pad out the list to the right length with ID::Count so we @@ -1715,6 +1768,7 @@ DOMClass { native_hooks: &sNativePropertyHooks, }""" % prototypeChainString + class CGDOMJSClass(CGThing): """ Generate a DOMJSClass for a given descriptor @@ -1736,7 +1790,9 @@ class CGDOMJSClass(CGThing): static Class: DOMJSClass = DOMJSClass { base: js::jsapi::Class { name: %s as *const u8 as *const libc::c_char, - flags: JSCLASS_IS_DOMJSCLASS | JSCLASS_IMPLEMENTS_BARRIERS | %s | (((%s) & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT), //JSCLASS_HAS_RESERVED_SLOTS(%s), + flags: JSCLASS_IS_DOMJSCLASS | JSCLASS_IMPLEMENTS_BARRIERS | %s | + (((%s) & JSCLASS_RESERVED_SLOTS_MASK) << + JSCLASS_RESERVED_SLOTS_SHIFT), //JSCLASS_HAS_RESERVED_SLOTS(%s), addProperty: None, delProperty: None, getProperty: None, @@ -1785,17 +1841,18 @@ static Class: DOMJSClass = DOMJSClass { }, }, dom_class: %s -}; -""" % (str_to_const_array(self.descriptor.interface.identifier.name), - flags, slots, slots, - FINALIZE_HOOK_NAME, traceHook, - self.descriptor.outerObjectHook, - self.descriptor.outerObjectHook, - CGGeneric(DOMClass(self.descriptor)).define()) +};""" % (str_to_const_array(self.descriptor.interface.identifier.name), + flags, slots, slots, + FINALIZE_HOOK_NAME, traceHook, + self.descriptor.outerObjectHook, + self.descriptor.outerObjectHook, + CGGeneric(DOMClass(self.descriptor)).define()) + def str_to_const_array(s): return "b\"%s\\0\"" % s + class CGPrototypeJSClass(CGThing): def __init__(self, descriptor): CGThing.__init__(self) @@ -1822,6 +1879,7 @@ static PrototypeClass: JSClass = JSClass { }; """ % str_to_const_array(self.descriptor.interface.identifier.name + "Prototype") + class CGInterfaceObjectJSClass(CGThing): def __init__(self, descriptor): CGThing.__init__(self) @@ -1852,6 +1910,7 @@ const InterfaceObjectClass: JSClass = { }; """ % (str_to_const_array("Function"), ctorname, hasinstance, ctorname) + class CGList(CGThing): """ Generate code for a list of GCThings. Just concatenates them together, with @@ -1861,10 +1920,13 @@ class CGList(CGThing): CGThing.__init__(self) self.children = children self.joiner = joiner + def append(self, child): self.children.append(child) + def prepend(self, child): self.children.insert(0, child) + def join(self, generator): return self.joiner.join(filter(lambda s: len(s) > 0, (child for child in generator))) @@ -1874,8 +1936,8 @@ class CGList(CGThing): class CGIfElseWrapper(CGList): def __init__(self, condition, ifTrue, ifFalse): - kids = [ CGIfWrapper(ifTrue, condition), - CGWrapper(CGIndenter(ifFalse), pre=" else {\n", post="\n}") ] + kids = [CGIfWrapper(ifTrue, condition), + CGWrapper(CGIndenter(ifFalse), pre=" else {\n", post="\n}")] CGList.__init__(self, kids) @@ -1890,6 +1952,7 @@ class CGGeneric(CGThing): def define(self): return self.text + class CGCallbackTempRoot(CGGeneric): def __init__(self, name): CGGeneric.__init__(self, "%s::new(${val}.get().to_object())" % name) @@ -1912,12 +1975,14 @@ def getAllTypes(descriptors, dictionaries, callbacks): for t in getTypesFromCallback(callback): yield (t, None, None) + def SortedTuples(l): """ Sort a list of tuples based on the first item in the tuple """ return sorted(l, key=operator.itemgetter(0)) + def SortedDictValues(d): """ Returns a list of values from the dict sorted by key. @@ -1927,6 +1992,7 @@ def SortedDictValues(d): # We're only interested in the values. return (i[1] for i in d) + def UnionTypes(descriptors, dictionaries, callbacks, config): """ Returns a CGList containing CGUnionStructs for every union. @@ -1956,7 +2022,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, config): if not t.isUnion(): continue name = str(t) - if not name in unionStructs: + if name not in unionStructs: provider = descriptor or config.getDescriptorProvider() unionStructs[name] = CGList([ CGUnionStruct(t, provider), @@ -1975,15 +2041,18 @@ class Argument(): self.name = name self.default = default self.mutable = mutable + def declare(self): string = ('mut ' if self.mutable else '') + self.name + ((': ' + self.argType) if self.argType else '') - #XXXjdm Support default arguments somehow :/ - #if self.default is not None: - # string += " = " + self.default + # XXXjdm Support default arguments somehow :/ + # if self.default is not None: + # string += " = " + self.default return string + def define(self): return self.argType + ' ' + self.name + class CGAbstractMethod(CGThing): """ An abstract class for generating code for a method. Subclasses @@ -2007,7 +2076,9 @@ class CGAbstractMethod(CGThing): template arguments, and the function will be templatized using those arguments. """ - def __init__(self, descriptor, name, returnType, args, inline=False, alwaysInline=False, extern=False, pub=False, templateArgs=None, unsafe=True): + def __init__(self, descriptor, name, returnType, args, inline=False, + alwaysInline=False, extern=False, pub=False, templateArgs=None, + unsafe=True): CGThing.__init__(self) self.descriptor = descriptor self.name = name @@ -2016,10 +2087,12 @@ class CGAbstractMethod(CGThing): self.alwaysInline = alwaysInline self.extern = extern self.templateArgs = templateArgs - self.pub = pub; + self.pub = pub self.unsafe = unsafe + def _argstring(self): return ', '.join([a.declare() for a in self.args]) + def _template(self): if self.templateArgs is None: return '' @@ -2055,11 +2128,14 @@ class CGAbstractMethod(CGThing): def definition_prologue(self): return "%sfn %s%s(%s)%s {\n" % (self._decorators(), self.name, self._template(), - self._argstring(), self._returnType()) + self._argstring(), self._returnType()) + def definition_epilogue(self): return "\n}\n" + def definition_body(self): - assert(False) # Override me! + assert(False) # Override me! + def CreateBindingJSObject(descriptor, parent=None): create = "let mut raw = Box::into_raw(object);\nlet _rt = RootedTraceable::new(&*raw);\n" @@ -2080,11 +2156,18 @@ let obj = RootedObject::new(cx, obj);\ """ % (descriptor.name, parent) else: if descriptor.isGlobal(): - create += "let obj = RootedObject::new(cx, create_dom_global(cx, &Class.base as *const js::jsapi::Class as *const JSClass, Some(%s)));\n" % TRACE_HOOK_NAME + create += ("let obj = RootedObject::new(\n" + " cx,\n" + " create_dom_global(\n" + " cx,\n" + " &Class.base as *const js::jsapi::Class as *const JSClass,\n" + " Some(%s))\n" + ");\n" % TRACE_HOOK_NAME) else: create += ("let obj = {\n" " let _ac = JSAutoCompartment::new(cx, proto.ptr);\n" - " JS_NewObjectWithGivenProto(cx, &Class.base as *const js::jsapi::Class as *const JSClass, proto.handle())\n" + " JS_NewObjectWithGivenProto(\n" + " cx, &Class.base as *const js::jsapi::Class as *const JSClass, proto.handle())\n" "};\n" "let obj = RootedObject::new(cx, obj);\n") create += """\ @@ -2094,6 +2177,7 @@ JS_SetReservedSlot(obj.ptr, DOM_OBJECT_SLOT, PrivateValue(raw as *const libc::c_void));""" return create + class CGWrapMethod(CGAbstractMethod): """ Class that generates the FooBinding::Wrap function for non-callback @@ -2183,6 +2267,7 @@ class CGAbstractExternMethod(CGAbstractMethod): CGAbstractMethod.__init__(self, descriptor, name, returnType, args, inline=False, extern=True) + class PropertyArrays(): def __init__(self, descriptor): self.static_methods = MethodDefiner(descriptor, "StaticMethods", @@ -2203,6 +2288,7 @@ class PropertyArrays(): for array in self.arrayNames(): names[array] = getattr(self, array).variableName() return names + def __str__(self): define = "" for array in self.arrayNames(): @@ -2246,6 +2332,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): Argument('MutableHandleObject', 'rval')] CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'void', args) self.properties = properties + def definition_body(self): protoChain = self.descriptor.prototypeChain if len(protoChain) == 1: @@ -2297,7 +2384,7 @@ do_create_interface_objects(cx, receiver, parent_proto.handle(), let named_constructors: [(NonNullJSNative, &'static str, u32); %d] = [ """ % len(self.descriptor.interface.namedConstructors) for ctor in self.descriptor.interface.namedConstructors: - constructHook = CONSTRUCT_HOOK_NAME + "_" + ctor.identifier.name; + constructHook = CONSTRUCT_HOOK_NAME + "_" + ctor.identifier.name constructArgs = methodLength(ctor) constructor = '(%s as NonNullJSNative, "%s", %d)' % ( constructHook, ctor.identifier.name, constructArgs) @@ -2311,6 +2398,7 @@ let named_constructors: [(NonNullJSNative, &'static str, u32); %d] = [ CGGeneric(call % self.properties.variableNames()) ], "\n") + class CGGetPerInterfaceObject(CGAbstractMethod): """ A method for getting a per-interface object (a prototype object or interface @@ -2323,6 +2411,7 @@ class CGGetPerInterfaceObject(CGAbstractMethod): CGAbstractMethod.__init__(self, descriptor, name, 'void', args, pub=pub) self.id = idPrefix + "ID::" + self.descriptor.name + def definition_body(self): return CGGeneric(""" @@ -2349,6 +2438,7 @@ if <*mut JSObject>::needs_post_barrier(rval.get()) { } """ % (self.id, self.id, self.id)) + class CGGetProtoObjectMethod(CGGetPerInterfaceObject): """ A method for getting the interface prototype object. @@ -2356,6 +2446,7 @@ class CGGetProtoObjectMethod(CGGetPerInterfaceObject): def __init__(self, descriptor): CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObject", "PrototypeList::", pub=True) + def definition_body(self): return CGList([ CGGeneric("""\ @@ -2364,6 +2455,7 @@ class CGGetProtoObjectMethod(CGGetPerInterfaceObject): CGGetPerInterfaceObject.definition_body(self), ]) + class CGGetConstructorObjectMethod(CGGetPerInterfaceObject): """ A method for getting the interface constructor object. @@ -2371,6 +2463,7 @@ class CGGetConstructorObjectMethod(CGGetPerInterfaceObject): def __init__(self, descriptor): CGGetPerInterfaceObject.__init__(self, descriptor, "GetConstructorObject", "constructors::") + def definition_body(self): return CGList([ CGGeneric("""\ @@ -2433,8 +2526,7 @@ let traps = ProxyTraps { }; CreateProxyHandler(&traps, &Class as *const _ as *const _)\ -""" % (customDefineProperty, customDelete, TRACE_HOOK_NAME, - FINALIZE_HOOK_NAME) +""" % (customDefineProperty, customDelete, TRACE_HOOK_NAME, FINALIZE_HOOK_NAME) return CGGeneric(body) @@ -2468,11 +2560,13 @@ assert!(!proto.ptr.is_null()); """ return CGGeneric("assert!(!global.get().is_null());\n" + code) + def needCx(returnType, arguments, considerTypes): return (considerTypes and (typeNeedsCx(returnType, True) or any(typeNeedsCx(a.type) for a in arguments))) + class CGCallGenerator(CGThing): """ A class to generate an actual call to a C++ object. Assumes that the C++ @@ -2496,14 +2590,14 @@ class CGCallGenerator(CGThing): args = CGList([CGGeneric(arg) for arg in argsPre], ", ") for (a, name) in arguments: - #XXXjdm Perhaps we should pass all nontrivial types by borrowed pointer + # XXXjdm Perhaps we should pass all nontrivial types by borrowed pointer if a.type.isDictionary(): name = "&" + name args.append(CGGeneric(name)) needsCx = needCx(returnType, (a for (a, _) in arguments), True) - if not "cx" in argsPre and needsCx: + if "cx" not in argsPre and needsCx: args.prepend(CGGeneric("cx")) # Build up our actual call @@ -2543,10 +2637,12 @@ class CGCallGenerator(CGThing): def define(self): return self.cgRoot.define() + class MethodNotCreatorError(Exception): def __init__(self, typename): self.typename = typename + class CGPerSignatureCall(CGThing): """ This class handles the guts of generating code for a particular @@ -2594,16 +2690,18 @@ class CGPerSignatureCall(CGThing): errorResult = " JSFalse" cgThings.append(CGCallGenerator( - errorResult, - self.getArguments(), self.argsPre, returnType, - self.extendedAttributes, descriptor, nativeMethodName, - static)) + errorResult, + self.getArguments(), self.argsPre, returnType, + self.extendedAttributes, descriptor, nativeMethodName, + static)) self.cgRoot = CGList(cgThings, "\n") def getArgs(self): return "args" if self.argCount > 0 else "" + def getArgc(self): return "argc" + def getArguments(self): def process(arg, i): argVal = "arg" + str(i) @@ -2613,7 +2711,7 @@ class CGPerSignatureCall(CGThing): return [(a, process(a, i)) for (i, a) in enumerate(self.arguments)] def isFallible(self): - return not 'infallible' in self.extendedAttributes + return 'infallible' not in self.extendedAttributes def wrap_return_value(self): return wrapForType('args.rval()') @@ -2621,6 +2719,7 @@ class CGPerSignatureCall(CGThing): def define(self): return (self.cgRoot.define() + "\n" + self.wrap_return_value()) + class CGSwitch(CGList): """ A class to generate code for a switch statement. @@ -2634,7 +2733,7 @@ class CGSwitch(CGList): def __init__(self, expression, cases, default=None): CGList.__init__(self, [CGIndenter(c) for c in cases], "\n") self.prepend(CGWrapper(CGGeneric(expression), - pre="match ", post=" {")); + pre="match ", post=" {")) if default is not None: self.append( CGIndenter( @@ -2642,12 +2741,13 @@ class CGSwitch(CGList): CGIndenter(default), pre="_ => {\n", post="\n}" - ) ) ) + ) self.append(CGGeneric("}")) + class CGCase(CGList): """ A class to generate code for a case statement. @@ -2662,10 +2762,11 @@ class CGCase(CGList): bodyList = CGList([body], "\n") if fallThrough: raise TypeError("fall through required but unsupported") - #bodyList.append(CGGeneric('panic!("fall through unsupported"); /* Fall through */')) - self.append(CGIndenter(bodyList)); + # bodyList.append(CGGeneric('panic!("fall through unsupported"); /* Fall through */')) + self.append(CGIndenter(bodyList)) self.append(CGGeneric("}")) + class CGGetterCall(CGPerSignatureCall): """ A class to generate a native object getter call for a particular IDL @@ -2676,6 +2777,7 @@ class CGGetterCall(CGPerSignatureCall): nativeMethodName, attr.isStatic(), descriptor, attr, getter=True) + class FakeArgument(): """ A class that quacks like an IDLArgument. This is used to make @@ -2694,6 +2796,7 @@ class FakeArgument(): def allowTreatNonCallableAsNull(self): return self._allowTreatNonObjectAsNull + class CGSetterCall(CGPerSignatureCall): """ A class to generate a native object setter call for a particular IDL @@ -2704,15 +2807,19 @@ class CGSetterCall(CGPerSignatureCall): [FakeArgument(argType, attr, allowTreatNonObjectAsNull=True)], nativeMethodName, attr.isStatic(), descriptor, attr, setter=True) + def wrap_return_value(self): # We have no return value return "\nreturn 1;" + def getArgc(self): return "1" + def getArgvDecl(self): # We just get our stuff from our last arg no matter what return "" + class CGAbstractStaticBindingMethod(CGAbstractMethod): """ Common class to generate the JSNatives for all our static methods, getters @@ -2738,6 +2845,7 @@ let global = global_object_for_js_object(JS_CALLEE(cx, vp).to_object()); def generate_code(self): assert False # Override me + class CGSpecializedMethod(CGAbstractExternMethod): """ A class for generating the C++ code for a specialized method that the JIT @@ -2765,6 +2873,7 @@ class CGSpecializedMethod(CGAbstractExternMethod): name = method.identifier.name return MakeNativeName(descriptor.binaryNameFor(name)) + class CGStaticMethod(CGAbstractStaticBindingMethod): """ A class for generating the Rust code for an IDL static method. @@ -2781,6 +2890,7 @@ class CGStaticMethod(CGAbstractStaticBindingMethod): call = CGMethodCall(["global.r()"], nativeName, True, self.descriptor, self.method) return CGList([setupArgs, call]) + class CGSpecializedGetter(CGAbstractExternMethod): """ A class for generating the code for a specialized attribute getter @@ -2789,10 +2899,10 @@ class CGSpecializedGetter(CGAbstractExternMethod): def __init__(self, descriptor, attr): self.attr = attr name = 'get_' + attr.identifier.name - args = [ Argument('*mut JSContext', 'cx'), - Argument('HandleObject', '_obj'), - Argument('*const %s' % descriptor.concreteType, 'this'), - Argument('JSJitGetterCallArgs', 'args') ] + args = [Argument('*mut JSContext', 'cx'), + Argument('HandleObject', '_obj'), + Argument('*const %s' % descriptor.concreteType, 'this'), + Argument('JSJitGetterCallArgs', 'args')] CGAbstractExternMethod.__init__(self, descriptor, name, "u8", args) def definition_body(self): @@ -2832,6 +2942,7 @@ class CGStaticGetter(CGAbstractStaticBindingMethod): self.attr) return CGList([setupArgs, call]) + class CGSpecializedSetter(CGAbstractExternMethod): """ A class for generating the code for a specialized attribute setter @@ -2840,10 +2951,10 @@ class CGSpecializedSetter(CGAbstractExternMethod): def __init__(self, descriptor, attr): self.attr = attr name = 'set_' + attr.identifier.name - args = [ Argument('*mut JSContext', 'cx'), - Argument('HandleObject', 'obj'), - Argument('*const %s' % descriptor.concreteType, 'this'), - Argument('JSJitSetterCallArgs', 'args')] + args = [Argument('*mut JSContext', 'cx'), + Argument('HandleObject', 'obj'), + Argument('*const %s' % descriptor.concreteType, 'this'), + Argument('JSJitSetterCallArgs', 'args')] CGAbstractExternMethod.__init__(self, descriptor, name, "u8", args) def definition_body(self): @@ -2881,6 +2992,7 @@ class CGStaticSetter(CGAbstractStaticBindingMethod): self.attr) return CGList([checkForArg, call]) + class CGSpecializedForwardingSetter(CGSpecializedSetter): """ A class for generating the code for an IDL attribute forwarding setter. @@ -2907,6 +3019,7 @@ let target_obj = RootedObject::new(cx, v.ptr.to_object()); JS_SetProperty(cx, target_obj.handle(), %s as *const u8 as *const i8, args.get(0)) """ % (str_to_const_array(attrName), attrName, str_to_const_array(forwardToAttrName))) + class CGMemberJITInfo(CGThing): """ A class for generating the JITInfo for a property that points to @@ -2979,7 +3092,7 @@ class CGMemberJITInfo(CGThing): if self.member.slotIndex is not None: assert isAlwaysInSlot or self.member.getExtendedAttribute("Cached") isLazilyCachedInSlot = not isAlwaysInSlot - slotIndex = memberReservedSlot(self.member) + slotIndex = memberReservedSlot(self.member) # noqa:FIXME: memberReservedSlot is not defined # We'll statically assert that this is not too big in # CGUpdateMemberSlotsMethod, in the case when # isAlwaysInSlot is true. @@ -2992,8 +3105,7 @@ class CGMemberJITInfo(CGThing): isAlwaysInSlot, isLazilyCachedInSlot, slotIndex, [self.member.type], None) - if (not self.member.readonly or - self.member.getExtendedAttribute("PutForwards")): + if (not self.member.readonly or self.member.getExtendedAttribute("PutForwards")): setterinfo = ("%s_setterinfo" % self.member.identifier.name) setter = ("set_%s" % self.member.identifier.name) # Setters are always fallible, since they have to do a typed unwrap. @@ -3163,6 +3275,7 @@ class CGMemberJITInfo(CGThing): # Different types return "JSVAL_TYPE_UNKNOWN" + def getEnumValueName(value): # Some enum values can be empty strings. Others might have weird # characters in them. Deal with the former by returning "_empty", @@ -3183,6 +3296,7 @@ def getEnumValueName(value): return "_empty" return MakeNativeName(value) + class CGEnum(CGThing): def __init__(self, enum): CGThing.__init__(self) @@ -3236,6 +3350,7 @@ def convertConstIDLValueToRust(value): raise TypeError("Const value of unhandled type: " + value.type) + class CGConstant(CGThing): def __init__(self, constants): CGThing.__init__(self) @@ -3249,6 +3364,7 @@ class CGConstant(CGThing): return CGIndenter(CGList(stringDecl(m) for m in self.constants)).define() + def getUnionTypeTemplateVars(type, descriptorProvider): # For dictionaries and sequences we need to pass None as the failureCode # for getJSToNativeConversionInfo. @@ -3265,7 +3381,7 @@ def getUnionTypeTemplateVars(type, descriptorProvider): typeName = name elif type.isArray() or type.isSequence(): name = str(type) - #XXXjdm dunno about typeName here + # XXXjdm dunno about typeName here typeName = "/*" + type.name + "*/" elif type.isDOMString(): name = type.name @@ -3295,6 +3411,7 @@ def getUnionTypeTemplateVars(type, descriptorProvider): "jsConversion": jsConversion, } + class CGUnionStruct(CGThing): def __init__(self, type, descriptorProvider): assert not type.nullable() @@ -3311,7 +3428,8 @@ class CGUnionStruct(CGThing): " e%s(%s)," % (v["name"], v["typeName"]) for v in templateVars ] enumConversions = [ - " %s::e%s(ref inner) => inner.to_jsval(cx, rval)," % (self.type, v["name"]) for v in templateVars + " %s::e%s(ref inner) => inner.to_jsval(cx, rval)," + % (self.type, v["name"]) for v in templateVars ] # XXXManishearth The following should be #[must_root], # however we currently allow it till #2661 is fixed @@ -3328,8 +3446,7 @@ impl ToJSValConvertible for %s { } } } -""") % (self.type, "\n".join(enumValues), - self.type, "\n".join(enumConversions)) +""") % (self.type, "\n".join(enumValues), self.type, "\n".join(enumConversions)) class CGUnionConversionStruct(CGThing): @@ -3424,11 +3541,11 @@ class CGUnionConversionStruct(CGThing): else: name = memberType.name match = ( - "match %s::TryConvertTo%s(cx, value) {\n" - " Err(_) => return Err(()),\n" - " Ok(Some(value)) => return Ok(%s::e%s(value)),\n" - " Ok(None) => (),\n" - "}\n") % (self.type, name, self.type, name) + "match %s::TryConvertTo%s(cx, value) {\n" + " Err(_) => return Err(()),\n" + " Ok(Some(value)) => return Ok(%s::e%s(value)),\n" + " Ok(None) => (),\n" + "}\n") % (self.type, name, self.type, name) conversions.append(CGGeneric(match)) names.append(name) @@ -3437,7 +3554,8 @@ class CGUnionConversionStruct(CGThing): "Err(())" % ", ".join(names))) method = CGWrapper( CGIndenter(CGList(conversions, "\n\n")), - pre="fn from_jsval(cx: *mut JSContext, value: HandleValue, _option: ()) -> Result<%s, ()> {\n" % self.type, + pre="fn from_jsval(cx: *mut JSContext,\n" + " value: HandleValue, _option: ()) -> Result<%s, ()> {\n" % self.type, post="\n}") return CGWrapper( CGIndenter(CGList([ @@ -3476,20 +3594,26 @@ class ClassItem: def __init__(self, name, visibility): self.name = name self.visibility = visibility + def declare(self, cgClass): assert False + def define(self, cgClass): assert False + class ClassBase(ClassItem): def __init__(self, name, visibility='pub'): ClassItem.__init__(self, name, visibility) + def declare(self, cgClass): return '%s %s' % (self.visibility, self.name) + def define(self, cgClass): # Only in the header return '' + class ClassMethod(ClassItem): def __init__(self, name, returnType, args, inline=False, static=False, virtual=False, const=False, bodyInHeader=False, @@ -3541,26 +3665,28 @@ class ClassMethod(ClassItem): body = CGIndenter(CGGeneric(self.getBody())).define() body = ' {\n' + body + '\n}' else: - body = ';' - - return string.Template("${decorators}%s" - "${visibility}fn ${name}${templateClause}(${args})${returnType}${const}${override}${body}%s" % - (self.breakAfterReturnDecl, self.breakAfterSelf) - ).substitute({ - 'templateClause': templateClause, - 'decorators': self.getDecorators(True), - 'returnType': (" -> %s" % self.returnType) if self.returnType else "", - 'name': self.name, - 'const': ' const' if self.const else '', - 'override': ' MOZ_OVERRIDE' if self.override else '', - 'args': args, - 'body': body, - 'visibility': self.visibility + ' ' if self.visibility is not 'priv' else '' - }) + body = ';' + + return string.Template( + "${decorators}%s" + "${visibility}fn ${name}${templateClause}(${args})${returnType}${const}${override}${body}%s" % + (self.breakAfterReturnDecl, self.breakAfterSelf) + ).substitute({ + 'templateClause': templateClause, + 'decorators': self.getDecorators(True), + 'returnType': (" -> %s" % self.returnType) if self.returnType else "", + 'name': self.name, + 'const': ' const' if self.const else '', + 'override': ' MOZ_OVERRIDE' if self.override else '', + 'args': args, + 'body': body, + 'visibility': self.visibility + ' ' if self.visibility is not 'priv' else '' + }) def define(self, cgClass): pass + class ClassUsingDeclaration(ClassItem): """" Used for importing a name from a base class into a CGClass @@ -3579,12 +3705,13 @@ class ClassUsingDeclaration(ClassItem): def declare(self, cgClass): return string.Template("""\ using ${baseClass}::${name}; -""").substitute({ 'baseClass': self.baseClass, - 'name': self.name }) +""").substitute({'baseClass': self.baseClass, + 'name': self.name}) def define(self, cgClass): return '' + class ClassConstructor(ClassItem): """ Used for adding a constructor to a CGClass. @@ -3655,7 +3782,7 @@ class ClassConstructor(ClassItem): def declare(self, cgClass): args = ', '.join([a.declare() for a in self.args]) - body = ' ' + self.getBody(cgClass); + body = ' ' + self.getBody(cgClass) body = stripTrailingWhitespace(body.replace('\n', '\n ')) if len(body) > 0: body += '\n' @@ -3663,10 +3790,10 @@ class ClassConstructor(ClassItem): return string.Template("""\ pub fn ${decorators}new(${args}) -> Rc<${className}>${body} -""").substitute({ 'decorators': self.getDecorators(True), - 'className': cgClass.getNameString(), - 'args': args, - 'body': body }) +""").substitute({'decorators': self.getDecorators(True), + 'className': cgClass.getNameString(), + 'args': args, + 'body': body}) def define(self, cgClass): if self.bodyInHeader: @@ -3683,11 +3810,12 @@ pub fn ${decorators}new(${args}) -> Rc<${className}>${body} ${decorators} ${className}::${className}(${args})${initializationList} {${body}} -""").substitute({ 'decorators': self.getDecorators(False), - 'className': cgClass.getNameString(), - 'args': args, - 'initializationList': self.getInitializationList(cgClass), - 'body': body }) +""").substitute({'decorators': self.getDecorators(False), + 'className': cgClass.getNameString(), + 'args': args, + 'initializationList': self.getInitializationList(cgClass), + 'body': body}) + class ClassDestructor(ClassItem): """ @@ -3728,7 +3856,7 @@ class ClassDestructor(ClassItem): def declare(self, cgClass): if self.bodyInHeader: - body = ' ' + self.getBody(); + body = ' ' + self.getBody() body = stripTrailingWhitespace(body.replace('\n', '\n ')) if len(body) > 0: body += '\n' @@ -3738,9 +3866,9 @@ class ClassDestructor(ClassItem): return string.Template("""\ ${decorators}~${className}()${body} -""").substitute({ 'decorators': self.getDecorators(True), - 'className': cgClass.getNameString(), - 'body': body }) +""").substitute({'decorators': self.getDecorators(True), + 'className': cgClass.getNameString(), + 'body': body}) def define(self, cgClass): if self.bodyInHeader: @@ -3755,14 +3883,15 @@ ${decorators}~${className}()${body} ${decorators} ${className}::~${className}() {${body}} -""").substitute({ 'decorators': self.getDecorators(False), - 'className': cgClass.getNameString(), - 'body': body }) +""").substitute({'decorators': self.getDecorators(False), + 'className': cgClass.getNameString(), + 'body': body}) + class ClassMember(ClassItem): def __init__(self, name, type, visibility="priv", static=False, body=None): - self.type = type; + self.type = type self.static = static self.body = body ClassItem.__init__(self, name, visibility) @@ -3778,7 +3907,8 @@ class ClassMember(ClassItem): else: body = "" return '%s %s::%s%s;\n' % (self.type, cgClass.getNameString(), - self.name, body) + self.name, body) + class ClassTypedef(ClassItem): def __init__(self, name, type, visibility="public"): @@ -3792,6 +3922,7 @@ class ClassTypedef(ClassItem): # Only goes in the header return '' + class ClassEnum(ClassItem): def __init__(self, name, entries, values=None, visibility="public"): self.entries = entries @@ -3813,6 +3944,7 @@ class ClassEnum(ClassItem): # Only goes in the header return '' + class ClassUnion(ClassItem): def __init__(self, name, entries, visibility="public"): self.entries = [entry + ";" for entry in entries] @@ -3825,10 +3957,11 @@ class ClassUnion(ClassItem): # Only goes in the header return '' + class CGClass(CGThing): def __init__(self, name, bases=[], members=[], constructors=[], destructor=None, methods=[], - typedefs = [], enums=[], unions=[], templateArgs=[], + typedefs=[], enums=[], unions=[], templateArgs=[], templateSpecialization=[], isStruct=False, disallowCopyConstruction=False, indent='', decorators='', @@ -3868,8 +4001,7 @@ class CGClass(CGThing): if self.templateArgs: templateArgs = [a.declare() for a in self.templateArgs] templateArgs = templateArgs[len(self.templateSpecialization):] - result = result + self.indent + 'template <%s>\n' \ - % ','.join([str(a) for a in templateArgs]) + result = result + self.indent + 'template <%s>\n' % ','.join([str(a) for a in templateArgs]) if self.templateSpecialization: specialization = \ @@ -3883,7 +4015,7 @@ class CGClass(CGThing): myself += '%spub struct %s%s' % (self.indent, self.name, specialization) result += myself - assert len(self.bases) == 1 #XXjdm Can we support multiple inheritance? + assert len(self.bases) == 1 # XXjdm Can we support multiple inheritance? result += ' {\n' @@ -3906,6 +4038,7 @@ class CGClass(CGThing): class DisallowedCopyConstructor(object): def __init__(self): self.visibility = "private" + def declare(self, cgClass): name = cgClass.getNameString() return ("%s(const %s&) MOZ_DELETE;\n" @@ -3939,6 +4072,7 @@ class CGClass(CGThing): result += "}" return result + class CGProxySpecialOperation(CGPerSignatureCall): """ Base class for classes for calling an indexed or named special operation @@ -3972,8 +4106,8 @@ class CGProxySpecialOperation(CGPerSignatureCall): "val": "value.handle()", } self.cgRoot.prepend(instantiateJSToNativeConversionTemplate( - template, templateValues, declType, argument.identifier.name, - needsRooting)) + template, templateValues, declType, argument.identifier.name, + needsRooting)) self.cgRoot.prepend(CGGeneric("let value = RootedValue::new(cx, desc.get().value);")) elif operation.isGetter(): self.cgRoot.prepend(CGGeneric("let mut found = false;")) @@ -3999,6 +4133,7 @@ class CGProxySpecialOperation(CGPerSignatureCall): wrap = CGIfWrapper(wrap, "found") return "\n" + wrap.define() + class CGProxyIndexedGetter(CGProxySpecialOperation): """ Class to generate a call to an indexed getter. If templateValues is not None @@ -4008,6 +4143,7 @@ class CGProxyIndexedGetter(CGProxySpecialOperation): self.templateValues = templateValues CGProxySpecialOperation.__init__(self, descriptor, 'IndexedGetter') + class CGProxyIndexedSetter(CGProxySpecialOperation): """ Class to generate a call to an indexed setter. @@ -4015,6 +4151,7 @@ class CGProxyIndexedSetter(CGProxySpecialOperation): def __init__(self, descriptor): CGProxySpecialOperation.__init__(self, descriptor, 'IndexedSetter') + class CGProxyNamedGetter(CGProxySpecialOperation): """ Class to generate a call to an named getter. If templateValues is not None @@ -4024,6 +4161,7 @@ class CGProxyNamedGetter(CGProxySpecialOperation): self.templateValues = templateValues CGProxySpecialOperation.__init__(self, descriptor, 'NamedGetter') + class CGProxyNamedPresenceChecker(CGProxyNamedGetter): """ Class to generate a call that checks whether a named property exists. @@ -4032,6 +4170,7 @@ class CGProxyNamedPresenceChecker(CGProxyNamedGetter): def __init__(self, descriptor): CGProxyNamedGetter.__init__(self, descriptor) + class CGProxyNamedSetter(CGProxySpecialOperation): """ Class to generate a call to a named setter. @@ -4039,6 +4178,7 @@ class CGProxyNamedSetter(CGProxySpecialOperation): def __init__(self, descriptor): CGProxySpecialOperation.__init__(self, descriptor, 'NamedSetter') + class CGProxyNamedDeleter(CGProxySpecialOperation): """ Class to generate a call to a named deleter. @@ -4050,7 +4190,8 @@ class CGProxyNamedDeleter(CGProxySpecialOperation): class CGProxyUnwrap(CGAbstractMethod): def __init__(self, descriptor): args = [Argument('HandleObject', 'obj')] - CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", '*const ' + descriptor.concreteType, args, alwaysInline=True) + CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", + '*const ' + descriptor.concreteType, args, alwaysInline=True) def definition_body(self): return CGGeneric("""\ @@ -4061,6 +4202,7 @@ class CGProxyUnwrap(CGAbstractMethod): let box_ = GetProxyPrivate(*obj.ptr).to_private() as *const %s; return box_;""" % self.descriptor.concreteType) + class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): def __init__(self, descriptor): args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'), @@ -4069,6 +4211,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): CGAbstractExternMethod.__init__(self, descriptor, "getOwnPropertyDescriptor", "u8", args) self.descriptor = descriptor + def getBody(self): indexedGetter = self.descriptor.operations['IndexedGetter'] indexedSetter = self.descriptor.operations['IndexedSetter'] @@ -4079,12 +4222,14 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): if indexedGetter: readonly = toStringBool(self.descriptor.operations['IndexedSetter'] is None) - fillDescriptor = "desc.get().value = result_root.ptr;\nfill_property_descriptor(&mut *desc.ptr, *proxy.ptr, %s);\nreturn JSTrue;" % readonly + fillDescriptor = ("desc.get().value = result_root.ptr;\n" + "fill_property_descriptor(&mut *desc.ptr, *proxy.ptr, %s);\n" + "return JSTrue;" % readonly) templateValues = { 'jsvalRef': 'result_root.handle_mut()', 'successCode': fillDescriptor, 'pre': 'let mut result_root = RootedValue::new(cx, UndefinedValue());' - } + } get += ("if index.is_some() {\n" + " let index = index.unwrap();\n" + " let this = UnwrapProxy(proxy);\n" + @@ -4095,12 +4240,14 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): namedGetter = self.descriptor.operations['NamedGetter'] if namedGetter: readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None) - fillDescriptor = "desc.get().value = result_root.ptr;\nfill_property_descriptor(&mut *desc.ptr, *proxy.ptr, %s);\nreturn JSTrue;" % readonly + fillDescriptor = ("desc.get().value = result_root.ptr;\n" + "fill_property_descriptor(&mut *desc.ptr, *proxy.ptr, %s);\n" + "return JSTrue;" % readonly) templateValues = { 'jsvalRef': 'result_root.handle_mut()', 'successCode': fillDescriptor, 'pre': 'let mut result_root = RootedValue::new(cx, UndefinedValue());' - } + } # Once we start supporting OverrideBuiltins we need to make # ResolveOwnProperty or EnumerateOwnProperties filter out named # properties that shadow prototype properties. @@ -4134,6 +4281,7 @@ return JSTrue;""" def definition_body(self): return CGGeneric(self.getBody()) + # TODO(Issue 5876) class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): def __init__(self, descriptor): @@ -4143,6 +4291,7 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): Argument('*mut ObjectOpResult', 'opresult')] CGAbstractExternMethod.__init__(self, descriptor, "defineProperty", "u8", args) self.descriptor = descriptor + def getBody(self): set = "" @@ -4201,6 +4350,7 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): def definition_body(self): return CGGeneric(self.getBody()) + class CGDOMJSProxyHandler_delete(CGAbstractExternMethod): def __init__(self, descriptor): args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'), @@ -4222,12 +4372,14 @@ class CGDOMJSProxyHandler_delete(CGAbstractExternMethod): def definition_body(self): return CGGeneric(self.getBody()) + class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod): def __init__(self, descriptor): args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'), Argument('HandleId', 'id'), Argument('*mut u8', 'bp')] CGAbstractExternMethod.__init__(self, descriptor, "hasOwn", "u8", args) self.descriptor = descriptor + def getBody(self): indexedGetter = self.descriptor.operations['IndexedGetter'] if indexedGetter: @@ -4274,6 +4426,7 @@ return JSTrue;""" def definition_body(self): return CGGeneric(self.getBody()) + class CGDOMJSProxyHandler_get(CGAbstractExternMethod): def __init__(self, descriptor): args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'), @@ -4281,6 +4434,7 @@ class CGDOMJSProxyHandler_get(CGAbstractExternMethod): Argument('MutableHandleValue', 'vp')] CGAbstractExternMethod.__init__(self, descriptor, "get", "u8", args) self.descriptor = descriptor + def getBody(self): getFromExpando = """\ let expando = RootedObject::new(cx, get_expando_object(proxy)); @@ -4349,17 +4503,20 @@ return JSTrue;""" % (getIndexedOrExpando, getNamed) def definition_body(self): return CGGeneric(self.getBody()) + class CGDOMJSProxyHandler_className(CGAbstractExternMethod): def __init__(self, descriptor): args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', '_proxy')] CGAbstractExternMethod.__init__(self, descriptor, "className", "*const i8", args) self.descriptor = descriptor + def getBody(self): return '%s as *const u8 as *const i8' % str_to_const_array(self.descriptor.name) def definition_body(self): return CGGeneric(self.getBody()) + class CGAbstractClassHook(CGAbstractExternMethod): """ Meant for implementing JSClass hooks, like Finalize or Trace. Does very raw @@ -4384,6 +4541,7 @@ let this: *const %s = native_from_reflector::<%s>(obj); # Override me assert(False) + def finalizeHook(descriptor, hookName, context): release = "" if descriptor.isGlobal(): @@ -4396,6 +4554,7 @@ debug!("%s finalize: {:p}", this);\ """ % (descriptor.concreteType, descriptor.concreteType) return release + class CGClassTraceHook(CGAbstractClassHook): """ A hook to trace through our native object; used for GC and CC @@ -4413,6 +4572,7 @@ class CGClassTraceHook(CGAbstractClassHook): body += [CGGeneric("trace_global(trc, obj);")] return CGList(body, "\n") + class CGClassConstructHook(CGAbstractExternMethod): """ JS-visible constructor for our objects @@ -4439,6 +4599,7 @@ let args = CallArgs::from_vp(vp, argc); self.descriptor, self._ctor) return CGList([preamble, callGenerator]) + class CGClassNameConstructHook(CGAbstractExternMethod): """ JS-visible named constructor for our objects @@ -4448,7 +4609,7 @@ class CGClassNameConstructHook(CGAbstractExternMethod): self._ctor = ctor CGAbstractExternMethod.__init__(self, descriptor, CONSTRUCT_HOOK_NAME + "_" + - self._ctor.identifier.name, + self._ctor.identifier.name, 'u8', args) def definition_body(self): @@ -4475,6 +4636,7 @@ class CGClassFinalizeHook(CGAbstractClassHook): def generate_code(self): return CGGeneric(finalizeHook(self.descriptor, self.name, self.args[0].name)) + class CGDOMJSProxyHandlerDOMClass(CGThing): def __init__(self, descriptor): CGThing.__init__(self) @@ -4488,7 +4650,6 @@ class CGInterfaceTrait(CGThing): def __init__(self, descriptor): CGThing.__init__(self) - def attribute_arguments(needCx, argument=None): if needCx: yield "cx", "*mut JSContext" @@ -4496,11 +4657,10 @@ class CGInterfaceTrait(CGThing): if argument: yield "value", argument_type(descriptor, argument) - def members(): for m in descriptor.interface.members: if (m.isMethod() and not m.isStatic() and - (not m.isIdentifierLess() or m.isStringifier())): + (not m.isIdentifierLess() or m.isStringifier())): name = CGSpecializedMethod.makeNativeName(descriptor, m) infallible = 'infallible' in descriptor.getExtendedAttributes(m) for idx, (rettype, arguments) in enumerate(m.signatures()): @@ -4510,7 +4670,9 @@ class CGInterfaceTrait(CGThing): elif m.isAttr() and not m.isStatic(): name = CGSpecializedGetter.makeNativeName(descriptor, m) infallible = 'infallible' in descriptor.getExtendedAttributes(m, getter=True) - yield name, attribute_arguments(typeNeedsCx(m.type, True)), return_type(descriptor, m.type, infallible) + yield (name, + attribute_arguments(typeNeedsCx(m.type, True)), + return_type(descriptor, m.type, infallible)) if not m.readonly: name = CGSpecializedSetter.makeNativeName(descriptor, m) @@ -4571,7 +4733,7 @@ class CGDescriptor(CGThing): for m in descriptor.interface.members: if (m.isMethod() and - (not m.isIdentifierLess() or m == descriptor.operations["Stringifier"])): + (not m.isIdentifierLess() or m == descriptor.operations["Stringifier"])): if m.isStatic(): assert descriptor.interface.hasInterfaceObject() cgThings.append(CGStaticMethod(descriptor, m)) @@ -4599,8 +4761,7 @@ class CGDescriptor(CGThing): elif m.getExtendedAttribute("PutForwards"): cgThings.append(CGSpecializedForwardingSetter(descriptor, m)) - if (not m.isStatic() and - not descriptor.interface.isCallback()): + if (not m.isStatic() and not descriptor.interface.isCallback()): cgThings.append(CGMemberJITInfo(descriptor, m)) if descriptor.concrete: @@ -4634,7 +4795,7 @@ class CGDescriptor(CGThing): if descriptor.concrete: if descriptor.proxy: - #cgThings.append(CGProxyIsProxy(descriptor)) + # cgThings.append(CGProxyIsProxy(descriptor)) cgThings.append(CGProxyUnwrap(descriptor)) cgThings.append(CGDOMJSProxyHandlerDOMClass(descriptor)) cgThings.append(CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor)) @@ -4651,8 +4812,8 @@ class CGDescriptor(CGThing): if descriptor.operations['NamedDeleter']: cgThings.append(CGDOMJSProxyHandler_delete(descriptor)) - #cgThings.append(CGDOMJSProxyHandler(descriptor)) - #cgThings.append(CGIsMethod(descriptor)) + # cgThings.append(CGDOMJSProxyHandler(descriptor)) + # cgThings.append(CGIsMethod(descriptor)) pass else: cgThings.append(CGDOMJSClass(descriptor)) @@ -4665,14 +4826,15 @@ class CGDescriptor(CGThing): cgThings.append(CGInterfaceTrait(descriptor)) cgThings = CGList(cgThings, "\n") - #self.cgRoot = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name), - # cgThings), - # post='\n') + # self.cgRoot = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name), + # cgThings), + # post='\n') self.cgRoot = cgThings def define(self): return self.cgRoot.define() + class CGNonNamespacedEnum(CGThing): def __init__(self, enumName, names, values, comment="", deriving="", repr=""): @@ -4703,11 +4865,11 @@ class CGNonNamespacedEnum(CGThing): curr = CGGeneric(enumstr) # Add some whitespace padding. - curr = CGWrapper(curr, pre='\n',post='\n') + curr = CGWrapper(curr, pre='\n', post='\n') # Add the typedef - #typedef = '\ntypedef %s::%s %s;\n\n' % (namespace, enumName, enumName) - #curr = CGList([curr, CGGeneric(typedef)]) + # typedef = '\ntypedef %s::%s %s;\n\n' % (namespace, enumName, enumName) + # curr = CGList([curr, CGGeneric(typedef)]) # Save the result. self.node = curr @@ -4715,9 +4877,10 @@ class CGNonNamespacedEnum(CGThing): def define(self): return self.node.define() + class CGDictionary(CGThing): def __init__(self, dictionary, descriptorProvider): - self.dictionary = dictionary; + self.dictionary = dictionary if all(CGDictionary(d, descriptorProvider).generatable for d in CGDictionary.getDictionaryDependencies(dictionary)): self.generatable = True @@ -4734,7 +4897,7 @@ class CGDictionary(CGThing): defaultValue=member.defaultValue, failureCode="return Err(());", exceptionCode="return Err(());")) - for member in dictionary.members ] + for member in dictionary.members] def define(self): if not self.generatable: @@ -4757,8 +4920,8 @@ class CGDictionary(CGThing): "pub struct ${selfName} {\n" + "${inheritance}" + "\n".join(memberDecls) + "\n" + - "}").substitute( { "selfName": self.makeClassName(d), - "inheritance": inheritance })) + "}").substitute({"selfName": self.makeClassName(d), + "inheritance": inheritance})) def impl(self): d = self.dictionary @@ -4778,7 +4941,10 @@ class CGDictionary(CGThing): def memberInsert(memberInfo): member, _ = memberInfo name = self.makeMemberName(member.identifier.name) - insertion = ("let mut %s = RootedValue::new(cx, UndefinedValue());\nself.%s.to_jsval(cx, %s.handle_mut());\nset_dictionary_property(cx, obj.handle(), \"%s\", %s.handle()).unwrap();" % (name, name, name, name, name)) + insertion = ("let mut %s = RootedValue::new(cx, UndefinedValue());\n" + "self.%s.to_jsval(cx, %s.handle_mut());\n" + "set_dictionary_property(cx, obj.handle(), \"%s\", %s.handle()).unwrap();" + % (name, name, name, name, name)) return CGGeneric("%s\n" % insertion) memberInits = CGList([memberInit(m) for m in self.memberInfo]) @@ -4816,7 +4982,7 @@ class CGDictionary(CGThing): "initParent": CGIndenter(CGGeneric(initParent), indentLevel=12).define(), "initMembers": CGIndenter(memberInits, indentLevel=12).define(), "insertMembers": CGIndenter(memberInserts, indentLevel=8).define(), - }) + }) @staticmethod def makeDictionaryName(dictionary): @@ -4843,8 +5009,7 @@ class CGDictionary(CGThing): member, info = memberInfo templateBody = info.template default = info.default - declType = info.declType - replacements = { "val": "rval.handle()" } + replacements = {"val": "rval.handle()"} conversion = string.Template(templateBody).substitute(replacements) if memberType.isAny(): conversion = "%s.get()" % conversion @@ -4868,7 +5033,6 @@ class CGDictionary(CGThing): return CGGeneric(conversion) - @staticmethod def makeIdName(name): return name + "_id" @@ -4882,7 +5046,7 @@ class CGDictionary(CGThing): @staticmethod def getDictionaryDependencies(dictionary): - deps = set(); + deps = set() if dictionary.parent: deps.add(dictionary.parent) for member in dictionary.members: @@ -4890,6 +5054,7 @@ class CGDictionary(CGThing): deps.add(member.type.unroll().inner) return deps + class CGRegisterProtos(CGAbstractMethod): def __init__(self, config): arguments = [ @@ -4915,7 +5080,8 @@ class CGRegisterProxyHandlersMethod(CGAbstractMethod): def definition_body(self): return CGList([ - CGGeneric("proxy_handlers[Proxies::%s as usize] = codegen::Bindings::%sBinding::DefineProxyHandler();" % (desc.name, desc.name)) + CGGeneric("proxy_handlers[Proxies::%s as usize] = codegen::Bindings::%sBinding::DefineProxyHandler();" + % (desc.name, desc.name)) for desc in self.descriptors ], "\n") @@ -4925,7 +5091,8 @@ class CGRegisterProxyHandlers(CGThing): descriptors = config.getDescriptors(proxy=True) length = len(descriptors) self.root = CGList([ - CGGeneric("pub static mut proxy_handlers: [*const libc::c_void; %d] = [0 as *const libc::c_void; %d];" % (length, length)), + CGGeneric("pub static mut proxy_handlers: [*const libc::c_void; %d] = [0 as *const libc::c_void; %d];" + % (length, length)), CGRegisterProxyHandlersMethod(descriptors), ], "\n") @@ -4979,8 +5146,8 @@ class CGBindingRoot(CGThing): curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n") # Wrap all of that in our namespaces. - #curr = CGNamespace.build(['dom'], - # CGWrapper(curr, pre="\n")) + # curr = CGNamespace.build(['dom'], + # CGWrapper(curr, pre="\n")) # Add imports curr = CGImports(curr, descriptors + callbackDescriptors, mainCallbacks, [ @@ -4997,8 +5164,8 @@ class CGBindingRoot(CGThing): 'js::jsapi::{JS_NewObjectWithGivenProto, JS_NewObject, IsCallable, JS_SetProperty, JS_SetPrototype}', 'js::jsapi::{JS_SetReservedSlot, JS_WrapValue, JSContext}', 'js::jsapi::{JSClass, FreeOp, JSFreeOp, JSFunctionSpec, jsid}', - 'js::jsapi::{MutableHandleValue, MutableHandleObject, HandleObject, HandleValue, RootedObject, RootedValue}', - 'js::jsapi::{JSNativeWrapper, JSNative, JSObject, JSPropertyDescriptor}', + 'js::jsapi::{MutableHandleValue, MutableHandleObject, HandleObject, HandleValue, RootedObject}', + 'js::jsapi::{RootedValue, JSNativeWrapper, JSNative, JSObject, JSPropertyDescriptor}', 'js::jsapi::{JSPropertySpec}', 'js::jsapi::{JSString, JSTracer, JSJitInfo, JSJitInfo_OpType, JSJitInfo_AliasSet}', 'js::jsapi::{MutableHandle, Handle, HandleId, JSType, JSValueType}', @@ -5085,6 +5252,7 @@ class CGBindingRoot(CGThing): def define(self): return stripTrailingWhitespace(self.root.define()) + def argument_type(descriptorProvider, ty, optional=False, defaultValue=None, variadic=False): info = getJSToNativeConversionInfo( ty, descriptorProvider, isArgument=True) @@ -5100,24 +5268,27 @@ def argument_type(descriptorProvider, ty, optional=False, defaultValue=None, var return declType.define() + def method_arguments(descriptorProvider, returnType, arguments, passJSBits=True, trailing=None): if needCx(returnType, arguments, passJSBits): yield "cx", "*mut JSContext" for argument in arguments: ty = argument_type(descriptorProvider, argument.type, argument.optional, - argument.defaultValue, argument.variadic) + argument.defaultValue, argument.variadic) yield CGDictionary.makeMemberName(argument.identifier.name), ty if trailing: yield trailing + def return_type(descriptorProvider, rettype, infallible): result = getRetvalDeclarationForType(rettype, descriptorProvider) if not infallible: result = CGWrapper(result, pre="Fallible<", post=">") return result.define() + class CGNativeMember(ClassMethod): def __init__(self, descriptorProvider, member, name, signature, extendedAttrs, breakAfter=True, passJSBitsAsNeeded=True, visibility="public", @@ -5158,6 +5329,7 @@ class CGNativeMember(ClassMethod): argList, self.passJSBitsAsNeeded)] + class CGCallback(CGClass): def __init__(self, idlObject, descriptorProvider, baseName, methods, getters=[], setters=[]): @@ -5179,7 +5351,7 @@ class CGCallback(CGClass): CGClass.__init__(self, name, bases=[ClassBase(baseName)], constructors=self.getConstructors(), - methods=realMethods+getters+setters, + methods=realMethods + getters + setters, decorators="#[derive(JSTraceable, PartialEq)]") def getConstructors(self): @@ -5190,7 +5362,7 @@ class CGCallback(CGClass): explicit=False, baseConstructors=[ "%s::new()" % self.baseName - ])] + ])] def getMethodImpls(self, method): assert method.needThisHandling @@ -5213,7 +5385,7 @@ class CGCallback(CGClass): # And now insert our template argument. argsWithoutThis = list(args) - args.insert(0, Argument("&T", "thisObj")) + args.insert(0, Argument("&T", "thisObj")) # And the self argument method.args.insert(0, Argument(None, "&self")) @@ -5226,29 +5398,29 @@ class CGCallback(CGClass): "}\n") bodyWithThis = string.Template( - setupCall+ + setupCall + "let mut thisObjJS = RootedObject::new(s.get_context(), ptr::null_mut());\n" "wrap_call_this_object(s.get_context(), thisObj, thisObjJS.handle_mut());\n" "if thisObjJS.ptr.is_null() {\n" " return Err(JSFailed);\n" "}\n" "return ${methodName}(${callArgs});").substitute({ - "callArgs" : ", ".join(argnamesWithThis), + "callArgs": ", ".join(argnamesWithThis), "methodName": 'self.' + method.name, - }) + }) bodyWithoutThis = string.Template( setupCall + "let thisObjJS = RootedObject::new(s.get_context(), ptr::null_mut());" "return ${methodName}(${callArgs});").substitute({ - "callArgs" : ", ".join(argnamesWithoutThis), + "callArgs": ", ".join(argnamesWithoutThis), "methodName": 'self.' + method.name, - }) - return [ClassMethod(method.name+'_', method.returnType, args, + }) + return [ClassMethod(method.name + '_', method.returnType, args, bodyInHeader=True, templateArgs=["T: Reflectable"], body=bodyWithThis, visibility='pub'), - ClassMethod(method.name+'__', method.returnType, argsWithoutThis, + ClassMethod(method.name + '__', method.returnType, argsWithoutThis, bodyInHeader=True, body=bodyWithoutThis, visibility='pub'), @@ -5257,6 +5429,7 @@ class CGCallback(CGClass): def deps(self): return self._deps + # We're always fallible def callbackGetterName(attr, descriptor): return "Get" + MakeNativeName( @@ -5277,6 +5450,7 @@ class CGCallbackFunction(CGCallback): def getConstructors(self): return CGCallback.getConstructors(self) + class CGCallbackFunctionImpl(CGGeneric): def __init__(self, callback): impl = string.Template("""\ @@ -5298,6 +5472,7 @@ impl ToJSValConvertible for ${type} { """).substitute({"type": callback.name}) CGGeneric.__init__(self, impl) + class CGCallbackInterface(CGCallback): def __init__(self, descriptor): iface = descriptor.interface @@ -5313,18 +5488,24 @@ class CGCallbackInterface(CGCallback): CGCallback.__init__(self, iface, descriptor, "CallbackInterface", methods, getters=getters, setters=setters) + class FakeMember(): def __init__(self): self.treatNullAs = "Default" + def isStatic(self): return False + def isAttr(self): return False + def isMethod(self): return False + def getExtendedAttribute(self, name): return None + class CallbackMember(CGNativeMember): def __init__(self, sig, name, descriptorProvider, needThisHandling): """ @@ -5338,7 +5519,7 @@ class CallbackMember(CGNativeMember): self.argCount = len(args) if self.argCount > 0: # Check for variadic arguments - lastArg = args[self.argCount-1] + lastArg = args[self.argCount - 1] if lastArg.variadic: self.argCountStr = ( "(%d - 1) + %s.len()" % (self.argCount, @@ -5370,12 +5551,12 @@ class CallbackMember(CGNativeMember): "convertArgs": self.getArgConversions(), "doCall": self.getCall(), "setupCall": self.getCallSetup(), - } + } if self.argCount > 0: replacements["argCount"] = self.argCountStr replacements["argvDecl"] = string.Template( "let mut argv = repeat(UndefinedValue()).take(${argCount}).collect::<Vec<_>>();\n" - ).substitute(replacements) + ).substitute(replacements) else: # Avoid weird 0-sized arrays replacements["argvDecl"] = "" @@ -5430,7 +5611,7 @@ class CallbackMember(CGNativeMember): in enumerate(self.originalSig[1])] # Do them back to front, so our argc modifications will work # correctly, because we examine trailing arguments first. - argConversions.reverse(); + argConversions.reverse() argConversions = [CGGeneric(c) for c in argConversions] if self.argCount > 0: argConversions.insert(0, self.getArgcDecl()) @@ -5457,7 +5638,7 @@ class CallbackMember(CGNativeMember): "for idx in 0..${arg}.len() {\n" + CGIndenter(CGGeneric(conversion)).define() + "\n" "}" - ).substitute({ "arg": arg.identifier.name }) + ).substitute({"arg": arg.identifier.name}) elif arg.optional and not arg.defaultValue: conversion = ( CGIfWrapper(CGGeneric(conversion), @@ -5467,7 +5648,7 @@ class CallbackMember(CGNativeMember): " argc -= 1;\n" "} else {\n" " argv[%d] = UndefinedValue();\n" - "}" % (i+1, i)) + "}" % (i + 1, i)) return conversion def getArgs(self, returnType, argList): @@ -5495,7 +5676,7 @@ class CallbackMember(CGNativeMember): "}\n") def getArgcDecl(self): - return CGGeneric("let mut argc = %s;" % self.argCountStr); + return CGGeneric("let mut argc = %s;" % self.argCountStr) @staticmethod def ensureASCIIName(idlObject): @@ -5512,10 +5693,12 @@ class CallbackMember(CGNativeMember): (type, idlObject.identifier.name, idlObject.location)) + class CallbackMethod(CallbackMember): def __init__(self, sig, name, descriptorProvider, needThisHandling): CallbackMember.__init__(self, sig, name, descriptorProvider, needThisHandling) + def getRvalDecl(self): return "let mut rval = RootedValue::new(cx, UndefinedValue());\n" @@ -5523,22 +5706,28 @@ class CallbackMethod(CallbackMember): replacements = { "thisObj": self.getThisObj(), "getCallable": self.getCallableDecl() - } + } if self.argCount > 0: replacements["argv"] = "argv.as_ptr()" replacements["argc"] = "argc" else: replacements["argv"] = "ptr::null_mut()" replacements["argc"] = "0" - return string.Template("${getCallable}" - "let ok = unsafe {\n" - " let rootedThis = RootedObject::new(cx, ${thisObj});\n" - " JS_CallFunctionValue(cx, rootedThis.handle(), callable.handle(),\n" - " &HandleValueArray { length_: ${argc} as ::libc::size_t, elements_: ${argv} }, rval.handle_mut())\n" - "};\n" - "if ok == 0 {\n" - " return Err(JSFailed);\n" - "}\n").substitute(replacements) + return string.Template( + "${getCallable}" + "let ok = unsafe {\n" + " let rootedThis = RootedObject::new(cx, ${thisObj});\n" + " JS_CallFunctionValue(\n" + " cx, rootedThis.handle(), callable.handle(),\n" + " &HandleValueArray {\n" + " length_: ${argc} as ::libc::size_t,\n" + " elements_: ${argv}\n" + " }, rval.handle_mut())\n" + "};\n" + "if ok == 0 {\n" + " return Err(JSFailed);\n" + "}\n").substitute(replacements) + class CallCallback(CallbackMethod): def __init__(self, callback, descriptorProvider): @@ -5551,6 +5740,7 @@ class CallCallback(CallbackMethod): def getCallableDecl(self): return "let callable = RootedValue::new(cx, ObjectValue(unsafe {&*self.parent.callback()}));\n" + class CallbackOperationBase(CallbackMethod): """ Common class for implementing various callback operations. @@ -5585,6 +5775,7 @@ class CallbackOperationBase(CallbackMethod): CGGeneric('unsafe { RootedValue::new(cx, ObjectValue(&*self.parent.callback())) }'), CGGeneric(getCallableFromProp))).define() + ';\n') + class CallbackOperation(CallbackOperationBase): """ Codegen actual WebIDL operations on callback interfaces. @@ -5597,6 +5788,7 @@ class CallbackOperation(CallbackOperationBase): MakeNativeName(descriptor.binaryNameFor(jsName)), descriptor, descriptor.interface.isSingleOperationInterface()) + class CallbackGetter(CallbackMember): def __init__(self, attr, descriptor): self.ensureASCIIName(attr) @@ -5617,7 +5809,8 @@ class CallbackGetter(CallbackMember): return string.Template( 'if (!JS_GetProperty(cx, mCallback, "${attrName}", &rval)) {\n' ' return Err(JSFailed);\n' - '}\n').substitute(replacements); + '}\n').substitute(replacements) + class CallbackSetter(CallbackMember): def __init__(self, attr, descriptor): @@ -5638,7 +5831,7 @@ class CallbackSetter(CallbackMember): replacements = { "attrName": self.attrName, "argv": "argv.handleAt(0)", - } + } return string.Template( 'MOZ_ASSERT(argv.length() == 1);\n' 'if (!JS_SetProperty(cx, mCallback, "${attrName}", ${argv})) {\n' @@ -5648,6 +5841,7 @@ class CallbackSetter(CallbackMember): def getArgcDecl(self): return None + class GlobalGenRoots(): """ Roots for global codegen. @@ -5678,7 +5872,6 @@ class GlobalGenRoots(): CGNonNamespacedEnum('Proxies', proxies, [0], deriving="PartialEq, Copy, Clone"), ]) - @staticmethod def RegisterBindings(config): # TODO - Generate the methods we want diff --git a/components/script/dom/bindings/codegen/Configuration.py b/components/script/dom/bindings/codegen/Configuration.py index 6e4bcbed34c..436823a9329 100644 --- a/components/script/dom/bindings/codegen/Configuration.py +++ b/components/script/dom/bindings/codegen/Configuration.py @@ -1,11 +1,12 @@ # This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this file, -# You can obtain one at http://mozilla.org/MPL/2.0/. +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. from WebIDL import IDLInterface autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n" + class Configuration: """ Represents global configuration state based on IDL parse data and @@ -22,7 +23,7 @@ class Configuration: # |parseData|. self.descriptors = [] self.interfaces = {} - self.maxProtoChainLength = 0; + self.maxProtoChainLength = 0 for thing in parseData: # Some toplevel things are sadly types, and those have an # isInterface that doesn't mean the same thing as IDLObject's @@ -44,7 +45,8 @@ class Configuration: if not isinstance(entry, list): assert isinstance(entry, dict) entry = [entry] - self.descriptors.extend([Descriptor(self, iface, x) for x in entry]) + self.descriptors.extend( + [Descriptor(self, iface, x) for x in entry]) # Mark the descriptors for which only a single nativeType implements # an interface. @@ -60,10 +62,11 @@ class Configuration: c.isCallback() and not c.isInterface()] # Keep the descriptor list sorted for determinism. - self.descriptors.sort(lambda x,y: cmp(x.name, y.name)) + self.descriptors.sort(lambda x, y: cmp(x.name, y.name)) def getInterface(self, ifname): return self.interfaces[ifname] + def getDescriptors(self, **filters): """Gets the descriptors that match the given filters.""" curr = self.descriptors @@ -80,6 +83,7 @@ class Configuration: getter = lambda x: getattr(x, key) curr = filter(lambda x: getter(x) == val, curr) return curr + def getEnums(self, webIDLFile): return filter(lambda e: e.filename() == webIDLFile, self.enums) @@ -93,6 +97,7 @@ class Configuration: def getDictionaries(self, webIDLFile=""): return self._filterForFile(self.dictionaries, webIDLFile=webIDLFile) + def getCallbacks(self, webIDLFile=""): return self._filterForFile(self.callbacks, webIDLFile=webIDLFile) @@ -104,20 +109,23 @@ class Configuration: descriptors = self.getDescriptors(interface=iface) # We should have exactly one result. - if len(descriptors) is not 1: + if len(descriptors) != 1: raise NoSuchDescriptorError("For " + interfaceName + " found " + - str(len(matches)) + " matches"); + str(len(descriptors)) + " matches") return descriptors[0] + def getDescriptorProvider(self): """ Gets a descriptor provider that can provide descriptors as needed. """ return DescriptorProvider(self) + class NoSuchDescriptorError(TypeError): def __init__(self, str): TypeError.__init__(self, str) + class DescriptorProvider: """ A way of getting descriptors for interface names @@ -132,6 +140,7 @@ class DescriptorProvider: """ return self.config.getDescriptor(interfaceName) + class Descriptor(DescriptorProvider): """ Represents a single descriptor for an interface. See Bindings.conf. @@ -148,7 +157,7 @@ class Descriptor(DescriptorProvider): if self.interface.isCallback(): self.needsRooting = False ty = "%sBinding::%s" % (ifaceName, ifaceName) - self.returnType = "Rc<%s>"% ty + self.returnType = "Rc<%s>" % ty self.argumentType = "???" self.memberType = "???" self.nativeType = ty @@ -230,7 +239,7 @@ class Descriptor(DescriptorProvider): # self.extendedAttributes is a dict of dicts, keyed on # all/getterOnly/setterOnly and then on member name. Values are an # array of extended attributes. - self.extendedAttributes = { 'all': {}, 'getterOnly': {}, 'setterOnly': {} } + self.extendedAttributes = {'all': {}, 'getterOnly': {}, 'setterOnly': {}} def addExtendedAttribute(attribute, config): def add(key, members, attribute): @@ -334,6 +343,7 @@ def getTypesFromDescriptor(descriptor): types.extend(a.type for a in members if a.isAttr()) return types + def getFlatTypes(types): retval = set() for type in types: @@ -344,6 +354,7 @@ def getFlatTypes(types): retval.add(type) return retval + def getTypesFromDictionary(dictionary): """ Get all member types for this dictionary @@ -355,12 +366,13 @@ def getTypesFromDictionary(dictionary): curDict = curDict.parent return types + def getTypesFromCallback(callback): """ Get the types this callback depends on: its return type and the types of its arguments. """ sig = callback.signatures()[0] - types = [sig[0]] # Return type - types.extend(arg.type for arg in sig[1]) # Arguments + types = [sig[0]] # Return type + types.extend(arg.type for arg in sig[1]) # Arguments return types diff --git a/components/script/dom/bindings/codegen/GenerateCSS2PropertiesWebIDL.py b/components/script/dom/bindings/codegen/GenerateCSS2PropertiesWebIDL.py index 1bb50afaee7..55303f6c55b 100644 --- a/components/script/dom/bindings/codegen/GenerateCSS2PropertiesWebIDL.py +++ b/components/script/dom/bindings/codegen/GenerateCSS2PropertiesWebIDL.py @@ -1,6 +1,6 @@ # This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this file, -# You can obtain one at http://mozilla.org/MPL/2.0/. +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. import sys import string @@ -18,9 +18,9 @@ for [prop, pref] in propList: props += " [%s] attribute DOMString %s;\n" % (", ".join(extendedAttrs), prop) -idlFile = open(sys.argv[1], "r"); -idlTemplate = idlFile.read(); -idlFile.close(); +idlFile = open(sys.argv[1], "r") +idlTemplate = idlFile.read() +idlFile.close() print ("/* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT */\n\n" + - string.Template(idlTemplate).substitute({ "props": props })) + string.Template(idlTemplate).substitute({"props": props})) diff --git a/components/script/dom/bindings/codegen/GlobalGen.py b/components/script/dom/bindings/codegen/GlobalGen.py index e596ea44f51..1bebc213e38 100644 --- a/components/script/dom/bindings/codegen/GlobalGen.py +++ b/components/script/dom/bindings/codegen/GlobalGen.py @@ -1,6 +1,6 @@ # This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this file, -# You can obtain one at http://mozilla.org/MPL/2.0/. +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. # We do one global pass over all the WebIDL to generate our prototype enum # and generate information for subsequent phases. @@ -9,12 +9,12 @@ import sys sys.path.append("./parser/") sys.path.append("./ply/") import os -import cStringIO import WebIDL import cPickle -from Configuration import * +from Configuration import Configuration from CodegenRust import GlobalGenRoots, replaceFileIfChanged + def generate_file(config, name, filename): root = getattr(GlobalGenRoots, name)(config) code = root.define() @@ -24,6 +24,7 @@ def generate_file(config, name, filename): else: print "%s hasn't changed - not touching it" % (filename) + def main(): # Parse arguments. from optparse import OptionParser diff --git a/components/script/dom/bindings/codegen/pythonpath.py b/components/script/dom/bindings/codegen/pythonpath.py index 49b2d2f740f..793089551b5 100644 --- a/components/script/dom/bindings/codegen/pythonpath.py +++ b/components/script/dom/bindings/codegen/pythonpath.py @@ -54,7 +54,8 @@ def main(args): # Freeze scope here ... why this makes things work I have no idea ... frozenglobals = globals() -import sys, os +import sys +import os if __name__ == '__main__': main(sys.argv[1:]) diff --git a/components/script/dom/bindings/codegen/test/TestBindingHeader.h b/components/script/dom/bindings/codegen/test/TestBindingHeader.h index 1fbab0a9fb8..20e01813119 100644 --- a/components/script/dom/bindings/codegen/test/TestBindingHeader.h +++ b/components/script/dom/bindings/codegen/test/TestBindingHeader.h @@ -1,8 +1,7 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef TestBindingHeader_h #define TestBindingHeader_h @@ -126,7 +125,7 @@ public: const TestInterfaceOrOnlyForUseInConstructor&, ErrorResult&); */ - + // Integer types int8_t ReadonlyByte(); int8_t WritableByte(); @@ -215,7 +214,8 @@ public: void ReceiveNonWrapperCacheInterfaceSequence(nsTArray<nsRefPtr<TestNonWrapperCacheInterface> >&); void ReceiveNullableNonWrapperCacheInterfaceSequence(nsTArray<nsRefPtr<TestNonWrapperCacheInterface> >&); void ReceiveNonWrapperCacheInterfaceNullableSequence(Nullable<nsTArray<nsRefPtr<TestNonWrapperCacheInterface> > >&); - void ReceiveNullableNonWrapperCacheInterfaceNullableSequence(Nullable<nsTArray<nsRefPtr<TestNonWrapperCacheInterface> > >&); + void ReceiveNullableNonWrapperCacheInterfaceNullableSequence( + Nullable<nsTArray<nsRefPtr<TestNonWrapperCacheInterface> > >&); already_AddRefed<TestNonCastableInterface> ReceiveOther(); already_AddRefed<TestNonCastableInterface> ReceiveNullableOther(); diff --git a/python/tidy.py b/python/tidy.py index 75b372995e1..c65425de01a 100644 --- a/python/tidy.py +++ b/python/tidy.py @@ -32,9 +32,10 @@ ignored_files = [ "python/mozinfo/*", "python/mozlog/*", "python/toml/*", + "components/script/dom/bindings/codegen/parser/*", + "components/script/dom/bindings/codegen/ply/*", # Generated and upstream code combined with our own. Could use cleanup - "components/script/dom/bindings/codegen/*", "components/style/properties/mod.rs", "target/*", "ports/gonk/src/native_window_glue.cpp", @@ -72,7 +73,13 @@ def should_check_reftest(file_name): return file_name.endswith(reftest_filetype) +EMACS_HEADER = "/* -*- Mode:" +VIM_HEADER = "/* vim:" + + def check_license(contents): + while contents.startswith(EMACS_HEADER) or contents.startswith(VIM_HEADER): + _, _, contents = contents.partition("\n") valid_license = any(contents.startswith(license) for license in licenses) acknowledged_bad_license = "xfail-license" in contents[:100] if not (valid_license or acknowledged_bad_license): |