Backed out changeset 3a0940f90455
authorKyle Huey <khuey@kylehuey.com>
Wed, 04 Apr 2012 13:42:12 -0700
changeset 91438 869edbbfad819b65543cf38ada8d1a8e1005cdf9
parent 91437 3a0940f904553197a95534bf8ac153bc691766b4
child 91439 ed9cbe6a817e085705d2676a012019d7b21dbf76
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
milestone14.0a1
backs out3a0940f904553197a95534bf8ac153bc691766b4
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)