Backed out changeset 3a0940f90455
authorKyle Huey <khuey@kylehuey.com>
Wed, 04 Apr 2012 13:42:12 -0700
changeset 90980 869edbbfad81
parent 90979 3a0940f90455
child 90981 ed9cbe6a817e
push id22406
push userkhuey@mozilla.com
push dateWed, 04 Apr 2012 20:42:18 +0000
treeherdermozilla-central@869edbbfad81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone14.0a1
backs out3a0940f90455
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
Backed out changeset 3a0940f90455
client.py
dom/bindings/parser/WebIDL.py
dom/bindings/parser/__init__.py
dom/bindings/parser/runtests.py
dom/bindings/parser/tests/test_array_of_interface.py
dom/bindings/parser/tests/test_builtin_filename.py
dom/bindings/parser/tests/test_constructor.py
dom/bindings/parser/tests/test_deduplicate.py
dom/bindings/parser/tests/test_enum.py
dom/bindings/parser/tests/test_error_colno.py
dom/bindings/parser/tests/test_nullable_equivalency.py
--- a/client.py
+++ b/client.py
@@ -2,71 +2,49 @@
 
 NSPR_DIRS = (('nsprpub', 'mozilla/nsprpub'),)
 NSS_DIRS  = (('dbm', 'mozilla/dbm'),
              ('security/nss', 'mozilla/security/nss'),
              ('security/coreconf', 'mozilla/security/coreconf'),
              ('security/dbm', 'mozilla/security/dbm'))
 NSSCKBI_DIRS = (('security/nss/lib/ckfw/builtins', 'mozilla/security/nss/lib/ckfw/builtins'),)
 LIBFFI_DIRS = (('js/ctypes/libffi', 'libffi'),)
-WEBIDLPARSER_DIR = 'dom/bindings/parser'
-WEBIDLPARSER_REPO = 'https://hg.mozilla.org/users/khuey_mozilla.com/webidl-parser'
-WEBIDLPARSER_EXCLUSIONS = ['.hgignore', '.gitignore', '.hg', 'ply']
 
 CVSROOT_MOZILLA = ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'
 CVSROOT_LIBFFI = ':pserver:anoncvs@sources.redhat.com:/cvs/libffi'
 
 import os
 import sys
 import datetime
 import shutil
-import glob
 from optparse import OptionParser
 from subprocess import check_call
 
 topsrcdir = os.path.dirname(__file__)
 if topsrcdir == '':
     topsrcdir = '.'
 
 def check_call_noisy(cmd, *args, **kwargs):
     print "Executing command:", cmd
     check_call(cmd, *args, **kwargs)
 
 def do_hg_pull(dir, repository, hg):
     fulldir = os.path.join(topsrcdir, dir)
     # clone if the dir doesn't exist, pull if it does
     if not os.path.exists(fulldir):
+        fulldir = os.path.join(topsrcdir, dir)
         check_call_noisy([hg, 'clone', repository, fulldir])
     else:
         cmd = [hg, 'pull', '-u', '-R', fulldir]
         if repository is not None:
             cmd.append(repository)
         check_call_noisy(cmd)
     check_call([hg, 'parent', '-R', fulldir,
                 '--template=Updated to revision {node}.\n'])
 
-def do_hg_replace(dir, repository, tag, exclusions, hg):
-    """
-        Replace the contents of dir with the contents of repository, except for
-        files matching exclusions.
-    """
-    fulldir = os.path.join(topsrcdir, dir)
-    if os.path.exists(fulldir):
-        shutil.rmtree(fulldir)
-
-    assert not os.path.exists(fulldir)
-    check_call_noisy([hg, 'clone', '-u', tag, repository, fulldir])
-
-    for thing in exclusions:
-        for excluded in glob.iglob(os.path.join(fulldir, thing)):
-            if os.path.isdir(excluded):
-                shutil.rmtree(excluded)
-            else:
-                os.remove(excluded)
-
 def do_cvs_export(modules, tag, cvsroot, cvs):
     """Check out a CVS directory without CVS metadata, using "export"
     modules is a list of directories to check out and the corresponding
     cvs module, e.g. (('nsprpub', 'mozilla/nsprpub'))
     """
     for module_tuple in modules:
         module = module_tuple[0]
         cvs_module = module_tuple[1]
@@ -77,27 +55,25 @@ def do_cvs_export(modules, tag, cvsroot,
 
         (parent, leaf) = os.path.split(module)
         print "CVS export begin: " + datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")
         check_call_noisy([cvs, '-d', cvsroot,
                           'export', '-r', tag, '-d', leaf, cvs_module],
                          cwd=os.path.join(topsrcdir, parent))
         print "CVS export end: " + datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")
 
-o = OptionParser(usage="client.py [options] update_nspr tagname | update_nss tagname | update_libffi tagname | update_webidlparser tagname")
+o = OptionParser(usage="client.py [options] update_nspr tagname | update_nss tagname | update_libffi tagname")
 o.add_option("--skip-mozilla", dest="skip_mozilla",
              action="store_true", default=False,
              help="Obsolete")
 
 o.add_option("--cvs", dest="cvs", default=os.environ.get('CVS', 'cvs'),
              help="The location of the cvs binary")
 o.add_option("--cvsroot", dest="cvsroot",
              help="The CVSROOT (default for mozilla checkouts: %s)" % CVSROOT_MOZILLA)
-o.add_option("--hg", dest="hg", default=os.environ.get('HG', 'hg'),
-             help="The location of the hg binary")
 
 try:
     options, args = o.parse_args()
     action = args[0]
 except IndexError:
     o.print_help()
     sys.exit(2)
 
@@ -123,14 +99,11 @@ elif action in ('update_nssckbi'):
         options.cvsroot = os.environ.get('CVSROOT', CVSROOT_MOZILLA)
     do_cvs_export(NSSCKBI_DIRS, tag, options.cvsroot, options.cvs)
     print >>file("security/nss/TAG-INFO-CKBI", "w"), tag
 elif action in ('update_libffi'):
     tag, = args[1:]
     if not options.cvsroot:
         options.cvsroot = CVSROOT_LIBFFI
     do_cvs_export(LIBFFI_DIRS, tag, options.cvsroot, options.cvs)
-elif action in ('update_webidlparser'):
-    tag, = args[1:]
-    do_hg_replace(WEBIDLPARSER_DIR, WEBIDLPARSER_REPO, tag, WEBIDLPARSER_EXCLUSIONS, options.hg)
 else:
     o.print_help()
     sys.exit(2)
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -64,110 +64,98 @@ def parseInt(literal):
         base = 10
 
     value = int(string, base)
     return value * sign
 
 # Magic for creating enums
 def M_add_class_attribs(attribs):
     def foo(name, bases, dict_):
-        for v, k in enumerate(attribs):
+        for v, k in attribs:
             dict_[k] = v
-        assert 'length' not in dict_
-        dict_['length'] = len(attribs)
         return type(name, bases, dict_)
     return foo
 
 def enum(*names):
     class Foo(object):
-        __metaclass__ = M_add_class_attribs(names)
+        __metaclass__ = M_add_class_attribs(enumerate(names))
         def __setattr__(self, name, value):  # this makes it read-only
             raise NotImplementedError
     return Foo()
 
 class WebIDLError(Exception):
     def __init__(self, message, location, warning=False):
         self.message = message
         self.location = location
         self.warning = warning
 
     def __str__(self):
         return "%s: %s%s%s" % (self.warning and 'warning' or 'error',
                                self.message, ", " if self.location else "",
                                self.location)
 
 class Location(object):
+    _line = None
+
     def __init__(self, lexer, lineno, lexpos, filename):
-        self._line = None
         self._lineno = lineno
         self._lexpos = lexpos
         self._lexdata = lexer.lexdata
         self._file = filename if filename else "<unknown>"
 
     def __eq__(self, other):
         return self._lexpos == other._lexpos and \
                self._file == other._file
 
-    def filename(self):
-        return self.filename
-
     def resolve(self):
         if self._line:
             return
 
         startofline = self._lexdata.rfind('\n', 0, self._lexpos) + 1
         endofline = self._lexdata.find('\n', self._lexpos, self._lexpos + 80)
-        if endofline != -1:
-            self._line = self._lexdata[startofline:endofline]
-        else:
-            self._line = self._lexdata[startofline:]
+        self._line = self._lexdata[startofline:endofline]
         self._colno = self._lexpos - startofline
 
+    def pointerline(self):
+        def i():
+            for i in xrange(0, self._colno):
+                yield " "
+            yield "^"
+
+        return "".join(i())
+
     def get(self):
         self.resolve()
         return "%s line %s:%s" % (self._file, self._lineno, self._colno)
 
-    def _pointerline(self):
-        return " " * self._colno + "^"
-
     def __str__(self):
         self.resolve()
         return "%s line %s:%s\n%s\n%s" % (self._file, self._lineno, self._colno,
-                                          self._line, self._pointerline())
+                                          self._line, self.pointerline())
 
 class BuiltinLocation(object):
     def __init__(self, text):
         self.msg = text
 
-    def __eq__(self, other):
-        return isinstance(other, BuiltinLocation) and \
-               self.msg == other.msg
-
-    def filename(self):
-        return '<builtin>'
-
-    def resolve(self):
-        pass
-
     def get(self):
         return self.msg
 
     def __str__(self):
         return self.get()
 
 
 # Data Model
 
 class IDLObject(object):
     def __init__(self, location):
         self.location = location
         self.userData = dict()
 
     def filename(self):
-        return self.location.filename()
+        return self.location._file
 
     def isInterface(self):
         return False
 
     def isEnum(self):
         return False
 
     def isCallback(self):
@@ -205,21 +193,16 @@ class IDLScope(IDLObject):
         return self.QName()
 
     def QName(self):
         if self._name:
             return self._name.QName() + "::"
         return "::"
 
     def ensureUnique(self, identifier, object):
-        """
-            Ensure that there is at most one 'identifier' in scope ('self').
-            Note that object can be None.  This occurs if we end up here for an
-            interface type we haven't seen yet.
-        """
         assert isinstance(identifier, IDLUnresolvedIdentifier)
         assert not object or isinstance(object, IDLObjectWithIdentifier)
         assert not object or object.identifier == identifier
 
         if identifier.name in self._dict:
             if not object:
                 return
 
@@ -312,19 +295,16 @@ class IDLUnresolvedIdentifier(IDLObject)
 
         scope.ensureUnique(self, object)
 
         identifier = IDLIdentifier(self.location, scope, self.name)
         if object:
             object.identifier = identifier
         return identifier
 
-    def finish(self):
-        assert False # Should replace with a resolved identifier first.
-
 class IDLObjectWithIdentifier(IDLObject):
     def __init__(self, location, parentScope, identifier):
         IDLObject.__init__(self, location)
 
         assert isinstance(identifier, IDLUnresolvedIdentifier)
 
         self.identifier = identifier
 
@@ -383,18 +363,19 @@ class IDLExternalInterface(IDLObjectWith
 class IDLInterface(IDLObjectWithScope):
     def __init__(self, location, parentScope, name, parent, members):
         assert isinstance(parentScope, IDLScope)
         assert isinstance(name, IDLUnresolvedIdentifier)
         assert not parent or isinstance(parent, IDLParentPlaceholder)
 
         self.parent = parent
         self._callback = False
-        self._finished = False
+
         self.members = list(members) # clone the list
+        assert iter(self.members) # Assert it's iterable
 
         IDLObjectWithScope.__init__(self, location, parentScope, name)
 
     def __str__(self):
         return "Interface '%s'" % self.identifier.name
 
     def ctor(self):
         identifier = IDLUnresolvedIdentifier(self.location, "constructor",
@@ -418,82 +399,116 @@ class IDLInterface(IDLObjectWithScope):
 
         retval = originalObject.addOverload(newObject)
         # Might be a ctor, which isn't in self.members
         if newObject in self.members:
             self.members.remove(newObject)
         return retval
 
     def finish(self, scope):
-        if self._finished:
+        if hasattr(self, "_finished"):
             return
 
         self._finished = True
 
         assert not self.parent or isinstance(self.parent, IDLParentPlaceholder)
         parent = self.parent.finish(scope) if self.parent else None
         assert not parent or isinstance(parent, IDLInterface)
 
         self.parent = parent
 
         assert iter(self.members)
+        members = None
 
         if self.parent:
             self.parent.finish(scope)
             assert iter(self.parent.members)
 
             members = list(self.parent.members)
             members.extend(self.members)
         else:
             members = list(self.members)
 
+        SpecialType = enum(
+            'NamedGetter',
+            'NamedSetter',
+            'NamedCreator',
+            'NamedDeleter',
+            'IndexedGetter',
+            'IndexedSetter',
+            'IndexedCreator',
+            'IndexedDeleter'
+        )
+
+        specialMembersSeen = [False for i in range(8)]
+
         def memberNotOnParentChain(member, iface):
             assert iface
 
             if not iface.parent:
                 return True
 
             assert isinstance(iface.parent, IDLInterface)
             if member in iface.parent.members:
                 return False
             return memberNotOnParentChain(member, iface.parent)
 
-        # Ensure that there's at most one of each {named,indexed}
-        # {getter,setter,creator,deleter}.
-        specialMembersSeen = set()
         for member in members:
             if memberNotOnParentChain(member, self):
                 member.resolve(self)
-
-            if member.tag != IDLInterfaceMember.Tags.Method:
-                continue
-
-            if member.isGetter():
-                memberType = "getters"
-            elif member.isSetter():
-                memberType = "setters"
-            elif member.isCreator():
-                memberType = "creators"
-            elif member.isDeleter():
-                memberType = "deleters"
-            else:
-                continue
-
-            if member.isNamed():
-                memberType = "named " + memberType
-            elif member.isIndexed():
-                memberType = "indexed " + memberType
-            else:
-                continue
-
-            if memberType in specialMembersSeen:
-                raise WebIDLError("Multiple " + memberType + " on %s" % (self),
-                                   self.location)
-
-            specialMembersSeen.add(memberType)
+                
+            if member.tag == IDLInterfaceMember.Tags.Method:
+                if member.isGetter():
+                    if member.isNamed():
+                        if specialMembersSeen[SpecialType.NamedGetter]:
+                            raise WebIDLError("Multiple named getters on %s" % (self),
+                                              self.location)
+                        specialMembersSeen[SpecialType.NamedGetter] = True
+                    else:
+                        assert member.isIndexed()
+                        if specialMembersSeen[SpecialType.IndexedGetter]:
+                            raise WebIDLError("Multiple indexed getters on %s" % (self),
+                                              self.location)
+                        specialMembersSeen[SpecialType.IndexedGetter] = True
+                if member.isSetter():
+                    if member.isNamed():
+                        if specialMembersSeen[SpecialType.NamedSetter]:
+                            raise WebIDLError("Multiple named setters on %s" % (self),
+                                              self.location)
+                        specialMembersSeen[SpecialType.NamedSetter] = True
+                    else:
+                        assert member.isIndexed()
+                        if specialMembersSeen[SpecialType.IndexedSetter]:
+                            raise WebIDLError("Multiple indexed setters on %s" % (self),
+                                              self.location)
+                        specialMembersSeen[SpecialType.IndexedSetter] = True
+                if member.isCreator():
+                    if member.isNamed():
+                        if specialMembersSeen[SpecialType.NamedCreator]:
+                            raise WebIDLError("Multiple named creators on %s" % (self),
+                                              self.location)
+                        specialMembersSeen[SpecialType.NamedCreator] = True
+                    else:
+                        assert member.isIndexed()
+                        if specialMembersSeen[SpecialType.IndexedCreator]:
+                            raise WebIDLError("Multiple indexed creators on %s" % (self),
+                                              self.location)
+                        specialMembersSeen[SpecialType.IndexedCreator] = True
+                if member.isDeleter():
+                    if member.isNamed():
+                        if specialMembersSeen[SpecialType.NamedDeleter]:
+                            raise WebIDLError("Multiple named deleters on %s" % (self),
+                                              self.location)
+                        specialMembersSeen[SpecialType.NamedDeleter] = True
+                    else:
+                        assert member.isIndexed()
+                        if specialMembersSeen[SpecialType.IndexedDeleter]:
+                            raise WebIDLError("Multiple indexed Deleters on %s" % (self),
+                                              self.location)
+                        specialMembersSeen[SpecialType.IndexedDeleter] = True
 
         for member in self.members:
             member.finish(scope)
 
     def isInterface(self):
         return True
 
     def isExternal(self):
@@ -509,17 +524,17 @@ class IDLInterface(IDLObjectWithScope):
         depth = 0
         parent = self.parent
         while parent:
             depth = depth + 1
             parent = parent.parent
         return depth
 
     def hasConstants(self):
-        return any(m.isConst() for m in self.members)
+        return reduce(lambda b, m: b or m.isConst(), self.members, False)
 
     def hasInterfaceObject(self):
         if self.isCallback():
             return self.hasConstants()
         return not hasattr(self, "_noInterfaceObject")
 
     def hasInterfacePrototypeObject(self):
         return not self.isCallback()
@@ -547,17 +562,20 @@ class IDLInterface(IDLObjectWithScope):
 
                 args = attrlist[0] if len(attrlist) else []
 
                 retType = IDLWrapperType(self.location, self)
                 
                 identifier = IDLUnresolvedIdentifier(self.location, "constructor",
                                                      allowForbidden=True)
 
-                method = IDLMethod(self.location, identifier, retType, args)
+                method = IDLMethod(self.location, identifier, retType, args,
+                                   False, False, False, False, False, False,
+                                   False, False)
+
                 method.resolve(self)
 
             self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True
 
 class IDLEnum(IDLObjectWithIdentifier):
     def __init__(self, location, parentScope, name, values):
         assert isinstance(parentScope, IDLScope)
         assert isinstance(name, IDLUnresolvedIdentifier)
@@ -740,34 +758,25 @@ class IDLNullableType(IDLType):
         return self.inner.isCallback()
 
     def isPrimitive(self):
         return self.inner.isPrimitive()
 
     def isString(self):
         return self.inner.isString()
 
-    def isFloat(self):
-        return self.inner.isFloat()
-
-    def isInteger(self):
-        return self.inner.isInteger()
-
     def isVoid(self):
         return False
 
     def isSequence(self):
         return self.inner.isSequence()
 
     def isArray(self):
         return self.inner.isArray()
 
-    def isArrayBuffer(self):
-        return self.inner.isArrayBuffer()
-
     def isDictionary(self):
         return self.inner.isDictionary()
 
     def isInterface(self):
         return self.inner.isInterface()
 
     def isEnum(self):
         return self.inner.isEnum()
@@ -783,17 +792,17 @@ class IDLNullableType(IDLType):
         return self.inner.isComplete()
 
     def complete(self, scope):
         self.inner = self.inner.complete(scope)
         self.name = self.inner.name
         return self
 
     def unroll(self):
-        return self.inner.unroll()
+        return self.inner
 
     def isDistinguishableFrom(self, other):
         if other.nullable():
             # Can't tell which type null should become
             return False
         return self.inner.isDistinguishableFrom(other)
 
 class IDLSequenceType(IDLType):
@@ -821,45 +830,43 @@ class IDLSequenceType(IDLType):
 
     def isVoid(self):
         return False
 
     def isSequence(self):
         return True
 
     def isArray(self):
-        return False
+        return self.inner.isArray()
 
     def isDictionary(self):
-        return False
+        return self.inner.isDictionary()
 
     def isInterface(self):
-        return False
+        return self.inner.isInterface()
 
     def isEnum(self):
-        return False
+        return self.inner.isEnum();
 
     def tag(self):
-        # XXXkhuey this is probably wrong.
         return self.inner.tag()
 
     def resolveType(self, parentScope):
         assert isinstance(parentScope, IDLScope)
         self.inner.resolveType(parentScope)
 
     def isComplete(self):
         return self.inner.isComplete()
 
     def complete(self, scope):
         self.inner = self.inner.complete(scope)
-        self.name = self.inner.name
         return self
 
     def unroll(self):
-        return self.inner.unroll()
+        return self.inner
 
     def isDistinguishableFrom(self, other):
         return (other.isPrimitive() or other.isString() or other.isEnum() or
                 other.isDictionary() or other.isDate() or
                 # XXXbz we should also be checking for indexed
                 # properties on interfaces
                 (other.isInterface() and not other.isCallback() and
                  not other.isArrayBuffer()))
@@ -883,59 +890,57 @@ class IDLArrayType(IDLType):
 
     def __str__(self):
         return self.inner.__str__() + "Array"
 
     def nullable(self):
         return False
 
     def isPrimitive(self):
-        return False
+        return self.inner.isPrimitive()
 
     def isString(self):
-        return False
+        return self.inner.isString()
 
     def isVoid(self):
         return False
 
     def isSequence(self):
         assert not self.inner.isSequence()
-        return False
+        return self.inner.isSequence()
 
     def isArray(self):
         return True
 
     def isDictionary(self):
         assert not self.inner.isDictionary()
-        return False
+        return self.inner.isDictionary()
 
     def isInterface(self):
-        return False
+        return self.inner.isInterface()
 
     def isEnum(self):
-        return False
+        return self.inner.isEnum()
 
     def tag(self):
-        # XXXkhuey this is probably wrong.
         return self.inner.tag()
 
     def resolveType(self, parentScope):
         assert isinstance(parentScope, IDLScope)
         self.inner.resolveType(parentScope)
 
     def isComplete(self):
         return self.inner.isComplete()
 
     def complete(self, scope):
         self.inner = self.inner.complete(scope)
-        self.name = self.inner.name
         return self
 
     def unroll(self):
-        return self.inner.unroll()
+        return self.inner
 
     def isDistinguishableFrom(self, other):
         return (other.isPrimitive() or other.isString() or other.isEnum() or
                 other.isDictionary() or other.isDate() or
                 # XXXbz we should also be checking for indexed
                 # properties on interfaces
                 (other.isInterface() and not other.isCallback() and
                  not other.isArrayBuffer()))
@@ -985,17 +990,17 @@ class IDLTypedefType(IDLType, IDLObjectW
     def resolve(self, parentScope):
         assert isinstance(parentScope, IDLScope)
         IDLObjectWithIdentifier.resolve(self, parentScope)
 
     def tag(self):
         return self.inner.tag()
 
     def unroll(self):
-        return self.inner.unroll()
+        return self.inner
 
     def isDistinguishableFrom(self, other):
         return self.inner.isDistinguishableFrom(other)
 
 class IDLWrapperType(IDLType):
     def __init__(self, location, inner):
         IDLType.__init__(self, location, inner.identifier.name)
         self.inner = inner
@@ -1031,20 +1036,16 @@ class IDLWrapperType(IDLType):
 
     def isInterface(self):
         return isinstance(self.inner, IDLInterface) or \
                isinstance(self.inner, IDLExternalInterface)
 
     def isEnum(self):
         return isinstance(self.inner, IDLEnum)
 
-    def resolveType(self, parentScope):
-        assert isinstance(parentScope, IDLScope)
-        self.inner.resolve(parentScope)
-
     def isComplete(self):
         return True
 
     def tag(self):
         if self.isInterface():
             return IDLType.Tags.interface
         elif self.isEnum():
             return IDLType.Tags.enum
@@ -1116,42 +1117,42 @@ class IDLBuiltinType(IDLType):
             Types.date: IDLType.Tags.date,
             Types.void: IDLType.Tags.void,
             Types.ArrayBuffer: IDLType.Tags.interface
         }
 
     def __init__(self, location, name, type):
         IDLType.__init__(self, location, name)
         self.builtin = True
-        self._typeTag = type
+        self.type = type
 
     def isPrimitive(self):
-        return self._typeTag <= IDLBuiltinType.Types.double
+        return self.type <= IDLBuiltinType.Types.double
 
     def isString(self):
-        return self._typeTag == IDLBuiltinType.Types.domstring
+        return self.type == IDLBuiltinType.Types.domstring
 
     def isInteger(self):
-        return self._typeTag <= IDLBuiltinType.Types.unsigned_long_long
+        return self.type <= IDLBuiltinType.Types.unsigned_long_long
 
     def isArrayBuffer(self):
-        return self._typeTag == IDLBuiltinType.Types.ArrayBuffer
+        return self.type == IDLBuiltinType.Types.ArrayBuffer
 
     def isInterface(self):
         # ArrayBuffers are interface types per the TypedArray spec,
         # but we handle them as builtins because SpiderMonkey implements
         # ArrayBuffers.
-        return self._typeTag == IDLBuiltinType.Types.ArrayBuffer
+        return self.type == IDLBuiltinType.Types.ArrayBuffer
 
     def isFloat(self):
-        return self._typeTag == IDLBuiltinType.Types.float or \
-               self._typeTag == IDLBuiltinType.Types.double
+        return self.type == IDLBuiltinType.Types.float or \
+               self.type == IDLBuiltinType.Types.double
 
     def tag(self):
-        return IDLBuiltinType.TagLookup[self._typeTag]
+        return IDLBuiltinType.TagLookup[self.type]
 
     def isDistinguishableFrom(self, other):
         if self.isPrimitive() or self.isString():
             return (other.isInterface() or other.isObject() or
                     other.isCallback() or other.isDictionary() or
                     other.isSequence() or other.isArray() or
                     other.isDate())
         if self.isAny():
@@ -1274,17 +1275,17 @@ class IDLValue(IDLObject):
         # Else, see if we can coerce to 'type'.
         if self.type.isInteger():
             if not self.type.isInteger():
                 raise WebIDLError("Cannot coerce type %s to type %s." %
                                   (self.type, type), location)
 
             # We're both integer types.  See if we fit.
 
-            (min, max) = integerTypeSizes[type._typeTag]
+            (min, max) = integerTypeSizes[type.type]
             if self.value <= max and self.value >= min:
                 # Promote
                 return IDLValue(self.location, type, self.value)
             else:
                 raise WebIDLError("Value %s is out of range for type %s." %
                                   (self.value, type), location)
         else:
             pass
@@ -1486,20 +1487,18 @@ class IDLMethod(IDLInterfaceMember, IDLS
 
     NamedOrIndexed = enum(
         'Neither',
         'Named',
         'Indexed'
     )
 
     def __init__(self, location, identifier, returnType, arguments,
-                 static=False, getter=False, setter=False, creator=False,
-                 deleter=False, specialType=NamedOrIndexed.Neither,
-                 legacycaller=False, stringifier=False):
-        # REVIEW: specialType is NamedOrIndexed -- wow, this is messed up.
+                 static, getter, setter, creator, deleter, specialType, legacycaller,
+                 stringifier):
         IDLInterfaceMember.__init__(self, location, identifier,
                                     IDLInterfaceMember.Tags.Method)
 
         self._hasOverloads = False
 
         assert isinstance(returnType, IDLType)
         self._returnType = [returnType]
 
@@ -1674,17 +1673,16 @@ class Tokenizer(object):
         "STRING",
         "WHITESPACE",
         "OTHER"
         ]
 
     def t_INTEGER(self, t):
         r'-?(0([0-7]+|[Xx][0-9A-Fa-f]+)?|[1-9][0-9]*)'
         try:
-            # Can't use int(), because that doesn't handle octal properly.
             t.value = parseInt(t.value)
         except:
             raise WebIDLError("Invalid integer literal",
                               Location(lexer=self.lexer,
                                        lineno=self.lexer.lineno,
                                        lexpos=self.lexer.lexpos,
                                        filename=self._filename))
         return t
@@ -2258,19 +2256,18 @@ class Parser(Tokenizer):
                  "indexed" if specialType == IDLMethod.NamedOrIndexed.Indexed else "",
                  "getter" if getter else "",
                  "setter" if setter else "",
                  "deleter" if deleter else "",
                  "creator" if creator else "",
                  "legacycaller" if legacycaller else ""), allowDoubleUnderscore=True)
 
         method = IDLMethod(self.getLocation(p, 2), identifier, returnType, arguments,
-                           static=static, getter=getter, setter=setter, creator=creator,
-                           deleter=deleter, specialType=specialType,
-                           legacycaller=legacycaller, stringifier=False)
+                           static, getter, setter, creator, deleter, specialType,
+                           legacycaller, False)
         p[0] = method
 
     def p_QualifiersStatic(self, p):
         """
             Qualifiers : STATIC
         """
         p[0] = [IDLMethod.Special.Static]
 
@@ -2859,24 +2856,17 @@ class Parser(Tokenizer):
         self._filename = filename
         self._productions.extend(self.parser.parse(lexer=self.lexer))
         self._filename = None
 
     def finish(self):
         for production in self._productions:
             production.finish(self.globalScope())
 
-        # De-duplicate self._productions, without modifying its order.
-        seen = set()
-        result = []
-        for p in self._productions:
-            if p not in seen:
-                seen.add(p)
-                result.append(p)
-        return result
+        return set(self._productions)
 
     def reset(self):
         return Parser()
 
     # Builtin IDL defined by WebIDL
     _builtins = """
         typedef unsigned long long DOMTimeStamp;
     """
new file mode 100644
--- /dev/null
+++ b/dom/bindings/parser/__init__.py
@@ -0,0 +1,1 @@
+__all__ = ['WebIDL']
--- a/dom/bindings/parser/runtests.py
+++ b/dom/bindings/parser/runtests.py
@@ -32,81 +32,41 @@
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 import os, sys
 import glob
-import optparse
-import traceback
 import WebIDL
 
 class TestHarness(object):
-    def __init__(self, test, verbose):
-        self.test = test
-        self.verbose = verbose
-        self.printed_intro = False
-
-    def start(self):
-        if self.verbose:
-            self.maybe_print_intro()
-
-    def finish(self):
-        if self.verbose or self.printed_intro:
-            print "Finished test %s" % self.test
-
-    def maybe_print_intro(self):
-        if not self.printed_intro:
-            print "Starting test %s" % self.test
-            self.printed_intro = True
-
-    def test_pass(self, msg):
-        if self.verbose:
-            print "TEST-PASS | %s" % msg
-
-    def test_fail(self, msg):
-        self.maybe_print_intro()
-        print "TEST-UNEXPECTED-FAIL | %s" % msg
-
     def ok(self, condition, msg):
         if condition:
-            self.test_pass(msg)
+            print "TEST-PASS | %s" % msg
         else:
-            self.test_fail(msg)
+            print "TEST-UNEXPECTED-FAIL | %s" % msg
 
     def check(self, a, b, msg):
         if a == b:
-            self.test_pass(msg)
+            print "TEST-PASS | %s" % msg
         else:
-            self.test_fail(msg)
+            print "TEST-UNEXPECTED-FAIL | %s" % msg
             print "\tGot %s expected %s" % (a, b)
 
-def run_tests(tests, verbose):
-    testdir = os.path.join(os.path.dirname(__file__), 'tests')
-    if not tests:
-        tests = glob.iglob(os.path.join(testdir, "*.py"))
-    sys.path.append(testdir)
+def run_tests():
+    harness = TestHarness()
 
+    tests = glob.iglob("tests/*.py")
+    sys.path.append("./tests")
     for test in tests:
         (testpath, ext) = os.path.splitext(os.path.basename(test))
         _test = __import__(testpath, globals(), locals(), ['WebIDLTest'])
-
-        harness = TestHarness(test, verbose)
-        harness.start()
-        try:
-            _test.WebIDLTest.__call__(WebIDL.Parser(), harness)
-        except:
-            print "TEST-UNEXPECTED-FAIL | Unhandled exception in test %s" % testpath
-            traceback.print_exc()
-        finally:
-            harness.finish()
+        #try:
+        _test.WebIDLTest.__call__(WebIDL.Parser(), harness)
+        #except:
+        #    print "TEST-UNEXPECTED-FAIL | Unhandled exception in Test %s" % testpath
+        #    print sys.exc_info()[0]
+        print "Test %s Complete\n" % testpath
 
 if __name__ == '__main__':
-    usage = """%prog [OPTIONS] [TESTS]
-               Where TESTS are relative to the tests directory."""
-    parser = optparse.OptionParser(usage=usage)
-    parser.add_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
-                      help="Don't print passing tests.")
-    options, tests = parser.parse_args()
-
-    run_tests(tests, verbose=options.verbose)
+    run_tests()
deleted file mode 100644
--- a/dom/bindings/parser/tests/test_array_of_interface.py
+++ /dev/null
@@ -1,13 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
-    parser.parse("""
-      interface A {
-        attribute long a;
-      };
-
-      interface B {
-        attribute A[] b;
-      };
-    """);
-    parser.finish()
deleted file mode 100644
--- a/dom/bindings/parser/tests/test_builtin_filename.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
-    parser.parse("""
-        interface Test {
-          attribute long b;
-        };
-    """);
-
-    attr = parser.finish()[0].members[0]
-    harness.check(attr.type.filename(), '<builtin>', 'Filename on builtin type')
--- a/dom/bindings/parser/tests/test_constructor.py
+++ b/dom/bindings/parser/tests/test_constructor.py
@@ -57,19 +57,19 @@ def WebIDLTest(parser, harness):
     results = parser.finish()
     harness.check(len(results), 3, "Should be two productions")
     harness.ok(isinstance(results[0], WebIDL.IDLInterface),
                "Should be an IDLInterface")
     harness.ok(isinstance(results[1], WebIDL.IDLInterface),
                "Should be an IDLInterface")
 
     checkMethod(results[0].ctor(), "::TestConstructorNoArgs::constructor",
-                "constructor", [("TestConstructorNoArgs (Wrapper)", [])])
+                "constructor", [("TestConstructorNoArgs", [])])
     checkMethod(results[1].ctor(), "::TestConstructorWithArgs::constructor",
                 "constructor",
-                [("TestConstructorWithArgs (Wrapper)",
+                [("TestConstructorWithArgs",
                  [("::TestConstructorWithArgs::constructor::name", "name", "String", False, False)])])
     checkMethod(results[2].ctor(), "::TestConstructorOverloads::constructor",
                 "constructor",
-                [("TestConstructorOverloads (Wrapper)",
+                [("TestConstructorOverloads",
                  [("::TestConstructorOverloads::constructor::foo", "foo", "Object", False, False)]),
-                 ("TestConstructorOverloads (Wrapper)",
+                 ("TestConstructorOverloads",
                  [("::TestConstructorOverloads::constructor::bar", "bar", "Boolean", False, False)])])
deleted file mode 100644
--- a/dom/bindings/parser/tests/test_deduplicate.py
+++ /dev/null
@@ -1,15 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
-    parser.parse("""
-        interface Foo;
-        interface Bar;
-        interface Foo;
-        """);
-
-    results = parser.finish()
-
-    # There should be no duplicate interfaces in the result.
-    expectedNames = sorted(['Foo', 'Bar'])
-    actualNames = sorted(map(lambda iface: iface.identifier.name, results))
-    harness.check(actualNames, expectedNames, "Parser shouldn't output duplicate names.")
--- a/dom/bindings/parser/tests/test_enum.py
+++ b/dom/bindings/parser/tests/test_enum.py
@@ -42,20 +42,20 @@ def WebIDLTest(parser, harness):
     harness.check(method.identifier.QName(), "::TestEnumInterface::doFoo",
                   "Method has correct QName")
     harness.check(method.identifier.name, "doFoo", "Method has correct name")
 
     signatures = method.signatures()
     harness.check(len(signatures), 1, "Expect one signature")
 
     (returnType, arguments) = signatures[0]
-    harness.check(str(returnType), "TestEnum (Wrapper)", "Method type is the correct name")
+    harness.check(str(returnType), "TestEnum", "Method type is the correct name")
     harness.check(len(arguments), 1, "Method has the right number of arguments")
     arg = arguments[0]
     harness.ok(isinstance(arg, WebIDL.IDLArgument), "Should be an IDLArgument")
     harness.check(str(arg.type), "Boolean", "Argument has the right type")
 
     attr = members[1]
     harness.check(attr.identifier.QName(), "::TestEnumInterface::foo",
                   "Attr has correct QName")
     harness.check(attr.identifier.name, "foo", "Attr has correct name")
 
-    harness.check(str(attr.type), "TestEnum (Wrapper)", "Attr type is the correct name")
+    harness.check(str(attr.type), "TestEnum", "Attr type is the correct name")
deleted file mode 100644
--- a/dom/bindings/parser/tests/test_error_colno.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
-    # Check that error messages put the '^' in the right place.
-
-    threw = False
-    input = 'interface ?'
-    try:
-        parser.parse(input)
-        results = parser.finish()
-    except WebIDL.WebIDLError as e:
-        threw = True
-        lines = str(e).split('\n')
-
-        harness.check(len(lines), 3, 'Expected number of lines in error message')
-        harness.check(lines[1], input, 'Second line shows error')
-        harness.check(lines[2], ' ' * (len(input) - 1) + '^',
-                      'Correct column pointer in error message')
-
-    harness.ok(threw, "Should have thrown.")
deleted file mode 100644
--- a/dom/bindings/parser/tests/test_nullable_equivalency.py
+++ /dev/null
@@ -1,134 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
-    parser.parse("""
-        interface TestNullableEquivalency1 {
-          attribute long  a;
-          attribute long? b;
-        };
-
-        interface TestNullableEquivalency2 {
-          attribute ArrayBuffer  a;
-          attribute ArrayBuffer? b;
-        };
-
-        /* Not implemented */
-        /*dictionary TestNullableEquivalency3Dict {
-          long foo = 42;
-        };
-
-        interface TestNullableEquivalency3 {
-          attribute Test3Dict  a;
-          attribute Test3Dict? b;
-        };*/
-
-        enum TestNullableEquivalency4Enum {
-          "Foo",
-          "Bar"
-        };
-
-        interface TestNullableEquivalency4 {
-          attribute TestNullableEquivalency4Enum  a;
-          attribute TestNullableEquivalency4Enum? b;
-        };
-
-        interface TestNullableEquivalency5 {
-          attribute TestNullableEquivalency4  a;
-          attribute TestNullableEquivalency4? b;
-        };
-
-        interface TestNullableEquivalency6 {
-          attribute boolean  a;
-          attribute boolean? b;
-        };
-
-        interface TestNullableEquivalency7 {
-          attribute DOMString  a;
-          attribute DOMString? b;
-        };
-
-        /* Not implemented. */
-        /*interface TestNullableEquivalency8 {
-          attribute float  a;
-          attribute float? b;
-        };*/
-
-        interface TestNullableEquivalency8 {
-          attribute double  a;
-          attribute double? b;
-        };
-
-        interface TestNullableEquivalency9 {
-          attribute object  a;
-          attribute object? b;
-        };
-
-        interface TestNullableEquivalency10 {
-          attribute double[]  a;
-          attribute double[]? b;
-        };
-
-        interface TestNullableEquivalency11 {
-          attribute TestNullableEquivalency9[]  a;
-          attribute TestNullableEquivalency9[]? b;
-        };
-    """)
-
-    for decl in parser.finish():
-        if decl.isInterface():
-            checkEquivalent(decl, harness)
-
-def checkEquivalent(iface, harness):
-    type1 = iface.members[0].type
-    type2 = iface.members[1].type
-
-    harness.check(type1.nullable(), False, 'attr1 should not be nullable')
-    harness.check(type2.nullable(), True, 'attr2 should be nullable')
-
-    # We don't know about type1, but type2, the nullable type, definitely
-    # shouldn't be builtin.
-    harness.check(type2.builtin, False, 'attr2 should not be builtin')
-
-    # Ensure that all attributes of type2 match those in type1, except for:
-    #  - names on an ignore list,
-    #  - names beginning with '_',
-    #  - functions which throw when called with no args, and
-    #  - class-level non-callables ("static variables").
-    #
-    # Yes, this is an ugly, fragile hack.  But it finds bugs...
-    for attr in dir(type1):
-        if attr.startswith('_') or \
-           attr in ['nullable', 'builtin', 'filename', 'location',
-                    'inner', 'QName'] or \
-           (hasattr(type(type1), attr) and not callable(getattr(type1, attr))):
-            continue
-
-        a1 = getattr(type1, attr)
-
-        if callable(a1):
-            try:
-                v1 = a1()
-            except:
-                # Can't call a1 with no args, so skip this attriute.
-                continue
-
-            try:
-                a2 = getattr(type2, attr)
-            except:
-                harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface))
-                continue
-
-            if not callable(a2):
-                harness.ok(False, "%s attribute on type %s in %s wasn't callable" % (attr, type2, iface))
-                continue
-
-            v2 = a2()
-            harness.check(v2, v1, '%s method return value' % attr)
-        else:
-            try:
-                a2 = getattr(type2, attr)
-            except:
-                harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface))
-                continue
-
-            harness.check(a2, a1, '%s attribute should match' % attr)