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()