author | Kyle Huey <khuey@kylehuey.com> |
Thu, 12 Apr 2012 09:06:29 -0700 | |
changeset 91516 | b7c1c0145079b1c0c6a72b316787735868fab92e |
parent 91515 | adef80d2b5a0c80c0cc6bc48a072f201d13fbf48 |
child 91517 | 0d1e86660e49f1848cbe8b400e865de50d8bebb5 |
push id | 8254 |
push user | eakhgari@mozilla.com |
push date | Thu, 12 Apr 2012 16:21:01 +0000 |
treeherder | mozilla-inbound@21106c79a43d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 14.0a1 |
backs out | adef80d2b5a0c80c0cc6bc48a072f201d13fbf48 |
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
|
client.py | file | annotate | diff | comparison | revisions | |
dom/bindings/parser/WebIDL.py | file | annotate | diff | comparison | revisions | |
dom/bindings/parser/__init__.py | file | annotate | diff | comparison | revisions | |
dom/bindings/parser/runtests.py | file | annotate | diff | comparison | revisions | |
dom/bindings/parser/tests/test_array_of_interface.py | file | annotate | diff | comparison | revisions | |
dom/bindings/parser/tests/test_builtin_filename.py | file | annotate | diff | comparison | revisions | |
dom/bindings/parser/tests/test_constructor.py | file | annotate | diff | comparison | revisions | |
dom/bindings/parser/tests/test_deduplicate.py | file | annotate | diff | comparison | revisions | |
dom/bindings/parser/tests/test_enum.py | file | annotate | diff | comparison | revisions | |
dom/bindings/parser/tests/test_error_colno.py | file | annotate | diff | comparison | revisions | |
dom/bindings/parser/tests/test_nullable_equivalency.py | file | annotate | diff | comparison | revisions |
--- 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._file - 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)