Bug 986492, part 2 - Use fill() and dedent() throughout Codegen.py. Change dedent() to strip an initial blank line from its argument, if present. r=peterv.
authorJason Orendorff <jorendorff@mozilla.com>
Fri, 25 Apr 2014 11:50:34 -0500
changeset 198824 0436eec4d294f73a424e931945a27fe38cd3e028
parent 198823 ac3d60d50ccd112fb7407c2229c086634d5a0b0c
child 198825 d6064bbed583e732e28b5ecdb31d75b780976afe
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs986492
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 986492, part 2 - Use fill() and dedent() throughout Codegen.py. Change dedent() to strip an initial blank line from its argument, if present. r=peterv.
dom/bindings/Codegen.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -5,17 +5,17 @@
 # Common codegen classes.
 
 import operator
 import os
 import re
 import string
 import math
 import itertools
-from textwrap import dedent
+import textwrap
 
 from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute, IDLUndefinedValue
 from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, Descriptor
 
 AUTOGENERATED_WARNING_COMMENT = \
     "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n"
 ADDPROPERTY_HOOK_NAME = '_addProperty'
 FINALIZE_HOOK_NAME = '_finalize'
@@ -70,16 +70,25 @@ def indent(s, indentLevel=2):
     Weird secret feature: this doesn't indent lines that start with # (such as
     #include lines).
     """
     if s == "":
         return s
     return re.sub(lineStartDetector, indentLevel * " ", s)
 
 
+def dedent(s):
+    """
+    Remove all leading whitespace from s, and remove a blank line
+    at the beginning.
+    """
+    if s.startswith('\n'):
+        s = s[1:]
+    return textwrap.dedent(s)
+
 def fill(template, **args):
     """
     Convenience function for filling in a multiline template.
 
     `fill(template, name1=v1, name2=v2)` is a lot like
     `string.Template(template).substitute({"name1": v1, "name2": v2})`.
 
     However, it's shorter, and has a few nice features:
@@ -129,20 +138,17 @@ def fill(template, **args):
         modified_name = name + "_" + str(depth)
         indented_value = indent(args[name], depth)
         if modified_name in args:
             assert args[modified_name] == indented_value
         else:
             args[modified_name] = indented_value
         return "${" + modified_name + "}"
 
-    t = template
-    if t.startswith("\n"):
-        t = t[1:]
-    t = dedent(t)
+    t = dedent(template)
     assert t.endswith("\n") or "\n" not in t
     t = re.sub(multiline_substitution_re, replace, t)
     t = string.Template(t)
     return t.substitute(args)
 
 
 class CGThing():
     """
@@ -221,24 +227,26 @@ class CGNativePropertyHooks(CGThing):
     def __init__(self, descriptor, properties):
         CGThing.__init__(self)
         self.descriptor = descriptor
         self.properties = properties
 
     def declare(self):
         if self.descriptor.workers:
             return ""
-        return """// We declare this as an array so that retrieving a pointer to this
-// binding's property hooks only requires compile/link-time resolvable
-// address arithmetic.  Declaring it as a pointer instead would require
-// doing a run-time load to fetch a pointer to this binding's property
-// hooks.  And then structures which embedded a pointer to this structure
-// would require a run-time load for proper initialization, which would
-// then induce static constructors.  Lots of static constructors.
-extern const NativePropertyHooks sNativePropertyHooks[];"""
+        return dedent("""
+            // We declare this as an array so that retrieving a pointer to this
+            // binding's property hooks only requires compile/link-time resolvable
+            // address arithmetic.  Declaring it as a pointer instead would require
+            // doing a run-time load to fetch a pointer to this binding's property
+            // hooks.  And then structures which embedded a pointer to this structure
+            // would require a run-time load for proper initialization, which would
+            // then induce static constructors.  Lots of static constructors.
+            extern const NativePropertyHooks sNativePropertyHooks[];
+            """).rstrip()  # BOGUS strip newline from the last line here (!)
 
     def define(self):
         if self.descriptor.workers:
             return ""
         if self.descriptor.concrete and self.descriptor.proxy:
             resolveOwnProperty = "ResolveOwnProperty"
             enumerateOwnProperties = "EnumerateOwnProperties"
         elif self.descriptor.needsXrayResolveHooks():
@@ -264,29 +272,34 @@ extern const NativePropertyHooks sNative
         if self.descriptor.interface.hasInterfacePrototypeObject():
             prototypeID += self.descriptor.name
         else:
             prototypeID += "_ID_Count"
         parent = self.descriptor.interface.parent
         parentHooks = (toBindingNamespace(parent.identifier.name) + "::sNativePropertyHooks"
                        if parent else 'nullptr')
 
-        return CGWrapper(CGIndenter(CGList([CGGeneric(resolveOwnProperty),
-                                            CGGeneric(enumerateOwnProperties),
-                                            CGWrapper(CGList([CGGeneric(regular),
-                                                              CGGeneric(chrome)],
-                                                             ", "),
-                                                      pre="{ ", post=" }"),
-                                            CGGeneric(prototypeID),
-                                            CGGeneric(constructorID),
-                                            CGGeneric(parentHooks)],
-                                           ",\n")),
-                         pre="const NativePropertyHooks sNativePropertyHooks[] = { {\n",
-                         post=("\n"
-                               "} };\n")).define()
+        return fill(
+            """
+            const NativePropertyHooks sNativePropertyHooks[] = { {
+              ${resolveOwnProperty},
+              ${enumerateOwnProperties},
+              { ${regular}, ${chrome} },
+              ${prototypeID},
+              ${constructorID},
+              ${parentHooks}
+            } };
+            """,
+            resolveOwnProperty=resolveOwnProperty,
+            enumerateOwnProperties=enumerateOwnProperties,
+            regular=regular,
+            chrome=chrome,
+            prototypeID=prototypeID,
+            constructorID=constructorID,
+            parentHooks=parentHooks)
 
 
 def NativePropertyHooks(descriptor):
     return "&sWorkerNativePropertyHooks" if descriptor.workers else "sNativePropertyHooks"
 
 
 def DOMClass(descriptor):
     def make_name(d):
@@ -488,43 +501,56 @@ def CallOnUnforgeableHolder(descriptor, 
     If isXrayCheck is not None it should be a string that contains a statement
     returning whether proxy is an Xray. If isXrayCheck is None the generated
     code won't try to unwrap Xrays.
 
     If useSharedRoot is true, we will use an existing
     JS::Rooted<JSObject*> sharedRoot for storing our unforgeable holder instead
     of declaring a new Rooted.
     """
-    code = string.Template(code).substitute({"holder": "unforgeableHolder"})
     if not isXrayCheck is None:
-        pre = """// Scope for 'global', 'ac' and 'unforgeableHolder'
-{
-  JS::Rooted<JSObject*> global(cx);
-  Maybe<JSAutoCompartment> ac;
-  if (""" + isXrayCheck + """) {
-    global = js::GetGlobalForObjectCrossCompartment(js::UncheckedUnwrap(proxy));
-    ac.construct(cx, global);
-  } else {
-    global = js::GetGlobalForObjectCrossCompartment(proxy);
-  }"""
+        pre = fill(
+            """
+            // Scope for 'global', 'ac' and 'unforgeableHolder'
+            {
+              JS::Rooted<JSObject*> global(cx);
+              Maybe<JSAutoCompartment> ac;
+              if (${isXrayCheck}) {
+                global = js::GetGlobalForObjectCrossCompartment(js::UncheckedUnwrap(proxy));
+                ac.construct(cx, global);
+              } else {
+                global = js::GetGlobalForObjectCrossCompartment(proxy);
+              }
+            """,
+            isXrayCheck=isXrayCheck)
     else:
-        pre = """// Scope for 'global' and 'unforgeableHolder'
-{
-  JSObject* global = js::GetGlobalForObjectCrossCompartment(proxy);"""
+        pre = dedent("""
+            // Scope for 'global' and 'unforgeableHolder'
+            {
+              JSObject* global = js::GetGlobalForObjectCrossCompartment(proxy);
+            """)
 
     if useSharedRoot:
-        holderDecl = "JS::Rooted<JSObject*>& unforgeableHolder(sharedRoot)"
+        holderDecl = "JS::Rooted<JSObject*>& unforgeableHolder(sharedRoot);\n"
     else:
-        holderDecl = "JS::Rooted<JSObject*> unforgeableHolder(cx)"
-    return (pre + """
-  %s;
-  unforgeableHolder = GetUnforgeableHolder(global, prototypes::id::%s);
-""" + CGIndenter(CGGeneric(code)).define() + """
-}
-""") % (holderDecl, descriptor.name)
+        holderDecl = "JS::Rooted<JSObject*> unforgeableHolder(cx);\n"
+
+    code = string.Template(code).substitute({"holder": "unforgeableHolder"})
+    return fill(
+        """
+        $*{pre}
+          $*{holderDecl}
+          unforgeableHolder = GetUnforgeableHolder(global, prototypes::id::${name});
+          $*{code}
+        }
+        """,
+        pre=pre,
+        holderDecl=holderDecl,
+        name=descriptor.name,
+        code=code)
 
 
 class CGPrototypeJSClass(CGThing):
     def __init__(self, descriptor, properties):
         CGThing.__init__(self)
         self.descriptor = descriptor
         self.properties = properties
 
@@ -532,45 +558,48 @@ class CGPrototypeJSClass(CGThing):
         # We're purely for internal consumption
         return ""
 
     def define(self):
         (prototypeID, depth) = PrototypeIDAndDepth(self.descriptor)
         slotCount = "DOM_INTERFACE_PROTO_SLOTS_BASE"
         if UseHolderForUnforgeable(self.descriptor):
             slotCount += " + 1 /* slot for the JSObject holding the unforgeable properties */"
-        template = """static const DOMIfaceAndProtoJSClass PrototypeClass = {
-  {
-    "%sPrototype",
-    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(%s),
-    JS_PropertyStub,       /* addProperty */
-    JS_DeletePropertyStub, /* delProperty */
-    JS_PropertyStub,       /* getProperty */
-    JS_StrictPropertyStub, /* setProperty */
-    JS_EnumerateStub,
-    JS_ResolveStub,
-    JS_ConvertStub,
-    nullptr,               /* finalize */
-    nullptr,               /* call */
-    nullptr,               /* hasInstance */
-    nullptr,               /* construct */
-    nullptr,               /* trace */
-    JSCLASS_NO_INTERNAL_MEMBERS
-  },
-  eInterfacePrototype,
-  %s,
-  "[object %sPrototype]",
-  %s,
-  %s
-};
-"""
-        return template % (self.descriptor.interface.identifier.name, slotCount,
-                           NativePropertyHooks(self.descriptor),
-                           self.descriptor.interface.identifier.name,
-                           prototypeID, depth)
+        return fill(
+            """
+            static const DOMIfaceAndProtoJSClass PrototypeClass = {
+              {
+                "${name}Prototype",
+                JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(${slotCount}),
+                JS_PropertyStub,       /* addProperty */
+                JS_DeletePropertyStub, /* delProperty */
+                JS_PropertyStub,       /* getProperty */
+                JS_StrictPropertyStub, /* setProperty */
+                JS_EnumerateStub,
+                JS_ResolveStub,
+                JS_ConvertStub,
+                nullptr,               /* finalize */
+                nullptr,               /* call */
+                nullptr,               /* hasInstance */
+                nullptr,               /* construct */
+                nullptr,               /* trace */
+                JSCLASS_NO_INTERNAL_MEMBERS
+              },
+              eInterfacePrototype,
+              ${hooks},
+              "[object ${name}Prototype]",
+              ${prototypeID},
+              ${depth}
+            };
+            """,
+            name=self.descriptor.interface.identifier.name,
+            slotCount=slotCount,
+            hooks=NativePropertyHooks(self.descriptor),
+            prototypeID=prototypeID,
+            depth=depth)
 
 
 def NeedsGeneratedHasInstance(descriptor):
     return descriptor.hasXPConnectImpls or descriptor.interface.isConsequential()
 
 
 class CGInterfaceObjectJSClass(CGThing):
     def __init__(self, descriptor, properties):
@@ -593,46 +622,51 @@ class CGInterfaceObjectJSClass(CGThing):
             hasinstance = "InterfaceHasInstance"
         else:
             hasinstance = "nullptr"
         (prototypeID, depth) = PrototypeIDAndDepth(self.descriptor)
         slotCount = "DOM_INTERFACE_SLOTS_BASE"
         if len(self.descriptor.interface.namedConstructors) > 0:
             slotCount += (" + %i /* slots for the named constructors */" %
                           len(self.descriptor.interface.namedConstructors))
-        template = """
-static const DOMIfaceAndProtoJSClass InterfaceObjectClass = {
-  {
-    "Function",
-    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(%s),
-    JS_PropertyStub,       /* addProperty */
-    JS_DeletePropertyStub, /* delProperty */
-    JS_PropertyStub,       /* getProperty */
-    JS_StrictPropertyStub, /* setProperty */
-    JS_EnumerateStub,
-    JS_ResolveStub,
-    JS_ConvertStub,
-    nullptr,               /* finalize */
-    %s, /* call */
-    %s, /* hasInstance */
-    %s, /* construct */
-    nullptr,               /* trace */
-    JSCLASS_NO_INTERNAL_MEMBERS
-  },
-  eInterface,
-  %s,
-  "function %s() {\\n    [native code]\\n}",
-  %s,
-  %s
-};
-"""
-        return template % (slotCount, ctorname,
-                           hasinstance, ctorname, NativePropertyHooks(self.descriptor),
-                           self.descriptor.interface.identifier.name,
-                           prototypeID, depth)
+        return fill(  # BOGUS extra newline at the top
+            """
+
+            static const DOMIfaceAndProtoJSClass InterfaceObjectClass = {
+              {
+                "Function",
+                JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(${slotCount}),
+                JS_PropertyStub,       /* addProperty */
+                JS_DeletePropertyStub, /* delProperty */
+                JS_PropertyStub,       /* getProperty */
+                JS_StrictPropertyStub, /* setProperty */
+                JS_EnumerateStub,
+                JS_ResolveStub,
+                JS_ConvertStub,
+                nullptr,               /* finalize */
+                ${ctorname}, /* call */
+                ${hasInstance}, /* hasInstance */
+                ${ctorname}, /* construct */
+                nullptr,               /* trace */
+                JSCLASS_NO_INTERNAL_MEMBERS
+              },
+              eInterface,
+              ${hooks},
+              "function ${name}() {\\n    [native code]\\n}",
+              ${prototypeID},
+              ${depth}
+            };
+            """,
+            slotCount=slotCount,
+            ctorname=ctorname,
+            hasInstance=hasinstance,
+            hooks=NativePropertyHooks(self.descriptor),
+            name=self.descriptor.interface.identifier.name,
+            prototypeID=prototypeID,
+            depth=depth)
 
 
 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=""):
@@ -754,29 +788,57 @@ class CGWrapper(CGThing):
         lastLineWidth = len(widthString.splitlines()[-1])
         return stripTrailingWhitespace(
             stringToIndent.replace("\n", "\n" + (" " * lastLineWidth)))
 
     def deps(self):
         return self.child.deps()
 
 
-class CGIfWrapper(CGWrapper):
+class CGIfWrapper(CGList):
     def __init__(self, child, condition):
-        pre = CGWrapper(CGGeneric(condition), pre="if (", post=") {\n",
-                        reindent=True)
-        CGWrapper.__init__(self, CGIndenter(child), pre=pre.define(),
-                           post="\n}")
+        CGList.__init__(self, [
+            CGWrapper(CGGeneric(condition), pre="if (", post=") {\n", reindent=True),
+            CGIndenter(child),
+            CGGeneric("}\n")
+        ])
 
 
 class CGIfElseWrapper(CGList):
     def __init__(self, condition, ifTrue, ifFalse):
-        kids = [CGIfWrapper(ifTrue, condition),
-                CGWrapper(CGIndenter(ifFalse), pre=" else {\n", post="\n}")]
-        CGList.__init__(self, kids)
+        CGList.__init__(self, [
+            CGWrapper(CGGeneric(condition), pre="if (", post=") {\n", reindent=True),
+            CGIndenter(ifTrue),
+            CGGeneric("} else {\n"),
+            CGIndenter(ifFalse),
+            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:
+            return ""
+        s = self.children[0].define()
+        assert s.endswith("\n")
+        for child in self.children[1:]:
+            code = child.define()
+            assert code.startswith("if") or code.startswith("{")
+            assert code.endswith("\n")
+            s = s.rstrip() + " else " + code
+        return s
 
 
 class CGTemplatedType(CGWrapper):
     def __init__(self, templateName, child, isConst=False, isReference=False):
         const = "const " if isConst else ""
         pre = "%s%s<" % (const, templateName)
         ref = "&" if isReference else ""
         post = ">%s" % ref
@@ -1283,27 +1345,27 @@ class CGAbstractMethod(CGThing):
         return ' '.join(decorators) + maybeNewline
 
     def declare(self):
         if self.inline:
             return self._define(True)
         return "%s%s%s(%s);\n" % (self._template(), self._decorators(), self.name, self._argstring(True))
 
     def _define(self, fromDeclare=False):
-        return self.definition_prologue(fromDeclare) + "\n" + self.definition_body() + self.definition_epilogue()
+        return self.definition_prologue(fromDeclare) + self.definition_body() + self.definition_epilogue()
 
     def define(self):
         return "" if self.inline else self._define()
 
     def definition_prologue(self, fromDeclare):
-        return "%s%s%s(%s)\n{" % (self._template(), self._decorators(),
-                                  self.name, self._argstring(fromDeclare))
+        return "%s%s%s(%s)\n{\n" % (self._template(), self._decorators(),
+                                    self.name, self._argstring(fromDeclare))
 
     def definition_epilogue(self):
-        return "\n}\n"
+        return "}\n"
 
     def definition_body(self):
         assert False  # Override me!
 
 
 class CGAbstractStaticMethod(CGAbstractMethod):
     """
     Abstract base class for codegen of implementation-only (no
@@ -1323,53 +1385,55 @@ class CGAbstractClassHook(CGAbstractStat
     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 = UnwrapDOMObject<%s>(obj);
-""" % (self.descriptor.nativeType, self.descriptor.nativeType)
+        return ("\n"  # BOGUS extra blank line at start of function
+                "  %s* self = UnwrapDOMObject<%s>(obj);\n" %
+                (self.descriptor.nativeType, self.descriptor.nativeType))
 
     def definition_body(self):
         return self.definition_body_prologue() + self.generate_code()
 
     def generate_code(self):
         assert False  # Override me!
 
 
 class CGGetJSClassMethod(CGAbstractMethod):
     def __init__(self, descriptor):
         CGAbstractMethod.__init__(self, descriptor, 'GetJSClass', 'const JSClass*',
                                   [])
 
     def definition_body(self):
-        return "  return Class.ToJSClass();"
+        return "  return Class.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::MutableHandle<JS::Value>', 'vp')]
         CGAbstractClassHook.__init__(self, descriptor, ADDPROPERTY_HOOK_NAME,
                                      'bool', args)
 
     def generate_code(self):
         assert self.descriptor.wrapperCache
-        return ("  // We don't want to preserve if we don't have a wrapper.\n"
-                "  if (self->GetWrapperPreserveColor()) {\n"
-                "    PreserveWrapper(self);\n"
-                "  }\n"
-                "  return true;")
+        return indent(dedent("""
+            // We don't want to preserve if we don't have a wrapper.
+            if (self->GetWrapperPreserveColor()) {
+              PreserveWrapper(self);
+            }
+            return true;
+            """))
 
 
 def DeferredFinalizeSmartPtr(descriptor):
     if descriptor.nativeOwnership == 'owned':
         smartPtr = 'nsAutoPtr'
     else:
         smartPtr = 'nsRefPtr'
     return smartPtr
@@ -1378,32 +1442,32 @@ def DeferredFinalizeSmartPtr(descriptor)
 def finalizeHook(descriptor, hookName, freeOp):
     finalize = "JSBindingFinalized<%s>::Finalized(self);\n" % descriptor.nativeType
     if descriptor.wrapperCache:
         finalize += "ClearWrapper(self, self);\n"
     if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
         finalize += "self->mExpandoAndGeneration.expando = JS::UndefinedValue();\n"
     if descriptor.interface.getExtendedAttribute("Global"):
         finalize += "mozilla::dom::FinalizeGlobal(CastToJSFreeOp(%s), obj);\n" % freeOp
-    finalize += ("AddForDeferredFinalization<%s, %s >(self);" %
+    finalize += ("AddForDeferredFinalization<%s, %s >(self);\n" %
                  (descriptor.nativeType, DeferredFinalizeSmartPtr(descriptor)))
     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 CGIndenter(finalizeHook(self.descriptor, self.name, self.args[0].name)).define()
+        return indent(finalizeHook(self.descriptor, self.name, self.args[0].name).define())
 
 
 class CGClassConstructor(CGAbstractStaticMethod):
     """
     JS-visible constructor for our objects
     """
     def __init__(self, descriptor, ctor, name=CONSTRUCT_HOOK_NAME):
         args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'), Argument('JS::Value*', 'vp')]
@@ -1414,125 +1478,138 @@ class CGClassConstructor(CGAbstractStati
         if not self._ctor:
             return ""
         return CGAbstractStaticMethod.define(self)
 
     def definition_body(self):
         return self.generate_code()
 
     def generate_code(self):
-        preamble = """
-JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-JS::Rooted<JSObject*> obj(cx, &args.callee());
-"""
         # [ChromeOnly] interfaces may only be constructed by chrome.
+        chromeOnlyCheck = ""
         if isChromeOnly(self._ctor):
-            preamble += (
-                "if (!nsContentUtils::ThreadsafeIsCallerChrome()) {\n"
-                "  return ThrowingConstructor(cx, argc, vp);\n"
-                "}\n\n")
+            chromeOnlyCheck = dedent("""
+                if (!nsContentUtils::ThreadsafeIsCallerChrome()) {
+                  return ThrowingConstructor(cx, argc, vp);
+                }
+
+                """)
 
         # Additionally, we want to throw if a caller does a bareword invocation
         # of a constructor without |new|. We don't enforce this for chrome in
         # realease builds to avoid the addon compat fallout of making that
         # change. See bug 916644.
         #
         # Figure out the name of our constructor for error reporting purposes.
         # For unnamed webidl constructors, identifier.name is "constructor" but
         # the name JS sees is the interface name; for named constructors
         # identifier.name is the actual name.
         name = self._ctor.identifier.name
         if name != "constructor":
             ctorName = name
         else:
             ctorName = self.descriptor.interface.identifier.name
-        preamble += (
-            "bool mayInvoke = args.isConstructing();\n"
-            "#ifdef RELEASE_BUILD\n"
-            "mayInvoke = mayInvoke || nsContentUtils::ThreadsafeIsCallerChrome();\n"
-            "#endif // RELEASE_BUILD\n"
-            "if (!mayInvoke) {\n"
-            "  // XXXbz wish I could get the name from the callee instead of\n"
-            "  // Adding more relocations\n"
-            '  return ThrowConstructorWithoutNew(cx, "%s");\n'
-            "}" % ctorName)
+
+        preamble = fill(  # BOGUS extra blank line at beginning of function body
+            """
+
+            JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+            JS::Rooted<JSObject*> obj(cx, &args.callee());
+            $*{chromeOnlyCheck}
+            bool mayInvoke = args.isConstructing();
+            #ifdef RELEASE_BUILD
+            mayInvoke = mayInvoke || nsContentUtils::ThreadsafeIsCallerChrome();
+            #endif // RELEASE_BUILD
+            if (!mayInvoke) {
+              // XXXbz wish I could get the name from the callee instead of
+              // Adding more relocations
+              return ThrowConstructorWithoutNew(cx, "${ctorName}");
+            }
+            """,
+            chromeOnlyCheck=chromeOnlyCheck,
+            ctorName=ctorName)
 
         name = self._ctor.identifier.name
         nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
         callGenerator = CGMethodCall(nativeName, True, self.descriptor,
                                      self._ctor, isConstructor=True,
                                      constructorName=ctorName)
-        return CGList([CGIndenter(CGGeneric(preamble)), callGenerator],
-                      "\n").define()
+        return indent(preamble) + callGenerator.define()
 
 
 # Encapsulate the constructor in a helper method to share genConstructorBody with CGJSImplMethod.
 class CGConstructNavigatorObjectHelper(CGAbstractStaticMethod):
     """
     Construct a new JS-implemented WebIDL DOM object, for use on navigator.
     """
     def __init__(self, descriptor):
         name = "ConstructNavigatorObjectHelper"
         args = [Argument('JSContext*', 'cx'),
                 Argument('GlobalObject&', 'global'),
                 Argument('ErrorResult&', 'aRv')]
         rtype = 'already_AddRefed<%s>' % descriptor.name
         CGAbstractStaticMethod.__init__(self, descriptor, name, rtype, args)
 
     def definition_body(self):
-        return CGIndenter(CGGeneric(genConstructorBody(self.descriptor))).define()
+        return indent(genConstructorBody(self.descriptor))
 
 
 class CGConstructNavigatorObject(CGAbstractMethod):
     """
     Wrap a JS-implemented WebIDL object into a JS value, for use on navigator.
     """
     def __init__(self, descriptor):
         name = 'ConstructNavigatorObject'
         args = [Argument('JSContext*', 'aCx'), Argument('JS::Handle<JSObject*>', 'aObj')]
         CGAbstractMethod.__init__(self, descriptor, name, 'JSObject*', args)
 
     def definition_body(self):
         if not self.descriptor.interface.isJSImplemented():
             raise TypeError("Only JS-implemented classes are currently supported "
                             "on navigator. See bug 856820.")
-        template = """  GlobalObject global(aCx, aObj);
-  if (global.Failed()) {
-    return nullptr;
-  }
-  ErrorResult rv;
-  nsRefPtr<mozilla::dom::${descriptorName}> result = ConstructNavigatorObjectHelper(aCx, global, rv);
-  rv.WouldReportJSException();
-  if (rv.Failed()) {
-    ThrowMethodFailedWithDetails(aCx, rv, "${descriptorName}", "navigatorConstructor");
-    return nullptr;
-  }
-  JS::Rooted<JS::Value> v(aCx);
-  if (!WrapNewBindingObject(aCx, result, &v)) {
-    //XXX Assertion disabled for now, see bug 991271.
-    MOZ_ASSERT(true || JS_IsExceptionPending(aCx));
-    return nullptr;
-  }
-  return &v.toObject();"""
-        return string.Template(template).substitute({
-            'descriptorName': self.descriptor.name,
-        })
+        return indent(fill(
+            """
+            GlobalObject global(aCx, aObj);
+            if (global.Failed()) {
+              return nullptr;
+            }
+            ErrorResult rv;
+            nsRefPtr<mozilla::dom::${descriptorName}> result = ConstructNavigatorObjectHelper(aCx, global, rv);
+            rv.WouldReportJSException();
+            if (rv.Failed()) {
+              ThrowMethodFailedWithDetails(aCx, rv, "${descriptorName}", "navigatorConstructor");
+              return nullptr;
+            }
+            JS::Rooted<JS::Value> v(aCx);
+            if (!WrapNewBindingObject(aCx, result, &v)) {
+              //XXX Assertion disabled for now, see bug 991271.
+              MOZ_ASSERT(true || JS_IsExceptionPending(aCx));
+              return nullptr;
+            }
+            return &v.toObject();
+            """,
+            descriptorName=self.descriptor.name))
 
 
 class CGClassConstructHookHolder(CGGeneric):
     def __init__(self, descriptor):
         if descriptor.interface.ctor():
             constructHook = CONSTRUCT_HOOK_NAME
         else:
             constructHook = "ThrowingConstructor"
-        CGGeneric.__init__(self,
-                           "static const JSNativeHolder " + CONSTRUCT_HOOK_NAME + "_holder = {\n" +
-                           "  " + constructHook + ",\n" +
-                           "  " + NativePropertyHooks(descriptor) + "\n" +
-                           "};\n")
+        CGGeneric.__init__(self, fill(
+            """
+            static const JSNativeHolder ${CONSTRUCT_HOOK_NAME}_holder = {
+              ${constructHook},
+              ${hooks}
+            };
+            """,
+            CONSTRUCT_HOOK_NAME=CONSTRUCT_HOOK_NAME,
+            constructHook=constructHook,
+            hooks=NativePropertyHooks(descriptor)))
 
 
 def NamedConstructorName(m):
     return '_' + m.identifier.name
 
 
 class CGNamedConstructors(CGThing):
     def __init__(self, descriptor):
@@ -1590,67 +1667,80 @@ class CGClassHasInstanceHook(CGAbstractS
         if not NeedsGeneratedHasInstance(self.descriptor):
             return ""
         return CGAbstractStaticMethod.define(self)
 
     def definition_body(self):
         return self.generate_code()
 
     def generate_code(self):
-        header = """
-  if (!vp.isObject()) {
-    *bp = false;
-    return true;
-  }
-
-  JS::Rooted<JSObject*> instance(cx, &vp.toObject());
-  """
+        # BOGUS extra blank line at start of function
+        header = dedent("""
+
+            if (!vp.isObject()) {
+              *bp = false;
+              return true;
+            }
+
+            JS::Rooted<JSObject*> instance(cx, &vp.toObject());
+            """)
         if self.descriptor.interface.hasInterfacePrototypeObject():
-            return header + """
-  static_assert(IsBaseOf<nsISupports, %s>::value,
-                "HasInstance only works for nsISupports-based classes.");
-
-  bool ok = InterfaceHasInstance(cx, obj, instance, bp);
-  if (!ok || *bp) {
-    return ok;
-  }
-
-  // FIXME Limit this to chrome by checking xpc::AccessCheck::isChrome(obj).
-  nsISupports* native =
-    nsContentUtils::XPConnect()->GetNativeOfWrapper(cx,
-                                                    js::UncheckedUnwrap(instance));
-  nsCOMPtr<nsIDOM%s> qiResult = do_QueryInterface(native);
-  *bp = !!qiResult;
-  return true;
-         """ % (self.descriptor.nativeType,
-                self.descriptor.interface.identifier.name)
-
-        hasInstanceCode = """
-  const DOMClass* domClass = GetDOMClass(js::UncheckedUnwrap(instance));
-  *bp = false;
-  if (!domClass) {
-    // Not a DOM object, so certainly not an instance of this interface
-    return true;
-  }
-  """
+            return indent(
+                header +
+                fill(
+                    """
+
+                    static_assert(IsBaseOf<nsISupports, ${nativeType}>::value,
+                                  "HasInstance only works for nsISupports-based classes.");
+
+                    bool ok = InterfaceHasInstance(cx, obj, instance, bp);
+                    if (!ok || *bp) {
+                      return ok;
+                    }
+
+                    // FIXME Limit this to chrome by checking xpc::AccessCheck::isChrome(obj).
+                    nsISupports* native =
+                      nsContentUtils::XPConnect()->GetNativeOfWrapper(cx,
+                                                                      js::UncheckedUnwrap(instance));
+                    nsCOMPtr<nsIDOM${name}> qiResult = do_QueryInterface(native);
+                    *bp = !!qiResult;
+                    return true;
+
+                    """,  # BOGUS extra blank line at end of function
+                    nativeType=self.descriptor.nativeType,
+                    name=self.descriptor.interface.identifier.name))
+
+        hasInstanceCode = dedent("""
+
+            const DOMClass* domClass = GetDOMClass(js::UncheckedUnwrap(instance));
+            *bp = false;
+            if (!domClass) {
+              // Not a DOM object, so certainly not an instance of this interface
+              return true;
+            }
+            """)
         if self.descriptor.interface.identifier.name == "ChromeWindow":
             setBp = "*bp = UnwrapDOMObject<nsGlobalWindow>(js::UncheckedUnwrap(instance))->IsChromeWindow()"
         else:
             setBp = "*bp = true"
         # Sort interaces implementing self by name so we get stable output.
         for iface in sorted(self.descriptor.interface.interfacesImplementingSelf,
                             key=lambda iface: iface.identifier.name):
-            hasInstanceCode += """
-  if (domClass->mInterfaceChain[PrototypeTraits<prototypes::id::%s>::Depth] == prototypes::id::%s) {
-    %s;
-    return true;
-  }
-""" % (iface.identifier.name, iface.identifier.name, setBp)
-        hasInstanceCode += "  return true;"
-        return header + hasInstanceCode
+            hasInstanceCode += fill(
+                """
+
+                if (domClass->mInterfaceChain[PrototypeTraits<prototypes::id::${name}>::Depth] == prototypes::id::${name}) {
+                  ${setBp};
+                  return true;
+                }
+                """,
+                name=iface.identifier.name,
+                setBp=setBp)
+        hasInstanceCode += "return true;\n"
+        return indent(header + hasInstanceCode)
 
 
 def isChromeOnly(m):
     return m.getExtendedAttribute("ChromeOnly")
 
 
 def getAvailableInTestFunc(obj):
     availableIn = obj.getExtendedAttribute("AvailableIn")
@@ -1818,26 +1908,34 @@ class PropertyDefiner:
                 switchToCondition(self, curCondition)
                 lastCondition = curCondition
             # And the actual spec
             specs.append(specTemplate % getDataTuple(member))
         specs.append(specTerminator)
         prefableSpecs.append("  { false, nullptr }")
 
         specType = "const " + specType
-        arrays = (("static %s %s_specs[] = {\n" +
-                   ',\n'.join(specs) + "\n" +
-                   "};\n\n" +
-                   "// Can't be const because the pref-enabled boolean needs to be writable\n"
-                   "static Prefable<%s> %s[] = {\n" +
-                   ',\n'.join(prefableSpecs) + "\n" +
-                   "};\n\n") % (specType, name, specType, name))
+        arrays = fill(
+            """
+            static ${specType} ${name}_specs[] = {
+            ${specs}
+            };
+
+            // Can't be const because the pref-enabled boolean needs to be writable
+            static Prefable<${specType}> ${name}[] = {
+            ${prefableSpecs}
+            };
+
+            """,
+            specType=specType,
+            name=name,
+            specs=',\n'.join(specs),
+            prefableSpecs=',\n'.join(prefableSpecs))
         if doIdArrays:
-            arrays += ("static jsid %s_ids[%i];\n\n" %
-                       (name, len(specs)))
+            arrays += "static jsid %s_ids[%i];\n\n" % (name, len(specs))
         return arrays
 
 
 # The length of a method is the minimum of the lengths of the
 # argument lists of all its overloads.
 def overloadLength(arguments):
     i = len(arguments)
     while i > 0 and arguments[i - 1].optional:
@@ -2193,30 +2291,35 @@ class CGNativeProperties(CGList):
                         ids = "nullptr"
                     props = "%(name)s, " + ids + ", %(name)s_specs"
                     props = (props % {'name': propertyArray.variableName(chrome)})
                 else:
                     props = "nullptr, nullptr, nullptr"
                 nativeProps.append(CGGeneric(props))
             return CGWrapper(CGIndenter(CGList(nativeProps, ",\n")),
                              pre="static const NativeProperties %s = {\n" % name,
-                             post="\n};")
+                             post="\n};\n")
 
         nativeProperties = []
         if properties.hasNonChromeOnly():
             nativeProperties.append(
                 generateNativeProperties("sNativeProperties", False))
         if properties.hasChromeOnly():
             nativeProperties.append(
                 generateNativeProperties("sChromeOnlyNativeProperties", True))
-        CGList.__init__(self, nativeProperties, "\n\n")
+
+        CGList.__init__(self, nativeProperties, "\n")
 
     def declare(self):
         return ""
 
+    def define(self):
+        # BOGUSly strip off a newline
+        return CGList.define(self).rstrip()
+
 
 class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
     """
     Generate the CreateInterfaceObjects method for an interface descriptor.
 
     properties should be a PropertyArrays instance.
     """
     def __init__(self, descriptor, properties):
@@ -2274,68 +2377,77 @@ class CGCreateInterfaceObjectsMethod(CGA
                 # We only have non-chrome ids to init if we have no chrome ids.
                 if props.hasChromeOnly():
                     idsToInit.append(props.variableName(True))
                 if props.hasNonChromeOnly():
                     idsToInit.append(props.variableName(False))
         if len(idsToInit) > 0:
             initIdCalls = ["!InitIds(aCx, %s, %s_ids)" % (varname, varname)
                            for varname in idsToInit]
-            idsInitedFlag = CGGeneric("static bool sIdsInited = false;")
-            setFlag = CGGeneric("sIdsInited = true;")
-            initIdConditionals = [CGIfWrapper(CGGeneric("return;"), call)
+            idsInitedFlag = CGGeneric("static bool sIdsInited = false;\n")
+            setFlag = CGGeneric("sIdsInited = true;\n")
+            initIdConditionals = [CGIfWrapper(CGGeneric("return;\n"), call)
                                   for call in initIdCalls]
             initIds = CGList([idsInitedFlag,
-                              CGIfWrapper(CGList(initIdConditionals + [setFlag],
-                                                 "\n"),
-                                          "!sIdsInited && NS_IsMainThread()")],
-                             "\n")
+                              CGIfWrapper(CGList(initIdConditionals + [setFlag]),
+                                          "!sIdsInited && NS_IsMainThread()")])
         else:
             initIds = None
 
         prefCacheData = []
         for var in self.properties.arrayNames():
             props = getattr(self.properties, var)
             prefCacheData.extend(props.prefCacheData)
-        if len(prefCacheData) is not 0:
+        if len(prefCacheData) != 0:
             prefCacheData = [
-                CGGeneric('Preferences::AddBoolVarCache(%s, "%s");' % (ptr, pref)) for
-                (pref, ptr) in prefCacheData]
-            prefCache = CGWrapper(CGIndenter(CGList(prefCacheData, "\n")),
+                CGGeneric('Preferences::AddBoolVarCache(%s, "%s");\n' % (ptr, pref))
+                for (pref, ptr) in prefCacheData]
+            prefCache = CGWrapper(CGIndenter(CGList(prefCacheData)),
                                   pre=("static bool sPrefCachesInited = false;\n"
                                        "if (!sPrefCachesInited) {\n"
                                        "  sPrefCachesInited = true;\n"),
-                                  post="\n}")
+                                  post="}\n")
         else:
             prefCache = None
 
         if UseHolderForUnforgeable(self.descriptor):
-            createUnforgeableHolder = CGGeneric("""JS::Rooted<JSObject*> unforgeableHolder(aCx,
-  JS_NewObjectWithGivenProto(aCx, nullptr, JS::NullPtr(), JS::NullPtr()));
-if (!unforgeableHolder) {
-  return;
-}""")
+            createUnforgeableHolder = CGGeneric(dedent("""
+                JS::Rooted<JSObject*> unforgeableHolder(aCx,
+                  JS_NewObjectWithGivenProto(aCx, nullptr, JS::NullPtr(), JS::NullPtr()));
+                if (!unforgeableHolder) {
+                  return;
+                }
+                """))
             defineUnforgeables = InitUnforgeablePropertiesOnObject(self.descriptor,
                                                                    "unforgeableHolder",
                                                                    self.properties)
-            createUnforgeableHolder = CGList([createUnforgeableHolder,
-                                              defineUnforgeables],
-                                             "\n")
+            createUnforgeableHolder = CGList(
+                [createUnforgeableHolder, defineUnforgeables])
         else:
             createUnforgeableHolder = None
 
-        getParentProto = ("JS::%s<JSObject*> parentProto(%s);\n" +
-                          "if (!parentProto) {\n" +
-                          "  return;\n" +
-                          "}") % (parentProtoType, getParentProto)
-
-        getConstructorProto = ("JS::%s<JSObject*> constructorProto(%s);\n"
-                               "if (!constructorProto) {\n"
-                               "  return;\n"
-                               "}" % (constructorProtoType, getConstructorProto))
+        getParentProto = fill(
+            """
+            JS::${type}<JSObject*> parentProto(${getParentProto});
+            if (!parentProto) {
+              return;
+            }
+            """,
+            type=parentProtoType,
+            getParentProto=getParentProto)
+
+        getConstructorProto = fill(
+            """
+            JS::${type}<JSObject*> constructorProto(${getConstructorProto});
+            if (!constructorProto) {
+              return;
+            }
+            """,
+            type=constructorProtoType,
+            getConstructorProto=getConstructorProto)
 
         if (needInterfaceObject and
             self.descriptor.needsConstructHookHolder()):
             constructHookHolder = "&" + CONSTRUCT_HOOK_NAME + "_holder"
         else:
             constructHookHolder = "nullptr"
         if self.descriptor.interface.ctor():
             constructArgs = methodLength(self.descriptor.interface.ctor())
@@ -2370,114 +2482,135 @@ if (!unforgeableHolder) {
             properties = "&sNativeProperties"
         else:
             properties = "nullptr"
         if self.properties.hasChromeOnly():
             accessCheck = "nsContentUtils::ThreadsafeIsCallerChrome()"
             chromeProperties = accessCheck + " ? &sChromeOnlyNativeProperties : nullptr"
         else:
             chromeProperties = "nullptr"
-        call = (
-            "dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,\n"
-            "                            %s, %s,\n"
-            "                            constructorProto, %s, %s, %d, %s,\n"
-            "                            %s,\n"
-            "                            %s,\n"
-            "                            %s,\n"
-            "                            %s,\n"
-            "                            %s, aDefineOnGlobal);" % (
-                protoClass, protoCache,
-                interfaceClass, constructHookHolder, constructArgs,
-                namedConstructors,
-                interfaceCache,
-                domClass,
-                properties,
-                chromeProperties,
-                '"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "nullptr"))
+
+        call = fill(
+            """
+            dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
+                                        ${protoClass}, ${protoCache},
+                                        constructorProto, ${interfaceClass}, ${constructHookHolder}, ${constructArgs}, ${namedConstructors},
+                                        ${interfaceCache},
+                                        ${domClass},
+                                        ${properties},
+                                        ${chromeProperties},
+                                        ${name}, aDefineOnGlobal);
+            """,
+            protoClass=protoClass,
+            protoCache=protoCache,
+            interfaceClass=interfaceClass,
+            constructHookHolder=constructHookHolder,
+            constructArgs=constructArgs,
+            namedConstructors=namedConstructors,
+            interfaceCache=interfaceCache,
+            domClass=domClass,
+            properties=properties,
+            chromeProperties=chromeProperties,
+            name='"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "nullptr")
+
         if UseHolderForUnforgeable(self.descriptor):
             assert needInterfacePrototypeObject
-            setUnforgeableHolder = CGGeneric(
-                "JSObject* proto = aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::%s);\n"
-                "if (proto) {\n"
-                "  js::SetReservedSlot(proto, DOM_INTERFACE_PROTO_SLOTS_BASE,\n"
-                "                      JS::ObjectValue(*unforgeableHolder));\n"
-                "}" % self.descriptor.name)
+            setUnforgeableHolder = CGGeneric(fill(
+                """
+                JSObject* proto = aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::${name});
+                if (proto) {
+                  js::SetReservedSlot(proto, DOM_INTERFACE_PROTO_SLOTS_BASE,
+                                      JS::ObjectValue(*unforgeableHolder));
+                }
+                """,
+                name=self.descriptor.name))
         else:
             setUnforgeableHolder = None
         functionBody = CGList(
             [CGGeneric(getParentProto), CGGeneric(getConstructorProto), initIds,
              prefCache, createUnforgeableHolder, CGGeneric(call), setUnforgeableHolder],
-            "\n\n")
+            "\n")
         return CGIndenter(functionBody).define()
 
 
 class CGGetPerInterfaceObject(CGAbstractMethod):
     """
     A method for getting a per-interface object (a prototype object or interface
     constructor object).
     """
     def __init__(self, descriptor, name, idPrefix="", extraArgs=[]):
         args = [Argument('JSContext*', 'aCx'),
                 Argument('JS::Handle<JSObject*>', 'aGlobal')] + extraArgs
         CGAbstractMethod.__init__(self, descriptor, name,
                                   'JS::Handle<JSObject*>', args)
         self.id = idPrefix + "id::" + self.descriptor.name
 
     def definition_body(self):
-        return ("""
-
-  /* Make sure our global is sane.  Hopefully we can remove this sometime */
-  if (!(js::GetObjectClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL)) {
-    return JS::NullPtr();
-  }
-  /* Check to see whether the interface objects are already installed */
-  ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(aGlobal);
-  if (!protoAndIfaceCache.EntrySlotIfExists(%s)) {
-    CreateInterfaceObjects(aCx, aGlobal, protoAndIfaceCache, aDefineOnGlobal);
-  }
-
-  /*
-   * The object might _still_ be null, but that's OK.
-   *
-   * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
-   * traced by TraceProtoAndIfaceCache() and its contents are never
-   * changed after they have been set.
-   */
-  return JS::Handle<JSObject*>::fromMarkedLocation(protoAndIfaceCache.EntrySlotMustExist(%s).address());""" % (self.id, self.id))
+        # BOGUS extra blank line at the beginning of the code below
+        # BOGUS - should be a blank line between an if-block and following comment below
+        return indent(fill(
+            """
+
+            /* Make sure our global is sane.  Hopefully we can remove this sometime */
+            if (!(js::GetObjectClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL)) {
+              return JS::NullPtr();
+            }
+            /* Check to see whether the interface objects are already installed */
+            ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(aGlobal);
+            if (!protoAndIfaceCache.EntrySlotIfExists(${id})) {
+              CreateInterfaceObjects(aCx, aGlobal, protoAndIfaceCache, aDefineOnGlobal);
+            }
+
+            /*
+             * The object might _still_ be null, but that's OK.
+             *
+             * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
+             * traced by TraceProtoAndIfaceCache() and its contents are never
+             * changed after they have been set.
+             */
+            return JS::Handle<JSObject*>::fromMarkedLocation(protoAndIfaceCache.EntrySlotMustExist(${id}).address());
+            """,
+            id=self.id))
 
 
 class CGGetProtoObjectMethod(CGGetPerInterfaceObject):
     """
     A method for getting the interface prototype object.
     """
     def __init__(self, descriptor):
         CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObject",
                                          "prototypes::")
 
     def definition_body(self):
-        return """
-  /* Get the interface prototype object for this class.  This will create the
-     object as needed. */
-  bool aDefineOnGlobal = true;""" + CGGetPerInterfaceObject.definition_body(self)
+        # BOGUS extra blank line at start of method
+        return indent(dedent("""
+
+            /* Get the interface prototype object for this class.  This will create the
+               object as needed. */
+            bool aDefineOnGlobal = true;
+            """)) + CGGetPerInterfaceObject.definition_body(self)
 
 
 class CGGetConstructorObjectMethod(CGGetPerInterfaceObject):
     """
     A method for getting the interface constructor object.
     """
     def __init__(self, descriptor):
         CGGetPerInterfaceObject.__init__(
             self, descriptor, "GetConstructorObject",
             "constructors::",
             extraArgs=[Argument("bool", "aDefineOnGlobal", "true")])
 
     def definition_body(self):
-        return """
-  /* Get the interface object for this class.  This will create the object as
-     needed. */""" + CGGetPerInterfaceObject.definition_body(self)
+        # BOGUS extra blank line at start of method
+        return indent(dedent("""
+
+            /* Get the interface object for this class.  This will create the object as
+               needed. */
+            """)) + CGGetPerInterfaceObject.definition_body(self)
 
 
 class CGDefineDOMInterfaceMethod(CGAbstractMethod):
     """
     A method for resolve hooks to try to lazily define the interface object for
     a given interface.
     """
     def __init__(self, descriptor):
@@ -2494,29 +2627,31 @@ class CGDefineDOMInterfaceMethod(CGAbstr
 
     def define(self):
         if self.descriptor.workers:
             return ''
         return CGAbstractMethod.define(self)
 
     def definition_body(self):
         if len(self.descriptor.interface.namedConstructors) > 0:
-            getConstructor = """  JSObject* interfaceObject = GetConstructorObject(aCx, aGlobal, aDefineOnGlobal);
-  if (!interfaceObject) {
-    return nullptr;
-  }
-  for (unsigned slot = DOM_INTERFACE_SLOTS_BASE; slot < JSCLASS_RESERVED_SLOTS(&InterfaceObjectClass.mBase); ++slot) {
-    JSObject* constructor = &js::GetReservedSlot(interfaceObject, slot).toObject();
-    if (JS_GetFunctionId(JS_GetObjectFunction(constructor)) == JSID_TO_STRING(id)) {
-      return constructor;
-    }
-  }
-  return interfaceObject;"""
-        else:
-            getConstructor = "  return GetConstructorObject(aCx, aGlobal, aDefineOnGlobal);"
+            getConstructor = indent(dedent("""
+                JSObject* interfaceObject = GetConstructorObject(aCx, aGlobal, aDefineOnGlobal);
+                if (!interfaceObject) {
+                  return nullptr;
+                }
+                for (unsigned slot = DOM_INTERFACE_SLOTS_BASE; slot < JSCLASS_RESERVED_SLOTS(&InterfaceObjectClass.mBase); ++slot) {
+                  JSObject* constructor = &js::GetReservedSlot(interfaceObject, slot).toObject();
+                  if (JS_GetFunctionId(JS_GetObjectFunction(constructor)) == JSID_TO_STRING(id)) {
+                    return constructor;
+                  }
+                }
+                return interfaceObject;
+                """))
+        else:
+            getConstructor = "  return GetConstructorObject(aCx, aGlobal, aDefineOnGlobal);\n"
         return getConstructor
 
 
 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.
@@ -2542,151 +2677,158 @@ class CGConstructorEnabled(CGAbstractMet
             conditions.append("%s(aCx, aObj)" % func[0])
         availableIn = getAvailableInTestFunc(iface)
         if availableIn:
             conditions.append("%s(aCx, aObj)" % availableIn)
         # We should really have some conditions
         assert len(conditions)
         body = CGWrapper(CGList((CGGeneric(cond) for cond in conditions),
                                 " &&\n"),
-                         pre="return ", post=";", reindent=True)
+                         pre="return ", post=";\n", reindent=True)
         return CGIndenter(body).define()
 
 
 def CreateBindingJSObject(descriptor, properties, parent):
     # We don't always need to root obj, but there are a variety
     # of cases where we do, so for simplicity, just always root it.
-    objDecl = "  JS::Rooted<JSObject*> obj(aCx);\n"
+    objDecl = "JS::Rooted<JSObject*> obj(aCx);\n"
     if descriptor.proxy:
-        create = """  JS::Rooted<JS::Value> proxyPrivateVal(aCx, JS::PrivateValue(aObject));
-  js::ProxyOptions options;
-  options.setClass(&Class.mBase);
-  obj = NewProxyObject(aCx, DOMProxyHandler::getInstance(),
-                       proxyPrivateVal, proto, %s, options);
-  if (!obj) {
-    return nullptr;
-  }
-
-"""
+        create = fill(
+            """
+            JS::Rooted<JS::Value> proxyPrivateVal(aCx, JS::PrivateValue(aObject));
+            js::ProxyOptions options;
+            options.setClass(&Class.mBase);
+            obj = NewProxyObject(aCx, DOMProxyHandler::getInstance(),
+                                 proxyPrivateVal, proto, ${parent}, options);
+            if (!obj) {
+              return nullptr;
+            }
+
+            """,
+            parent=parent)
         if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
-            create += """  js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO,
-                    JS::PrivateValue(&aObject->mExpandoAndGeneration));
-
-"""
+            create += dedent("""
+                js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO,
+                                  JS::PrivateValue(&aObject->mExpandoAndGeneration));
+
+                """)
     else:
-        create = """  obj = JS_NewObject(aCx, Class.ToJSClass(), proto, %s);
-  if (!obj) {
-    return nullptr;
-  }
-
-  js::SetReservedSlot(obj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aObject));
-"""
+        create = fill(
+            """
+            obj = JS_NewObject(aCx, Class.ToJSClass(), proto, ${parent});
+            if (!obj) {
+              return nullptr;
+            }
+
+            js::SetReservedSlot(obj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aObject));
+            """,
+            parent=parent)
         if "Window" in descriptor.interface.identifier.name:
-            create = """  MOZ_ASSERT(false,
-             "Our current reserved slot situation is unsafe for globals. Fix "
-             "bug 760095!");
-""" + create
+            create = dedent("""
+                MOZ_ASSERT(false,
+                           "Our current reserved slot situation is unsafe for globals. Fix "
+                           "bug 760095!");
+                """) + create
     create = objDecl + create
 
     if descriptor.nativeOwnership == 'refcounted':
-        create += """  NS_ADDREF(aObject);
-"""
+        create += "NS_ADDREF(aObject);\n"
     else:
-        create += """  // Make sure the native objects inherit from NonRefcountedDOMObject so that we
-  // log their ctor and dtor.
-  MustInheritFromNonRefcountedDOMObject(aObject);
-  *aTookOwnership = true;
-"""
-    return create % parent
+        create += dedent("""
+            // Make sure the native objects inherit from NonRefcountedDOMObject so that we
+            // log their ctor and dtor.
+            MustInheritFromNonRefcountedDOMObject(aObject);
+            *aTookOwnership = true;
+            """)
+    return create
 
 
 def InitUnforgeablePropertiesOnObject(descriptor, obj, properties, failureReturnValue=""):
     """
     properties is a PropertyArrays instance
     """
-    failureReturn = "return"
-    if len(failureReturnValue) > 0:
-        failureReturn += " " + failureReturnValue
-    failureReturn += ";"
-
-    defineUnforgeables = ("if (!DefineUnforgeableAttributes(aCx, " + obj + ", %s)) {\n"
-                          "  " + failureReturn + "\n"
-                          "}")
+    defineUnforgeables = fill(
+        """
+        if (!DefineUnforgeableAttributes(aCx, ${obj}, %s)) {
+          return${rv};
+        }
+        """,
+        obj=obj,
+        rv=" " + failureReturnValue if failureReturnValue else "")
 
     unforgeableAttrs = properties.unforgeableAttrs
     unforgeables = []
     if unforgeableAttrs.hasNonChromeOnly():
         unforgeables.append(CGGeneric(defineUnforgeables %
                                       unforgeableAttrs.variableName(False)))
     if unforgeableAttrs.hasChromeOnly():
         unforgeables.append(
             CGIfWrapper(CGGeneric(defineUnforgeables %
                                   unforgeableAttrs.variableName(True)),
                         "nsContentUtils::ThreadsafeIsCallerChrome()"))
-    return CGList(unforgeables, "\n")
+    return CGList(unforgeables)
 
 
 def InitUnforgeableProperties(descriptor, properties):
     """
     properties is a PropertyArrays instance
     """
     unforgeableAttrs = properties.unforgeableAttrs
     if not unforgeableAttrs.hasNonChromeOnly() and not unforgeableAttrs.hasChromeOnly():
         return ""
 
     if descriptor.proxy:
         unforgeableProperties = CGGeneric(
             "// Unforgeable properties on proxy-based bindings are stored in an object held\n"
-            "// by the interface prototype object.\n")
+            "// by the interface prototype object.\n"
+            "\n")  # BOGUS extra blank line
     else:
         unforgeableProperties = CGWrapper(
             InitUnforgeablePropertiesOnObject(descriptor, "obj", properties, "nullptr"),
             pre=(
                 "// Important: do unforgeable property setup after we have handed\n"
                 "// over ownership of the C++ object to obj as needed, so that if\n"
                 "// we fail and it ends up GCed it won't have problems in the\n"
                 "// finalizer trying to drop its ownership of the C++ object.\n"))
-    return CGIndenter(CGWrapper(unforgeableProperties, pre="\n", post="\n")).define()
+    return CGWrapper(unforgeableProperties, pre="\n").define()
 
 
 def AssertInheritanceChain(descriptor):
     asserts = ""
     iface = descriptor.interface
     while iface:
         desc = descriptor.getDescriptor(iface.identifier.name)
         asserts += (
             "  MOZ_ASSERT(static_cast<%s*>(aObject) == \n"
             "             reinterpret_cast<%s*>(aObject));\n" %
             (desc.nativeType, desc.nativeType))
         iface = iface.parent
-    asserts += (
-        "  MOZ_ASSERT(ToSupportsIsCorrect(aObject));\n")
+    asserts += "  MOZ_ASSERT(ToSupportsIsCorrect(aObject));\n"
     return asserts
 
 
 def InitMemberSlots(descriptor, wrapperCache):
     """
     Initialize member slots on our JS object if we're supposed to have some.
 
     Note that this is called after the SetWrapper() call in the
     wrapperCache case, since that can affect how our getters behave
     and we plan to invoke them here.  So if we fail, we need to
     ClearWrapper.
     """
     if not descriptor.interface.hasMembersInSlots():
-        return ""
+        return "\n"  # BOGUS blank line only if this returns empty
     if wrapperCache:
         clearWrapper = "  aCache->ClearWrapper();\n"
     else:
         clearWrapper = ""
-    return CGIndenter(CGGeneric(
-        "if (!UpdateMemberSlots(aCx, obj, aObject)) {\n"
-        "%s"
-        "  return nullptr;\n"
-        "}" % clearWrapper)).define()
+    return ("if (!UpdateMemberSlots(aCx, obj, aObject)) {\n"
+            "%s"
+            "  return nullptr;\n"
+            "}\n" % clearWrapper)
 
 
 class CGWrapWithCacheMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a given native that implements nsWrapperCache.
 
     properties should be a PropertyArrays instance.
     """
@@ -2694,68 +2836,72 @@ class CGWrapWithCacheMethod(CGAbstractMe
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
                 Argument(descriptor.nativeType + '*', 'aObject'),
                 Argument('nsWrapperCache*', 'aCache')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
         self.properties = properties
 
     def definition_body(self):
-        assertISupportsInheritance = (
-            '  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),\n'
-            '             "nsISupports must be on our primary inheritance chain");\n')
-        return """%s
-%s
-  JS::Rooted<JSObject*> parent(aCx,
-    GetRealParentObject(aObject,
-                        WrapNativeParent(aCx, aObject->GetParentObject())));
-  if (!parent) {
-    return nullptr;
-  }
-
-  // That might have ended up wrapping us already, due to the wonders
-  // of XBL.  Check for that, and bail out as needed.  Scope so we don't
-  // collide with the "obj" we declare in CreateBindingJSObject.
-  {
-    JSObject* obj = aCache->GetWrapper();
-    if (obj) {
-      return obj;
-    }
-  }
-
-  JSAutoCompartment ac(aCx, parent);
-  JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, parent));
-  JS::Handle<JSObject*> proto = GetProtoObject(aCx, global);
-  if (!proto) {
-    return nullptr;
-  }
-
-%s
-%s
-  aCache->SetWrapper(obj);
-%s
-  return obj;""" % (AssertInheritanceChain(self.descriptor),
-                    assertISupportsInheritance,
-                    CreateBindingJSObject(self.descriptor, self.properties,
-                                          "parent"),
-                    InitUnforgeableProperties(self.descriptor, self.properties),
-                    InitMemberSlots(self.descriptor, True))
+        return fill(
+            """
+            ${assertion}
+              MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
+                         "nsISupports must be on our primary inheritance chain");
+
+              JS::Rooted<JSObject*> parent(aCx,
+                GetRealParentObject(aObject,
+                                    WrapNativeParent(aCx, aObject->GetParentObject())));
+              if (!parent) {
+                return nullptr;
+              }
+
+              // That might have ended up wrapping us already, due to the wonders
+              // of XBL.  Check for that, and bail out as needed.  Scope so we don't
+              // collide with the "obj" we declare in CreateBindingJSObject.
+              {
+                JSObject* obj = aCache->GetWrapper();
+                if (obj) {
+                  return obj;
+                }
+              }
+
+              JSAutoCompartment ac(aCx, parent);
+              JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, parent));
+              JS::Handle<JSObject*> proto = GetProtoObject(aCx, global);
+              if (!proto) {
+                return nullptr;
+              }
+
+              $*{parent}
+
+              $*{unforgeable}
+
+              aCache->SetWrapper(obj);
+              $*{slots}
+              return obj;
+            """,
+            assertion=AssertInheritanceChain(self.descriptor),
+            parent=CreateBindingJSObject(self.descriptor, self.properties,
+                                         "parent"),
+            unforgeable=InitUnforgeableProperties(self.descriptor, self.properties),
+            slots=InitMemberSlots(self.descriptor, True))
 
 
 class CGWrapMethod(CGAbstractMethod):
     def __init__(self, descriptor):
         # XXX can we wrap if we don't have an interface prototype object?
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
                 Argument('T*', 'aObject')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args,
                                   inline=True, templateArgs=["class T"])
 
     def definition_body(self):
-        return "  return Wrap(aCx, aObject, aObject);"
+        return "  return Wrap(aCx, aObject, aObject);\n"
 
 
 class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a given native that does not implement
     nsWrapperCache.
 
     properties should be a PropertyArrays instance.
@@ -2766,31 +2912,37 @@ class CGWrapNonWrapperCacheMethod(CGAbst
         args = [Argument('JSContext*', 'aCx'),
                 Argument(descriptor.nativeType + '*', 'aObject')]
         if descriptor.nativeOwnership == 'owned':
             args.append(Argument('bool*', 'aTookOwnership'))
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
         self.properties = properties
 
     def definition_body(self):
-        return """%s
-  JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
-  JS::Handle<JSObject*> proto = GetProtoObject(aCx, global);
-  if (!proto) {
-    return nullptr;
-  }
-
-%s
-%s
-%s
-  return obj;""" % (AssertInheritanceChain(self.descriptor),
-                    CreateBindingJSObject(self.descriptor, self.properties,
+        return fill(
+            """
+            ${assertions}
+              JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
+              JS::Handle<JSObject*> proto = GetProtoObject(aCx, global);
+              if (!proto) {
+                return nullptr;
+              }
+
+              $*{global_}
+
+              $*{unforgeable}
+
+              $*{slots}
+              return obj;
+            """,
+            assertions=AssertInheritanceChain(self.descriptor),
+            global_=CreateBindingJSObject(self.descriptor, self.properties,
                                           "global"),
-                    InitUnforgeableProperties(self.descriptor, self.properties),
-                    InitMemberSlots(self.descriptor, False))
+            unforgeable=InitUnforgeableProperties(self.descriptor, self.properties),
+            slots=InitMemberSlots(self.descriptor, False))
 
 
 class CGWrapGlobalMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a global.  The global must implement
     nsWrapperCache.
 
     properties should be a PropertyArrays instance.
@@ -2802,68 +2954,73 @@ class CGWrapGlobalMethod(CGAbstractMetho
                 Argument('nsWrapperCache*', 'aCache'),
                 Argument('JS::CompartmentOptions&', 'aOptions'),
                 Argument('JSPrincipals*', 'aPrincipal')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
         self.descriptor = descriptor
         self.properties = properties
 
     def definition_body(self):
-        return """%s
-  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
-             "nsISupports must be on our primary inheritance chain");
-
-  JS::Rooted<JSObject*> obj(aCx);
-  obj = CreateGlobal<%s, GetProtoObject>(aCx,
-                                         aObject,
-                                         aCache,
-                                         Class.ToJSClass(),
-                                         aOptions,
-                                         aPrincipal);
-
-%s
-%s
-
-  // XXXkhuey can't do this yet until workers can lazy resolve.
-  // JS_FireOnNewGlobalObject(aCx, obj);
-
-  return obj;""" % (AssertInheritanceChain(self.descriptor),
-                    self.descriptor.nativeType,
-                    InitUnforgeableProperties(self.descriptor, self.properties),
-                    InitMemberSlots(self.descriptor, True))
+        return fill(
+            """
+            ${assertions}
+              MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
+                         "nsISupports must be on our primary inheritance chain");
+
+              JS::Rooted<JSObject*> obj(aCx);
+              obj = CreateGlobal<${nativeType}, GetProtoObject>(aCx,
+                                                     aObject,
+                                                     aCache,
+                                                     Class.ToJSClass(),
+                                                     aOptions,
+                                                     aPrincipal);
+
+              $*{unforgeable}
+
+              $*{slots}
+
+              // XXXkhuey can't do this yet until workers can lazy resolve.
+              // JS_FireOnNewGlobalObject(aCx, obj);
+
+              return obj;
+            """,
+            assertions=AssertInheritanceChain(self.descriptor),
+            nativeType=self.descriptor.nativeType,
+            unforgeable=InitUnforgeableProperties(self.descriptor, self.properties),
+            slots=InitMemberSlots(self.descriptor, True))
 
 
 class CGUpdateMemberSlotsMethod(CGAbstractStaticMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'aCx'),
                 Argument('JS::Handle<JSObject*>', 'aWrapper'),
                 Argument(descriptor.nativeType + '*', 'aObject')]
         CGAbstractStaticMethod.__init__(self, descriptor, 'UpdateMemberSlots', 'bool', args)
 
     def definition_body(self):
-        slotMembers = (m for m in self.descriptor.interface.members if
-                       m.isAttr() and m.getExtendedAttribute("StoreInSlot"))
-        storeSlots = (
-            CGGeneric(
-                'static_assert(%s < js::shadow::Object::MAX_FIXED_SLOTS,\n'
-                '              "Not enough fixed slots to fit \'%s.%s\'");\n'
-                "if (!get_%s(aCx, aWrapper, aObject, args)) {\n"
-                "  return false;\n"
-                "}\n"
-                "// Getter handled setting our reserved slots" %
-                (memberReservedSlot(m),
-                 self.descriptor.interface.identifier.name,
-                 m.identifier.name, m.identifier.name))
-            for m in slotMembers)
-        body = CGList(storeSlots, "\n\n")
-        body.prepend(CGGeneric("JS::Rooted<JS::Value> temp(aCx);\n"
-                               "JSJitGetterCallArgs args(&temp);"))
-        body.append(CGGeneric("return true;"))
-
-        return CGIndenter(body).define()
+        body = ("JS::Rooted<JS::Value> temp(aCx);\n"
+                "JSJitGetterCallArgs args(&temp);\n")
+        for m in self.descriptor.interface.members:
+            if m.isAttr() and m.getExtendedAttribute("StoreInSlot"):
+                body += fill(
+                    """
+
+                    static_assert(${slot} < js::shadow::Object::MAX_FIXED_SLOTS,
+                                  "Not enough fixed slots to fit '${interface}.${member}'");
+                    if (!get_${member}(aCx, aWrapper, aObject, args)) {
+                      return false;
+                    }
+                    // Getter handled setting our reserved slots
+                    """,
+                    slot=memberReservedSlot(m),
+                    interface=self.descriptor.interface.identifier.name,
+                    member=m.identifier.name)
+
+        body += "\nreturn true;\n"
+        return indent(body)
 
 
 class CGClearCachedValueMethod(CGAbstractMethod):
     def __init__(self, descriptor, member):
         self.member = member
         # If we're StoreInSlot, we'll need to call the getter
         if member.getExtendedAttribute("StoreInSlot"):
             args = [Argument('JSContext*', 'aCx')]
@@ -2875,48 +3032,57 @@ class CGClearCachedValueMethod(CGAbstrac
         name = ("ClearCached%sValue" % MakeNativeName(member.identifier.name))
         CGAbstractMethod.__init__(self, descriptor, name, returnType, args)
 
     def definition_body(self):
         slotIndex = memberReservedSlot(self.member)
         if self.member.getExtendedAttribute("StoreInSlot"):
             # We have to root things and save the old value in case
             # regetting fails, so we can restore it.
-            declObj = "JS::Rooted<JSObject*> obj(aCx);"
+            declObj = "JS::Rooted<JSObject*> obj(aCx);\n"
             noopRetval = " true"
             saveMember = (
                 "JS::Rooted<JS::Value> oldValue(aCx, js::GetReservedSlot(obj, %s));\n" %
                 slotIndex)
-            regetMember = ("\n"
-                           "JS::Rooted<JS::Value> temp(aCx);\n"
-                           "JSJitGetterCallArgs args(&temp);\n"
-                           "JSAutoCompartment ac(aCx, obj);\n"
-                           "if (!get_%s(aCx, obj, aObject, args)) {\n"
-                           "  js::SetReservedSlot(obj, %s, oldValue);\n"
-                           "  nsJSUtils::ReportPendingException(aCx);\n"
-                           "  return false;\n"
-                           "}\n"
-                           "return true;" % (self.member.identifier.name, slotIndex))
-        else:
-            declObj = "JSObject* obj;"
+            regetMember = fill(
+                """
+                JS::Rooted<JS::Value> temp(aCx);
+                JSJitGetterCallArgs args(&temp);
+                JSAutoCompartment ac(aCx, obj);
+                if (!get_${name}(aCx, obj, aObject, args)) {
+                  js::SetReservedSlot(obj, ${slotIndex}, oldValue);
+                  nsJSUtils::ReportPendingException(aCx);
+                  return false;
+                }
+                return true;
+                """,
+                name=self.member.identifier.name,
+                slotIndex=slotIndex)
+        else:
+            declObj = "JSObject* obj;\n"
             noopRetval = ""
             saveMember = ""
             regetMember = ""
 
-        return CGIndenter(CGGeneric(
-            "%s\n"
-            "obj = aObject->GetWrapper();\n"
-            "if (!obj) {\n"
-            "  return%s;\n"
-            "}\n"
-            "%s"
-            "js::SetReservedSlot(obj, %s, JS::UndefinedValue());"
-            "%s"
-            % (declObj, noopRetval, saveMember, slotIndex, regetMember)
-        )).define()
+        return indent(fill(
+            """
+            $*{declObj}
+            obj = aObject->GetWrapper();
+            if (!obj) {
+              return${noopRetval};
+            }
+            $*{saveMember}
+            js::SetReservedSlot(obj, ${slotIndex}, JS::UndefinedValue());
+            $*{regetMember}
+            """,
+            declObj=declObj,
+            noopRetval=noopRetval,
+            saveMember=saveMember,
+            slotIndex=slotIndex,
+            regetMember=regetMember))
 
 
 class CGIsPermittedMethod(CGAbstractMethod):
     """
     crossOriginGetters/Setters/Methods are sets of names of the relevant members.
     """
     def __init__(self, descriptor, crossOriginGetters, crossOriginSetters,
                  crossOriginMethods):
@@ -2939,26 +3105,26 @@ class CGIsPermittedMethod(CGAbstractMeth
             cond = 'JS_FlatStringEqualsAscii(prop, "%s")' % name
             if name in readonly:
                 cond = "!set && %s" % cond
             elif name in writeonly:
                 cond = "set && %s" % cond
             else:
                 assert name in readwrite
             firstLetter = name[0]
-            case = cases.get(firstLetter, CGList([], "\n"))
+            case = cases.get(firstLetter, CGList([]))
             case.append(CGGeneric("if (%s) {\n"
                                   "  return true;\n"
-                                  "}" % cond))
+                                  "}\n" % cond))
             cases[firstLetter] = case
         caseList = []
         for firstLetter in sorted(cases.keys()):
             caseList.append(CGCase("'%s'" % firstLetter, cases[firstLetter]))
         switch = CGSwitch("propFirstChar", caseList)
-        return CGIndenter(CGList([switch, CGGeneric("return false;")], "\n\n")).define()
+        return indent(switch.define() + "\nreturn false;\n")
 
 builtinNames = {
     IDLType.Tags.bool: 'bool',
     IDLType.Tags.int8: 'int8_t',
     IDLType.Tags.int16: 'int16_t',
     IDLType.Tags.int32: 'int32_t',
     IDLType.Tags.int64: 'int64_t',
     IDLType.Tags.uint8: 'uint8_t',
@@ -3013,89 +3179,99 @@ class CastableObjectUnwrapper():
     have isn't one already.
 
     If allowCrossOriginObj is True, then we'll first do an
     UncheckedUnwrap and then operate on the result.
     """
     def __init__(self, descriptor, source, target, codeOnFailure,
                  exceptionCode=None, isCallbackReturnValue=False,
                  allowCrossOriginObj=False):
-        if not exceptionCode:
-            exceptionCode = codeOnFailure
         self.substitution = {
             "type": descriptor.nativeType,
             "protoID": "prototypes::id::" + descriptor.name,
             "target": target,
-            "codeOnFailure": CGIndenter(CGGeneric(codeOnFailure)).define(),
-            "exceptionCode": CGIndenter(CGGeneric(exceptionCode), 4).define()
+            "codeOnFailure": codeOnFailure,
         }
         if allowCrossOriginObj:
             self.substitution["uncheckedObjDecl"] = (
-                "\n  JS::Rooted<JSObject*> uncheckedObj(cx, js::UncheckedUnwrap(%s));" % source)
+                "JS::Rooted<JSObject*> uncheckedObj(cx, js::UncheckedUnwrap(%s));\n" % source)
             self.substitution["source"] = "uncheckedObj"
-            xpconnectUnwrap = (
-                "nsresult rv;\n"
-                "{ // Scope for the JSAutoCompartment, because we only\n"
-                "  // want to be in that compartment for the UnwrapArg call.\n"
-                "  JSAutoCompartment ac(cx, ${source});\n"
-                "  rv = UnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, &val);\n"
-                "}\n")
+            xpconnectUnwrap = dedent("""
+                nsresult rv;
+                { // Scope for the JSAutoCompartment, because we only
+                  // want to be in that compartment for the UnwrapArg call.
+                  JSAutoCompartment ac(cx, ${source});
+                  rv = UnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, &val);
+                }
+                """)
         else:
             self.substitution["uncheckedObjDecl"] = ""
             self.substitution["source"] = source
             xpconnectUnwrap = "nsresult rv = UnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, &val);\n"
 
         if descriptor.hasXPConnectImpls:
             # We don't use xpc_qsUnwrapThis because it will always throw on
             # unwrap failure, whereas we want to control whether we throw or
             # not.
-            self.substitution["codeOnFailure"] = CGIndenter(CGGeneric(string.Template(
+            self.substitution["codeOnFailure"] = string.Template(
                 "${type} *objPtr;\n"
                 "SelfRef objRef;\n"
                 "JS::Rooted<JS::Value> val(cx, JS::ObjectValue(*${source}));\n" +
                 xpconnectUnwrap +
                 "if (NS_FAILED(rv)) {\n"
-                "${codeOnFailure}\n"
+                "${indentedCodeOnFailure}"
                 "}\n"
                 "// We should be castable!\n"
                 "MOZ_ASSERT(!objRef.ptr);\n"
                 "// We should have an object, too!\n"
                 "MOZ_ASSERT(objPtr);\n"
-                "${target} = objPtr;").substitute(self.substitution)), 4).define()
+                "${target} = objPtr;\n"
+            ).substitute(self.substitution,
+                         indentedCodeOnFailure=indent(codeOnFailure))
         elif (isCallbackReturnValue == "JSImpl" and
               descriptor.interface.isJSImplemented()):
-            self.substitution["codeOnFailure"] = CGIndenter(CGGeneric(string.Template(
-                "// Be careful to not wrap random DOM objects here, even if\n"
-                "// they're wrapped in opaque security wrappers for some reason.\n"
-                "// XXXbz Wish we could check for a JS-implemented object\n"
-                "// that already has a content reflection...\n"
-                "if (!IsDOMObject(js::UncheckedUnwrap(${source}))) {\n"
-                "  nsCOMPtr<nsPIDOMWindow> ourWindow;\n"
-                "  if (!GetWindowForJSImplementedObject(cx, Callback(), getter_AddRefs(ourWindow))) {\n"
-                "${exceptionCode}\n"
-                "  }\n"
-                "  JS::Rooted<JSObject*> jsImplSourceObj(cx, ${source});\n"
-                "  ${target} = new ${type}(jsImplSourceObj, ourWindow);\n"
-                "} else {\n"
-                "${codeOnFailure}\n"
-                "}").substitute(self.substitution)), 4).define()
-        else:
-            self.substitution["codeOnFailure"] = CGIndenter(
-                CGGeneric(self.substitution["codeOnFailure"])).define()
+            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}))) {
+                  nsCOMPtr<nsPIDOMWindow> ourWindow;
+                  if (!GetWindowForJSImplementedObject(cx, Callback(), getter_AddRefs(ourWindow))) {
+                    $*{exceptionCode}
+                  }
+                  JS::Rooted<JSObject*> jsImplSourceObj(cx, ${source});
+                  ${target} = new ${type}(jsImplSourceObj, ourWindow);
+                } else {
+                  $*{codeOnFailure}
+                }
+                """,
+                exceptionCode=exceptionCode,
+                **self.substitution)
+        else:
+            self.substitution["codeOnFailure"] = codeOnFailure
 
     def __str__(self):
-        codeOnFailure = self.substitution["codeOnFailure"] % {'securityError': 'rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO'}
-        return string.Template(
-            """{${uncheckedObjDecl}
-  nsresult rv = UnwrapObject<${protoID}, ${type}>(${source}, ${target});
-  if (NS_FAILED(rv)) {
-${codeOnFailure}
-  }
-}"""
-        ).substitute(self.substitution, codeOnFailure=codeOnFailure)
+        substitution = self.substitution.copy()
+        substitution["codeOnFailure"] %= {
+            'securityError': 'rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO'
+        }
+        return fill(
+            """
+            {
+              $*{uncheckedObjDecl}
+              nsresult rv = UnwrapObject<${protoID}, ${type}>(${source}, ${target});
+              if (NS_FAILED(rv)) {
+                $*{codeOnFailure}
+              }
+            }
+            """,
+            **substitution)
 
 
 class FailureFatalCastableObjectUnwrapper(CastableObjectUnwrapper):
     """
     As CastableObjectUnwrapper, but defaulting to throwing if unwrapping fails
     """
     def __init__(self, descriptor, source, target, exceptionCode,
                  isCallbackReturnValue, sourceDescription):
@@ -3105,21 +3281,22 @@ class FailureFatalCastableObjectUnwrappe
             '%s' % (sourceDescription, descriptor.interface.identifier.name,
                     exceptionCode),
             exceptionCode,
             isCallbackReturnValue)
 
 
 class CGCallbackTempRoot(CGGeneric):
     def __init__(self, name):
-        define = """{ // Scope for tempRoot
-  JS::Rooted<JSObject*> tempRoot(cx, &${val}.toObject());
-  ${declName} = new %s(tempRoot, mozilla::dom::GetIncumbentGlobal());
-}
-""" % name
+        define = dedent("""
+            { // Scope for tempRoot
+              JS::Rooted<JSObject*> tempRoot(cx, &${val}.toObject());
+              ${declName} = new %s(tempRoot, mozilla::dom::GetIncumbentGlobal());
+            }
+            """) % name
         CGGeneric.__init__(self, define=define)
 
 
 class JSToNativeConversionInfo():
     """
     An object representing information about a JS-to-native conversion.
     """
     def __init__(self, template, declType=None, holderType=None,
@@ -3296,99 +3473,103 @@ def getJSToNativeConversionInfo(type, de
     # And we can't both be an object and be null or undefined
     assert not isDefinitelyObject or not isNullOrUndefined
 
     # If exceptionCode is not set, we'll just rethrow the exception we got.
     # Note that we can't just set failureCode to exceptionCode, because setting
     # failureCode will prevent pending exceptions from being set in cases when
     # they really should be!
     if exceptionCode is None:
-        exceptionCode = "return false;"
+        exceptionCode = "return false;\n"
     # We often want exceptionCode to be indented, since it often appears in an
     # if body.
     exceptionCodeIndented = CGIndenter(CGGeneric(exceptionCode))
 
     # Unfortunately, .capitalize() on a string will lowercase things inside the
     # string, which we do not want.
     def firstCap(string):
         return string[0].upper() + string[1:]
 
     # Helper functions for dealing with failures due to the JS value being the
     # wrong type of value
     def onFailureNotAnObject(failureCode):
-        return CGWrapper(
-            CGGeneric(
-                failureCode or
-                ('ThrowErrorMessage(cx, MSG_NOT_OBJECT, "%s");\n'
-                 '%s' % (firstCap(sourceDescription), exceptionCode))),
-            post="\n")
+        return CGGeneric(
+            failureCode or
+            ('ThrowErrorMessage(cx, MSG_NOT_OBJECT, "%s");\n'
+             '%s' % (firstCap(sourceDescription), exceptionCode)))
 
     def onFailureBadType(failureCode, typeName):
-        return CGWrapper(
-            CGGeneric(
-                failureCode or
-                ('ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "%s", "%s");\n'
-                 '%s' % (firstCap(sourceDescription), typeName,
-                         exceptionCode))),
-            post="\n")
+        return CGGeneric(
+            failureCode or
+            ('ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "%s", "%s");\n'
+             '%s' % (firstCap(sourceDescription), typeName, exceptionCode)))
 
     def onFailureNotCallable(failureCode):
-        return CGWrapper(
-            CGGeneric(
-                failureCode or
-                ('ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "%s");\n'
-                 '%s' % (firstCap(sourceDescription), exceptionCode))),
-            post="\n")
+        return CGGeneric(
+            failureCode or
+            ('ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "%s");\n'
+             '%s' % (firstCap(sourceDescription), exceptionCode)))
 
     # A helper function for handling default values.  Takes a template
     # body and the C++ code to set the default value and wraps the
     # given template body in handling for the default value.
     def handleDefault(template, setDefault):
         if defaultValue is None:
             return template
-        return CGWrapper(
-            CGIndenter(CGGeneric(template)),
-            pre="if (${haveValue}) {\n",
-            post=("\n"
-                  "} else {\n"
-                  "%s;\n"
-                  "}" %
-                  CGIndenter(CGGeneric(setDefault)).define())).define()
+        return (
+            "if (${haveValue}) {\n" +
+            indent(template) +
+            "} else {\n" +
+            indent(setDefault) +
+            "}\n")
 
     # A helper function for handling null default values.  Much like
     # handleDefault, but checks that the default value, if it exists, is null.
     def handleDefaultNull(template, codeToSetNull):
         if (defaultValue is not None and
             not isinstance(defaultValue, IDLNullValue)):
             raise TypeError("Can't handle non-null default value here")
         return handleDefault(template, codeToSetNull)
 
     # A helper function for wrapping up the template body for
     # possibly-nullable objecty stuff
     def wrapObjectTemplate(templateBody, type, codeToSetNull, failureCode=None):
         if isNullOrUndefined and type.nullable():
             # Just ignore templateBody and set ourselves to null.
             # Note that we don't have to worry about default values
             # here either, since we already examined this value.
-            return "%s;" % codeToSetNull
+            return codeToSetNull
 
         if not isDefinitelyObject:
             # Handle the non-object cases by wrapping up the whole
             # thing in an if cascade.
-            templateBody = (
-                "if (${val}.isObject()) {\n" +
-                CGIndenter(CGGeneric(templateBody)).define() + "\n")
             if type.nullable():
-                templateBody += (
-                    "} else if (${val}.isNullOrUndefined()) {\n"
-                    "%s;\n" % CGIndenter(CGGeneric(codeToSetNull)).define())
-            templateBody += (
-                "} else {\n" +
-                CGIndenter(onFailureNotAnObject(failureCode)).define() +
-                "}")
+                elifLine = "} else if (${val}.isNullOrUndefined()) {\n"
+                elifBody = codeToSetNull
+            else:
+                elifLine = ""
+                elifBody = ""
+
+            # Note that $${val} below expands to ${val}. This string is
+            # used as a template later, and val will be filled in then.
+            templateBody = fill(
+                """
+                if ($${val}.isObject()) {
+                  $*{templateBody}
+                $*{elifLine}
+                  $*{elifBody}
+                } else {
+                  $*{failureBody}
+                }
+                """,
+                templateBody=templateBody,
+                elifLine=elifLine,
+                elifBody=elifBody,
+                failureBody=onFailureNotAnObject(failureCode).define())
+
             if type.nullable():
                 templateBody = handleDefaultNull(templateBody, codeToSetNull)
             else:
                 assert defaultValue is None
 
         return templateBody
 
     # A helper function for converting things that look like a JSObject*.
@@ -3402,18 +3583,18 @@ def getJSToNativeConversionInfo(type, de
                 declType = CGGeneric("JS::Rooted<JSObject*>")
             declArgs = "cx"
         else:
             assert (isMember == "Sequence" or isMember == "Variadic" or
                     isMember == "Dictionary" or isMember == "OwningUnion")
             # We'll get traced by the sequence or dictionary or union tracer
             declType = CGGeneric("JSObject*")
             declArgs = None
-        templateBody = "${declName} = &${val}.toObject();"
-        setToNullCode = "${declName} = nullptr;"
+        templateBody = "${declName} = &${val}.toObject();\n"
+        setToNullCode = "${declName} = nullptr;;\n"  # BOGUS extra semicolon
         template = wrapObjectTemplate(templateBody, type, setToNullCode,
                                       failureCode)
         return JSToNativeConversionInfo(template, declType=declType,
                                         dealWithOptional=isOptional,
                                         declArgs=declArgs)
 
     assert not (isEnforceRange and isClamp)  # These are mutually exclusive
 
@@ -3472,64 +3653,62 @@ def getJSToNativeConversionInfo(type, de
         sequenceType = typeName.define()
         if nullable:
             typeName = CGTemplatedType("Nullable", typeName)
             arrayRef = "${declName}.SetValue()"
         else:
             arrayRef = "${declName}"
 
         # NOTE: Keep this in sync with variadic conversions as needed
-        templateBody = """JS::ForOfIterator iter(cx);
-if (!iter.init(${val}, JS::ForOfIterator::AllowNonIterable)) {
-%s
-}
-if (!iter.valueIsIterable()) {
-%s
-}
-%s &arr = %s;
-JS::Rooted<JS::Value> temp(cx);
-while (true) {
-  bool done;
-  if (!iter.next(&temp, &done)) {
-%s
-  }
-  if (done) {
-    break;
-  }
-  %s* slotPtr = arr.AppendElement();
-  if (!slotPtr) {
-    JS_ReportOutOfMemory(cx);
-%s
-  }
-  %s& slot = *slotPtr;
-"""
-        templateBody %= (
-            exceptionCodeIndented.define(),
-            CGIndenter(CGGeneric(notSequence)).define(),
-            sequenceType,
-            arrayRef,
-            CGIndenter(exceptionCodeIndented).define(),
-            elementInfo.declType.define(),
-            CGIndenter(exceptionCodeIndented).define(),
-            elementInfo.declType.define())
-
-        templateBody += CGIndenter(CGGeneric(
+        templateBody = fill(
+            """
+            JS::ForOfIterator iter(cx);
+            if (!iter.init($${val}, JS::ForOfIterator::AllowNonIterable)) {
+              $*{exceptionCode}
+            }
+            if (!iter.valueIsIterable()) {
+              $*{notSequence}
+            }
+            ${sequenceType} &arr = ${arrayRef};
+            JS::Rooted<JS::Value> temp(cx);
+            while (true) {
+              bool done;
+              if (!iter.next(&temp, &done)) {
+                $*{exceptionCode}
+              }
+              if (done) {
+                break;
+              }
+              ${elementType}* slotPtr = arr.AppendElement();
+              if (!slotPtr) {
+                JS_ReportOutOfMemory(cx);
+                $*{exceptionCode}
+              }
+              ${elementType}& slot = *slotPtr;
+            """,
+            exceptionCode=exceptionCode,
+            notSequence=notSequence,
+            sequenceType=sequenceType,
+            arrayRef=arrayRef,
+            elementType=elementInfo.declType.define())
+
+        templateBody += indent(
             string.Template(elementInfo.template).substitute({
                 "val": "temp",
                 "mutableVal": "&temp",
                 "declName": "slot",
                 # We only need holderName here to handle isExternal()
                 # interfaces, which use an internal holder for the
                 # conversion even when forceOwningType ends up true.
-                "holderName": "tempHolder",
-            }))).define()
-
-        templateBody += "\n}"
+                "holderName": "tempHolder"
+            }))
+
+        templateBody += "}\n"
         templateBody = wrapObjectTemplate(templateBody, type,
-                                          "${declName}.SetNull()", notSequence)
+                                          "${declName}.SetNull();\n", notSequence)
         # Sequence arguments that might contain traceable things need
         # to get traced
         if not isMember and typeNeedsRooting(elementType):
             holderType = CGTemplatedType("SequenceRooter", elementInfo.declType)
             # If our sequence is nullable, this will set the Nullable to be
             # not-null, but that's ok because we make an explicit SetNull() call
             # on it as needed if our JS value is actually null.
             holderArgs = "cx, &%s" % arrayRef
@@ -3564,100 +3743,103 @@ while (true) {
                     name = memberType.inner.identifier.name
                 else:
                     name = memberType.name
                 interfaceObject.append(
                     CGGeneric("(failed = !%s.TrySetTo%s(cx, ${val}, ${mutableVal}, tryNext)) || !tryNext" %
                               (unionArgumentObj, name)))
                 names.append(name)
             interfaceObject = CGWrapper(CGList(interfaceObject, " ||\n"),
-                                        pre="done = ", post=";\n", reindent=True)
+                                        pre="done = ", post=";\n\n", reindent=True)
         else:
             interfaceObject = None
 
         arrayObjectMemberTypes = filter(lambda t: t.isArray() or t.isSequence(), memberTypes)
         if len(arrayObjectMemberTypes) > 0:
             raise TypeError("Bug 767924: We don't support sequences in unions yet")
         else:
             arrayObject = None
 
         dateObjectMemberTypes = filter(lambda t: t.isDate(), memberTypes)
         if len(dateObjectMemberTypes) > 0:
             assert len(dateObjectMemberTypes) == 1
             memberType = dateObjectMemberTypes[0]
             name = memberType.name
             dateObject = CGGeneric("%s.SetTo%s(cx, ${val}, ${mutableVal});\n"
-                                   "done = true;" % (unionArgumentObj, name))
+                                   "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)
         if len(callbackMemberTypes) > 0:
             assert len(callbackMemberTypes) == 1
             memberType = callbackMemberTypes[0]
             name = memberType.name
-            callbackObject = CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${val}, ${mutableVal}, tryNext)) || !tryNext;" % (unionArgumentObj, name))
+            callbackObject = CGGeneric(
+                "done = (failed = !%s.TrySetTo%s(cx, ${val}, ${mutableVal}, tryNext)) || !tryNext;\n" %
+                (unionArgumentObj, name))
             names.append(name)
         else:
             callbackObject = None
 
         dictionaryMemberTypes = filter(lambda t: t.isDictionary(), memberTypes)
         if len(dictionaryMemberTypes) > 0:
             assert len(dictionaryMemberTypes) == 1
             name = dictionaryMemberTypes[0].inner.identifier.name
-            setDictionary = CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${val}, ${mutableVal}, tryNext)) || !tryNext;" % (unionArgumentObj, name))
+            setDictionary = CGGeneric(
+                "done = (failed = !%s.TrySetTo%s(cx, ${val}, ${mutableVal}, tryNext)) || !tryNext;\n" %
+                (unionArgumentObj, name))
             names.append(name)
         else:
             setDictionary = None
 
         objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
         if len(objectMemberTypes) > 0:
             assert len(objectMemberTypes) == 1
             # Very important to NOT construct a temporary Rooted here, since the
             # SetToObject call can call a Rooted constructor and we need to keep
             # stack discipline for Rooted.
             object = CGGeneric("%s.SetToObject(cx, &${val}.toObject());\n"
-                               "done = true;" % unionArgumentObj)
+                               "done = true;\n" % unionArgumentObj)
             names.append(objectMemberTypes[0].name)
         else:
             object = None
 
         hasObjectTypes = interfaceObject or arrayObject or dateObject or callbackObject or object
         if hasObjectTypes:
             # "object" is not distinguishable from other types
             assert not object or not (interfaceObject or arrayObject or dateObject or callbackObject)
             if arrayObject or dateObject or callbackObject:
                 # An object can be both an array object and a callback or
                 # dictionary, but we shouldn't have both in the union's members
                 # because they are not distinguishable.
                 assert not (arrayObject and callbackObject)
-                templateBody = CGList([arrayObject, dateObject, callbackObject],
-                                      " else ")
+                templateBody = CGElseChain([arrayObject, dateObject, callbackObject])
             else:
                 templateBody = None
             if interfaceObject:
                 assert not object
                 if templateBody:
                     templateBody = CGIfWrapper(templateBody, "!done")
-                templateBody = CGList([interfaceObject, templateBody], "\n")
-            else:
-                templateBody = CGList([templateBody, object], "\n")
+                templateBody = CGList([interfaceObject, templateBody])
+            else:
+                templateBody = CGList([templateBody, object])
 
             if dateObject:
-                templateBody.prepend(CGGeneric("JS::Rooted<JSObject*> argObj(cx, &${val}.toObject());"))
+                templateBody.prepend(CGGeneric("JS::Rooted<JSObject*> argObj(cx, &${val}.toObject());\n"))
             templateBody = CGIfWrapper(templateBody, "${val}.isObject()")
         else:
             templateBody = CGGeneric()
 
         if setDictionary:
             assert not object
             templateBody = CGList([templateBody,
-                                   CGIfWrapper(setDictionary, "!done")], "\n")
+                                   CGIfWrapper(setDictionary, "!done")])
 
         stringTypes = [t for t in memberTypes if t.isString() or t.isEnum()]
         numericTypes = [t for t in memberTypes if t.isNumeric()]
         booleanTypes = [t for t in memberTypes if t.isBoolean()]
         if stringTypes or numericTypes or booleanTypes:
             assert len(stringTypes) <= 1
             assert len(numericTypes) <= 1
             assert len(booleanTypes) <= 1
@@ -3665,18 +3847,18 @@ while (true) {
             # We will wrap all this stuff in a do { } while (0); so we
             # can use "break" for flow control.
             def getStringOrPrimitiveConversion(memberType):
                 if memberType.isEnum():
                     name = memberType.inner.identifier.name
                 else:
                     name = memberType.name
                 return CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${val}, ${mutableVal}, tryNext)) || !tryNext;\n"
-                                 "break;" % (unionArgumentObj, name))
-            other = CGList([], "\n")
+                                 "break;\n" % (unionArgumentObj, name))
+            other = CGList([])
             stringConversion = map(getStringOrPrimitiveConversion, stringTypes)
             numericConversion = map(getStringOrPrimitiveConversion, numericTypes)
             booleanConversion = map(getStringOrPrimitiveConversion, booleanTypes)
             if stringConversion:
                 if booleanConversion:
                     other.append(CGIfWrapper(booleanConversion[0],
                                              "${val}.isBoolean()"))
                 if numericConversion:
@@ -3687,53 +3869,56 @@ while (true) {
                 if booleanConversion:
                     other.append(CGIfWrapper(booleanConversion[0],
                                              "${val}.isBoolean()"))
                 other.append(numericConversion[0])
             else:
                 assert booleanConversion
                 other.append(booleanConversion[0])
 
-            other = CGWrapper(CGIndenter(other), pre="do {\n", post="\n} while (0);")
+            other = CGWrapper(CGIndenter(other), pre="do {\n", post="} while (0);\n")
             if hasObjectTypes or setDictionary:
-                other = CGWrapper(CGIndenter(other), "{\n", post="\n}")
+                other = CGWrapper(CGIndenter(other), "{\n", post="}\n")
                 if object:
-                    join = " else "
+                    templateBody = CGElseChain([templateBody, other])
                 else:
                     other = CGWrapper(other, pre="if (!done) ")
-                    join = "\n"
-                templateBody = CGList([templateBody, other], join)
+                    templateBody = CGList([templateBody, other])
             else:
                 assert templateBody.define() == ""
                 templateBody = other
         else:
             other = None
 
         templateBody = CGWrapper(templateBody, pre="bool done = false, failed = false, tryNext;\n")
-        throw = CGGeneric("if (failed) {\n"
-                          "%s\n"
-                          "}\n"
-                          "if (!done) {\n"
-                          '  ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "%s", "%s");\n'
-                          "%s\n"
-                          "}" % (exceptionCodeIndented.define(),
-                                 firstCap(sourceDescription),
-                                 ", ".join(names),
-                                 exceptionCodeIndented.define()))
-        templateBody = CGWrapper(CGIndenter(CGList([templateBody, throw], "\n")), pre="{\n", post="\n}")
+        throw = CGGeneric(fill(
+            """
+            if (failed) {
+              $*{exceptionCode}
+            }
+            if (!done) {
+              ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "${desc}", "${names}");
+              $*{exceptionCode}
+            }
+            """,
+            exceptionCode=exceptionCode,
+            desc=firstCap(sourceDescription),
+            names=", ".join(names)))
+
+        templateBody = CGWrapper(CGIndenter(CGList([templateBody, throw])), pre="{\n", post="}\n")
 
         typeName = CGUnionStruct.unionTypeDecl(type, isMember)
         argumentTypeName = typeName + "Argument"
         if nullable:
             typeName = "Nullable<" + typeName + " >"
 
         def handleNull(templateBody, setToNullVar, extraConditionForNull=""):
             nullTest = "%s${val}.isNullOrUndefined()" % extraConditionForNull
             return CGIfElseWrapper(nullTest,
-                                   CGGeneric("%s.SetNull();" % setToNullVar),
+                                   CGGeneric("%s.SetNull();\n" % setToNullVar),
                                    templateBody)
 
         if type.hasNullableType:
             assert not nullable
             # Make sure to handle a null default value here
             if defaultValue and isinstance(defaultValue, IDLNullValue):
                 assert defaultValue.type == type
                 extraConditionForNull = "!(${haveValue}) || "
@@ -3756,47 +3941,47 @@ while (true) {
         # constructed if we're null.  But if we're isMember we don't have a
         # holder anyway, so we can do the normal Optional codepath.
         declLoc = "${declName}"
         constructDecl = None
         if nullable:
             if isOptional and not isMember:
                 holderArgs = "${declName}.Value().SetValue()"
                 declType = CGTemplatedType("Optional", declType)
-                constructDecl = CGGeneric("${declName}.Construct();")
+                constructDecl = CGGeneric("${declName}.Construct();\n")
                 declLoc = "${declName}.Value()"
             else:
                 holderArgs = "${declName}.SetValue()"
             if holderType is not None:
-                constructHolder = CGGeneric("${holderName}.construct(%s);" % holderArgs)
+                constructHolder = CGGeneric("${holderName}.construct(%s);\n" % holderArgs)
             else:
                 constructHolder = None
             # Don't need to pass those args when the holder is being constructed
             holderArgs = None
         else:
             holderArgs = "${declName}"
             constructHolder = None
 
         if defaultValue and not isinstance(defaultValue, IDLNullValue):
             tag = defaultValue.type.tag()
 
             if tag in numericSuffixes or tag is IDLType.Tags.bool:
                 defaultStr = getHandleDefault(defaultValue)
                 value = declLoc + (".Value()" if nullable else "")
-                default = CGGeneric("%s.RawSetAs%s() = %s;" %
+                default = CGGeneric("%s.RawSetAs%s() = %s;\n" %
                                     (value, defaultValue.type, defaultStr))
             else:
                 default = CGGeneric(
                     handleDefaultStringValue(
                         defaultValue, "%s.SetStringData" % unionArgumentObj) +
-                    ";")
+                    ";\n")
 
             templateBody = CGIfElseWrapper("!(${haveValue})", default, templateBody)
 
-        templateBody = CGList([constructHolder, templateBody], "\n")
+        templateBody = CGList([constructHolder, templateBody])
 
         if nullable:
             if defaultValue:
                 if isinstance(defaultValue, IDLNullValue):
                     extraConditionForNull = "!(${haveValue}) || "
                 else:
                     extraConditionForNull = "${haveValue} && "
             else:
@@ -3807,25 +3992,25 @@ while (true) {
               isinstance(defaultValue, IDLNullValue)):
             assert type.hasDictionaryType
             assert defaultValue.type.isDictionary()
             if not isMember and typeNeedsRooting(defaultValue.type):
                 ctorArgs = "cx"
             else:
                 ctorArgs = ""
             initDictionaryWithNull = CGIfWrapper(
-                CGGeneric("return false;"),
+                CGGeneric("return false;\n"),
                 ('!%s.RawSetAs%s(%s).Init(cx, JS::NullHandleValue, "Member of %s")'
                  % (declLoc, getUnionMemberName(defaultValue.type),
                     ctorArgs, type)))
             templateBody = CGIfElseWrapper("!(${haveValue})",
                                            initDictionaryWithNull,
                                            templateBody)
 
-        templateBody = CGList([constructDecl, templateBody], "\n")
+        templateBody = CGList([constructDecl, templateBody])
 
         return JSToNativeConversionInfo(templateBody.define(),
                                         declType=declType,
                                         holderType=holderType,
                                         holderArgs=holderArgs,
                                         dealWithOptional=isOptional and (not nullable or isMember))
 
     if type.isGeckoInterface():
@@ -3840,20 +4025,21 @@ while (true) {
             return handleJSObjectType(type, isMember, failureCode)
 
         if descriptor.interface.isCallback():
             name = descriptor.interface.identifier.name
             if type.nullable() or isCallbackReturnValue:
                 declType = CGGeneric("nsRefPtr<%s>" % name)
             else:
                 declType = CGGeneric("OwningNonNull<%s>" % name)
-            conversion = CGIndenter(CGCallbackTempRoot(name)).define()
+            # BOGUS extra blank line here turns out to be at the end of a block:
+            conversion = indent(CGCallbackTempRoot(name).define()) + "\n"
 
             template = wrapObjectTemplate(conversion, type,
-                                          "${declName} = nullptr",
+                                          "${declName} = nullptr;\n",
                                           failureCode)
             return JSToNativeConversionInfo(template, declType=declType,
                                             dealWithOptional=isOptional)
 
         # This is an interface that we implement as a concrete class
         # or an XPCOM interface.
 
         # Allow null pointers for nullable types and old-binding classes, and
@@ -3939,31 +4125,32 @@ while (true) {
             templateBody += CGIndenter(onFailureBadType(failureCode,
                                                         descriptor.interface.identifier.name)).define()
             templateBody += ("}\n"
                              "MOZ_ASSERT(tmp);\n")
 
             if not isDefinitelyObject and not forceOwningType:
                 # Our tmpVal will go out of scope, so we can't rely on it
                 # for rooting
-                templateBody += (
-                    "if (tmpVal != ${val} && !${holderName}) {\n"
-                    "  // We have to have a strong ref, because we got this off\n"
-                    "  // some random object that might get GCed\n"
-                    "  ${holderName} = tmp;\n"
-                    "}\n")
+                templateBody += dedent("""
+                    if (tmpVal != ${val} && !${holderName}) {
+                      // We have to have a strong ref, because we got this off
+                      // some random object that might get GCed
+                      ${holderName} = tmp;
+                    }
+                    """)
 
             # And store our tmp, before it goes out of scope.
-            templateBody += "${declName} = tmp;"
+            templateBody += "${declName} = tmp;\n"
 
         # Just pass failureCode, not onFailureBadType, here, so we'll report the
         # thing as not an object as opposed to not implementing whatever our
         # interface is.
         templateBody = wrapObjectTemplate(templateBody, type,
-                                          "${declName} = nullptr", failureCode)
+                                          "${declName} = nullptr;\n", failureCode)
 
         declType = CGGeneric(declType)
         if holderType is not None:
             holderType = CGGeneric(holderType)
         return JSToNativeConversionInfo(templateBody,
                                         declType=declType,
                                         holderType=holderType,
                                         dealWithOptional=isOptional)
@@ -3974,23 +4161,29 @@ while (true) {
         arrayType = CGGeneric(name)
         declType = arrayType
         if type.nullable():
             declType = CGTemplatedType("Nullable", declType)
             objRef = "${declName}.SetValue()"
         else:
             objRef = "${declName}"
 
-        template = (
-            "if (!%s.Init(&${val}.toObject())) {\n"
-            "%s"  # No newline here because onFailureBadType() handles that
-            "}\n" %
-            (objRef,
-             CGIndenter(onFailureBadType(failureCode, type.name)).define()))
-        template = wrapObjectTemplate(template, type, "${declName}.SetNull()",
+        # Again, this is a bit strange since we are actually building a
+        # template string here. ${objRef} and $*{badType} below are filled in
+        # right now; $${val} expands to ${val}, to be filled in later.
+        template = fill(
+            """
+            if (!${objRef}.Init(&$${val}.toObject())) {
+              $*{badType}
+            }
+
+            """,  # BOGUS extra blank line
+            objRef=objRef,
+            badType=onFailureBadType(failureCode, type.name).define())
+        template = wrapObjectTemplate(template, type, "${declName}.SetNull();\n",
                                       failureCode)
         if not isMember:
             # This is a bit annoying.  In a union we don't want to have a
             # holder, since unions don't support that.  But if we're optional we
             # want to have a holder, so that the callee doesn't see
             # Optional<RootedTypedArray<ArrayType> >.  So do a holder if we're
             # optional and use a RootedTypedArray otherwise.
             if isOptional:
@@ -4034,55 +4227,60 @@ while (true) {
             undefinedBehavior = "eNull"
         else:
             undefinedBehavior = "eStringify"
         nullBehavior = treatAs[treatNullAs]
 
         def getConversionCode(varName):
             conversionCode = (
                 "if (!ConvertJSValueToString(cx, ${val}, ${mutableVal}, %s, %s, %s)) {\n"
-                "%s\n"
-                "}" % (nullBehavior, undefinedBehavior, varName,
-                       exceptionCodeIndented.define()))
+                "%s"
+                "}\n" % (nullBehavior, undefinedBehavior, varName,
+                         exceptionCodeIndented.define()))
             if defaultValue is None:
                 return conversionCode
 
             if isinstance(defaultValue, IDLNullValue):
                 assert(type.nullable())
                 defaultCode = "%s.SetNull()" % varName
             else:
                 defaultCode = handleDefaultStringValue(defaultValue,
                                                        "%s.SetData" % varName)
-            return handleDefault(conversionCode, defaultCode)
+            return handleDefault(conversionCode, defaultCode + ";\n")
 
         if isMember:
             # We have to make a copy, except in the variadic case, because our
             # jsval may well not live as long as our string needs to.
             declType = CGGeneric("nsString")
             if isMember == "Variadic":
                 # The string is kept alive by the argument, so we can just
                 # depend on it.
-                assignString = "${declName}.Rebind(str.Data(), str.Length())"
-            else:
-                assignString = "${declName} = str"
+                assignString = "${declName}.Rebind(str.Data(), str.Length());\n"
+            else:
+                assignString = "${declName} = str;\n"
             return JSToNativeConversionInfo(
-                "{\n"
-                "  binding_detail::FakeDependentString str;\n"
-                "%s\n"
-                "  %s;\n"
-                "}\n" % (
-                    CGIndenter(CGGeneric(getConversionCode("str"))).define(),
-                    assignString),
-                declType=declType, dealWithOptional=isOptional)
+                fill(
+                    """
+                    {
+                      binding_detail::FakeDependentString str;
+                      $*{convert}
+                      $*{assign}
+                    }
+
+                    """,  # BOGUS extra newline
+                    convert=getConversionCode("str"),
+                    assign=assignString),
+                declType=declType,
+                dealWithOptional=isOptional)
 
         if isOptional:
             declType = "Optional<nsAString>"
             holderType = CGGeneric("binding_detail::FakeDependentString")
-            conversionCode = ("%s\n"
-                              "${declName} = &${holderName};" %
+            conversionCode = ("%s"
+                              "${declName} = &${holderName};\n" %
                               getConversionCode("${holderName}"))
         else:
             declType = "binding_detail::FakeDependentString"
             holderType = None
             conversionCode = getConversionCode("${declName}")
 
         # No need to deal with optional here; we handled it already
         return JSToNativeConversionInfo(
@@ -4091,20 +4289,19 @@ while (true) {
             holderType=holderType)
 
     if type.isByteString():
         assert not isEnforceRange and not isClamp
 
         nullable = toStringBool(type.nullable())
 
         conversionCode = (
-            "if (!ConvertJSValueToByteString(cx, ${val}, ${mutableVal},"
-            " %s, ${declName})) {\n"
-            "%s\n"
-            "}" % (nullable, exceptionCodeIndented.define()))
+            "if (!ConvertJSValueToByteString(cx, ${val}, ${mutableVal}, %s, ${declName})) {\n"
+            "%s"
+            "}\n" % (nullable, exceptionCodeIndented.define()))
         # ByteString arguments cannot have a default value.
         assert defaultValue is None
 
         return JSToNativeConversionInfo(
             conversionCode,
             declType=CGGeneric("nsCString"),
             dealWithOptional=isOptional)
 
@@ -4117,113 +4314,115 @@ while (true) {
             declType = CGTemplatedType("Nullable", declType)
             declType = declType.define()
             enumLoc = "${declName}.SetValue()"
         else:
             enumLoc = "${declName}"
             declType = declType.define()
 
         if invalidEnumValueFatal:
-            handleInvalidEnumValueCode = "  MOZ_ASSERT(index >= 0);\n"
+            handleInvalidEnumValueCode = "MOZ_ASSERT(index >= 0);\n"
         else:
             # invalidEnumValueFatal is false only for attributes.  So we won't
             # have a non-default exceptionCode here unless attribute "arg
             # conversion" code starts passing in an exceptionCode.  At which
             # point we'll need to figure out what that even means.
-            assert exceptionCode == "return false;"
-            handleInvalidEnumValueCode = (
-                "  if (index < 0) {\n"
-                "    return true;\n"
-                "  }\n")
-
-        template = (
-            "{\n"
-            "  bool ok;\n"
-            '  int index = FindEnumStringIndex<%(invalidEnumValueFatal)s>(cx, ${val}, %(values)s, "%(enumtype)s", "%(sourceDescription)s", &ok);\n'
-            "  if (!ok) {\n"
-            "%(exceptionCode)s\n"
-            "  }\n"
-            "%(handleInvalidEnumValueCode)s"
-            "  %(enumLoc)s = static_cast<%(enumtype)s>(index);\n"
-            "}" % {
-                "enumtype": enumName,
-                "values": enumName + "Values::" + ENUM_ENTRY_VARIABLE_NAME,
-                "invalidEnumValueFatal": toStringBool(invalidEnumValueFatal),
-                "handleInvalidEnumValueCode": handleInvalidEnumValueCode,
-                "exceptionCode": CGIndenter(exceptionCodeIndented).define(),
-                "enumLoc": enumLoc,
-                "sourceDescription": firstCap(sourceDescription)
-            })
-
-        setNull = "${declName}.SetNull();"
+            assert exceptionCode == "return false;\n"
+            handleInvalidEnumValueCode = dedent("""
+                if (index < 0) {
+                  return true;
+                }
+                """)
+
+        template = fill(
+            """
+            {
+              bool ok;
+              int index = FindEnumStringIndex<${invalidEnumValueFatal}>(cx, $${val}, ${values}, "${enumtype}", "${sourceDescription}", &ok);
+              if (!ok) {
+                $*{exceptionCode}
+              }
+              $*{handleInvalidEnumValueCode}
+              ${enumLoc} = static_cast<${enumtype}>(index);
+            }
+            """,
+            enumtype=enumName,
+            values=enumName + "Values::" + ENUM_ENTRY_VARIABLE_NAME,
+            invalidEnumValueFatal=toStringBool(invalidEnumValueFatal),
+            handleInvalidEnumValueCode=handleInvalidEnumValueCode,
+            exceptionCode=exceptionCode,
+            enumLoc=enumLoc,
+            sourceDescription=firstCap(sourceDescription))
+
+        setNull = "${declName}.SetNull();\n"
 
         if type.nullable():
             template = CGIfElseWrapper("${val}.isNullOrUndefined()",
                                        CGGeneric(setNull),
                                        CGGeneric(template)).define()
 
         if defaultValue is not None:
             if isinstance(defaultValue, IDLNullValue):
                 assert type.nullable()
-                template = handleDefault(template, setNull)
+                template = handleDefault(template, setNull.rstrip() + ";\n")  # BOGUS extra semicolon
             else:
                 assert(defaultValue.type.tag() == IDLType.Tags.domstring)
                 template = handleDefault(template,
-                                         ("%s = %s::%s" %
+                                         ("%s = %s::%s;\n" %
                                           (enumLoc, enumName,
                                            getEnumValueName(defaultValue.value))))
         return JSToNativeConversionInfo(template, declType=CGGeneric(declType),
                                         dealWithOptional=isOptional)
 
     if type.isCallback():
         assert not isEnforceRange and not isClamp
         assert not type.treatNonCallableAsNull() or type.nullable()
         assert not type.treatNonObjectAsNull() or type.nullable()
         assert not type.treatNonObjectAsNull() or not type.treatNonCallableAsNull()
 
         name = type.unroll().identifier.name
         if type.nullable():
             declType = CGGeneric("nsRefPtr<%s>" % name)
         else:
             declType = CGGeneric("OwningNonNull<%s>" % name)
-        conversion = CGIndenter(CGCallbackTempRoot(name)).define()
+        conversion = indent(CGCallbackTempRoot(name).define())
 
         if allowTreatNonCallableAsNull and type.treatNonCallableAsNull():
             haveCallable = "JS_ObjectIsCallable(cx, &${val}.toObject())"
             if not isDefinitelyObject:
                 haveCallable = "${val}.isObject() && " + haveCallable
             if defaultValue is not None:
                 assert(isinstance(defaultValue, IDLNullValue))
                 haveCallable = "${haveValue} && " + haveCallable
             template = (
                 ("if (%s) {\n" % haveCallable) +
                 conversion +
                 "} else {\n"
                 "  ${declName} = nullptr;\n"
-                "}")
+                "}\n")
         elif allowTreatNonCallableAsNull and type.treatNonObjectAsNull():
             if not isDefinitelyObject:
                 haveObject = "${val}.isObject()"
                 if defaultValue is not None:
                     assert(isinstance(defaultValue, IDLNullValue))
                     haveObject = "${haveValue} && " + haveObject
                 template = CGIfElseWrapper(haveObject,
-                                           CGGeneric(conversion),
-                                           CGGeneric("${declName} = nullptr;")).define()
+                                           CGGeneric(conversion + "\n"),  # BOGUS extra blank line
+                                           CGGeneric("${declName} = nullptr;\n")).define()
             else:
                 template = conversion
         else:
             template = wrapObjectTemplate(
                 "if (JS_ObjectIsCallable(cx, &${val}.toObject())) {\n" +
                 conversion +
-                "} else {\n"
-                "%s"
-                "}" % CGIndenter(onFailureNotCallable(failureCode)).define(),
+                "} else {\n" +
+                indent(onFailureNotCallable(failureCode).define()) +
+                "}\n",
                 type,
-                "${declName} = nullptr",
+                "${declName} = nullptr;\n",
                 failureCode)
         return JSToNativeConversionInfo(template, declType=declType,
                                         dealWithOptional=isOptional)
 
     if type.isAny():
         assert not isEnforceRange and not isClamp
 
         declArgs = None
@@ -4231,25 +4430,25 @@ while (true) {
             # Rooting is handled by the sequence and dictionary tracers.
             declType = "JS::Value"
         else:
             assert not isMember
             declType = "JS::Rooted<JS::Value>"
             declArgs = "cx"
 
         assert not isOptional
-        templateBody = "${declName} = ${val};"
+        templateBody = "${declName} = ${val};\n"
         # We may not have a default value if we're being converted for
         # a setter, say.
         if defaultValue:
             if isinstance(defaultValue, IDLNullValue):
-                defaultHandling = "${declName} = JS::NullValue()"
+                defaultHandling = "${declName} = JS::NullValue();\n"
             else:
                 assert isinstance(defaultValue, IDLUndefinedValue)
-                defaultHandling = "${declName} = JS::UndefinedValue()"
+                defaultHandling = "${declName} = JS::UndefinedValue();\n"
             templateBody = handleDefault(templateBody, defaultHandling)
         return JSToNativeConversionInfo(templateBody,
                                         declType=CGGeneric(declType),
                                         declArgs=declArgs)
 
     if type.isObject():
         assert not isEnforceRange and not isClamp
         return handleJSObjectType(type, isMember, failureCode)
@@ -4289,33 +4488,33 @@ while (true) {
             if isDefinitelyObject:
                 dictionaryTest = "IsObjectValueConvertibleToDictionary"
             else:
                 dictionaryTest = "IsConvertibleToDictionary"
             # Check that the value we have can in fact be converted to
             # a dictionary, and return failureCode if not.
             template = CGIfWrapper(
                 CGGeneric(failureCode),
-                "!%s(cx, ${val})" % dictionaryTest).define() + "\n\n"
+                "!%s(cx, ${val})" % dictionaryTest).define() + "\n"
         else:
             template = ""
 
         dictLoc = "${declName}"
         if type.nullable():
             dictLoc += ".SetValue()"
 
         template += ('if (!%s.Init(cx, %s, "%s")) {\n'
-                     "%s\n"
-                     "}" % (dictLoc, val, firstCap(sourceDescription),
-                            exceptionCodeIndented.define()))
+                     "%s"
+                     "}\n" % (dictLoc, val, firstCap(sourceDescription),
+                              exceptionCodeIndented.define()))
 
         if type.nullable():
             declType = CGTemplatedType("Nullable", declType)
             template = CGIfElseWrapper("${val}.isNullOrUndefined()",
-                                       CGGeneric("${declName}.SetNull();"),
+                                       CGGeneric("${declName}.SetNull();\n"),
                                        CGGeneric(template)).define()
 
         # Dictionary arguments that might contain traceable things need to get
         # traced
         if not isMember and isCallbackReturnValue:
             # Go ahead and just convert directly into our actual return value
             declType = CGWrapper(declType, post="&")
             declArgs = "aRetVal"
@@ -4345,26 +4544,29 @@ while (true) {
             dateVal = "${declName}"
 
         if failureCode is None:
             notDate = ('ThrowErrorMessage(cx, MSG_NOT_DATE, "%s");\n'
                        "%s" % (firstCap(sourceDescription), exceptionCode))
         else:
             notDate = failureCode
 
-        conversion = (
-            "JS::Rooted<JSObject*> possibleDateObject(cx, &${val}.toObject());\n"
-            "if (!JS_ObjectIsDate(cx, possibleDateObject) ||\n"
-            "    !%s.SetTimeStamp(cx, possibleDateObject)) {\n"
-            "%s\n"
-            "}" %
-            (dateVal, CGIndenter(CGGeneric(notDate)).define()))
+        conversion = fill(
+            """
+            JS::Rooted<JSObject*> possibleDateObject(cx, &$${val}.toObject());
+            if (!JS_ObjectIsDate(cx, possibleDateObject) ||
+                !${dateVal}.SetTimeStamp(cx, possibleDateObject)) {
+              $*{notDate}
+            }
+            """,
+            dateVal=dateVal,
+            notDate=notDate)
 
         conversion = wrapObjectTemplate(conversion, type,
-                                        "${declName}.SetNull()", notDate)
+                                        "${declName}.SetNull();\n", notDate)
         return JSToNativeConversionInfo(conversion,
                                         declType=declType,
                                         dealWithOptional=isOptional)
 
     if not type.isPrimitive():
         raise TypeError("Need conversion for argument type '%s'" % str(type))
 
     typeName = builtinNames[type.tag()]
@@ -4383,53 +4585,58 @@ while (true) {
         readLoc = "${declName}.Value()"
         nullCondition = "${val}.isNullOrUndefined()"
         if defaultValue is not None and isinstance(defaultValue, IDLNullValue):
             nullCondition = "!(${haveValue}) || " + nullCondition
         template = (
             "if (%s) {\n"
             "  ${declName}.SetNull();\n"
             "} else if (!ValueToPrimitive<%s, %s>(cx, ${val}, &%s)) {\n"
-            "%s\n"
-            "}" % (nullCondition, typeName, conversionBehavior,
-                   writeLoc, exceptionCodeIndented.define()))
+            "%s"
+            "}\n" % (nullCondition, typeName, conversionBehavior,
+                     writeLoc, exceptionCodeIndented.define()))
     else:
         assert(defaultValue is None or
                not isinstance(defaultValue, IDLNullValue))
         writeLoc = "${declName}"
         readLoc = writeLoc
         template = (
             "if (!ValueToPrimitive<%s, %s>(cx, ${val}, &%s)) {\n"
-            "%s\n"
-            "}" % (typeName, conversionBehavior, writeLoc,
-                   exceptionCodeIndented.define()))
+            "%s"
+            "}\n" % (typeName, conversionBehavior, writeLoc,
+                     exceptionCodeIndented.define()))
         declType = CGGeneric(typeName)
 
     if type.isFloat() and not type.isUnrestricted():
         if lenientFloatCode is not None:
-            nonFiniteCode = CGIndenter(CGGeneric(lenientFloatCode)).define()
-        else:
-            nonFiniteCode = ('  ThrowErrorMessage(cx, MSG_NOT_FINITE, "%s");\n'
-                             "%s" % (firstCap(sourceDescription),
-                                     exceptionCodeIndented.define()))
-        template += (" else if (!mozilla::IsFinite(%s)) {\n"
-                     "  // Note: mozilla::IsFinite will do the right thing\n"
-                     "  //       when passed a non-finite float too.\n"
-                     "%s\n"
-                     "}" % (readLoc, nonFiniteCode))
+            nonFiniteCode = lenientFloatCode
+        else:
+            nonFiniteCode = ('ThrowErrorMessage(cx, MSG_NOT_FINITE, "%s");\n'
+                             "%s" % (firstCap(sourceDescription), exceptionCode))
+        template = template.rstrip()
+        template += fill(
+            """
+             else if (!mozilla::IsFinite(${readLoc})) {
+              // Note: mozilla::IsFinite will do the right thing
+              //       when passed a non-finite float too.
+              $*{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)):
         tag = defaultValue.type.tag()
         defaultStr = getHandleDefault(defaultValue)
         template = CGIfElseWrapper(
             "${haveValue}",
             CGGeneric(template),
-            CGGeneric("%s = %s;" % (writeLoc, defaultStr))).define()
+            CGGeneric("%s = %s;\n" % (writeLoc, defaultStr))).define()
 
     return JSToNativeConversionInfo(template, declType=declType,
                                     dealWithOptional=isOptional)
 
 
 def instantiateJSToNativeConversion(info, replacements, checkForValue=False):
     """
     Take a JSToNativeConversionInfo as returned by getJSToNativeConversionInfo
@@ -4449,86 +4656,83 @@ def instantiateJSToNativeConversion(info
                         "outside the check for big enough arg count!")
 
     # We can't precompute our holder constructor arguments, since
     # those might depend on ${declName}, which we change below.  Just
     # compute arguments at the point when we need them as we go.
     def getArgsCGThing(args):
         return CGGeneric(string.Template(args).substitute(replacements))
 
-    result = CGList([], "\n")
+    result = CGList([])
     # Make a copy of "replacements" since we may be about to start modifying it
     replacements = dict(replacements)
     originalDeclName = replacements["declName"]
     if declType is not None:
         if dealWithOptional:
             replacements["declName"] = "%s.Value()" % originalDeclName
             declType = CGTemplatedType("Optional", declType)
             declCtorArgs = None
         elif info.declArgs is not None:
             declCtorArgs = CGWrapper(getArgsCGThing(info.declArgs),
                                      pre="(", post=")")
         else:
             declCtorArgs = None
         result.append(
             CGList([declType, CGGeneric(" "),
                     CGGeneric(originalDeclName),
-                    declCtorArgs, CGGeneric(";")]))
+                    declCtorArgs, CGGeneric(";\n")]))
 
     originalHolderName = replacements["holderName"]
     if holderType is not None:
         if dealWithOptional:
             replacements["holderName"] = "%s.ref()" % originalHolderName
             holderType = CGTemplatedType("Maybe", holderType)
             holderCtorArgs = None
         elif info.holderArgs is not None:
             holderCtorArgs = CGWrapper(getArgsCGThing(info.holderArgs),
                                        pre="(", post=")")
         else:
             holderCtorArgs = None
         result.append(
             CGList([holderType, CGGeneric(" "),
                     CGGeneric(originalHolderName),
-                    holderCtorArgs, CGGeneric(";")]))
+                    holderCtorArgs, CGGeneric(";\n")]))
 
     conversion = CGGeneric(
         string.Template(templateBody).substitute(replacements))
 
     if checkForValue:
         if dealWithOptional:
             declConstruct = CGIndenter(
-                CGGeneric("%s.Construct(%s);" %
+                CGGeneric("%s.Construct(%s);\n" %
                           (originalDeclName,
                            getArgsCGThing(info.declArgs).define() if
                            info.declArgs else "")))
             if holderType is not None:
                 holderConstruct = CGIndenter(
-                    CGGeneric("%s.construct(%s);" %
+                    CGGeneric("%s.construct(%s);\n" %
                               (originalHolderName,
                                getArgsCGThing(info.holderArgs).define() if
                                info.holderArgs else "")))
             else:
                 holderConstruct = None
         else:
             declConstruct = None
             holderConstruct = None
 
         conversion = CGList([
             CGGeneric(
-                string.Template("if (${haveValue}) {").substitute(replacements)),
+                string.Template("if (${haveValue}) {\n").substitute(replacements)),
             declConstruct,
             holderConstruct,
             CGIndenter(conversion),
-            CGGeneric("}")
-        ], "\n")
+            CGGeneric("}\n")
+        ])
 
     result.append(conversion)
-    # Add an empty CGGeneric to get an extra newline after the argument
-    # conversion.
-    result.append(CGGeneric(""))
     return result
 
 
 def convertConstIDLValueToJSVal(value):
     if isinstance(value, IDLNullValue):
         return "JS::NullValue()"
     if isinstance(value, IDLUndefinedValue):
         return "JS::UndefinedValue()"
@@ -4623,44 +4827,46 @@ class CGArgumentConverter(CGThing):
         if typeNeedsRooting(self.argument.type):
             rooterDecl = ("SequenceRooter<%s> ${holderName}(cx, &${declName});\n" %
                           typeConversion.declType.define())
         else:
             rooterDecl = ""
         replacer["elemType"] = typeConversion.declType.define()
 
         # NOTE: Keep this in sync with sequence conversions as needed
-        variadicConversion = string.Template("${seqType} ${declName};\n" +
-                                             rooterDecl +
-                                             """if (${argc} > ${index}) {
-  if (!${declName}.SetCapacity(${argc} - ${index})) {
-    JS_ReportOutOfMemory(cx);
-    return false;
-  }
-  for (uint32_t variadicArg = ${index}; variadicArg < ${argc}; ++variadicArg) {
-    ${elemType}& slot = *${declName}.AppendElement();
-""").substitute(replacer)
+        variadicConversion = string.Template(
+            "${seqType} ${declName};\n" +
+            rooterDecl +
+            dedent("""
+                if (${argc} > ${index}) {
+                  if (!${declName}.SetCapacity(${argc} - ${index})) {
+                    JS_ReportOutOfMemory(cx);
+                    return false;
+                  }
+                  for (uint32_t variadicArg = ${index}; variadicArg < ${argc}; ++variadicArg) {
+                    ${elemType}& slot = *${declName}.AppendElement();
+                """)
+        ).substitute(replacer)
 
         val = string.Template("args[variadicArg]").substitute(replacer)
-        variadicConversion += CGIndenter(CGGeneric(
+        variadicConversion += indent(
             string.Template(typeConversion.template).substitute({
                 "val": val,
                 "mutableVal": val,
                 "declName": "slot",
                 # We only need holderName here to handle isExternal()
                 # interfaces, which use an internal holder for the
                 # conversion even when forceOwningType ends up true.
                 "holderName": "tempHolder",
                 # Use the same ${obj} as for the variadic arg itself
                 "obj": replacer["obj"]
-            })), 4).define()
-
-        variadicConversion += ("\n"
-                               "  }\n"
-                               "}")
+            }), 4)
+
+        variadicConversion += ("  }\n"
+                               "}\n")
         return variadicConversion
 
 
 def getMaybeWrapValueFuncForType(type):
     # Callbacks might actually be DOM objects; nothing prevents a page from
     # doing that.
     if type.isCallback() or type.isCallbackInterface() or type.isObject():
         if type.nullable():
@@ -4707,21 +4913,17 @@ def getWrapTemplateForType(type, descrip
                 JS::Value* and .set() called on it to set it to a JS::Value.
                 This can be a JS::MutableHandle<JS::Value> or a
                 JS::Rooted<JS::Value>.
       obj: a JS::Handle<JSObject*>.
 
     Returns (templateString, infallibility of conversion template)
     """
     if successCode is None:
-        successCode = "return true;"
-
-    # We often want exceptionCode to be indented, since it often appears in an
-    # if body.
-    exceptionCodeIndented = CGIndenter(CGGeneric(exceptionCode))
+        successCode = "return true;\n"
 
     def setUndefined():
         return _setValue("", setter="setUndefined")
 
     def setNull():
         return _setValue("", setter="setNull")
 
     def setInt32(value):
@@ -4751,109 +4953,129 @@ def getWrapTemplateForType(type, descrip
 
         If wrapAsType is not None, then will wrap the resulting value using the
         function that getMaybeWrapValueFuncForType(wrapAsType) returns.
         Otherwise, no wrapping will be done.
         """
         if wrapAsType is None:
             tail = successCode
         else:
-            tail = (("if (!%s(cx, ${jsvalHandle})) {\n"
-                     "%s\n" % (getMaybeWrapValueFuncForType(wrapAsType),
-                               exceptionCodeIndented.define())) +
-                    "}\n" +
-                    successCode)
+            tail = fill(
+                """
+                if (!${maybeWrap}(cx, $${jsvalHandle})) {
+                  $*{exceptionCode}
+                }
+                $*{successCode}
+                """,
+                maybeWrap=getMaybeWrapValueFuncForType(wrapAsType),
+                exceptionCode=exceptionCode,
+                successCode=successCode)
         return ("${jsvalRef}.%s(%s);\n" % (setter, value)) + tail
 
     def wrapAndSetPtr(wrapCall, failureCode=None):
         """
         Returns the code to set the jsval by calling "wrapCall". "failureCode"
         is the code to run if calling "wrapCall" fails
         """
         if failureCode is None:
             failureCode = exceptionCode
-        str = ("if (!%s) {\n" +
-               CGIndenter(CGGeneric(failureCode)).define() + "\n" +
-               "}\n" +
-               successCode) % (wrapCall)
-        return str
+        return fill(
+            """
+            if (!${wrapCall}) {
+              $*{failureCode}
+            }
+            $*{successCode}
+            """,
+            wrapCall=wrapCall,
+            failureCode=failureCode,
+            successCode=successCode)
 
     if type is None or type.isVoid():
         return (setUndefined(), True)
 
     if type.isArray():
         raise TypeError("Can't handle array return values yet")
 
     if type.isSequence():
         if type.nullable():
             # Nullable sequences are Nullable< nsTArray<T> >
             (recTemplate, recInfall) = getWrapTemplateForType(type.inner, descriptorProvider,
                                                               "%s.Value()" % result, successCode,
                                                               returnsNewObject, exceptionCode,
                                                               typedArraysAreStructs)
-            return ("""
-if (%s.IsNull()) {
-%s
-}
-%s""" % (result, CGIndenter(CGGeneric(setNull())).define(), recTemplate), recInfall)
+            code = fill(
+                """
+
+                if (${result}.IsNull()) {
+                  $*{setNull}
+                }
+                $*{recTemplate}
+                """,
+                result=result,
+                setNull=setNull(),
+                recTemplate=recTemplate)
+            return code, recInfall
 
         # Now do non-nullable sequences.  Our success code is just to break to
         # where we set the element in the array.  Note that we bump the
         # sequenceWrapLevel around this call so that nested sequence conversions
         # will use different iteration variables.
         global sequenceWrapLevel
         index = "sequenceIdx%d" % sequenceWrapLevel
         sequenceWrapLevel += 1
         innerTemplate = wrapForType(
             type.inner, descriptorProvider,
             {
                 'result': "%s[%s]" % (result, index),
-                'successCode': "break;",
+                'successCode': "break;\n",
                 'jsvalRef': "tmp",
                 'jsvalHandle': "&tmp",
                 'returnsNewObject': returnsNewObject,
                 'exceptionCode': exceptionCode,
                 'obj': "returnArray"
             })
         sequenceWrapLevel -= 1
-        innerTemplate = CGIndenter(CGGeneric(innerTemplate), 6).define()
-        template = """
-uint32_t length = %s.Length();
-JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
-if (!returnArray) {
-%s
-}
-// Scope for 'tmp'
-{
-  JS::Rooted<JS::Value> tmp(cx);
-  for (uint32_t %s = 0; %s < length; ++%s) {
-    // Control block to let us common up the JS_DefineElement calls when there
-    // are different ways to succeed at wrapping the object.
-    do {
-%s
-    } while (0);
-    if (!JS_DefineElement(cx, returnArray, %s, tmp,
-                          nullptr, nullptr, JSPROP_ENUMERATE)) {
-%s
-    }
-  }
-}
-%s"""
-        code = template % (result, exceptionCodeIndented.define(),
-                           index, index, index,
-                           innerTemplate, index,
-                           CGIndenter(exceptionCodeIndented, 4).define(),
-                           setObject("*returnArray"))
+        code = fill(
+            """
+
+            uint32_t length = ${result}.Length();
+            JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
+            if (!returnArray) {
+              $*{exceptionCode}
+            }
+            // Scope for 'tmp'
+            {
+              JS::Rooted<JS::Value> tmp(cx);
+              for (uint32_t ${index} = 0; ${index} < length; ++${index}) {
+                // Control block to let us common up the JS_DefineElement calls when there
+                // are different ways to succeed at wrapping the object.
+                do {
+                  $*{innerTemplate}
+                } while (0);
+                if (!JS_DefineElement(cx, returnArray, ${index}, tmp,
+                                      nullptr, nullptr, JSPROP_ENUMERATE)) {
+                  $*{exceptionCode}
+                }
+              }
+            }
+            $*{set}
+            """,
+            result=result,
+            exceptionCode=exceptionCode,
+            index=index,
+            innerTemplate=innerTemplate,
+            set=setObject("*returnArray"))
+
         return (code, False)
 
     if type.isGeckoInterface() and not type.isCallbackInterface():
         descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name)
         if type.nullable():
             wrappingCode = ("if (!%s) {\n" % (result) +
-                            CGIndenter(CGGeneric(setNull())).define() + "\n" +
+                            indent(setNull()) +
                             "}\n")
         else:
             wrappingCode = ""
 
         if not descriptor.interface.isExternal() and not descriptor.skipGen:
             if descriptor.wrapperCache:
                 assert descriptor.nativeOwnership != 'owned'
                 wrapMethod = "WrapNewBindingObject"
@@ -4901,50 +5123,52 @@ if (!returnArray) {
         else:
             return (wrapAndSetPtr("NonVoidByteStringToJsval(cx, %s, ${jsvalHandle})" % result), False)
 
     if type.isEnum():
         if type.nullable():
             resultLoc = "%s.Value()" % result
         else:
             resultLoc = result
-        conversionTemplate = """{
-  // Scope for resultStr
-  MOZ_ASSERT(uint32_t(%(result)s) < ArrayLength(%(strings)s));
-  JSString* resultStr = JS_NewStringCopyN(cx, %(strings)s[uint32_t(%(result)s)].value, %(strings)s[uint32_t(%(result)s)].length);
-  if (!resultStr) {
-%(exceptionCode)s
-  }
-"""
-        conversion = conversionTemplate % {
-            "result": resultLoc,
-            "strings": (type.unroll().inner.identifier.name + "Values::" +
-                        ENUM_ENTRY_VARIABLE_NAME),
-            "exceptionCode": CGIndenter(exceptionCodeIndented).define()
-        }
-        conversion += CGIndenter(CGGeneric(setString("resultStr"))).define() + "\n}"
+        conversion = fill(
+            """
+            {
+              // Scope for resultStr
+              MOZ_ASSERT(uint32_t(${result}) < ArrayLength(${strings}));
+              JSString* resultStr = JS_NewStringCopyN(cx, ${strings}[uint32_t(${result})].value, ${strings}[uint32_t(${result})].length);
+              if (!resultStr) {
+                $*{exceptionCode}
+              }
+              $*{setResultStr}
+            }
+            """,
+            result=resultLoc,
+            strings=(type.unroll().inner.identifier.name + "Values::" +
+                     ENUM_ENTRY_VARIABLE_NAME),
+            exceptionCode=exceptionCode,
+            setResultStr=setString("resultStr"))
 
         if type.nullable():
             conversion = CGIfElseWrapper(
                 "%s.IsNull()" % result,
                 CGGeneric(setNull()),
                 CGGeneric(conversion)).define()
         return conversion, False
 
     if type.isCallback() or type.isCallbackInterface():
         wrapCode = setObject(
             "*GetCallbackFromCallbackObject(%(result)s)",
             wrapAsType=type)
         if type.nullable():
             wrapCode = (
                 "if (%(result)s) {\n" +
-                CGIndenter(CGGeneric(wrapCode)).define() + "\n"
+                indent(wrapCode) +
                 "} else {\n" +
-                CGIndenter(CGGeneric(setNull())).define() + "\n"
-                "}")
+                indent(setNull()) +
+                "}\n")
         wrapCode = wrapCode % {"result": result}
         return wrapCode, False
 
     if type.isAny():
         # See comments in WrapNewBindingObject explaining why we need
         # to wrap here.
         # NB: _setValue(..., type-that-is-any) calls JS_WrapValue(), so is fallible
         return (_setValue(result, wrapAsType=type), False)
@@ -4968,18 +5192,19 @@ if (!returnArray) {
         raise TypeError("Need to learn to wrap %s" % type)
 
     if type.nullable():
         (recTemplate, recInfal) = getWrapTemplateForType(type.inner, descriptorProvider,
                                                          "%s.Value()" % result, successCode,
                                                          returnsNewObject, exceptionCode,
                                                          typedArraysAreStructs)
         return ("if (%s.IsNull()) {\n" % result +
-                CGIndenter(CGGeneric(setNull())).define() + "\n" +
-                "}\n" + recTemplate, recInfal)
+                indent(setNull()) +
+                "}\n" +
+                recTemplate, recInfal)
 
     if type.isSpiderMonkeyInterface():
         assert typedArraysAreStructs
         # See comments in WrapNewBindingObject explaining why we need
         # to wrap here.
         # NB: setObject(..., some-object-type) calls JS_WrapValue(), so is fallible
         return (setObject("*%s.Obj()" % result,
                           wrapAsType=type), False)
@@ -5051,17 +5276,17 @@ def wrapForType(type, descriptorProvider
                                     The default is "return false;".  The code
                                     passed here must return.
     """
     wrap = getWrapTemplateForType(type, descriptorProvider,
                                   templateValues.get('result', 'result'),
                                   templateValues.get('successCode', None),
                                   templateValues.get('returnsNewObject', False),
                                   templateValues.get('exceptionCode',
-                                                     "return false;"),
+                                                     "return false;\n"),
                                   templateValues.get('typedArraysAreStructs',
                                                      False))[0]
 
     defaultValues = {'obj': 'obj'}
     return string.Template(wrap).substitute(defaultValues, **templateValues)
 
 
 def infallibleForMember(member, type, descriptorProvider):
@@ -5071,17 +5296,17 @@ def infallibleForMember(member, type, de
     are used, since the fallbility does not change based on the boolean values,
     and the template will be discarded.
 
     CURRENT ASSUMPTIONS:
         We assume that successCode for wrapping up return values cannot contain
         failure conditions.
     """
     return getWrapTemplateForType(type, descriptorProvider, 'result', None,
-                                  memberReturnsNewObject(member), "return false;",
+                                  memberReturnsNewObject(member), "return false;\n",
                                   False)[1]
 
 
 def leafTypeNeedsCx(type, retVal):
     return (type.isAny() or type.isObject() or
             (retVal and type.isSpiderMonkeyInterface()))
 
 
@@ -5192,17 +5417,17 @@ def getRetvalDeclarationForType(returnTy
         # If our result is already addrefed, use the right type in the
         # sequence argument here.
         (result, _, _, _) = getRetvalDeclarationForType(returnType.inner,
                                                         descriptorProvider,
                                                         resultAlreadyAddRefed,
                                                         isMember="Sequence")
         # While we have our inner type, set up our rooter, if needed
         if not isMember and typeNeedsRooting(returnType):
-            rooter = CGGeneric("SequenceRooter<%s > resultRooter(cx, &result);" %
+            rooter = CGGeneric("SequenceRooter<%s > resultRooter(cx, &result);\n" %
                                result.define())
         else:
             rooter = None
         result = CGTemplatedType("nsTArray", result)
         if nullable:
             result = CGTemplatedType("Nullable", result)
         return result, True, rooter, None
     if returnType.isDictionary():
@@ -5326,43 +5551,43 @@ class CGCallGenerator(CGThing):
         # Return values that go in outparams go here
         if resultOutParam:
             args.append(CGGeneric("result"))
         if isFallible:
             args.append(CGGeneric("rv"))
         args.extend(CGGeneric(arg) for arg in argsPost)
 
         # Build up our actual call
-        self.cgRoot = CGList([], "\n")
+        self.cgRoot = CGList([])
 
         call = CGGeneric(nativeMethodName)
         if not static:
             call = CGWrapper(call, pre="%s->" % object)
-        call = CGList([call, CGWrapper(args, pre="(", post=");")])
+        call = CGList([call, CGWrapper(args, pre="(", post=");\n")])
         if result is not None:
             if resultRooter is not None:
                 self.cgRoot.prepend(resultRooter)
             if resultArgs is not None:
                 resultArgs = "(%s)" % resultArgs
             else:
                 resultArgs = ""
-            result = CGWrapper(result, post=(" result%s;" % resultArgs))
+            result = CGWrapper(result, post=(" result%s;\n" % resultArgs))
             self.cgRoot.prepend(result)
             if not resultOutParam:
                 call = CGWrapper(call, pre="result = ")
 
         call = CGWrapper(call)
         self.cgRoot.append(call)
 
         if isFallible:
-            self.cgRoot.prepend(CGGeneric("ErrorResult rv;"))
-            self.cgRoot.append(CGGeneric("rv.WouldReportJSException();"))
-            self.cgRoot.append(CGGeneric("if (rv.Failed()) {"))
+            self.cgRoot.prepend(CGGeneric("ErrorResult rv;\n"))
+            self.cgRoot.append(CGGeneric("rv.WouldReportJSException();\n"))
+            self.cgRoot.append(CGGeneric("if (rv.Failed()) {\n"))
             self.cgRoot.append(CGIndenter(errorReport))
-            self.cgRoot.append(CGGeneric("}"))
+            self.cgRoot.append(CGGeneric("}\n"))
 
     def define(self):
         return self.cgRoot.define()
 
 
 def getUnionMemberName(type):
     if type.isGeckoInterface():
         return type.inner.identifier.name
@@ -5392,34 +5617,34 @@ def wrapTypeIntoCurrentCompartment(type,
     if type.isAny():
         assert not type.nullable()
         if isMember:
             value = "JS::MutableHandle<JS::Value>::fromMarkedLocation(&%s)" % value
         else:
             value = "&" + value
         return CGGeneric("if (!JS_WrapValue(cx, %s)) {\n"
                          "  return false;\n"
-                         "}" % value)
+                         "}\n" % value)
 
     if type.isObject():
         if isMember:
             value = "JS::MutableHandle<JSObject*>::fromMarkedLocation(&%s)" % value
         else:
             value = "&" + value
         return CGGeneric("if (!JS_WrapObject(cx, %s)) {\n"
                          "  return false;\n"
-                         "}" % value)
+                         "}\n" % value)
 
     if type.isSpiderMonkeyInterface():
         origValue = value
         if type.nullable():
             value = "%s.Value()" % value
         wrapCode = CGGeneric("if (!%s.WrapIntoNewCompartment(cx)) {\n"
                              "  return false;\n"
-                             "}" % value)
+                             "}\n" % value)
         if type.nullable():
             wrapCode = CGIfWrapper(wrapCode, "!%s.IsNull()" % origValue)
         return wrapCode
 
     if type.isSequence():
         origValue = value
         origType = type
         if type.nullable():
@@ -5431,34 +5656,34 @@ def wrapTypeIntoCurrentCompartment(type,
         wrapElement = wrapTypeIntoCurrentCompartment(type.inner,
                                                      "%s[%s]" % (value, index))
         sequenceWrapLevel -= 1
         if not wrapElement:
             return None
         wrapCode = CGWrapper(CGIndenter(wrapElement),
                              pre=("for (uint32_t %s = 0; %s < %s.Length(); ++%s) {\n" %
                                   (index, index, value, index)),
-                             post="\n}")
+                             post="}\n")
         if origType.nullable():
             wrapCode = CGIfWrapper(wrapCode, "!%s.IsNull()" % origValue)
         return wrapCode
 
     if type.isDictionary():
         assert not type.nullable()
         myDict = type.inner
         memberWraps = []
         while myDict:
             for member in myDict.members:
                 memberWrap = wrapArgIntoCurrentCompartment(
                     member,
                     "%s.%s" % (value, CGDictionary.makeMemberName(member.identifier.name)))
                 if memberWrap:
                     memberWraps.append(memberWrap)
             myDict = myDict.parent
-        return CGList(memberWraps, "\n") if len(memberWraps) != 0 else None
+        return CGList(memberWraps) if len(memberWraps) != 0 else None
 
     if type.isUnion():
         memberWraps = []
         if type.nullable():
             type = type.inner
             value = "%s.Value()" % value
         for member in type.flatMemberTypes:
             memberName = getUnionMemberName(member)
@@ -5532,39 +5757,43 @@ class CGPerSignatureCall(CGThing):
                                                                    getter=getter,
                                                                    setter=setter)
         self.arguments = arguments
         self.argCount = len(arguments)
         cgThings = []
         lenientFloatCode = None
         if idlNode.getExtendedAttribute('LenientFloat') is not None:
             if setter:
-                lenientFloatCode = "return true;"
+                lenientFloatCode = "return true;\n"
             elif idlNode.isMethod():
                 lenientFloatCode = ("args.rval().setUndefined();\n"
-                                    "return true;")
+                                    "return true;\n")
 
         argsPre = []
         if static:
             nativeMethodName = "%s::%s" % (descriptor.nativeType,
                                            nativeMethodName)
             # If we're a constructor, "obj" may not be a function, so calling
             # XrayAwareCalleeGlobal() on it is not safe.  Of course in the
             # constructor case either "obj" is an Xray or we're already in the
             # content compartment, not the Xray compartment, so just
             # constructing the GlobalObject from "obj" is fine.
             if isConstructor:
                 objForGlobalObject = "obj"
             else:
                 objForGlobalObject = "xpc::XrayAwareCalleeGlobal(obj)"
-            cgThings.append(CGGeneric("""GlobalObject global(cx, %s);
-if (global.Failed()) {
-  return false;
-}
-""" % objForGlobalObject))
+            cgThings.append(CGGeneric(fill(
+                """
+                GlobalObject global(cx, ${obj});
+                if (global.Failed()) {
+                  return false;
+                }
+
+                """,
+                obj=objForGlobalObject)))
             argsPre.append("global")
 
         # For JS-implemented interfaces we do not want to base the
         # needsCx decision on the types involved, just on our extended
         # attributes.
         needsCx = needCx(returnType, arguments, self.extendedAttributes,
                          not descriptor.interface.isJSImplemented())
         if needsCx and not (static and descriptor.workers):
@@ -5585,17 +5814,17 @@ if (global.Failed()) {
                              idlNode.getExtendedAttribute("StoreInSlot")):
             needsUnwrap = True
             needsUnwrappedVar = True
             argsPre.append("unwrappedObj.empty() ? obj : unwrappedObj.ref()")
 
         if needsUnwrap and needsUnwrappedVar:
             # We cannot assign into obj because it's a Handle, not a
             # MutableHandle, so we need a separate Rooted.
-            cgThings.append(CGGeneric("Maybe<JS::Rooted<JSObject*> > unwrappedObj;"))
+            cgThings.append(CGGeneric("Maybe<JS::Rooted<JSObject*> > unwrappedObj;\n"))
             unwrappedVar = "unwrappedObj.ref()"
 
         if idlNode.isMethod() and idlNode.isLegacycaller():
             # If we can have legacycaller with identifier, we can't
             # just use the idlNode to determine whether we're
             # generating code for the legacycaller or not.
             assert idlNode.isIdentifierLess()
             # Pass in our thisVal
@@ -5611,64 +5840,67 @@ if (global.Failed()) {
             assert self.argCount == 0
 
         if needsUnwrap:
             # It's very important that we construct our unwrappedObj, if we need
             # to do it, before we might start setting up Rooted things for our
             # arguments, so that we don't violate the stack discipline Rooted
             # depends on.
             cgThings.append(CGGeneric(
-                "bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);"))
+                "bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);\n"))
             if needsUnwrappedVar:
                 cgThings.append(CGIfWrapper(
-                    CGGeneric("unwrappedObj.construct(cx, obj);"),
+                    CGGeneric("unwrappedObj.construct(cx, obj);\n"),
                     "objIsXray"))
 
-        cgThings.extend([CGArgumentConverter(arguments[i], i, self.descriptor,
-                                             argDescription % {"index": i + 1},
-                                             invalidEnumValueFatal=not setter,
-                                             lenientFloatCode=lenientFloatCode)
-                         for i in range(argConversionStartsAt, self.argCount)])
+        for i in range(argConversionStartsAt, self.argCount):
+            cgThings.append(
+                CGArgumentConverter(arguments[i], i, self.descriptor,
+                                    argDescription % {"index": i + 1},
+                                    invalidEnumValueFatal=not setter,
+                                    lenientFloatCode=lenientFloatCode))
 
         if needsUnwrap:
             # Something depends on having the unwrapped object, so unwrap it now.
             xraySteps = []
             # XXXkhuey we should be able to MOZ_ASSERT that ${obj} is
             # not null.
             xraySteps.append(
-                CGGeneric(string.Template("""${obj} = js::CheckedUnwrap(${obj});
-if (!${obj}) {
-  return false;
-}""").substitute({'obj': unwrappedVar})))
+                CGGeneric(string.Template(dedent("""
+                    ${obj} = js::CheckedUnwrap(${obj});
+                    if (!${obj}) {
+                      return false;
+                    }
+                    """)).substitute({'obj': unwrappedVar})))
             if isConstructor:
                 # If we're called via an xray, we need to enter the underlying
                 # object's compartment and then wrap up all of our arguments into
                 # that compartment as needed.  This is all happening after we've
                 # already done the conversions from JS values to WebIDL (C++)
                 # values, so we only need to worry about cases where there are 'any'
                 # or 'object' types, or other things that we represent as actual
                 # JSAPI types, present.  Effectively, we're emulating a
                 # CrossCompartmentWrapper, but working with the C++ types, not the
                 # original list of JS::Values.
-                cgThings.append(CGGeneric("Maybe<JSAutoCompartment> ac;"))
-                xraySteps.append(CGGeneric("ac.construct(cx, obj);"))
+                cgThings.append(CGGeneric("Maybe<JSAutoCompartment> ac;\n"))
+                xraySteps.append(CGGeneric("ac.construct(cx, obj);\n"))
                 xraySteps.extend(
                     wrapArgIntoCurrentCompartment(arg, argname, isMember=False)
                     for (arg, argname) in self.getArguments())
 
             cgThings.append(
-                CGIfWrapper(CGList(xraySteps, "\n"),
+                CGIfWrapper(CGList(xraySteps),
                             "objIsXray"))
 
         cgThings.append(CGCallGenerator(
             self.getErrorReport() if self.isFallible() else None,
             self.getArguments(), argsPre, returnType,
             self.extendedAttributes, descriptor, nativeMethodName,
             static, argsPost=argsPost))
-        self.cgRoot = CGList(cgThings, "\n")
+        self.cgRoot = CGList(cgThings)
 
     def getArguments(self):
         return [(a, "arg" + str(i)) for (i, a) in enumerate(self.arguments)]
 
     def isFallible(self):
         return not 'infallible' in self.extendedAttributes
 
     def wrap_return_value(self):
@@ -5679,30 +5911,29 @@ if (!${obj}) {
                    # NewObject can return raw pointers to owned objects
                    (self.returnType.isGeckoInterface() and
                     self.descriptor.getDescriptor(self.returnType.unroll().inner.identifier.name).nativeOwnership == 'owned'))
 
         setSlot = self.idlNode.isAttr() and self.idlNode.slotIndex is not None
         if setSlot:
             # For attributes in slots, we want to do some
             # post-processing once we've wrapped them.
-            successCode = "break;"
+            successCode = "break;\n"
         else:
             successCode = None
 
         resultTemplateValues = {
             'jsvalRef': 'args.rval()',
             'jsvalHandle': 'args.rval()',
             'returnsNewObject': returnsNewObject,
             'successCode': successCode,
             'obj': "reflector" if setSlot else "obj"
         }
         try:
-            wrapCode = CGGeneric(wrapForType(self.returnType, self.descriptor,
-                                             resultTemplateValues))
+            wrapCode = wrapForType(self.returnType, self.descriptor, resultTemplateValues)
         except MethodNotNewObjectError, err:
             assert not returnsNewObject
             raise TypeError("%s being returned from non-NewObject method or property %s.%s" %
                             (err.typename,
                              self.descriptor.interface.identifier.name,
                              self.idlNode.identifier.name))
         if setSlot:
             # We need to make sure that our initial wrapping is done in the
@@ -5716,106 +5947,107 @@ if (!${obj}) {
             # wrapping into args.rval().
             postSteps = ""
             if self.idlNode.getExtendedAttribute("Frozen"):
                 assert self.idlNode.type.isSequence() or self.idlNode.type.isDictionary()
                 freezeValue = CGGeneric(
                     "JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());\n"
                     "if (!JS_FreezeObject(cx, rvalObj)) {\n"
                     "  return false;\n"
-                    "}")
+                    "}\n")
                 if self.idlNode.type.nullable():
                     freezeValue = CGIfWrapper(freezeValue,
                                               "args.rval().isObject()")
-                postSteps += freezeValue.define() + "\n"
+                postSteps += freezeValue.define()
             postSteps += ("js::SetReservedSlot(reflector, %s, args.rval());\n" %
                           memberReservedSlot(self.idlNode))
             # For the case of Cached attributes, go ahead and preserve our
             # 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):
                 postSteps += "PreserveWrapper(self);\n"
 
-            wrapCode = CGWrapper(
-                CGIndenter(wrapCode, 4),
-                pre=("{ // Make sure we wrap and store in the slot in reflector's compartment\n"
-                     "  JSAutoCompartment ac(cx, reflector);\n"
-                     "  do { // block we break out of when done wrapping\n"),
-                post=("\n"
-                      "  } while (0);\n"
-                      "%s"
-                      "}\n"
-                      "// And now make sure args.rval() is in the caller compartment\n"
-                      "return %s(cx, args.rval());" %
-                      (CGIndenter(CGGeneric(postSteps)).define(),
-                       getMaybeWrapValueFuncForType(self.idlNode.type))))
-        return wrapCode.define()
+            wrapCode = fill(
+                """
+                { // Make sure we wrap and store in the slot in reflector's compartment
+                  JSAutoCompartment ac(cx, reflector);
+                  do { // block we break out of when done wrapping
+                    $*{wrapCode}
+                  } while (0);
+                  $*{postSteps}
+                }
+                // And now make sure args.rval() is in the caller compartment
+                return ${maybeWrap}(cx, args.rval());
+                """,
+                wrapCode=wrapCode,
+                postSteps=postSteps,
+                maybeWrap=getMaybeWrapValueFuncForType(self.idlNode.type))
+        return wrapCode
 
     def getErrorReport(self):
         jsImplemented = ""
         if self.descriptor.interface.isJSImplemented():
             jsImplemented = ", true"
-        return CGGeneric('return ThrowMethodFailedWithDetails(cx, rv, "%s", "%s"%s);'
+        return CGGeneric('return ThrowMethodFailedWithDetails(cx, rv, "%s", "%s"%s);\n'
                          % (self.descriptor.interface.identifier.name,
                             self.idlNode.identifier.name,
                             jsImplemented))
 
     def define(self):
-        return (self.cgRoot.define() + "\n" + self.wrap_return_value())
+        return (self.cgRoot.define() + self.wrap_return_value())
 
 
 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], "\n")
-        self.prepend(CGWrapper(CGGeneric(expression),
-                               pre="switch (", post=") {"))
+        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),
                         pre="default: {\n",
-                        post="\n  break;\n}")))
-
-        self.append(CGGeneric("}"))
+                        post="  break;\n}\n")))
+
+        self.append(CGGeneric("}\n"))
 
 
 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, [], "\n")
-        self.append(CGWrapper(CGGeneric(expression), pre="case ", post=": {"))
-        bodyList = CGList([body], "\n")
+        CGList.__init__(self, [])
+        self.append(CGGeneric("case " + expression + ": {\n"))
+        bodyList = CGList([body])
         if fallThrough:
-            bodyList.append(CGGeneric("/* Fall through */"))
-        else:
-            bodyList.append(CGGeneric("break;"))
+            bodyList.append(CGGeneric("/* Fall through */\n"))
+        else:
+            bodyList.append(CGGeneric("break;\n"))
         self.append(CGIndenter(bodyList))
-        self.append(CGGeneric("}"))
+        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,
@@ -5850,22 +6082,26 @@ class CGMethodCall(CGThing):
             # Special case: we can just do a per-signature method call
             # here for our one signature and not worry about switching
             # on anything.
             signature = signatures[0]
             self.cgRoot = CGList([CGIndenter(getPerSignatureCall(signature))])
             requiredArgs = requiredArgCount(signature)
 
             if requiredArgs > 0:
-                code = (
-                    "if (args.length() < %d) {\n"
-                    '  return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "%s");\n'
-                    "}" % (requiredArgs, methodName))
-                self.cgRoot.prepend(
-                    CGWrapper(CGIndenter(CGGeneric(code)), pre="\n", post="\n"))
+                code = indent(fill(  # BOGUS extra blank line
+                    """
+
+                    if (args.length() < ${requiredArgs}) {
+                      return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "${methodName}");
+                    }
+                    """,
+                    requiredArgs=requiredArgs,
+                    methodName=methodName))
+                self.cgRoot.prepend(CGGeneric(code))
             return
 
         # Need to find the right overload
         maxArgCount = method.maxArgCount
         allowedArgCounts = method.allowedArgCounts
 
         argCountCases = []
         for (argCountIdx, argCount) in enumerate(allowedArgCounts):
@@ -5949,17 +6185,17 @@ class CGMethodCall(CGThing):
             # Select the right overload from our set.
             distinguishingArg = "args[%d]" % distinguishingIndex
 
             def tryCall(signature, indent, isDefinitelyObject=False,
                         isNullOrUndefined=False):
                 assert not isDefinitelyObject or not isNullOrUndefined
                 assert isDefinitelyObject or isNullOrUndefined
                 if isDefinitelyObject:
-                    failureCode = "break;"
+                    failureCode = "break;\n"
                 else:
                     failureCode = None
                 type = distinguishingType(signature)
                 # The argument at index distinguishingIndex can't possibly be
                 # unset here, because we've already checked that argc is large
                 # enough that we can examine this argument.  But note that we
                 # still want to claim that optional arguments are optional, in
                 # case undefined was passed in.
@@ -6039,40 +6275,40 @@ class CGMethodCall(CGThing):
                          distinguishingIndex < len(s[1]) and
                          s[1][distinguishingIndex].optional and
                          hasConditionalConversion(s[1][distinguishingIndex].type) and
                          not needsNullOrUndefinedCase(s[1][distinguishingIndex].type)]
             # Can't have multiple signatures with an optional argument at the
             # same index.
             assert len(undefSigs) < 2
             if len(undefSigs) > 0:
-                caseBody.append(CGGeneric("if (%s.isUndefined()) {" %
+                caseBody.append(CGGeneric("if (%s.isUndefined()) {\n" %
                                           distinguishingArg))
                 tryCall(undefSigs[0], 2, isNullOrUndefined=True)
-                caseBody.append(CGGeneric("}"))
+                caseBody.append(CGGeneric("}\n"))
 
             # Next, check for null or undefined.  That means looking for
             # nullable arguments at the distinguishing index and outputting a
             # separate branch for them.  But if the nullable argument has an
             # unconditional conversion, we don't need to do that.  The reason
             # for that is that at most one argument at the distinguishing index
             # is nullable (since two nullable arguments are not
             # distinguishable), and null/undefined values will always fall
             # through to the unconditional conversion we have, if any, since
             # they will fail whatever the conditions on the input value are for
             # our other conversions.
             nullOrUndefSigs = [s for s in possibleSignatures
                                if needsNullOrUndefinedCase(distinguishingType(s))]
             # Can't have multiple nullable types here
             assert len(nullOrUndefSigs) < 2
             if len(nullOrUndefSigs) > 0:
-                caseBody.append(CGGeneric("if (%s.isNullOrUndefined()) {" %
+                caseBody.append(CGGeneric("if (%s.isNullOrUndefined()) {\n" %
                                           distinguishingArg))
                 tryCall(nullOrUndefSigs[0], 2, isNullOrUndefined=True)
-                caseBody.append(CGGeneric("}"))
+                caseBody.append(CGGeneric("}\n"))
 
             # Now check for distinguishingArg being various kinds of objects.
             # The spec says to check for the following things in order:
             # 1)  A platform object that's not a platform array object, being
             #     passed to an interface or "object" arg.
             # 2)  A Date object being passed to a Date or "object" arg.
             # 3)  A RegExp object being passed to a RegExp or "object" arg.
             # 4)  A callable object being passed to a callback or "object" arg.
@@ -6119,26 +6355,26 @@ class CGMethodCall(CGThing):
                 # sequences, arrays, and Dates will just bail out and move on to
                 # the next overload if the object fails to unwrap correctly,
                 # while "object" accepts any object anyway.  We could even not
                 # do the isObject() check up front here, but in cases where we
                 # have multiple object overloads it makes sense to do it only
                 # once instead of for each overload.  That will also allow the
                 # unwrapping test to skip having to do codegen for the
                 # null-or-undefined case, which we already handled above.
-                caseBody.append(CGGeneric("if (%s.isObject()) {" %
+                caseBody.append(CGGeneric("if (%s.isObject()) {\n" %
                                           distinguishingArg))
                 for sig in objectSigs:
-                    caseBody.append(CGIndenter(CGGeneric("do {")))
+                    caseBody.append(CGIndenter(CGGeneric("do {\n")))
                     # Indent by 4, since we need to indent further
                     # than our "do" statement
                     tryCall(sig, 4, isDefinitelyObject=True)
-                    caseBody.append(CGIndenter(CGGeneric("} while (0);")))
-
-                caseBody.append(CGGeneric("}"))
+                    caseBody.append(CGIndenter(CGGeneric("} while (0);\n")))
+
+                caseBody.append(CGGeneric("}\n"))
 
             # Now we only have to consider booleans, numerics, and strings.  If
             # we only have one of them, then we can just output it.  But if not,
             # then we need to output some of the cases conditionally: if we have
             # a string overload, then boolean and numeric are conditional, and
             # if not then boolean is conditional if we have a numeric overload.
             def findUniqueSignature(filterLambda):
                 sigs = filter(filterLambda, possibleSignatures)
@@ -6179,34 +6415,35 @@ class CGMethodCall(CGThing):
             if stringSignature:
                 addCase(stringSignature, None)
 
             if (not booleanSignature and not numericSignature and
                 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");' %
+                    'return ThrowErrorMessage(cx, MSG_OVERLOAD_RESOLUTION_FAILED, "%d", "%d", "%s");\n' %
                     (distinguishingIndex + 1, argCount, methodName)))
 
-            argCountCases.append(CGCase(str(argCount),
-                                        CGList(caseBody, "\n")))
+            argCountCases.append(CGCase(str(argCount), CGList(caseBody)))
 
         overloadCGThings = []
         overloadCGThings.append(
-            CGGeneric("unsigned argcount = std::min(args.length(), %du);" %
+            CGGeneric("unsigned argcount = std::min(args.length(), %du);\n" %
                       maxArgCount))
         overloadCGThings.append(
             CGSwitch("argcount",
                      argCountCases,
-                     CGGeneric('return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "%s");\n' % methodName)))
+                     # BOGUS extra blank line at end of default block
+                     CGGeneric('return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "%s");\n\n' %
+                               methodName)))
         overloadCGThings.append(
             CGGeneric('MOZ_CRASH("We have an always-returning default case");\n'
-                      'return false;'))
-        self.cgRoot = CGWrapper(CGIndenter(CGList(overloadCGThings, "\n")),
+                      'return false;\n'))
+        self.cgRoot = CGWrapper(CGIndenter(CGList(overloadCGThings)),
                                 pre="\n")
 
     def define(self):
         return self.cgRoot.define()
 
 
 class CGGetterCall(CGPerSignatureCall):
     """
@@ -6267,17 +6504,17 @@ class CGSetterCall(CGPerSignatureCall):
             clearSlot = ("ClearCached%sValue(%s);\n" %
                          (MakeNativeName(self.idlNode.identifier.name), args))
         else:
             clearSlot = ""
 
         # We have no return value
         return ("\n"
                 "%s"
-                "return true;" % clearSlot)
+                "return true;\n" % clearSlot)
 
 
 class CGAbstractBindingMethod(CGAbstractStaticMethod):
     """
     Common class to generate the JSNatives for all our methods, getters, and
     setters.  This will generate the function declaration and unwrap the
     |this| object.  Subclasses are expected to override the generate_code
     function to do the rest of the work.  This function should return a
@@ -6292,22 +6529,22 @@ class CGAbstractBindingMethod(CGAbstract
     called 'args'.  This can be "" if there is already such a variable
     around.
 
     If allowCrossOriginThis is true, then this-unwrapping will first do an
     UncheckedUnwrap and after that operate on the result.
     """
     def __init__(self, descriptor, name, args, unwrapFailureCode=None,
                  getThisObj=None,
-                 callArgs="JS::CallArgs args = JS::CallArgsFromVp(argc, vp);",
+                 callArgs="JS::CallArgs args = JS::CallArgsFromVp(argc, vp);\n",
                  allowCrossOriginThis=False):
         CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
 
         if unwrapFailureCode is None:
-            self.unwrapFailureCode = 'return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "%s");' % descriptor.interface.identifier.name
+            self.unwrapFailureCode = 'return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "%s");\n' % descriptor.interface.identifier.name
         else:
             self.unwrapFailureCode = unwrapFailureCode
 
         if getThisObj == "":
             self.getThisObj = None
         else:
             if getThisObj is None:
                 if descriptor.interface.isOnGlobalProtoChain():
@@ -6319,42 +6556,36 @@ class CGAbstractBindingMethod(CGAbstract
                 unwrapFailureCode = self.unwrapFailureCode % {'securityError': 'false'}
                 ensureThisObj = CGIfWrapper(CGGeneric(unwrapFailureCode),
                                             ensureCondition)
             else:
                 ensureThisObj = None
             self.getThisObj = CGList(
                 [ensureThisObj,
                  CGGeneric("JS::Rooted<JSObject*> obj(cx, %s);\n" %
-                           getThisObj)],
-                "\n")
+                           getThisObj)])
         self.callArgs = callArgs
         self.allowCrossOriginThis = allowCrossOriginThis
 
     def definition_body(self):
+        body = self.callArgs
+        if self.getThisObj is not None:
+            body += self.getThisObj.define() + "\n"
+        body += "%s* self;\n" % self.descriptor.nativeType
+
         # Our descriptor might claim that we're not castable, simply because
         # we're someone's consequential interface.  But for this-unwrapping, we
         # know that we're the real deal.  So fake a descriptor here for
         # consumption by CastableObjectUnwrapper.
-        getThis = CGList([
-            CGGeneric(self.callArgs) if self.callArgs != "" else None,
-            self.getThisObj,
-            CGGeneric("%s* self;" % self.descriptor.nativeType)
-        ], "\n")
-
-        unwrapThis = CGGeneric(
-            str(CastableObjectUnwrapper(
-                self.descriptor,
-                "obj", "self", self.unwrapFailureCode,
-                allowCrossOriginObj=self.allowCrossOriginThis)))
-        return CGList([
-            CGIndenter(getThis),
-            CGIndenter(unwrapThis),
-            self.generate_code()
-        ], "\n").define()
+        body += str(CastableObjectUnwrapper(
+            self.descriptor,
+            "obj", "self", self.unwrapFailureCode,
+            allowCrossOriginObj=self.allowCrossOriginThis))
+
+        return indent(body) + self.generate_code().define()
 
     def generate_code(self):
         assert False  # Override me
 
 
 class CGAbstractStaticBindingMethod(CGAbstractStaticMethod):
     """
     Common class to generate the JSNatives for all our static methods, getters
@@ -6366,19 +6597,22 @@ class CGAbstractStaticBindingMethod(CGAb
     def __init__(self, descriptor, name):
         args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
                 Argument('JS::Value*', 'vp')]
         CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
 
     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 = CGGeneric("""JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-JS::Rooted<JSObject*> obj(cx, &args.callee());""")
-        return CGList([CGIndenter(unwrap), self.generate_code()], "\n\n").define()
+        unwrap = indent(dedent("""
+            JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+            JS::Rooted<JSObject*> obj(cx, &args.callee());
+
+            """))
+        return unwrap + self.generate_code().define()
 
     def generate_code(self):
         assert False  # Override me
 
 
 def MakeNativeName(name):
     return name[0].upper() + name[1:]
 
@@ -6389,30 +6623,31 @@ class CGGenericMethod(CGAbstractBindingM
 
     If allowCrossOriginThis is true, then this-unwrapping will first do an
     UncheckedUnwrap and after that operate on the result.
     """
     def __init__(self, descriptor, allowCrossOriginThis=False):
         args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
                 Argument('JS::Value*', 'vp')]
         unwrapFailureCode = (
-            'return ThrowInvalidThis(cx, args, GetInvalidThisErrorForMethod(%%(securityError)s), "%s");' %
+            'return ThrowInvalidThis(cx, args, GetInvalidThisErrorForMethod(%%(securityError)s), "%s");\n' %
             descriptor.interface.identifier.name)
         name = "genericCrossOriginMethod" if allowCrossOriginThis else "genericMethod"
         CGAbstractBindingMethod.__init__(self, descriptor, name,
                                          args,
                                          unwrapFailureCode=unwrapFailureCode,
                                          allowCrossOriginThis=allowCrossOriginThis)
 
     def generate_code(self):
-        return CGIndenter(CGGeneric(
-            "const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());\n"
-            "MOZ_ASSERT(info->type() == JSJitInfo::Method);\n"
-            "JSJitMethodOp method = info->method;\n"
-            "return method(cx, obj, self, JSJitMethodCallArgs(args));"))
+        return CGGeneric(indent(dedent("""
+            const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
+            MOZ_ASSERT(info->type() == JSJitInfo::Method);
+            JSJitMethodOp method = info->method;
+            return method(cx, obj, self, JSJitMethodCallArgs(args));
+            """)))
 
 
 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):
@@ -6442,59 +6677,67 @@ class CGMethodPromiseWrapper(CGAbstractS
     """
     def __init__(self, descriptor, methodToWrap):
         self.method = methodToWrap
         name = self.makeName(methodToWrap.name)
         args = list(methodToWrap.args)
         CGAbstractStaticMethod.__init__(self, descriptor, name, 'bool', args)
 
     def definition_body(self):
-        return (
-            "  // Make sure to save the callee before someone maybe messes\n"
-            "  // with rval().\n"
-            "  JS::Rooted<JSObject*> callee(cx, &args.callee());\n"
-            "  bool ok = %s(%s);\n"
-            "  if (ok) {\n"
-            "    return true;\n"
-            "  }\n"
-            "  return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),\n"
-            "                                   args.rval());" %
-            (self.method.name,
-             ", ".join(arg.name for arg in self.args)))
+        return indent(fill(
+            """
+            // Make sure to save the callee before someone maybe messes
+            // with rval().
+            JS::Rooted<JSObject*> callee(cx, &args.callee());
+            bool ok = ${methodName}(${args});
+            if (ok) {
+              return true;
+            }
+            return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
+                                             args.rval());
+            """,
+            methodName=self.method.name,
+            args=", ".join(arg.name for arg in self.args)))
 
     @staticmethod
     def makeName(methodName):
         return methodName + "_promiseWrapper"
 
 
 class CGJsonifierMethod(CGSpecializedMethod):
     def __init__(self, descriptor, method):
         assert method.isJsonifier()
         CGSpecializedMethod.__init__(self, descriptor, method)
 
     def definition_body(self):
-        ret = ('JS::Rooted<JSObject*> result(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));\n'
-               'if (!result) {\n'
-               '  return false;\n'
-               '}\n')
+        ret = dedent("""
+            JS::Rooted<JSObject*> result(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
+            if (!result) {
+              return false;
+            }
+            """)
         for m in self.descriptor.interface.members:
             if m.isAttr() and not m.isStatic() and m.type.isSerializable():
-                ret += ('{ // scope for "temp"\n'
-                        '  JS::Rooted<JS::Value> temp(cx);\n'
-                        '  if (!get_%s(cx, obj, self, JSJitGetterCallArgs(&temp))) {\n'
-                        '    return false;\n'
-                        '  }\n'
-                        '  if (!JS_DefineProperty(cx, result, "%s", temp, JSPROP_ENUMERATE)) {\n'
-                        '    return false;\n'
-                        '  }\n'
-                        '}\n' % (m.identifier.name, m.identifier.name))
+                ret += fill(
+                    """
+                    { // scope for "temp"
+                      JS::Rooted<JS::Value> temp(cx);
+                      if (!get_${name}(cx, obj, self, JSJitGetterCallArgs(&temp))) {
+                        return false;
+                      }
+                      if (!JS_DefineProperty(cx, result, "${name}", temp, JSPROP_ENUMERATE)) {
+                        return false;
+                      }
+                    }
+                    """,
+                    name=m.identifier.name)
 
         ret += ('args.rval().setObject(*result);\n'
-                'return true;')
-        return CGIndenter(CGGeneric(ret)).define()
+                'return true;\n')
+        return indent(ret)
 
 
 class CGLegacyCallHook(CGAbstractBindingMethod):
     """
     Call hook for our object
     """
     def __init__(self, descriptor):
         self._legacycaller = descriptor.operations["LegacyCaller"]
@@ -6528,46 +6771,49 @@ class CGNewResolveHook(CGAbstractBinding
                 Argument('JS::Handle<jsid>', 'id'), Argument('unsigned', 'flags'),
                 Argument('JS::MutableHandle<JSObject*>', 'objp')]
         # Our "self" is actually the "obj" argument in this case, not the thisval.
         CGAbstractBindingMethod.__init__(
             self, descriptor, NEWRESOLVE_HOOK_NAME,
             args, getThisObj="", callArgs="")
 
     def generate_code(self):
-        return CGIndenter(CGGeneric(
-            "JS::Rooted<JSPropertyDescriptor> desc(cx);\n"
-            "if (!self->DoNewResolve(cx, obj, id, &desc)) {\n"
-            "  return false;\n"
-            "}\n"
-            "if (!desc.object()) {\n"
-            "  return true;\n"
-            "}\n"
-            "// If desc.value() is undefined, then the DoNewResolve call\n"
-            "// has already defined it on the object.  Don't try to also\n"
-            "// define it.\n"
-            "if (!desc.value().isUndefined() &&\n"
-            "    !JS_DefinePropertyById(cx, obj, id, desc.value(),\n"
-            "                           desc.getter(), desc.setter(),\n"
-            "                           desc.attributes())) {\n"
-            "  return false;\n"
-            "}\n"
-            "objp.set(obj);\n"
-            "return true;"))
+        return CGGeneric(indent(dedent("""
+            JS::Rooted<JSPropertyDescriptor> desc(cx);
+            if (!self->DoNewResolve(cx, obj, id, &desc)) {
+              return false;
+            }
+            if (!desc.object()) {
+              return true;
+            }
+            // If desc.value() is undefined, then the DoNewResolve call
+            // has already defined it on the object.  Don't try to also
+            // define it.
+            if (!desc.value().isUndefined() &&
+                !JS_DefinePropertyById(cx, obj, id, desc.value(),
+                                       desc.getter(), desc.setter(),
+                                       desc.attributes())) {
+              return false;
+            }
+            objp.set(obj);
+            return true;
+            """)))
 
     def definition_body(self):
         if self.descriptor.interface.getExtendedAttribute("Global"):
             # Resolve standard classes
-            prefix = CGIndenter(CGGeneric(
-                "if (!ResolveGlobal(cx, obj, id, flags, objp)) {\n"
-                "  return false;\n"
-                "}\n"
-                "if (objp) {\n"
-                "  return true;\n"
-                "}\n\n")).define()
+            prefix = indent(dedent("""
+                if (!ResolveGlobal(cx, obj, id, flags, objp)) {
+                  return false;
+                }
+                if (objp) {
+                  return true;
+                }
+
+                """))
         else:
             prefix = ""
         return prefix + CGAbstractBindingMethod.definition_body(self)
 
 
 class CGEnumerateHook(CGAbstractBindingMethod):
     """
     Enumerate hook for objects with custom hooks.
@@ -6578,39 +6824,42 @@ class CGEnumerateHook(CGAbstractBindingM
         args = [Argument('JSContext*', 'cx'),
                 Argument('JS::Handle<JSObject*>', 'obj')]
         # Our "self" is actually the "obj" argument in this case, not the thisval.
         CGAbstractBindingMethod.__init__(
             self, descriptor, ENUMERATE_HOOK_NAME,
             args, getThisObj="", callArgs="")
 
     def generate_code(self):
-        return CGIndenter(CGGeneric(
-            "nsAutoTArray<nsString, 8> names;\n"
-            "ErrorResult rv;\n"
-            "self->GetOwnPropertyNames(cx, names, rv);\n"
-            "rv.WouldReportJSException();\n"
-            "if (rv.Failed()) {\n"
-            '  return ThrowMethodFailedWithDetails(cx, rv, "%s", "enumerate");\n'
-            "}\n"
-            "JS::Rooted<JS::Value> dummy(cx);\n"
-            "for (uint32_t i = 0; i < names.Length(); ++i) {\n"
-            "  if (!JS_LookupUCProperty(cx, obj, names[i].get(), names[i].Length(), &dummy)) {\n"
-            "    return false;\n"
-            "  }\n"
-            "}\n"
-            "return true;"))
+        return CGGeneric(indent(dedent("""
+            nsAutoTArray<nsString, 8> names;
+            ErrorResult rv;
+            self->GetOwnPropertyNames(cx, names, rv);
+            rv.WouldReportJSException();
+            if (rv.Failed()) {
+              return ThrowMethodFailedWithDetails(cx, rv, "%s", "enumerate");
+            }
+            JS::Rooted<JS::Value> dummy(cx);
+            for (uint32_t i = 0; i < names.Length(); ++i) {
+              if (!JS_LookupUCProperty(cx, obj, names[i].get(), names[i].Length(), &dummy)) {
+                return false;
+              }
+            }
+            return true;
+            """)))
 
     def definition_body(self):
         if self.descriptor.interface.getExtendedAttribute("Global"):
             # Enumerate standard classes
-            prefix = CGIndenter(CGGeneric(
-                "if (!EnumerateGlobal(cx, obj)) {\n"
-                "  return false;\n"
-                "}\n\n")).define()
+            prefix = indent(dedent("""
+                if (!EnumerateGlobal(cx, obj)) {
+                  return false;
+                }
+
+                """))
         else:
             prefix = ""
         return prefix + CGAbstractBindingMethod.definition_body(self)
 
 
 class CppKeywords():
     """
     A class for checking if method names declared in webidl
@@ -6656,41 +6905,43 @@ class CGGenericGetter(CGAbstractBindingM
     """
     A class for generating the C++ code for an IDL attribute getter.
     """
     def __init__(self, descriptor, lenientThis=False, allowCrossOriginThis=False):
         args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
                 Argument('JS::Value*', 'vp')]
         if lenientThis:
             name = "genericLenientGetter"
-            unwrapFailureCode = (
-                "MOZ_ASSERT(!JS_IsExceptionPending(cx));\n"
-                "if (!ReportLenientThisUnwrappingFailure(cx, &args.callee())) {\n"
-                "  return false;\n"
-                "}\n"
-                "args.rval().set(JS::UndefinedValue());\n"
-                "return true;")
+            unwrapFailureCode = dedent("""
+                MOZ_ASSERT(!JS_IsExceptionPending(cx));
+                if (!ReportLenientThisUnwrappingFailure(cx, &args.callee())) {
+                  return false;
+                }
+                args.rval().set(JS::UndefinedValue());
+                return true;
+                """)
         else:
             if allowCrossOriginThis:
                 name = "genericCrossOriginGetter"
             else:
                 name = "genericGetter"
             unwrapFailureCode = (
-                'return ThrowInvalidThis(cx, args, GetInvalidThisErrorForGetter(%%(securityError)s), "%s");' %
+                'return ThrowInvalidThis(cx, args, GetInvalidThisErrorForGetter(%%(securityError)s), "%s");\n' %
                 descriptor.interface.identifier.name)
         CGAbstractBindingMethod.__init__(self, descriptor, name, args,
                                          unwrapFailureCode,
                                          allowCrossOriginThis=allowCrossOriginThis)
 
     def generate_code(self):
-        return CGIndenter(CGGeneric(
-            "const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());\n"
-            "MOZ_ASSERT(info->type() == JSJitInfo::Getter);\n"
-            "JSJitGetterOp getter = info->getter;\n"
-            "return getter(cx, obj, self, JSJitGetterCallArgs(args));"))
+        return CGGeneric(indent(dedent("""
+            const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
+            MOZ_ASSERT(info->type() == JSJitInfo::Getter);
+            JSJitGetterOp getter = info->getter;
+            return getter(cx, obj, self, JSJitGetterCallArgs(args));
+            """)))
 
 
 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):
@@ -6710,40 +6961,44 @@ class CGSpecializedGetter(CGAbstractStat
         if self.attr.slotIndex is not None:
             if (self.descriptor.hasXPConnectImpls and
                 (self.descriptor.interface.identifier.name != 'Window' or
                  self.attr.identifier.name != 'document')):
                 raise TypeError("Interface '%s' has XPConnect impls, so we "
                                 "can't use our slot for property '%s'!" %
                                 (self.descriptor.interface.identifier.name,
                                  self.attr.identifier.name))
-            prefix = (
-                "  // Have to either root across the getter call or reget after.\n"
-                "  JS::Rooted<JSObject*> reflector(cx);\n"
-                "  // Safe to do an unchecked unwrap, since we've gotten this far.\n"
-                "  // Also make sure to unwrap outer windows, since we want the\n"
-                "  // real DOM object.\n"
-                "  reflector = IsDOMObject(obj) ? obj : js::UncheckedUnwrap(obj, /* stopAtOuter = */ false);\n"
-                "  {\n"
-                "    // Scope for cachedVal\n"
-                "    JS::Value cachedVal = js::GetReservedSlot(reflector, %s);\n"
-                "    if (!cachedVal.isUndefined()) {\n"
-                "      args.rval().set(cachedVal);\n"
-                "      // The cached value is in the compartment of reflector,\n"
-                "      // so wrap into the caller compartment as needed.\n"
-                "      return %s(cx, args.rval());\n"
-                "    }\n"
-                "  }\n\n" % (memberReservedSlot(self.attr),
-                             getMaybeWrapValueFuncForType(self.attr.type)))
+            prefix = indent(fill(
+                """
+                // Have to either root across the getter call or reget after.
+                JS::Rooted<JSObject*> reflector(cx);
+                // Safe to do an unchecked unwrap, since we've gotten this far.
+                // Also make sure to unwrap outer windows, since we want the
+                // real DOM object.
+                reflector = IsDOMObject(obj) ? obj : js::UncheckedUnwrap(obj, /* stopAtOuter = */ false);
+                {
+                  // Scope for cachedVal
+                  JS::Value cachedVal = js::GetReservedSlot(reflector, ${slot});
+                  if (!cachedVal.isUndefined()) {
+                    args.rval().set(cachedVal);
+                    // The cached value is in the compartment of reflector,
+                    // so wrap into the caller compartment as needed.
+                    return ${maybeWrap}(cx, args.rval());
+                  }
+                }
+
+                """,
+                slot=memberReservedSlot(self.attr),
+                maybeWrap=getMaybeWrapValueFuncForType(self.attr.type)))
         else:
             prefix = ""
 
         return (prefix +
-                CGIndenter(CGGetterCall(self.attr.type, nativeName,
-                                        self.descriptor, self.attr)).define())
+                indent(CGGetterCall(self.attr.type, nativeName,
+                                    self.descriptor, self.attr).define()))
 
     @staticmethod
     def makeNativeName(descriptor, attr):
         name = attr.identifier.name
         nativeName = MakeNativeName(descriptor.binaryNames.get(name, name))
         # resultOutParam does not depend on whether resultAlreadyAddRefed is set
         (_, resultOutParam, _, _) = getRetvalDeclarationForType(attr.type,
                                                                 descriptor,
@@ -6775,49 +7030,53 @@ class CGGenericSetter(CGAbstractBindingM
     """
     A class for generating the C++ code for an IDL attribute setter.
     """
     def __init__(self, descriptor, lenientThis=False, allowCrossOriginThis=False):
         args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
                 Argument('JS::Value*', 'vp')]
         if lenientThis:
             name = "genericLenientSetter"
-            unwrapFailureCode = (
-                "MOZ_ASSERT(!JS_IsExceptionPending(cx));\n"
-                "if (!ReportLenientThisUnwrappingFailure(cx, &args.callee())) {\n"
-                "  return false;\n"
-                "}\n"
-                "args.rval().set(JS::UndefinedValue());\n"
-                "return true;")
+            unwrapFailureCode = dedent("""
+                MOZ_ASSERT(!JS_IsExceptionPending(cx));
+                if (!ReportLenientThisUnwrappingFailure(cx, &args.callee())) {
+                  return false;
+                }
+                args.rval().set(JS::UndefinedValue());
+                return true;
+                """)
         else:
             if allowCrossOriginThis:
                 name = "genericCrossOriginSetter"
             else:
                 name = "genericSetter"
             unwrapFailureCode = (
-                'return ThrowInvalidThis(cx, args, GetInvalidThisErrorForSetter(%%(securityError)s), "%s");' %
+                'return ThrowInvalidThis(cx, args, GetInvalidThisErrorForSetter(%%(securityError)s), "%s");\n' %
                 descriptor.interface.identifier.name)
 
         CGAbstractBindingMethod.__init__(self, descriptor, name, args,
                                          unwrapFailureCode,
                                          allowCrossOriginThis=allowCrossOriginThis)
 
     def generate_code(self):
-        return CGIndenter(CGGeneric(
-            "if (args.length() == 0) {\n"
-            '  return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "%s attribute setter");\n'
-            "}\n"
-            "const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());\n"
-            "MOZ_ASSERT(info->type() == JSJitInfo::Setter);\n"
-            "JSJitSetterOp setter = info->setter;\n"
-            "if (!setter(cx, obj, self, JSJitSetterCallArgs(args))) {\n"
-            "  return false;\n"
-            "}\n"
-            "args.rval().set(JSVAL_VOID);\n"
-            "return true;" % self.descriptor.interface.identifier.name))
+        return CGGeneric(indent(fill(
+            """
+            if (args.length() == 0) {
+              return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "${name} attribute setter");
+            }
+            const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
+            MOZ_ASSERT(info->type() == JSJitInfo::Setter);
+            JSJitSetterOp setter = info->setter;
+            if (!setter(cx, obj, self, JSJitSetterCallArgs(args))) {
+              return false;
+            }
+            args.rval().set(JSVAL_VOID);
+            return true;
+            """,
+            name=self.descriptor.interface.identifier.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):
@@ -6848,64 +7107,75 @@ class CGStaticSetter(CGAbstractStaticBin
     def __init__(self, descriptor, attr):
         self.attr = attr
         name = 'set_' + attr.identifier.name
         CGAbstractStaticBindingMethod.__init__(self, descriptor, name)
 
     def generate_code(self):
         nativeName = CGSpecializedSetter.makeNativeName(self.descriptor,
                                                         self.attr)
-        checkForArg = CGGeneric("""if (args.length() == 0) {
-  return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "%s setter");
-}""" % self.attr.identifier.name)
+        checkForArg = CGGeneric(fill(
+            """
+            if (args.length() == 0) {
+              return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "${name} setter");
+            }
+            """,
+            name=self.attr.identifier.name))
         call = CGSetterCall(self.attr.type, nativeName, self.descriptor,
                             self.attr)
-        return CGIndenter(CGList([checkForArg, call], "\n"))
+        return CGIndenter(CGList([checkForArg, call]))
 
 
 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)
         assert all(ord(c) < 128 for c in forwardToAttrName)
-        return CGIndenter(CGGeneric("""JS::Rooted<JS::Value> v(cx);
-if (!JS_GetProperty(cx, obj, "%s", &v)) {
-  return false;
-}
-
-if (!v.isObject()) {
-  return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "%s.%s");
-}
-
-JS::Rooted<JSObject*> targetObj(cx, &v.toObject());
-return JS_SetProperty(cx, targetObj, "%s", args[0]);""" % (attrName, self.descriptor.interface.identifier.name, attrName, forwardToAttrName))).define()
+        return indent(fill(
+            """
+            JS::Rooted<JS::Value> v(cx);
+            if (!JS_GetProperty(cx, obj, "${attr}", &v)) {
+              return false;
+            }
+
+            if (!v.isObject()) {
+              return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "${interface}.${attr}");
+            }
+
+            JS::Rooted<JSObject*> targetObj(cx, &v.toObject());
+            return JS_SetProperty(cx, targetObj, "${forwardToAttrName}", args[0]);
+            """,
+            attr=attrName,
+            interface=self.descriptor.interface.identifier.name,
+            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 CGIndenter(CGGeneric("""return JS_DefineProperty(cx, obj, "%s", args[0], JSPROP_ENUMERATE);""" % attrName)).define()
+        return indent('return JS_DefineProperty(cx, obj, "%s", args[0], JSPROP_ENUMERATE);\n' %
+                      attrName)
 
 
 def memberReturnsNewObject(member):
     return member.getExtendedAttribute("NewObject") is not None
 
 
 class CGMemberJITInfo(CGThing):
     """
@@ -6925,55 +7195,67 @@ 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 hasSlot or movable)  # Things with slots had better be movable
-        protoID = "prototypes::id::%s" % self.descriptor.name
-        depth = "PrototypeTraits<%s>::Depth" % protoID
-        failstr = toStringBool(infallible)
-        movablestr = toStringBool(movable)
-        slotStr = toStringBool(hasSlot)
-        returnType = reduce(CGMemberJITInfo.getSingleReturnType, returnTypes,
-                            "")
 
         def jitInfoInitializer(isTypedMethod):
-            typedMethodStr = toStringBool(isTypedMethod)
-            return ("{\n"
-                    " { %s },\n"
-                    "  %s,\n"
-                    "  %s,\n"
-                    "  JSJitInfo::%s,\n"
-                    "  JSJitInfo::%s, /* aliasSet.  Not relevant for setters. */\n"
-                    "  %s,  /* returnType.  Not relevant for setters. */\n"
-                    "  %s,  /* isInfallible. False in setters. */\n"
-                    "  %s,  /* isMovable.  Not relevant for setters. */\n"
-                    "  %s,  /* isInSlot.  Only relevant for getters. */\n"
-                    "  %s,  /* isTypedMethod.  Only relevant for methods. */\n"
-                    "  %s   /* Reserved slot index, if we're stored in a slot, else 0. */\n"
-                    "}" % (opName, protoID, depth, opType, aliasSet,
-                           returnType, failstr, movablestr, slotStr,
-                           typedMethodStr, slotIndex))
+            initializer = fill(
+                """
+                {
+                 { ${opName} },
+                  prototypes::id::${name},
+                  PrototypeTraits<prototypes::id::${name}>::Depth,
+                  JSJitInfo::${opType},
+                  JSJitInfo::${aliasSet}, /* aliasSet.  Not relevant for setters. */
+                  ${returnType},  /* returnType.  Not relevant for setters. */
+                  ${isInfallible},  /* isInfallible. False in setters. */
+                  ${isMovable},  /* isMovable.  Not relevant for setters. */
+                  ${isInSlot},  /* isInSlot.  Only relevant for getters. */
+                  ${isTypedMethod},  /* isTypedMethod.  Only relevant for methods. */
+                  ${slotIndex}   /* Reserved slot index, if we're stored in a slot, else 0. */
+                }
+                """,
+                opName=opName,
+                name=self.descriptor.name,
+                opType=opType,
+                aliasSet=aliasSet,
+                returnType=reduce(CGMemberJITInfo.getSingleReturnType, returnTypes,
+                                  ""),
+                isInfallible=toStringBool(infallible),
+                isMovable=toStringBool(movable),
+                isInSlot=toStringBool(hasSlot),
+                isTypedMethod=toStringBool(isTypedMethod),
+                slotIndex=slotIndex)
+            return initializer.rstrip()
+
         if args is not None:
             argTypes = "%s_argTypes" % infoName
             args = [CGMemberJITInfo.getJSArgType(arg.type) for arg in args]
             args.append("JSJitInfo::ArgTypeListEnd")
             argTypesDecl = (
                 "static const JSJitInfo::ArgType %s[] = { %s };\n" %
                 (argTypes, ", ".join(args)))
-            return ("\n"
-                    "%s"
-                    "static const JSTypedMethodJitInfo %s = {\n"
-                    "  %s,\n"
-                    "  %s\n"
-                    "};\n" % (argTypesDecl, infoName,
-                              jitInfoInitializer(True), argTypes))
+            return fill(
+                """
+
+                $*{argTypesDecl}
+                static const JSTypedMethodJitInfo ${infoName} = {
+                  ${jitInfo},
+                  ${argTypes}
+                };
+                """,
+                argTypesDecl=argTypesDecl,
+                infoName=infoName,
+                jitInfo=jitInfoInitializer(True),
+                argTypes=argTypes)
 
         return ("\n"
                 "static const JSJitInfo %s = %s;\n"
                 % (infoName, jitInfoInitializer(False)))
 
     def define(self):
         if self.member.isAttr():
             getterinfo = ("%s_getterinfo" % self.member.identifier.name)
@@ -7263,41 +7545,47 @@ class CGEnum(CGThing):
 
     def stringsNamespace(self):
         return self.enum.identifier.name + "Values"
 
     def nEnumStrings(self):
         return len(self.enum.values()) + 1
 
     def declare(self):
-        enumName = self.enum.identifier.name
+        decl = fill(  # BOGUS extra newline at top
+            """
+
+            MOZ_BEGIN_ENUM_CLASS(${name}, uint32_t)
+              $*{enums}
+            MOZ_END_ENUM_CLASS(${name})
+            """,
+            name=self.enum.identifier.name,
+            enums=",\n".join(map(getEnumValueName, self.enum.values())) + "\n")
         strings = CGNamespace(self.stringsNamespace(),
                               CGGeneric(declare="extern const EnumEntry %s[%d];\n"
                                         % (ENUM_ENTRY_VARIABLE_NAME, self.nEnumStrings())))
-        pattern = """
-MOZ_BEGIN_ENUM_CLASS(%s, uint32_t)
-  %s
-MOZ_END_ENUM_CLASS(%s)
-
-"""
-        return pattern % (enumName,
-                          ",\n  ".join(map(getEnumValueName, self.enum.values())),
-                          enumName) + strings.declare()
+        return decl + "\n" + strings.declare()
 
     def define(self):
-        pattern = """
-  extern const EnumEntry %s[%d] = {
-    %s,
-    { nullptr, 0 }
-  };
-"""
-        strings = pattern % (ENUM_ENTRY_VARIABLE_NAME, self.nEnumStrings(),
-                             ",\n    ".join('{"' + val + '", ' + str(len(val)) + '}'
-                                            for val in self.enum.values()))
-        return CGNamespace(self.stringsNamespace(), CGGeneric(define=strings)).define()
+        strings = fill(  # BOGUS extra newline at top
+            """
+
+            extern const EnumEntry ${name}[${count}] = {
+              $*{entries}
+              { nullptr, 0 }
+            };
+            """,
+            name=ENUM_ENTRY_VARIABLE_NAME,
+            count=self.nEnumStrings(),
+            entries=''.join('{"%s", %d},\n' % (val, len(val))
+                            for val in self.enum.values()))
+        # BOGUS - CGNamespace automatically indents; the extra indent() below causes
+        # the output to be indented 4 spaces.
+        return CGNamespace(self.stringsNamespace(),
+                           CGGeneric(define=indent(strings))).define()
 
     def deps(self):
         return self.enum.getDeps()
 
 
 def getUnionAccessorSignatureType(type, descriptorProvider):
     """
     Returns the types that are used in the getter and setter signatures for
@@ -7396,17 +7684,17 @@ def getUnionTypeTemplateVars(unionType, 
     name = getUnionMemberName(type)
 
     # By the time tryNextCode is invoked, we're guaranteed the union has been
     # constructed as some type, since we've been trying to convert into the
     # corresponding member.
     prefix = "" if ownsMembers else "mUnion."
     tryNextCode = ("%sDestroy%s();\n"
                    "tryNext = true;\n"
-                   "return true;" % (prefix, name))
+                   "return true;\n" % (prefix, name))
     conversionInfo = getJSToNativeConversionInfo(
         type, descriptorProvider, failureCode=tryNextCode,
         isDefinitelyObject=not type.isDictionary(),
         isMember=("OwningUnion" if ownsMembers else None),
         sourceDescription="member of %s" % unionType)
 
     ctorNeedsCx = conversionInfo.declArgs == "cx"
     ctorArgs = "cx" if ctorNeedsCx else ""
@@ -7415,54 +7703,64 @@ def getUnionTypeTemplateVars(unionType, 
     # arguments so the type can't be const.
     structType = conversionInfo.declType.define()
     if structType.startswith("const "):
         structType = structType[6:]
     externalType = getUnionAccessorSignatureType(type, descriptorProvider).define()
 
     if type.isObject():
         if ownsMembers:
-            body = ("MOZ_ASSERT(mType == eUninitialized);\n"
-                    "mValue.mObject.SetValue(obj);\n"
-                    "mType = eObject;")
-        else:
-            body = ("MOZ_ASSERT(mUnion.mType == mUnion.eUninitialized);\n"
-                    "mUnion.mValue.mObject.SetValue(cx, obj);\n"
-                    "mUnion.mType = mUnion.eObject;")
+            body = dedent("""
+                MOZ_ASSERT(mType == eUninitialized);
+                mValue.mObject.SetValue(obj);
+                mType = eObject;
+                """)
+        else:
+            body = dedent("""
+                MOZ_ASSERT(mUnion.mType == mUnion.eUninitialized);
+                mUnion.mValue.mObject.SetValue(cx, obj);
+                mUnion.mType = mUnion.eObject;
+                """)
         setter = ClassMethod("SetToObject", "void",
                              [Argument("JSContext*", "cx"),
                               Argument("JSObject*", "obj")],
                              inline=True, bodyInHeader=True,
                              body=body)
 
     else:
         # Important: we need to not have our declName involve
         # maybe-GCing operations.
         jsConversion = string.Template(conversionInfo.template).substitute({
             "val": "value",
             "mutableVal": "pvalue",
             "declName": "memberSlot",
             "holderName": "m" + name + "Holder",
         })
-        jsConversion = CGWrapper(CGIndenter(CGGeneric(jsConversion)),
-                                 pre=("tryNext = false;\n"
-                                      "{ // scope for memberSlot\n"
-                                      "  %s& memberSlot = RawSetAs%s(%s);\n"
-                                      % (structType, name, ctorArgs)),
-                                 post=("\n"
-                                       "}\n"
-                                       "return true;"))
+        jsConversion = fill(
+            """
+            tryNext = false;
+            { // scope for memberSlot
+              ${structType}& memberSlot = RawSetAs${name}(${ctorArgs});
+              $*{jsConversion}
+            }
+            return true;
+            """,
+            structType=structType,
+            name=name,
+            ctorArgs=ctorArgs,
+            jsConversion=jsConversion)
+
         setter = ClassMethod("TrySetTo" + name, "bool",
                              [Argument("JSContext*", "cx"),
                               Argument("JS::Handle<JS::Value>", "value"),
                               Argument("JS::MutableHandle<JS::Value>", "pvalue"),
                               Argument("bool&", "tryNext")],
                              inline=not ownsMembers,
                              bodyInHeader=not ownsMembers,
-                             body=jsConversion.define())
+                             body=jsConversion)
 
     return {
         "name": name,
         "structType": structType,
         "externalType": externalType,
         "setter": setter,
         "holderType": conversionInfo.holderType.define() if conversionInfo.holderType else None,
         "ctorArgs": ctorArgs,
@@ -7488,54 +7786,57 @@ class CGUnionStruct(CGThing):
 
         members = [ClassMember("mType", "Type", body="eUninitialized"),
                    ClassMember("mValue", "Value")]
         ctor = ClassConstructor([], bodyInHeader=True, visibility="public",
                                 explicit=True)
 
         methods = []
         enumValues = ["eUninitialized"]
-        toJSValCases = [CGCase("eUninitialized", CGGeneric("return false;"))]
+        toJSValCases = [CGCase("eUninitialized", CGGeneric("return false;\n"))]
         destructorCases = [CGCase("eUninitialized", None)]
         assignmentCases = [
             CGCase("eUninitialized",
                    CGGeneric('MOZ_ASSERT(mType == eUninitialized,\n'
-                             '           "We need to destroy ourselves?");'))]
+                             '           "We need to destroy ourselves?");\n'))]
         traceCases = []
         unionValues = []
         if self.type.hasNullableType:
             enumValues.append("eNull")
             methods.append(ClassMethod("IsNull", "bool", [], const=True, inline=True,
-                                       body="return mType == eNull;",
+                                       body="return mType == eNull;\n",
                                        bodyInHeader=True))
             methods.append(ClassMethod("SetNull", "void", [], inline=True,
                                        body=("Uninit();\n"
-                                             "mType = eNull;"),
+                                             "mType = eNull;\n"),
                                        bodyInHeader=True))
             destructorCases.append(CGCase("eNull", None))
             assignmentCases.append(CGCase("eNull",
                                           CGGeneric("MOZ_ASSERT(mType == eUninitialized);\n"
-                                                    "mType = eNull;")))
+                                                    "mType = eNull;\n")))
             toJSValCases.append(CGCase("eNull", CGGeneric("rval.setNull();\n"
-                                                          "return true;")))
+                                                          "return true;\n")))
 
         hasObjectType = any(t.isObject() for t in self.type.flatMemberTypes)
         for t in self.type.flatMemberTypes:
             vars = getUnionTypeTemplateVars(self.type,
                                             t, self.descriptorProvider,
                                             ownsMembers=self.ownsMembers)
             if vars["name"] != "Object" or self.ownsMembers:
-                body = string.Template(
-                    "if (mType == e${name}) {\n"
-                    "  return mValue.m${name}.Value();\n"
-                    "}\n"
-                    "%s\n"
-                    "mType = e${name};\n"
-                    "return mValue.m${name}.SetValue(${ctorArgs});"
-                ).substitute(vars)
+                body = fill(
+                    """
+                    if (mType == e${name}) {
+                      return mValue.m${name}.Value();
+                    }
+                    %s
+                    mType = e${name};
+                    return mValue.m${name}.SetValue(${ctorArgs});
+                    """,
+                    **vars)
+
                 # bodyInHeader must be false for return values because they own
                 # their union members and we don't want include headers in
                 # UnionTypes.h just to call Addref/Release
                 methods.append(ClassMethod(
                     "RawSetAs" + vars["name"],
                     vars["structType"] + "&",
                     vars["ctorArgList"],
                     bodyInHeader=not self.ownsMembers,
@@ -7552,83 +7853,88 @@ class CGUnionStruct(CGThing):
                 if self.ownsMembers:
                     methods.append(vars["setter"])
                     if t.isString():
                         methods.append(
                             ClassMethod("SetStringData", "void",
                                         [Argument("const nsString::char_type*", "aData"),
                                          Argument("nsString::size_type", "aLength")],
                                         inline=True, bodyInHeader=True,
-                                        body="RawSetAsString().Assign(aData, aLength);"))
-
-            body = string.Template(
-                'MOZ_ASSERT(Is${name}(), "Wrong type!");\n'
-                'mValue.m${name}.Destroy();\n'
-                'mType = eUninitialized;'
-            ).substitute(vars)
+                                        body="RawSetAsString().Assign(aData, aLength);\n"))
+
+            body = fill(
+                """
+                MOZ_ASSERT(Is${name}(), "Wrong type!");
+                mValue.m${name}.Destroy();
+                mType = eUninitialized;
+                """,
+                **vars)
             methods.append(ClassMethod("Destroy" + vars["name"],
                                        "void",
                                        [],
                                        visibility="private",
                                        bodyInHeader=not self.ownsMembers,
                                        body=body))
 
-            body = string.Template(
-                "return mType == e${name};").substitute(vars)
+            body = fill("return mType == e${name};\n", **vars)
             methods.append(ClassMethod("Is" + vars["name"],
                                        "bool",
                                        [],
                                        const=True,
                                        bodyInHeader=True,
                                        body=body))
 
-            body = string.Template('MOZ_ASSERT(Is${name}(), "Wrong type!");\n'
-                                   'return const_cast<${structType}&>(mValue.m${name}.Value());').substitute(vars)
+            body = fill(
+                """
+                MOZ_ASSERT(Is${name}(), "Wrong type!");
+                return const_cast<${structType}&>(mValue.m${name}.Value());
+                """,
+                **vars)
             if self.ownsMembers:
                 getterReturnType = "%s&" % vars["structType"]
             else:
                 getterReturnType = vars["externalType"]
             methods.append(ClassMethod("GetAs" + vars["name"],
                                        getterReturnType,
                                        [],
                                        const=True,
                                        bodyInHeader=True,
                                        body=body))
 
             unionValues.append(
-                string.Template("UnionMember<${structType} > m${name}").substitute(vars))
+                fill("UnionMember<${structType} > m${name}", **vars))
             enumValues.append("e" + vars["name"])
 
             toJSValCases.append(
                 CGCase("e" + vars["name"],
                        self.getConversionToJS(vars, t)))
             destructorCases.append(
                 CGCase("e" + vars["name"],
-                       CGGeneric("Destroy%s();" % vars["name"])))
+                       CGGeneric("Destroy%s();\n" % vars["name"])))
             assignmentCases.append(
                 CGCase("e" + vars["name"],
-                       CGGeneric("SetAs%s() = aOther.GetAs%s();" %
+                       CGGeneric("SetAs%s() = aOther.GetAs%s();\n" %
                                  (vars["name"], vars["name"]))))
             if self.ownsMembers and typeNeedsRooting(t):
                 if t.isObject():
                     traceCases.append(
                         CGCase("e" + vars["name"],
-                               CGGeneric('JS_CallObjectTracer(trc, %s, "%s");' %
+                               CGGeneric('JS_CallObjectTracer(trc, %s, "%s");\n' %
                                          ("&mValue.m" + vars["name"] + ".Value()",
                                           "mValue.m" + vars["name"]))))
                 elif t.isDictionary():
                     traceCases.append(
                         CGCase("e" + vars["name"],
-                               CGGeneric("mValue.m%s.Value().TraceDictionary(trc);" %
+                               CGGeneric("mValue.m%s.Value().TraceDictionary(trc);\n" %
                                          vars["name"])))
                 else:
                     assert t.isSpiderMonkeyInterface()
                     traceCases.append(
                         CGCase("e" + vars["name"],
-                               CGGeneric("mValue.m%s.Value().TraceSelf(trc);" %
+                               CGGeneric("mValue.m%s.Value().TraceSelf(trc);\n" %
                                          vars["name"])))
 
         dtor = CGSwitch("mType", destructorCases).define()
 
         methods.append(ClassMethod("Uninit", "void", [],
                                    visibility="private", body=dtor,
                                    bodyInHeader=not self.ownsMembers,
                                    inline=not self.ownsMembers))
@@ -7638,27 +7944,29 @@ class CGUnionStruct(CGThing):
                 "ToJSVal",
                 "bool",
                 [
                     Argument("JSContext*", "cx"),
                     Argument("JS::Handle<JSObject*>", "scopeObj"),
                     Argument("JS::MutableHandle<JS::Value>", "rval")
                 ],
                 body=CGSwitch("mType", toJSValCases,
-                              default=CGGeneric("return false;")).define(),
+                              default=CGGeneric("return false;\n")).define(),
                 const=True))
 
         constructors = [ctor]
         selfName = CGUnionStruct.unionTypeName(self.type, self.ownsMembers)
         if self.ownsMembers:
-            if len(traceCases):
+            if traceCases:
+                # BOGUS blank line in default case
                 traceBody = CGSwitch("mType", traceCases,
-                                     default=CGGeneric("")).define()
-            else:
-                traceBody = ""
+                                     default=CGGeneric("\n")).define()
+            else:
+                # BOGUS blank line in method
+                traceBody = "\n"
             methods.append(ClassMethod("TraceUnion", "void",
                                        [Argument("JSTracer*", "trc")],
                                        body=traceBody))
             if CGUnionStruct.isUnionCopyConstructible(self.type):
                 constructors.append(
                     ClassConstructor([Argument("const %s&" % selfName,
                                                "aOther")],
                                      bodyInHeader=True,
@@ -7748,42 +8056,44 @@ class CGUnionConversionStruct(CGThing):
                                 visibility="public",
                                 explicit=True)
         methods = []
 
         if self.type.hasNullableType:
             methods.append(ClassMethod("SetNull", "bool", [],
                                        body=("MOZ_ASSERT(mUnion.mType == mUnion.eUninitialized);\n"
                                              "mUnion.mType = mUnion.eNull;\n"
-                                             "return true;"),
+                                             "return true;\n"),
                                        inline=True, bodyInHeader=True))
 
         for t in self.type.flatMemberTypes:
             vars = getUnionTypeTemplateVars(self.type,
                                             t, self.descriptorProvider)
             methods.append(vars["setter"])
             if vars["name"] != "Object":
-                body = string.Template(
-                    "MOZ_ASSERT(mUnion.mType == mUnion.eUninitialized);\n"
-                    "mUnion.mType = mUnion.e${name};\n"
-                    "return mUnion.mValue.m${name}.SetValue(${ctorArgs});"
-                ).substitute(vars)
+                body = fill(
+                    """
+                    MOZ_ASSERT(mUnion.mType == mUnion.eUninitialized);
+                    mUnion.mType = mUnion.e${name};
+                    return mUnion.mValue.m${name}.SetValue(${ctorArgs});
+                    """,
+                    **vars)
                 methods.append(ClassMethod("RawSetAs" + vars["name"],
                                            vars["structType"] + "&",
                                            vars["ctorArgList"],
                                            bodyInHeader=True,
                                            body=body,
                                            visibility="private"))
                 if t.isString():
                     methods.append(
                         ClassMethod("SetStringData", "void",
                                     [Argument("const nsDependentString::char_type*", "aData"),
                                      Argument("nsDependentString::size_type", "aLength")],
                                     inline=True, bodyInHeader=True,
-                                    body="RawSetAsString().SetData(aData, aLength);"))
+                                    body="RawSetAsString().SetData(aData, aLength);\n"))
 
             if vars["holderType"] is not None:
                 members.append(ClassMember("m%sHolder" % vars["name"],
                                            vars["holderType"]))
 
         return CGClass(structName + "Argument",
                        members=members,
                        constructors=[ctor],
@@ -7861,35 +8171,35 @@ class ClassMethod(ClassItem):
         assert self.body is not None
         return self.body
 
     def declare(self, cgClass):
         templateClause = ('template <%s>\n' % ', '.join(self.templateArgs)
                           if self.bodyInHeader and self.templateArgs else '')
         args = ', '.join([a.declare() for a in self.args])
         if self.bodyInHeader:
-            body = CGIndenter(CGGeneric(self.getBody())).define()
-            body = '\n{\n' + body + '\n}'
-        else:
-            body = ';'
-
-        return string.Template(
-            "${templateClause}${decorators}${returnType}%s"
-            "${name}(${args})${const}${override}${body}%s" %
-            (self.breakAfterReturnDecl, self.breakAfterSelf)
-        ).substitute({
-            'templateClause': templateClause,
-            'decorators': self.getDecorators(True),
-            'returnType': self.returnType,
-            'name': self.name,
-            'const': ' const' if self.const else '',
-            'override': ' MOZ_OVERRIDE' if self.override else '',
-            'args': args,
-            'body': body
-        })
+            body = indent(self.getBody())
+            body = '\n{\n' + body + '}\n'
+        else:
+            body = ';\n'
+
+        return fill(
+            "${templateClause}${decorators}${returnType}${breakAfterReturnDecl}"
+            "${name}(${args})${const}${override}${body}"
+            "${breakAfterSelf}",
+            templateClause=templateClause,
+            decorators=self.getDecorators(True),
+            returnType=self.returnType,
+            breakAfterReturnDecl=self.breakAfterReturnDecl,
+            name=self.name,
+            args=args,
+            const=' const' if self.const else '',
+            override=' MOZ_OVERRIDE' if self.override else '',
+            body=body,
+            breakAfterSelf=self.breakAfterSelf)
 
     def define(self, cgClass):
         if self.bodyInHeader:
             return ''
 
         templateArgs = cgClass.templateArgs
         if templateArgs:
             if cgClass.templateSpecialization:
@@ -7897,35 +8207,32 @@ class ClassMethod(ClassItem):
                     templateArgs[len(cgClass.templateSpecialization):]
 
         if templateArgs:
             templateClause = \
                 'template <%s>\n' % ', '.join([str(a) for a in templateArgs])
         else:
             templateClause = ''
 
-        args = ', '.join([a.define() for a in self.args])
-
-        body = CGIndenter(CGGeneric(self.getBody())).define()
-
-        return string.Template("""${templateClause}${decorators}${returnType}
-${className}::${name}(${args})${const}
-{
-${body}
-}
-""").substitute({
-            'templateClause': templateClause,
-            'decorators': self.getDecorators(False),
-            'returnType': self.returnType,
-            'className': cgClass.getNameString(),
-            'name': self.name,
-            'args': args,
-            'const': ' const' if self.const else '',
-            'body': body
-        })
+        return fill(
+            """
+            ${templateClause}${decorators}${returnType}
+            ${className}::${name}(${args})${const}
+            {
+              $*{body}
+            }
+            """,
+            templateClause=templateClause,
+            decorators=self.getDecorators(False),
+            returnType=self.returnType,
+            className=cgClass.getNameString(),
+            name=self.name,
+            args=', '.join([a.define() for a in self.args]),
+            const=' const' if self.const else '',
+            body=self.getBody())
 
 
 class ClassUsingDeclaration(ClassItem):
     """"
     Used for importing a name from a base class into a CGClass
 
     baseClass is the name of the base class to import the name from
 
@@ -7935,17 +8242,17 @@ class ClassUsingDeclaration(ClassItem):
     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 string.Template(
-            "using ${baseClass}::${name};\n"
+            "using ${baseClass}::${name};\n\n"
         ).substitute({
             'baseClass': self.baseClass,
             'name': self.name
         })
 
     def define(self, cgClass):
         return ''
 
@@ -8006,54 +8313,44 @@ class ClassConstructor(ClassItem):
         return ''
 
     def getBody(self):
         return self.body
 
     def declare(self, cgClass):
         args = ', '.join([a.declare() for a in self.args])
         if self.bodyInHeader:
-            body = '  ' + self.getBody()
-            body = stripTrailingWhitespace(body.replace('\n', '\n  '))
-            if len(body) > 0:
-                body += '\n'
-            body = self.getInitializationList(cgClass) + '\n{\n' + body + '}'
-        else:
-            body = ';'
-
-        return string.Template(
-            "${decorators}${className}(${args})${body}\n"
-        ).substitute({
-            'decorators': self.getDecorators(True),
-            'className': cgClass.getNameString(),
-            'args': args,
-            'body': body
-        })
+            body = self.getInitializationList(cgClass) + '\n{\n' + indent(self.getBody()) + '}\n'
+        else:
+            body = ';\n'
+
+        return fill(
+            "${decorators}${className}(${args})${body}\n",
+            decorators=self.getDecorators(True),
+            className=cgClass.getNameString(),
+            args=args,
+            body=body)
 
     def define(self, cgClass):
         if self.bodyInHeader:
             return ''
 
-        args = ', '.join([a.define() for a in self.args])
-
-        body = '  ' + self.getBody()
-        body = '\n' + stripTrailingWhitespace(body.replace('\n', '\n  '))
-        if len(body) > 0:
-            body += '\n'
-
-        return string.Template("""${decorators}
-${className}::${className}(${args})${initializationList}
-{${body}}
-""").substitute({
-            'decorators': self.getDecorators(False),
-            'className': cgClass.getNameString(),
-            'args': args,
-            'initializationList': self.getInitializationList(cgClass),
-            'body': body
-        })
+        return fill(
+            """
+            ${decorators}
+            ${className}::${className}(${args})${initializationList}
+            {
+              $*{body}
+            }
+            """,
+            decorators=self.getDecorators(False),
+            className=cgClass.getNameString(),
+            args=', '.join([a.define() for a in self.args]),
+            initializationList=self.getInitializationList(cgClass),
+            body=self.getBody())
 
 
 class ClassDestructor(ClassItem):
     """
     Used for adding a destructor to a CGClass.
 
     inline should be True if the destructor should be marked inline.
 
@@ -8085,49 +8382,40 @@ class ClassDestructor(ClassItem):
             return ' '.join(decorators) + ' '
         return ''
 
     def getBody(self):
         return self.body
 
     def declare(self, cgClass):
         if self.bodyInHeader:
-            body = '  ' + self.getBody()
-            body = stripTrailingWhitespace(body.replace('\n', '\n  '))
-            if len(body) > 0:
-                body += '\n'
-            body = '\n{\n' + body + '}'
-        else:
-            body = ';'
-
-        return string.Template(
-            "${decorators}~${className}()${body}\n"
-        ).substitute({
-            'decorators': self.getDecorators(True),
-            'className': cgClass.getNameString(),
-            'body': body
-        })
+            body = '\n{\n' + indent(self.getBody()) + '}\n'
+        else:
+            body = ';\n'
+
+        return fill(
+            "${decorators}~${className}()${body}\n",
+            decorators=self.getDecorators(True),
+            className=cgClass.getNameString(),
+            body=body)
 
     def define(self, cgClass):
         if self.bodyInHeader:
             return ''
-
-        body = '  ' + self.getBody()
-        body = '\n' + stripTrailingWhitespace(body.replace('\n', '\n  '))
-        if len(body) > 0:
-            body += '\n'
-
-        return string.Template("""${decorators}
-${className}::~${className}()
-{${body}}
-""").substitute({
-            'decorators': self.getDecorators(False),
-            'className': cgClass.getNameString(),
-            'body': body
-        })
+        return fill(
+            """
+            ${decorators}
+            ${className}::~${className}()
+            {
+              $*{body}
+            }
+            """,
+            decorators=self.getDecorators(False),
+            className=cgClass.getNameString(),
+            body=self.getBody() or "\n")  # BOGUS extra blank line if empty
 
 
 class ClassMember(ClassItem):
     def __init__(self, name, type, visibility="private", static=False,
                  body=None):
         self.type = type
         self.static = static
         self.body = body
@@ -8171,30 +8459,30 @@ class ClassEnum(ClassItem):
         entries = []
         for i in range(0, len(self.entries)):
             if not self.values or i >= len(self.values):
                 entry = '%s' % self.entries[i]
             else:
                 entry = '%s = %s' % (self.entries[i], self.values[i])
             entries.append(entry)
         name = '' if not self.name else ' ' + self.name
-        return 'enum%s\n{\n  %s\n};\n' % (name, ',\n  '.join(entries))
+        return 'enum%s\n{\n%s\n};\n' % (name, indent(',\n'.join(entries)))
 
     def define(self, cgClass):
         # Only goes in the header
         return ''
 
 
 class ClassUnion(ClassItem):
     def __init__(self, name, entries, visibility="public"):
-        self.entries = [entry + ";" for entry in entries]
+        self.entries = [entry + ";\n" for entry in entries]
         ClassItem.__init__(self, name, visibility)
 
     def declare(self, cgClass):
-        return 'union %s\n{\n  %s\n};\n' % (self.name, '\n  '.join(self.entries))
+        return "union %s\n{\n%s\n};\n" % (self.name, indent(''.join(self.entries)))
 
     def define(self, cgClass):
         # Only goes in the header
         return ''
 
 
 class CGClass(CGThing):
     def __init__(self, name, bases=[], members=[], constructors=[],
@@ -8234,51 +8522,48 @@ class CGClass(CGThing):
                                              for a in self.templateSpecialization])
         return className
 
     def declare(self):
         result = ''
         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 += ('template <%s>\n' %
+                       ','.join([str(a) for a in templateArgs]))
 
         type = 'struct' if self.isStruct else 'class'
 
         if self.templateSpecialization:
             specialization = \
                 '<%s>' % ', '.join([str(a) for a in self.templateSpecialization])
         else:
             specialization = ''
 
-        myself = '%s%s %s%s' % (self.indent, type, self.name, specialization)
+        myself = '%s %s%s' % (type, self.name, specialization)
         if self.decorators != '':
             myself += " " + self.decorators
         result += myself
 
         if self.bases:
             inherit = ' : '
             result += inherit
             # Grab our first base
             baseItems = [CGGeneric(b.declare(self)) for b in self.bases]
             bases = baseItems[:1]
             # Indent the rest
-            bases.extend(CGIndenter(b, len(myself) + len(inherit)) for
-                         b in baseItems[1:])
+            bases.extend(CGIndenter(b, len(myself) + len(inherit))
+                         for b in baseItems[1:])
             result += ",\n".join(b.define() for b in bases)
 
-        result = result + '\n%s{\n' % self.indent
-
-        result += CGIndenter(CGGeneric(self.extradeclarations),
-                             len(self.indent)).define()
-
-        def declareMembers(cgClass, memberList, defaultVisibility, itemCount,
-                           separator=''):
+        result += '\n{\n'
+
+        result += self.extradeclarations
+
+        def declareMembers(cgClass, memberList, defaultVisibility):
             members = {'private': [], 'protected': [], 'public': []}
 
             for member in memberList:
                 members[member.visibility].append(member)
 
             if defaultVisibility == 'public':
                 order = ['public', 'protected', 'private']
             else:
@@ -8286,61 +8571,53 @@ class CGClass(CGThing):
 
             result = ''
 
             lastVisibility = defaultVisibility
             for visibility in order:
                 list = members[visibility]
                 if list:
                     if visibility != lastVisibility:
-                        if itemCount:
-                            result = result + '\n'
-                        result = result + visibility + ':\n'
-                        itemCount = 0
+                        result += visibility + ':\n'
                     for member in list:
-                        if itemCount != 0:
-                            result = result + separator
-                        declaration = member.declare(cgClass)
-                        declaration = CGIndenter(CGGeneric(declaration)).define()
-                        result = result + declaration
-                        itemCount = itemCount + 1
+                        result += indent(member.declare(cgClass))
                     lastVisibility = visibility
-            return (result, lastVisibility, itemCount)
+            return (result, lastVisibility)
 
         if self.disallowCopyConstruction:
             class DisallowedCopyConstructor(object):
                 def __init__(self):
                     self.visibility = "private"
 
                 def declare(self, cgClass):
                     name = cgClass.getNameString()
                     return ("%s(const %s&) MOZ_DELETE;\n"
                             "void operator=(const %s) MOZ_DELETE;\n" % (name, name, name))
 
             disallowedCopyConstructors = [DisallowedCopyConstructor()]
         else:
             disallowedCopyConstructors = []
 
-        order = [(self.enums, ''), (self.unions, ''),
-                 (self.typedefs, ''), (self.members, ''),
-                 (self.constructors + disallowedCopyConstructors, '\n'),
-                 (self.destructors, '\n'), (self.methods, '\n')]
+        order = [self.enums, self.unions,
+                 self.typedefs, self.members,
+                 self.constructors + disallowedCopyConstructors,
+                 self.destructors, self.methods]
 
         lastVisibility = self.defaultVisibility
-        itemCount = 0
-        for (memberList, separator) in order:
-            (memberString, lastVisibility, itemCount) = \
-                declareMembers(self, memberList, lastVisibility, itemCount,
-                               separator)
-            if self.indent:
-                memberString = CGIndenter(CGGeneric(memberString),
-                                          len(self.indent)).define()
-            result = result + memberString
-
-        result = result + self.indent + '};\n'
+        pieces = []
+        for memberList in order:
+            (code, lastVisibility) = declareMembers(self, memberList, lastVisibility)
+
+            if code:
+                code = code.rstrip() + "\n"  # remove extra blank lines at the end
+                pieces.append(code)
+
+        result += '\n'.join(pieces)
+        result += '};\n'
+        result = indent(result, len(self.indent))
         return result
 
     def define(self):
         def defineMembers(cgClass, memberList, itemCount, separator=''):
             result = ''
             for member in memberList:
                 if itemCount != 0:
                     result = result + separator
@@ -8371,17 +8648,18 @@ class CGResolveOwnProperty(CGAbstractSta
                 Argument('JS::Handle<jsid>', 'id'),
                 Argument('JS::MutableHandle<JSPropertyDescriptor>', 'desc'),
                 Argument('unsigned', 'flags'),
                 ]
         CGAbstractStaticMethod.__init__(self, descriptor, "ResolveOwnProperty",
                                         "bool", args)
 
     def definition_body(self):
-        return "  return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc, flags);\n"
+        # BOGUS extra blank line at end of function
+        return "  return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc, flags);\n\n"
 
 
 class CGResolveOwnPropertyViaNewresolve(CGAbstractBindingMethod):
     """
     An implementation of Xray ResolveOwnProperty stuff for things that have a
     newresolve hook.
     """
     def __init__(self, descriptor):
@@ -8393,54 +8671,56 @@ class CGResolveOwnPropertyViaNewresolve(
                 Argument('unsigned', 'flags'),
                 ]
         CGAbstractBindingMethod.__init__(self, descriptor,
                                          "ResolveOwnPropertyViaNewresolve",
                                          args, getThisObj="",
                                          callArgs="")
 
     def generate_code(self):
-        return CGIndenter(CGGeneric(
-            "{\n"
-            "  // Since we're dealing with an Xray, do the resolve on the\n"
-            "  // underlying object first.  That gives it a chance to\n"
-            "  // define properties on the actual object as needed, and\n"
-            "  // then use the fact that it created the objects as a flag\n"
-            "  // o avoid re-resolving the properties if someone deletes\n"
-            "  // them.\n"
-            "  JSAutoCompartment ac(cx, obj);\n"
-            "  JS::Rooted<JSPropertyDescriptor> objDesc(cx);\n"
-            "  if (!self->DoNewResolve(cx, obj, id, &objDesc)) {\n"
-            "    return false;\n"
-            "  }\n"
-            "  // If desc.value() is undefined, then the DoNewResolve call\n"
-            "  // has already defined the property on the object.  Don't\n"
-            "  // try to also define it.\n"
-            "  if (objDesc.object() &&\n"
-            "      !objDesc.value().isUndefined() &&\n"
-            "      !JS_DefinePropertyById(cx, obj, id, objDesc.value(),\n"
-            "                             objDesc.getter(), objDesc.setter(),\n"
-            "                             objDesc.attributes())) {\n"
-            "    return false;\n"
-            "  }\n"
-            "}\n"
-            "return self->DoNewResolve(cx, wrapper, id, desc);"))
+        return CGGeneric(indent(dedent("""
+            {
+              // Since we're dealing with an Xray, do the resolve on the
+              // underlying object first.  That gives it a chance to
+              // define properties on the actual object as needed, and
+              // then use the fact that it created the objects as a flag
+              // o avoid re-resolving the properties if someone deletes
+              // them.
+              JSAutoCompartment ac(cx, obj);
+              JS::Rooted<JSPropertyDescriptor> objDesc(cx);
+              if (!self->DoNewResolve(cx, obj, id, &objDesc)) {
+                return false;
+              }
+              // If desc.value() is undefined, then the DoNewResolve call
+              // has already defined the property on the object.  Don't
+              // try to also define it.
+              if (objDesc.object() &&
+                  !objDesc.value().isUndefined() &&
+                  !JS_DefinePropertyById(cx, obj, id, objDesc.value(),
+                                         objDesc.getter(), objDesc.setter(),
+                                         objDesc.attributes())) {
+                return false;
+              }
+            }
+            return self->DoNewResolve(cx, wrapper, id, desc);
+            """)))
 
 
 class CGEnumerateOwnProperties(CGAbstractStaticMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'),
                 Argument('JS::Handle<JSObject*>', 'wrapper'),
                 Argument('JS::Handle<JSObject*>', 'obj'),
                 Argument('JS::AutoIdVector&', 'props')]
         CGAbstractStaticMethod.__init__(self, descriptor,
                                         "EnumerateOwnProperties", "bool", args)
 
     def definition_body(self):
-        return "  return js::GetProxyHandler(obj)->getOwnPropertyNames(cx, wrapper, props);\n"
+        # BOGUS extra newline
+        return "  return js::GetProxyHandler(obj)->getOwnPropertyNames(cx, wrapper, props);\n\n"
 
 
 class CGEnumerateOwnPropertiesViaGetOwnPropertyNames(CGAbstractBindingMethod):
     """
     An implementation of Xray EnumerateOwnProperties stuff for things
     that have a newresolve hook.
     """
     def __init__(self, descriptor):
@@ -8449,27 +8729,28 @@ class CGEnumerateOwnPropertiesViaGetOwnP
                 Argument('JS::Handle<JSObject*>', 'obj'),
                 Argument('JS::AutoIdVector&', 'props')]
         CGAbstractBindingMethod.__init__(self, descriptor,
                                          "EnumerateOwnPropertiesViaGetOwnPropertyNames",
                                          args, getThisObj="",
                                          callArgs="")
 
     def generate_code(self):
-        return CGIndenter(CGGeneric(
-            "nsAutoTArray<nsString, 8> names;\n"
-            "ErrorResult rv;\n"
-            "self->GetOwnPropertyNames(cx, names, rv);\n"
-            "rv.WouldReportJSException();\n"
-            "if (rv.Failed()) {\n"
-            '  return ThrowMethodFailedWithDetails(cx, rv, "%s", "enumerate");\n'
-            "}\n"
-            '// OK to pass null as "proxy" because it\'s ignored if\n'
-            "// shadowPrototypeProperties is true\n"
-            "return AppendNamedPropertyIds(cx, JS::NullPtr(), names, true, props);"))
+        return CGIndenter(CGGeneric(dedent("""
+            nsAutoTArray<nsString, 8> names;
+            ErrorResult rv;
+            self->GetOwnPropertyNames(cx, names, rv);
+            rv.WouldReportJSException();
+            if (rv.Failed()) {
+              return ThrowMethodFailedWithDetails(cx, rv, "%s", "enumerate");
+            }
+            // OK to pass null as "proxy" because it's ignored if
+            // shadowPrototypeProperties is true
+            return AppendNamedPropertyIds(cx, JS::NullPtr(), names, true, props);
+            """)))
 
 
 class CGPrototypeTraitsClass(CGClass):
     def __init__(self, descriptor, indent=''):
         templateArgs = [Argument('prototypes::ID', 'PrototypeID')]
         templateSpecialization = ['prototypes::id::' + descriptor.name]
         enums = [ClassEnum('', ['Depth'],
                            [descriptor.interface.inheritanceDepth()])]
@@ -8536,17 +8817,17 @@ class CGProxySpecialOperation(CGPerSigna
                 "declName": argument.identifier.name,
                 "holderName": argument.identifier.name + "_holder",
                 "val": "desc.value()",
                 "mutableVal": "desc.value()",
                 "obj": "obj"
             }
             self.cgRoot.prepend(instantiateJSToNativeConversion(info, templateValues))
         elif operation.isGetter() or operation.isDeleter():
-            self.cgRoot.prepend(CGGeneric("bool found;"))
+            self.cgRoot.prepend(CGGeneric("bool found;\n"))
 
     def getArguments(self):
         args = [(a, a.identifier.name) for a in self.arguments]
         if self.idlNode.isGetter() or self.idlNode.isDeleter():
             args.append((FakeArgument(BuiltinTypes[IDLBuiltinType.Types.boolean],
                                       self.idlNode),
                          "found"))
         return args
@@ -8554,17 +8835,17 @@ class CGProxySpecialOperation(CGPerSigna
     def wrap_return_value(self):
         if not self.idlNode.isGetter() or self.templateValues is None:
             return ""
 
         wrap = CGGeneric(wrapForType(self.returnType, self.descriptor, self.templateValues))
         if self.checkFound:
             wrap = CGIfWrapper(wrap, "found")
         else:
-            wrap = CGList([CGGeneric("MOZ_ASSERT(found);"), wrap], "\n")
+            wrap = CGList([CGGeneric("MOZ_ASSERT(found);\n"), wrap])
         return "\n" + wrap.define()
 
 
 class CGProxyIndexedOperation(CGProxySpecialOperation):
     """
     Class to generate a call to an indexed operation.
 
     If doUnwrap is False, the caller is responsible for making sure a variable
@@ -8616,17 +8897,17 @@ class CGProxyIndexedGetter(CGProxyIndexe
 class CGProxyIndexedPresenceChecker(CGProxyIndexedGetter):
     """
     Class to generate a call that checks whether an indexed property exists.
 
     For now, we just delegate to CGProxyIndexedGetter
     """
     def __init__(self, descriptor):
         CGProxyIndexedGetter.__init__(self, descriptor)
-        self.cgRoot.append(CGGeneric("(void)result;"))
+        self.cgRoot.append(CGGeneric("(void)result;\n"))
 
 
 class CGProxyIndexedSetter(CGProxyIndexedOperation):
     """
     Class to generate a call to an indexed setter.
     """
     def __init__(self, descriptor):
         CGProxyIndexedOperation.__init__(self, descriptor, 'IndexedSetter')
@@ -8648,46 +8929,61 @@ class CGProxyNamedOperation(CGProxySpeci
         argName = self.arguments[0].identifier.name
         if argName == "id":
             # deal with the name collision
             idDecl = "JS::Rooted<jsid> id_(cx, id);\n"
             idName = "id_"
         else:
             idDecl = ""
             idName = "id"
-        unwrapString = (
-            "if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n"
-            "                            eStringify, eStringify, %s)) {\n"
-            "  return false;\n"
-            "}" % argName)
+        unwrapString = fill(
+            """
+            if (!ConvertJSValueToString(cx, nameVal, &nameVal,
+                                        eStringify, eStringify, ${argName})) {
+              return false;
+            }
+            """,
+            argName=argName)
         if self.value is None:
             # We're just using 'id', and if it's an atom we can take a
             # fast path here.
-            unwrapString = CGIfElseWrapper(
-                ("MOZ_LIKELY(JSID_IS_ATOM(%s))" % idName),
-                CGGeneric(
-                    "%s.SetData(js::GetAtomChars(JSID_TO_ATOM(%s)), js::GetAtomLength(JSID_TO_ATOM(%s)));" % (argName, idName, idName)),
-                CGGeneric(("nameVal = js::IdToValue(%s);\n" % idName) +
-                          unwrapString)).define()
+            unwrapString = fill(
+                """
+                if (MOZ_LIKELY(JSID_IS_ATOM(${idName}))) {
+                  ${argName}.SetData(js::GetAtomChars(JSID_TO_ATOM(${idName})), js::GetAtomLength(JSID_TO_ATOM(${idName})));
+                } else {
+                  nameVal = js::IdToValue(${idName});
+                  $*{unwrapString}
+                }
+                """,
+                idName=idName,
+                argName=argName,
+                unwrapString=unwrapString)
         else:
             unwrapString = ("nameVal = %s;\n" % self.value) + unwrapString
 
         # Sadly, we have to set up nameVal even if we have an atom id,
         # because we don't know for sure, and we can end up needing it
         # so it needs to be higher up the stack.  Using a Maybe here
         # seems like probable overkill.
-        return ("JS::Rooted<JS::Value> nameVal(cx);\n" +
-                idDecl +
-                ("binding_detail::FakeDependentString %s;\n" % argName) +
-                unwrapString +
-                ("\n"
-                 "\n"
-                 "%s* self = UnwrapProxy(proxy);\n" %
-                 self.descriptor.nativeType) +
-                CGProxySpecialOperation.define(self))
+        return fill(
+            """
+            JS::Rooted<JS::Value> nameVal(cx);
+            $*{idDecl}
+            binding_detail::FakeDependentString ${argName};
+            $*{unwrapString}
+
+            ${nativeType}* self = UnwrapProxy(proxy);
+            $*{op}
+            """,
+            idDecl=idDecl,
+            argName=argName,
+            unwrapString=unwrapString,
+            nativeType=self.descriptor.nativeType,
+            op=CGProxySpecialOperation.define(self))
 
 
 class CGProxyNamedGetter(CGProxyNamedOperation):
     """
     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.
@@ -8700,17 +8996,17 @@ class CGProxyNamedGetter(CGProxyNamedOpe
 class CGProxyNamedPresenceChecker(CGProxyNamedGetter):
     """
     Class to generate a call that checks whether a named property exists.
 
     For now, we just delegate to CGProxyNamedGetter
     """
     def __init__(self, descriptor):
         CGProxyNamedGetter.__init__(self, descriptor)
-        self.cgRoot.append(CGGeneric("(void)result;"))
+        self.cgRoot.append(CGGeneric("(void)result;\n"))
 
 
 class CGProxyNamedSetter(CGProxyNamedOperation):
     """
     Class to generate a call to a named setter.
     """
     def __init__(self, descriptor):
         CGProxyNamedOperation.__init__(self, descriptor, 'NamedSetter')
@@ -8736,35 +9032,39 @@ class CGProxyIsProxy(CGAbstractMethod):
     def __init__(self, descriptor):
         args = [Argument('JSObject*', 'obj')]
         CGAbstractMethod.__init__(self, descriptor, "IsProxy", "bool", args, alwaysInline=True)
 
     def declare(self):
         return ""
 
     def definition_body(self):
-        return "  return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();"
+        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)
 
     def declare(self):
         return ""
 
     def definition_body(self):
-        return """  MOZ_ASSERT(js::IsProxy(obj));
-  if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
-    MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
-    obj = js::UncheckedUnwrap(obj);
-  }
-  MOZ_ASSERT(IsProxy(obj));
-  return static_cast<%s*>(js::GetProxyPrivate(obj).toPrivate());""" % (self.descriptor.nativeType)
+        return indent(fill(
+            """
+            MOZ_ASSERT(js::IsProxy(obj));
+            if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
+              MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
+              obj = js::UncheckedUnwrap(obj);
+            }
+            MOZ_ASSERT(IsProxy(obj));
+            return static_cast<${type}*>(js::GetProxyPrivate(obj).toPrivate());
+            """,
+            type=self.descriptor.nativeType))
 
 
 class CGDOMJSProxyHandler_getOwnPropertyDescriptor(ClassMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'), Argument('JS::Handle<JSObject*>', 'proxy'),
                 Argument('JS::Handle<jsid>', 'id'),
                 Argument('JS::MutableHandle<JSPropertyDescriptor>', 'desc'),
                 Argument('unsigned', 'flags')]
@@ -8775,124 +9075,141 @@ class CGDOMJSProxyHandler_getOwnProperty
     def getBody(self):
         indexedGetter = self.descriptor.operations['IndexedGetter']
         indexedSetter = self.descriptor.operations['IndexedSetter']
 
         setOrIndexedGet = "bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);\n"
         if self.descriptor.supportsIndexedProperties():
             setOrIndexedGet += "int32_t index = GetArrayIndexFromId(cx, id);\n"
             readonly = toStringBool(indexedSetter is None)
-            fillDescriptor = "FillPropertyDescriptor(desc, proxy, %s);\nreturn true;" % readonly
-            templateValues = {'jsvalRef': 'desc.value()', 'jsvalHandle': 'desc.value()',
-                              'obj': 'proxy', 'successCode': fillDescriptor}
-            get = ("if (IsArrayIndex(index)) {\n" +
-                   CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define() + "\n" +
-                   "}\n") % (self.descriptor.nativeType)
+            fillDescriptor = "FillPropertyDescriptor(desc, proxy, %s);\nreturn true;\n" % readonly
+            templateValues = {
+                'jsvalRef': 'desc.value()',
+                'jsvalHandle': 'desc.value()',
+                'obj': 'proxy',
+                'successCode': fillDescriptor
+            }
+            get = fill(
+                """
+                if (IsArrayIndex(index)) {
+                  $*{callGetter}
+                }
+                """,
+                callGetter=(CGProxyIndexedGetter(self.descriptor, templateValues).define() %
+                            self.descriptor.nativeType))
 
         if UseHolderForUnforgeable(self.descriptor):
-            getUnforgeable = """if (!JS_GetPropertyDescriptorById(cx, ${holder}, id, flags, desc)) {
-  return false;
-}
-MOZ_ASSERT_IF(desc.object(), desc.object() == ${holder});"""
+            tryHolder = dedent("""
+                if (!JS_GetPropertyDescriptorById(cx, ${holder}, id, flags, desc)) {
+                  return false;
+                }
+                MOZ_ASSERT_IF(desc.object(), desc.object() == ${holder});
+                """)
             # We don't want to look at the unforgeable holder at all
             # in the xray case; that part got handled already.
-            getUnforgeable = CallOnUnforgeableHolder(self.descriptor,
-                                                     getUnforgeable)
-            getUnforgeable += """if (desc.object()) {
-  desc.object().set(proxy);
-  return true;
-}"""
-            getUnforgeable = CGIfWrapper(CGGeneric(getUnforgeable),
-                                         "!isXray").define() + "\n\n"
+            getUnforgeable = fill(
+                """
+                if (!isXray) {
+                  $*{callOnUnforgeable}
+                  if (desc.object()) {
+                    desc.object().set(proxy);
+                    return true;
+                  }
+                }
+
+                """,
+                callOnUnforgeable=CallOnUnforgeableHolder(self.descriptor, tryHolder))
         else:
             getUnforgeable = ""
 
         if indexedSetter or self.descriptor.operations['NamedSetter']:
             setOrIndexedGet += "if (flags & JSRESOLVE_ASSIGNING) {\n"
             if indexedSetter:
                 setOrIndexedGet += ("  if (IsArrayIndex(index)) {\n")
                 if not 'IndexedCreator' in self.descriptor.operations:
                     # FIXME need to check that this is a 'supported property
                     # index'.  But if that happens, watch out for the assumption
                     # below that the name setter always returns for
                     # IsArrayIndex(index).
                     assert False
                 setOrIndexedGet += ("    FillPropertyDescriptor(desc, proxy, JSVAL_VOID, false);\n" +
                                     "    return true;\n" +
                                     "  }\n")
-            setOrIndexedGet += CGIndenter(CGGeneric(getUnforgeable)).define()
+            setOrIndexedGet += indent(getUnforgeable)
             if self.descriptor.operations['NamedSetter']:
                 if not 'NamedCreator' in self.descriptor.operations:
                     # FIXME need to check that this is a 'supported property name'
                     assert False
                 create = CGGeneric("FillPropertyDescriptor(desc, proxy, JSVAL_VOID, false);\n"
-                                   "return true;")
+                                   "return true;\n")
                 # If we have an indexed setter we've already returned
                 if (self.descriptor.supportsIndexedProperties() and
-                    not indexedSetter):
+                        not indexedSetter):
                     create = CGIfWrapper(create, "!IsArrayIndex(index)")
-                setOrIndexedGet += CGIndenter(create).define() + "\n"
-            setOrIndexedGet += "}"
+                setOrIndexedGet += indent(create.define())
+            setOrIndexedGet += "} else {\n"
             if indexedGetter:
-                setOrIndexedGet += (" else {\n" +
-                                    CGIndenter(CGGeneric(get + "\n" + getUnforgeable)).define() +
-                                    "}")
-            else:
-                setOrIndexedGet += (" else {\n" +
-                                    CGIndenter(CGGeneric(getUnforgeable)).define() +
-                                    "}")
-            setOrIndexedGet += "\n\n"
+                setOrIndexedGet += indent(get + "\n" + getUnforgeable)
+            else:
+                setOrIndexedGet += indent(getUnforgeable)
+            setOrIndexedGet += "}\n\n"
         else:
             if indexedGetter:
                 setOrIndexedGet += ("if (!(flags & JSRESOLVE_ASSIGNING)) {\n" +
-                                    CGIndenter(CGGeneric(get)).define() +
+                                    indent(get) +
                                     "}\n\n")
             setOrIndexedGet += getUnforgeable
 
         if self.descriptor.supportsNamedProperties():
             operations = self.descriptor.operations
             readonly = toStringBool(operations['NamedSetter'] is None)
             enumerable = (
                 "self->NameIsEnumerable(Constify(%s))" %
                 # First [0] means first (and only) signature, [1] means
                 # "arguments" as opposed to return type, [0] means first (and
                 # only) argument.
                 operations['NamedGetter'].signatures()[0][1][0].identifier.name)
             fillDescriptor = (
                 "FillPropertyDescriptor(desc, proxy, %s, %s);\n"
-                "return true;" % (readonly, enumerable))
+                "return true;\n" % (readonly, enumerable))
             templateValues = {'jsvalRef': 'desc.value()', 'jsvalHandle': 'desc.value()',
                               'obj': 'proxy', 'successCode': fillDescriptor}
             condition = "!HasPropertyOnPrototype(cx, proxy, id)"
             if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
                 condition = "(!isXray || %s)" % condition
             condition = "!(flags & JSRESOLVE_ASSIGNING) && " + condition
             if self.descriptor.supportsIndexedProperties():
                 condition = "!IsArrayIndex(index) && " + condition
-            namedGet = ("\n" +
-                        CGIfWrapper(CGProxyNamedGetter(self.descriptor, templateValues),
+            namedGet = (CGIfWrapper(CGProxyNamedGetter(self.descriptor, templateValues),
                                     condition).define() +
                         "\n")
         else:
             namedGet = ""
 
-        return setOrIndexedGet + """JS::Rooted<JSObject*> expando(cx);
-if (!isXray && (expando = GetExpandoObject(proxy))) {
-  if (!JS_GetPropertyDescriptorById(cx, expando, id, flags, desc)) {
-    return false;
-  }
-  if (desc.object()) {
-    // Pretend the property lives on the wrapper.
-    desc.object().set(proxy);
-    return true;
-  }
-}
-""" + namedGet + """
-desc.object().set(nullptr);
-return true;"""
+        return fill(
+            """
+            $*{setOrIndexedGet}
+            JS::Rooted<JSObject*> expando(cx);
+            if (!isXray && (expando = GetExpandoObject(proxy))) {
+              if (!JS_GetPropertyDescriptorById(cx, expando, id, flags, desc)) {
+                return false;
+              }
+              if (desc.object()) {
+                // Pretend the property lives on the wrapper.
+                desc.object().set(proxy);
+                return true;
+              }
+            }
+
+            $*{namedGet}
+            desc.object().set(nullptr);
+            return true;
+            """,
+            setOrIndexedGet=setOrIndexedGet,
+            namedGet=namedGet)
 
 
 class CGDOMJSProxyHandler_defineProperty(ClassMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'), Argument('JS::Handle<JSObject*>', 'proxy'),
                 Argument('JS::Handle<jsid>', 'id'),
                 Argument('JS::MutableHandle<JSPropertyDescriptor>', 'desc'),
                 Argument('bool*', 'defined')]
@@ -8903,55 +9220,72 @@ class CGDOMJSProxyHandler_defineProperty
         set = ""
 
         indexedSetter = self.descriptor.operations['IndexedSetter']
         if indexedSetter:
             if not (self.descriptor.operations['IndexedCreator'] is indexedSetter):
                 raise TypeError("Can't handle creator that's different from the setter")
             set += ("int32_t index = GetArrayIndexFromId(cx, id);\n" +
                     "if (IsArrayIndex(index)) {\n" +
-                    "  *defined = true;" +
-                    CGIndenter(CGProxyIndexedSetter(self.descriptor)).define() +
+                    "  *defined = true;" +  # SUPER BOGUS missing newline here
+                    indent(CGProxyIndexedSetter(self.descriptor).define()) +
                     "  return true;\n" +
-                    "}\n") % (self.descriptor.nativeType)
+                    "}\n") % self.descriptor.nativeType
         elif self.descriptor.supportsIndexedProperties():
-            set += ("if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {\n"
-                    "  return js::IsInNonStrictPropertySet(cx) || ThrowErrorMessage(cx, MSG_NO_INDEXED_SETTER, \"%s\");\n"
-                    "}\n" % self.descriptor.name)
+            set += fill(
+                """
+                if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
+                  return js::IsInNonStrictPropertySet(cx) || ThrowErrorMessage(cx, MSG_NO_INDEXED_SETTER, "${name}");
+                }
+                """,
+                name=self.descriptor.name)
 
         if UseHolderForUnforgeable(self.descriptor):
             defineOnUnforgeable = ("bool hasUnforgeable;\n"
                                    "if (!JS_HasPropertyById(cx, ${holder}, id, &hasUnforgeable)) {\n"
                                    "  return false;\n"
                                    "}\n"
                                    "if (hasUnforgeable) {\n"
-                                   "  *defined = true;" +
+                                   "  *defined = true;"  # SUPER BOGUS missing newline
                                    "  bool unused;\n"
                                    "  return js_DefineOwnProperty(cx, ${holder}, id, desc, &unused);\n"
-                                   "}\n")
+                                   "}\n"
+                                   "\n")  # BOGUS extra blank line at end of block or method
             set += CallOnUnforgeableHolder(self.descriptor,
                                            defineOnUnforgeable,
                                            "xpc::WrapperFactory::IsXrayWrapper(proxy)")
 
         namedSetter = self.descriptor.operations['NamedSetter']
         if namedSetter:
             if not self.descriptor.operations['NamedCreator'] is namedSetter:
                 raise TypeError("Can't handle creator that's different from the setter")
             # If we support indexed properties, we won't get down here for
             # indices, so we can just do our setter unconditionally here.
-            set += ("*defined = true;\n" +
-                    CGProxyNamedSetter(self.descriptor).define() + "\n" +
-                    "return true;\n")
+            set += fill(
+                """
+                *defined = true;
+                $*{callSetter}
+
+                return true;
+
+                """,  # BOGUS extra blank line at end of method
+                callSetter=CGProxyNamedSetter(self.descriptor).define())
         else:
             if self.descriptor.supportsNamedProperties():
-                set += (CGProxyNamedPresenceChecker(self.descriptor).define() + "\n" +
-                        "if (found) {\n"
-                        "  return js::IsInNonStrictPropertySet(cx) || ThrowErrorMessage(cx, MSG_NO_NAMED_SETTER, \"%s\");\n"
-                        "}\n" % self.descriptor.name)
-            set += ("return mozilla::dom::DOMProxyHandler::defineProperty(%s);" %
+                set += fill(
+                    """
+                    $*{presenceChecker}
+
+                    if (found) {
+                      return js::IsInNonStrictPropertySet(cx) || ThrowErrorMessage(cx, MSG_NO_NAMED_SETTER, "${name}");
+                    }
+                    """,
+                    presenceChecker=CGProxyNamedPresenceChecker(self.descriptor).define(),
+                    name=self.descriptor.name)
+            set += ("return mozilla::dom::DOMProxyHandler::defineProperty(%s);\n" %
                     ", ".join(a.name for a in self.args))
         return set
 
 
 class CGDOMJSProxyHandler_delete(ClassMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'), Argument('JS::Handle<JSObject*>', 'proxy'),
                 Argument('JS::Handle<jsid>', 'id'),
@@ -8966,77 +9300,92 @@ class CGDOMJSProxyHandler_delete(ClassMe
             type should be "Named" or "Indexed"
             """
             assert type is "Named" or type is "Indexed"
             deleter = self.descriptor.operations[type + 'Deleter']
             if deleter:
                 if (not deleter.signatures()[0][0].isPrimitive() or
                     deleter.signatures()[0][0].nullable() or
                     deleter.signatures()[0][0].tag() != IDLType.Tags.bool):
-                    setBp = "*bp = true;"
+                    setBp = "*bp = true;\n"
                 else:
-                    setBp = ("if (found) {\n"
-                             "  *bp = result;\n"
-                             "} else {\n"
-                             "  *bp = true;\n"
-                             "}")
+                    setBp = dedent("""
+                        if (found) {
+                          *bp = result;
+                        } else {
+                          *bp = true;
+                        }
+                        """)
                 body = (eval("CGProxy%sDeleter" % type)(self.descriptor).define() +
                         setBp)
             elif eval("self.descriptor.supports%sProperties()" % type):
                 body = (eval("CGProxy%sPresenceChecker" % type)(self.descriptor).define() +
-                        "if (found) {\n"
-                        "  *bp = false;\n"
-                        "} else {\n"
-                        "  *bp = true;\n"
-                        "}")
+                        dedent("""
+                            if (found) {
+                              *bp = false;
+                            } else {
+                              *bp = true;
+                            }
+                            """))
             else:
                 body = None
             return body
 
-        delete = """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
-          "Should not have a XrayWrapper here");
-
-"""
+        delete = dedent("""
+            MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
+                      "Should not have a XrayWrapper here");
+
+            """)
 
         indexedBody = getDeleterBody("Indexed")
         if indexedBody is not None:
-            delete += ("int32_t index = GetArrayIndexFromId(cx, id);\n" +
-                       "if (IsArrayIndex(index)) {\n" +
-                       CGIndenter(CGGeneric(indexedBody)).define() + "\n"
-                       "  // We always return here, even if the property was not found\n"
-                       "  return true;\n" +
-                       "}\n") % self.descriptor.nativeType
+            delete += fill(
+                """
+                int32_t index = GetArrayIndexFromId(cx, id);
+                if (IsArrayIndex(index)) {
+                  $*{indexedBody}
+                  // We always return here, even if the property was not found
+                  return true;
+                }
+                """,
+                indexedBody=indexedBody % self.descriptor.nativeType)
 
         if UseHolderForUnforgeable(self.descriptor):
-            unforgeable = ("bool hasUnforgeable;\n"
-                           "if (!JS_HasPropertyById(cx, ${holder}, id, &hasUnforgeable)) {\n"
-                           "  return false;\n"
-                           "}\n"
-                           "if (hasUnforgeable) {\n"
-                           "  *bp = false;\n"
-                           "  return true;\n"
-                           "}")
+            unforgeable = dedent("""
+                bool hasUnforgeable;
+                if (!JS_HasPropertyById(cx, ${holder}, id, &hasUnforgeable)) {
+                  return false;
+                }
+                if (hasUnforgeable) {
+                  *bp = false;
+                  return true;
+                }
+                """)
             delete += CallOnUnforgeableHolder(self.descriptor, unforgeable)
             delete += "\n"
 
         namedBody = getDeleterBody("Named")
         if namedBody is not None:
             # We always return above for an index id in the case when we support
             # indexed properties, so we can just treat the id as a name
             # unconditionally here.
-            delete += (CGGeneric(namedBody).define() + "\n"
+            delete += (namedBody +
                        "if (found) {\n"
                        "  return true;\n"
-                       "}\n")
+                       "}\n\n")  # BOGUS extra blank line
             if not self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
                 delete = CGIfWrapper(CGGeneric(delete),
                                      "!HasPropertyOnPrototype(cx, proxy, id)").define()
-        delete += """
-
-return dom::DOMProxyHandler::delete_(cx, proxy, id, bp);"""
+        else:
+            delete += "\n"  # BOGUS extra blank line
+
+        delete += dedent("""
+
+            return dom::DOMProxyHandler::delete_(cx, proxy, id, bp);
+            """)
 
         return delete
 
 
 class CGDOMJSProxyHandler_ownPropNames(ClassMethod):
     def __init__(self, descriptor, ):
         args = [Argument('JSContext*', 'cx'),
                 Argument('JS::Handle<JSObject*>', 'proxy'),
@@ -9044,236 +9393,286 @@ class CGDOMJSProxyHandler_ownPropNames(C
                 Argument('JS::AutoIdVector&', 'props')]
         ClassMethod.__init__(self, "ownPropNames", "bool", args,
                              virtual=True, override=True)
         self.descriptor = descriptor
 
     def getBody(self):
         # Per spec, we do indices, then named props, then everything else
         if self.descriptor.supportsIndexedProperties():
-            addIndices = """
-uint32_t length = UnwrapProxy(proxy)->Length();
-MOZ_ASSERT(int32_t(length) >= 0);
-for (int32_t i = 0; i < int32_t(length); ++i) {
-  if (!props.append(INT_TO_JSID(i))) {
-    return false;
-  }
-}
-"""
+            addIndices = dedent("""
+
+                uint32_t length = UnwrapProxy(proxy)->Length();
+                MOZ_ASSERT(int32_t(length) >= 0);
+                for (int32_t i = 0; i < int32_t(length); ++i) {
+                  if (!props.append(INT_TO_JSID(i))) {
+                    return false;
+                  }
+                }
+                """)
         else:
             addIndices = ""
 
+        if UseHolderForUnforgeable(self.descriptor):
+            addUnforgeable = dedent("""
+                if (!js::GetPropertyNames(cx, ${holder}, flags, &props)) {
+                  return false;
+                }
+                """)
+            addUnforgeable = CallOnUnforgeableHolder(self.descriptor,
+                                                     addUnforgeable,
+                                                     "isXray")
+        else:
+            addUnforgeable = ""
+
         if self.descriptor.supportsNamedProperties():
             if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
                 shadow = "!isXray"
             else:
                 shadow = "false"
-            addNames = """
-nsTArray<nsString> names;
-UnwrapProxy(proxy)->GetSupportedNames(flags, names);
-if (!AppendNamedPropertyIds(cx, proxy, names, %s, props)) {
-  return false;
-}
-""" % shadow
+            addNames = fill(
+                """
+
+                nsTArray<nsString> names;
+                UnwrapProxy(proxy)->GetSupportedNames(flags, names);
+                if (!AppendNamedPropertyIds(cx, proxy, names, ${shadow}, props)) {
+                  return false;
+                }
+                """,
+                shadow=shadow)
         else:
             addNames = ""
 
-        if UseHolderForUnforgeable(self.descriptor):
-            addUnforgeable = (
-                "if (!js::GetPropertyNames(cx, ${holder}, flags, &props)) {\n"
-                "  return false;\n"
-                "}")
-            addUnforgeable = CallOnUnforgeableHolder(self.descriptor,
-                                                     addUnforgeable,
-                                                     "isXray")
-        else:
-            addUnforgeable = ""
-        return """bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
-""" + addIndices + addUnforgeable + addNames + """
-JS::Rooted<JSObject*> expando(cx);
-if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
-    !js::GetPropertyNames(cx, expando, flags, &props)) {
-  return false;
-}
-
-return true;"""
+        return fill(
+            """
+            bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
+            $*{addIndices}
+            $*{addUnforgeable}
+            $*{addNames}
+
+            JS::Rooted<JSObject*> expando(cx);
+            if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
+                !js::GetPropertyNames(cx, expando, flags, &props)) {
+              return false;
+            }
+
+            return true;
+            """,
+            addIndices=addIndices,
+            addUnforgeable=addUnforgeable,
+            addNames=addNames)
 
 
 class CGDOMJSProxyHandler_hasOwn(ClassMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'),
                 Argument('JS::Handle<JSObject*>', 'proxy'),
                 Argument('JS::Handle<jsid>', 'id'),
                 Argument('bool*', 'bp')]
         ClassMethod.__init__(self, "hasOwn", "bool", args,
                              virtual=True, override=True)
         self.descriptor = descriptor
 
     def getBody(self):
         if self.descriptor.supportsIndexedProperties():
-            indexed = ("int32_t index = GetArrayIndexFromId(cx, id);\n" +
-                       "if (IsArrayIndex(index)) {\n" +
-                       CGIndenter(CGProxyIndexedPresenceChecker(self.descriptor)).define() + "\n" +
-                       "  *bp = found;\n" +
-                       "  return true;\n" +
-                       "}\n\n") % (self.descriptor.nativeType)
+            indexed = fill(
+                """
+                int32_t index = GetArrayIndexFromId(cx, id);
+                if (IsArrayIndex(index)) {
+                  $*{presenceChecker}
+
+                  *bp = found;
+                  return true;
+                }
+
+                """,
+                presenceChecker=(CGProxyIndexedPresenceChecker(self.descriptor).define() %
+                                 self.descriptor.nativeType))
         else:
             indexed = ""
 
         if UseHolderForUnforgeable(self.descriptor):
-            unforgeable = ("bool b = true;\n"
-                           "bool ok = JS_AlreadyHasOwnPropertyById(cx, ${holder}, id, &b);\n"
-                           "*bp = !!b;\n"
-                           "if (!ok || *bp) {\n"
-                           "  return ok;\n"
-                           "}")
+            unforgeable = dedent("""
+                bool b = true;
+                bool ok = JS_AlreadyHasOwnPropertyById(cx, ${holder}, id, &b);
+                *bp = !!b;
+                if (!ok || *bp) {
+                  return ok;
+                }
+                """)
             unforgeable = CallOnUnforgeableHolder(self.descriptor, unforgeable)
         else:
             unforgeable = ""
 
         if self.descriptor.supportsNamedProperties():
             # If we support indexed properties we always return above for index
             # property names, so no need to check for those here.
-            named = (CGProxyNamedPresenceChecker(self.descriptor).define() + "\n" +
+            named = (CGProxyNamedPresenceChecker(self.descriptor).define() +
+                     "\n" +
                      "*bp = found;\n")
             if not self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
-                named = CGIfWrapper(CGGeneric(named + "return true;\n"),
+                # BOGUS extra blank line at end of block
+                named = CGIfWrapper(CGGeneric(named + "return true;\n\n"),
                                     "!HasPropertyOnPrototype(cx, proxy, id)").define()
-                named += ("\n"
-                          "*bp = false;")
-        else:
-            named = "*bp = false;"
-
-        return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
-          "Should not have a XrayWrapper here");
-
-""" + indexed + unforgeable + """
-JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
-if (expando) {
-  bool b = true;
-  bool ok = JS_HasPropertyById(cx, expando, id, &b);
-  *bp = !!b;
-  if (!ok || *bp) {
-    return ok;
-  }
-}
-
-""" + named + """
-return true;"""
+                named += "*bp = false;\n"
+            else:
+                named += "\n"
+        else:
+            named = "*bp = false;\n"
+
+        return fill(
+            """
+            MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
+                      "Should not have a XrayWrapper here");
+
+            $*{indexed}
+            $*{unforgeable}
+
+            JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
+            if (expando) {
+              bool b = true;
+              bool ok = JS_HasPropertyById(cx, expando, id, &b);
+              *bp = !!b;
+              if (!ok || *bp) {
+                return ok;
+              }
+            }
+
+            $*{named}
+            return true;
+            """,
+            indexed=indexed,
+            unforgeable=unforgeable,
+            named=named)
 
 
 class CGDOMJSProxyHandler_get(ClassMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'),
                 Argument('JS::Handle<JSObject*>', 'proxy'),
                 Argument('JS::Handle<JSObject*>', 'receiver'),
                 Argument('JS::Handle<jsid>', 'id'),
                 Argument('JS::MutableHandle<JS::Value>', 'vp')]
         ClassMethod.__init__(self, "get", "bool", args,
                              virtual=True, override=True)
         self.descriptor = descriptor
 
     def getBody(self):
         getUnforgeableOrExpando = "JS::Rooted<JSObject*> sharedRoot(cx);\n"
         if UseHolderForUnforgeable(self.descriptor):
-            hasUnforgeable = (
-                "bool hasUnforgeable;\n"
-                "if (!JS_AlreadyHasOwnPropertyById(cx, ${holder}, id, &hasUnforgeable)) {\n"
-                "  return false;\n"
-                "}\n"
-                "if (hasUnforgeable) {\n"
-                "  return JS_ForwardGetPropertyTo(cx, ${holder}, id, proxy, vp);\n"
-                "}")
+            hasUnforgeable = dedent("""
+                bool hasUnforgeable;
+                if (!JS_AlreadyHasOwnPropertyById(cx, ${holder}, id, &hasUnforgeable)) {
+                  return false;
+                }
+                if (hasUnforgeable) {
+                  return JS_ForwardGetPropertyTo(cx, ${holder}, id, proxy, vp);
+                }
+                """)
             getUnforgeableOrExpando += CallOnUnforgeableHolder(self.descriptor,
                                                                hasUnforgeable,
                                                                useSharedRoot=True)
-        getUnforgeableOrExpando += """{ // Scope for expando
-  JS::Rooted<JSObject*>& expando(sharedRoot);
-  expando = DOMProxyHandler::GetExpandoObject(proxy);
-  if (expando) {
-    bool hasProp;
-    if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
-      return false;
-    }
-
-    if (hasProp) {
-      // Forward the get to the expando object, but our receiver is whatever our
-      // receiver is.
-      return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp);
-    }
-  }
-}"""
+        getUnforgeableOrExpando += dedent("""
+            { // Scope for expando
+              JS::Rooted<JSObject*>& expando(sharedRoot);
+              expando = DOMProxyHandler::GetExpandoObject(proxy);
+              if (expando) {
+                bool hasProp;
+                if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
+                  return false;
+                }
+
+                if (hasProp) {
+                  // Forward the get to the expando object, but our receiver is whatever our
+                  // receiver is.
+                  return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp);
+                }
+              }
+            }
+            """)
 
         templateValues = {'jsvalRef': 'vp', 'jsvalHandle': 'vp', 'obj': 'proxy'}
 
         if self.descriptor.supportsIndexedProperties():
-            getIndexedOrExpando = ("int32_t index = GetArrayIndexFromId(cx, id);\n" +
-                                   "if (IsArrayIndex(index)) {\n" +
-                                   CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define()) % (self.descriptor.nativeType)
-            getIndexedOrExpando += """
-  // Even if we don't have this index, we don't forward the
-  // get on to our expando object.
-} else {
-  %s
-}
-
-""" % (stripTrailingWhitespace(getUnforgeableOrExpando.replace('\n', '\n  ')))
-        else:
-            getIndexedOrExpando = getUnforgeableOrExpando + "\n\n"
+            getIndexedOrExpando = fill(
+                """
+                int32_t index = GetArrayIndexFromId(cx, id);
+                if (IsArrayIndex(index)) {
+                  $*{callGetter}
+                  // Even if we don't have this index, we don't forward the
+                  // get on to our expando object.
+                } else {
+                  $*{getUnforgeableOrExpando}
+                }
+                """,
+                callGetter=(CGProxyIndexedGetter(self.descriptor, templateValues).define() %
+                            self.descriptor.nativeType),
+                getUnforgeableOrExpando=getUnforgeableOrExpando)
+        else:
+            getIndexedOrExpando = getUnforgeableOrExpando
 
         if self.descriptor.supportsNamedProperties():
             getNamed = CGProxyNamedGetter(self.descriptor, templateValues)
             if self.descriptor.supportsIndexedProperties():
                 getNamed = CGIfWrapper(getNamed, "!IsArrayIndex(index)")
-            getNamed = getNamed.define() + "\n\n"
+            getNamed = getNamed.define() + "\n"
         else:
             getNamed = ""
 
-        getOnPrototype = """bool foundOnPrototype;
-if (!GetPropertyOnPrototype(cx, proxy, id, &foundOnPrototype, vp.address())) {
-  return false;
-}
-
-if (foundOnPrototype) {
-  return true;
-}
-
-"""
+        getOnPrototype = dedent("""
+            bool foundOnPrototype;
+            if (!GetPropertyOnPrototype(cx, proxy, id, &foundOnPrototype, vp.address())) {
+              return false;
+            }
+
+            if (foundOnPrototype) {
+              return true;
+            }
+
+            """)
         if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
             getNamed = getNamed + getOnPrototype
         else:
             getNamed = getOnPrototype + getNamed
 
-        return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
-            "Should not have a XrayWrapper here");
-
-""" + getIndexedOrExpando + getNamed + """vp.setUndefined();
-return true;"""
+        return fill(
+            """
+            MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
+                        "Should not have a XrayWrapper here");
+
+            $*{indexedOrExpando}
+
+            $*{named}
+            vp.setUndefined();
+            return true;
+            """,
+            indexedOrExpando=getIndexedOrExpando,
+            named=getNamed)
 
 
 class CGDOMJSProxyHandler_className(ClassMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'), Argument('JS::Handle<JSObject*>', 'proxy')]
         ClassMethod.__init__(self, "className", "const char*", args,
                              virtual=True, override=True)
         self.descriptor = descriptor
 
     def getBody(self):
-        return 'return "%s";' % self.descriptor.name
+        return 'return "%s";\n' % self.descriptor.name
 
 
 class CGDOMJSProxyHandler_finalizeInBackground(ClassMethod):
     def __init__(self, descriptor):
         args = [Argument('JS::Value', 'priv')]
         ClassMethod.__init__(self, "finalizeInBackground", "bool", args,
                              virtual=True, override=True)
         self.descriptor = descriptor
 
     def getBody(self):
-        return ("return false;")
+        return "return false;\n"
 
 
 class CGDOMJSProxyHandler_finalize(ClassMethod):
     def __init__(self, descriptor):
         args = [Argument('JSFreeOp*', 'fop'), Argument('JSObject*', 'proxy')]
         ClassMethod.__init__(self, "finalize", "void", args,
                              virtual=True, override=True)
         self.descriptor = descriptor
@@ -9295,57 +9694,64 @@ class CGDOMJSProxyHandler_slice(ClassMet
         ClassMethod.__init__(self, "slice", "bool", args)
         self.descriptor = descriptor
 
     def getBody(self):
         # Just like getOwnPropertyNames 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.
-        header = CGGeneric(
-            'JS::Rooted<JS::Value> temp(cx);\n'
-            'MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),\n'
-            '           "Should not have a XrayWrapper here");\n'
-            '\n'
-            '%s* self = UnwrapProxy(proxy);\n'
-            'uint32_t length = self->Length();\n'
-            "// Compute the end of the indices we'll get ourselves\n"
-            'uint32_t ourEnd = std::max(begin, std::min(end, length));' %
-            self.descriptor.nativeType)
-
-        successCode = ("js::UnsafeDefineElement(cx, array, index - begin, temp);\n"
-                       "continue;")
-        templateValues = {'jsvalRef': 'temp', 'jsvalHandle': '&temp',
-                          'obj': 'proxy', 'successCode': successCode}
-        get = CGProxyIndexedGetter(self.descriptor, templateValues, False, False)
-
-        getOurElements = CGWrapper(
-            CGIndenter(get),
-            pre="for (uint32_t index = begin; index < ourEnd; ++index) {\n",
-            post="\n}")
-
-        getProtoElements = CGIfWrapper(
-            CGGeneric("JS::Rooted<JSObject*> proto(cx);\n"
-                      "if (!js::GetObjectProto(cx, proxy, &proto)) {\n"
-                      "  return false;\n"
-                      "}\n"
-                      "return js::SliceSlowly(cx, proto, proxy, ourEnd, end, array);"),
-            "end > ourEnd")
-
-        return CGList([header, getOurElements, getProtoElements,
-                       CGGeneric("return true;")], "\n\n").define()
+
+        templateValues = {
+            'jsvalRef': 'temp',
+            'jsvalHandle': '&temp',
+            'obj': 'proxy',
+            'successCode': ("js::UnsafeDefineElement(cx, array, index - begin, temp);\n"
+                            "continue;\n")
+        }
+        get = CGProxyIndexedGetter(self.descriptor, templateValues, False, False).define()
+
+        return fill(
+            """
+            JS::Rooted<JS::Value> temp(cx);
+            MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
+                       "Should not have a XrayWrapper here");
+
+            ${nativeType}* self = UnwrapProxy(proxy);
+            uint32_t length = self->Length();
+            // Compute the end of the indices we'll get ourselves
+            uint32_t ourEnd = std::max(begin, std::min(end, length));
+
+            for (uint32_t index = begin; index < ourEnd; ++index) {
+              $*{get}
+            }
+
+            if (end > ourEnd) {
+              JS::Rooted<JSObject*> proto(cx);
+              if (!js::GetObjectProto(cx, proxy, &proto)) {
+                return false;
+              }
+              return js::SliceSlowly(cx, proto, proxy, ourEnd, end, array);
+            }
+
+            return true;
+            """,
+            nativeType=self.descriptor.nativeType,
+            get=get)
 
 
 class CGDOMJSProxyHandler_getInstance(ClassMethod):
     def __init__(self):
         ClassMethod.__init__(self, "getInstance", "DOMProxyHandler*", [], static=True)
 
     def getBody(self):
-        return """static DOMProxyHandler instance;
-return &instance;"""
+        return dedent("""
+            static DOMProxyHandler instance;
+            return &instance;
+            """)
 
 
 class CGDOMJSProxyHandler(CGClass):
     def __init__(self, descriptor):
         assert (descriptor.supportsIndexedProperties() or
                 descriptor.supportsNamedProperties())
         methods = [CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor),
                    CGDOMJSProxyHandler_defineProperty(descriptor),
@@ -9579,21 +9985,24 @@ class CGDescriptor(CGThing):
             cgThings.append(CGConstructorEnabled(descriptor))
 
         if descriptor.concrete:
             if descriptor.proxy:
                 if descriptor.interface.totalMembersInSlots != 0:
                     raise TypeError("We can't have extra reserved slots for "
                                     "proxy interface %s" %
                                     descriptor.interface.identifier.name)
-                cgThings.append(CGGeneric("""static_assert(IsBaseOf<nsISupports, %s >::value,
-                  "We don't support non-nsISupports native classes for "
-                  "proxy-based bindings yet");
-
-""" % descriptor.nativeType))
+                cgThings.append(CGGeneric(fill(
+                    """
+                    static_assert(IsBaseOf<nsISupports, ${nativeType} >::value,
+                                      "We don't support non-nsISupports native classes for "
+                                      "proxy-based bindings yet");
+
+                    """,
+                    nativeType=descriptor.nativeType)))
                 if not descriptor.wrapperCache:
                     raise TypeError("We need a wrappercache to support expandos for proxy-based "
                                     "bindings (" + descriptor.name + ")")
                 handlerThing = CGDOMJSProxyHandler(descriptor)
                 cgThings.append(CGDOMJSProxyHandlerDeclarer(handlerThing))
                 cgThings.append(CGProxyIsProxy(descriptor))
                 cgThings.append(CGProxyUnwrap(descriptor))
                 cgThings.append(CGDOMJSProxyHandlerDefiner(handlerThing))
@@ -9751,142 +10160,160 @@ class CGDictionary(CGThing):
         return self.structs.define()
 
     def base(self):
         if self.dictionary.parent:
             return self.makeClassName(self.dictionary.parent)
         return "DictionaryBase"
 
     def initMethod(self):
-        body = (
-            "// Passing a null JSContext is OK only if we're initing from null,\n"
-            "// Since in that case we will not have to do any property gets\n"
-            "MOZ_ASSERT_IF(!cx, val.isNull());\n")
+        body = dedent("""
+            // Passing a null JSContext is OK only if we're initing from null,
+            // Since in that case we will not have to do any property gets
+            MOZ_ASSERT_IF(!cx, val.isNull());
+            """)
 
         if self.needToInitIds:
-            initIdText = """${dictName}Atoms* atomsCache = nullptr;
-if (cx) {
-  atomsCache = GetAtomCache<${dictName}Atoms>(cx);
-  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
-    return false;
-  }
-}
-
-"""
-            body += string.Template(initIdText).substitute({
-                "dictName": self.makeClassName(self.dictionary)
-            })
+            body += fill(
+                """
+                ${dictName}Atoms* atomsCache = nullptr;
+                if (cx) {
+                  atomsCache = GetAtomCache<${dictName}Atoms>(cx);
+                  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
+                    return false;
+                  }
+                }
+
+                """,
+                dictName=self.makeClassName(self.dictionary))
 
         if self.dictionary.parent:
-            body += (
-                "// Per spec, we init the parent's members first\n"
-                "if (!%s::Init(cx, val)) {\n"
-                "  return false;\n"
-                "}\n"
-                "MOZ_ASSERT(IsConvertibleToDictionary(cx, val));\n"
-                "\n") % self.makeClassName(self.dictionary.parent)
-        else:
-            body += (
-                "if (!IsConvertibleToDictionary(cx, val)) {\n"
-                "  return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);\n"
-                "}\n"
-                "\n")
+            body += fill(
+                """
+                // Per spec, we init the parent's members first
+                if (!${dictName}::Init(cx, val)) {
+                  return false;
+                }
+                MOZ_ASSERT(IsConvertibleToDictionary(cx, val));
+
+                """,
+                dictName=self.makeClassName(self.dictionary.parent))
+        else:
+            body += fill(
+                """
+                if (!IsConvertibleToDictionary(cx, val)) {
+                  return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
+                }
+
+                """)
 
         memberInits = [self.getMemberConversion(m).define()
                        for m in self.memberInfo]
         if memberInits:
-            body += (
-                "bool isNull = val.isNullOrUndefined();\n"
-                "// We only need these if !isNull, in which case we have |cx|.\n"
-                "Maybe<JS::Rooted<JSObject *> > object;\n"
-                "Maybe<JS::Rooted<JS::Value> > temp;\n"
-                "if (!isNull) {\n"
-                "  object.construct(cx, &val.toObject());\n"
-                "  temp.construct(cx);\n"
-                "}\n")
-            body += "\n\n".join(memberInits) + "\n"
-
-        body += "return true;"
+            body += fill(
+                """
+                bool isNull = val.isNullOrUndefined();
+                // We only need these if !isNull, in which case we have |cx|.
+                Maybe<JS::Rooted<JSObject *> > object;
+                Maybe<JS::Rooted<JS::Value> > temp;
+                if (!isNull) {
+                  object.construct(cx, &val.toObject());
+                  temp.construct(cx);
+                }
+                $*{memberInits}
+                """,
+                memberInits="\n".join(memberInits))
+
+        body += "return true;\n"
 
         return ClassMethod("Init", "bool", [
             Argument('JSContext*', 'cx'),
             Argument('JS::Handle<JS::Value>', 'val'),
             Argument('const char*', 'sourceDescription', default='"Value"')
         ], body=body)
 
     def initFromJSONMethod(self):
         return ClassMethod(
             "Init", "bool",
             [Argument('const nsAString&', 'aJSON')],
-            body=(
-                "MOZ_ASSERT(NS_IsMainThread());\n"
-                "AutoSafeJSContext cx;\n"
-                "JS::Rooted<JS::Value> json(cx);\n"
-                "bool ok = ParseJSON(cx, aJSON, &json);\n"
-                "NS_ENSURE_TRUE(ok, false);\n"
-                "return Init(cx, json);"))
+            body=dedent("""
+                MOZ_ASSERT(NS_IsMainThread());
+                AutoSafeJSContext cx;
+                JS::Rooted<JS::Value> json(cx);
+                bool ok = ParseJSON(cx, aJSON, &json);
+                NS_ENSURE_TRUE(ok, false);
+                return Init(cx, json);
+                """))
 
     def toObjectMethod(self):
         body = ""
         if self.needToInitIds:
-            initIdText = """${dictName}Atoms* atomsCache = GetAtomCache<${dictName}Atoms>(cx);
-if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
-  return false;
-}
-
-"""
-            body += string.Template(initIdText).substitute(
-                {"dictName": self.makeClassName(self.dictionary)})
+            body += fill(
+                """
+                ${dictName}Atoms* atomsCache = GetAtomCache<${dictName}Atoms>(cx);
+                if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
+                  return false;
+                }
+
+                """,
+                dictName=self.makeClassName(self.dictionary))
 
         if self.dictionary.parent:
-            body += (
-                "// Per spec, we define the parent's members first\n"
-                "if (!%s::ToObject(cx, rval)) {\n"
-                "  return false;\n"
-                "}\n"
-                "JS::Rooted<JSObject*> obj(cx, &rval.toObject());\n"
-                "\n") % self.makeClassName(self.dictionary.parent)
-        else:
-            body += (
-                "JS::Rooted<JSObject*> obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));\n"
-                "if (!obj) {\n"
-                "  return false;\n"
-                "}\n"
-                "rval.set(JS::ObjectValue(*obj));\n"
-                "\n")
-
-        body += "\n\n".join(self.getMemberDefinition(m).define()
-                            for m in self.memberInfo)
-        body += "\n\nreturn true;"
+            body += fill(
+                """
+                // Per spec, we define the parent's members first
+                if (!${dictName}::ToObject(cx, rval)) {
+                  return false;
+                }
+                JS::Rooted<JSObject*> obj(cx, &rval.toObject());
+
+                """,
+                dictName=self.makeClassName(self.dictionary.parent))
+        else:
+            body += fill(
+                """
+                JS::Rooted<JSObject*> obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
+                if (!obj) {
+                  return false;
+                }
+                rval.set(JS::ObjectValue(*obj));
+
+                """)
+
+        if self.memberInfo:
+            body += "\n".join(self.getMemberDefinition(m).define()
+                              for m in self.memberInfo)
+        else:
+            body += "\n"  # BOGUS extra blank line
+        body += "\nreturn true;\n"
 
         return ClassMethod("ToObject", "bool", [
             Argument('JSContext*', 'cx'),
             Argument('JS::MutableHandle<JS::Value>', 'rval'),
         ], const=True, body=body)
 
     def initIdsMethod(self):
         assert self.needToInitIds
-        idinit = [CGGeneric('!atomsCache->%s.init(cx, "%s")' %
-                            (CGDictionary.makeIdName(m.identifier.name),
-                             m.identifier.name))
+        idinit = ['!atomsCache->%s.init(cx, "%s")' %
+                  (CGDictionary.makeIdName(m.identifier.name),
+                   m.identifier.name)
                   for m in self.dictionary.members]
         idinit.reverse()
-        idinit = CGList(idinit, " ||\n")
-        idinit = CGWrapper(idinit, pre="""
-// Initialize these in reverse order so that any failure leaves the first one
-// uninitialized.
-if (""",
-                           post=(") {\n"
-                                 "  return false;\n"
-                                 "}"),
-                           reindent=True)
-        body = (
-            "MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));\n"
-            "%s\n"
-            "return true;") % idinit.define()
+        body = fill(
+            """
+            MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
+
+            // Initialize these in reverse order so that any failure leaves the first one
+            // uninitialized.
+            if (${idinit}) {
+              return false;
+            }
+            return true;
+            """,
+            idinit=" ||\n    ".join(idinit))
 
         return ClassMethod("InitIds", "bool", [
             Argument("JSContext*", "cx"),
             Argument("%sAtoms*" % self.makeClassName(self.dictionary),
                      "atomsCache"),
         ], static=True, body=body, visibility="private")
 
     def traceDictionaryMethod(self):
@@ -9894,68 +10321,75 @@ if (""",
         if self.dictionary.parent:
             cls = self.makeClassName(self.dictionary.parent)
             body += "%s::TraceDictionary(trc);\n" % cls
 
         memberTraces = [self.getMemberTrace(m)
                         for m in self.dictionary.members
                         if typeNeedsRooting(m.type)]
 
-        body += "\n\n".join(memberTraces)
+        if memberTraces:
+            body += "\n".join(memberTraces)
+        else:
+            body += "\n"  # BOGUS extra newline
 
         return ClassMethod("TraceDictionary", "void", [
             Argument("JSTracer*", "trc"),
         ], body=body)
 
     def assignmentOperator(self):
-        body = CGList([], "\n")
+        body = CGList([])
         if self.dictionary.parent:
             body.append(CGGeneric(
-                "%s::operator=(aOther);" %
+                "%s::operator=(aOther);\n" %
                 self.makeClassName(self.dictionary.parent)))
         for (m, _) in self.memberInfo:
             memberName = self.makeMemberName(m.identifier.name)
             if not m.defaultValue:
-                memberAssign = CGIfElseWrapper(
-                    "aOther.%s.WasPassed()" % memberName,
-                    CGGeneric("%s.Construct();\n"
-                              "%s.Value() = aOther.%s.Value();" %
-                              (memberName, memberName, memberName)),
-                    CGGeneric("%s.Reset();" % memberName))
+                memberAssign = CGGeneric(fill(
+                    """
+                    if (aOther.${name}.WasPassed()) {
+                      ${name}.Construct();
+                      ${name}.Value() = aOther.${name}.Value();
+                    } else {
+                      ${name}.Reset();
+                    }
+                    """,
+                    name=memberName))
             else:
                 memberAssign = CGGeneric(
-                    "%s = aOther.%s;" % (memberName, memberName))
+                    "%s = aOther.%s;\n" % (memberName, memberName))
             body.append(memberAssign)
         return ClassMethod(
             "operator=", "void",
             [Argument("const %s&" % self.makeClassName(self.dictionary),
                       "aOther")],
-            body=body.define())
+            body=body.define() or "\n")  # BOGUS blank line when empty
 
     def getStructs(self):
         d = self.dictionary
         selfName = self.makeClassName(d)
         members = [ClassMember(self.makeMemberName(m[0].identifier.name),
                                self.getMemberType(m),
                                visibility="public",
                                body=self.getMemberInitializer(m))
                    for m in self.memberInfo]
         ctors = [
             ClassConstructor(
                 [],
                 visibility="public",
                 body=(
                     "// Safe to pass a null context if we pass a null value\n"
-                    "Init(nullptr, JS::NullHandleValue);")),
+                    "Init(nullptr, JS::NullHandleValue);\n")),
             ClassConstructor(
                 [Argument("int", "")],
                 visibility="protected",
                 explicit=True,
                 bodyInHeader=True,
-                body='// Do nothing here; this is used by our "Fast" subclass')
+                body='// Do nothing here; this is used by our "Fast" subclass\n')
         ]
         methods = []
 
         if self.needToInitIds:
             methods.append(self.initIdsMethod())
 
         methods.append(self.initMethod())
         methods.append(self.initFromJSONMethod())
@@ -9972,17 +10406,17 @@ if (""",
             disallowCopyConstruction = False
             # Note: no base constructors because our operator= will
             # deal with that.
             ctors.append(ClassConstructor([Argument("const %s&" % selfName,
                                                     "aOther")],
                                           bodyInHeader=True,
                                           visibility="public",
                                           explicit=True,
-                                          body="*this = aOther;"))
+                                          body="*this = aOther;\n"))
             methods.append(self.assignmentOperator())
         else:
             disallowCopyConstruction = True
 
         struct = CGClass(selfName,
                          bases=[ClassBase(self.base())],
                          members=members,
                          constructors=ctors,
@@ -9990,17 +10424,17 @@ if (""",
                          isStruct=True,
                          disallowCopyConstruction=disallowCopyConstruction)
 
         fastDictionaryCtor = ClassConstructor(
             [],
             visibility="public",
             bodyInHeader=True,
             baseConstructors=["%s(42)" % selfName],
-            body="// Doesn't matter what int we pass to the parent constructor")
+            body="// Doesn't matter what int we pass to the parent constructor\n")
 
         fastStruct = CGClass("Fast" + selfName,
                              bases=[ClassBase(selfName)],
                              constructors=[fastDictionaryCtor],
                              isStruct=True)
 
         return CGList([struct,
                        CGNamespace.build(['binding_detail'], fastStruct)],
@@ -10060,20 +10494,19 @@ if (""",
                       "  return false;\n"
                       "}\n")
         if member.defaultValue:
             conversion += "${convert}"
         else:
             conversion += (
                 "if (!isNull && !temp.ref().isUndefined()) {\n"
                 "  ${prop}.Construct();\n"
-                "${convert}\n"
-                "}")
-            conversionReplacements["convert"] = CGIndenter(
-                CGGeneric(conversionReplacements["convert"])).define()
+                "${convert}"
+                "}\n")
+            conversionReplacements["convert"] = indent(conversionReplacements["convert"])
 
         return CGGeneric(
             string.Template(conversion).substitute(conversionReplacements))
 
     def getMemberDefinition(self, memberInfo):
         member = memberInfo[0]
         declType = memberInfo[1].declType
         memberLoc = self.makeMemberName(member.identifier.name)
@@ -10104,17 +10537,17 @@ if (""",
 
         innerTemplate = wrapForType(
             member.type, self.descriptorProvider,
             {
                 'result': "currentValue",
                 'successCode': ("if (!%s) {\n"
                                 "  return false;\n"
                                 "}\n"
-                                "break;" % propDef),
+                                "break;\n" % propDef),
                 'jsvalRef': "temp",
                 'jsvalHandle': "&temp",
                 'returnsNewObject': False,
                 # 'obj' can just be allowed to be the string "obj", since that
                 # will be our dictionary object, which is presumably itself in
                 # the right scope.
                 'typedArraysAreStructs': True
             })
@@ -10127,17 +10560,17 @@ if (""",
 
         # Now make sure that our successCode can actually break out of the
         # conversion.  This incidentally gives us a scope for 'temp' and
         # 'currentValue'.
         conversion = CGWrapper(
             CGIndenter(conversion),
             pre=("do {\n"
                  "  // block for our 'break' successCode and scope for 'temp' and 'currentValue'\n"),
-            post="\n} while(0);")
+            post="} while(0);\n")
         if not member.defaultValue:
             # Only do the conversion if we have a value
             conversion = CGIfWrapper(conversion, "%s.WasPassed()" % memberLoc)
         return conversion
 
     def getMemberTrace(self, member):
         type = member.type
         assert typeNeedsRooting(type)
@@ -10147,35 +10580,35 @@ if (""",
         else:
             # The data is inside the Optional<>
             memberData = "%s.Value()" % memberLoc
 
         memberName = "%s.%s" % (self.makeClassName(self.dictionary),
                                 memberLoc)
 
         if type.isObject():
-            trace = CGGeneric('JS_CallObjectTracer(trc, %s, "%s");' %
+            trace = CGGeneric('JS_CallObjectTracer(trc, %s, "%s");\n' %
                               ("&"+memberData, memberName))
         elif type.isAny():
-            trace = CGGeneric('JS_CallValueTracer(trc, %s, "%s");' %
+            trace = CGGeneric('JS_CallValueTracer(trc, %s, "%s");\n' %
                               ("&"+memberData, memberName))
         elif (type.isSequence() or type.isDictionary() or
               type.isSpiderMonkeyInterface() or type.isUnion()):
             if type.nullable():
                 memberNullable = memberData
                 memberData = "%s.Value()" % memberData
             if type.isSequence():
-                trace = CGGeneric('DoTraceSequence(trc, %s);' % memberData)
+                trace = CGGeneric('DoTraceSequence(trc, %s);\n' % memberData)
             elif type.isDictionary():
-                trace = CGGeneric('%s.TraceDictionary(trc);' % memberData)
+                trace = CGGeneric('%s.TraceDictionary(trc);\n' % memberData)
             elif type.isUnion():
-                trace = CGGeneric('%s.TraceUnion(trc);' % memberData)
+                trace = CGGeneric('%s.TraceUnion(trc);\n' % memberData)
             else:
                 assert type.isSpiderMonkeyInterface()
-                trace = CGGeneric('%s.TraceSelf(trc);' % memberData)
+                trace = CGGeneric('%s.TraceSelf(trc);\n' % memberData)
             if type.nullable():
                 trace = CGIfWrapper(trace, "!%s.IsNull()" % memberNullable)
         else:
             assert False  # unknown type
 
         if not member.defaultValue:
             trace = CGIfWrapper(trace, "%s.WasPassed()" % memberLoc)
 
@@ -10231,53 +10664,53 @@ if (""",
 
 class CGRegisterProtos(CGAbstractMethod):
     def __init__(self, config):
         CGAbstractMethod.__init__(self, None, 'Register', 'void',
                                   [Argument('nsScriptNameSpaceManager*', 'aNameSpaceManager')])
         self.config = config
 
     def _defineMacro(self):
-        return """
-#define REGISTER_PROTO(_dom_class, _ctor_check) \\
-  aNameSpaceManager->RegisterDefineDOMInterface(MOZ_UTF16(#_dom_class), _dom_class##Binding::DefineDOMInterface, _ctor_check);
-#define REGISTER_CONSTRUCTOR(_dom_constructor, _dom_class, _ctor_check) \\
-  aNameSpaceManager->RegisterDefineDOMInterface(MOZ_UTF16(#_dom_constructor), _dom_class##Binding::DefineDOMInterface, _ctor_check);
-#define REGISTER_NAVIGATOR_CONSTRUCTOR(_prop, _dom_class, _ctor_check) \\
-  aNameSpaceManager->RegisterNavigatorDOMConstructor(MOZ_UTF16(_prop), _dom_class##Binding::ConstructNavigatorObject, _ctor_check);
-
-"""
+        return dedent("""
+            #define REGISTER_PROTO(_dom_class, _ctor_check) \\
+              aNameSpaceManager->RegisterDefineDOMInterface(MOZ_UTF16(#_dom_class), _dom_class##Binding::DefineDOMInterface, _ctor_check);
+            #define REGISTER_CONSTRUCTOR(_dom_constructor, _dom_class, _ctor_check) \\
+              aNameSpaceManager->RegisterDefineDOMInterface(MOZ_UTF16(#_dom_constructor), _dom_class##Binding::DefineDOMInterface, _ctor_check);
+            #define REGISTER_NAVIGATOR_CONSTRUCTOR(_prop, _dom_class, _ctor_check) \\
+              aNameSpaceManager->RegisterNavigatorDOMConstructor(MOZ_UTF16(_prop), _dom_class##Binding::ConstructNavigatorObject, _ctor_check);
+            """)
 
     def _undefineMacro(self):
-        return """
-#undef REGISTER_CONSTRUCTOR
-#undef REGISTER_PROTO
-#undef REGISTER_NAVIGATOR_CONSTRUCTOR"""
+        return dedent("""
+            #undef REGISTER_CONSTRUCTOR
+            #undef REGISTER_PROTO
+            #undef REGISTER_NAVIGATOR_CONSTRUCTOR
+            """)
 
     def _registerProtos(self):
         def getCheck(desc):
             if not desc.isExposedConditionally():
                 return "nullptr"
             return "%sBinding::ConstructorEnabled" % desc.name
         lines = []
         for desc in self.config.getDescriptors(hasInterfaceObject=True,
                                                isExternal=False,
                                                workers=False,
                                                register=True):
-            lines.append("REGISTER_PROTO(%s, %s);" % (desc.name, getCheck(desc)))
-            lines.extend("REGISTER_CONSTRUCTOR(%s, %s, %s);" % (n.identifier.name, desc.name, getCheck(desc))
+            lines.append("REGISTER_PROTO(%s, %s);\n" % (desc.name, getCheck(desc)))
+            lines.extend("REGISTER_CONSTRUCTOR(%s, %s, %s);\n" % (n.identifier.name, desc.name, getCheck(desc))
                          for n in desc.interface.namedConstructors)
         for desc in self.config.getDescriptors(isNavigatorProperty=True, register=True):
             propName = desc.interface.getNavigatorProperty()
             assert propName
-            lines.append('REGISTER_NAVIGATOR_CONSTRUCTOR("%s", %s, %s);' % (propName, desc.name, getCheck(desc)))
-        return '\n'.join(lines) + '\n'
+            lines.append('REGISTER_NAVIGATOR_CONSTRUCTOR("%s", %s, %s);\n' % (propName, desc.name, getCheck(desc)))
+        return ''.join(lines)
 
     def definition_body(self):
-        return self._defineMacro() + self._registerProtos() + self._undefineMacro()
+        return "\n" + self._defineMacro() + "\n" + self._registerProtos() + "\n" + self._undefineMacro()
 
 
 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
     that have no dependencies are just sorted by name.
@@ -10687,38 +11120,38 @@ class CGNativeMember(ClassMethod):
         if type.isPrimitive() and type.tag() in builtinNames:
             result = CGGeneric(builtinNames[type.tag()])
             defaultReturnArg = "0"
             if type.nullable():
                 result = CGTemplatedType("Nullable", result)
                 defaultReturnArg = ""
             return (result.define(),
                     "%s(%s)" % (result.define(), defaultReturnArg),
-                    "return ${declName};")
+                    "return ${declName};\n")
         if type.isDOMString():
             if isMember:
                 # No need for a third element in the isMember case
                 return "nsString", None, None
             # Outparam
-            return "void", "", "aRetVal = ${declName};"
+            return "void", "", "aRetVal = ${declName};\n"
         if type.isByteString():
             if isMember:
                 # No need for a third element in the isMember case
                 return "nsCString", None, None
             # Outparam
-            return "void", "", "aRetVal = ${declName};"
+            return "void", "", "aRetVal = ${declName};\n"
         if type.isEnum():
             enumName = type.unroll().inner.identifier.name
             if type.nullable():
                 enumName = CGTemplatedType("Nullable",
                                            CGGeneric(enumName)).define()
                 defaultValue = "%s()" % enumName
             else:
                 defaultValue = "%s(0)" % enumName
-            return enumName, defaultValue, "return ${declName};"
+            return enumName, defaultValue, "return ${declName};\n"
         if type.isGeckoInterface():
             iface = type.unroll().inner
             nativeType = self.descriptorProvider.getDescriptor(
                 iface.identifier.name).nativeType
             # Now trim off unnecessary namespaces
             nativeType = nativeType.split("::")
             if nativeType[0] == "mozilla":
                 nativeType.pop(0)
@@ -10737,51 +11170,53 @@ class CGNativeMember(ClassMethod):
                 result = CGWrapper(result,
                                    pre=("%s%s<" % (warning, holder)),
                                    post=">")
             else:
                 result = CGWrapper(result, post="*")
             # Since we always force an owning type for callback return values,
             # our ${declName} is an OwningNonNull or nsRefPtr.  So we can just
             # .forget() to get our already_AddRefed.
-            return result.define(), "nullptr", "return ${declName}.forget();"
+            return result.define(), "nullptr", "return ${declName}.forget();\n"
         if type.isCallback():
             return ("already_AddRefed<%s>" % type.unroll().identifier.name,
-                    "nullptr", "return ${declName}.forget();")
+                    "nullptr", "return ${declName}.forget();\n")
         if type.isAny():
-            return "JS::Value", "JS::UndefinedValue()", "return ${declName};"
+            return "JS::Value", "JS::UndefinedValue()", "return ${declName};\n"
         if type.isObject():
-            return "JSObject*", "nullptr", "return ${declName};"
+            return "JSObject*", "nullptr", "return ${declName};\n"
         if type.isSpiderMonkeyInterface():
             if type.nullable():
-                returnCode = "return ${declName}.IsNull() ? nullptr : ${declName}.Value().Obj();"
-            else:
-                returnCode = "return ${declName}.Obj();"
+                returnCode = "return ${declName}.IsNull() ? nullptr : ${declName}.Value().Obj();\n"
+            else:
+                returnCode = "return ${declName}.Obj();\n"
             return "JSObject*", "nullptr", returnCode
         if type.isSequence():
             # If we want to handle sequence-of-sequences return values, we're
             # going to need to fix example codegen to not produce nsTArray<void>
             # for the relevant argument...
             assert not isMember
             # Outparam.
             if type.nullable():
-                returnCode = ("if (${declName}.IsNull()) {\n"
-                              "  aRetVal.SetNull();\n"
-                              "} else {\n"
-                              "  aRetVal.SetValue().SwapElements(${declName}.Value());\n"
-                              "}")
-            else:
-                returnCode = "aRetVal.SwapElements(${declName});"
+                returnCode = dedent("""
+                    if (${declName}.IsNull()) {
+                      aRetVal.SetNull();
+                    } else {
+                      aRetVal.SetValue().SwapElements(${declName}.Value());
+                    }
+                    """)
+            else:
+                returnCode = "aRetVal.SwapElements(${declName});\n"
             return "void", "", returnCode
         if type.isDate():
             result = CGGeneric("Date")
             if type.nullable():
                 result = CGTemplatedType("Nullable", result)
             return (result.define(), "%s()" % result.define(),
-                    "return ${declName};")
+                    "return ${declName};\n")
         if type.isDictionary():
             if isMember:
                 # Only the first member of the tuple matters here, but return
                 # bogus values for the others in case someone decides to use
                 # them.
                 return CGDictionary.makeDictionaryName(type.inner), None, None
             # In this case we convert directly into our outparam to start with
             return "void", "", ""
@@ -11251,73 +11686,76 @@ class CGExampleClass(CGBindingImplClass)
 
     def define(self):
         # Just override CGClass and do our own thing
         if self.descriptor.wrapperCache:
             setDOMBinding = "  SetIsDOMBinding();\n"
         else:
             setDOMBinding = ""
         if self.refcounted:
-            ctordtor = """${nativeType}::${nativeType}()
-{
-%s}
-
-${nativeType}::~${nativeType}()
-{
-}
-""" % setDOMBinding
-        else:
-            ctordtor = """${nativeType}::${nativeType}()
-{
-  MOZ_COUNT_CTOR(${nativeType});
-}
-
-${nativeType}::~${nativeType}()
-{
-  MOZ_COUNT_DTOR(${nativeType});
-}
-"""
+            ctordtor = dedent("""
+                ${nativeType}::${nativeType}()
+                {
+                %s}
+
+                ${nativeType}::~${nativeType}()
+                {
+                }
+                """) % setDOMBinding
+        else:
+            ctordtor = dedent("""
+                ${nativeType}::${nativeType}()
+                {
+                  MOZ_COUNT_CTOR(${nativeType});
+                }
+
+                ${nativeType}::~${nativeType}()
+                {
+                  MOZ_COUNT_DTOR(${nativeType});
+                }
+                """)
 
         if self.refcounted:
             if self.parentIface:
-                classImpl = """
-NS_IMPL_CYCLE_COLLECTION_INHERITED_0(${nativeType}, ${parentType})
-NS_IMPL_ADDREF_INHERITED(${nativeType}, ${parentType})
-NS_IMPL_RELEASE_INHERITED(${nativeType}, ${parentType})
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
-NS_INTERFACE_MAP_END_INHERITING(${parentType})
-
-"""
-            else:
-                classImpl = """
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(${nativeType})
-NS_IMPL_CYCLE_COLLECTING_ADDREF(${nativeType})
-NS_IMPL_CYCLE_COLLECTING_RELEASE(${nativeType})
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-"""
-        else:
-            classImpl = ""
-
-        classImpl += """%s
-JSObject*
-${nativeType}::WrapObject(JSContext* aCx)
-{
-  return ${ifaceName}Binding::Wrap(aCx, this);
-}
-
-""" % ctordtor
-        return string.Template(classImpl).substitute({
-            "ifaceName": self.descriptor.name,
-            "nativeType": self.nativeLeafName(self.descriptor),
-            "parentType": self.nativeLeafName(self.parentDesc) if self.parentIface else "",
-        })
+                ccImpl = dedent("""
+
+                    NS_IMPL_CYCLE_COLLECTION_INHERITED_0(${nativeType}, ${parentType})
+                    NS_IMPL_ADDREF_INHERITED(${nativeType}, ${parentType})
+                    NS_IMPL_RELEASE_INHERITED(${nativeType}, ${parentType})
+                    NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
+                    NS_INTERFACE_MAP_END_INHERITING(${parentType})
+
+                    """)
+            else:
+                ccImpl = dedent("""
+
+                    NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(${nativeType})
+                    NS_IMPL_CYCLE_COLLECTING_ADDREF(${nativeType})
+                    NS_IMPL_CYCLE_COLLECTING_RELEASE(${nativeType})
+                    NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
+                      NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+                      NS_INTERFACE_MAP_ENTRY(nsISupports)
+                    NS_INTERFACE_MAP_END
+
+                    """)
+        else:
+            ccImpl = ""
+
+        classImpl = ccImpl + ctordtor + "\n" + dedent("""
+            JSObject*
+            ${nativeType}::WrapObject(JSContext* aCx)
+            {
+              return ${ifaceName}Binding::Wrap(aCx, this);
+            }
+
+            """)
+        return string.Template(classImpl).substitute(
+            ifaceName=self.descriptor.name,
+            nativeType=self.nativeLeafName(self.descriptor),
+            parentType=self.nativeLeafName(self.parentDesc) if self.parentIface else "")
 
     @staticmethod
     def nativeLeafName(descriptor):
         return descriptor.nativeType.split('::')[-1]
 
 
 class CGExampleRoot(CGThing):
     """
@@ -11347,23 +11785,24 @@ class CGExampleRoot(CGThing):
                                ("mozilla/dom/%s" %
                                 CGHeaders.getDeclarationFilename(descriptor.interface)),
                                "nsContentUtils.h"], "", self.root)
 
         # And now some include guards
         self.root = CGIncludeGuard(interfaceName, self.root)
 
         # And our license block comes before everything else
-        self.root = CGWrapper(self.root, pre="""/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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/. */
-
-""")
+        self.root = CGWrapper(self.root, pre=dedent("""
+            /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+            /* vim:set ts=2 sw=2 sts=2 et cindent: */
+            /* 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/. */
+
+            """))
 
     def declare(self):
         return self.root.declare()
 
     def define(self):
         return self.root.define()
 
 
@@ -11417,69 +11856,70 @@ class CGJSImplMethod(CGJSImplMember):
             # Skip the JSCompartment bits for constructors; it's handled
             # manually in getImpl.
             return CGNativeMember.getArgs(self, returnType, argList)
         return CGJSImplMember.getArgs(self, returnType, argList)
 
     def getImpl(self):
         args = self.getArgs(self.signature[0], self.signature[1])
         if not self.isConstructor:
-            return 'return mImpl->%s(%s);' % (self.name, ", ".join(arg.name for arg in args))
+            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.")
         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()
             assert args[0].argType == 'const GlobalObject&'
             assert args[1].argType == 'JSContext*'
             constructorArgs = [arg.name for arg in args[2:]]
             constructorArgs.append("js::GetObjectCompartment(scopeObj)")
-            initCall = """
-// Wrap the object before calling __Init so that __DOM_IMPL__ is available.
-nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(window);
-JS::Rooted<JSObject*> scopeObj(cx, globalHolder->GetGlobalJSObject());
-MOZ_ASSERT(js::IsObjectInContextCompartment(scopeObj, cx));
-JS::Rooted<JS::Value> wrappedVal(cx);
-if (!WrapNewBindingObject(cx, impl, &wrappedVal)) {
-  //XXX Assertion disabled for now, see bug 991271.
-  MOZ_ASSERT(true || JS_IsExceptionPending(cx));
-  aRv.Throw(NS_ERROR_UNEXPECTED);
-  return nullptr;
-}
-// Initialize the object with the constructor arguments.
-impl->mImpl->__Init(%s);
-if (aRv.Failed()) {
-  return nullptr;
-}""" % (", ".join(constructorArgs))
+            initCall = fill(
+                """
+                // Wrap the object before calling __Init so that __DOM_IMPL__ is available.
+                nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(window);
+                JS::Rooted<JSObject*> scopeObj(cx, globalHolder->GetGlobalJSObject());
+                MOZ_ASSERT(js::IsObjectInContextCompartment(scopeObj, cx));
+                JS::Rooted<JS::Value> wrappedVal(cx);
+                if (!WrapNewBindingObject(cx, impl, &wrappedVal)) {
+                  //XXX Assertion disabled for now, see bug 991271.
+                  MOZ_ASSERT(true || JS_IsExceptionPending(cx));
+                  aRv.Throw(NS_ERROR_UNEXPECTED);
+                  return nullptr;
+                }
+                // Initialize the object with the constructor arguments.
+                impl->mImpl->__Init(${args});
+                if (aRv.Failed()) {
+                  return nullptr;
+                }
+                """,
+                args=", ".join(constructorArgs))
         else:
             initCall = ""
         return genConstructorBody(self.descriptor, initCall)
 
 
 def genConstructorBody(descriptor, initCall=""):
-    template = (
-        "JS::Rooted<JSObject*> jsImplObj(cx);\n"
-        "nsCOMPtr<nsPIDOMWindow> window =\n"
-        '  ConstructJSImplementation(cx, "${contractId}", global, &jsImplObj, aRv);\n'
-        "if (aRv.Failed()) {\n"
-        "  return nullptr;\n"
-        "}\n"
-        "// Build the C++ implementation.\n"
-        # Leave off the newline in case initCall is empty.
-        "nsRefPtr<${implClass}> impl = new ${implClass}(jsImplObj, window);"
-        "${initCall}\n"
-        "return impl.forget();")
-
-    return string.Template(template).substitute({
-        "implClass": descriptor.name,
-        "contractId": descriptor.interface.getJSImplementation(),
-        "initCall": initCall
-    })
+    return fill(
+        """
+        JS::Rooted<JSObject*> jsImplObj(cx);
+        nsCOMPtr<nsPIDOMWindow> window =
+          ConstructJSImplementation(cx, "${contractId}", global, &jsImplObj, aRv);
+        if (aRv.Failed()) {
+          return nullptr;
+        }
+        // Build the C++ implementation.
+        nsRefPtr<${implClass}> impl = new ${implClass}(jsImplObj, window);
+        $*{initCall}
+        return impl.forget();
+        """,
+        contractId=descriptor.interface.getJSImplementation(),
+        implClass=descriptor.name,
+        initCall=initCall)
 
 
 # We're always fallible
 def callbackGetterName(attr, descriptor):
     return "Get" + MakeNativeName(
         descriptor.binaryNames.get(attr.identifier.name, attr.identifier.name))
 
 
@@ -11499,17 +11939,17 @@ class CGJSImplGetter(CGJSImplMember):
                                                                    attr),
                                 (attr.type, []),
                                 descriptor.getExtendedAttributes(attr,
                                                                  getter=True),
                                 passJSBitsAsNeeded=False)
 
     def getImpl(self):
         callbackArgs = [arg.name for arg in self.getArgs(self.member.type, [])]
-        return 'return mImpl->%s(%s);' % (
+        return 'return mImpl->%s(%s);\n' % (
             callbackGetterName(self.member, self.descriptorProvider),
             ", ".join(callbackArgs))
 
 
 class CGJSImplSetter(CGJSImplMember):
     """
     Class for generating code for the setters of attributes for a JS-implemented
     WebIDL interface.
@@ -11522,88 +11962,94 @@ class CGJSImplSetter(CGJSImplMember):
                                  [FakeArgument(attr.type, attr)]),
                                 descriptor.getExtendedAttributes(attr,
                                                                  setter=True),
                                 passJSBitsAsNeeded=False)
 
     def getImpl(self):
         callbackArgs = [arg.name for arg in self.getArgs(BuiltinTypes[IDLBuiltinType.Types.void],
                                                          [FakeArgument(self.member.type, self.member)])]
-        return 'mImpl->%s(%s);' % (
+        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)
 
         if descriptor.interface.parent:
             parentClass = descriptor.getDescriptor(
                 descriptor.interface.parent.identifier.name).jsImplParent
             baseClasses = [ClassBase(parentClass)]
-            isupportsDecl = "NS_DECL_ISUPPORTS_INHERITED"
-            ccDecl = ("NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(%s, %s)" %
+            isupportsDecl = "NS_DECL_ISUPPORTS_INHERITED\n"
+            ccDecl = ("NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(%s, %s)\n" %
                       (descriptor.name, parentClass))
-            constructorBody = (
-                "// Make sure we're an nsWrapperCache already\n"
-                "MOZ_ASSERT(static_cast<nsWrapperCache*>(this));\n"
-                "// And that our ancestor has called SetIsDOMBinding()\n"
-                "MOZ_ASSERT(IsDOMBinding());")
-            extradefinitions = string.Template(
-                "NS_IMPL_CYCLE_COLLECTION_INHERITED_2(${ifaceName}, ${parentClass}, mImpl, mParent)\n"
-                "NS_IMPL_ADDREF_INHERITED(${ifaceName}, ${parentClass})\n"
-                "NS_IMPL_RELEASE_INHERITED(${ifaceName}, ${parentClass})\n"
-                "NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(${ifaceName})\n"
-                "NS_INTERFACE_MAP_END_INHERITING(${parentClass})\n"
-            ).substitute({
-                "ifaceName": self.descriptor.name,
-                "parentClass": parentClass
-            })
+            constructorBody = dedent("""
+                // Make sure we're an nsWrapperCache already
+                MOZ_ASSERT(static_cast<nsWrapperCache*>(this));
+                // And that our ancestor has called SetIsDOMBinding()
+                MOZ_ASSERT(IsDOMBinding());
+                """)
+            extradefinitions = fill(
+                """
+                NS_IMPL_CYCLE_COLLECTION_INHERITED_2(${ifaceName}, ${parentClass}, mImpl, mParent)
+                NS_IMPL_ADDREF_INHERITED(${ifaceName}, ${parentClass})
+                NS_IMPL_RELEASE_INHERITED(${ifaceName}, ${parentClass})
+                NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(${ifaceName})
+                NS_INTERFACE_MAP_END_INHERITING(${parentClass})
+                """,
+                ifaceName=self.descriptor.name,
+                parentClass=parentClass)
         else:
             baseClasses = [ClassBase("nsSupportsWeakReference"),
                            ClassBase("nsWrapperCache")]
-            isupportsDecl = "NS_DECL_CYCLE_COLLECTING_ISUPPORTS"
-            ccDecl = ("NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(%s)" %
+            isupportsDecl = "NS_DECL_CYCLE_COLLECTING_ISUPPORTS\n"
+            ccDecl = ("NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(%s)\n" %
                       descriptor.name)
-            constructorBody = "SetIsDOMBinding();"
-            extradefinitions = string.Template(
-                "NS_IMPL_CYCLE_COLLECTION_CLASS(${ifaceName})\n"
-                "NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(${ifaceName})\n"
-                "  NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)\n"
-                "  NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)\n"
-                "  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER\n"
-                "  tmp->ClearWeakReferences();\n"
-                "NS_IMPL_CYCLE_COLLECTION_UNLINK_END\n"
-                "NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(${ifaceName})\n"
-                "  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)\n"
-                "  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)\n"
-                "  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS\n"
-                "NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END\n"
-                "NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(${ifaceName})\n"
-                "NS_IMPL_CYCLE_COLLECTING_ADDREF(${ifaceName})\n"
-                "NS_IMPL_CYCLE_COLLECTING_RELEASE(${ifaceName})\n"
-                "NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${ifaceName})\n"
-                "  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY\n"
-                "  NS_INTERFACE_MAP_ENTRY(nsISupports)\n"
-                "  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)\n"
-                "NS_INTERFACE_MAP_END\n"
-            ).substitute({
-                "ifaceName": self.descriptor.name
-            })
-
-        extradeclarations = (
-            "public:\n"
-            "  %s\n"
-            "  %s\n"
-            "\n"
-            "private:\n"
-            "  nsRefPtr<%s> mImpl;\n"
-            "  nsCOMPtr<nsISupports> mParent;\n"
-            "\n" % (isupportsDecl, ccDecl, jsImplName(descriptor.name)))
+            constructorBody = "SetIsDOMBinding();\n"
+            extradefinitions = fill(
+                """
+                NS_IMPL_CYCLE_COLLECTION_CLASS(${ifaceName})
+                NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(${ifaceName})
+                  NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
+                  NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
+                  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+                  tmp->ClearWeakReferences();
+                NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+                NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(${ifaceName})
+                  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
+                  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
+                  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+                NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+                NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(${ifaceName})
+                NS_IMPL_CYCLE_COLLECTING_ADDREF(${ifaceName})
+                NS_IMPL_CYCLE_COLLECTING_RELEASE(${ifaceName})
+                NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${ifaceName})
+                  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+                  NS_INTERFACE_MAP_ENTRY(nsISupports)
+                  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+                NS_INTERFACE_MAP_END
+                """,
+                ifaceName=self.descriptor.name)
+
+        extradeclarations = fill(
+            """
+            public:
+              $*{isupportsDecl}
+              $*{ccDecl}
+
+            private:
+              nsRefPtr<${jsImplName}> mImpl;
+              nsCOMPtr<nsISupports> mParent;
+
+            """,
+            isupportsDecl=isupportsDecl,
+            ccDecl=ccDecl,
+            jsImplName=jsImplName(descriptor.name))
 
         if descriptor.interface.hasChildInterfaces():
             decorators = ""
             # We need a public virtual destructor our subclasses can use
             destructor = ClassDestructor(virtual=True, visibility="public")
         else:
             decorators = "MOZ_FINAL"
             destructor = None
@@ -11645,73 +12091,77 @@ class CGJSImplClass(CGBindingImplClass):
                          constructors=[constructor],
                          destructor=destructor,
                          methods=self.methodDecls,
                          decorators=decorators,
                          extradeclarations=extradeclarations,
                          extradefinitions=extradefinitions)
 
     def getWrapObjectBody(self):
-        return ("JS::Rooted<JSObject*> obj(aCx, %sBinding::Wrap(aCx, this));\n"
-                "if (!obj) {\n"
-                "  return nullptr;\n"
-                "}\n"
-                "\n"
-                "// Now define it on our chrome object\n"
-                "JSAutoCompartment ac(aCx, mImpl->Callback());\n"
-                "if (!JS_WrapObject(aCx, &obj)) {\n"
-                "  return nullptr;\n"
-                "}\n"
-                'if (!JS_DefineProperty(aCx, mImpl->Callback(), "__DOM_IMPL__", obj, 0)) {\n'
-                "  return nullptr;\n"
-                "}\n"
-                "return obj;" % self.descriptor.name)
+        return fill(
+            """
+            JS::Rooted<JSObject*> obj(aCx, ${name}Binding::Wrap(aCx, this));
+            if (!obj) {
+              return nullptr;
+            }
+
+            // Now define it on our chrome object
+            JSAutoCompartment ac(aCx, mImpl->Callback());
+            if (!JS_WrapObject(aCx, &obj)) {
+              return nullptr;
+            }
+            if (!JS_DefineProperty(aCx, mImpl->Callback(), "__DOM_IMPL__", obj, 0)) {
+              return nullptr;
+            }
+            return obj;
+            """,
+            name=self.descriptor.name)
 
     def getGetParentObjectReturnType(self):
         return "nsISupports*"
 
     def getGetParentObjectBody(self):
-        return "return mParent;"
+        return "return mParent;\n"
 
     def getCreateFromExistingBody(self):
         # XXXbz we could try to get parts of this (e.g. the argument
         # conversions) auto-generated by somehow creating an IDLMethod and
         # adding it to our interface, but we'd still need to special-case the
         # implementation slightly to have it not try to forward to the JS
         # object...
-        return string.Template(
-            "JS::CallArgs args = JS::CallArgsFromVp(argc, vp);\n"
-            "if (args.length() < 2) {\n"
-            '  return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "${ifaceName}._create");\n'
-            "}\n"
-            "if (!args[0].isObject()) {\n"
-            '  return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of ${ifaceName}._create");\n'
-            "}\n"
-            "if (!args[1].isObject()) {\n"
-            '  return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of ${ifaceName}._create");\n'
-            "}\n"
-            "\n"
-            "// GlobalObject will go through wrappers as needed for us, and\n"
-            "// is simpler than the right UnwrapArg incantation.\n"
-            "GlobalObject global(cx, &args[0].toObject());\n"
-            "if (global.Failed()) {\n"
-            "  return false;\n"
-            "}\n"
-            "nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(global.GetAsSupports());\n"
-            "if (!window) {\n"
-            '  return ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of ${ifaceName}._create", "Window");\n'
-            "}\n"
-            "JS::Rooted<JSObject*> arg(cx, &args[1].toObject());\n"
-            "nsRefPtr<${implName}> impl = new ${implName}(arg, window);\n"
-            "MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));\n"
-            "return WrapNewBindingObject(cx, impl, args.rval());"
-        ).substitute({
-            "ifaceName": self.descriptor.interface.identifier.name,
-            "implName": self.descriptor.name
-        })
+        return fill(
+            """
+            JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+            if (args.length() < 2) {
+              return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "${ifaceName}._create");
+            }
+            if (!args[0].isObject()) {
+              return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of ${ifaceName}._create");
+            }
+            if (!args[1].isObject()) {
+              return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of ${ifaceName}._create");
+            }
+
+            // GlobalObject will go through wrappers as needed for us, and
+            // is simpler than the right UnwrapArg incantation.
+            GlobalObject global(cx, &args[0].toObject());
+            if (global.Failed()) {
+              return false;
+            }
+            nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(global.GetAsSupports());
+            if (!window) {
+              return ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of ${ifaceName}._create", "Window");
+            }
+            JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
+            nsRefPtr<${implName}> impl = new ${implName}(arg, window);
+            MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
+            return WrapNewBindingObject(cx, impl, args.rval());
+            """,
+            ifaceName=self.descriptor.interface.identifier.name,
+            implName=self.descriptor.name)
 
 
 def isJSImplementedDescriptor(descriptorProvider):
     return (isinstance(descriptorProvider, Descriptor) and
             descriptorProvider.interface.isJSImplemented())
 
 
 class CGCallback(CGClass):
@@ -11735,26 +12185,26 @@ class CGCallback(CGClass):
                 realMethods.append(method)
             else:
                 realMethods.extend(self.getMethodImpls(method))
         realMethods.append(
             ClassMethod("operator==", "bool",
                         [Argument("const %s&" % name, "aOther")],
                         inline=True, bodyInHeader=True,
                         const=True,
-                        body=("return %s::operator==(aOther);" % baseName)))
+                        body=("return %s::operator==(aOther);\n" % baseName)))
         CGClass.__init__(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):
-            body = "MOZ_ASSERT(JS_ObjectIsCallable(nullptr, mCallback));"
+            body = "MOZ_ASSERT(JS_ObjectIsCallable(nullptr, mCallback));\n"
         else:
             # Not much we can assert about it, other than not being null, and
             # CallbackObject does that already.
             body = ""
         return [ClassConstructor(
             [Argument("JS::Handle<JSObject*>", "aCallback"),
              Argument("nsIGlobalObject*", "aIncumbentGlobal")],
             bodyInHeader=True,
@@ -11781,47 +12231,55 @@ class CGCallback(CGClass):
         # Now that we've recorded the argnames for our call to our private
         # method, insert our optional argument for deciding whether the
         # CallSetup should re-throw exceptions on aRv.
         args.append(Argument("ExceptionHandling", "aExceptionHandling",
                              "eReportExceptions"))
         # And now insert our template argument.
         argsWithoutThis = list(args)
         args.insert(0, Argument("const T&",  "thisObjPtr"))
-
-        setupCall = ("CallSetup s(this, aRv, aExceptionHandling);\n"
-                     "if (!s.GetContext()) {\n"
-                     "  aRv.Throw(NS_ERROR_UNEXPECTED);\n"
-                     "  return${errorReturn};\n"
-                     "}\n")
-
-        bodyWithThis = string.Template(
-            setupCall +
-            "JS::Rooted<JSObject*> thisObjJS(s.GetContext(),\n"
-            "  WrapCallThisObject(s.GetContext(), thisObjPtr));\n"
-            "if (!thisObjJS) {\n"
-            "  aRv.Throw(NS_ERROR_FAILURE);\n"
-            "  return${errorReturn};\n"
-            "}\n"
-            "JS::Rooted<JS::Value> thisValJS(s.GetContext(),\n"
-            "                                JS::ObjectValue(*thisObjJS));\n"
-            "return ${methodName}(${callArgs});"
-        ).substitute({
-            "errorReturn": method.getDefaultRetval(),
-            "callArgs": ", ".join(argnamesWithThis),
-            "methodName": method.name,
-        })
-        bodyWithoutThis = string.Template(
-            setupCall +
-            "return ${methodName}(${callArgs});"
-        ).substitute({
-            "errorReturn": method.getDefaultRetval(),
-            "callArgs": ", ".join(argnamesWithoutThis),
-            "methodName": method.name,
-        })
+        errorReturn = method.getDefaultRetval()
+
+        setupCall = fill(
+            """
+            CallSetup s(this, aRv, aExceptionHandling);
+            if (!s.GetContext()) {
+              aRv.Throw(NS_ERROR_UNEXPECTED);
+              return${errorReturn};
+            }
+            """,
+            errorReturn=errorReturn)
+
+        bodyWithThis = fill(
+            """
+            $*{setupCall}
+            JS::Rooted<JSObject*> thisObjJS(s.GetContext(),
+              WrapCallThisObject(s.GetContext(), thisObjPtr));
+            if (!thisObjJS) {
+              aRv.Throw(NS_ERROR_FAILURE);
+              return${errorReturn};
+            }
+            JS::Rooted<JS::Value> thisValJS(s.GetContext(),
+                                            JS::ObjectValue(*thisObjJS));
+            return ${methodName}(${callArgs});
+            """,
+            setupCall=setupCall,
+            errorReturn=errorReturn,
+            methodName=method.name,
+            callArgs=", ".join(argnamesWithThis))
+        bodyWithoutThis = fill(
+            """
+            $*{setupCall}
+            return ${methodName}(${callArgs});
+            """,
+            setupCall=setupCall,
+            errorReturn=errorReturn,
+            methodName=method.name,
+            callArgs=", ".join(argnamesWithoutThis))
+
         return [ClassMethod(method.name, method.returnType, args,
                             bodyInHeader=True,
                             templateArgs=["typename T"],
                             body=bodyWithThis),
                 ClassMethod(method.name, method.returnType, argsWithoutThis,
                             bodyInHeader=True,
                             body=bodyWithoutThis),
                 method]
@@ -11921,49 +12379,41 @@ class CallbackMember(CGNativeMember):
                                 name, (self.retvalType, args),
                                 extendedAttrs={},
                                 passJSBitsAsNeeded=False,
                                 visibility=visibility,
                                 jsObjectsArePtr=True)
         # We have to do all the generation of our body now, because
         # the caller relies on us throwing if we can't manage it.
         self.exceptionCode = ("aRv.Throw(NS_ERROR_UNEXPECTED);\n"
-                              "return%s;" % self.getDefaultRetval())
+                              "return%s;\n" % self.getDefaultRetval())
         self.body = self.getImpl()
 
     def getImpl(self):
-        replacements = {
-            "declRval": self.getRvalDecl(),
-            "errorReturn": self.getDefaultRetval(),
-            "returnResult": self.getResultConversion(),
-            "convertArgs": self.getArgConversions(),
-            "doCall": self.getCall(),
-            "setupCall": self.getCallSetup(),
-        }
+        setupCall = self.getCallSetup()
+        declRval = self.getRvalDecl()
         if self.argCount > 0:
-            replacements["argCount"] = self.argCountStr
-            replacements["argvDecl"] = string.Template(
-                "JS::AutoValueVector argv(cx);\n"
-                "if (!argv.resize(${argCount})) {\n"
-                "  aRv.Throw(NS_ERROR_OUT_OF_MEMORY);\n"
-                "  return${errorReturn};\n"
-                "}\n"
-            ).substitute(replacements)
+            argvDecl = fill(
+                """
+                JS::AutoValueVector argv(cx);
+                if (!argv.resize(${argCount})) {
+                  aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
+                  return${errorReturn};
+                }
+                """,
+                argCount=self.argCountStr,
+                errorReturn=self.getDefaultRetval())
         else:
             # Avoid weird 0-sized arrays
-            replacements["argvDecl"] = ""
-
-        return string.Template(
-            # Newlines and semicolons are in the values
-            "${setupCall}"
-            "${declRval}"
-            "${argvDecl}"
-            "${convertArgs}"
-            "${doCall}"
-            "${returnResult}").substitute(replacements)
+            argvDecl = ""
+        convertArgs = self.getArgConversions()
+        doCall = self.getCall()
+        returnResult = self.getResultConversion()
+
+        return setupCall + declRval + argvDecl + convertArgs + doCall + returnResult
 
     def getResultConversion(self):
         replacements = {
             "val": "rval",
             "mutableVal": "&rval",
             "holderName": "rvalHolder",
             "declName": "rvalDecl",
             # We actually want to pass in a null scope object here, because
@@ -11982,37 +12432,45 @@ class CallbackMember(CGNativeMember):
                                         self.descriptorProvider,
                                         exceptionCode=self.exceptionCode,
                                         isCallbackReturnValue=isCallbackReturnValue,
                                         sourceDescription=sourceDescription),
             replacements)
         assignRetval = string.Template(
             self.getRetvalInfo(self.retvalType,
                                False)[2]).substitute(replacements)
-        return convertType.define() + "\n" + assignRetval
+        type = convertType.define()
+        if type == "":
+            type = "\n"  # BOGUS extra blank line
+        if assignRetval == "":
+            assignRetval = "\n"  # BOGUS extra blank line
+        return type + assignRetval
 
     def getArgConversions(self):
         # Just reget the arglist from self.originalSig, because our superclasses
         # just have way to many members they like to clobber, so I can't find a
         # safe member name to store it in.
         argConversions = [self.getArgConversion(i, arg) for (i, arg)
                           in enumerate(self.originalSig[1])]
+        if not argConversions:
+            return "\n\n"  # BOGUS extra blank line
+
         # Do them back to front, so our argc modifications will work
         # correctly, because we examine trailing arguments first.
         argConversions.reverse()
         # Wrap each one in a scope so that any locals it has don't leak out, and
         # also so that we can just "break;" for our successCode.
         argConversions = [CGWrapper(CGIndenter(CGGeneric(c)),
                                     pre="do {\n",
-                                    post="\n} while (0);")
+                                    post="} while (0);\n")
                           for c in argConversions]
         if self.argCount > 0:
             argConversions.insert(0, self.getArgcDecl())
         # And slap them together.
-        return CGList(argConversions, "\n\n").define() + "\n\n"
+        return CGList(argConversions, "\n").define() + "\n"
 
     def getArgConversion(self, i, arg):
         argval = arg.identifier.name
 
         if arg.variadic:
             argval = argval + "[idx]"
             jsvalIndex = "%d + idx" % i
         else:
@@ -12029,47 +12487,57 @@ class CallbackMember(CGNativeMember):
             result = argval
             prepend = ""
 
         try:
             conversion = prepend + wrapForType(
                 arg.type, self.descriptorProvider,
                 {
                     'result': result,
-                    'successCode': "continue;" if arg.variadic else "break;",
+                    'successCode': "continue;\n" if arg.variadic else "break;\n",
                     'jsvalRef': "argv.handleAt(%s)" % jsvalIndex,
                     'jsvalHandle': "argv.handleAt(%s)" % jsvalIndex,
                     # XXXbz we don't have anything better to use for 'obj',
                     # really...  It's OK to use CallbackPreserveColor because
                     # CallSetup already handled the unmark-gray bits for us.
                     'obj': 'CallbackPreserveColor()',
                     'returnsNewObject': False,
                     'exceptionCode': self.exceptionCode
                 })
         except MethodNotNewObjectError as err:
             raise TypeError("%s being passed as an argument to %s but is not "
                             "wrapper cached, so can't be reliably converted to "
                             "a JS object." %
                             (err.typename, self.getPrettyName()))
         if arg.variadic:
-            conversion = string.Template(
-                "for (uint32_t idx = 0; idx < ${arg}.Length(); ++idx) {\n" +
-                CGIndenter(CGGeneric(conversion)).define() + "\n"
-                "}\n"
-                "break;").substitute({"arg": arg.identifier.name})
+            conversion = fill(
+                """
+                for (uint32_t idx = 0; idx < ${arg}.Length(); ++idx) {
+                  $*{conversion}
+                }
+                break;
+                """,
+                arg=arg.identifier.name,
+                conversion=conversion)
         elif arg.optional and not arg.defaultValue:
-            conversion = (
-                CGIfWrapper(CGGeneric(conversion),
-                            "%s.WasPassed()" % arg.identifier.name).define() +
-                " else if (argc == %d) {\n"
-                "  // This is our current trailing argument; reduce argc\n"
-                "  --argc;\n"
-                "} else {\n"
-                "  argv[%d] = JS::UndefinedValue();\n"
-                "}" % (i+1, i))
+            conversion = fill(
+                """
+                if (${argName}.WasPassed()) {
+                  $*{conversion}
+                } else if (argc == ${iPlus1}) {
+                  // This is our current trailing argument; reduce argc
+                  --argc;
+                } else {
+                  argv[${i}] = JS::UndefinedValue();
+                }
+                """,
+                argName=arg.identifier.name,
+                conversion=conversion,
+                iPlus1=i + 1,
+                i=i)
         return conversion
 
     def getDefaultRetval(self):
         default = self.getRetvalInfo(self.retvalType, False)[1]
         if len(default) != 0:
             default = " " + default
         return default
 
@@ -12096,31 +12564,31 @@ class CallbackMember(CGNativeMember):
         callSetup = "CallSetup s(this, aRv"
         if self.rethrowContentException:
             # getArgs doesn't add the aExceptionHandling argument but does add
             # aCompartment for us.
             callSetup += ", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ "
             callSetup += toStringBool(isJSImplementedDescriptor(self.descriptorProvider))
         else:
             callSetup += ", aExceptionHandling"
-        callSetup += ");"
-        return string.Template(
-            "${callSetup}\n"
-            "JSContext* cx = s.GetContext();\n"
-            "if (!cx) {\n"
-            "  aRv.Throw(NS_ERROR_UNEXPECTED);\n"
-            "  return${errorReturn};\n"
-            "}\n"
-        ).substitute({
-            "callSetup": callSetup,
-            "errorReturn": self.getDefaultRetval(),
-        })
+        callSetup += ");\n"
+        return fill(
+            """
+            $*{callSetup}
+            JSContext* cx = s.GetContext();
+            if (!cx) {
+              aRv.Throw(NS_ERROR_UNEXPECTED);
+              return${errorReturn};
+            }
+            """,
+            callSetup=callSetup,
+            errorReturn=self.getDefaultRetval())
 
     def getArgcDecl(self):
-        return CGGeneric("unsigned argc = %s;" % self.argCountStr)
+        return CGGeneric("unsigned argc = %s;\n" % self.argCountStr)
 
     @staticmethod
     def ensureASCIIName(idlObject):
         type = "attribute" if idlObject.isAttr() else "operation"
         if re.match("[^\x20-\x7E]", idlObject.identifier.name):
             raise SyntaxError('Callback %s name "%s" contains non-ASCII '
                               "characters.  We can't handle that.  %s" %
                               (type, idlObject.identifier.name,
@@ -12138,35 +12606,37 @@ class CallbackMethod(CallbackMember):
                  rethrowContentException=False):
         CallbackMember.__init__(self, sig, name, descriptorProvider,
                                 needThisHandling, rethrowContentException)
 
     def getRvalDecl(self):
         return "JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());\n"
 
     def getCall(self):
-        replacements = {
-            "errorReturn": self.getDefaultRetval(),
-            "declThis": self.getThisDecl(),
-            "thisVal": self.getThisVal(),
-            "declCallable": self.getCallableDecl(),
-            "callGuard": self.getCallGuard()
-            }
         if self.argCount > 0:
-            replacements["args"] = "JS::HandleValueArray::subarray(argv, 0, argc)"
-        else:
-            replacements["args"] = "JS::HandleValueArray::empty()"
-        return string.Template(
-            "${declCallable}${declThis}"
-            "if (${callGuard}!JS::Call(cx, ${thisVal}, callable,\n"
-            "              ${args}, &rval)) {\n"
-            "  aRv.Throw(NS_ERROR_UNEXPECTED);\n"
-            "  return${errorReturn};\n"
-            "}\n"
-        ).substitute(replacements)
+            args = "JS::HandleValueArray::subarray(argv, 0, argc)"
+        else:
+            args = "JS::HandleValueArray::empty()"
+
+        return fill(
+            """
+            $*{declCallable}
+            $*{declThis}
+            if (${callGuard}!JS::Call(cx, ${thisVal}, callable,
+                          ${args}, &rval)) {
+              aRv.Throw(NS_ERROR_UNEXPECTED);
+              return${errorReturn};
+            }
+            """,
+            declCallable=self.getCallableDecl(),
+            declThis=self.getThisDecl(),
+            callGuard=self.getCallGuard(),
+            thisVal=self.getThisVal(),
+            args=args,
+            errorReturn=self.getDefaultRetval())
 
 
 class CallCallback(CallbackMethod):
     def __init__(self, callback, descriptorProvider):
         self.callback = callback
         CallbackMethod.__init__(self, callback.signatures()[0], "Call",
                                 descriptorProvider, needThisHandling=True)
 
@@ -12198,44 +12668,47 @@ class CallbackOperationBase(CallbackMeth
         CallbackMethod.__init__(self, signature, nativeName, descriptor, singleOperation, rethrowContentException)
 
     def getThisDecl(self):
         if not self.singleOperation:
             return "JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));\n"
         # This relies on getCallableDecl declaring a boolean
         # isCallable in the case when we're a single-operation
         # interface.
-        return (
-            'JS::Rooted<JS::Value> thisValue(cx, isCallable ? aThisVal.get()\n'
-            '                                               : JS::ObjectValue(*mCallback));\n')
+        return dedent("""
+            JS::Rooted<JS::Value> thisValue(cx, isCallable ? aThisVal.get()
+                                                           : JS::ObjectValue(*mCallback));
+            """)
 
     def getThisVal(self):
         return "thisValue"
 
     def getCallableDecl(self):
-        replacements = {
-            "errorReturn": self.getDefaultRetval(),
-            "methodName": self.methodName
-        }
-        getCallableFromProp = string.Template(
-            'if (!GetCallableProperty(cx, "${methodName}", &callable)) {\n'
-            '  aRv.Throw(NS_ERROR_UNEXPECTED);\n'
-            '  return${errorReturn};\n'
-            '}\n'
-        ).substitute(replacements)
+        getCallableFromProp = fill(
+            """
+            if (!GetCallableProperty(cx, "${methodName}", &callable)) {
+              aRv.Throw(NS_ERROR_UNEXPECTED);
+              return${errorReturn};
+            }
+            """,
+            methodName=self.methodName,
+            errorReturn=self.getDefaultRetval())
         if not self.singleOperation:
             return 'JS::Rooted<JS::Value> callable(cx);\n' + getCallableFromProp
-        return (
-            'bool isCallable = JS_ObjectIsCallable(cx, mCallback);\n'
-            'JS::Rooted<JS::Value> callable(cx);\n'
-            'if (isCallable) {\n'
-            '  callable = JS::ObjectValue(*mCallback);\n'
-            '} else {\n'
-            '%s'
-            '}\n' % CGIndenter(CGGeneric(getCallableFromProp)).define())
+        return fill(
+            """
+            bool isCallable = JS_ObjectIsCallable(cx, mCallback);
+            JS::Rooted<JS::Value> callable(cx);
+            if (isCallable) {
+              callable = JS::ObjectValue(*mCallback);
+            } else {
+              $*{getCallableFromProp}
+            }
+            """,
+            getCallableFromProp=getCallableFromProp)
 
     def getCallGuard(self):
         return ""
 
 
 class CallbackOperation(CallbackOperationBase):
     """
     Codegen actual WebIDL operations on callback interfaces.
@@ -12277,55 +12750,53 @@ class CallbackGetter(CallbackAccessor):
                                   (attr.type, []),
                                   callbackGetterName(attr, descriptor),
                                   descriptor)
 
     def getRvalDecl(self):
         return "JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());\n"
 
     def getCall(self):
-        replacements = {
-            "errorReturn": self.getDefaultRetval(),
-            "attrName": self.descriptorProvider.binaryNames.get(self.attrName,
-                                                                self.attrName)
-        }
-        return string.Template(
-            'JS::Rooted<JSObject *> callback(cx, mCallback);\n'
-            'if (!JS_GetProperty(cx, callback, "${attrName}", &rval)) {\n'
-            '  aRv.Throw(NS_ERROR_UNEXPECTED);\n'
-            '  return${errorReturn};\n'
-            '}\n'
-        ).substitute(replacements)
+        return fill(
+            """
+            JS::Rooted<JSObject *> callback(cx, mCallback);
+            if (!JS_GetProperty(cx, callback, "${attrName}", &rval)) {
+              aRv.Throw(NS_ERROR_UNEXPECTED);
+              return${errorReturn};
+            }
+            """,
+            attrName=self.descriptorProvider.binaryNames.get(self.attrName,
+                                                             self.attrName),
+            errorReturn=self.getDefaultRetval())
 
 
 class CallbackSetter(CallbackAccessor):
     def __init__(self, attr, descriptor):
         CallbackAccessor.__init__(self, attr,
                                   (BuiltinTypes[IDLBuiltinType.Types.void],
                                    [FakeArgument(attr.type, attr)]),
                                   callbackSetterName(attr, descriptor),
                                   descriptor)
 
     def getRvalDecl(self):
         # We don't need an rval
         return ""
 
     def getCall(self):
-        replacements = {
-            "errorReturn": self.getDefaultRetval(),
-            "attrName": self.descriptorProvider.binaryNames.get(self.attrName,
-                                                                self.attrName),
-            "argv": "argv.handleAt(0)"
-        }
-        return string.Template(
-            'MOZ_ASSERT(argv.length() == 1);\n'
-            'if (!JS_SetProperty(cx, CallbackPreserveColor(), "${attrName}", ${argv})) {\n'
-            '  aRv.Throw(NS_ERROR_UNEXPECTED);\n'
-            '  return${errorReturn};\n'
-            '}\n').substitute(replacements)
+        return fill(
+            """
+            MOZ_ASSERT(argv.length() == 1);
+            if (!JS_SetProperty(cx, CallbackPreserveColor(), "${attrName}", argv.handleAt(0))) {
+              aRv.Throw(NS_ERROR_UNEXPECTED);
+              return${errorReturn};
+            }
+            """,
+            attrName=self.descriptorProvider.binaryNames.get(self.attrName,
+                                                             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.
@@ -12458,29 +12929,29 @@ 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)
 
-        traitsDecls = [CGGeneric(declare="""
-template <prototypes::ID PrototypeID>
-struct PrototypeTraits;
-""")]
+        traitsDecls = [CGGeneric(declare=dedent("""
+            template <prototypes::ID PrototypeID>
+            struct PrototypeTraits;
+            """))]
         traitsDecls.extend(CGPrototypeTraitsClass(d) for d in descriptorsWithPrototype)
 
         ifaceNamesWithProto = [d.interface.identifier.name
                                for d in descriptorsWithPrototype]
         traitsDecls.append(CGStringTable("NamesOfInterfacesWithProtos",
                                          ifaceNamesWithProto))
 
         traitsDecl = CGNamespace.build(['mozilla', 'dom'],
-                                       CGList(traitsDecls, "\n"))
+                                       CGList(traitsDecls))
 
         curr.append(traitsDecl)
 
         # Add include guards.
         curr = CGIncludeGuard('PrototypeList', curr)
 
         # Add the auto-generated comment.
         curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
@@ -12619,31 +13090,37 @@ class CGEventGetter(CGNativeMember):
         if self.member.isStatic():
             raise TypeError("Event code generators does not support static attributes")
         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.isGeckoInterface():
-            return "return " + memberName + ";"
+            return "return " + memberName + ";\n"
         if type.isDOMString() or type.isByteString():
-            return "aRetVal = " + memberName + ";"
+            return "aRetVal = " + memberName + ";\n"
         if type.isSpiderMonkeyInterface() or type.isObject():
-            ret = "if (%s) {\n" % memberName
-            ret += "  JS::ExposeObjectToActiveJS(%s);\n" % memberName
-            ret += "}\n"
-            ret += "return " + memberName + ";"
-            return ret
+            return fill(
+                """
+                if (${memberName}) {
+                  JS::ExposeObjectToActiveJS(${memberName});
+                }
+                return ${memberName};
+                """,
+                memberName=memberName)
         if type.isAny():
-            ret = "JS::ExposeValueToActiveJS(" + memberName + ");\n"
-            ret += "return " + memberName + ";"
-            return ret
+            return fill(
+                """
+                JS::ExposeValueToActiveJS(${memberName});
+                return ${memberName};
+                """,
+                memberName=memberName)
         if type.isUnion():
-            return "aRetVal = " + memberName + ";"
+            return "aRetVal = " + memberName + ";\n"
         raise TypeError("Event code generator does not support this type!")
 
     def declare(self, cgClass):
         if getattr(self.member, "originatingInterface",
                    cgClass.descriptor.interface) != cgClass.descriptor.interface:
             return ""
         return CGNativeMember.declare(self, cgClass)
 
@@ -12713,39 +13190,42 @@ class CGEventMethod(CGNativeMember):
                                cgClass.descriptor.interface).identifier.name == "Event":
                         continue
                     name = CGDictionary.makeMemberName(m.identifier.name)
                     members += "e->%s = %s.%s;\n" % (name, self.args[1].name, name)
                     if m.type.isAny() or m.type.isObject() or m.type.isSpiderMonkeyInterface():
                         holdJS = "mozilla::HoldJSObjects(e.get());\n"
             iface = iface.parent
 
-        self.body = (
-            "nsRefPtr<${nativeType}> e = new ${nativeType}(aOwner);\n"
-            "bool trusted = e->Init(aOwner);\n"
-            "e->InitEvent(${eventType}, ${eventInit}.mBubbles, ${eventInit}.mCancelable);\n"
-            "${members}"
-            "e->SetTrusted(trusted);\n"
-            "${holdJS}"
-            "return e.forget();")
-        self.body = string.Template(self.body).substitute(
-            {
-                "nativeType": self.descriptorProvider.nativeType.split('::')[-1],
-                "eventType": self.args[0].name,
-                "eventInit": self.args[1].name,
-                "members": members,
-                "holdJS": holdJS
-            })
+        self.body = fill(
+            """
+            nsRefPtr<${nativeType}> e = new ${nativeType}(aOwner);
+            bool trusted = e->Init(aOwner);
+            e->InitEvent(${eventType}, ${eventInit}.mBubbles, ${eventInit}.mCancelable);
+            $*{members}
+            e->SetTrusted(trusted);
+            $*{holdJS}
+            return e.forget();
+            """,
+            nativeType=self.descriptorProvider.nativeType.split('::')[-1],
+            eventType=self.args[0].name,
+            eventInit=self.args[1].name,
+            members=members,
+            holdJS=holdJS)
 
         self.args.insert(0, Argument("mozilla::dom::EventTarget*", "aOwner"))
         constructorForNativeCaller = CGNativeMember.define(self, cgClass) + "\n"
         self.args = list(self.originalArgs)
-        self.body = (
-            "nsCOMPtr<mozilla::dom::EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());\n"
-            "return Constructor(owner, %s, %s);" % (self.args[0].name, self.args[1].name))
+        self.body = fill(
+            """
+            nsCOMPtr<mozilla::dom::EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
+            return Constructor(owner, ${arg0}, ${arg1});
+            """,
+            arg0=self.args[0].name,
+            arg1=self.args[1].name)
         if needCx(None, self.descriptorProvider.interface.members, [], True):
             self.args.insert(0, Argument("JSContext*", "aCx"))
         self.args.insert(0, Argument("const GlobalObject&", "aGlobal"))
         self.args.append(Argument('ErrorResult&', 'aRv'))
         return constructorForNativeCaller + CGNativeMember.define(self, cgClass)
 
 
 class CGEventClass(CGBindingImplClass):
@@ -12796,46 +13276,45 @@ class CGEventClass(CGBindingImplClass):
                                     m.type)
                 members.append(ClassMember(CGDictionary.makeMemberName(m.identifier.name),
                                nativeType,
                                visibility="private",
                                body="body"))
 
         parent = self.descriptor.interface.parent
         self.parentType = self.descriptor.getDescriptor(parent.identifier.name).nativeType.split('::')[-1]
-        baseDeclarations = (
-            "public:\n"
-            "  NS_DECL_ISUPPORTS_INHERITED\n"
-            "  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(${nativeType}, ${parentType})\n"
-            "  virtual ~${nativeType}();\n"
-            "protected:\n"
-            "  ${nativeType}(mozilla::dom::EventTarget* aOwner);\n\n")
-
-        baseDeclarations = string.Template(baseDeclarations).substitute(
-            {
-                "nativeType": self.descriptor.nativeType.split('::')[-1],
-                "parentType": self.parentType
-            })
+        baseDeclarations = fill(
+            """
+            public:
+              NS_DECL_ISUPPORTS_INHERITED
+              NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(${nativeType}, ${parentType})
+              virtual ~${nativeType}();
+            protected:
+              ${nativeType}(mozilla::dom::EventTarget* aOwner);
+
+            """,
+            nativeType=self.descriptor.nativeType.split('::')[-1],
+            parentType=self.parentType)
 
         className = descriptor.nativeType.split('::')[-1]
         asConcreteTypeMethod = ClassMethod("As%s" % className,
                                            "%s*" % className,
                                            [],
                                            virtual=True,
-                                           body="return this;",
+                                           body="return this;\n",
                                            breakAfterReturnDecl=" ")
 
         CGClass.__init__(self, className,
                          bases=[ClassBase(self.parentType)],
                          methods=[asConcreteTypeMethod]+self.methodDecls,
                          members=members,
                          extradeclarations=baseDeclarations)
 
     def getWrapObjectBody(self):
-        return "return %sBinding::Wrap(aCx, this);" % self.descriptor.name
+        return "return %sBinding::Wrap(aCx, this);\n" % self.descriptor.name
 
     def implTraverse(self):
         retVal = ""
         for m in self.descriptor.interface.members:
             if m.isAttr() and m.type.isGeckoInterface():
                 retVal += ("  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(" +
                            CGDictionary.makeMemberName(m.identifier.name) +
                            ")\n")
@@ -12869,77 +13348,83 @@ class CGEventClass(CGBindingImplClass):
         return retVal
 
     def define(self):
         dropJS = ""
         for m in self.descriptor.interface.members:
             if m.isAttr():
                 member = CGDictionary.makeMemberName(m.identifier.name)
                 if m.type.isAny():
-                    dropJS += "  " + member + " = JS::UndefinedValue();\n"
+                    dropJS += member + " = JS::UndefinedValue();\n"
                 elif m.type.isObject() or m.type.isSpiderMonkeyInterface():
-                    dropJS += "  " + member + " = nullptr;\n"
+                    dropJS += member + " = nullptr;\n"
         if dropJS != "":
-            dropJS += "  mozilla::DropJSObjects(this);\n"
+            dropJS += "mozilla::DropJSObjects(this);\n"
         # Just override CGClass and do our own thing
         nativeType = self.descriptor.nativeType.split('::')[-1]
         ctorParams = ("aOwner, nullptr, nullptr" if self.parentType == "Event"
                       else "aOwner")
-        classImpl = """
-NS_IMPL_CYCLE_COLLECTION_CLASS(${nativeType})
-
-NS_IMPL_ADDREF_INHERITED(${nativeType}, ${parentType})
-NS_IMPL_RELEASE_INHERITED(${nativeType}, ${parentType})
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(${nativeType}, ${parentType})
-${traverse}NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(${nativeType}, ${parentType})
-${trace}NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(${nativeType}, ${parentType})
-${unlink}NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(${nativeType})
-NS_INTERFACE_MAP_END_INHERITING(${parentType})
-
-${nativeType}::${nativeType}(mozilla::dom::EventTarget* aOwner)
-  : ${parentType}(${ctorParams})
-{
-}
-
-${nativeType}::~${nativeType}()
-{
-${dropJS}}
-
-"""
-        return string.Template(classImpl).substitute({
-            "ifaceName": self.descriptor.name,
-            "nativeType": nativeType,
-            "ctorParams": ctorParams,
-            "parentType": self.parentType,
-            "traverse": self.implTraverse(),
-            "unlink": self.implUnlink(),
-            "trace": self.implTrace(),
-            "dropJS": dropJS
-        }) + CGBindingImplClass.define(self)
+
+        classImpl = fill(
+            """
+
+            NS_IMPL_CYCLE_COLLECTION_CLASS(${nativeType})
+
+            NS_IMPL_ADDREF_INHERITED(${nativeType}, ${parentType})
+            NS_IMPL_RELEASE_INHERITED(${nativeType}, ${parentType})
+
+            NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(${nativeType}, ${parentType})
+            $*{traverse}
+            NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+            NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(${nativeType}, ${parentType})
+            $*{trace}
+            NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
+            NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(${nativeType}, ${parentType})
+            $*{unlink}
+            NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+            NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(${nativeType})
+            NS_INTERFACE_MAP_END_INHERITING(${parentType})
+
+            ${nativeType}::${nativeType}(mozilla::dom::EventTarget* aOwner)
+              : ${parentType}(${ctorParams})
+            {
+            }
+
+            ${nativeType}::~${nativeType}()
+            {
+              $*{dropJS}
+            }
+
+            """,
+            ifaceName=self.descriptor.name,
+            nativeType=nativeType,
+            ctorParams=ctorParams,
+            parentType=self.parentType,
+            traverse=self.implTraverse(),
+            unlink=self.implUnlink(),
+            trace=self.implTrace(),
+            dropJS=dropJS)
+        return classImpl + CGBindingImplClass.define(self)
 
 
 class CGEventRoot(CGThing):
     def __init__(self, config, interfaceName):
         # Let's assume we're not doing workers stuff, for now
         descriptor = config.getDescriptor(interfaceName, False)
 
         self.root = CGWrapper(CGEventClass(descriptor),
                               pre="\n", post="\n")
 
         self.root = CGNamespace.build(["mozilla", "dom"], self.root)
 
         self.root = CGList([CGClassForwardDeclare("JSContext", isStruct=True),
-                            self.root], "\n")
+                            self.root])
 
         parent = descriptor.interface.parent.identifier.name
 
         # Throw in our #includes
         self.root = CGHeaders([descriptor], [], [], [],
                               [
                                   config.getDescriptor(parent, False).headerFile,
                                   "mozilla/Attributes.h",
@@ -12955,21 +13440,22 @@ class CGEventRoot(CGThing):
                               ],
                               "", self.root)
 
         # And now some include guards
         self.root = CGIncludeGuard(interfaceName, self.root)
 
         self.root = CGWrapper(self.root, pre=AUTOGENERATED_WARNING_COMMENT)
 
-        self.root = CGWrapper(self.root, pre="""/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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/. */
-
-""")
+        self.root = CGWrapper(self.root, pre=dedent("""
+            /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+            /* vim:set ts=2 sw=2 sts=2 et cindent: */
+            /* 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/. */
+
+            """))
 
     def declare(self):
         return self.root.declare()
 
     def define(self):
         return self.root.define()