dom/bindings/parser/WebIDL.py

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/bindings/parser/WebIDL.py	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,5104 @@
     1.4 +# This Source Code Form is subject to the terms of the Mozilla Public
     1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 +# file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.7 +
     1.8 +""" A WebIDL parser. """
     1.9 +
    1.10 +from ply import lex, yacc
    1.11 +import re
    1.12 +import os
    1.13 +import traceback
    1.14 +import math
    1.15 +
    1.16 +# Machinery
    1.17 +
    1.18 +def parseInt(literal):
    1.19 +    string = literal
    1.20 +    sign = 0
    1.21 +    base = 0
    1.22 +
    1.23 +    if string[0] == '-':
    1.24 +        sign = -1
    1.25 +        string = string[1:]
    1.26 +    else:
    1.27 +        sign = 1
    1.28 +
    1.29 +    if string[0] == '0' and len(string) > 1:
    1.30 +        if string[1] == 'x' or string[1] == 'X':
    1.31 +            base = 16
    1.32 +            string = string[2:]
    1.33 +        else:
    1.34 +            base = 8
    1.35 +            string = string[1:]
    1.36 +    else:
    1.37 +        base = 10
    1.38 +
    1.39 +    value = int(string, base)
    1.40 +    return value * sign
    1.41 +
    1.42 +# Magic for creating enums
    1.43 +def M_add_class_attribs(attribs, start):
    1.44 +    def foo(name, bases, dict_):
    1.45 +        for v, k in enumerate(attribs):
    1.46 +            dict_[k] = start + v
    1.47 +        assert 'length' not in dict_
    1.48 +        dict_['length'] = start + len(attribs)
    1.49 +        return type(name, bases, dict_)
    1.50 +    return foo
    1.51 +
    1.52 +def enum(*names, **kw):
    1.53 +    if len(kw) == 1:
    1.54 +        base = kw['base'].__class__
    1.55 +        start = base.length
    1.56 +    else:
    1.57 +        assert len(kw) == 0
    1.58 +        base = object
    1.59 +        start = 0
    1.60 +    class Foo(base):
    1.61 +        __metaclass__ = M_add_class_attribs(names, start)
    1.62 +        def __setattr__(self, name, value):  # this makes it read-only
    1.63 +            raise NotImplementedError
    1.64 +    return Foo()
    1.65 +
    1.66 +class WebIDLError(Exception):
    1.67 +    def __init__(self, message, locations, warning=False):
    1.68 +        self.message = message
    1.69 +        self.locations = [str(loc) for loc in locations]
    1.70 +        self.warning = warning
    1.71 +
    1.72 +    def __str__(self):
    1.73 +        return "%s: %s%s%s" % (self.warning and 'warning' or 'error',
    1.74 +                                 self.message,
    1.75 +                                 ", " if len(self.locations) != 0 else "",
    1.76 +                                 "\n".join(self.locations))
    1.77 +
    1.78 +class Location(object):
    1.79 +    def __init__(self, lexer, lineno, lexpos, filename):
    1.80 +        self._line = None
    1.81 +        self._lineno = lineno
    1.82 +        self._lexpos = lexpos
    1.83 +        self._lexdata = lexer.lexdata
    1.84 +        self._file = filename if filename else "<unknown>"
    1.85 +
    1.86 +    def __eq__(self, other):
    1.87 +        return self._lexpos == other._lexpos and \
    1.88 +               self._file == other._file
    1.89 +
    1.90 +    def filename(self):
    1.91 +        return self._file
    1.92 +
    1.93 +    def resolve(self):
    1.94 +        if self._line:
    1.95 +            return
    1.96 +
    1.97 +        startofline = self._lexdata.rfind('\n', 0, self._lexpos) + 1
    1.98 +        endofline = self._lexdata.find('\n', self._lexpos, self._lexpos + 80)
    1.99 +        if endofline != -1:
   1.100 +            self._line = self._lexdata[startofline:endofline]
   1.101 +        else:
   1.102 +            self._line = self._lexdata[startofline:]
   1.103 +        self._colno = self._lexpos - startofline
   1.104 +
   1.105 +        # Our line number seems to point to the start of self._lexdata
   1.106 +        self._lineno += self._lexdata.count('\n', 0, startofline)
   1.107 +
   1.108 +    def get(self):
   1.109 +        self.resolve()
   1.110 +        return "%s line %s:%s" % (self._file, self._lineno, self._colno)
   1.111 +
   1.112 +    def _pointerline(self):
   1.113 +        return " " * self._colno + "^"
   1.114 +
   1.115 +    def __str__(self):
   1.116 +        self.resolve()
   1.117 +        return "%s line %s:%s\n%s\n%s" % (self._file, self._lineno, self._colno,
   1.118 +                                          self._line, self._pointerline())
   1.119 +
   1.120 +class BuiltinLocation(object):
   1.121 +    def __init__(self, text):
   1.122 +        self.msg = text + "\n"
   1.123 +
   1.124 +    def __eq__(self, other):
   1.125 +        return isinstance(other, BuiltinLocation) and \
   1.126 +               self.msg == other.msg
   1.127 +
   1.128 +    def filename(self):
   1.129 +        return '<builtin>'
   1.130 +
   1.131 +    def resolve(self):
   1.132 +        pass
   1.133 +
   1.134 +    def get(self):
   1.135 +        return self.msg
   1.136 +
   1.137 +    def __str__(self):
   1.138 +        return self.get()
   1.139 +
   1.140 +
   1.141 +# Data Model
   1.142 +
   1.143 +class IDLObject(object):
   1.144 +    def __init__(self, location):
   1.145 +        self.location = location
   1.146 +        self.userData = dict()
   1.147 +
   1.148 +    def filename(self):
   1.149 +        return self.location.filename()
   1.150 +
   1.151 +    def isInterface(self):
   1.152 +        return False
   1.153 +
   1.154 +    def isEnum(self):
   1.155 +        return False
   1.156 +
   1.157 +    def isCallback(self):
   1.158 +        return False
   1.159 +
   1.160 +    def isType(self):
   1.161 +        return False
   1.162 +
   1.163 +    def isDictionary(self):
   1.164 +        return False;
   1.165 +
   1.166 +    def isUnion(self):
   1.167 +        return False
   1.168 +
   1.169 +    def getUserData(self, key, default):
   1.170 +        return self.userData.get(key, default)
   1.171 +
   1.172 +    def setUserData(self, key, value):
   1.173 +        self.userData[key] = value
   1.174 +
   1.175 +    def addExtendedAttributes(self, attrs):
   1.176 +        assert False # Override me!
   1.177 +
   1.178 +    def handleExtendedAttribute(self, attr):
   1.179 +        assert False # Override me!
   1.180 +
   1.181 +    def _getDependentObjects(self):
   1.182 +        assert False # Override me!
   1.183 +
   1.184 +    def getDeps(self, visited=None):
   1.185 +        """ Return a set of files that this object depends on.  If any of
   1.186 +            these files are changed the parser needs to be rerun to regenerate
   1.187 +            a new IDLObject.
   1.188 +
   1.189 +            The visited argument is a set of all the objects already visited.
   1.190 +            We must test to see if we are in it, and if so, do nothing.  This
   1.191 +            prevents infinite recursion."""
   1.192 +
   1.193 +        # NB: We can't use visited=set() above because the default value is
   1.194 +        # evaluated when the def statement is evaluated, not when the function
   1.195 +        # is executed, so there would be one set for all invocations.
   1.196 +        if visited == None:
   1.197 +            visited = set()
   1.198 +
   1.199 +        if self in visited:
   1.200 +            return set()
   1.201 +
   1.202 +        visited.add(self)
   1.203 +
   1.204 +        deps = set()
   1.205 +        if self.filename() != "<builtin>":
   1.206 +            deps.add(self.filename())
   1.207 +
   1.208 +        for d in self._getDependentObjects():
   1.209 +            deps = deps.union(d.getDeps(visited))
   1.210 +
   1.211 +        return deps
   1.212 +
   1.213 +class IDLScope(IDLObject):
   1.214 +    def __init__(self, location, parentScope, identifier):
   1.215 +        IDLObject.__init__(self, location)
   1.216 +
   1.217 +        self.parentScope = parentScope
   1.218 +        if identifier:
   1.219 +            assert isinstance(identifier, IDLIdentifier)
   1.220 +            self._name = identifier
   1.221 +        else:
   1.222 +            self._name = None
   1.223 +
   1.224 +        self._dict = {}
   1.225 +
   1.226 +    def __str__(self):
   1.227 +        return self.QName()
   1.228 +
   1.229 +    def QName(self):
   1.230 +        if self._name:
   1.231 +            return self._name.QName() + "::"
   1.232 +        return "::"
   1.233 +
   1.234 +    def ensureUnique(self, identifier, object):
   1.235 +        """
   1.236 +            Ensure that there is at most one 'identifier' in scope ('self').
   1.237 +            Note that object can be None.  This occurs if we end up here for an
   1.238 +            interface type we haven't seen yet.
   1.239 +        """
   1.240 +        assert isinstance(identifier, IDLUnresolvedIdentifier)
   1.241 +        assert not object or isinstance(object, IDLObjectWithIdentifier)
   1.242 +        assert not object or object.identifier == identifier
   1.243 +
   1.244 +        if identifier.name in self._dict:
   1.245 +            if not object:
   1.246 +                return
   1.247 +
   1.248 +            # ensureUnique twice with the same object is not allowed
   1.249 +            assert id(object) != id(self._dict[identifier.name])
   1.250 +
   1.251 +            replacement = self.resolveIdentifierConflict(self, identifier,
   1.252 +                                                         self._dict[identifier.name],
   1.253 +                                                         object)
   1.254 +            self._dict[identifier.name] = replacement
   1.255 +            return
   1.256 +
   1.257 +        assert object
   1.258 +
   1.259 +        self._dict[identifier.name] = object
   1.260 +
   1.261 +    def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject):
   1.262 +        if isinstance(originalObject, IDLExternalInterface) and \
   1.263 +           isinstance(newObject, IDLExternalInterface) and \
   1.264 +           originalObject.identifier.name == newObject.identifier.name:
   1.265 +            return originalObject
   1.266 +
   1.267 +        if (isinstance(originalObject, IDLExternalInterface) or
   1.268 +            isinstance(newObject, IDLExternalInterface)):
   1.269 +            raise WebIDLError(
   1.270 +                "Name collision between "
   1.271 +                "interface declarations for identifier '%s' at '%s' and '%s'"
   1.272 +                % (identifier.name,
   1.273 +                    originalObject.location, newObject.location), [])
   1.274 +
   1.275 +        # We do the merging of overloads here as opposed to in IDLInterface
   1.276 +        # because we need to merge overloads of NamedConstructors and we need to
   1.277 +        # detect conflicts in those across interfaces. See also the comment in
   1.278 +        # IDLInterface.addExtendedAttributes for "NamedConstructor".
   1.279 +        if originalObject.tag == IDLInterfaceMember.Tags.Method and \
   1.280 +           newObject.tag == IDLInterfaceMember.Tags.Method:
   1.281 +            return originalObject.addOverload(newObject)
   1.282 +
   1.283 +        # Default to throwing, derived classes can override.
   1.284 +        conflictdesc = "\n\t%s at %s\n\t%s at %s" % \
   1.285 +          (originalObject, originalObject.location, newObject, newObject.location)
   1.286 +
   1.287 +        raise WebIDLError(
   1.288 +            "Multiple unresolvable definitions of identifier '%s' in scope '%s%s"
   1.289 +            % (identifier.name, str(self), conflictdesc), [])
   1.290 +
   1.291 +    def _lookupIdentifier(self, identifier):
   1.292 +        return self._dict[identifier.name]
   1.293 +
   1.294 +    def lookupIdentifier(self, identifier):
   1.295 +        assert isinstance(identifier, IDLIdentifier)
   1.296 +        assert identifier.scope == self
   1.297 +        return self._lookupIdentifier(identifier)
   1.298 +
   1.299 +class IDLIdentifier(IDLObject):
   1.300 +    def __init__(self, location, scope, name):
   1.301 +        IDLObject.__init__(self, location)
   1.302 +
   1.303 +        self.name = name
   1.304 +        assert isinstance(scope, IDLScope)
   1.305 +        self.scope = scope
   1.306 +
   1.307 +    def __str__(self):
   1.308 +        return self.QName()
   1.309 +
   1.310 +    def QName(self):
   1.311 +        return self.scope.QName() + self.name
   1.312 +
   1.313 +    def __hash__(self):
   1.314 +        return self.QName().__hash__()
   1.315 +
   1.316 +    def __eq__(self, other):
   1.317 +        return self.QName() == other.QName()
   1.318 +
   1.319 +    def object(self):
   1.320 +        return self.scope.lookupIdentifier(self)
   1.321 +
   1.322 +class IDLUnresolvedIdentifier(IDLObject):
   1.323 +    def __init__(self, location, name, allowDoubleUnderscore = False,
   1.324 +                 allowForbidden = False):
   1.325 +        IDLObject.__init__(self, location)
   1.326 +
   1.327 +        assert len(name) > 0
   1.328 +
   1.329 +        if name[:2] == "__" and name != "__content" and name != "___noSuchMethod__"  and not allowDoubleUnderscore:
   1.330 +            raise WebIDLError("Identifiers beginning with __ are reserved",
   1.331 +                              [location])
   1.332 +        if name[0] == '_' and not allowDoubleUnderscore:
   1.333 +            name = name[1:]
   1.334 +        # TODO: Bug 872377, Restore "toJSON" to below list.
   1.335 +        # We sometimes need custom serialization, so allow toJSON for now.
   1.336 +        if (name in ["constructor", "toString"] and
   1.337 +            not allowForbidden):
   1.338 +            raise WebIDLError("Cannot use reserved identifier '%s'" % (name),
   1.339 +                              [location])
   1.340 +
   1.341 +        self.name = name
   1.342 +
   1.343 +    def __str__(self):
   1.344 +        return self.QName()
   1.345 +
   1.346 +    def QName(self):
   1.347 +        return "<unresolved scope>::" + self.name
   1.348 +
   1.349 +    def resolve(self, scope, object):
   1.350 +        assert isinstance(scope, IDLScope)
   1.351 +        assert not object or isinstance(object, IDLObjectWithIdentifier)
   1.352 +        assert not object or object.identifier == self
   1.353 +
   1.354 +        scope.ensureUnique(self, object)
   1.355 +
   1.356 +        identifier = IDLIdentifier(self.location, scope, self.name)
   1.357 +        if object:
   1.358 +            object.identifier = identifier
   1.359 +        return identifier
   1.360 +
   1.361 +    def finish(self):
   1.362 +        assert False # Should replace with a resolved identifier first.
   1.363 +
   1.364 +class IDLObjectWithIdentifier(IDLObject):
   1.365 +    def __init__(self, location, parentScope, identifier):
   1.366 +        IDLObject.__init__(self, location)
   1.367 +
   1.368 +        assert isinstance(identifier, IDLUnresolvedIdentifier)
   1.369 +
   1.370 +        self.identifier = identifier
   1.371 +
   1.372 +        if parentScope:
   1.373 +            self.resolve(parentScope)
   1.374 +
   1.375 +        self.treatNullAs = "Default"
   1.376 +
   1.377 +    def resolve(self, parentScope):
   1.378 +        assert isinstance(parentScope, IDLScope)
   1.379 +        assert isinstance(self.identifier, IDLUnresolvedIdentifier)
   1.380 +        self.identifier.resolve(parentScope, self)
   1.381 +
   1.382 +    def checkForStringHandlingExtendedAttributes(self, attrs,
   1.383 +                                                 isDictionaryMember=False,
   1.384 +                                                 isOptional=False):
   1.385 +        """
   1.386 +        A helper function to deal with TreatNullAs.  Returns the list
   1.387 +        of attrs it didn't handle itself.
   1.388 +        """
   1.389 +        assert isinstance(self, IDLArgument) or isinstance(self, IDLAttribute)
   1.390 +        unhandledAttrs = list()
   1.391 +        for attr in attrs:
   1.392 +            if not attr.hasValue():
   1.393 +                unhandledAttrs.append(attr)
   1.394 +                continue
   1.395 +
   1.396 +            identifier = attr.identifier()
   1.397 +            value = attr.value()
   1.398 +            if identifier == "TreatNullAs":
   1.399 +                if not self.type.isDOMString() or self.type.nullable():
   1.400 +                    raise WebIDLError("[TreatNullAs] is only allowed on "
   1.401 +                                      "arguments or attributes whose type is "
   1.402 +                                      "DOMString",
   1.403 +                                      [self.location])
   1.404 +                if isDictionaryMember:
   1.405 +                    raise WebIDLError("[TreatNullAs] is not allowed for "
   1.406 +                                      "dictionary members", [self.location])
   1.407 +                if value != 'EmptyString':
   1.408 +                    raise WebIDLError("[TreatNullAs] must take the identifier "
   1.409 +                                      "'EmptyString', not '%s'" % value,
   1.410 +                                      [self.location])
   1.411 +                self.treatNullAs = value
   1.412 +            else:
   1.413 +                unhandledAttrs.append(attr)
   1.414 +
   1.415 +        return unhandledAttrs
   1.416 +
   1.417 +class IDLObjectWithScope(IDLObjectWithIdentifier, IDLScope):
   1.418 +    def __init__(self, location, parentScope, identifier):
   1.419 +        assert isinstance(identifier, IDLUnresolvedIdentifier)
   1.420 +
   1.421 +        IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier)
   1.422 +        IDLScope.__init__(self, location, parentScope, self.identifier)
   1.423 +
   1.424 +class IDLIdentifierPlaceholder(IDLObjectWithIdentifier):
   1.425 +    def __init__(self, location, identifier):
   1.426 +        assert isinstance(identifier, IDLUnresolvedIdentifier)
   1.427 +        IDLObjectWithIdentifier.__init__(self, location, None, identifier)
   1.428 +
   1.429 +    def finish(self, scope):
   1.430 +        try:
   1.431 +            scope._lookupIdentifier(self.identifier)
   1.432 +        except:
   1.433 +            raise WebIDLError("Unresolved type '%s'." % self.identifier,
   1.434 +                              [self.location])
   1.435 +
   1.436 +        obj = self.identifier.resolve(scope, None)
   1.437 +        return scope.lookupIdentifier(obj)
   1.438 +
   1.439 +class IDLExternalInterface(IDLObjectWithIdentifier):
   1.440 +    def __init__(self, location, parentScope, identifier):
   1.441 +        assert isinstance(identifier, IDLUnresolvedIdentifier)
   1.442 +        assert isinstance(parentScope, IDLScope)
   1.443 +        self.parent = None
   1.444 +        IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier)
   1.445 +        IDLObjectWithIdentifier.resolve(self, parentScope)
   1.446 +
   1.447 +    def finish(self, scope):
   1.448 +        pass
   1.449 +
   1.450 +    def validate(self):
   1.451 +        pass
   1.452 +
   1.453 +    def isExternal(self):
   1.454 +        return True
   1.455 +
   1.456 +    def isInterface(self):
   1.457 +        return True
   1.458 +
   1.459 +    def isConsequential(self):
   1.460 +        return False
   1.461 +
   1.462 +    def addExtendedAttributes(self, attrs):
   1.463 +        assert len(attrs) == 0
   1.464 +
   1.465 +    def resolve(self, parentScope):
   1.466 +        pass
   1.467 +
   1.468 +    def getJSImplementation(self):
   1.469 +        return None
   1.470 +
   1.471 +    def isJSImplemented(self):
   1.472 +        return False
   1.473 +
   1.474 +    def getNavigatorProperty(self):
   1.475 +        return None
   1.476 +
   1.477 +    def _getDependentObjects(self):
   1.478 +        return set()
   1.479 +
   1.480 +class IDLInterface(IDLObjectWithScope):
   1.481 +    def __init__(self, location, parentScope, name, parent, members,
   1.482 +                 isPartial):
   1.483 +        assert isinstance(parentScope, IDLScope)
   1.484 +        assert isinstance(name, IDLUnresolvedIdentifier)
   1.485 +        assert not isPartial or not parent
   1.486 +
   1.487 +        self.parent = None
   1.488 +        self._callback = False
   1.489 +        self._finished = False
   1.490 +        self.members = []
   1.491 +        # namedConstructors needs deterministic ordering because bindings code
   1.492 +        # outputs the constructs in the order that namedConstructors enumerates
   1.493 +        # them.
   1.494 +        self.namedConstructors = list()
   1.495 +        self.implementedInterfaces = set()
   1.496 +        self._consequential = False
   1.497 +        self._isPartial = True
   1.498 +        # self.interfacesBasedOnSelf is the set of interfaces that inherit from
   1.499 +        # self or have self as a consequential interface, including self itself.
   1.500 +        # Used for distinguishability checking.
   1.501 +        self.interfacesBasedOnSelf = set([self])
   1.502 +        # self.interfacesImplementingSelf is the set of interfaces that directly
   1.503 +        # have self as a consequential interface
   1.504 +        self.interfacesImplementingSelf = set()
   1.505 +        self._hasChildInterfaces = False
   1.506 +        self._isOnGlobalProtoChain = False
   1.507 +        # Tracking of the number of reserved slots we need for our
   1.508 +        # members and those of ancestor interfaces.
   1.509 +        self.totalMembersInSlots = 0
   1.510 +        # Tracking of the number of own own members we have in slots
   1.511 +        self._ownMembersInSlots = 0
   1.512 +
   1.513 +        IDLObjectWithScope.__init__(self, location, parentScope, name)
   1.514 +
   1.515 +        if not isPartial:
   1.516 +            self.setNonPartial(location, parent, members)
   1.517 +        else:
   1.518 +            # Just remember our members for now
   1.519 +            self.members = members
   1.520 +
   1.521 +    def __str__(self):
   1.522 +        return "Interface '%s'" % self.identifier.name
   1.523 +
   1.524 +    def ctor(self):
   1.525 +        identifier = IDLUnresolvedIdentifier(self.location, "constructor",
   1.526 +                                             allowForbidden=True)
   1.527 +        try:
   1.528 +            return self._lookupIdentifier(identifier)
   1.529 +        except:
   1.530 +            return None
   1.531 +
   1.532 +    def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject):
   1.533 +        assert isinstance(scope, IDLScope)
   1.534 +        assert isinstance(originalObject, IDLInterfaceMember)
   1.535 +        assert isinstance(newObject, IDLInterfaceMember)
   1.536 +
   1.537 +        retval = IDLScope.resolveIdentifierConflict(self, scope, identifier,
   1.538 +                                                    originalObject, newObject)
   1.539 +
   1.540 +        # Might be a ctor, which isn't in self.members
   1.541 +        if newObject in self.members:
   1.542 +            self.members.remove(newObject)
   1.543 +        return retval
   1.544 +
   1.545 +    def finish(self, scope):
   1.546 +        if self._finished:
   1.547 +            return
   1.548 +
   1.549 +        self._finished = True
   1.550 +
   1.551 +        if self._isPartial:
   1.552 +            raise WebIDLError("Interface %s does not have a non-partial "
   1.553 +                              "declaration" % self.identifier.name,
   1.554 +                              [self.location])
   1.555 +
   1.556 +        assert not self.parent or isinstance(self.parent, IDLIdentifierPlaceholder)
   1.557 +        parent = self.parent.finish(scope) if self.parent else None
   1.558 +        if parent and isinstance(parent, IDLExternalInterface):
   1.559 +            raise WebIDLError("%s inherits from %s which does not have "
   1.560 +                              "a definition" %
   1.561 +                              (self.identifier.name,
   1.562 +                               self.parent.identifier.name),
   1.563 +                              [self.location])
   1.564 +        assert not parent or isinstance(parent, IDLInterface)
   1.565 +
   1.566 +        self.parent = parent
   1.567 +
   1.568 +        assert iter(self.members)
   1.569 +
   1.570 +        if self.parent:
   1.571 +            self.parent.finish(scope)
   1.572 +
   1.573 +            self.parent._hasChildInterfaces = True
   1.574 +
   1.575 +            self.totalMembersInSlots = self.parent.totalMembersInSlots
   1.576 +
   1.577 +            # Interfaces with [Global] must not have anything inherit from them
   1.578 +            if self.parent.getExtendedAttribute("Global"):
   1.579 +                # Note: This is not a self.parent.isOnGlobalProtoChain() check
   1.580 +                # because ancestors of a [Global] interface can have other
   1.581 +                # descendants.
   1.582 +                raise WebIDLError("[Global] interface has another interface "
   1.583 +                                  "inheriting from it",
   1.584 +                                  [self.location, self.parent.location])
   1.585 +
   1.586 +            # Callbacks must not inherit from non-callbacks or inherit from
   1.587 +            # anything that has consequential interfaces.
   1.588 +            # XXXbz Can non-callbacks inherit from callbacks?  Spec issue pending.
   1.589 +            # XXXbz Can callbacks have consequential interfaces?  Spec issue pending
   1.590 +            if self.isCallback():
   1.591 +                if not self.parent.isCallback():
   1.592 +                    raise WebIDLError("Callback interface %s inheriting from "
   1.593 +                                      "non-callback interface %s" %
   1.594 +                                      (self.identifier.name,
   1.595 +                                       self.parent.identifier.name),
   1.596 +                                      [self.location, self.parent.location])
   1.597 +            elif self.parent.isCallback():
   1.598 +                raise WebIDLError("Non-callback interface %s inheriting from "
   1.599 +                                  "callback interface %s" %
   1.600 +                                  (self.identifier.name,
   1.601 +                                   self.parent.identifier.name),
   1.602 +                                  [self.location, self.parent.location])
   1.603 +
   1.604 +        for iface in self.implementedInterfaces:
   1.605 +            iface.finish(scope)
   1.606 +
   1.607 +        cycleInGraph = self.findInterfaceLoopPoint(self)
   1.608 +        if cycleInGraph:
   1.609 +            raise WebIDLError("Interface %s has itself as ancestor or "
   1.610 +                              "implemented interface" % self.identifier.name,
   1.611 +                              [self.location, cycleInGraph.location])
   1.612 +
   1.613 +        if self.isCallback():
   1.614 +            # "implements" should have made sure we have no
   1.615 +            # consequential interfaces.
   1.616 +            assert len(self.getConsequentialInterfaces()) == 0
   1.617 +            # And that we're not consequential.
   1.618 +            assert not self.isConsequential()
   1.619 +
   1.620 +        # Now resolve() and finish() our members before importing the
   1.621 +        # ones from our implemented interfaces.
   1.622 +
   1.623 +        # resolve() will modify self.members, so we need to iterate
   1.624 +        # over a copy of the member list here.
   1.625 +        for member in list(self.members):
   1.626 +            member.resolve(self)
   1.627 +
   1.628 +        for member in self.members:
   1.629 +            member.finish(scope)
   1.630 +
   1.631 +        ctor = self.ctor()
   1.632 +        if ctor is not None:
   1.633 +            ctor.finish(scope)
   1.634 +
   1.635 +        for ctor in self.namedConstructors:
   1.636 +            ctor.finish(scope)
   1.637 +
   1.638 +        # Make a copy of our member list, so things that implement us
   1.639 +        # can get those without all the stuff we implement ourselves
   1.640 +        # admixed.
   1.641 +        self.originalMembers = list(self.members)
   1.642 +
   1.643 +        # Import everything from our consequential interfaces into
   1.644 +        # self.members.  Sort our consequential interfaces by name
   1.645 +        # just so we have a consistent order.
   1.646 +        for iface in sorted(self.getConsequentialInterfaces(),
   1.647 +                            cmp=cmp,
   1.648 +                            key=lambda x: x.identifier.name):
   1.649 +            # Flag the interface as being someone's consequential interface
   1.650 +            iface.setIsConsequentialInterfaceOf(self)
   1.651 +            additionalMembers = iface.originalMembers;
   1.652 +            for additionalMember in additionalMembers:
   1.653 +                for member in self.members:
   1.654 +                    if additionalMember.identifier.name == member.identifier.name:
   1.655 +                        raise WebIDLError(
   1.656 +                            "Multiple definitions of %s on %s coming from 'implements' statements" %
   1.657 +                            (member.identifier.name, self),
   1.658 +                            [additionalMember.location, member.location])
   1.659 +            self.members.extend(additionalMembers)
   1.660 +            iface.interfacesImplementingSelf.add(self)
   1.661 +
   1.662 +        for ancestor in self.getInheritedInterfaces():
   1.663 +            ancestor.interfacesBasedOnSelf.add(self)
   1.664 +            for ancestorConsequential in ancestor.getConsequentialInterfaces():
   1.665 +                ancestorConsequential.interfacesBasedOnSelf.add(self)
   1.666 +
   1.667 +        for member in self.members:
   1.668 +            if (member.isAttr() and member.isUnforgeable() and
   1.669 +                not hasattr(member, "originatingInterface")):
   1.670 +                member.originatingInterface = self
   1.671 +
   1.672 +        # Compute slot indices for our members before we pull in
   1.673 +        # unforgeable members from our parent.
   1.674 +        for member in self.members:
   1.675 +            if (member.isAttr() and
   1.676 +                (member.getExtendedAttribute("StoreInSlot") or
   1.677 +                 member.getExtendedAttribute("Cached"))):
   1.678 +                member.slotIndex = self.totalMembersInSlots
   1.679 +                self.totalMembersInSlots += 1
   1.680 +                if member.getExtendedAttribute("StoreInSlot"):
   1.681 +                    self._ownMembersInSlots += 1
   1.682 +
   1.683 +        if self.parent:
   1.684 +            # Make sure we don't shadow any of the [Unforgeable] attributes on
   1.685 +            # our ancestor interfaces.  We don't have to worry about
   1.686 +            # consequential interfaces here, because those have already been
   1.687 +            # imported into the relevant .members lists.  And we don't have to
   1.688 +            # worry about anything other than our parent, because it has already
   1.689 +            # imported its ancestors unforgeable attributes into its member
   1.690 +            # list.
   1.691 +            for unforgeableAttr in (attr for attr in self.parent.members if
   1.692 +                                    attr.isAttr() and not attr.isStatic() and
   1.693 +                                    attr.isUnforgeable()):
   1.694 +                shadows = [ m for m in self.members if
   1.695 +                            (m.isAttr() or m.isMethod()) and
   1.696 +                            not m.isStatic() and
   1.697 +                            m.identifier.name == unforgeableAttr.identifier.name ]
   1.698 +                if len(shadows) != 0:
   1.699 +                    locs = [unforgeableAttr.location] + [ s.location for s
   1.700 +                                                          in shadows ]
   1.701 +                    raise WebIDLError("Interface %s shadows [Unforgeable] "
   1.702 +                                      "members of %s" %
   1.703 +                                      (self.identifier.name,
   1.704 +                                       ancestor.identifier.name),
   1.705 +                                      locs)
   1.706 +                # And now just stick it in our members, since we won't be
   1.707 +                # inheriting this down the proto chain.  If we really cared we
   1.708 +                # could try to do something where we set up the unforgeable
   1.709 +                # attributes of ancestor interfaces, with their corresponding
   1.710 +                # getters, on our interface, but that gets pretty complicated
   1.711 +                # and seems unnecessary.
   1.712 +                self.members.append(unforgeableAttr)
   1.713 +
   1.714 +        # Ensure that there's at most one of each {named,indexed}
   1.715 +        # {getter,setter,creator,deleter}, at most one stringifier,
   1.716 +        # and at most one legacycaller.  Note that this last is not
   1.717 +        # quite per spec, but in practice no one overloads
   1.718 +        # legacycallers.
   1.719 +        specialMembersSeen = {}
   1.720 +        for member in self.members:
   1.721 +            if not member.isMethod():
   1.722 +                continue
   1.723 +
   1.724 +            if member.isGetter():
   1.725 +                memberType = "getters"
   1.726 +            elif member.isSetter():
   1.727 +                memberType = "setters"
   1.728 +            elif member.isCreator():
   1.729 +                memberType = "creators"
   1.730 +            elif member.isDeleter():
   1.731 +                memberType = "deleters"
   1.732 +            elif member.isStringifier():
   1.733 +                memberType = "stringifiers"
   1.734 +            elif member.isJsonifier():
   1.735 +                memberType = "jsonifiers"
   1.736 +            elif member.isLegacycaller():
   1.737 +                memberType = "legacycallers"
   1.738 +            else:
   1.739 +                continue
   1.740 +
   1.741 +            if (memberType != "stringifiers" and memberType != "legacycallers" and
   1.742 +                memberType != "jsonifiers"):
   1.743 +                if member.isNamed():
   1.744 +                    memberType = "named " + memberType
   1.745 +                else:
   1.746 +                    assert member.isIndexed()
   1.747 +                    memberType = "indexed " + memberType
   1.748 +
   1.749 +            if memberType in specialMembersSeen:
   1.750 +                raise WebIDLError("Multiple " + memberType + " on %s" % (self),
   1.751 +                                   [self.location,
   1.752 +                                    specialMembersSeen[memberType].location,
   1.753 +                                    member.location])
   1.754 +
   1.755 +            specialMembersSeen[memberType] = member
   1.756 +
   1.757 +        if self._isOnGlobalProtoChain:
   1.758 +            # Make sure we have no named setters, creators, or deleters
   1.759 +            for memberType in ["setter", "creator", "deleter"]:
   1.760 +                memberId = "named " + memberType + "s"
   1.761 +                if memberId in specialMembersSeen:
   1.762 +                    raise WebIDLError("Interface with [Global] has a named %s" %
   1.763 +                                      memberType,
   1.764 +                                      [self.location,
   1.765 +                                       specialMembersSeen[memberId].location])
   1.766 +            # Make sure we're not [OverrideBuiltins]
   1.767 +            if self.getExtendedAttribute("OverrideBuiltins"):
   1.768 +                raise WebIDLError("Interface with [Global] also has "
   1.769 +                                  "[OverrideBuiltins]",
   1.770 +                                  [self.location])
   1.771 +            # Mark all of our ancestors as being on the global's proto chain too
   1.772 +            parent = self.parent
   1.773 +            while parent:
   1.774 +                # Must not inherit from an interface with [OverrideBuiltins]
   1.775 +                if parent.getExtendedAttribute("OverrideBuiltins"):
   1.776 +                    raise WebIDLError("Interface with [Global] inherits from "
   1.777 +                                      "interface with [OverrideBuiltins]",
   1.778 +                                      [self.location, parent.location])
   1.779 +                parent._isOnGlobalProtoChain = True
   1.780 +                parent = parent.parent
   1.781 +
   1.782 +    def validate(self):
   1.783 +        for member in self.members:
   1.784 +            member.validate()
   1.785 +
   1.786 +            # Check that PutForwards refers to another attribute and that no
   1.787 +            # cycles exist in forwarded assignments.
   1.788 +            if member.isAttr():
   1.789 +                iface = self
   1.790 +                attr = member
   1.791 +                putForwards = attr.getExtendedAttribute("PutForwards")
   1.792 +                if putForwards and self.isCallback():
   1.793 +                    raise WebIDLError("[PutForwards] used on an attribute "
   1.794 +                                      "on interface %s which is a callback "
   1.795 +                                      "interface" % self.identifier.name,
   1.796 +                                      [self.location, member.location])
   1.797 +
   1.798 +                while putForwards is not None:
   1.799 +                    forwardIface = attr.type.unroll().inner
   1.800 +                    fowardAttr = None
   1.801 +
   1.802 +                    for forwardedMember in forwardIface.members:
   1.803 +                        if (not forwardedMember.isAttr() or
   1.804 +                            forwardedMember.identifier.name != putForwards[0]):
   1.805 +                            continue
   1.806 +                        if forwardedMember == member:
   1.807 +                            raise WebIDLError("Cycle detected in forwarded "
   1.808 +                                              "assignments for attribute %s on "
   1.809 +                                              "%s" %
   1.810 +                                              (member.identifier.name, self),
   1.811 +                                              [member.location])
   1.812 +                        fowardAttr = forwardedMember
   1.813 +                        break
   1.814 +
   1.815 +                    if fowardAttr is None:
   1.816 +                        raise WebIDLError("Attribute %s on %s forwards to "
   1.817 +                                          "missing attribute %s" %
   1.818 +                              (attr.identifier.name, iface, putForwards),
   1.819 +                              [attr.location])
   1.820 +
   1.821 +                    iface = forwardIface
   1.822 +                    attr = fowardAttr
   1.823 +                    putForwards = attr.getExtendedAttribute("PutForwards")
   1.824 +
   1.825 +
   1.826 +    def isInterface(self):
   1.827 +        return True
   1.828 +
   1.829 +    def isExternal(self):
   1.830 +        return False
   1.831 +
   1.832 +    def setIsConsequentialInterfaceOf(self, other):
   1.833 +        self._consequential = True
   1.834 +        self.interfacesBasedOnSelf.add(other)
   1.835 +
   1.836 +    def isConsequential(self):
   1.837 +        return self._consequential
   1.838 +
   1.839 +    def setCallback(self, value):
   1.840 +        self._callback = value
   1.841 +
   1.842 +    def isCallback(self):
   1.843 +        return self._callback
   1.844 +
   1.845 +    def isSingleOperationInterface(self):
   1.846 +        assert self.isCallback() or self.isJSImplemented()
   1.847 +        return (
   1.848 +            # JS-implemented things should never need the
   1.849 +            # this-handling weirdness of single-operation interfaces.
   1.850 +            not self.isJSImplemented() and
   1.851 +            # Not inheriting from another interface
   1.852 +            not self.parent and
   1.853 +            # No consequential interfaces
   1.854 +            len(self.getConsequentialInterfaces()) == 0 and
   1.855 +            # No attributes of any kinds
   1.856 +            not any(m.isAttr() for m in self.members) and
   1.857 +            # There is at least one regular operation, and all regular
   1.858 +            # operations have the same identifier
   1.859 +            len(set(m.identifier.name for m in self.members if
   1.860 +                    m.isMethod() and not m.isStatic())) == 1)
   1.861 +
   1.862 +    def inheritanceDepth(self):
   1.863 +        depth = 0
   1.864 +        parent = self.parent
   1.865 +        while parent:
   1.866 +            depth = depth + 1
   1.867 +            parent = parent.parent
   1.868 +        return depth
   1.869 +
   1.870 +    def hasConstants(self):
   1.871 +        return any(m.isConst() for m in self.members)
   1.872 +
   1.873 +    def hasInterfaceObject(self):
   1.874 +        if self.isCallback():
   1.875 +            return self.hasConstants()
   1.876 +        return not hasattr(self, "_noInterfaceObject")
   1.877 +
   1.878 +    def hasInterfacePrototypeObject(self):
   1.879 +        return not self.isCallback() and self.getUserData('hasConcreteDescendant', False)
   1.880 +
   1.881 +    def addExtendedAttributes(self, attrs):
   1.882 +        self._extendedAttrDict = {}
   1.883 +        for attr in attrs:
   1.884 +            identifier = attr.identifier()
   1.885 +
   1.886 +            # Special cased attrs
   1.887 +            if identifier == "TreatNonCallableAsNull":
   1.888 +                raise WebIDLError("TreatNonCallableAsNull cannot be specified on interfaces",
   1.889 +                                  [attr.location, self.location])
   1.890 +            if identifier == "TreatNonObjectAsNull":
   1.891 +                raise WebIDLError("TreatNonObjectAsNull cannot be specified on interfaces",
   1.892 +                                  [attr.location, self.location])
   1.893 +            elif identifier == "NoInterfaceObject":
   1.894 +                if not attr.noArguments():
   1.895 +                    raise WebIDLError("[NoInterfaceObject] must take no arguments",
   1.896 +                                      [attr.location])
   1.897 +
   1.898 +                if self.ctor():
   1.899 +                    raise WebIDLError("Constructor and NoInterfaceObject are incompatible",
   1.900 +                                      [self.location])
   1.901 +
   1.902 +                self._noInterfaceObject = True
   1.903 +            elif identifier == "Constructor" or identifier == "NamedConstructor" or identifier == "ChromeConstructor":
   1.904 +                if identifier == "Constructor" and not self.hasInterfaceObject():
   1.905 +                    raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible",
   1.906 +                                      [self.location])
   1.907 +
   1.908 +                if identifier == "NamedConstructor" and not attr.hasValue():
   1.909 +                    raise WebIDLError("NamedConstructor must either take an identifier or take a named argument list",
   1.910 +                                      [attr.location])
   1.911 +
   1.912 +                if identifier == "ChromeConstructor" and not self.hasInterfaceObject():
   1.913 +                    raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible",
   1.914 +                                      [self.location])
   1.915 +
   1.916 +                args = attr.args() if attr.hasArgs() else []
   1.917 +
   1.918 +                retType = IDLWrapperType(self.location, self)
   1.919 +                
   1.920 +                if identifier == "Constructor" or identifier == "ChromeConstructor":
   1.921 +                    name = "constructor"
   1.922 +                    allowForbidden = True
   1.923 +                else:
   1.924 +                    name = attr.value()
   1.925 +                    allowForbidden = False
   1.926 +
   1.927 +                methodIdentifier = IDLUnresolvedIdentifier(self.location, name,
   1.928 +                                                           allowForbidden=allowForbidden)
   1.929 +
   1.930 +                method = IDLMethod(self.location, methodIdentifier, retType,
   1.931 +                                   args, static=True)
   1.932 +                # Constructors are always NewObject and are always
   1.933 +                # assumed to be able to throw (since there's no way to
   1.934 +                # indicate otherwise) and never have any other
   1.935 +                # extended attributes.
   1.936 +                method.addExtendedAttributes(
   1.937 +                    [IDLExtendedAttribute(self.location, ("NewObject",)),
   1.938 +                     IDLExtendedAttribute(self.location, ("Throws",))])
   1.939 +                if identifier == "ChromeConstructor":
   1.940 +                    method.addExtendedAttributes(
   1.941 +                        [IDLExtendedAttribute(self.location, ("ChromeOnly",))])
   1.942 +
   1.943 +                if identifier == "Constructor" or identifier == "ChromeConstructor":
   1.944 +                    method.resolve(self)
   1.945 +                else:
   1.946 +                    # We need to detect conflicts for NamedConstructors across
   1.947 +                    # interfaces. We first call resolve on the parentScope,
   1.948 +                    # which will merge all NamedConstructors with the same
   1.949 +                    # identifier accross interfaces as overloads.
   1.950 +                    method.resolve(self.parentScope)
   1.951 +
   1.952 +                    # Then we look up the identifier on the parentScope. If the
   1.953 +                    # result is the same as the method we're adding then it
   1.954 +                    # hasn't been added as an overload and it's the first time
   1.955 +                    # we've encountered a NamedConstructor with that identifier.
   1.956 +                    # If the result is not the same as the method we're adding
   1.957 +                    # then it has been added as an overload and we need to check
   1.958 +                    # whether the result is actually one of our existing
   1.959 +                    # NamedConstructors.
   1.960 +                    newMethod = self.parentScope.lookupIdentifier(method.identifier)
   1.961 +                    if newMethod == method:
   1.962 +                        self.namedConstructors.append(method)
   1.963 +                    elif not newMethod in self.namedConstructors:
   1.964 +                        raise WebIDLError("NamedConstructor conflicts with a NamedConstructor of a different interface",
   1.965 +                                          [method.location, newMethod.location])
   1.966 +            elif (identifier == "ArrayClass"):
   1.967 +                if not attr.noArguments():
   1.968 +                    raise WebIDLError("[ArrayClass] must take no arguments",
   1.969 +                                      [attr.location])
   1.970 +                if self.parent:
   1.971 +                    raise WebIDLError("[ArrayClass] must not be specified on "
   1.972 +                                      "an interface with inherited interfaces",
   1.973 +                                      [attr.location, self.location])
   1.974 +            elif identifier == "Global":
   1.975 +                if not attr.noArguments():
   1.976 +                    raise WebIDLError("[Global] must take no arguments",
   1.977 +                                      [attr.location])
   1.978 +                self._isOnGlobalProtoChain = True
   1.979 +            elif (identifier == "NeedNewResolve" or
   1.980 +                  identifier == "OverrideBuiltins" or
   1.981 +                  identifier == "ChromeOnly"):
   1.982 +                # Known extended attributes that do not take values
   1.983 +                if not attr.noArguments():
   1.984 +                    raise WebIDLError("[%s] must take no arguments" % identifier,
   1.985 +                                      [attr.location])
   1.986 +            elif (identifier == "Pref" or
   1.987 +                  identifier == "JSImplementation" or
   1.988 +                  identifier == "HeaderFile" or
   1.989 +                  identifier == "NavigatorProperty" or
   1.990 +                  identifier == "AvailableIn" or
   1.991 +                  identifier == "Func"):
   1.992 +                # Known extended attributes that take a string value
   1.993 +                if not attr.hasValue():
   1.994 +                    raise WebIDLError("[%s] must have a value" % identifier,
   1.995 +                                      [attr.location])
   1.996 +            else:
   1.997 +                raise WebIDLError("Unknown extended attribute %s on interface" % identifier,
   1.998 +                                  [attr.location])
   1.999 +
  1.1000 +            attrlist = attr.listValue()
  1.1001 +            self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True
  1.1002 +
  1.1003 +    def addImplementedInterface(self, implementedInterface):
  1.1004 +        assert(isinstance(implementedInterface, IDLInterface))
  1.1005 +        self.implementedInterfaces.add(implementedInterface)
  1.1006 +
  1.1007 +    def getInheritedInterfaces(self):
  1.1008 +        """
  1.1009 +        Returns a list of the interfaces this interface inherits from
  1.1010 +        (not including this interface itself).  The list is in order
  1.1011 +        from most derived to least derived.
  1.1012 +        """
  1.1013 +        assert(self._finished)
  1.1014 +        if not self.parent:
  1.1015 +            return []
  1.1016 +        parentInterfaces = self.parent.getInheritedInterfaces()
  1.1017 +        parentInterfaces.insert(0, self.parent)
  1.1018 +        return parentInterfaces
  1.1019 +
  1.1020 +    def getConsequentialInterfaces(self):
  1.1021 +        assert(self._finished)
  1.1022 +        # The interfaces we implement directly
  1.1023 +        consequentialInterfaces = set(self.implementedInterfaces)
  1.1024 +
  1.1025 +        # And their inherited interfaces
  1.1026 +        for iface in self.implementedInterfaces:
  1.1027 +            consequentialInterfaces |= set(iface.getInheritedInterfaces())
  1.1028 +
  1.1029 +        # And now collect up the consequential interfaces of all of those
  1.1030 +        temp = set()
  1.1031 +        for iface in consequentialInterfaces:
  1.1032 +            temp |= iface.getConsequentialInterfaces()
  1.1033 +
  1.1034 +        return consequentialInterfaces | temp
  1.1035 +
  1.1036 +    def findInterfaceLoopPoint(self, otherInterface):
  1.1037 +        """
  1.1038 +        Finds an interface, amongst our ancestors and consequential interfaces,
  1.1039 +        that inherits from otherInterface or implements otherInterface
  1.1040 +        directly.  If there is no such interface, returns None.
  1.1041 +        """
  1.1042 +        if self.parent:
  1.1043 +            if self.parent == otherInterface:
  1.1044 +                return self
  1.1045 +            loopPoint = self.parent.findInterfaceLoopPoint(otherInterface)
  1.1046 +            if loopPoint:
  1.1047 +                return loopPoint
  1.1048 +        if otherInterface in self.implementedInterfaces:
  1.1049 +            return self
  1.1050 +        for iface in self.implementedInterfaces:
  1.1051 +            loopPoint = iface.findInterfaceLoopPoint(otherInterface)
  1.1052 +            if loopPoint:
  1.1053 +                return loopPoint
  1.1054 +        return None
  1.1055 +
  1.1056 +    def getExtendedAttribute(self, name):
  1.1057 +        return self._extendedAttrDict.get(name, None)
  1.1058 +
  1.1059 +    def setNonPartial(self, location, parent, members):
  1.1060 +        assert not parent or isinstance(parent, IDLIdentifierPlaceholder)
  1.1061 +        if not self._isPartial:
  1.1062 +            raise WebIDLError("Two non-partial definitions for the "
  1.1063 +                              "same interface",
  1.1064 +                              [location, self.location])
  1.1065 +        self._isPartial = False
  1.1066 +        # Now make it look like we were parsed at this new location, since
  1.1067 +        # that's the place where the interface is "really" defined
  1.1068 +        self.location = location
  1.1069 +        assert not self.parent
  1.1070 +        self.parent = parent
  1.1071 +        # Put the new members at the beginning
  1.1072 +        self.members = members + self.members
  1.1073 +
  1.1074 +    def getJSImplementation(self):
  1.1075 +        classId = self.getExtendedAttribute("JSImplementation")
  1.1076 +        if not classId:
  1.1077 +            return classId
  1.1078 +        assert isinstance(classId, list)
  1.1079 +        assert len(classId) == 1
  1.1080 +        return classId[0]
  1.1081 +
  1.1082 +    def isJSImplemented(self):
  1.1083 +        return bool(self.getJSImplementation())
  1.1084 +
  1.1085 +    def getNavigatorProperty(self):
  1.1086 +        naviProp = self.getExtendedAttribute("NavigatorProperty")
  1.1087 +        if not naviProp:
  1.1088 +            return None
  1.1089 +        assert len(naviProp) == 1
  1.1090 +        assert isinstance(naviProp, list)
  1.1091 +        assert len(naviProp[0]) != 0
  1.1092 +        return naviProp[0]
  1.1093 +
  1.1094 +    def hasChildInterfaces(self):
  1.1095 +        return self._hasChildInterfaces
  1.1096 +
  1.1097 +    def isOnGlobalProtoChain(self):
  1.1098 +        return self._isOnGlobalProtoChain
  1.1099 +
  1.1100 +    def _getDependentObjects(self):
  1.1101 +        deps = set(self.members)
  1.1102 +        deps.union(self.implementedInterfaces)
  1.1103 +        if self.parent:
  1.1104 +            deps.add(self.parent)
  1.1105 +        return deps
  1.1106 +
  1.1107 +    def hasMembersInSlots(self):
  1.1108 +        return self._ownMembersInSlots != 0
  1.1109 +
  1.1110 +class IDLDictionary(IDLObjectWithScope):
  1.1111 +    def __init__(self, location, parentScope, name, parent, members):
  1.1112 +        assert isinstance(parentScope, IDLScope)
  1.1113 +        assert isinstance(name, IDLUnresolvedIdentifier)
  1.1114 +        assert not parent or isinstance(parent, IDLIdentifierPlaceholder)
  1.1115 +
  1.1116 +        self.parent = parent
  1.1117 +        self._finished = False
  1.1118 +        self.members = list(members)
  1.1119 +
  1.1120 +        IDLObjectWithScope.__init__(self, location, parentScope, name)
  1.1121 +
  1.1122 +    def __str__(self):
  1.1123 +        return "Dictionary '%s'" % self.identifier.name
  1.1124 +
  1.1125 +    def isDictionary(self):
  1.1126 +        return True;
  1.1127 +
  1.1128 +    def finish(self, scope):
  1.1129 +        if self._finished:
  1.1130 +            return
  1.1131 +
  1.1132 +        self._finished = True
  1.1133 +
  1.1134 +        if self.parent:
  1.1135 +            assert isinstance(self.parent, IDLIdentifierPlaceholder)
  1.1136 +            oldParent = self.parent
  1.1137 +            self.parent = self.parent.finish(scope)
  1.1138 +            if not isinstance(self.parent, IDLDictionary):
  1.1139 +                raise WebIDLError("Dictionary %s has parent that is not a dictionary" %
  1.1140 +                                  self.identifier.name,
  1.1141 +                                  [oldParent.location, self.parent.location])
  1.1142 +
  1.1143 +            # Make sure the parent resolves all its members before we start
  1.1144 +            # looking at them.
  1.1145 +            self.parent.finish(scope)
  1.1146 +
  1.1147 +        for member in self.members:
  1.1148 +            member.resolve(self)
  1.1149 +            if not member.isComplete():
  1.1150 +                member.complete(scope)
  1.1151 +                assert member.type.isComplete()
  1.1152 +
  1.1153 +        # Members of a dictionary are sorted in lexicographic order
  1.1154 +        self.members.sort(cmp=cmp, key=lambda x: x.identifier.name)
  1.1155 +
  1.1156 +        inheritedMembers = []
  1.1157 +        ancestor = self.parent
  1.1158 +        while ancestor:
  1.1159 +            if ancestor == self:
  1.1160 +                raise WebIDLError("Dictionary %s has itself as an ancestor" %
  1.1161 +                                  self.identifier.name,
  1.1162 +                                  [self.identifier.location])
  1.1163 +            inheritedMembers.extend(ancestor.members)
  1.1164 +            ancestor = ancestor.parent
  1.1165 +
  1.1166 +        # Catch name duplication
  1.1167 +        for inheritedMember in inheritedMembers:
  1.1168 +            for member in self.members:
  1.1169 +                if member.identifier.name == inheritedMember.identifier.name:
  1.1170 +                    raise WebIDLError("Dictionary %s has two members with name %s" %
  1.1171 +                                      (self.identifier.name, member.identifier.name),
  1.1172 +                                      [member.location, inheritedMember.location])
  1.1173 +
  1.1174 +    def validate(self):
  1.1175 +        def typeContainsDictionary(memberType, dictionary):
  1.1176 +            """
  1.1177 +            Returns a tuple whose:
  1.1178 +
  1.1179 +                - First element is a Boolean value indicating whether
  1.1180 +                  memberType contains dictionary.
  1.1181 +
  1.1182 +                - Second element is:
  1.1183 +                    A list of locations that leads from the type that was passed in
  1.1184 +                    the memberType argument, to the dictionary being validated,
  1.1185 +                    if the boolean value in the first element is True.
  1.1186 +
  1.1187 +                    None, if the boolean value in the first element is False.
  1.1188 +            """
  1.1189 +
  1.1190 +            if (memberType.nullable() or
  1.1191 +                memberType.isArray() or
  1.1192 +                memberType.isSequence() or
  1.1193 +                memberType.isMozMap()):
  1.1194 +                return typeContainsDictionary(memberType.inner, dictionary)
  1.1195 +
  1.1196 +            if memberType.isDictionary():
  1.1197 +                if memberType.inner == dictionary:
  1.1198 +                    return (True, [memberType.location])
  1.1199 +
  1.1200 +                (contains, locations) = dictionaryContainsDictionary(memberType.inner, \
  1.1201 +                                                                     dictionary)
  1.1202 +                if contains:
  1.1203 +                    return (True, [memberType.location] + locations)
  1.1204 +
  1.1205 +            if memberType.isUnion():
  1.1206 +                for member in memberType.flatMemberTypes:
  1.1207 +                    (contains, locations) = typeContainsDictionary(member, dictionary)
  1.1208 +                    if contains:
  1.1209 +                        return (True, locations)
  1.1210 +
  1.1211 +            return (False, None)
  1.1212 +
  1.1213 +        def dictionaryContainsDictionary(dictMember, dictionary):
  1.1214 +            for member in dictMember.members:
  1.1215 +                (contains, locations) = typeContainsDictionary(member.type, dictionary)
  1.1216 +                if contains:
  1.1217 +                    return (True, [member.location] + locations)
  1.1218 +
  1.1219 +            if dictMember.parent:
  1.1220 +                if dictMember.parent == dictionary:
  1.1221 +                    return (True, [dictMember.location])
  1.1222 +                else:
  1.1223 +                    (contains, locations) = dictionaryContainsDictionary(dictMember.parent, dictionary)
  1.1224 +                    if contains:
  1.1225 +                        return (True, [dictMember.location] + locations)
  1.1226 +
  1.1227 +            return (False, None)
  1.1228 +
  1.1229 +        for member in self.members:
  1.1230 +            if member.type.isDictionary() and member.type.nullable():
  1.1231 +                raise WebIDLError("Dictionary %s has member with nullable "
  1.1232 +                                  "dictionary type" % self.identifier.name,
  1.1233 +                                  [member.location])
  1.1234 +            (contains, locations) = typeContainsDictionary(member.type, self)
  1.1235 +            if contains:
  1.1236 +                raise WebIDLError("Dictionary %s has member with itself as type." %
  1.1237 +                                  self.identifier.name,
  1.1238 +                                  [member.location] + locations)
  1.1239 +
  1.1240 +    def addExtendedAttributes(self, attrs):
  1.1241 +        assert len(attrs) == 0
  1.1242 +
  1.1243 +    def _getDependentObjects(self):
  1.1244 +        deps = set(self.members)
  1.1245 +        if (self.parent):
  1.1246 +            deps.add(self.parent)
  1.1247 +        return deps
  1.1248 +
  1.1249 +class IDLEnum(IDLObjectWithIdentifier):
  1.1250 +    def __init__(self, location, parentScope, name, values):
  1.1251 +        assert isinstance(parentScope, IDLScope)
  1.1252 +        assert isinstance(name, IDLUnresolvedIdentifier)
  1.1253 +
  1.1254 +        if len(values) != len(set(values)):
  1.1255 +            raise WebIDLError("Enum %s has multiple identical strings" % name.name,
  1.1256 +                              [location])
  1.1257 +
  1.1258 +        IDLObjectWithIdentifier.__init__(self, location, parentScope, name)
  1.1259 +        self._values = values
  1.1260 +
  1.1261 +    def values(self):
  1.1262 +        return self._values
  1.1263 +
  1.1264 +    def finish(self, scope):
  1.1265 +        pass
  1.1266 +
  1.1267 +    def validate(self):
  1.1268 +        pass
  1.1269 +
  1.1270 +    def isEnum(self):
  1.1271 +        return True
  1.1272 +
  1.1273 +    def addExtendedAttributes(self, attrs):
  1.1274 +        assert len(attrs) == 0
  1.1275 +
  1.1276 +    def _getDependentObjects(self):
  1.1277 +        return set()
  1.1278 +
  1.1279 +class IDLType(IDLObject):
  1.1280 +    Tags = enum(
  1.1281 +        # The integer types
  1.1282 +        'int8',
  1.1283 +        'uint8',
  1.1284 +        'int16',
  1.1285 +        'uint16',
  1.1286 +        'int32',
  1.1287 +        'uint32',
  1.1288 +        'int64',
  1.1289 +        'uint64',
  1.1290 +        # Additional primitive types
  1.1291 +        'bool',
  1.1292 +        'unrestricted_float',
  1.1293 +        'float',
  1.1294 +        'unrestricted_double',
  1.1295 +        # "double" last primitive type to match IDLBuiltinType
  1.1296 +        'double',
  1.1297 +        # Other types
  1.1298 +        'any',
  1.1299 +        'domstring',
  1.1300 +        'bytestring',
  1.1301 +        'object',
  1.1302 +        'date',
  1.1303 +        'void',
  1.1304 +        # Funny stuff
  1.1305 +        'interface',
  1.1306 +        'dictionary',
  1.1307 +        'enum',
  1.1308 +        'callback',
  1.1309 +        'union',
  1.1310 +        'sequence',
  1.1311 +        'mozmap',
  1.1312 +        'array'
  1.1313 +        )
  1.1314 +
  1.1315 +    def __init__(self, location, name):
  1.1316 +        IDLObject.__init__(self, location)
  1.1317 +        self.name = name
  1.1318 +        self.builtin = False
  1.1319 +
  1.1320 +    def __eq__(self, other):
  1.1321 +        return other and self.builtin == other.builtin and self.name == other.name
  1.1322 +
  1.1323 +    def __ne__(self, other):
  1.1324 +        return not self == other
  1.1325 +
  1.1326 +    def __str__(self):
  1.1327 +        return str(self.name)
  1.1328 +
  1.1329 +    def isType(self):
  1.1330 +        return True
  1.1331 +
  1.1332 +    def nullable(self):
  1.1333 +        return False
  1.1334 +
  1.1335 +    def isPrimitive(self):
  1.1336 +        return False
  1.1337 +
  1.1338 +    def isBoolean(self):
  1.1339 +        return False
  1.1340 +
  1.1341 +    def isNumeric(self):
  1.1342 +        return False
  1.1343 +
  1.1344 +    def isString(self):
  1.1345 +        return False
  1.1346 +
  1.1347 +    def isByteString(self):
  1.1348 +        return False
  1.1349 +
  1.1350 +    def isDOMString(self):
  1.1351 +        return False
  1.1352 +
  1.1353 +    def isVoid(self):
  1.1354 +        return self.name == "Void"
  1.1355 +
  1.1356 +    def isSequence(self):
  1.1357 +        return False
  1.1358 +
  1.1359 +    def isMozMap(self):
  1.1360 +        return False
  1.1361 +
  1.1362 +    def isArray(self):
  1.1363 +        return False
  1.1364 +
  1.1365 +    def isArrayBuffer(self):
  1.1366 +        return False
  1.1367 +
  1.1368 +    def isArrayBufferView(self):
  1.1369 +        return False
  1.1370 +
  1.1371 +    def isTypedArray(self):
  1.1372 +        return False
  1.1373 +
  1.1374 +    def isCallbackInterface(self):
  1.1375 +        return False
  1.1376 +
  1.1377 +    def isNonCallbackInterface(self):
  1.1378 +        return False
  1.1379 +
  1.1380 +    def isGeckoInterface(self):
  1.1381 +        """ Returns a boolean indicating whether this type is an 'interface'
  1.1382 +            type that is implemented in Gecko. At the moment, this returns
  1.1383 +            true for all interface types that are not types from the TypedArray
  1.1384 +            spec."""
  1.1385 +        return self.isInterface() and not self.isSpiderMonkeyInterface()
  1.1386 +
  1.1387 +    def isSpiderMonkeyInterface(self):
  1.1388 +        """ Returns a boolean indicating whether this type is an 'interface'
  1.1389 +            type that is implemented in Spidermonkey.  At the moment, this
  1.1390 +            only returns true for the types from the TypedArray spec. """
  1.1391 +        return self.isInterface() and (self.isArrayBuffer() or \
  1.1392 +                                       self.isArrayBufferView() or \
  1.1393 +                                       self.isTypedArray())
  1.1394 +
  1.1395 +    def isDictionary(self):
  1.1396 +        return False
  1.1397 +
  1.1398 +    def isInterface(self):
  1.1399 +        return False
  1.1400 +
  1.1401 +    def isAny(self):
  1.1402 +        return self.tag() == IDLType.Tags.any
  1.1403 +
  1.1404 +    def isDate(self):
  1.1405 +        return self.tag() == IDLType.Tags.date
  1.1406 +
  1.1407 +    def isObject(self):
  1.1408 +        return self.tag() == IDLType.Tags.object
  1.1409 +
  1.1410 +    def isPromise(self):
  1.1411 +        return False
  1.1412 +
  1.1413 +    def isComplete(self):
  1.1414 +        return True
  1.1415 +
  1.1416 +    def includesRestrictedFloat(self):
  1.1417 +        return False
  1.1418 +
  1.1419 +    def isFloat(self):
  1.1420 +        return False
  1.1421 +
  1.1422 +    def isUnrestricted(self):
  1.1423 +        # Should only call this on float types
  1.1424 +        assert self.isFloat()
  1.1425 +
  1.1426 +    def isSerializable(self):
  1.1427 +        return False
  1.1428 +
  1.1429 +    def tag(self):
  1.1430 +        assert False # Override me!
  1.1431 +
  1.1432 +    def treatNonCallableAsNull(self):
  1.1433 +        assert self.tag() == IDLType.Tags.callback
  1.1434 +        return self.nullable() and self.inner._treatNonCallableAsNull
  1.1435 +
  1.1436 +    def treatNonObjectAsNull(self):
  1.1437 +        assert self.tag() == IDLType.Tags.callback
  1.1438 +        return self.nullable() and self.inner._treatNonObjectAsNull
  1.1439 +
  1.1440 +    def addExtendedAttributes(self, attrs):
  1.1441 +        assert len(attrs) == 0
  1.1442 +
  1.1443 +    def resolveType(self, parentScope):
  1.1444 +        pass
  1.1445 +
  1.1446 +    def unroll(self):
  1.1447 +        return self
  1.1448 +
  1.1449 +    def isDistinguishableFrom(self, other):
  1.1450 +        raise TypeError("Can't tell whether a generic type is or is not "
  1.1451 +                        "distinguishable from other things")
  1.1452 +
  1.1453 +class IDLUnresolvedType(IDLType):
  1.1454 +    """
  1.1455 +        Unresolved types are interface types 
  1.1456 +    """
  1.1457 +
  1.1458 +    def __init__(self, location, name):
  1.1459 +        IDLType.__init__(self, location, name)
  1.1460 +
  1.1461 +    def isComplete(self):
  1.1462 +        return False
  1.1463 +
  1.1464 +    def complete(self, scope):
  1.1465 +        obj = None
  1.1466 +        try:
  1.1467 +            obj = scope._lookupIdentifier(self.name)
  1.1468 +        except:
  1.1469 +            raise WebIDLError("Unresolved type '%s'." % self.name,
  1.1470 +                              [self.location])
  1.1471 +
  1.1472 +        assert obj
  1.1473 +        if obj.isType():
  1.1474 +            # obj itself might not be complete; deal with that.
  1.1475 +            assert obj != self
  1.1476 +            if not obj.isComplete():
  1.1477 +                obj = obj.complete(scope)
  1.1478 +            return obj
  1.1479 +
  1.1480 +        name = self.name.resolve(scope, None)
  1.1481 +        return IDLWrapperType(self.location, obj)
  1.1482 +
  1.1483 +    def isDistinguishableFrom(self, other):
  1.1484 +        raise TypeError("Can't tell whether an unresolved type is or is not "
  1.1485 +                        "distinguishable from other things")
  1.1486 +
  1.1487 +class IDLNullableType(IDLType):
  1.1488 +    def __init__(self, location, innerType):
  1.1489 +        assert not innerType.isVoid()
  1.1490 +        assert not innerType == BuiltinTypes[IDLBuiltinType.Types.any]
  1.1491 +
  1.1492 +        IDLType.__init__(self, location, innerType.name)
  1.1493 +        self.inner = innerType
  1.1494 +        self.builtin = False
  1.1495 +
  1.1496 +    def __eq__(self, other):
  1.1497 +        return isinstance(other, IDLNullableType) and self.inner == other.inner
  1.1498 +
  1.1499 +    def __str__(self):
  1.1500 +        return self.inner.__str__() + "OrNull"
  1.1501 +
  1.1502 +    def nullable(self):
  1.1503 +        return True
  1.1504 +
  1.1505 +    def isCallback(self):
  1.1506 +        return self.inner.isCallback()
  1.1507 +
  1.1508 +    def isPrimitive(self):
  1.1509 +        return self.inner.isPrimitive()
  1.1510 +
  1.1511 +    def isBoolean(self):
  1.1512 +        return self.inner.isBoolean()
  1.1513 +
  1.1514 +    def isNumeric(self):
  1.1515 +        return self.inner.isNumeric()
  1.1516 +
  1.1517 +    def isString(self):
  1.1518 +        return self.inner.isString()
  1.1519 +
  1.1520 +    def isByteString(self):
  1.1521 +        return self.inner.isByteString()
  1.1522 +
  1.1523 +    def isDOMString(self):
  1.1524 +        return self.inner.isDOMString()
  1.1525 +
  1.1526 +    def isFloat(self):
  1.1527 +        return self.inner.isFloat()
  1.1528 +
  1.1529 +    def isUnrestricted(self):
  1.1530 +        return self.inner.isUnrestricted()
  1.1531 +
  1.1532 +    def includesRestrictedFloat(self):
  1.1533 +        return self.inner.includesRestrictedFloat()
  1.1534 +
  1.1535 +    def isInteger(self):
  1.1536 +        return self.inner.isInteger()
  1.1537 +
  1.1538 +    def isVoid(self):
  1.1539 +        return False
  1.1540 +
  1.1541 +    def isSequence(self):
  1.1542 +        return self.inner.isSequence()
  1.1543 +
  1.1544 +    def isMozMap(self):
  1.1545 +        return self.inner.isMozMap()
  1.1546 +
  1.1547 +    def isArray(self):
  1.1548 +        return self.inner.isArray()
  1.1549 +
  1.1550 +    def isArrayBuffer(self):
  1.1551 +        return self.inner.isArrayBuffer()
  1.1552 +
  1.1553 +    def isArrayBufferView(self):
  1.1554 +        return self.inner.isArrayBufferView()
  1.1555 +
  1.1556 +    def isTypedArray(self):
  1.1557 +        return self.inner.isTypedArray()
  1.1558 +
  1.1559 +    def isDictionary(self):
  1.1560 +        return self.inner.isDictionary()
  1.1561 +
  1.1562 +    def isInterface(self):
  1.1563 +        return self.inner.isInterface()
  1.1564 +
  1.1565 +    def isCallbackInterface(self):
  1.1566 +        return self.inner.isCallbackInterface()
  1.1567 +
  1.1568 +    def isNonCallbackInterface(self):
  1.1569 +        return self.inner.isNonCallbackInterface()
  1.1570 +
  1.1571 +    def isEnum(self):
  1.1572 +        return self.inner.isEnum()
  1.1573 +
  1.1574 +    def isUnion(self):
  1.1575 +        return self.inner.isUnion()
  1.1576 +
  1.1577 +    def isSerializable(self):
  1.1578 +        return self.inner.isSerializable()
  1.1579 +
  1.1580 +    def tag(self):
  1.1581 +        return self.inner.tag()
  1.1582 +
  1.1583 +    def resolveType(self, parentScope):
  1.1584 +        assert isinstance(parentScope, IDLScope)
  1.1585 +        self.inner.resolveType(parentScope)
  1.1586 +
  1.1587 +    def isComplete(self):
  1.1588 +        return self.inner.isComplete()
  1.1589 +
  1.1590 +    def complete(self, scope):
  1.1591 +        self.inner = self.inner.complete(scope)
  1.1592 +        if self.inner.nullable():
  1.1593 +            raise WebIDLError("The inner type of a nullable type must not be "
  1.1594 +                              "a nullable type",
  1.1595 +                              [self.location, self.inner.location])
  1.1596 +        if self.inner.isUnion():
  1.1597 +            if self.inner.hasNullableType:
  1.1598 +                raise WebIDLError("The inner type of a nullable type must not "
  1.1599 +                                  "be a union type that itself has a nullable "
  1.1600 +                                  "type as a member type", [self.location])
  1.1601 +
  1.1602 +        self.name = self.inner.name
  1.1603 +        return self
  1.1604 +
  1.1605 +    def unroll(self):
  1.1606 +        return self.inner.unroll()
  1.1607 +
  1.1608 +    def isDistinguishableFrom(self, other):
  1.1609 +        if (other.nullable() or (other.isUnion() and other.hasNullableType) or
  1.1610 +            other.isDictionary()):
  1.1611 +            # Can't tell which type null should become
  1.1612 +            return False
  1.1613 +        return self.inner.isDistinguishableFrom(other)
  1.1614 +
  1.1615 +    def _getDependentObjects(self):
  1.1616 +        return self.inner._getDependentObjects()
  1.1617 +
  1.1618 +class IDLSequenceType(IDLType):
  1.1619 +    def __init__(self, location, parameterType):
  1.1620 +        assert not parameterType.isVoid()
  1.1621 +
  1.1622 +        IDLType.__init__(self, location, parameterType.name)
  1.1623 +        self.inner = parameterType
  1.1624 +        self.builtin = False
  1.1625 +
  1.1626 +    def __eq__(self, other):
  1.1627 +        return isinstance(other, IDLSequenceType) and self.inner == other.inner
  1.1628 +
  1.1629 +    def __str__(self):
  1.1630 +        return self.inner.__str__() + "Sequence"
  1.1631 +
  1.1632 +    def nullable(self):
  1.1633 +        return False
  1.1634 +
  1.1635 +    def isPrimitive(self):
  1.1636 +        return False;
  1.1637 +
  1.1638 +    def isString(self):
  1.1639 +        return False;
  1.1640 +
  1.1641 +    def isByteString(self):
  1.1642 +        return False
  1.1643 +
  1.1644 +    def isDOMString(self):
  1.1645 +        return False
  1.1646 +
  1.1647 +    def isVoid(self):
  1.1648 +        return False
  1.1649 +
  1.1650 +    def isSequence(self):
  1.1651 +        return True
  1.1652 +
  1.1653 +    def isArray(self):
  1.1654 +        return False
  1.1655 +
  1.1656 +    def isDictionary(self):
  1.1657 +        return False
  1.1658 +
  1.1659 +    def isInterface(self):
  1.1660 +        return False
  1.1661 +
  1.1662 +    def isEnum(self):
  1.1663 +        return False
  1.1664 +
  1.1665 +    def isSerializable(self):
  1.1666 +        return self.inner.isSerializable()
  1.1667 +
  1.1668 +    def includesRestrictedFloat(self):
  1.1669 +        return self.inner.includesRestrictedFloat()
  1.1670 +
  1.1671 +    def tag(self):
  1.1672 +        return IDLType.Tags.sequence
  1.1673 +
  1.1674 +    def resolveType(self, parentScope):
  1.1675 +        assert isinstance(parentScope, IDLScope)
  1.1676 +        self.inner.resolveType(parentScope)
  1.1677 +
  1.1678 +    def isComplete(self):
  1.1679 +        return self.inner.isComplete()
  1.1680 +
  1.1681 +    def complete(self, scope):
  1.1682 +        self.inner = self.inner.complete(scope)
  1.1683 +        self.name = self.inner.name
  1.1684 +        return self
  1.1685 +
  1.1686 +    def unroll(self):
  1.1687 +        return self.inner.unroll()
  1.1688 +
  1.1689 +    def isDistinguishableFrom(self, other):
  1.1690 +        if other.isUnion():
  1.1691 +            # Just forward to the union; it'll deal
  1.1692 +            return other.isDistinguishableFrom(self)
  1.1693 +        return (other.isPrimitive() or other.isString() or other.isEnum() or
  1.1694 +                other.isDate() or other.isNonCallbackInterface())
  1.1695 +
  1.1696 +    def _getDependentObjects(self):
  1.1697 +        return self.inner._getDependentObjects()
  1.1698 +
  1.1699 +class IDLMozMapType(IDLType):
  1.1700 +    # XXXbz This is pretty similar to IDLSequenceType in various ways.
  1.1701 +    # And maybe to IDLNullableType.  Should we have a superclass for
  1.1702 +    # "type containing this other type"?  Bug 1015318.
  1.1703 +    def __init__(self, location, parameterType):
  1.1704 +        assert not parameterType.isVoid()
  1.1705 +
  1.1706 +        IDLType.__init__(self, location, parameterType.name)
  1.1707 +        self.inner = parameterType
  1.1708 +        self.builtin = False
  1.1709 +
  1.1710 +    def __eq__(self, other):
  1.1711 +        return isinstance(other, IDLMozMapType) and self.inner == other.inner
  1.1712 +
  1.1713 +    def __str__(self):
  1.1714 +        return self.inner.__str__() + "MozMap"
  1.1715 +
  1.1716 +    def isMozMap(self):
  1.1717 +        return True
  1.1718 +
  1.1719 +    def includesRestrictedFloat(self):
  1.1720 +        return self.inner.includesRestrictedFloat()
  1.1721 +
  1.1722 +    def tag(self):
  1.1723 +        return IDLType.Tags.mozmap
  1.1724 +
  1.1725 +    def resolveType(self, parentScope):
  1.1726 +        assert isinstance(parentScope, IDLScope)
  1.1727 +        self.inner.resolveType(parentScope)
  1.1728 +
  1.1729 +    def isComplete(self):
  1.1730 +        return self.inner.isComplete()
  1.1731 +
  1.1732 +    def complete(self, scope):
  1.1733 +        self.inner = self.inner.complete(scope)
  1.1734 +        self.name = self.inner.name
  1.1735 +        return self
  1.1736 +
  1.1737 +    def unroll(self):
  1.1738 +        # We do not unroll our inner.  Just stop at ourselves.  That
  1.1739 +        # lets us add headers for both ourselves and our inner as
  1.1740 +        # needed.
  1.1741 +        return self
  1.1742 +
  1.1743 +    def isDistinguishableFrom(self, other):
  1.1744 +        if other.isUnion():
  1.1745 +            # Just forward to the union; it'll deal
  1.1746 +            return other.isDistinguishableFrom(self)
  1.1747 +        return (other.isPrimitive() or other.isString() or other.isEnum() or
  1.1748 +                other.isDate() or other.isNonCallbackInterface())
  1.1749 +
  1.1750 +    def _getDependentObjects(self):
  1.1751 +        return self.inner._getDependentObjects()
  1.1752 +
  1.1753 +class IDLUnionType(IDLType):
  1.1754 +    def __init__(self, location, memberTypes):
  1.1755 +        IDLType.__init__(self, location, "")
  1.1756 +        self.memberTypes = memberTypes
  1.1757 +        self.hasNullableType = False
  1.1758 +        self.hasDictionaryType = False
  1.1759 +        self.flatMemberTypes = None
  1.1760 +        self.builtin = False
  1.1761 +
  1.1762 +    def __eq__(self, other):
  1.1763 +        return isinstance(other, IDLUnionType) and self.memberTypes == other.memberTypes
  1.1764 +
  1.1765 +    def isVoid(self):
  1.1766 +        return False
  1.1767 +
  1.1768 +    def isUnion(self):
  1.1769 +        return True
  1.1770 +
  1.1771 +    def isSerializable(self):
  1.1772 +        return all(m.isSerializable() for m in self.memberTypes)
  1.1773 +
  1.1774 +    def includesRestrictedFloat(self):
  1.1775 +        return any(t.includesRestrictedFloat() for t in self.memberTypes)
  1.1776 +
  1.1777 +    def tag(self):
  1.1778 +        return IDLType.Tags.union
  1.1779 +
  1.1780 +    def resolveType(self, parentScope):
  1.1781 +        assert isinstance(parentScope, IDLScope)
  1.1782 +        for t in self.memberTypes:
  1.1783 +            t.resolveType(parentScope)
  1.1784 +
  1.1785 +    def isComplete(self):
  1.1786 +        return self.flatMemberTypes is not None
  1.1787 +
  1.1788 +    def complete(self, scope):
  1.1789 +        def typeName(type):
  1.1790 +            if isinstance(type, IDLNullableType):
  1.1791 +                return typeName(type.inner) + "OrNull"
  1.1792 +            if isinstance(type, IDLWrapperType):
  1.1793 +                return typeName(type._identifier.object())
  1.1794 +            if isinstance(type, IDLObjectWithIdentifier):
  1.1795 +                return typeName(type.identifier)
  1.1796 +            if (isinstance(type, IDLType) and
  1.1797 +                (type.isArray() or type.isSequence() or type.isMozMap)):
  1.1798 +                return str(type)
  1.1799 +            return type.name
  1.1800 +
  1.1801 +        for (i, type) in enumerate(self.memberTypes):
  1.1802 +            if not type.isComplete():
  1.1803 +                self.memberTypes[i] = type.complete(scope)
  1.1804 +
  1.1805 +        self.name = "Or".join(typeName(type) for type in self.memberTypes)
  1.1806 +        self.flatMemberTypes = list(self.memberTypes)
  1.1807 +        i = 0
  1.1808 +        while i < len(self.flatMemberTypes):
  1.1809 +            if self.flatMemberTypes[i].nullable():
  1.1810 +                if self.hasNullableType:
  1.1811 +                    raise WebIDLError("Can't have more than one nullable types in a union",
  1.1812 +                                      [nullableType.location, self.flatMemberTypes[i].location])
  1.1813 +                if self.hasDictionaryType:
  1.1814 +                    raise WebIDLError("Can't have a nullable type and a "
  1.1815 +                                      "dictionary type in a union",
  1.1816 +                                      [dictionaryType.location,
  1.1817 +                                       self.flatMemberTypes[i].location])
  1.1818 +                self.hasNullableType = True
  1.1819 +                nullableType = self.flatMemberTypes[i]
  1.1820 +                self.flatMemberTypes[i] = self.flatMemberTypes[i].inner
  1.1821 +                continue
  1.1822 +            if self.flatMemberTypes[i].isDictionary():
  1.1823 +                if self.hasNullableType:
  1.1824 +                    raise WebIDLError("Can't have a nullable type and a "
  1.1825 +                                      "dictionary type in a union",
  1.1826 +                                      [nullableType.location,
  1.1827 +                                       self.flatMemberTypes[i].location])
  1.1828 +                self.hasDictionaryType = True
  1.1829 +                dictionaryType = self.flatMemberTypes[i]
  1.1830 +            elif self.flatMemberTypes[i].isUnion():
  1.1831 +                self.flatMemberTypes[i:i + 1] = self.flatMemberTypes[i].memberTypes
  1.1832 +                continue
  1.1833 +            i += 1
  1.1834 +
  1.1835 +        for (i, t) in enumerate(self.flatMemberTypes[:-1]):
  1.1836 +            for u in self.flatMemberTypes[i + 1:]:
  1.1837 +                if not t.isDistinguishableFrom(u):
  1.1838 +                    raise WebIDLError("Flat member types of a union should be "
  1.1839 +                                      "distinguishable, " + str(t) + " is not "
  1.1840 +                                      "distinguishable from " + str(u),
  1.1841 +                                      [self.location, t.location, u.location])
  1.1842 +
  1.1843 +        return self
  1.1844 +
  1.1845 +    def isDistinguishableFrom(self, other):
  1.1846 +        if self.hasNullableType and other.nullable():
  1.1847 +            # Can't tell which type null should become
  1.1848 +            return False
  1.1849 +        if other.isUnion():
  1.1850 +            otherTypes = other.unroll().memberTypes
  1.1851 +        else:
  1.1852 +            otherTypes = [other]
  1.1853 +        # For every type in otherTypes, check that it's distinguishable from
  1.1854 +        # every type in our types
  1.1855 +        for u in otherTypes:
  1.1856 +            if any(not t.isDistinguishableFrom(u) for t in self.memberTypes):
  1.1857 +                return False
  1.1858 +        return True
  1.1859 +
  1.1860 +    def _getDependentObjects(self):
  1.1861 +        return set(self.memberTypes)
  1.1862 +
  1.1863 +class IDLArrayType(IDLType):
  1.1864 +    def __init__(self, location, parameterType):
  1.1865 +        assert not parameterType.isVoid()
  1.1866 +        if parameterType.isSequence():
  1.1867 +            raise WebIDLError("Array type cannot parameterize over a sequence type",
  1.1868 +                              [location])
  1.1869 +        if parameterType.isMozMap():
  1.1870 +            raise WebIDLError("Array type cannot parameterize over a MozMap type",
  1.1871 +                              [location])
  1.1872 +        if parameterType.isDictionary():
  1.1873 +            raise WebIDLError("Array type cannot parameterize over a dictionary type",
  1.1874 +                              [location])
  1.1875 +
  1.1876 +        IDLType.__init__(self, location, parameterType.name)
  1.1877 +        self.inner = parameterType
  1.1878 +        self.builtin = False
  1.1879 +
  1.1880 +    def __eq__(self, other):
  1.1881 +        return isinstance(other, IDLArrayType) and self.inner == other.inner
  1.1882 +
  1.1883 +    def __str__(self):
  1.1884 +        return self.inner.__str__() + "Array"
  1.1885 +
  1.1886 +    def nullable(self):
  1.1887 +        return False
  1.1888 +
  1.1889 +    def isPrimitive(self):
  1.1890 +        return False
  1.1891 +
  1.1892 +    def isString(self):
  1.1893 +        return False
  1.1894 +
  1.1895 +    def isByteString(self):
  1.1896 +        return False
  1.1897 +
  1.1898 +    def isDOMString(self):
  1.1899 +        return False
  1.1900 +
  1.1901 +    def isVoid(self):
  1.1902 +        return False
  1.1903 +
  1.1904 +    def isSequence(self):
  1.1905 +        assert not self.inner.isSequence()
  1.1906 +        return False
  1.1907 +
  1.1908 +    def isArray(self):
  1.1909 +        return True
  1.1910 +
  1.1911 +    def isDictionary(self):
  1.1912 +        assert not self.inner.isDictionary()
  1.1913 +        return False
  1.1914 +
  1.1915 +    def isInterface(self):
  1.1916 +        return False
  1.1917 +
  1.1918 +    def isEnum(self):
  1.1919 +        return False
  1.1920 +
  1.1921 +    def tag(self):
  1.1922 +        return IDLType.Tags.array
  1.1923 +
  1.1924 +    def resolveType(self, parentScope):
  1.1925 +        assert isinstance(parentScope, IDLScope)
  1.1926 +        self.inner.resolveType(parentScope)
  1.1927 +
  1.1928 +    def isComplete(self):
  1.1929 +        return self.inner.isComplete()
  1.1930 +
  1.1931 +    def complete(self, scope):
  1.1932 +        self.inner = self.inner.complete(scope)
  1.1933 +        self.name = self.inner.name
  1.1934 +
  1.1935 +        if self.inner.isDictionary():
  1.1936 +            raise WebIDLError("Array type must not contain "
  1.1937 +                              "dictionary as element type.",
  1.1938 +                              [self.inner.location])
  1.1939 +
  1.1940 +        assert not self.inner.isSequence()
  1.1941 +
  1.1942 +        return self
  1.1943 +
  1.1944 +    def unroll(self):
  1.1945 +        return self.inner.unroll()
  1.1946 +
  1.1947 +    def isDistinguishableFrom(self, other):
  1.1948 +        if other.isUnion():
  1.1949 +            # Just forward to the union; it'll deal
  1.1950 +            return other.isDistinguishableFrom(self)
  1.1951 +        return (other.isPrimitive() or other.isString() or other.isEnum() or
  1.1952 +                other.isDate() or other.isNonCallbackInterface())
  1.1953 +
  1.1954 +    def _getDependentObjects(self):
  1.1955 +        return self.inner._getDependentObjects()
  1.1956 +
  1.1957 +class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
  1.1958 +    def __init__(self, location, innerType, name):
  1.1959 +        IDLType.__init__(self, location, innerType.name)
  1.1960 +
  1.1961 +        identifier = IDLUnresolvedIdentifier(location, name)
  1.1962 +
  1.1963 +        IDLObjectWithIdentifier.__init__(self, location, None, identifier)
  1.1964 +
  1.1965 +        self.inner = innerType
  1.1966 +        self.name = name
  1.1967 +        self.builtin = False
  1.1968 +
  1.1969 +    def __eq__(self, other):
  1.1970 +        return isinstance(other, IDLTypedefType) and self.inner == other.inner
  1.1971 +
  1.1972 +    def __str__(self):
  1.1973 +        return self.identifier.name
  1.1974 +
  1.1975 +    def nullable(self):
  1.1976 +        return self.inner.nullable()
  1.1977 +
  1.1978 +    def isPrimitive(self):
  1.1979 +        return self.inner.isPrimitive()
  1.1980 +
  1.1981 +    def isBoolean(self):
  1.1982 +        return self.inner.isBoolean()
  1.1983 +
  1.1984 +    def isNumeric(self):
  1.1985 +        return self.inner.isNumeric()
  1.1986 +
  1.1987 +    def isString(self):
  1.1988 +        return self.inner.isString()
  1.1989 +
  1.1990 +    def isByteString(self):
  1.1991 +        return self.inner.isByteString()
  1.1992 +
  1.1993 +    def isDOMString(self):
  1.1994 +        return self.inner.isDOMString()
  1.1995 +
  1.1996 +    def isVoid(self):
  1.1997 +        return self.inner.isVoid()
  1.1998 +
  1.1999 +    def isSequence(self):
  1.2000 +        return self.inner.isSequence()
  1.2001 +
  1.2002 +    def isMozMap(self):
  1.2003 +        return self.inner.isMozMap()
  1.2004 +
  1.2005 +    def isArray(self):
  1.2006 +        return self.inner.isArray()
  1.2007 +
  1.2008 +    def isDictionary(self):
  1.2009 +        return self.inner.isDictionary()
  1.2010 +
  1.2011 +    def isArrayBuffer(self):
  1.2012 +        return self.inner.isArrayBuffer()
  1.2013 +
  1.2014 +    def isArrayBufferView(self):
  1.2015 +        return self.inner.isArrayBufferView()
  1.2016 +
  1.2017 +    def isTypedArray(self):
  1.2018 +        return self.inner.isTypedArray()
  1.2019 +
  1.2020 +    def isInterface(self):
  1.2021 +        return self.inner.isInterface()
  1.2022 +
  1.2023 +    def isCallbackInterface(self):
  1.2024 +        return self.inner.isCallbackInterface()
  1.2025 +
  1.2026 +    def isNonCallbackInterface(self):
  1.2027 +        return self.inner.isNonCallbackInterface()
  1.2028 +
  1.2029 +    def isComplete(self):
  1.2030 +        return False
  1.2031 +
  1.2032 +    def complete(self, parentScope):
  1.2033 +        if not self.inner.isComplete():
  1.2034 +            self.inner = self.inner.complete(parentScope)
  1.2035 +        assert self.inner.isComplete()
  1.2036 +        return self.inner
  1.2037 +
  1.2038 +    def finish(self, parentScope):
  1.2039 +        # Maybe the IDLObjectWithIdentifier for the typedef should be
  1.2040 +        # a separate thing from the type?  If that happens, we can
  1.2041 +        # remove some hackery around avoiding isInterface() in
  1.2042 +        # Configuration.py.
  1.2043 +        self.complete(parentScope)
  1.2044 +
  1.2045 +    def validate(self):
  1.2046 +        pass
  1.2047 +
  1.2048 +    # Do we need a resolveType impl?  I don't think it's particularly useful....
  1.2049 +
  1.2050 +    def tag(self):
  1.2051 +        return self.inner.tag()
  1.2052 +
  1.2053 +    def unroll(self):
  1.2054 +        return self.inner.unroll()
  1.2055 +
  1.2056 +    def isDistinguishableFrom(self, other):
  1.2057 +        return self.inner.isDistinguishableFrom(other)
  1.2058 +
  1.2059 +    def _getDependentObjects(self):
  1.2060 +        return self.inner._getDependentObjects()
  1.2061 +
  1.2062 +class IDLWrapperType(IDLType):
  1.2063 +    def __init__(self, location, inner):
  1.2064 +        IDLType.__init__(self, location, inner.identifier.name)
  1.2065 +        self.inner = inner
  1.2066 +        self._identifier = inner.identifier
  1.2067 +        self.builtin = False
  1.2068 +
  1.2069 +    def __eq__(self, other):
  1.2070 +        return isinstance(other, IDLWrapperType) and \
  1.2071 +               self._identifier == other._identifier and \
  1.2072 +               self.builtin == other.builtin
  1.2073 +
  1.2074 +    def __str__(self):
  1.2075 +        return str(self.name) + " (Wrapper)"
  1.2076 +
  1.2077 +    def nullable(self):
  1.2078 +        return False
  1.2079 +
  1.2080 +    def isPrimitive(self):
  1.2081 +        return False
  1.2082 +
  1.2083 +    def isString(self):
  1.2084 +        return False
  1.2085 +
  1.2086 +    def isByteString(self):
  1.2087 +        return False
  1.2088 +
  1.2089 +    def isDOMString(self):
  1.2090 +        return False
  1.2091 +
  1.2092 +    def isVoid(self):
  1.2093 +        return False
  1.2094 +
  1.2095 +    def isSequence(self):
  1.2096 +        return False
  1.2097 +
  1.2098 +    def isArray(self):
  1.2099 +        return False
  1.2100 +
  1.2101 +    def isDictionary(self):
  1.2102 +        return isinstance(self.inner, IDLDictionary)
  1.2103 +
  1.2104 +    def isInterface(self):
  1.2105 +        return isinstance(self.inner, IDLInterface) or \
  1.2106 +               isinstance(self.inner, IDLExternalInterface)
  1.2107 +
  1.2108 +    def isCallbackInterface(self):
  1.2109 +        return self.isInterface() and self.inner.isCallback()
  1.2110 +
  1.2111 +    def isNonCallbackInterface(self):
  1.2112 +        return self.isInterface() and not self.inner.isCallback()
  1.2113 +
  1.2114 +    def isEnum(self):
  1.2115 +        return isinstance(self.inner, IDLEnum)
  1.2116 +
  1.2117 +    def isPromise(self):
  1.2118 +        return isinstance(self.inner, IDLInterface) and \
  1.2119 +               self.inner.identifier.name == "Promise"
  1.2120 +
  1.2121 +    def isSerializable(self):
  1.2122 +        if self.isInterface():
  1.2123 +            if self.inner.isExternal():
  1.2124 +                return False
  1.2125 +            return any(m.isMethod() and m.isJsonifier() for m in self.inner.members)
  1.2126 +        elif self.isEnum():
  1.2127 +            return True
  1.2128 +        elif self.isDictionary():
  1.2129 +            return all(m.type.isSerializable() for m in self.inner.members)
  1.2130 +        else:
  1.2131 +            raise WebIDLError("IDLWrapperType wraps type %s that we don't know if "
  1.2132 +                              "is serializable" % type(self.inner), [self.location])
  1.2133 +
  1.2134 +    def resolveType(self, parentScope):
  1.2135 +        assert isinstance(parentScope, IDLScope)
  1.2136 +        self.inner.resolve(parentScope)
  1.2137 +
  1.2138 +    def isComplete(self):
  1.2139 +        return True
  1.2140 +
  1.2141 +    def tag(self):
  1.2142 +        if self.isInterface():
  1.2143 +            return IDLType.Tags.interface
  1.2144 +        elif self.isEnum():
  1.2145 +            return IDLType.Tags.enum
  1.2146 +        elif self.isDictionary():
  1.2147 +            return IDLType.Tags.dictionary
  1.2148 +        else:
  1.2149 +            assert False
  1.2150 +
  1.2151 +    def isDistinguishableFrom(self, other):
  1.2152 +        if other.isUnion():
  1.2153 +            # Just forward to the union; it'll deal
  1.2154 +            return other.isDistinguishableFrom(self)
  1.2155 +        assert self.isInterface() or self.isEnum() or self.isDictionary()
  1.2156 +        if self.isEnum():
  1.2157 +            return (other.isPrimitive() or other.isInterface() or other.isObject() or
  1.2158 +                    other.isCallback() or other.isDictionary() or
  1.2159 +                    other.isSequence() or other.isMozMap() or other.isArray() or
  1.2160 +                    other.isDate())
  1.2161 +        if self.isDictionary() and other.nullable():
  1.2162 +            return False
  1.2163 +        if other.isPrimitive() or other.isString() or other.isEnum() or other.isDate():
  1.2164 +            return True
  1.2165 +        if self.isDictionary():
  1.2166 +            return other.isNonCallbackInterface()
  1.2167 +
  1.2168 +        assert self.isInterface()
  1.2169 +        if other.isInterface():
  1.2170 +            if other.isSpiderMonkeyInterface():
  1.2171 +                # Just let |other| handle things
  1.2172 +                return other.isDistinguishableFrom(self)
  1.2173 +            assert self.isGeckoInterface() and other.isGeckoInterface()
  1.2174 +            if self.inner.isExternal() or other.unroll().inner.isExternal():
  1.2175 +                return self != other
  1.2176 +            return (len(self.inner.interfacesBasedOnSelf &
  1.2177 +                        other.unroll().inner.interfacesBasedOnSelf) == 0 and
  1.2178 +                    (self.isNonCallbackInterface() or
  1.2179 +                     other.isNonCallbackInterface()))
  1.2180 +        if (other.isDictionary() or other.isCallback() or
  1.2181 +            other.isSequence() or other.isMozMap() or other.isArray()):
  1.2182 +            return self.isNonCallbackInterface()
  1.2183 +
  1.2184 +        # Not much else |other| can be
  1.2185 +        assert other.isObject()
  1.2186 +        return False
  1.2187 +
  1.2188 +    def _getDependentObjects(self):
  1.2189 +        # NB: The codegen for an interface type depends on
  1.2190 +        #  a) That the identifier is in fact an interface (as opposed to
  1.2191 +        #     a dictionary or something else).
  1.2192 +        #  b) The native type of the interface.
  1.2193 +        #  If we depend on the interface object we will also depend on
  1.2194 +        #  anything the interface depends on which is undesirable.  We
  1.2195 +        #  considered implementing a dependency just on the interface type
  1.2196 +        #  file, but then every modification to an interface would cause this
  1.2197 +        #  to be regenerated which is still undesirable.  We decided not to
  1.2198 +        #  depend on anything, reasoning that:
  1.2199 +        #  1) Changing the concrete type of the interface requires modifying
  1.2200 +        #     Bindings.conf, which is still a global dependency.
  1.2201 +        #  2) Changing an interface to a dictionary (or vice versa) with the
  1.2202 +        #     same identifier should be incredibly rare.
  1.2203 +        return set()
  1.2204 +
  1.2205 +class IDLBuiltinType(IDLType):
  1.2206 +
  1.2207 +    Types = enum(
  1.2208 +        # The integer types
  1.2209 +        'byte',
  1.2210 +        'octet',
  1.2211 +        'short',
  1.2212 +        'unsigned_short',
  1.2213 +        'long',
  1.2214 +        'unsigned_long',
  1.2215 +        'long_long',
  1.2216 +        'unsigned_long_long',
  1.2217 +        # Additional primitive types
  1.2218 +        'boolean',
  1.2219 +        'unrestricted_float',
  1.2220 +        'float',
  1.2221 +        'unrestricted_double',
  1.2222 +        # IMPORTANT: "double" must be the last primitive type listed
  1.2223 +        'double',
  1.2224 +        # Other types
  1.2225 +        'any',
  1.2226 +        'domstring',
  1.2227 +        'bytestring',
  1.2228 +        'object',
  1.2229 +        'date',
  1.2230 +        'void',
  1.2231 +        # Funny stuff
  1.2232 +        'ArrayBuffer',
  1.2233 +        'ArrayBufferView',
  1.2234 +        'Int8Array',
  1.2235 +        'Uint8Array',
  1.2236 +        'Uint8ClampedArray',
  1.2237 +        'Int16Array',
  1.2238 +        'Uint16Array',
  1.2239 +        'Int32Array',
  1.2240 +        'Uint32Array',
  1.2241 +        'Float32Array',
  1.2242 +        'Float64Array'
  1.2243 +        )
  1.2244 +
  1.2245 +    TagLookup = {
  1.2246 +            Types.byte: IDLType.Tags.int8,
  1.2247 +            Types.octet: IDLType.Tags.uint8,
  1.2248 +            Types.short: IDLType.Tags.int16,
  1.2249 +            Types.unsigned_short: IDLType.Tags.uint16,
  1.2250 +            Types.long: IDLType.Tags.int32,
  1.2251 +            Types.unsigned_long: IDLType.Tags.uint32,
  1.2252 +            Types.long_long: IDLType.Tags.int64,
  1.2253 +            Types.unsigned_long_long: IDLType.Tags.uint64,
  1.2254 +            Types.boolean: IDLType.Tags.bool,
  1.2255 +            Types.unrestricted_float: IDLType.Tags.unrestricted_float,
  1.2256 +            Types.float: IDLType.Tags.float,
  1.2257 +            Types.unrestricted_double: IDLType.Tags.unrestricted_double,
  1.2258 +            Types.double: IDLType.Tags.double,
  1.2259 +            Types.any: IDLType.Tags.any,
  1.2260 +            Types.domstring: IDLType.Tags.domstring,
  1.2261 +            Types.bytestring: IDLType.Tags.bytestring,
  1.2262 +            Types.object: IDLType.Tags.object,
  1.2263 +            Types.date: IDLType.Tags.date,
  1.2264 +            Types.void: IDLType.Tags.void,
  1.2265 +            Types.ArrayBuffer: IDLType.Tags.interface,
  1.2266 +            Types.ArrayBufferView: IDLType.Tags.interface,
  1.2267 +            Types.Int8Array: IDLType.Tags.interface,
  1.2268 +            Types.Uint8Array: IDLType.Tags.interface,
  1.2269 +            Types.Uint8ClampedArray: IDLType.Tags.interface,
  1.2270 +            Types.Int16Array: IDLType.Tags.interface,
  1.2271 +            Types.Uint16Array: IDLType.Tags.interface,
  1.2272 +            Types.Int32Array: IDLType.Tags.interface,
  1.2273 +            Types.Uint32Array: IDLType.Tags.interface,
  1.2274 +            Types.Float32Array: IDLType.Tags.interface,
  1.2275 +            Types.Float64Array: IDLType.Tags.interface
  1.2276 +        }
  1.2277 +
  1.2278 +    def __init__(self, location, name, type):
  1.2279 +        IDLType.__init__(self, location, name)
  1.2280 +        self.builtin = True
  1.2281 +        self._typeTag = type
  1.2282 +
  1.2283 +    def isPrimitive(self):
  1.2284 +        return self._typeTag <= IDLBuiltinType.Types.double
  1.2285 +
  1.2286 +    def isBoolean(self):
  1.2287 +        return self._typeTag == IDLBuiltinType.Types.boolean
  1.2288 +
  1.2289 +    def isNumeric(self):
  1.2290 +        return self.isPrimitive() and not self.isBoolean()
  1.2291 +
  1.2292 +    def isString(self):
  1.2293 +        return self._typeTag == IDLBuiltinType.Types.domstring or \
  1.2294 +               self._typeTag == IDLBuiltinType.Types.bytestring
  1.2295 +
  1.2296 +    def isByteString(self):
  1.2297 +        return self._typeTag == IDLBuiltinType.Types.bytestring
  1.2298 +
  1.2299 +    def isDOMString(self):
  1.2300 +        return self._typeTag == IDLBuiltinType.Types.domstring
  1.2301 +
  1.2302 +    def isInteger(self):
  1.2303 +        return self._typeTag <= IDLBuiltinType.Types.unsigned_long_long
  1.2304 +
  1.2305 +    def isArrayBuffer(self):
  1.2306 +        return self._typeTag == IDLBuiltinType.Types.ArrayBuffer
  1.2307 +
  1.2308 +    def isArrayBufferView(self):
  1.2309 +        return self._typeTag == IDLBuiltinType.Types.ArrayBufferView
  1.2310 +
  1.2311 +    def isTypedArray(self):
  1.2312 +        return self._typeTag >= IDLBuiltinType.Types.Int8Array and \
  1.2313 +               self._typeTag <= IDLBuiltinType.Types.Float64Array
  1.2314 +
  1.2315 +    def isInterface(self):
  1.2316 +        # TypedArray things are interface types per the TypedArray spec,
  1.2317 +        # but we handle them as builtins because SpiderMonkey implements
  1.2318 +        # all of it internally.
  1.2319 +        return self.isArrayBuffer() or \
  1.2320 +               self.isArrayBufferView() or \
  1.2321 +               self.isTypedArray()
  1.2322 +
  1.2323 +    def isNonCallbackInterface(self):
  1.2324 +        # All the interfaces we can be are non-callback
  1.2325 +        return self.isInterface()
  1.2326 +
  1.2327 +    def isFloat(self):
  1.2328 +        return self._typeTag == IDLBuiltinType.Types.float or \
  1.2329 +               self._typeTag == IDLBuiltinType.Types.double or \
  1.2330 +               self._typeTag == IDLBuiltinType.Types.unrestricted_float or \
  1.2331 +               self._typeTag == IDLBuiltinType.Types.unrestricted_double
  1.2332 +
  1.2333 +    def isUnrestricted(self):
  1.2334 +        assert self.isFloat()
  1.2335 +        return self._typeTag == IDLBuiltinType.Types.unrestricted_float or \
  1.2336 +               self._typeTag == IDLBuiltinType.Types.unrestricted_double
  1.2337 +
  1.2338 +    def isSerializable(self):
  1.2339 +        return self.isPrimitive() or self.isDOMString() or self.isDate()
  1.2340 +
  1.2341 +    def includesRestrictedFloat(self):
  1.2342 +        return self.isFloat() and not self.isUnrestricted()
  1.2343 +
  1.2344 +    def tag(self):
  1.2345 +        return IDLBuiltinType.TagLookup[self._typeTag]
  1.2346 +
  1.2347 +    def isDistinguishableFrom(self, other):
  1.2348 +        if other.isUnion():
  1.2349 +            # Just forward to the union; it'll deal
  1.2350 +            return other.isDistinguishableFrom(self)
  1.2351 +        if self.isBoolean():
  1.2352 +            return (other.isNumeric() or other.isString() or other.isEnum() or
  1.2353 +                    other.isInterface() or other.isObject() or
  1.2354 +                    other.isCallback() or other.isDictionary() or
  1.2355 +                    other.isSequence() or other.isMozMap() or other.isArray() or
  1.2356 +                    other.isDate())
  1.2357 +        if self.isNumeric():
  1.2358 +            return (other.isBoolean() or other.isString() or other.isEnum() or
  1.2359 +                    other.isInterface() or other.isObject() or
  1.2360 +                    other.isCallback() or other.isDictionary() or
  1.2361 +                    other.isSequence() or other.isMozMap() or other.isArray() or
  1.2362 +                    other.isDate())
  1.2363 +        if self.isString():
  1.2364 +            return (other.isPrimitive() or other.isInterface() or
  1.2365 +                    other.isObject() or
  1.2366 +                    other.isCallback() or other.isDictionary() or
  1.2367 +                    other.isSequence() or other.isMozMap() or other.isArray() or
  1.2368 +                    other.isDate())
  1.2369 +        if self.isAny():
  1.2370 +            # Can't tell "any" apart from anything
  1.2371 +            return False
  1.2372 +        if self.isObject():
  1.2373 +            return other.isPrimitive() or other.isString() or other.isEnum()
  1.2374 +        if self.isDate():
  1.2375 +            return (other.isPrimitive() or other.isString() or other.isEnum() or
  1.2376 +                    other.isInterface() or other.isCallback() or
  1.2377 +                    other.isDictionary() or other.isSequence() or
  1.2378 +                    other.isMozMap() or other.isArray())
  1.2379 +        if self.isVoid():
  1.2380 +            return not other.isVoid()
  1.2381 +        # Not much else we could be!
  1.2382 +        assert self.isSpiderMonkeyInterface()
  1.2383 +        # Like interfaces, but we know we're not a callback
  1.2384 +        return (other.isPrimitive() or other.isString() or other.isEnum() or
  1.2385 +                other.isCallback() or other.isDictionary() or
  1.2386 +                other.isSequence() or other.isMozMap() or other.isArray() or
  1.2387 +                other.isDate() or
  1.2388 +                (other.isInterface() and (
  1.2389 +                 # ArrayBuffer is distinguishable from everything
  1.2390 +                 # that's not an ArrayBuffer or a callback interface
  1.2391 +                 (self.isArrayBuffer() and not other.isArrayBuffer()) or
  1.2392 +                 # ArrayBufferView is distinguishable from everything
  1.2393 +                 # that's not an ArrayBufferView or typed array.
  1.2394 +                 (self.isArrayBufferView() and not other.isArrayBufferView() and
  1.2395 +                  not other.isTypedArray()) or
  1.2396 +                 # Typed arrays are distinguishable from everything
  1.2397 +                 # except ArrayBufferView and the same type of typed
  1.2398 +                 # array
  1.2399 +                 (self.isTypedArray() and not other.isArrayBufferView() and not
  1.2400 +                  (other.isTypedArray() and other.name == self.name)))))
  1.2401 +
  1.2402 +    def _getDependentObjects(self):
  1.2403 +        return set()
  1.2404 +
  1.2405 +BuiltinTypes = {
  1.2406 +      IDLBuiltinType.Types.byte:
  1.2407 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Byte",
  1.2408 +                         IDLBuiltinType.Types.byte),
  1.2409 +      IDLBuiltinType.Types.octet:
  1.2410 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Octet",
  1.2411 +                         IDLBuiltinType.Types.octet),
  1.2412 +      IDLBuiltinType.Types.short:
  1.2413 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Short",
  1.2414 +                         IDLBuiltinType.Types.short),
  1.2415 +      IDLBuiltinType.Types.unsigned_short:
  1.2416 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnsignedShort",
  1.2417 +                         IDLBuiltinType.Types.unsigned_short),
  1.2418 +      IDLBuiltinType.Types.long:
  1.2419 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Long",
  1.2420 +                         IDLBuiltinType.Types.long),
  1.2421 +      IDLBuiltinType.Types.unsigned_long:
  1.2422 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnsignedLong",
  1.2423 +                         IDLBuiltinType.Types.unsigned_long),
  1.2424 +      IDLBuiltinType.Types.long_long:
  1.2425 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "LongLong",
  1.2426 +                         IDLBuiltinType.Types.long_long),
  1.2427 +      IDLBuiltinType.Types.unsigned_long_long:
  1.2428 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnsignedLongLong",
  1.2429 +                         IDLBuiltinType.Types.unsigned_long_long),
  1.2430 +      IDLBuiltinType.Types.boolean:
  1.2431 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Boolean",
  1.2432 +                         IDLBuiltinType.Types.boolean),
  1.2433 +      IDLBuiltinType.Types.float:
  1.2434 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float",
  1.2435 +                         IDLBuiltinType.Types.float),
  1.2436 +      IDLBuiltinType.Types.unrestricted_float:
  1.2437 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnrestrictedFloat",
  1.2438 +                         IDLBuiltinType.Types.unrestricted_float),
  1.2439 +      IDLBuiltinType.Types.double:
  1.2440 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Double",
  1.2441 +                         IDLBuiltinType.Types.double),
  1.2442 +      IDLBuiltinType.Types.unrestricted_double:
  1.2443 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnrestrictedDouble",
  1.2444 +                         IDLBuiltinType.Types.unrestricted_double),
  1.2445 +      IDLBuiltinType.Types.any:
  1.2446 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Any",
  1.2447 +                         IDLBuiltinType.Types.any),
  1.2448 +      IDLBuiltinType.Types.domstring:
  1.2449 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "String",
  1.2450 +                         IDLBuiltinType.Types.domstring),
  1.2451 +      IDLBuiltinType.Types.bytestring:
  1.2452 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "ByteString",
  1.2453 +                         IDLBuiltinType.Types.bytestring),
  1.2454 +      IDLBuiltinType.Types.object:
  1.2455 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Object",
  1.2456 +                         IDLBuiltinType.Types.object),
  1.2457 +      IDLBuiltinType.Types.date:
  1.2458 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Date",
  1.2459 +                         IDLBuiltinType.Types.date),
  1.2460 +      IDLBuiltinType.Types.void:
  1.2461 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Void",
  1.2462 +                         IDLBuiltinType.Types.void),
  1.2463 +      IDLBuiltinType.Types.ArrayBuffer:
  1.2464 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "ArrayBuffer",
  1.2465 +                         IDLBuiltinType.Types.ArrayBuffer),
  1.2466 +      IDLBuiltinType.Types.ArrayBufferView:
  1.2467 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "ArrayBufferView",
  1.2468 +                         IDLBuiltinType.Types.ArrayBufferView),
  1.2469 +      IDLBuiltinType.Types.Int8Array:
  1.2470 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int8Array",
  1.2471 +                         IDLBuiltinType.Types.Int8Array),
  1.2472 +      IDLBuiltinType.Types.Uint8Array:
  1.2473 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint8Array",
  1.2474 +                         IDLBuiltinType.Types.Uint8Array),
  1.2475 +      IDLBuiltinType.Types.Uint8ClampedArray:
  1.2476 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint8ClampedArray",
  1.2477 +                         IDLBuiltinType.Types.Uint8ClampedArray),
  1.2478 +      IDLBuiltinType.Types.Int16Array:
  1.2479 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int16Array",
  1.2480 +                         IDLBuiltinType.Types.Int16Array),
  1.2481 +      IDLBuiltinType.Types.Uint16Array:
  1.2482 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint16Array",
  1.2483 +                         IDLBuiltinType.Types.Uint16Array),
  1.2484 +      IDLBuiltinType.Types.Int32Array:
  1.2485 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int32Array",
  1.2486 +                         IDLBuiltinType.Types.Int32Array),
  1.2487 +      IDLBuiltinType.Types.Uint32Array:
  1.2488 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint32Array",
  1.2489 +                         IDLBuiltinType.Types.Uint32Array),
  1.2490 +      IDLBuiltinType.Types.Float32Array:
  1.2491 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float32Array",
  1.2492 +                         IDLBuiltinType.Types.Float32Array),
  1.2493 +      IDLBuiltinType.Types.Float64Array:
  1.2494 +          IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float64Array",
  1.2495 +                         IDLBuiltinType.Types.Float64Array)
  1.2496 +    }
  1.2497 +
  1.2498 +
  1.2499 +integerTypeSizes = {
  1.2500 +        IDLBuiltinType.Types.byte: (-128, 127),
  1.2501 +        IDLBuiltinType.Types.octet:  (0, 255),
  1.2502 +        IDLBuiltinType.Types.short: (-32768, 32767),
  1.2503 +        IDLBuiltinType.Types.unsigned_short: (0, 65535),
  1.2504 +        IDLBuiltinType.Types.long: (-2147483648, 2147483647),
  1.2505 +        IDLBuiltinType.Types.unsigned_long: (0, 4294967295),
  1.2506 +        IDLBuiltinType.Types.long_long: (-9223372036854775808,
  1.2507 +                                         9223372036854775807),
  1.2508 +        IDLBuiltinType.Types.unsigned_long_long: (0, 18446744073709551615)
  1.2509 +    }
  1.2510 +
  1.2511 +def matchIntegerValueToType(value):
  1.2512 +    for type, extremes in integerTypeSizes.items():
  1.2513 +        (min, max) = extremes
  1.2514 +        if value <= max and value >= min:
  1.2515 +            return BuiltinTypes[type]
  1.2516 +
  1.2517 +    return None
  1.2518 +
  1.2519 +class IDLValue(IDLObject):
  1.2520 +    def __init__(self, location, type, value):
  1.2521 +        IDLObject.__init__(self, location)
  1.2522 +        self.type = type
  1.2523 +        assert isinstance(type, IDLType)
  1.2524 +
  1.2525 +        self.value = value
  1.2526 +
  1.2527 +    def coerceToType(self, type, location):
  1.2528 +        if type == self.type:
  1.2529 +            return self # Nothing to do
  1.2530 +
  1.2531 +        # We first check for unions to ensure that even if the union is nullable
  1.2532 +        # we end up with the right flat member type, not the union's type.
  1.2533 +        if type.isUnion():
  1.2534 +            # We use the flat member types here, because if we have a nullable
  1.2535 +            # member type, or a nested union, we want the type the value
  1.2536 +            # actually coerces to, not the nullable or nested union type.
  1.2537 +            for subtype in type.unroll().flatMemberTypes:
  1.2538 +                try:
  1.2539 +                    coercedValue = self.coerceToType(subtype, location)
  1.2540 +                    # Create a new IDLValue to make sure that we have the
  1.2541 +                    # correct float/double type.  This is necessary because we
  1.2542 +                    # use the value's type when it is a default value of a
  1.2543 +                    # union, and the union cares about the exact float type.
  1.2544 +                    return IDLValue(self.location, subtype, coercedValue.value)
  1.2545 +                except:
  1.2546 +                    pass
  1.2547 +        # If the type allows null, rerun this matching on the inner type, except
  1.2548 +        # nullable enums.  We handle those specially, because we want our
  1.2549 +        # default string values to stay strings even when assigned to a nullable
  1.2550 +        # enum.
  1.2551 +        elif type.nullable() and not type.isEnum():
  1.2552 +            innerValue = self.coerceToType(type.inner, location)
  1.2553 +            return IDLValue(self.location, type, innerValue.value)
  1.2554 +
  1.2555 +        elif self.type.isInteger() and type.isInteger():
  1.2556 +            # We're both integer types.  See if we fit.
  1.2557 +
  1.2558 +            (min, max) = integerTypeSizes[type._typeTag]
  1.2559 +            if self.value <= max and self.value >= min:
  1.2560 +                # Promote
  1.2561 +                return IDLValue(self.location, type, self.value)
  1.2562 +            else:
  1.2563 +                raise WebIDLError("Value %s is out of range for type %s." %
  1.2564 +                                  (self.value, type), [location])
  1.2565 +        elif self.type.isInteger() and type.isFloat():
  1.2566 +            # Convert an integer literal into float
  1.2567 +            if -2**24 <= self.value <= 2**24:
  1.2568 +                floatType = BuiltinTypes[IDLBuiltinType.Types.float]
  1.2569 +                return IDLValue(self.location, floatType, float(self.value))
  1.2570 +            else:
  1.2571 +                raise WebIDLError("Converting value %s to %s will lose precision." %
  1.2572 +                                  (self.value, type), [location])
  1.2573 +        elif self.type.isString() and type.isEnum():
  1.2574 +            # Just keep our string, but make sure it's a valid value for this enum
  1.2575 +            enum = type.unroll().inner
  1.2576 +            if self.value not in enum.values():
  1.2577 +                raise WebIDLError("'%s' is not a valid default value for enum %s"
  1.2578 +                                  % (self.value, enum.identifier.name),
  1.2579 +                                  [location, enum.location])
  1.2580 +            return self
  1.2581 +        elif self.type.isFloat() and type.isFloat():
  1.2582 +            if (not type.isUnrestricted() and
  1.2583 +                (self.value == float("inf") or self.value == float("-inf") or
  1.2584 +                 math.isnan(self.value))):
  1.2585 +                raise WebIDLError("Trying to convert unrestricted value %s to non-unrestricted"
  1.2586 +                                  % self.value, [location]);
  1.2587 +            return self
  1.2588 +        raise WebIDLError("Cannot coerce type %s to type %s." %
  1.2589 +                          (self.type, type), [location])
  1.2590 +
  1.2591 +    def _getDependentObjects(self):
  1.2592 +        return set()
  1.2593 +
  1.2594 +class IDLNullValue(IDLObject):
  1.2595 +    def __init__(self, location):
  1.2596 +        IDLObject.__init__(self, location)
  1.2597 +        self.type = None
  1.2598 +        self.value = None
  1.2599 +
  1.2600 +    def coerceToType(self, type, location):
  1.2601 +        if (not isinstance(type, IDLNullableType) and
  1.2602 +            not (type.isUnion() and type.hasNullableType) and
  1.2603 +            not (type.isUnion() and type.hasDictionaryType) and
  1.2604 +            not type.isDictionary() and
  1.2605 +            not type.isAny()):
  1.2606 +            raise WebIDLError("Cannot coerce null value to type %s." % type,
  1.2607 +                              [location])
  1.2608 +
  1.2609 +        nullValue = IDLNullValue(self.location)
  1.2610 +        if type.isUnion() and not type.nullable() and type.hasDictionaryType:
  1.2611 +            # We're actually a default value for the union's dictionary member.
  1.2612 +            # Use its type.
  1.2613 +            for t in type.flatMemberTypes:
  1.2614 +                if t.isDictionary():
  1.2615 +                    nullValue.type = t
  1.2616 +                    return nullValue
  1.2617 +        nullValue.type = type
  1.2618 +        return nullValue
  1.2619 +
  1.2620 +    def _getDependentObjects(self):
  1.2621 +        return set()
  1.2622 +
  1.2623 +class IDLUndefinedValue(IDLObject):
  1.2624 +    def __init__(self, location):
  1.2625 +        IDLObject.__init__(self, location)
  1.2626 +        self.type = None
  1.2627 +        self.value = None
  1.2628 +
  1.2629 +    def coerceToType(self, type, location):
  1.2630 +        if not type.isAny():
  1.2631 +            raise WebIDLError("Cannot coerce undefined value to type %s." % type,
  1.2632 +                              [location])
  1.2633 +
  1.2634 +        undefinedValue = IDLUndefinedValue(self.location)
  1.2635 +        undefinedValue.type = type
  1.2636 +        return undefinedValue
  1.2637 +
  1.2638 +    def _getDependentObjects(self):
  1.2639 +        return set()
  1.2640 +
  1.2641 +class IDLInterfaceMember(IDLObjectWithIdentifier):
  1.2642 +
  1.2643 +    Tags = enum(
  1.2644 +        'Const',
  1.2645 +        'Attr',
  1.2646 +        'Method'
  1.2647 +    )
  1.2648 +
  1.2649 +    Special = enum(
  1.2650 +        'Static',
  1.2651 +        'Stringifier'
  1.2652 +    )
  1.2653 +
  1.2654 +    def __init__(self, location, identifier, tag):
  1.2655 +        IDLObjectWithIdentifier.__init__(self, location, None, identifier)
  1.2656 +        self.tag = tag
  1.2657 +        self._extendedAttrDict = {}
  1.2658 +
  1.2659 +    def isMethod(self):
  1.2660 +        return self.tag == IDLInterfaceMember.Tags.Method
  1.2661 +
  1.2662 +    def isAttr(self):
  1.2663 +        return self.tag == IDLInterfaceMember.Tags.Attr
  1.2664 +
  1.2665 +    def isConst(self):
  1.2666 +        return self.tag == IDLInterfaceMember.Tags.Const
  1.2667 +
  1.2668 +    def addExtendedAttributes(self, attrs):
  1.2669 +        for attr in attrs:
  1.2670 +            self.handleExtendedAttribute(attr)
  1.2671 +            attrlist = attr.listValue()
  1.2672 +            self._extendedAttrDict[attr.identifier()] = attrlist if len(attrlist) else True
  1.2673 +
  1.2674 +    def handleExtendedAttribute(self, attr):
  1.2675 +        pass
  1.2676 +
  1.2677 +    def getExtendedAttribute(self, name):
  1.2678 +        return self._extendedAttrDict.get(name, None)
  1.2679 +
  1.2680 +class IDLConst(IDLInterfaceMember):
  1.2681 +    def __init__(self, location, identifier, type, value):
  1.2682 +        IDLInterfaceMember.__init__(self, location, identifier,
  1.2683 +                                    IDLInterfaceMember.Tags.Const)
  1.2684 +
  1.2685 +        assert isinstance(type, IDLType)
  1.2686 +        if type.isDictionary():
  1.2687 +            raise WebIDLError("A constant cannot be of a dictionary type",
  1.2688 +                              [self.location])
  1.2689 +        self.type = type
  1.2690 +        self.value = value
  1.2691 +
  1.2692 +        if identifier.name == "prototype":
  1.2693 +            raise WebIDLError("The identifier of a constant must not be 'prototype'",
  1.2694 +                              [location])
  1.2695 +
  1.2696 +    def __str__(self):
  1.2697 +        return "'%s' const '%s'" % (self.type, self.identifier)
  1.2698 +
  1.2699 +    def finish(self, scope):
  1.2700 +        if not self.type.isComplete():
  1.2701 +            type = self.type.complete(scope)
  1.2702 +            if not type.isPrimitive() and not type.isString():
  1.2703 +                locations = [self.type.location, type.location]
  1.2704 +                try:
  1.2705 +                    locations.append(type.inner.location)
  1.2706 +                except:
  1.2707 +                    pass
  1.2708 +                raise WebIDLError("Incorrect type for constant", locations)
  1.2709 +            self.type = type
  1.2710 +
  1.2711 +        # The value might not match the type
  1.2712 +        coercedValue = self.value.coerceToType(self.type, self.location)
  1.2713 +        assert coercedValue
  1.2714 +
  1.2715 +        self.value = coercedValue
  1.2716 +
  1.2717 +    def validate(self):
  1.2718 +        pass
  1.2719 +
  1.2720 +    def _getDependentObjects(self):
  1.2721 +        return set([self.type, self.value])
  1.2722 +
  1.2723 +class IDLAttribute(IDLInterfaceMember):
  1.2724 +    def __init__(self, location, identifier, type, readonly, inherit=False,
  1.2725 +                 static=False, stringifier=False):
  1.2726 +        IDLInterfaceMember.__init__(self, location, identifier,
  1.2727 +                                    IDLInterfaceMember.Tags.Attr)
  1.2728 +
  1.2729 +        assert isinstance(type, IDLType)
  1.2730 +        self.type = type
  1.2731 +        self.readonly = readonly
  1.2732 +        self.inherit = inherit
  1.2733 +        self.static = static
  1.2734 +        self.lenientThis = False
  1.2735 +        self._unforgeable = False
  1.2736 +        self.stringifier = stringifier
  1.2737 +        self.enforceRange = False
  1.2738 +        self.clamp = False
  1.2739 +        self.slotIndex = None
  1.2740 +
  1.2741 +        if static and identifier.name == "prototype":
  1.2742 +            raise WebIDLError("The identifier of a static attribute must not be 'prototype'",
  1.2743 +                              [location])
  1.2744 +
  1.2745 +        if readonly and inherit:
  1.2746 +            raise WebIDLError("An attribute cannot be both 'readonly' and 'inherit'",
  1.2747 +                              [self.location])
  1.2748 +
  1.2749 +    def isStatic(self):
  1.2750 +        return self.static
  1.2751 +
  1.2752 +    def __str__(self):
  1.2753 +        return "'%s' attribute '%s'" % (self.type, self.identifier)
  1.2754 +
  1.2755 +    def finish(self, scope):
  1.2756 +        if not self.type.isComplete():
  1.2757 +            t = self.type.complete(scope)
  1.2758 +
  1.2759 +            assert not isinstance(t, IDLUnresolvedType)
  1.2760 +            assert not isinstance(t, IDLTypedefType)
  1.2761 +            assert not isinstance(t.name, IDLUnresolvedIdentifier)
  1.2762 +            self.type = t
  1.2763 +
  1.2764 +        if self.type.isDictionary() and not self.getExtendedAttribute("Cached"):
  1.2765 +            raise WebIDLError("An attribute cannot be of a dictionary type",
  1.2766 +                              [self.location])
  1.2767 +        if self.type.isSequence() and not self.getExtendedAttribute("Cached"):
  1.2768 +            raise WebIDLError("A non-cached attribute cannot be of a sequence "
  1.2769 +                              "type", [self.location])
  1.2770 +        if self.type.isMozMap() and not self.getExtendedAttribute("Cached"):
  1.2771 +            raise WebIDLError("A non-cached attribute cannot be of a MozMap "
  1.2772 +                              "type", [self.location])
  1.2773 +        if self.type.isUnion():
  1.2774 +            for f in self.type.unroll().flatMemberTypes:
  1.2775 +                if f.isDictionary():
  1.2776 +                    raise WebIDLError("An attribute cannot be of a union "
  1.2777 +                                      "type if one of its member types (or "
  1.2778 +                                      "one of its member types's member "
  1.2779 +                                      "types, and so on) is a dictionary "
  1.2780 +                                      "type", [self.location, f.location])
  1.2781 +                if f.isSequence():
  1.2782 +                    raise WebIDLError("An attribute cannot be of a union "
  1.2783 +                                      "type if one of its member types (or "
  1.2784 +                                      "one of its member types's member "
  1.2785 +                                      "types, and so on) is a sequence "
  1.2786 +                                      "type", [self.location, f.location])
  1.2787 +                if f.isMozMap():
  1.2788 +                    raise WebIDLError("An attribute cannot be of a union "
  1.2789 +                                      "type if one of its member types (or "
  1.2790 +                                      "one of its member types's member "
  1.2791 +                                      "types, and so on) is a MozMap "
  1.2792 +                                      "type", [self.location, f.location])
  1.2793 +        if not self.type.isInterface() and self.getExtendedAttribute("PutForwards"):
  1.2794 +            raise WebIDLError("An attribute with [PutForwards] must have an "
  1.2795 +                              "interface type as its type", [self.location])
  1.2796 +
  1.2797 +        if not self.type.isInterface() and self.getExtendedAttribute("SameObject"):
  1.2798 +            raise WebIDLError("An attribute with [SameObject] must have an "
  1.2799 +                              "interface type as its type", [self.location])
  1.2800 +
  1.2801 +    def validate(self):
  1.2802 +        if ((self.getExtendedAttribute("Cached") or
  1.2803 +             self.getExtendedAttribute("StoreInSlot")) and
  1.2804 +            not self.getExtendedAttribute("Constant") and
  1.2805 +            not self.getExtendedAttribute("Pure")):
  1.2806 +            raise WebIDLError("Cached attributes and attributes stored in "
  1.2807 +                              "slots must be constant or pure, since the "
  1.2808 +                              "getter won't always be called.",
  1.2809 +                              [self.location])
  1.2810 +        if self.getExtendedAttribute("Frozen"):
  1.2811 +            if (not self.type.isSequence() and not self.type.isDictionary() and
  1.2812 +                not self.type.isMozMap()):
  1.2813 +                raise WebIDLError("[Frozen] is only allowed on "
  1.2814 +                                  "sequence-valued, dictionary-valued, and "
  1.2815 +                                  "MozMap-valued attributes",
  1.2816 +                                  [self.location])
  1.2817 +
  1.2818 +    def handleExtendedAttribute(self, attr):
  1.2819 +        identifier = attr.identifier()
  1.2820 +        if identifier == "SetterThrows" and self.readonly:
  1.2821 +            raise WebIDLError("Readonly attributes must not be flagged as "
  1.2822 +                              "[SetterThrows]",
  1.2823 +                              [self.location])
  1.2824 +        elif (((identifier == "Throws" or identifier == "GetterThrows") and
  1.2825 +               self.getExtendedAttribute("StoreInSlot")) or
  1.2826 +              (identifier == "StoreInSlot" and
  1.2827 +               (self.getExtendedAttribute("Throws") or
  1.2828 +                self.getExtendedAttribute("GetterThrows")))):
  1.2829 +            raise WebIDLError("Throwing things can't be [Pure] or [Constant] "
  1.2830 +                              "or [SameObject] or [StoreInSlot]",
  1.2831 +                              [attr.location])
  1.2832 +        elif identifier == "LenientThis":
  1.2833 +            if not attr.noArguments():
  1.2834 +                raise WebIDLError("[LenientThis] must take no arguments",
  1.2835 +                                  [attr.location])
  1.2836 +            if self.isStatic():
  1.2837 +                raise WebIDLError("[LenientThis] is only allowed on non-static "
  1.2838 +                                  "attributes", [attr.location, self.location])
  1.2839 +            if self.getExtendedAttribute("CrossOriginReadable"):
  1.2840 +                raise WebIDLError("[LenientThis] is not allowed in combination "
  1.2841 +                                  "with [CrossOriginReadable]",
  1.2842 +                                  [attr.location, self.location])
  1.2843 +            if self.getExtendedAttribute("CrossOriginWritable"):
  1.2844 +                raise WebIDLError("[LenientThis] is not allowed in combination "
  1.2845 +                                  "with [CrossOriginWritable]",
  1.2846 +                                  [attr.location, self.location])
  1.2847 +            self.lenientThis = True
  1.2848 +        elif identifier == "Unforgeable":
  1.2849 +            if not self.readonly:
  1.2850 +                raise WebIDLError("[Unforgeable] is only allowed on readonly "
  1.2851 +                                  "attributes", [attr.location, self.location])
  1.2852 +            if self.isStatic():
  1.2853 +                raise WebIDLError("[Unforgeable] is only allowed on non-static "
  1.2854 +                                  "attributes", [attr.location, self.location])
  1.2855 +            self._unforgeable = True
  1.2856 +        elif identifier == "SameObject" and not self.readonly:
  1.2857 +            raise WebIDLError("[SameObject] only allowed on readonly attributes",
  1.2858 +                              [attr.location, self.location])
  1.2859 +        elif identifier == "Constant" and not self.readonly:
  1.2860 +            raise WebIDLError("[Constant] only allowed on readonly attributes",
  1.2861 +                              [attr.location, self.location])
  1.2862 +        elif identifier == "PutForwards":
  1.2863 +            if not self.readonly:
  1.2864 +                raise WebIDLError("[PutForwards] is only allowed on readonly "
  1.2865 +                                  "attributes", [attr.location, self.location])
  1.2866 +            if self.isStatic():
  1.2867 +                raise WebIDLError("[PutForwards] is only allowed on non-static "
  1.2868 +                                  "attributes", [attr.location, self.location])
  1.2869 +            if self.getExtendedAttribute("Replaceable") is not None:
  1.2870 +                raise WebIDLError("[PutForwards] and [Replaceable] can't both "
  1.2871 +                                  "appear on the same attribute",
  1.2872 +                                  [attr.location, self.location])
  1.2873 +            if not attr.hasValue():
  1.2874 +                raise WebIDLError("[PutForwards] takes an identifier",
  1.2875 +                                  [attr.location, self.location])
  1.2876 +        elif identifier == "Replaceable":
  1.2877 +            if self.getExtendedAttribute("PutForwards") is not None:
  1.2878 +                raise WebIDLError("[PutForwards] and [Replaceable] can't both "
  1.2879 +                                  "appear on the same attribute",
  1.2880 +                                  [attr.location, self.location])
  1.2881 +        elif identifier == "LenientFloat":
  1.2882 +            if self.readonly:
  1.2883 +                raise WebIDLError("[LenientFloat] used on a readonly attribute",
  1.2884 +                                  [attr.location, self.location])
  1.2885 +            if not self.type.includesRestrictedFloat():
  1.2886 +                raise WebIDLError("[LenientFloat] used on an attribute with a "
  1.2887 +                                  "non-restricted-float type",
  1.2888 +                                  [attr.location, self.location])
  1.2889 +        elif identifier == "EnforceRange":
  1.2890 +            if self.readonly:
  1.2891 +                raise WebIDLError("[EnforceRange] used on a readonly attribute",
  1.2892 +                                  [attr.location, self.location])
  1.2893 +            self.enforceRange = True
  1.2894 +        elif identifier == "Clamp":
  1.2895 +            if self.readonly:
  1.2896 +                raise WebIDLError("[Clamp] used on a readonly attribute",
  1.2897 +                                  [attr.location, self.location])
  1.2898 +            self.clamp = True
  1.2899 +        elif identifier == "StoreInSlot":
  1.2900 +            if self.getExtendedAttribute("Cached"):
  1.2901 +                raise WebIDLError("[StoreInSlot] and [Cached] must not be "
  1.2902 +                                  "specified on the same attribute",
  1.2903 +                                  [attr.location, self.location])
  1.2904 +        elif identifier == "Cached":
  1.2905 +            if self.getExtendedAttribute("StoreInSlot"):
  1.2906 +                raise WebIDLError("[Cached] and [StoreInSlot] must not be "
  1.2907 +                                  "specified on the same attribute",
  1.2908 +                                  [attr.location, self.location])
  1.2909 +        elif (identifier == "CrossOriginReadable" or
  1.2910 +              identifier == "CrossOriginWritable"):
  1.2911 +            if not attr.noArguments():
  1.2912 +                raise WebIDLError("[%s] must take no arguments" % identifier,
  1.2913 +                                  [attr.location])
  1.2914 +            if self.isStatic():
  1.2915 +                raise WebIDLError("[%s] is only allowed on non-static "
  1.2916 +                                  "attributes" % identifier,
  1.2917 +                                  [attr.location, self.location])
  1.2918 +            if self.getExtendedAttribute("LenientThis"):
  1.2919 +                raise WebIDLError("[LenientThis] is not allowed in combination "
  1.2920 +                                  "with [%s]" % identifier,
  1.2921 +                                  [attr.location, self.location])
  1.2922 +        elif (identifier == "Pref" or
  1.2923 +              identifier == "SetterThrows" or
  1.2924 +              identifier == "Pure" or
  1.2925 +              identifier == "Throws" or
  1.2926 +              identifier == "GetterThrows" or
  1.2927 +              identifier == "ChromeOnly" or
  1.2928 +              identifier == "SameObject" or
  1.2929 +              identifier == "Constant" or
  1.2930 +              identifier == "Func" or
  1.2931 +              identifier == "Frozen" or
  1.2932 +              identifier == "AvailableIn" or
  1.2933 +              identifier == "NewObject"):
  1.2934 +            # Known attributes that we don't need to do anything with here
  1.2935 +            pass
  1.2936 +        else:
  1.2937 +            raise WebIDLError("Unknown extended attribute %s on attribute" % identifier,
  1.2938 +                              [attr.location])
  1.2939 +        IDLInterfaceMember.handleExtendedAttribute(self, attr)
  1.2940 +
  1.2941 +    def resolve(self, parentScope):
  1.2942 +        assert isinstance(parentScope, IDLScope)
  1.2943 +        self.type.resolveType(parentScope)
  1.2944 +        IDLObjectWithIdentifier.resolve(self, parentScope)
  1.2945 +
  1.2946 +    def addExtendedAttributes(self, attrs):
  1.2947 +        attrs = self.checkForStringHandlingExtendedAttributes(attrs)
  1.2948 +        IDLInterfaceMember.addExtendedAttributes(self, attrs)
  1.2949 +
  1.2950 +    def hasLenientThis(self):
  1.2951 +        return self.lenientThis
  1.2952 +
  1.2953 +    def isUnforgeable(self):
  1.2954 +        return self._unforgeable
  1.2955 +
  1.2956 +    def _getDependentObjects(self):
  1.2957 +        return set([self.type])
  1.2958 +
  1.2959 +class IDLArgument(IDLObjectWithIdentifier):
  1.2960 +    def __init__(self, location, identifier, type, optional=False, defaultValue=None, variadic=False, dictionaryMember=False):
  1.2961 +        IDLObjectWithIdentifier.__init__(self, location, None, identifier)
  1.2962 +
  1.2963 +        assert isinstance(type, IDLType)
  1.2964 +        self.type = type
  1.2965 +
  1.2966 +        self.optional = optional
  1.2967 +        self.defaultValue = defaultValue
  1.2968 +        self.variadic = variadic
  1.2969 +        self.dictionaryMember = dictionaryMember
  1.2970 +        self._isComplete = False
  1.2971 +        self.enforceRange = False
  1.2972 +        self.clamp = False
  1.2973 +        self._allowTreatNonCallableAsNull = False
  1.2974 +
  1.2975 +        assert not variadic or optional
  1.2976 +
  1.2977 +    def addExtendedAttributes(self, attrs):
  1.2978 +        attrs = self.checkForStringHandlingExtendedAttributes(
  1.2979 +            attrs,
  1.2980 +            isDictionaryMember=self.dictionaryMember,
  1.2981 +            isOptional=self.optional)
  1.2982 +        for attribute in attrs:
  1.2983 +            identifier = attribute.identifier()
  1.2984 +            if identifier == "Clamp":
  1.2985 +                if not attribute.noArguments():
  1.2986 +                    raise WebIDLError("[Clamp] must take no arguments",
  1.2987 +                                      [attribute.location])
  1.2988 +                if self.enforceRange:
  1.2989 +                    raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive",
  1.2990 +                                      [self.location]);
  1.2991 +                self.clamp = True
  1.2992 +            elif identifier == "EnforceRange":
  1.2993 +                if not attribute.noArguments():
  1.2994 +                    raise WebIDLError("[EnforceRange] must take no arguments",
  1.2995 +                                      [attribute.location])
  1.2996 +                if self.clamp:
  1.2997 +                    raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive",
  1.2998 +                                      [self.location]);
  1.2999 +                self.enforceRange = True
  1.3000 +            elif identifier == "TreatNonCallableAsNull":
  1.3001 +                self._allowTreatNonCallableAsNull = True
  1.3002 +            else:
  1.3003 +                raise WebIDLError("Unhandled extended attribute on an argument",
  1.3004 +                                  [attribute.location])
  1.3005 +
  1.3006 +    def isComplete(self):
  1.3007 +        return self._isComplete
  1.3008 +
  1.3009 +    def complete(self, scope):
  1.3010 +        if self._isComplete:
  1.3011 +            return
  1.3012 +
  1.3013 +        self._isComplete = True
  1.3014 +
  1.3015 +        if not self.type.isComplete():
  1.3016 +            type = self.type.complete(scope)
  1.3017 +            assert not isinstance(type, IDLUnresolvedType)
  1.3018 +            assert not isinstance(type, IDLTypedefType)
  1.3019 +            assert not isinstance(type.name, IDLUnresolvedIdentifier)
  1.3020 +            self.type = type
  1.3021 +
  1.3022 +        if ((self.type.isDictionary() or
  1.3023 +             self.type.isUnion() and self.type.unroll().hasDictionaryType) and
  1.3024 +            self.optional and not self.defaultValue):
  1.3025 +            # Default optional dictionaries to null, for simplicity,
  1.3026 +            # so the codegen doesn't have to special-case this.
  1.3027 +            self.defaultValue = IDLNullValue(self.location)
  1.3028 +        elif self.type.isAny():
  1.3029 +            assert (self.defaultValue is None or
  1.3030 +                    isinstance(self.defaultValue, IDLNullValue))
  1.3031 +            # optional 'any' values always have a default value
  1.3032 +            if self.optional and not self.defaultValue and not self.variadic:
  1.3033 +                # Set the default value to undefined, for simplicity, so the
  1.3034 +                # codegen doesn't have to special-case this.
  1.3035 +                self.defaultValue = IDLUndefinedValue(self.location)
  1.3036 +
  1.3037 +        # Now do the coercing thing; this needs to happen after the
  1.3038 +        # above creation of a default value.
  1.3039 +        if self.defaultValue:
  1.3040 +            self.defaultValue = self.defaultValue.coerceToType(self.type,
  1.3041 +                                                               self.location)
  1.3042 +            assert self.defaultValue
  1.3043 +
  1.3044 +    def allowTreatNonCallableAsNull(self):
  1.3045 +        return self._allowTreatNonCallableAsNull
  1.3046 +
  1.3047 +    def _getDependentObjects(self):
  1.3048 +        deps = set([self.type])
  1.3049 +        if self.defaultValue:
  1.3050 +            deps.add(self.defaultValue)
  1.3051 +        return deps
  1.3052 +
  1.3053 +class IDLCallbackType(IDLType, IDLObjectWithScope):
  1.3054 +    def __init__(self, location, parentScope, identifier, returnType, arguments):
  1.3055 +        assert isinstance(returnType, IDLType)
  1.3056 +
  1.3057 +        IDLType.__init__(self, location, identifier.name)
  1.3058 +
  1.3059 +        self._returnType = returnType
  1.3060 +        # Clone the list
  1.3061 +        self._arguments = list(arguments)
  1.3062 +
  1.3063 +        IDLObjectWithScope.__init__(self, location, parentScope, identifier)
  1.3064 +
  1.3065 +        for (returnType, arguments) in self.signatures():
  1.3066 +            for argument in arguments:
  1.3067 +                argument.resolve(self)
  1.3068 +
  1.3069 +        self._treatNonCallableAsNull = False
  1.3070 +        self._treatNonObjectAsNull = False
  1.3071 +
  1.3072 +    def isCallback(self):
  1.3073 +        return True
  1.3074 +
  1.3075 +    def signatures(self):
  1.3076 +        return [(self._returnType, self._arguments)]
  1.3077 +
  1.3078 +    def tag(self):
  1.3079 +        return IDLType.Tags.callback
  1.3080 +
  1.3081 +    def finish(self, scope):
  1.3082 +        if not self._returnType.isComplete():
  1.3083 +            type = self._returnType.complete(scope)
  1.3084 +
  1.3085 +            assert not isinstance(type, IDLUnresolvedType)
  1.3086 +            assert not isinstance(type, IDLTypedefType)
  1.3087 +            assert not isinstance(type.name, IDLUnresolvedIdentifier)
  1.3088 +            self._returnType = type
  1.3089 +
  1.3090 +        for argument in self._arguments:
  1.3091 +            if argument.type.isComplete():
  1.3092 +                continue
  1.3093 +
  1.3094 +            type = argument.type.complete(scope)
  1.3095 +
  1.3096 +            assert not isinstance(type, IDLUnresolvedType)
  1.3097 +            assert not isinstance(type, IDLTypedefType)
  1.3098 +            assert not isinstance(type.name, IDLUnresolvedIdentifier)
  1.3099 +            argument.type = type
  1.3100 +
  1.3101 +    def validate(self):
  1.3102 +        pass
  1.3103 +
  1.3104 +    def isDistinguishableFrom(self, other):
  1.3105 +        if other.isUnion():
  1.3106 +            # Just forward to the union; it'll deal
  1.3107 +            return other.isDistinguishableFrom(self)
  1.3108 +        return (other.isPrimitive() or other.isString() or other.isEnum() or
  1.3109 +                other.isNonCallbackInterface() or other.isDate())
  1.3110 +
  1.3111 +    def addExtendedAttributes(self, attrs):
  1.3112 +        unhandledAttrs = []
  1.3113 +        for attr in attrs:
  1.3114 +            if attr.identifier() == "TreatNonCallableAsNull":
  1.3115 +                self._treatNonCallableAsNull = True
  1.3116 +            elif attr.identifier() == "TreatNonObjectAsNull":
  1.3117 +                self._treatNonObjectAsNull = True
  1.3118 +            else:
  1.3119 +                unhandledAttrs.append(attr)
  1.3120 +        if self._treatNonCallableAsNull and self._treatNonObjectAsNull:
  1.3121 +            raise WebIDLError("Cannot specify both [TreatNonCallableAsNull] "
  1.3122 +                              "and [TreatNonObjectAsNull]", [self.location])
  1.3123 +        if len(unhandledAttrs) != 0:
  1.3124 +            IDLType.addExtendedAttributes(self, unhandledAttrs)
  1.3125 +
  1.3126 +    def _getDependentObjects(self):
  1.3127 +        return set([self._returnType] + self._arguments)
  1.3128 +
  1.3129 +class IDLMethodOverload:
  1.3130 +    """
  1.3131 +    A class that represents a single overload of a WebIDL method.  This is not
  1.3132 +    quite the same as an element of the "effective overload set" in the spec,
  1.3133 +    because separate IDLMethodOverloads are not created based on arguments being
  1.3134 +    optional.  Rather, when multiple methods have the same name, there is an
  1.3135 +    IDLMethodOverload for each one, all hanging off an IDLMethod representing
  1.3136 +    the full set of overloads.
  1.3137 +    """
  1.3138 +    def __init__(self, returnType, arguments, location):
  1.3139 +        self.returnType = returnType
  1.3140 +        # Clone the list of arguments, just in case
  1.3141 +        self.arguments = list(arguments)
  1.3142 +        self.location = location
  1.3143 +
  1.3144 +    def _getDependentObjects(self):
  1.3145 +        deps = set(self.arguments)
  1.3146 +        deps.add(self.returnType)
  1.3147 +        return deps
  1.3148 +
  1.3149 +class IDLMethod(IDLInterfaceMember, IDLScope):
  1.3150 +
  1.3151 +    Special = enum(
  1.3152 +        'Getter',
  1.3153 +        'Setter',
  1.3154 +        'Creator',
  1.3155 +        'Deleter',
  1.3156 +        'LegacyCaller',
  1.3157 +        base=IDLInterfaceMember.Special
  1.3158 +    )
  1.3159 +
  1.3160 +    TypeSuffixModifier = enum(
  1.3161 +        'None',
  1.3162 +        'QMark',
  1.3163 +        'Brackets'
  1.3164 +    )
  1.3165 +
  1.3166 +    NamedOrIndexed = enum(
  1.3167 +        'Neither',
  1.3168 +        'Named',
  1.3169 +        'Indexed'
  1.3170 +    )
  1.3171 +
  1.3172 +    def __init__(self, location, identifier, returnType, arguments,
  1.3173 +                 static=False, getter=False, setter=False, creator=False,
  1.3174 +                 deleter=False, specialType=NamedOrIndexed.Neither,
  1.3175 +                 legacycaller=False, stringifier=False, jsonifier=False):
  1.3176 +        # REVIEW: specialType is NamedOrIndexed -- wow, this is messed up.
  1.3177 +        IDLInterfaceMember.__init__(self, location, identifier,
  1.3178 +                                    IDLInterfaceMember.Tags.Method)
  1.3179 +
  1.3180 +        self._hasOverloads = False
  1.3181 +
  1.3182 +        assert isinstance(returnType, IDLType)
  1.3183 +
  1.3184 +        # self._overloads is a list of IDLMethodOverloads
  1.3185 +        self._overloads = [IDLMethodOverload(returnType, arguments, location)]
  1.3186 +
  1.3187 +        assert isinstance(static, bool)
  1.3188 +        self._static = static
  1.3189 +        assert isinstance(getter, bool)
  1.3190 +        self._getter = getter
  1.3191 +        assert isinstance(setter, bool)
  1.3192 +        self._setter = setter
  1.3193 +        assert isinstance(creator, bool)
  1.3194 +        self._creator = creator
  1.3195 +        assert isinstance(deleter, bool)
  1.3196 +        self._deleter = deleter
  1.3197 +        assert isinstance(legacycaller, bool)
  1.3198 +        self._legacycaller = legacycaller
  1.3199 +        assert isinstance(stringifier, bool)
  1.3200 +        self._stringifier = stringifier
  1.3201 +        assert isinstance(jsonifier, bool)
  1.3202 +        self._jsonifier = jsonifier
  1.3203 +        self._specialType = specialType
  1.3204 +
  1.3205 +        if static and identifier.name == "prototype":
  1.3206 +            raise WebIDLError("The identifier of a static operation must not be 'prototype'",
  1.3207 +                              [location])
  1.3208 +
  1.3209 +        self.assertSignatureConstraints()
  1.3210 +
  1.3211 +    def __str__(self):
  1.3212 +        return "Method '%s'" % self.identifier
  1.3213 +
  1.3214 +    def assertSignatureConstraints(self):
  1.3215 +        if self._getter or self._deleter:
  1.3216 +            assert len(self._overloads) == 1
  1.3217 +            overload = self._overloads[0]
  1.3218 +            arguments =  overload.arguments
  1.3219 +            assert len(arguments) == 1
  1.3220 +            assert arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.domstring] or \
  1.3221 +                   arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]
  1.3222 +            assert not arguments[0].optional and not arguments[0].variadic
  1.3223 +            assert not self._getter or not overload.returnType.isVoid()
  1.3224 +
  1.3225 +        if self._setter or self._creator:
  1.3226 +            assert len(self._overloads) == 1
  1.3227 +            arguments = self._overloads[0].arguments
  1.3228 +            assert len(arguments) == 2
  1.3229 +            assert arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.domstring] or \
  1.3230 +                   arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]
  1.3231 +            assert not arguments[0].optional and not arguments[0].variadic
  1.3232 +            assert not arguments[1].optional and not arguments[1].variadic
  1.3233 +
  1.3234 +        if self._stringifier:
  1.3235 +            assert len(self._overloads) == 1
  1.3236 +            overload = self._overloads[0]
  1.3237 +            assert len(overload.arguments) == 0
  1.3238 +            assert overload.returnType == BuiltinTypes[IDLBuiltinType.Types.domstring]
  1.3239 +
  1.3240 +        if self._jsonifier:
  1.3241 +            assert len(self._overloads) == 1
  1.3242 +            overload = self._overloads[0]
  1.3243 +            assert len(overload.arguments) == 0
  1.3244 +            assert overload.returnType == BuiltinTypes[IDLBuiltinType.Types.object]
  1.3245 +
  1.3246 +    def isStatic(self):
  1.3247 +        return self._static
  1.3248 +
  1.3249 +    def isGetter(self):
  1.3250 +        return self._getter
  1.3251 +
  1.3252 +    def isSetter(self):
  1.3253 +        return self._setter
  1.3254 +
  1.3255 +    def isCreator(self):
  1.3256 +        return self._creator
  1.3257 +
  1.3258 +    def isDeleter(self):
  1.3259 +        return self._deleter
  1.3260 +
  1.3261 +    def isNamed(self):
  1.3262 +        assert self._specialType == IDLMethod.NamedOrIndexed.Named or \
  1.3263 +               self._specialType == IDLMethod.NamedOrIndexed.Indexed
  1.3264 +        return self._specialType == IDLMethod.NamedOrIndexed.Named
  1.3265 +
  1.3266 +    def isIndexed(self):
  1.3267 +        assert self._specialType == IDLMethod.NamedOrIndexed.Named or \
  1.3268 +               self._specialType == IDLMethod.NamedOrIndexed.Indexed
  1.3269 +        return self._specialType == IDLMethod.NamedOrIndexed.Indexed
  1.3270 +
  1.3271 +    def isLegacycaller(self):
  1.3272 +        return self._legacycaller
  1.3273 +
  1.3274 +    def isStringifier(self):
  1.3275 +        return self._stringifier
  1.3276 +
  1.3277 +    def isJsonifier(self):
  1.3278 +        return self._jsonifier
  1.3279 +
  1.3280 +    def hasOverloads(self):
  1.3281 +        return self._hasOverloads
  1.3282 +
  1.3283 +    def isIdentifierLess(self):
  1.3284 +        return self.identifier.name[:2] == "__" and self.identifier.name != "__noSuchMethod__"
  1.3285 +
  1.3286 +    def resolve(self, parentScope):
  1.3287 +        assert isinstance(parentScope, IDLScope)
  1.3288 +        IDLObjectWithIdentifier.resolve(self, parentScope)
  1.3289 +        IDLScope.__init__(self, self.location, parentScope, self.identifier)
  1.3290 +        for (returnType, arguments) in self.signatures():
  1.3291 +            for argument in arguments:
  1.3292 +                argument.resolve(self)
  1.3293 +
  1.3294 +    def addOverload(self, method):
  1.3295 +        assert len(method._overloads) == 1
  1.3296 +
  1.3297 +        if self._extendedAttrDict != method ._extendedAttrDict:
  1.3298 +            raise WebIDLError("Extended attributes differ on different "
  1.3299 +                              "overloads of %s" % method.identifier,
  1.3300 +                              [self.location, method.location])
  1.3301 +
  1.3302 +        self._overloads.extend(method._overloads)
  1.3303 +
  1.3304 +        self._hasOverloads = True
  1.3305 +
  1.3306 +        if self.isStatic() != method.isStatic():
  1.3307 +            raise WebIDLError("Overloaded identifier %s appears with different values of the 'static' attribute" % method.identifier,
  1.3308 +                              [method.location])
  1.3309 +
  1.3310 +        if self.isLegacycaller() != method.isLegacycaller():
  1.3311 +            raise WebIDLError("Overloaded identifier %s appears with different values of the 'legacycaller' attribute" % method.identifier,
  1.3312 +                              [method.location])
  1.3313 +
  1.3314 +        # Can't overload special things!
  1.3315 +        assert not self.isGetter()
  1.3316 +        assert not method.isGetter()
  1.3317 +        assert not self.isSetter()
  1.3318 +        assert not method.isSetter()
  1.3319 +        assert not self.isCreator()
  1.3320 +        assert not method.isCreator()
  1.3321 +        assert not self.isDeleter()
  1.3322 +        assert not method.isDeleter()
  1.3323 +        assert not self.isStringifier()
  1.3324 +        assert not method.isStringifier()
  1.3325 +        assert not self.isJsonifier()
  1.3326 +        assert not method.isJsonifier()
  1.3327 +
  1.3328 +        return self
  1.3329 +
  1.3330 +    def signatures(self):
  1.3331 +        return [(overload.returnType, overload.arguments) for overload in
  1.3332 +                self._overloads]
  1.3333 +
  1.3334 +    def finish(self, scope):
  1.3335 +        overloadWithPromiseReturnType = None
  1.3336 +        overloadWithoutPromiseReturnType = None
  1.3337 +        for overload in self._overloads:
  1.3338 +            variadicArgument = None
  1.3339 +
  1.3340 +            arguments = overload.arguments
  1.3341 +            for (idx, argument) in enumerate(arguments):
  1.3342 +                if not argument.isComplete():
  1.3343 +                    argument.complete(scope)
  1.3344 +                assert argument.type.isComplete()
  1.3345 +
  1.3346 +                if (argument.type.isDictionary() or
  1.3347 +                    (argument.type.isUnion() and
  1.3348 +                     argument.type.unroll().hasDictionaryType)):
  1.3349 +                    # Dictionaries and unions containing dictionaries at the
  1.3350 +                    # end of the list or followed by optional arguments must be
  1.3351 +                    # optional.
  1.3352 +                    if (not argument.optional and
  1.3353 +                        all(arg.optional for arg in arguments[idx+1:])):
  1.3354 +                        raise WebIDLError("Dictionary argument or union "
  1.3355 +                                          "argument containing a dictionary "
  1.3356 +                                          "not followed by a required argument "
  1.3357 +                                          "must be optional",
  1.3358 +                                          [argument.location])
  1.3359 +
  1.3360 +                    # An argument cannot be a Nullable Dictionary
  1.3361 +                    if argument.type.nullable():
  1.3362 +                        raise WebIDLError("An argument cannot be a nullable "
  1.3363 +                                          "dictionary or nullable union "
  1.3364 +                                          "containing a dictionary",
  1.3365 +                                          [argument.location])
  1.3366 +
  1.3367 +                # Only the last argument can be variadic
  1.3368 +                if variadicArgument:
  1.3369 +                    raise WebIDLError("Variadic argument is not last argument",
  1.3370 +                                      [variadicArgument.location])
  1.3371 +                if argument.variadic:
  1.3372 +                    variadicArgument = argument
  1.3373 +
  1.3374 +            returnType = overload.returnType
  1.3375 +            if not returnType.isComplete():
  1.3376 +                returnType = returnType.complete(scope)
  1.3377 +                assert not isinstance(returnType, IDLUnresolvedType)
  1.3378 +                assert not isinstance(returnType, IDLTypedefType)
  1.3379 +                assert not isinstance(returnType.name, IDLUnresolvedIdentifier)
  1.3380 +                overload.returnType = returnType
  1.3381 +
  1.3382 +            if returnType.isPromise():
  1.3383 +                overloadWithPromiseReturnType = overload
  1.3384 +            else:
  1.3385 +                overloadWithoutPromiseReturnType = overload
  1.3386 +
  1.3387 +        # Make sure either all our overloads return Promises or none do
  1.3388 +        if overloadWithPromiseReturnType and overloadWithoutPromiseReturnType:
  1.3389 +            raise WebIDLError("We have overloads with both Promise and "
  1.3390 +                              "non-Promise return types",
  1.3391 +                              [overloadWithPromiseReturnType.location,
  1.3392 +                               overloadWithoutPromiseReturnType.location])
  1.3393 +
  1.3394 +        if overloadWithPromiseReturnType and self._legacycaller:
  1.3395 +            raise WebIDLError("May not have a Promise return type for a "
  1.3396 +                              "legacycaller.",
  1.3397 +                              [overloadWithPromiseReturnType.location])
  1.3398 +
  1.3399 +        # Now compute various information that will be used by the
  1.3400 +        # WebIDL overload resolution algorithm.
  1.3401 +        self.maxArgCount = max(len(s[1]) for s in self.signatures())
  1.3402 +        self.allowedArgCounts = [ i for i in range(self.maxArgCount+1)
  1.3403 +                                  if len(self.signaturesForArgCount(i)) != 0 ]
  1.3404 +
  1.3405 +    def validate(self):
  1.3406 +        # Make sure our overloads are properly distinguishable and don't have
  1.3407 +        # different argument types before the distinguishing args.
  1.3408 +        for argCount in self.allowedArgCounts:
  1.3409 +            possibleOverloads = self.overloadsForArgCount(argCount)
  1.3410 +            if len(possibleOverloads) == 1:
  1.3411 +                continue
  1.3412 +            distinguishingIndex = self.distinguishingIndexForArgCount(argCount)
  1.3413 +            for idx in range(distinguishingIndex):
  1.3414 +                firstSigType = possibleOverloads[0].arguments[idx].type
  1.3415 +                for overload in possibleOverloads[1:]:
  1.3416 +                    if overload.arguments[idx].type != firstSigType:
  1.3417 +                        raise WebIDLError(
  1.3418 +                            "Signatures for method '%s' with %d arguments have "
  1.3419 +                            "different types of arguments at index %d, which "
  1.3420 +                            "is before distinguishing index %d" %
  1.3421 +                            (self.identifier.name, argCount, idx,
  1.3422 +                             distinguishingIndex),
  1.3423 +                            [self.location, overload.location])
  1.3424 +
  1.3425 +    def overloadsForArgCount(self, argc):
  1.3426 +        return [overload for overload in self._overloads if
  1.3427 +                len(overload.arguments) == argc or
  1.3428 +                (len(overload.arguments) > argc and
  1.3429 +                 all(arg.optional for arg in overload.arguments[argc:])) or
  1.3430 +                (len(overload.arguments) < argc and
  1.3431 +                 len(overload.arguments) > 0 and
  1.3432 +                 overload.arguments[-1].variadic)]
  1.3433 +
  1.3434 +    def signaturesForArgCount(self, argc):
  1.3435 +        return [(overload.returnType, overload.arguments) for overload
  1.3436 +                in self.overloadsForArgCount(argc)]
  1.3437 +
  1.3438 +    def locationsForArgCount(self, argc):
  1.3439 +        return [overload.location for overload in self.overloadsForArgCount(argc)]
  1.3440 +
  1.3441 +    def distinguishingIndexForArgCount(self, argc):
  1.3442 +        def isValidDistinguishingIndex(idx, signatures):
  1.3443 +            for (firstSigIndex, (firstRetval, firstArgs)) in enumerate(signatures[:-1]):
  1.3444 +                for (secondRetval, secondArgs) in signatures[firstSigIndex+1:]:
  1.3445 +                    if idx < len(firstArgs):
  1.3446 +                        firstType = firstArgs[idx].type
  1.3447 +                    else:
  1.3448 +                        assert(firstArgs[-1].variadic)
  1.3449 +                        firstType = firstArgs[-1].type
  1.3450 +                    if idx < len(secondArgs):
  1.3451 +                        secondType = secondArgs[idx].type
  1.3452 +                    else:
  1.3453 +                        assert(secondArgs[-1].variadic)
  1.3454 +                        secondType = secondArgs[-1].type
  1.3455 +                    if not firstType.isDistinguishableFrom(secondType):
  1.3456 +                        return False
  1.3457 +            return True
  1.3458 +        signatures = self.signaturesForArgCount(argc)
  1.3459 +        for idx in range(argc):
  1.3460 +            if isValidDistinguishingIndex(idx, signatures):
  1.3461 +                return idx
  1.3462 +        # No valid distinguishing index.  Time to throw
  1.3463 +        locations = self.locationsForArgCount(argc)
  1.3464 +        raise WebIDLError("Signatures with %d arguments for method '%s' are not "
  1.3465 +                          "distinguishable" % (argc, self.identifier.name),
  1.3466 +                          locations)
  1.3467 +
  1.3468 +    def handleExtendedAttribute(self, attr):
  1.3469 +        identifier = attr.identifier()
  1.3470 +        if identifier == "GetterThrows":
  1.3471 +            raise WebIDLError("Methods must not be flagged as "
  1.3472 +                              "[GetterThrows]",
  1.3473 +                              [attr.location, self.location])
  1.3474 +        elif identifier == "SetterThrows":
  1.3475 +            raise WebIDLError("Methods must not be flagged as "
  1.3476 +                              "[SetterThrows]",
  1.3477 +                              [attr.location, self.location])
  1.3478 +        elif identifier == "Unforgeable":
  1.3479 +            raise WebIDLError("Methods must not be flagged as "
  1.3480 +                              "[Unforgeable]",
  1.3481 +                              [attr.location, self.location])
  1.3482 +        elif identifier == "SameObject":
  1.3483 +            raise WebIDLError("Methods must not be flagged as [SameObject]",
  1.3484 +                              [attr.location, self.location]);
  1.3485 +        elif identifier == "Constant":
  1.3486 +            raise WebIDLError("Methods must not be flagged as [Constant]",
  1.3487 +                              [attr.location, self.location]);
  1.3488 +        elif identifier == "PutForwards":
  1.3489 +            raise WebIDLError("Only attributes support [PutForwards]",
  1.3490 +                              [attr.location, self.location])
  1.3491 +        elif identifier == "LenientFloat":
  1.3492 +            # This is called before we've done overload resolution
  1.3493 +            assert len(self.signatures()) == 1
  1.3494 +            sig = self.signatures()[0]
  1.3495 +            if not sig[0].isVoid():
  1.3496 +                raise WebIDLError("[LenientFloat] used on a non-void method",
  1.3497 +                                  [attr.location, self.location])
  1.3498 +            if not any(arg.type.includesRestrictedFloat() for arg in sig[1]):
  1.3499 +                raise WebIDLError("[LenientFloat] used on an operation with no "
  1.3500 +                                  "restricted float type arguments",
  1.3501 +                                  [attr.location, self.location])
  1.3502 +        elif (identifier == "Throws" or
  1.3503 +              identifier == "NewObject" or
  1.3504 +              identifier == "ChromeOnly" or
  1.3505 +              identifier == "Pref" or
  1.3506 +              identifier == "Func" or
  1.3507 +              identifier == "AvailableIn" or
  1.3508 +              identifier == "Pure" or
  1.3509 +              identifier == "CrossOriginCallable" or
  1.3510 +              identifier == "WebGLHandlesContextLoss"):
  1.3511 +            # Known attributes that we don't need to do anything with here
  1.3512 +            pass
  1.3513 +        else:
  1.3514 +            raise WebIDLError("Unknown extended attribute %s on method" % identifier,
  1.3515 +                              [attr.location])
  1.3516 +        IDLInterfaceMember.handleExtendedAttribute(self, attr)
  1.3517 +
  1.3518 +    def returnsPromise(self):
  1.3519 +        return self._overloads[0].returnType.isPromise()
  1.3520 +
  1.3521 +    def _getDependentObjects(self):
  1.3522 +        deps = set()
  1.3523 +        for overload in self._overloads:
  1.3524 +            deps.union(overload._getDependentObjects())
  1.3525 +        return deps
  1.3526 +
  1.3527 +class IDLImplementsStatement(IDLObject):
  1.3528 +    def __init__(self, location, implementor, implementee):
  1.3529 +        IDLObject.__init__(self, location)
  1.3530 +        self.implementor = implementor;
  1.3531 +        self.implementee = implementee
  1.3532 +
  1.3533 +    def finish(self, scope):
  1.3534 +        assert(isinstance(self.implementor, IDLIdentifierPlaceholder))
  1.3535 +        assert(isinstance(self.implementee, IDLIdentifierPlaceholder))
  1.3536 +        implementor = self.implementor.finish(scope)
  1.3537 +        implementee = self.implementee.finish(scope)
  1.3538 +        # NOTE: we depend on not setting self.implementor and
  1.3539 +        # self.implementee here to keep track of the original
  1.3540 +        # locations.
  1.3541 +        if not isinstance(implementor, IDLInterface):
  1.3542 +            raise WebIDLError("Left-hand side of 'implements' is not an "
  1.3543 +                              "interface",
  1.3544 +                              [self.implementor.location])
  1.3545 +        if implementor.isCallback():
  1.3546 +            raise WebIDLError("Left-hand side of 'implements' is a callback "
  1.3547 +                              "interface",
  1.3548 +                              [self.implementor.location])
  1.3549 +        if not isinstance(implementee, IDLInterface):
  1.3550 +            raise WebIDLError("Right-hand side of 'implements' is not an "
  1.3551 +                              "interface",
  1.3552 +                              [self.implementee.location])
  1.3553 +        if implementee.isCallback():
  1.3554 +            raise WebIDLError("Right-hand side of 'implements' is a callback "
  1.3555 +                              "interface",
  1.3556 +                              [self.implementee.location])
  1.3557 +        implementor.addImplementedInterface(implementee)
  1.3558 +
  1.3559 +    def validate(self):
  1.3560 +        pass
  1.3561 +
  1.3562 +    def addExtendedAttributes(self, attrs):
  1.3563 +        assert len(attrs) == 0
  1.3564 +
  1.3565 +class IDLExtendedAttribute(IDLObject):
  1.3566 +    """
  1.3567 +    A class to represent IDL extended attributes so we can give them locations
  1.3568 +    """
  1.3569 +    def __init__(self, location, tuple):
  1.3570 +        IDLObject.__init__(self, location)
  1.3571 +        self._tuple = tuple
  1.3572 +
  1.3573 +    def identifier(self):
  1.3574 +        return self._tuple[0]
  1.3575 +
  1.3576 +    def noArguments(self):
  1.3577 +        return len(self._tuple) == 1
  1.3578 +
  1.3579 +    def hasValue(self):
  1.3580 +        return len(self._tuple) >= 2 and isinstance(self._tuple[1], str)
  1.3581 +
  1.3582 +    def value(self):
  1.3583 +        assert(self.hasValue())
  1.3584 +        return self._tuple[1]
  1.3585 +
  1.3586 +    def hasArgs(self):
  1.3587 +        return (len(self._tuple) == 2 and isinstance(self._tuple[1], list) or
  1.3588 +                len(self._tuple) == 3)
  1.3589 +
  1.3590 +    def args(self):
  1.3591 +        assert(self.hasArgs())
  1.3592 +        # Our args are our last element
  1.3593 +        return self._tuple[-1]
  1.3594 +
  1.3595 +    def listValue(self):
  1.3596 +        """
  1.3597 +        Backdoor for storing random data in _extendedAttrDict
  1.3598 +        """
  1.3599 +        return list(self._tuple)[1:]
  1.3600 +
  1.3601 +# Parser
  1.3602 +
  1.3603 +class Tokenizer(object):
  1.3604 +    tokens = [
  1.3605 +        "INTEGER",
  1.3606 +        "FLOATLITERAL",
  1.3607 +        "IDENTIFIER",
  1.3608 +        "STRING",
  1.3609 +        "WHITESPACE",
  1.3610 +        "OTHER"
  1.3611 +        ]
  1.3612 +
  1.3613 +    def t_FLOATLITERAL(self, t):
  1.3614 +        r'(-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+|Infinity))|NaN'
  1.3615 +        t.value = float(t.value)
  1.3616 +        return t
  1.3617 +
  1.3618 +    def t_INTEGER(self, t):
  1.3619 +        r'-?(0([0-7]+|[Xx][0-9A-Fa-f]+)?|[1-9][0-9]*)'
  1.3620 +        try:
  1.3621 +            # Can't use int(), because that doesn't handle octal properly.
  1.3622 +            t.value = parseInt(t.value)
  1.3623 +        except:
  1.3624 +            raise WebIDLError("Invalid integer literal",
  1.3625 +                              [Location(lexer=self.lexer,
  1.3626 +                                        lineno=self.lexer.lineno,
  1.3627 +                                        lexpos=self.lexer.lexpos,
  1.3628 +                                        filename=self._filename)])
  1.3629 +        return t
  1.3630 +
  1.3631 +    def t_IDENTIFIER(self, t):
  1.3632 +        r'[A-Z_a-z][0-9A-Z_a-z]*'
  1.3633 +        t.type = self.keywords.get(t.value, 'IDENTIFIER')
  1.3634 +        return t
  1.3635 +
  1.3636 +    def t_STRING(self, t):
  1.3637 +        r'"[^"]*"'
  1.3638 +        t.value = t.value[1:-1]
  1.3639 +        return t
  1.3640 +
  1.3641 +    def t_WHITESPACE(self, t):
  1.3642 +        r'[\t\n\r ]+|[\t\n\r ]*((//[^\n]*|/\*.*?\*/)[\t\n\r ]*)+'
  1.3643 +        pass
  1.3644 +
  1.3645 +    def t_ELLIPSIS(self, t):
  1.3646 +        r'\.\.\.'
  1.3647 +        t.type = self.keywords.get(t.value)
  1.3648 +        return t
  1.3649 +
  1.3650 +    def t_OTHER(self, t):
  1.3651 +        r'[^\t\n\r 0-9A-Z_a-z]'
  1.3652 +        t.type = self.keywords.get(t.value, 'OTHER')
  1.3653 +        return t
  1.3654 +
  1.3655 +    keywords = {
  1.3656 +        "module": "MODULE",
  1.3657 +        "interface": "INTERFACE",
  1.3658 +        "partial": "PARTIAL",
  1.3659 +        "dictionary": "DICTIONARY",
  1.3660 +        "exception": "EXCEPTION",
  1.3661 +        "enum": "ENUM",
  1.3662 +        "callback": "CALLBACK",
  1.3663 +        "typedef": "TYPEDEF",
  1.3664 +        "implements": "IMPLEMENTS",
  1.3665 +        "const": "CONST",
  1.3666 +        "null": "NULL",
  1.3667 +        "true": "TRUE",
  1.3668 +        "false": "FALSE",
  1.3669 +        "serializer": "SERIALIZER",
  1.3670 +        "stringifier": "STRINGIFIER",
  1.3671 +        "jsonifier": "JSONIFIER",
  1.3672 +        "unrestricted": "UNRESTRICTED",
  1.3673 +        "attribute": "ATTRIBUTE",
  1.3674 +        "readonly": "READONLY",
  1.3675 +        "inherit": "INHERIT",
  1.3676 +        "static": "STATIC",
  1.3677 +        "getter": "GETTER",
  1.3678 +        "setter": "SETTER",
  1.3679 +        "creator": "CREATOR",
  1.3680 +        "deleter": "DELETER",
  1.3681 +        "legacycaller": "LEGACYCALLER",
  1.3682 +        "optional": "OPTIONAL",
  1.3683 +        "...": "ELLIPSIS",
  1.3684 +        "::": "SCOPE",
  1.3685 +        "Date": "DATE",
  1.3686 +        "DOMString": "DOMSTRING",
  1.3687 +        "ByteString": "BYTESTRING",
  1.3688 +        "any": "ANY",
  1.3689 +        "boolean": "BOOLEAN",
  1.3690 +        "byte": "BYTE",
  1.3691 +        "double": "DOUBLE",
  1.3692 +        "float": "FLOAT",
  1.3693 +        "long": "LONG",
  1.3694 +        "object": "OBJECT",
  1.3695 +        "octet": "OCTET",
  1.3696 +        "optional": "OPTIONAL",
  1.3697 +        "sequence": "SEQUENCE",
  1.3698 +        "MozMap": "MOZMAP",
  1.3699 +        "short": "SHORT",
  1.3700 +        "unsigned": "UNSIGNED",
  1.3701 +        "void": "VOID",
  1.3702 +        ":": "COLON",
  1.3703 +        ";": "SEMICOLON",
  1.3704 +        "{": "LBRACE",
  1.3705 +        "}": "RBRACE",
  1.3706 +        "(": "LPAREN",
  1.3707 +        ")": "RPAREN",
  1.3708 +        "[": "LBRACKET",
  1.3709 +        "]": "RBRACKET",
  1.3710 +        "?": "QUESTIONMARK",
  1.3711 +        ",": "COMMA",
  1.3712 +        "=": "EQUALS",
  1.3713 +        "<": "LT",
  1.3714 +        ">": "GT",
  1.3715 +        "ArrayBuffer": "ARRAYBUFFER",
  1.3716 +        "or": "OR"
  1.3717 +        }
  1.3718 +
  1.3719 +    tokens.extend(keywords.values())
  1.3720 +
  1.3721 +    def t_error(self, t):
  1.3722 +        raise WebIDLError("Unrecognized Input",
  1.3723 +               [Location(lexer=self.lexer,
  1.3724 +                         lineno=self.lexer.lineno,
  1.3725 +                         lexpos=self.lexer.lexpos,
  1.3726 +                         filename = self.filename)])
  1.3727 +
  1.3728 +    def __init__(self, outputdir, lexer=None):
  1.3729 +        if lexer:
  1.3730 +            self.lexer = lexer
  1.3731 +        else:
  1.3732 +            self.lexer = lex.lex(object=self,
  1.3733 +                                 outputdir=outputdir,
  1.3734 +                                 lextab='webidllex',
  1.3735 +                                 reflags=re.DOTALL)
  1.3736 +
  1.3737 +class Parser(Tokenizer):
  1.3738 +    def getLocation(self, p, i):
  1.3739 +        return Location(self.lexer, p.lineno(i), p.lexpos(i), self._filename)
  1.3740 +
  1.3741 +    def globalScope(self):
  1.3742 +        return self._globalScope
  1.3743 +
  1.3744 +    # The p_Foo functions here must match the WebIDL spec's grammar.
  1.3745 +    # It's acceptable to split things at '|' boundaries.
  1.3746 +    def p_Definitions(self, p):
  1.3747 +        """ 
  1.3748 +            Definitions : ExtendedAttributeList Definition Definitions
  1.3749 +        """
  1.3750 +        if p[2]:
  1.3751 +            p[0] = [p[2]]
  1.3752 +            p[2].addExtendedAttributes(p[1])
  1.3753 +        else:
  1.3754 +            assert not p[1]
  1.3755 +            p[0] = []
  1.3756 +
  1.3757 +        p[0].extend(p[3])
  1.3758 +
  1.3759 +    def p_DefinitionsEmpty(self, p):
  1.3760 +        """
  1.3761 +            Definitions :
  1.3762 +        """
  1.3763 +        p[0] = []
  1.3764 +
  1.3765 +    def p_Definition(self, p):
  1.3766 +        """
  1.3767 +            Definition : CallbackOrInterface
  1.3768 +                       | PartialInterface
  1.3769 +                       | Dictionary
  1.3770 +                       | Exception
  1.3771 +                       | Enum
  1.3772 +                       | Typedef
  1.3773 +                       | ImplementsStatement
  1.3774 +        """
  1.3775 +        p[0] = p[1]
  1.3776 +        assert p[1] # We might not have implemented something ...
  1.3777 +
  1.3778 +    def p_CallbackOrInterfaceCallback(self, p):
  1.3779 +        """
  1.3780 +            CallbackOrInterface : CALLBACK CallbackRestOrInterface
  1.3781 +        """
  1.3782 +        if p[2].isInterface():
  1.3783 +            assert isinstance(p[2], IDLInterface)
  1.3784 +            p[2].setCallback(True)
  1.3785 +
  1.3786 +        p[0] = p[2]
  1.3787 +
  1.3788 +    def p_CallbackOrInterfaceInterface(self, p):
  1.3789 +        """
  1.3790 +            CallbackOrInterface : Interface
  1.3791 +        """
  1.3792 +        p[0] = p[1]
  1.3793 +
  1.3794 +    def p_CallbackRestOrInterface(self, p):
  1.3795 +        """
  1.3796 +            CallbackRestOrInterface : CallbackRest
  1.3797 +                                    | Interface
  1.3798 +        """
  1.3799 +        assert p[1]
  1.3800 +        p[0] = p[1]
  1.3801 +
  1.3802 +    def p_Interface(self, p):
  1.3803 +        """
  1.3804 +            Interface : INTERFACE IDENTIFIER Inheritance LBRACE InterfaceMembers RBRACE SEMICOLON
  1.3805 +        """
  1.3806 +        location = self.getLocation(p, 1)
  1.3807 +        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
  1.3808 +        members = p[5]
  1.3809 +        parent = p[3]
  1.3810 +
  1.3811 +        try:
  1.3812 +            if self.globalScope()._lookupIdentifier(identifier):
  1.3813 +                p[0] = self.globalScope()._lookupIdentifier(identifier)
  1.3814 +                if not isinstance(p[0], IDLInterface):
  1.3815 +                    raise WebIDLError("Partial interface has the same name as "
  1.3816 +                                      "non-interface object",
  1.3817 +                                      [location, p[0].location])
  1.3818 +                p[0].setNonPartial(location, parent, members)
  1.3819 +                return
  1.3820 +        except Exception, ex:
  1.3821 +            if isinstance(ex, WebIDLError):
  1.3822 +                raise ex
  1.3823 +            pass
  1.3824 +
  1.3825 +        p[0] = IDLInterface(location, self.globalScope(), identifier, parent,
  1.3826 +                            members, isPartial=False)
  1.3827 +
  1.3828 +    def p_InterfaceForwardDecl(self, p):
  1.3829 +        """
  1.3830 +            Interface : INTERFACE IDENTIFIER SEMICOLON
  1.3831 +        """
  1.3832 +        location = self.getLocation(p, 1)
  1.3833 +        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
  1.3834 +
  1.3835 +        try:
  1.3836 +            if self.globalScope()._lookupIdentifier(identifier):
  1.3837 +                p[0] = self.globalScope()._lookupIdentifier(identifier)
  1.3838 +                if not isinstance(p[0], IDLExternalInterface):
  1.3839 +                    raise WebIDLError("Name collision between external "
  1.3840 +                                      "interface declaration for identifier "
  1.3841 +                                      "%s and %s" % (identifier.name, p[0]),
  1.3842 +                                      [location, p[0].location])
  1.3843 +                return
  1.3844 +        except Exception, ex:
  1.3845 +            if isinstance(ex, WebIDLError):
  1.3846 +                raise ex
  1.3847 +            pass
  1.3848 +
  1.3849 +        p[0] = IDLExternalInterface(location, self.globalScope(), identifier)
  1.3850 +
  1.3851 +    def p_PartialInterface(self, p):
  1.3852 +        """
  1.3853 +            PartialInterface : PARTIAL INTERFACE IDENTIFIER LBRACE InterfaceMembers RBRACE SEMICOLON
  1.3854 +        """
  1.3855 +        location = self.getLocation(p, 2)
  1.3856 +        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3])
  1.3857 +        members = p[5]
  1.3858 +
  1.3859 +        try:
  1.3860 +            if self.globalScope()._lookupIdentifier(identifier):
  1.3861 +                p[0] = self.globalScope()._lookupIdentifier(identifier)
  1.3862 +                if not isinstance(p[0], IDLInterface):
  1.3863 +                    raise WebIDLError("Partial interface has the same name as "
  1.3864 +                                      "non-interface object",
  1.3865 +                                      [location, p[0].location])
  1.3866 +                # Just throw our members into the existing IDLInterface.  If we
  1.3867 +                # have extended attributes, those will get added to it
  1.3868 +                # automatically.
  1.3869 +                p[0].members.extend(members)
  1.3870 +                return
  1.3871 +        except Exception, ex:
  1.3872 +            if isinstance(ex, WebIDLError):
  1.3873 +                raise ex
  1.3874 +            pass
  1.3875 +
  1.3876 +        p[0] = IDLInterface(location, self.globalScope(), identifier, None,
  1.3877 +                            members, isPartial=True)
  1.3878 +        pass
  1.3879 +
  1.3880 +    def p_Inheritance(self, p):
  1.3881 +        """
  1.3882 +            Inheritance : COLON ScopedName
  1.3883 +        """
  1.3884 +        p[0] = IDLIdentifierPlaceholder(self.getLocation(p, 2), p[2])
  1.3885 +
  1.3886 +    def p_InheritanceEmpty(self, p):
  1.3887 +        """
  1.3888 +            Inheritance :
  1.3889 +        """
  1.3890 +        pass
  1.3891 +
  1.3892 +    def p_InterfaceMembers(self, p):
  1.3893 +        """
  1.3894 +            InterfaceMembers : ExtendedAttributeList InterfaceMember InterfaceMembers
  1.3895 +        """
  1.3896 +        p[0] = [p[2]] if p[2] else []
  1.3897 +
  1.3898 +        assert not p[1] or p[2]
  1.3899 +        p[2].addExtendedAttributes(p[1])
  1.3900 +
  1.3901 +        p[0].extend(p[3])
  1.3902 +
  1.3903 +    def p_InterfaceMembersEmpty(self, p):
  1.3904 +        """
  1.3905 +            InterfaceMembers :
  1.3906 +        """
  1.3907 +        p[0] = []
  1.3908 +
  1.3909 +    def p_InterfaceMember(self, p):
  1.3910 +        """
  1.3911 +            InterfaceMember : Const
  1.3912 +                            | AttributeOrOperation
  1.3913 +        """
  1.3914 +        p[0] = p[1]
  1.3915 +
  1.3916 +    def p_Dictionary(self, p):
  1.3917 +        """
  1.3918 +            Dictionary : DICTIONARY IDENTIFIER Inheritance LBRACE DictionaryMembers RBRACE SEMICOLON
  1.3919 +        """
  1.3920 +        location = self.getLocation(p, 1)
  1.3921 +        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
  1.3922 +        members = p[5]
  1.3923 +        p[0] = IDLDictionary(location, self.globalScope(), identifier, p[3], members)
  1.3924 +
  1.3925 +    def p_DictionaryMembers(self, p):
  1.3926 +        """
  1.3927 +            DictionaryMembers : ExtendedAttributeList DictionaryMember DictionaryMembers
  1.3928 +                             |
  1.3929 +        """
  1.3930 +        if len(p) == 1:
  1.3931 +            # We're at the end of the list
  1.3932 +            p[0] = []
  1.3933 +            return
  1.3934 +        # Add our extended attributes
  1.3935 +        p[2].addExtendedAttributes(p[1])
  1.3936 +        p[0] = [p[2]]
  1.3937 +        p[0].extend(p[3])
  1.3938 +
  1.3939 +    def p_DictionaryMember(self, p):
  1.3940 +        """
  1.3941 +            DictionaryMember : Type IDENTIFIER DefaultValue SEMICOLON
  1.3942 +        """
  1.3943 +        # These quack a lot like optional arguments, so just treat them that way.
  1.3944 +        t = p[1]
  1.3945 +        assert isinstance(t, IDLType)
  1.3946 +        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
  1.3947 +        defaultValue = p[3]
  1.3948 +
  1.3949 +        p[0] = IDLArgument(self.getLocation(p, 2), identifier, t, optional=True,
  1.3950 +                           defaultValue=defaultValue, variadic=False,
  1.3951 +                           dictionaryMember=True)
  1.3952 +
  1.3953 +    def p_DefaultValue(self, p):
  1.3954 +        """
  1.3955 +            DefaultValue : EQUALS ConstValue
  1.3956 +                         |
  1.3957 +        """
  1.3958 +        if len(p) > 1:
  1.3959 +            p[0] = p[2]
  1.3960 +        else:
  1.3961 +            p[0] = None
  1.3962 +
  1.3963 +    def p_Exception(self, p):
  1.3964 +        """
  1.3965 +            Exception : EXCEPTION IDENTIFIER Inheritance LBRACE ExceptionMembers RBRACE SEMICOLON
  1.3966 +        """
  1.3967 +        pass
  1.3968 +
  1.3969 +    def p_Enum(self, p):
  1.3970 +        """
  1.3971 +            Enum : ENUM IDENTIFIER LBRACE EnumValueList RBRACE SEMICOLON
  1.3972 +        """
  1.3973 +        location = self.getLocation(p, 1)
  1.3974 +        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
  1.3975 +
  1.3976 +        values = p[4]
  1.3977 +        assert values
  1.3978 +        p[0] = IDLEnum(location, self.globalScope(), identifier, values)
  1.3979 +
  1.3980 +    def p_EnumValueList(self, p):
  1.3981 +        """
  1.3982 +            EnumValueList : STRING EnumValueListComma
  1.3983 +        """
  1.3984 +        p[0] = [p[1]]
  1.3985 +        p[0].extend(p[2])
  1.3986 +
  1.3987 +    def p_EnumValueListComma(self, p):
  1.3988 +        """
  1.3989 +            EnumValueListComma : COMMA EnumValueListString
  1.3990 +        """
  1.3991 +        p[0] = p[2]
  1.3992 +
  1.3993 +    def p_EnumValueListCommaEmpty(self, p):
  1.3994 +        """
  1.3995 +            EnumValueListComma :
  1.3996 +        """
  1.3997 +        p[0] = []
  1.3998 +
  1.3999 +    def p_EnumValueListString(self, p):
  1.4000 +        """
  1.4001 +            EnumValueListString : STRING EnumValueListComma
  1.4002 +        """
  1.4003 +        p[0] = [p[1]]
  1.4004 +        p[0].extend(p[2])
  1.4005 +
  1.4006 +    def p_EnumValueListStringEmpty(self, p):
  1.4007 +        """
  1.4008 +            EnumValueListString :
  1.4009 +        """
  1.4010 +        p[0] = []
  1.4011 +
  1.4012 +    def p_CallbackRest(self, p):
  1.4013 +        """
  1.4014 +            CallbackRest : IDENTIFIER EQUALS ReturnType LPAREN ArgumentList RPAREN SEMICOLON
  1.4015 +        """
  1.4016 +        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1])
  1.4017 +        p[0] = IDLCallbackType(self.getLocation(p, 1), self.globalScope(),
  1.4018 +                               identifier, p[3], p[5])
  1.4019 +
  1.4020 +    def p_ExceptionMembers(self, p):
  1.4021 +        """
  1.4022 +            ExceptionMembers : ExtendedAttributeList ExceptionMember ExceptionMembers
  1.4023 +                             |
  1.4024 +        """
  1.4025 +        pass
  1.4026 +
  1.4027 +    def p_Typedef(self, p):
  1.4028 +        """
  1.4029 +            Typedef : TYPEDEF Type IDENTIFIER SEMICOLON
  1.4030 +        """
  1.4031 +        typedef = IDLTypedefType(self.getLocation(p, 1), p[2], p[3])
  1.4032 +        typedef.resolve(self.globalScope())
  1.4033 +        p[0] = typedef
  1.4034 +
  1.4035 +    def p_ImplementsStatement(self, p):
  1.4036 +        """
  1.4037 +            ImplementsStatement : ScopedName IMPLEMENTS ScopedName SEMICOLON
  1.4038 +        """
  1.4039 +        assert(p[2] == "implements")
  1.4040 +        implementor = IDLIdentifierPlaceholder(self.getLocation(p, 1), p[1])
  1.4041 +        implementee = IDLIdentifierPlaceholder(self.getLocation(p, 3), p[3])
  1.4042 +        p[0] = IDLImplementsStatement(self.getLocation(p, 1), implementor,
  1.4043 +                                      implementee)
  1.4044 +
  1.4045 +    def p_Const(self, p):
  1.4046 +        """
  1.4047 +            Const : CONST ConstType IDENTIFIER EQUALS ConstValue SEMICOLON
  1.4048 +        """
  1.4049 +        location = self.getLocation(p, 1)
  1.4050 +        type = p[2]
  1.4051 +        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3])
  1.4052 +        value = p[5]
  1.4053 +        p[0] = IDLConst(location, identifier, type, value)
  1.4054 +
  1.4055 +    def p_ConstValueBoolean(self, p):
  1.4056 +        """
  1.4057 +            ConstValue : BooleanLiteral
  1.4058 +        """
  1.4059 +        location = self.getLocation(p, 1)
  1.4060 +        booleanType = BuiltinTypes[IDLBuiltinType.Types.boolean]
  1.4061 +        p[0] = IDLValue(location, booleanType, p[1])
  1.4062 +
  1.4063 +    def p_ConstValueInteger(self, p):
  1.4064 +        """
  1.4065 +            ConstValue : INTEGER
  1.4066 +        """
  1.4067 +        location = self.getLocation(p, 1)
  1.4068 +
  1.4069 +        # We don't know ahead of time what type the integer literal is.
  1.4070 +        # Determine the smallest type it could possibly fit in and use that.
  1.4071 +        integerType = matchIntegerValueToType(p[1])
  1.4072 +        if integerType == None:
  1.4073 +            raise WebIDLError("Integer literal out of range", [location])
  1.4074 +
  1.4075 +        p[0] = IDLValue(location, integerType, p[1])
  1.4076 +
  1.4077 +    def p_ConstValueFloat(self, p):
  1.4078 +        """
  1.4079 +            ConstValue : FLOATLITERAL
  1.4080 +        """
  1.4081 +        location = self.getLocation(p, 1)
  1.4082 +        p[0] = IDLValue(location, BuiltinTypes[IDLBuiltinType.Types.unrestricted_float], p[1])
  1.4083 +
  1.4084 +    def p_ConstValueString(self, p):
  1.4085 +        """
  1.4086 +            ConstValue : STRING
  1.4087 +        """
  1.4088 +        location = self.getLocation(p, 1)
  1.4089 +        stringType = BuiltinTypes[IDLBuiltinType.Types.domstring]
  1.4090 +        p[0] = IDLValue(location, stringType, p[1])
  1.4091 +
  1.4092 +    def p_ConstValueNull(self, p):
  1.4093 +        """
  1.4094 +            ConstValue : NULL
  1.4095 +        """
  1.4096 +        p[0] = IDLNullValue(self.getLocation(p, 1))
  1.4097 +
  1.4098 +    def p_BooleanLiteralTrue(self, p):
  1.4099 +        """
  1.4100 +            BooleanLiteral : TRUE
  1.4101 +        """
  1.4102 +        p[0] = True
  1.4103 +
  1.4104 +    def p_BooleanLiteralFalse(self, p):
  1.4105 +        """
  1.4106 +            BooleanLiteral : FALSE
  1.4107 +        """
  1.4108 +        p[0] = False
  1.4109 +
  1.4110 +    def p_AttributeOrOperation(self, p):
  1.4111 +        """
  1.4112 +            AttributeOrOperation : Attribute
  1.4113 +                                 | Operation
  1.4114 +        """
  1.4115 +        p[0] = p[1]
  1.4116 +
  1.4117 +    def p_AttributeWithQualifier(self, p):
  1.4118 +        """
  1.4119 +            Attribute : Qualifier AttributeRest
  1.4120 +        """
  1.4121 +        static = IDLInterfaceMember.Special.Static in p[1]
  1.4122 +        stringifier = IDLInterfaceMember.Special.Stringifier in p[1]
  1.4123 +        (location, identifier, type, readonly) = p[2]
  1.4124 +        p[0] = IDLAttribute(location, identifier, type, readonly, static=static,
  1.4125 +                            stringifier=stringifier)
  1.4126 +
  1.4127 +    def p_Attribute(self, p):
  1.4128 +        """
  1.4129 +            Attribute : Inherit AttributeRest
  1.4130 +        """
  1.4131 +        (location, identifier, type, readonly) = p[2]
  1.4132 +        p[0] = IDLAttribute(location, identifier, type, readonly, inherit=p[1])
  1.4133 +
  1.4134 +    def p_AttributeRest(self, p):
  1.4135 +        """
  1.4136 +            AttributeRest : ReadOnly ATTRIBUTE Type IDENTIFIER SEMICOLON
  1.4137 +        """
  1.4138 +        location = self.getLocation(p, 2)
  1.4139 +        readonly = p[1]
  1.4140 +        t = p[3]
  1.4141 +        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 4), p[4])
  1.4142 +        p[0] = (location, identifier, t, readonly)
  1.4143 +
  1.4144 +    def p_ReadOnly(self, p):
  1.4145 +        """
  1.4146 +            ReadOnly : READONLY
  1.4147 +        """
  1.4148 +        p[0] = True
  1.4149 +
  1.4150 +    def p_ReadOnlyEmpty(self, p):
  1.4151 +        """
  1.4152 +            ReadOnly :
  1.4153 +        """
  1.4154 +        p[0] = False
  1.4155 +
  1.4156 +    def p_Inherit(self, p):
  1.4157 +        """
  1.4158 +            Inherit : INHERIT
  1.4159 +        """
  1.4160 +        p[0] = True
  1.4161 +
  1.4162 +    def p_InheritEmpty(self, p):
  1.4163 +        """
  1.4164 +            Inherit :
  1.4165 +        """
  1.4166 +        p[0] = False
  1.4167 +
  1.4168 +    def p_Operation(self, p):
  1.4169 +        """
  1.4170 +            Operation : Qualifiers OperationRest
  1.4171 +        """
  1.4172 +        qualifiers = p[1]
  1.4173 +
  1.4174 +        # Disallow duplicates in the qualifier set
  1.4175 +        if not len(set(qualifiers)) == len(qualifiers):
  1.4176 +            raise WebIDLError("Duplicate qualifiers are not allowed",
  1.4177 +                              [self.getLocation(p, 1)])
  1.4178 +
  1.4179 +        static = IDLInterfaceMember.Special.Static in p[1]
  1.4180 +        # If static is there that's all that's allowed.  This is disallowed
  1.4181 +        # by the parser, so we can assert here.
  1.4182 +        assert not static or len(qualifiers) == 1
  1.4183 +
  1.4184 +        stringifier = IDLInterfaceMember.Special.Stringifier in p[1]
  1.4185 +        # If stringifier is there that's all that's allowed.  This is disallowed
  1.4186 +        # by the parser, so we can assert here.
  1.4187 +        assert not stringifier or len(qualifiers) == 1
  1.4188 +
  1.4189 +        getter = True if IDLMethod.Special.Getter in p[1] else False
  1.4190 +        setter = True if IDLMethod.Special.Setter in p[1] else False
  1.4191 +        creator = True if IDLMethod.Special.Creator in p[1] else False
  1.4192 +        deleter = True if IDLMethod.Special.Deleter in p[1] else False
  1.4193 +        legacycaller = True if IDLMethod.Special.LegacyCaller in p[1] else False
  1.4194 +
  1.4195 +        if getter or deleter:
  1.4196 +            if setter or creator:
  1.4197 +                raise WebIDLError("getter and deleter are incompatible with setter and creator",
  1.4198 +                                  [self.getLocation(p, 1)])
  1.4199 +
  1.4200 +        (returnType, identifier, arguments) = p[2]
  1.4201 +
  1.4202 +        assert isinstance(returnType, IDLType)
  1.4203 +
  1.4204 +        specialType = IDLMethod.NamedOrIndexed.Neither
  1.4205 +
  1.4206 +        if getter or deleter:
  1.4207 +            if len(arguments) != 1:
  1.4208 +                raise WebIDLError("%s has wrong number of arguments" %
  1.4209 +                                  ("getter" if getter else "deleter"),
  1.4210 +                                  [self.getLocation(p, 2)])
  1.4211 +            argType = arguments[0].type
  1.4212 +            if argType == BuiltinTypes[IDLBuiltinType.Types.domstring]:
  1.4213 +                specialType = IDLMethod.NamedOrIndexed.Named
  1.4214 +            elif argType == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]:
  1.4215 +                specialType = IDLMethod.NamedOrIndexed.Indexed
  1.4216 +            else:
  1.4217 +                raise WebIDLError("%s has wrong argument type (must be DOMString or UnsignedLong)" %
  1.4218 +                                  ("getter" if getter else "deleter"),
  1.4219 +                                  [arguments[0].location])
  1.4220 +            if arguments[0].optional or arguments[0].variadic:
  1.4221 +                raise WebIDLError("%s cannot have %s argument" %
  1.4222 +                                  ("getter" if getter else "deleter",
  1.4223 +                                   "optional" if arguments[0].optional else "variadic"),
  1.4224 +                                   [arguments[0].location])
  1.4225 +        if getter:
  1.4226 +            if returnType.isVoid():
  1.4227 +                raise WebIDLError("getter cannot have void return type",
  1.4228 +                                  [self.getLocation(p, 2)])
  1.4229 +        if setter or creator:
  1.4230 +            if len(arguments) != 2:
  1.4231 +                raise WebIDLError("%s has wrong number of arguments" %
  1.4232 +                                  ("setter" if setter else "creator"),
  1.4233 +                                  [self.getLocation(p, 2)])
  1.4234 +            argType = arguments[0].type
  1.4235 +            if argType == BuiltinTypes[IDLBuiltinType.Types.domstring]:
  1.4236 +                specialType = IDLMethod.NamedOrIndexed.Named
  1.4237 +            elif argType == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]:
  1.4238 +                specialType = IDLMethod.NamedOrIndexed.Indexed
  1.4239 +            else:
  1.4240 +                raise WebIDLError("%s has wrong argument type (must be DOMString or UnsignedLong)" %
  1.4241 +                                  ("setter" if setter else "creator"),
  1.4242 +                                  [arguments[0].location])
  1.4243 +            if arguments[0].optional or arguments[0].variadic:
  1.4244 +                raise WebIDLError("%s cannot have %s argument" %
  1.4245 +                                  ("setter" if setter else "creator",
  1.4246 +                                   "optional" if arguments[0].optional else "variadic"),
  1.4247 +                                  [arguments[0].location])
  1.4248 +            if arguments[1].optional or arguments[1].variadic:
  1.4249 +                raise WebIDLError("%s cannot have %s argument" %
  1.4250 +                                  ("setter" if setter else "creator",
  1.4251 +                                   "optional" if arguments[1].optional else "variadic"),
  1.4252 +                                  [arguments[1].location])
  1.4253 +
  1.4254 +        if stringifier:
  1.4255 +            if len(arguments) != 0:
  1.4256 +                raise WebIDLError("stringifier has wrong number of arguments",
  1.4257 +                                  [self.getLocation(p, 2)])
  1.4258 +            if not returnType.isDOMString():
  1.4259 +                raise WebIDLError("stringifier must have DOMString return type",
  1.4260 +                                  [self.getLocation(p, 2)])
  1.4261 +
  1.4262 +        # identifier might be None.  This is only permitted for special methods.
  1.4263 +        if not identifier:
  1.4264 +            if not getter and not setter and not creator and \
  1.4265 +               not deleter and not legacycaller and not stringifier:
  1.4266 +                raise WebIDLError("Identifier required for non-special methods",
  1.4267 +                                  [self.getLocation(p, 2)])
  1.4268 +
  1.4269 +            location = BuiltinLocation("<auto-generated-identifier>")
  1.4270 +            identifier = IDLUnresolvedIdentifier(location, "__%s%s%s%s%s%s%s" %
  1.4271 +                ("named" if specialType == IDLMethod.NamedOrIndexed.Named else \
  1.4272 +                 "indexed" if specialType == IDLMethod.NamedOrIndexed.Indexed else "",
  1.4273 +                 "getter" if getter else "",
  1.4274 +                 "setter" if setter else "",
  1.4275 +                 "deleter" if deleter else "",
  1.4276 +                 "creator" if creator else "",
  1.4277 +                 "legacycaller" if legacycaller else "",
  1.4278 +                 "stringifier" if stringifier else ""), allowDoubleUnderscore=True)
  1.4279 +
  1.4280 +        method = IDLMethod(self.getLocation(p, 2), identifier, returnType, arguments,
  1.4281 +                           static=static, getter=getter, setter=setter, creator=creator,
  1.4282 +                           deleter=deleter, specialType=specialType,
  1.4283 +                           legacycaller=legacycaller, stringifier=stringifier)
  1.4284 +        p[0] = method
  1.4285 +
  1.4286 +    def p_Stringifier(self, p):
  1.4287 +        """
  1.4288 +            Operation : STRINGIFIER SEMICOLON
  1.4289 +        """
  1.4290 +        identifier = IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
  1.4291 +                                             "__stringifier",
  1.4292 +                                             allowDoubleUnderscore=True)
  1.4293 +        method = IDLMethod(self.getLocation(p, 1),
  1.4294 +                           identifier,
  1.4295 +                           returnType=BuiltinTypes[IDLBuiltinType.Types.domstring],
  1.4296 +                           arguments=[],
  1.4297 +                           stringifier=True)
  1.4298 +        p[0] = method
  1.4299 +
  1.4300 +    def p_Jsonifier(self, p):
  1.4301 +        """
  1.4302 +            Operation : JSONIFIER SEMICOLON
  1.4303 +        """
  1.4304 +        identifier = IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
  1.4305 +                                             "__jsonifier", allowDoubleUnderscore=True)
  1.4306 +        method = IDLMethod(self.getLocation(p, 1),
  1.4307 +                           identifier,
  1.4308 +                           returnType=BuiltinTypes[IDLBuiltinType.Types.object],
  1.4309 +                           arguments=[],
  1.4310 +                           jsonifier=True)
  1.4311 +        p[0] = method
  1.4312 +
  1.4313 +    def p_QualifierStatic(self, p):
  1.4314 +        """
  1.4315 +            Qualifier : STATIC
  1.4316 +        """
  1.4317 +        p[0] = [IDLInterfaceMember.Special.Static]
  1.4318 +
  1.4319 +    def p_QualifierStringifier(self, p):
  1.4320 +        """
  1.4321 +            Qualifier : STRINGIFIER
  1.4322 +        """
  1.4323 +        p[0] = [IDLInterfaceMember.Special.Stringifier]
  1.4324 +
  1.4325 +    def p_Qualifiers(self, p):
  1.4326 +        """
  1.4327 +            Qualifiers : Qualifier
  1.4328 +                       | Specials
  1.4329 +        """
  1.4330 +        p[0] = p[1]
  1.4331 +
  1.4332 +    def p_Specials(self, p):
  1.4333 +        """
  1.4334 +            Specials : Special Specials
  1.4335 +        """
  1.4336 +        p[0] = [p[1]]
  1.4337 +        p[0].extend(p[2])
  1.4338 +
  1.4339 +    def p_SpecialsEmpty(self, p):
  1.4340 +        """
  1.4341 +            Specials :
  1.4342 +        """
  1.4343 +        p[0] = []
  1.4344 +
  1.4345 +    def p_SpecialGetter(self, p):
  1.4346 +        """
  1.4347 +            Special : GETTER
  1.4348 +        """
  1.4349 +        p[0] = IDLMethod.Special.Getter
  1.4350 +
  1.4351 +    def p_SpecialSetter(self, p):
  1.4352 +        """
  1.4353 +            Special : SETTER
  1.4354 +        """
  1.4355 +        p[0] = IDLMethod.Special.Setter
  1.4356 +
  1.4357 +    def p_SpecialCreator(self, p):
  1.4358 +        """
  1.4359 +            Special : CREATOR
  1.4360 +        """
  1.4361 +        p[0] = IDLMethod.Special.Creator
  1.4362 +
  1.4363 +    def p_SpecialDeleter(self, p):
  1.4364 +        """
  1.4365 +            Special : DELETER
  1.4366 +        """
  1.4367 +        p[0] = IDLMethod.Special.Deleter
  1.4368 +
  1.4369 +    def p_SpecialLegacyCaller(self, p):
  1.4370 +        """
  1.4371 +            Special : LEGACYCALLER
  1.4372 +        """
  1.4373 +        p[0] = IDLMethod.Special.LegacyCaller
  1.4374 +
  1.4375 +    def p_OperationRest(self, p):
  1.4376 +        """
  1.4377 +            OperationRest : ReturnType OptionalIdentifier LPAREN ArgumentList RPAREN SEMICOLON
  1.4378 +        """
  1.4379 +        p[0] = (p[1], p[2], p[4])
  1.4380 +
  1.4381 +    def p_OptionalIdentifier(self, p):
  1.4382 +        """
  1.4383 +            OptionalIdentifier : IDENTIFIER
  1.4384 +        """
  1.4385 +        p[0] = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1])
  1.4386 +
  1.4387 +    def p_OptionalIdentifierEmpty(self, p):
  1.4388 +        """
  1.4389 +            OptionalIdentifier :
  1.4390 +        """
  1.4391 +        pass
  1.4392 +
  1.4393 +    def p_ArgumentList(self, p):
  1.4394 +        """
  1.4395 +            ArgumentList : Argument Arguments
  1.4396 +        """
  1.4397 +        p[0] = [p[1]] if p[1] else []
  1.4398 +        p[0].extend(p[2])
  1.4399 +
  1.4400 +    def p_ArgumentListEmpty(self, p):
  1.4401 +        """
  1.4402 +            ArgumentList :
  1.4403 +        """
  1.4404 +        p[0] = []
  1.4405 +
  1.4406 +    def p_Arguments(self, p):
  1.4407 +        """
  1.4408 +            Arguments : COMMA Argument Arguments
  1.4409 +        """
  1.4410 +        p[0] = [p[2]] if p[2] else []
  1.4411 +        p[0].extend(p[3])
  1.4412 +
  1.4413 +    def p_ArgumentsEmpty(self, p):
  1.4414 +        """
  1.4415 +            Arguments :
  1.4416 +        """
  1.4417 +        p[0] = []
  1.4418 +
  1.4419 +    def p_Argument(self, p):
  1.4420 +        """
  1.4421 +            Argument : ExtendedAttributeList Optional Type Ellipsis ArgumentName DefaultValue
  1.4422 +        """
  1.4423 +        t = p[3]
  1.4424 +        assert isinstance(t, IDLType)
  1.4425 +        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 5), p[5])
  1.4426 +
  1.4427 +        optional = p[2]
  1.4428 +        variadic = p[4]
  1.4429 +        defaultValue = p[6]
  1.4430 +
  1.4431 +        if not optional and defaultValue:
  1.4432 +            raise WebIDLError("Mandatory arguments can't have a default value.",
  1.4433 +                              [self.getLocation(p, 6)])
  1.4434 +
  1.4435 +        # We can't test t.isAny() here and give it a default value as needed,
  1.4436 +        # since at this point t is not a fully resolved type yet (e.g. it might
  1.4437 +        # be a typedef).  We'll handle the 'any' case in IDLArgument.complete.
  1.4438 +
  1.4439 +        if variadic:
  1.4440 +            if optional:
  1.4441 +                raise WebIDLError("Variadic arguments should not be marked optional.",
  1.4442 +                                  [self.getLocation(p, 2)])
  1.4443 +            optional = variadic
  1.4444 +
  1.4445 +        p[0] = IDLArgument(self.getLocation(p, 5), identifier, t, optional, defaultValue, variadic)
  1.4446 +        p[0].addExtendedAttributes(p[1])
  1.4447 +
  1.4448 +    def p_ArgumentName(self, p):
  1.4449 +        """
  1.4450 +            ArgumentName : IDENTIFIER
  1.4451 +                         | ATTRIBUTE
  1.4452 +                         | CALLBACK
  1.4453 +                         | CONST
  1.4454 +                         | CREATOR
  1.4455 +                         | DELETER
  1.4456 +                         | DICTIONARY
  1.4457 +                         | ENUM
  1.4458 +                         | EXCEPTION
  1.4459 +                         | GETTER
  1.4460 +                         | IMPLEMENTS
  1.4461 +                         | INHERIT
  1.4462 +                         | INTERFACE
  1.4463 +                         | LEGACYCALLER
  1.4464 +                         | PARTIAL
  1.4465 +                         | SERIALIZER
  1.4466 +                         | SETTER
  1.4467 +                         | STATIC
  1.4468 +                         | STRINGIFIER
  1.4469 +                         | JSONIFIER
  1.4470 +                         | TYPEDEF
  1.4471 +                         | UNRESTRICTED
  1.4472 +        """
  1.4473 +        p[0] = p[1]
  1.4474 +
  1.4475 +    def p_Optional(self, p):
  1.4476 +        """
  1.4477 +            Optional : OPTIONAL
  1.4478 +        """
  1.4479 +        p[0] = True
  1.4480 +
  1.4481 +    def p_OptionalEmpty(self, p):
  1.4482 +        """
  1.4483 +            Optional :
  1.4484 +        """
  1.4485 +        p[0] = False
  1.4486 +
  1.4487 +    def p_Ellipsis(self, p):
  1.4488 +        """
  1.4489 +            Ellipsis : ELLIPSIS
  1.4490 +        """
  1.4491 +        p[0] = True
  1.4492 +
  1.4493 +    def p_EllipsisEmpty(self, p):
  1.4494 +        """
  1.4495 +            Ellipsis :
  1.4496 +        """
  1.4497 +        p[0] = False
  1.4498 +
  1.4499 +    def p_ExceptionMember(self, p):
  1.4500 +        """
  1.4501 +            ExceptionMember : Const
  1.4502 +                            | ExceptionField
  1.4503 +        """
  1.4504 +        pass
  1.4505 +
  1.4506 +    def p_ExceptionField(self, p):
  1.4507 +        """
  1.4508 +            ExceptionField : Type IDENTIFIER SEMICOLON
  1.4509 +        """
  1.4510 +        pass
  1.4511 +
  1.4512 +    def p_ExtendedAttributeList(self, p):
  1.4513 +        """
  1.4514 +            ExtendedAttributeList : LBRACKET ExtendedAttribute ExtendedAttributes RBRACKET
  1.4515 +        """
  1.4516 +        p[0] = [p[2]]
  1.4517 +        if p[3]:
  1.4518 +            p[0].extend(p[3])
  1.4519 +
  1.4520 +    def p_ExtendedAttributeListEmpty(self, p):
  1.4521 +        """
  1.4522 +            ExtendedAttributeList :
  1.4523 +        """
  1.4524 +        p[0] = []
  1.4525 +
  1.4526 +    def p_ExtendedAttribute(self, p):
  1.4527 +        """
  1.4528 +            ExtendedAttribute : ExtendedAttributeNoArgs
  1.4529 +                              | ExtendedAttributeArgList
  1.4530 +                              | ExtendedAttributeIdent
  1.4531 +                              | ExtendedAttributeNamedArgList
  1.4532 +        """
  1.4533 +        p[0] = IDLExtendedAttribute(self.getLocation(p, 1), p[1])
  1.4534 +
  1.4535 +    def p_ExtendedAttributeEmpty(self, p):
  1.4536 +        """
  1.4537 +            ExtendedAttribute :
  1.4538 +        """
  1.4539 +        pass
  1.4540 +
  1.4541 +    def p_ExtendedAttributes(self, p):
  1.4542 +        """
  1.4543 +            ExtendedAttributes : COMMA ExtendedAttribute ExtendedAttributes
  1.4544 +        """
  1.4545 +        p[0] = [p[2]] if p[2] else []
  1.4546 +        p[0].extend(p[3])
  1.4547 +
  1.4548 +    def p_ExtendedAttributesEmpty(self, p):
  1.4549 +        """
  1.4550 +            ExtendedAttributes :
  1.4551 +        """
  1.4552 +        p[0] = []
  1.4553 +
  1.4554 +    def p_Other(self, p):
  1.4555 +        """
  1.4556 +            Other : INTEGER
  1.4557 +                  | FLOATLITERAL
  1.4558 +                  | IDENTIFIER
  1.4559 +                  | STRING
  1.4560 +                  | OTHER
  1.4561 +                  | ELLIPSIS
  1.4562 +                  | COLON
  1.4563 +                  | SCOPE
  1.4564 +                  | SEMICOLON
  1.4565 +                  | LT
  1.4566 +                  | EQUALS
  1.4567 +                  | GT
  1.4568 +                  | QUESTIONMARK
  1.4569 +                  | DATE
  1.4570 +                  | DOMSTRING
  1.4571 +                  | BYTESTRING
  1.4572 +                  | ANY
  1.4573 +                  | ATTRIBUTE
  1.4574 +                  | BOOLEAN
  1.4575 +                  | BYTE
  1.4576 +                  | LEGACYCALLER
  1.4577 +                  | CONST
  1.4578 +                  | CREATOR
  1.4579 +                  | DELETER
  1.4580 +                  | DOUBLE
  1.4581 +                  | EXCEPTION
  1.4582 +                  | FALSE
  1.4583 +                  | FLOAT
  1.4584 +                  | GETTER
  1.4585 +                  | IMPLEMENTS
  1.4586 +                  | INHERIT
  1.4587 +                  | INTERFACE
  1.4588 +                  | LONG
  1.4589 +                  | MODULE
  1.4590 +                  | NULL
  1.4591 +                  | OBJECT
  1.4592 +                  | OCTET
  1.4593 +                  | OPTIONAL
  1.4594 +                  | SEQUENCE
  1.4595 +                  | MOZMAP
  1.4596 +                  | SETTER
  1.4597 +                  | SHORT
  1.4598 +                  | STATIC
  1.4599 +                  | STRINGIFIER
  1.4600 +                  | JSONIFIER
  1.4601 +                  | TRUE
  1.4602 +                  | TYPEDEF
  1.4603 +                  | UNSIGNED
  1.4604 +                  | VOID
  1.4605 +        """
  1.4606 +        pass
  1.4607 +
  1.4608 +    def p_OtherOrComma(self, p):
  1.4609 +        """
  1.4610 +            OtherOrComma : Other
  1.4611 +                         | COMMA
  1.4612 +        """
  1.4613 +        pass
  1.4614 +
  1.4615 +    def p_TypeSingleType(self, p):
  1.4616 +        """
  1.4617 +            Type : SingleType
  1.4618 +        """
  1.4619 +        p[0] = p[1]
  1.4620 +
  1.4621 +    def p_TypeUnionType(self, p):
  1.4622 +        """
  1.4623 +            Type : UnionType TypeSuffix
  1.4624 +        """
  1.4625 +        p[0] = self.handleModifiers(p[1], p[2])
  1.4626 +
  1.4627 +    def p_SingleTypeNonAnyType(self, p):
  1.4628 +        """
  1.4629 +            SingleType : NonAnyType
  1.4630 +        """
  1.4631 +        p[0] = p[1]
  1.4632 +
  1.4633 +    def p_SingleTypeAnyType(self, p):
  1.4634 +        """
  1.4635 +            SingleType : ANY TypeSuffixStartingWithArray
  1.4636 +        """
  1.4637 +        p[0] = self.handleModifiers(BuiltinTypes[IDLBuiltinType.Types.any], p[2])
  1.4638 +
  1.4639 +    def p_UnionType(self, p):
  1.4640 +        """
  1.4641 +            UnionType : LPAREN UnionMemberType OR UnionMemberType UnionMemberTypes RPAREN
  1.4642 +        """
  1.4643 +        types = [p[2], p[4]]
  1.4644 +        types.extend(p[5])
  1.4645 +        p[0] = IDLUnionType(self.getLocation(p, 1), types)
  1.4646 +
  1.4647 +    def p_UnionMemberTypeNonAnyType(self, p):
  1.4648 +        """
  1.4649 +            UnionMemberType : NonAnyType
  1.4650 +        """
  1.4651 +        p[0] = p[1]
  1.4652 +
  1.4653 +    def p_UnionMemberTypeArrayOfAny(self, p):
  1.4654 +        """
  1.4655 +            UnionMemberTypeArrayOfAny : ANY LBRACKET RBRACKET
  1.4656 +        """
  1.4657 +        p[0] = IDLArrayType(self.getLocation(p, 2),
  1.4658 +                            BuiltinTypes[IDLBuiltinType.Types.any])
  1.4659 +
  1.4660 +    def p_UnionMemberType(self, p):
  1.4661 +        """
  1.4662 +            UnionMemberType : UnionType TypeSuffix
  1.4663 +                            | UnionMemberTypeArrayOfAny TypeSuffix
  1.4664 +        """
  1.4665 +        p[0] = self.handleModifiers(p[1], p[2])
  1.4666 +
  1.4667 +    def p_UnionMemberTypes(self, p):
  1.4668 +        """
  1.4669 +            UnionMemberTypes : OR UnionMemberType UnionMemberTypes
  1.4670 +        """
  1.4671 +        p[0] = [p[2]]
  1.4672 +        p[0].extend(p[3])
  1.4673 +
  1.4674 +    def p_UnionMemberTypesEmpty(self, p):
  1.4675 +        """
  1.4676 +            UnionMemberTypes : 
  1.4677 +        """
  1.4678 +        p[0] = []
  1.4679 +
  1.4680 +    def p_NonAnyType(self, p):
  1.4681 +        """
  1.4682 +            NonAnyType : PrimitiveOrStringType TypeSuffix
  1.4683 +                       | ARRAYBUFFER TypeSuffix
  1.4684 +                       | OBJECT TypeSuffix
  1.4685 +        """
  1.4686 +        if p[1] == "object":
  1.4687 +            type = BuiltinTypes[IDLBuiltinType.Types.object]
  1.4688 +        elif p[1] == "ArrayBuffer":
  1.4689 +            type = BuiltinTypes[IDLBuiltinType.Types.ArrayBuffer]
  1.4690 +        else:
  1.4691 +            type = BuiltinTypes[p[1]]
  1.4692 +
  1.4693 +        p[0] = self.handleModifiers(type, p[2])
  1.4694 +
  1.4695 +    def p_NonAnyTypeSequenceType(self, p):
  1.4696 +        """
  1.4697 +            NonAnyType : SEQUENCE LT Type GT Null
  1.4698 +        """
  1.4699 +        innerType = p[3]
  1.4700 +        type = IDLSequenceType(self.getLocation(p, 1), innerType)
  1.4701 +        if p[5]:
  1.4702 +            type = IDLNullableType(self.getLocation(p, 5), type)
  1.4703 +        p[0] = type
  1.4704 +
  1.4705 +    def p_NonAnyTypeMozMapType(self, p):
  1.4706 +        """
  1.4707 +            NonAnyType : MOZMAP LT Type GT Null
  1.4708 +        """
  1.4709 +        innerType = p[3]
  1.4710 +        type = IDLMozMapType(self.getLocation(p, 1), innerType)
  1.4711 +        if p[5]:
  1.4712 +            type = IDLNullableType(self.getLocation(p, 5), type)
  1.4713 +        p[0] = type
  1.4714 +
  1.4715 +    def p_NonAnyTypeScopedName(self, p):
  1.4716 +        """
  1.4717 +            NonAnyType : ScopedName TypeSuffix
  1.4718 +        """
  1.4719 +        assert isinstance(p[1], IDLUnresolvedIdentifier)
  1.4720 +
  1.4721 +        type = None
  1.4722 +
  1.4723 +        try:
  1.4724 +            if self.globalScope()._lookupIdentifier(p[1]):
  1.4725 +                obj = self.globalScope()._lookupIdentifier(p[1])
  1.4726 +                if obj.isType():
  1.4727 +                    type = obj
  1.4728 +                else:
  1.4729 +                    type = IDLWrapperType(self.getLocation(p, 1), p[1])
  1.4730 +                p[0] = self.handleModifiers(type, p[2])
  1.4731 +                return
  1.4732 +        except:
  1.4733 +            pass
  1.4734 +
  1.4735 +        type = IDLUnresolvedType(self.getLocation(p, 1), p[1])
  1.4736 +        p[0] = self.handleModifiers(type, p[2])
  1.4737 +
  1.4738 +    def p_NonAnyTypeDate(self, p):
  1.4739 +        """
  1.4740 +            NonAnyType : DATE TypeSuffix
  1.4741 +        """
  1.4742 +        p[0] = self.handleModifiers(BuiltinTypes[IDLBuiltinType.Types.date],
  1.4743 +                                    p[2])
  1.4744 +
  1.4745 +    def p_ConstType(self, p):
  1.4746 +        """
  1.4747 +            ConstType : PrimitiveOrStringType Null
  1.4748 +        """
  1.4749 +        type = BuiltinTypes[p[1]]
  1.4750 +        if p[2]:
  1.4751 +            type = IDLNullableType(self.getLocation(p, 1), type)
  1.4752 +        p[0] = type
  1.4753 +
  1.4754 +    def p_ConstTypeIdentifier(self, p):
  1.4755 +        """
  1.4756 +            ConstType : IDENTIFIER Null
  1.4757 +        """
  1.4758 +        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1])
  1.4759 +
  1.4760 +        type = IDLUnresolvedType(self.getLocation(p, 1), identifier)
  1.4761 +        if p[2]:
  1.4762 +            type = IDLNullableType(self.getLocation(p, 1), type)
  1.4763 +        p[0] = type
  1.4764 +
  1.4765 +    def p_PrimitiveOrStringTypeUint(self, p):
  1.4766 +        """
  1.4767 +            PrimitiveOrStringType : UnsignedIntegerType
  1.4768 +        """
  1.4769 +        p[0] = p[1]
  1.4770 +
  1.4771 +    def p_PrimitiveOrStringTypeBoolean(self, p):
  1.4772 +        """
  1.4773 +            PrimitiveOrStringType : BOOLEAN
  1.4774 +        """
  1.4775 +        p[0] = IDLBuiltinType.Types.boolean
  1.4776 +
  1.4777 +    def p_PrimitiveOrStringTypeByte(self, p):
  1.4778 +        """
  1.4779 +            PrimitiveOrStringType : BYTE
  1.4780 +        """
  1.4781 +        p[0] = IDLBuiltinType.Types.byte
  1.4782 +
  1.4783 +    def p_PrimitiveOrStringTypeOctet(self, p):
  1.4784 +        """
  1.4785 +            PrimitiveOrStringType : OCTET
  1.4786 +        """
  1.4787 +        p[0] = IDLBuiltinType.Types.octet
  1.4788 +
  1.4789 +    def p_PrimitiveOrStringTypeFloat(self, p):
  1.4790 +        """
  1.4791 +            PrimitiveOrStringType : FLOAT
  1.4792 +        """
  1.4793 +        p[0] = IDLBuiltinType.Types.float
  1.4794 +
  1.4795 +    def p_PrimitiveOrStringTypeUnrestictedFloat(self, p):
  1.4796 +        """
  1.4797 +            PrimitiveOrStringType : UNRESTRICTED FLOAT
  1.4798 +        """
  1.4799 +        p[0] = IDLBuiltinType.Types.unrestricted_float
  1.4800 +
  1.4801 +    def p_PrimitiveOrStringTypeDouble(self, p):
  1.4802 +        """
  1.4803 +            PrimitiveOrStringType : DOUBLE
  1.4804 +        """
  1.4805 +        p[0] = IDLBuiltinType.Types.double
  1.4806 +
  1.4807 +    def p_PrimitiveOrStringTypeUnrestictedDouble(self, p):
  1.4808 +        """
  1.4809 +            PrimitiveOrStringType : UNRESTRICTED DOUBLE
  1.4810 +        """
  1.4811 +        p[0] = IDLBuiltinType.Types.unrestricted_double
  1.4812 +
  1.4813 +    def p_PrimitiveOrStringTypeDOMString(self, p):
  1.4814 +        """
  1.4815 +            PrimitiveOrStringType : DOMSTRING
  1.4816 +        """
  1.4817 +        p[0] = IDLBuiltinType.Types.domstring
  1.4818 +
  1.4819 +    def p_PrimitiveOrStringTypeBytestring(self, p):
  1.4820 +        """
  1.4821 +            PrimitiveOrStringType : BYTESTRING
  1.4822 +        """
  1.4823 +        p[0] = IDLBuiltinType.Types.bytestring
  1.4824 +
  1.4825 +    def p_UnsignedIntegerTypeUnsigned(self, p):
  1.4826 +        """
  1.4827 +            UnsignedIntegerType : UNSIGNED IntegerType
  1.4828 +        """
  1.4829 +        p[0] = p[2] + 1 # Adding one to a given signed integer type
  1.4830 +                        # gets you the unsigned type.
  1.4831 +
  1.4832 +    def p_UnsignedIntegerType(self, p):
  1.4833 +        """
  1.4834 +            UnsignedIntegerType : IntegerType
  1.4835 +        """
  1.4836 +        p[0] = p[1]
  1.4837 +
  1.4838 +    def p_IntegerTypeShort(self, p):
  1.4839 +        """
  1.4840 +            IntegerType : SHORT
  1.4841 +        """
  1.4842 +        p[0] = IDLBuiltinType.Types.short
  1.4843 +
  1.4844 +    def p_IntegerTypeLong(self, p):
  1.4845 +        """
  1.4846 +            IntegerType : LONG OptionalLong
  1.4847 +        """
  1.4848 +        if p[2]:
  1.4849 +            p[0] = IDLBuiltinType.Types.long_long
  1.4850 +        else:
  1.4851 +            p[0] = IDLBuiltinType.Types.long
  1.4852 +
  1.4853 +    def p_OptionalLong(self, p):
  1.4854 +        """
  1.4855 +            OptionalLong : LONG
  1.4856 +        """
  1.4857 +        p[0] = True
  1.4858 +
  1.4859 +    def p_OptionalLongEmpty(self, p):
  1.4860 +        """
  1.4861 +            OptionalLong :
  1.4862 +        """
  1.4863 +        p[0] = False
  1.4864 +
  1.4865 +    def p_TypeSuffixBrackets(self, p):
  1.4866 +        """
  1.4867 +            TypeSuffix : LBRACKET RBRACKET TypeSuffix
  1.4868 +        """
  1.4869 +        p[0] = [(IDLMethod.TypeSuffixModifier.Brackets, self.getLocation(p, 1))]
  1.4870 +        p[0].extend(p[3])
  1.4871 +
  1.4872 +    def p_TypeSuffixQMark(self, p):
  1.4873 +        """
  1.4874 +            TypeSuffix : QUESTIONMARK TypeSuffixStartingWithArray
  1.4875 +        """
  1.4876 +        p[0] = [(IDLMethod.TypeSuffixModifier.QMark, self.getLocation(p, 1))]
  1.4877 +        p[0].extend(p[2])
  1.4878 +
  1.4879 +    def p_TypeSuffixEmpty(self, p):
  1.4880 +        """
  1.4881 +            TypeSuffix :
  1.4882 +        """
  1.4883 +        p[0] = []
  1.4884 +
  1.4885 +    def p_TypeSuffixStartingWithArray(self, p):
  1.4886 +        """
  1.4887 +            TypeSuffixStartingWithArray : LBRACKET RBRACKET TypeSuffix
  1.4888 +        """
  1.4889 +        p[0] = [(IDLMethod.TypeSuffixModifier.Brackets, self.getLocation(p, 1))]
  1.4890 +        p[0].extend(p[3])
  1.4891 +
  1.4892 +    def p_TypeSuffixStartingWithArrayEmpty(self, p):
  1.4893 +        """
  1.4894 +            TypeSuffixStartingWithArray :
  1.4895 +        """
  1.4896 +        p[0] = []
  1.4897 +
  1.4898 +    def p_Null(self, p):
  1.4899 +        """
  1.4900 +            Null : QUESTIONMARK
  1.4901 +                 |
  1.4902 +        """
  1.4903 +        if len(p) > 1:
  1.4904 +            p[0] = True
  1.4905 +        else:
  1.4906 +            p[0] = False
  1.4907 +
  1.4908 +    def p_ReturnTypeType(self, p):
  1.4909 +        """
  1.4910 +            ReturnType : Type
  1.4911 +        """
  1.4912 +        p[0] = p[1]
  1.4913 +
  1.4914 +    def p_ReturnTypeVoid(self, p):
  1.4915 +        """
  1.4916 +            ReturnType : VOID
  1.4917 +        """
  1.4918 +        p[0] = BuiltinTypes[IDLBuiltinType.Types.void]
  1.4919 +
  1.4920 +    def p_ScopedName(self, p):
  1.4921 +        """
  1.4922 +            ScopedName : AbsoluteScopedName
  1.4923 +                       | RelativeScopedName
  1.4924 +        """
  1.4925 +        p[0] = p[1]
  1.4926 +
  1.4927 +    def p_AbsoluteScopedName(self, p):
  1.4928 +        """
  1.4929 +            AbsoluteScopedName : SCOPE IDENTIFIER ScopedNameParts
  1.4930 +        """
  1.4931 +        assert False
  1.4932 +        pass
  1.4933 +
  1.4934 +    def p_RelativeScopedName(self, p):
  1.4935 +        """
  1.4936 +            RelativeScopedName : IDENTIFIER ScopedNameParts
  1.4937 +        """
  1.4938 +        assert not p[2] # Not implemented!
  1.4939 +
  1.4940 +        p[0] = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1])
  1.4941 +
  1.4942 +    def p_ScopedNameParts(self, p):
  1.4943 +        """
  1.4944 +            ScopedNameParts : SCOPE IDENTIFIER ScopedNameParts
  1.4945 +        """
  1.4946 +        assert False
  1.4947 +        pass
  1.4948 +
  1.4949 +    def p_ScopedNamePartsEmpty(self, p):
  1.4950 +        """
  1.4951 +            ScopedNameParts :
  1.4952 +        """
  1.4953 +        p[0] = None
  1.4954 +
  1.4955 +    def p_ExtendedAttributeNoArgs(self, p):
  1.4956 +        """
  1.4957 +            ExtendedAttributeNoArgs : IDENTIFIER
  1.4958 +        """
  1.4959 +        p[0] = (p[1],)
  1.4960 +
  1.4961 +    def p_ExtendedAttributeArgList(self, p):
  1.4962 +        """
  1.4963 +            ExtendedAttributeArgList : IDENTIFIER LPAREN ArgumentList RPAREN
  1.4964 +        """
  1.4965 +        p[0] = (p[1], p[3])
  1.4966 +
  1.4967 +    def p_ExtendedAttributeIdent(self, p):
  1.4968 +        """
  1.4969 +            ExtendedAttributeIdent : IDENTIFIER EQUALS STRING
  1.4970 +                                   | IDENTIFIER EQUALS IDENTIFIER
  1.4971 +        """
  1.4972 +        p[0] = (p[1], p[3])
  1.4973 +
  1.4974 +    def p_ExtendedAttributeNamedArgList(self, p):
  1.4975 +        """
  1.4976 +            ExtendedAttributeNamedArgList : IDENTIFIER EQUALS IDENTIFIER LPAREN ArgumentList RPAREN
  1.4977 +        """
  1.4978 +        p[0] = (p[1], p[3], p[5])
  1.4979 +
  1.4980 +    def p_error(self, p):
  1.4981 +        if not p:
  1.4982 +            raise WebIDLError("Syntax Error at end of file. Possibly due to missing semicolon(;), braces(}) or both",
  1.4983 +                              [self._filename])
  1.4984 +        else:
  1.4985 +            raise WebIDLError("invalid syntax", [Location(self.lexer, p.lineno, p.lexpos, self._filename)])
  1.4986 +
  1.4987 +    def __init__(self, outputdir='', lexer=None):
  1.4988 +        Tokenizer.__init__(self, outputdir, lexer)
  1.4989 +        self.parser = yacc.yacc(module=self,
  1.4990 +                                outputdir=outputdir,
  1.4991 +                                tabmodule='webidlyacc',
  1.4992 +                                errorlog=yacc.NullLogger(),
  1.4993 +                                picklefile='WebIDLGrammar.pkl')
  1.4994 +        self._globalScope = IDLScope(BuiltinLocation("<Global Scope>"), None, None)
  1.4995 +        self._installBuiltins(self._globalScope)
  1.4996 +        self._productions = []
  1.4997 +
  1.4998 +        self._filename = "<builtin>"
  1.4999 +        self.lexer.input(Parser._builtins)
  1.5000 +        self._filename = None
  1.5001 +
  1.5002 +        self.parser.parse(lexer=self.lexer,tracking=True)
  1.5003 +
  1.5004 +    def _installBuiltins(self, scope):
  1.5005 +        assert isinstance(scope, IDLScope)
  1.5006 +
  1.5007 +        # xrange omits the last value.
  1.5008 +        for x in xrange(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.Float64Array + 1):
  1.5009 +            builtin = BuiltinTypes[x]
  1.5010 +            name = builtin.name
  1.5011 +
  1.5012 +            typedef = IDLTypedefType(BuiltinLocation("<builtin type>"), builtin, name)
  1.5013 +            typedef.resolve(scope)
  1.5014 +
  1.5015 +    @ staticmethod
  1.5016 +    def handleModifiers(type, modifiers):
  1.5017 +        for (modifier, modifierLocation) in modifiers:
  1.5018 +            assert modifier == IDLMethod.TypeSuffixModifier.QMark or \
  1.5019 +                   modifier == IDLMethod.TypeSuffixModifier.Brackets
  1.5020 +
  1.5021 +            if modifier == IDLMethod.TypeSuffixModifier.QMark:
  1.5022 +                type = IDLNullableType(modifierLocation, type)
  1.5023 +            elif modifier == IDLMethod.TypeSuffixModifier.Brackets:
  1.5024 +                type = IDLArrayType(modifierLocation, type)
  1.5025 +
  1.5026 +        return type
  1.5027 +
  1.5028 +    def parse(self, t, filename=None):
  1.5029 +        self.lexer.input(t)
  1.5030 +
  1.5031 +        #for tok in iter(self.lexer.token, None):
  1.5032 +        #    print tok
  1.5033 +
  1.5034 +        self._filename = filename
  1.5035 +        self._productions.extend(self.parser.parse(lexer=self.lexer,tracking=True))
  1.5036 +        self._filename = None
  1.5037 +
  1.5038 +    def finish(self):
  1.5039 +        # First, finish all the IDLImplementsStatements.  In particular, we
  1.5040 +        # have to make sure we do those before we do the IDLInterfaces.
  1.5041 +        # XXX khuey hates this bit and wants to nuke it from orbit.
  1.5042 +        implementsStatements = [ p for p in self._productions if
  1.5043 +                                 isinstance(p, IDLImplementsStatement)]
  1.5044 +        otherStatements = [ p for p in self._productions if
  1.5045 +                            not isinstance(p, IDLImplementsStatement)]
  1.5046 +        for production in implementsStatements:
  1.5047 +            production.finish(self.globalScope())
  1.5048 +        for production in otherStatements:
  1.5049 +            production.finish(self.globalScope())
  1.5050 +
  1.5051 +        # Do any post-finish validation we need to do
  1.5052 +        for production in self._productions:
  1.5053 +            production.validate()
  1.5054 +
  1.5055 +        # De-duplicate self._productions, without modifying its order.
  1.5056 +        seen = set()
  1.5057 +        result = []
  1.5058 +        for p in self._productions:
  1.5059 +            if p not in seen:
  1.5060 +                seen.add(p)
  1.5061 +                result.append(p)
  1.5062 +        return result
  1.5063 +
  1.5064 +    def reset(self):
  1.5065 +        return Parser(lexer=self.lexer)
  1.5066 +
  1.5067 +    # Builtin IDL defined by WebIDL
  1.5068 +    _builtins = """
  1.5069 +        typedef unsigned long long DOMTimeStamp;
  1.5070 +    """
  1.5071 +
  1.5072 +def main():
  1.5073 +    # Parse arguments.
  1.5074 +    from optparse import OptionParser
  1.5075 +    usageString = "usage: %prog [options] files"
  1.5076 +    o = OptionParser(usage=usageString)
  1.5077 +    o.add_option("--cachedir", dest='cachedir', default=None,
  1.5078 +                 help="Directory in which to cache lex/parse tables.")
  1.5079 +    o.add_option("--verbose-errors", action='store_true', default=False,
  1.5080 +                 help="When an error happens, display the Python traceback.")
  1.5081 +    (options, args) = o.parse_args()
  1.5082 +
  1.5083 +    if len(args) < 1:
  1.5084 +        o.error(usageString)
  1.5085 +
  1.5086 +    fileList = args
  1.5087 +    baseDir = os.getcwd()
  1.5088 +
  1.5089 +    # Parse the WebIDL.
  1.5090 +    parser = Parser(options.cachedir)
  1.5091 +    try:
  1.5092 +        for filename in fileList:
  1.5093 +            fullPath = os.path.normpath(os.path.join(baseDir, filename))
  1.5094 +            f = open(fullPath, 'rb')
  1.5095 +            lines = f.readlines()
  1.5096 +            f.close()
  1.5097 +            print fullPath
  1.5098 +            parser.parse(''.join(lines), fullPath)
  1.5099 +        parser.finish()
  1.5100 +    except WebIDLError, e:
  1.5101 +        if options.verbose_errors:
  1.5102 +            traceback.print_exc()
  1.5103 +        else:
  1.5104 +            print e
  1.5105 +
  1.5106 +if __name__ == '__main__':
  1.5107 +    main()

mercurial