mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Update webidl.py from upstream
This commit is contained in:
parent
427003210b
commit
8f5db8a7e1
12 changed files with 201 additions and 76 deletions
|
@ -1,6 +1,6 @@
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
""" A WebIDL parser. """
|
""" A WebIDL parser. """
|
||||||
|
|
||||||
|
@ -248,8 +248,14 @@ class IDLScope(IDLObject):
|
||||||
return self.QName()
|
return self.QName()
|
||||||
|
|
||||||
def QName(self):
|
def QName(self):
|
||||||
if self._name:
|
# It's possible for us to be called before __init__ has been called, for
|
||||||
return self._name.QName() + "::"
|
# the IDLObjectWithScope case. In that case, self._name won't be set yet.
|
||||||
|
if hasattr(self, "_name"):
|
||||||
|
name = self._name
|
||||||
|
else:
|
||||||
|
name = None
|
||||||
|
if name:
|
||||||
|
return name.QName() + "::"
|
||||||
return "::"
|
return "::"
|
||||||
|
|
||||||
def ensureUnique(self, identifier, object):
|
def ensureUnique(self, identifier, object):
|
||||||
|
@ -327,6 +333,13 @@ class IDLScope(IDLObject):
|
||||||
assert identifier.scope == self
|
assert identifier.scope == self
|
||||||
return self._lookupIdentifier(identifier)
|
return self._lookupIdentifier(identifier)
|
||||||
|
|
||||||
|
def addIfaceGlobalNames(self, interfaceName, globalNames):
|
||||||
|
"""Record the global names (from |globalNames|) that can be used in
|
||||||
|
[Exposed] to expose things in a global named |interfaceName|"""
|
||||||
|
self.globalNames.update(globalNames)
|
||||||
|
for name in globalNames:
|
||||||
|
self.globalNameMapping[name].add(interfaceName)
|
||||||
|
|
||||||
|
|
||||||
class IDLIdentifier(IDLObject):
|
class IDLIdentifier(IDLObject):
|
||||||
def __init__(self, location, scope, name):
|
def __init__(self, location, scope, name):
|
||||||
|
@ -504,8 +517,10 @@ class IDLExposureMixins():
|
||||||
return 'Window' in self.exposureSet
|
return 'Window' in self.exposureSet
|
||||||
|
|
||||||
def isExposedOnMainThread(self):
|
def isExposedOnMainThread(self):
|
||||||
return (self.isExposedInWindow() or
|
return self.isExposedInWindow()
|
||||||
self.isExposedInSystemGlobals())
|
|
||||||
|
def isExposedOffMainThread(self):
|
||||||
|
return len(self.exposureSet - {'Window', 'FakeTestPrimaryGlobal'}) > 0
|
||||||
|
|
||||||
def isExposedInAnyWorker(self):
|
def isExposedInAnyWorker(self):
|
||||||
return len(self.getWorkerExposureSet()) > 0
|
return len(self.getWorkerExposureSet()) > 0
|
||||||
|
@ -516,9 +531,6 @@ class IDLExposureMixins():
|
||||||
def isExposedInAnyWorklet(self):
|
def isExposedInAnyWorklet(self):
|
||||||
return len(self.getWorkletExposureSet()) > 0
|
return len(self.getWorkletExposureSet()) > 0
|
||||||
|
|
||||||
def isExposedInSystemGlobals(self):
|
|
||||||
return 'BackstagePass' in self.exposureSet
|
|
||||||
|
|
||||||
def isExposedInSomeButNotAllWorkers(self):
|
def isExposedInSomeButNotAllWorkers(self):
|
||||||
"""
|
"""
|
||||||
Returns true if the Exposed extended attribute for this interface
|
Returns true if the Exposed extended attribute for this interface
|
||||||
|
@ -597,6 +609,34 @@ class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
|
||||||
return set()
|
return set()
|
||||||
|
|
||||||
|
|
||||||
|
class IDLPartialDictionary(IDLObject):
|
||||||
|
def __init__(self, location, name, members, nonPartialDictionary):
|
||||||
|
assert isinstance(name, IDLUnresolvedIdentifier)
|
||||||
|
|
||||||
|
IDLObject.__init__(self, location)
|
||||||
|
self.identifier = name
|
||||||
|
self.members = members
|
||||||
|
self._nonPartialDictionary = nonPartialDictionary
|
||||||
|
self._finished = False
|
||||||
|
nonPartialDictionary.addPartialDictionary(self)
|
||||||
|
|
||||||
|
def addExtendedAttributes(self, attrs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def finish(self, scope):
|
||||||
|
if self._finished:
|
||||||
|
return
|
||||||
|
self._finished = True
|
||||||
|
|
||||||
|
# Need to make sure our non-partial dictionary gets
|
||||||
|
# finished so it can report cases when we only have partial
|
||||||
|
# dictionaries.
|
||||||
|
self._nonPartialDictionary.finish(scope)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class IDLPartialInterfaceOrNamespace(IDLObject):
|
class IDLPartialInterfaceOrNamespace(IDLObject):
|
||||||
def __init__(self, location, name, members, nonPartialInterfaceOrNamespace):
|
def __init__(self, location, name, members, nonPartialInterfaceOrNamespace):
|
||||||
assert isinstance(name, IDLUnresolvedIdentifier)
|
assert isinstance(name, IDLUnresolvedIdentifier)
|
||||||
|
@ -1322,7 +1362,6 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
|
||||||
for bindingAlias in member.bindingAliases:
|
for bindingAlias in member.bindingAliases:
|
||||||
checkDuplicateNames(member, bindingAlias, "BindingAlias")
|
checkDuplicateNames(member, bindingAlias, "BindingAlias")
|
||||||
|
|
||||||
|
|
||||||
# Conditional exposure makes no sense for interfaces with no
|
# Conditional exposure makes no sense for interfaces with no
|
||||||
# interface object, unless they're navigator properties.
|
# interface object, unless they're navigator properties.
|
||||||
# And SecureContext makes sense for interfaces with no interface object,
|
# And SecureContext makes sense for interfaces with no interface object,
|
||||||
|
@ -1704,9 +1743,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
||||||
self.globalNames = attr.args()
|
self.globalNames = attr.args()
|
||||||
else:
|
else:
|
||||||
self.globalNames = [self.identifier.name]
|
self.globalNames = [self.identifier.name]
|
||||||
self.parentScope.globalNames.update(self.globalNames)
|
self.parentScope.addIfaceGlobalNames(self.identifier.name,
|
||||||
for globalName in self.globalNames:
|
self.globalNames)
|
||||||
self.parentScope.globalNameMapping[globalName].add(self.identifier.name)
|
|
||||||
self._isOnGlobalProtoChain = True
|
self._isOnGlobalProtoChain = True
|
||||||
elif identifier == "PrimaryGlobal":
|
elif identifier == "PrimaryGlobal":
|
||||||
if not attr.noArguments():
|
if not attr.noArguments():
|
||||||
|
@ -1719,8 +1757,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
||||||
self.parentScope.primaryGlobalAttr.location])
|
self.parentScope.primaryGlobalAttr.location])
|
||||||
self.parentScope.primaryGlobalAttr = attr
|
self.parentScope.primaryGlobalAttr = attr
|
||||||
self.parentScope.primaryGlobalName = self.identifier.name
|
self.parentScope.primaryGlobalName = self.identifier.name
|
||||||
self.parentScope.globalNames.add(self.identifier.name)
|
self.parentScope.addIfaceGlobalNames(self.identifier.name,
|
||||||
self.parentScope.globalNameMapping[self.identifier.name].add(self.identifier.name)
|
[self.identifier.name])
|
||||||
self._isOnGlobalProtoChain = True
|
self._isOnGlobalProtoChain = True
|
||||||
elif identifier == "SecureContext":
|
elif identifier == "SecureContext":
|
||||||
if not attr.noArguments():
|
if not attr.noArguments():
|
||||||
|
@ -1743,7 +1781,6 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
||||||
identifier == "LegacyUnenumerableNamedProperties" or
|
identifier == "LegacyUnenumerableNamedProperties" or
|
||||||
identifier == "RunConstructorInCallerCompartment" or
|
identifier == "RunConstructorInCallerCompartment" or
|
||||||
identifier == "WantsEventListenerHooks" or
|
identifier == "WantsEventListenerHooks" or
|
||||||
identifier == "NonOrdinaryGetPrototypeOf" or
|
|
||||||
identifier == "Abstract" or
|
identifier == "Abstract" or
|
||||||
identifier == "Inline"):
|
identifier == "Inline"):
|
||||||
# Known extended attributes that do not take values
|
# Known extended attributes that do not take values
|
||||||
|
@ -1805,7 +1842,7 @@ class IDLNamespace(IDLInterfaceOrNamespace):
|
||||||
if not attr.noArguments():
|
if not attr.noArguments():
|
||||||
raise WebIDLError("[%s] must not have arguments" % identifier,
|
raise WebIDLError("[%s] must not have arguments" % identifier,
|
||||||
[attr.location])
|
[attr.location])
|
||||||
elif identifier == "Pref":
|
elif identifier == "Pref" or identifier == "Func":
|
||||||
# Known extended attributes that take a string value
|
# Known extended attributes that take a string value
|
||||||
if not attr.hasValue():
|
if not attr.hasValue():
|
||||||
raise WebIDLError("[%s] must have a value" % identifier,
|
raise WebIDLError("[%s] must have a value" % identifier,
|
||||||
|
@ -1828,6 +1865,7 @@ class IDLDictionary(IDLObjectWithScope):
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self._finished = False
|
self._finished = False
|
||||||
self.members = list(members)
|
self.members = list(members)
|
||||||
|
self._partialDictionaries = []
|
||||||
|
|
||||||
IDLObjectWithScope.__init__(self, location, parentScope, name)
|
IDLObjectWithScope.__init__(self, location, parentScope, name)
|
||||||
|
|
||||||
|
@ -1864,6 +1902,11 @@ class IDLDictionary(IDLObjectWithScope):
|
||||||
# looking at them.
|
# looking at them.
|
||||||
self.parent.finish(scope)
|
self.parent.finish(scope)
|
||||||
|
|
||||||
|
# Now go ahead and merge in our partial dictionaries.
|
||||||
|
for partial in self._partialDictionaries:
|
||||||
|
partial.finish(scope)
|
||||||
|
self.members.extend(partial.members)
|
||||||
|
|
||||||
for member in self.members:
|
for member in self.members:
|
||||||
member.resolve(self)
|
member.resolve(self)
|
||||||
if not member.isComplete():
|
if not member.isComplete():
|
||||||
|
@ -1968,6 +2011,9 @@ class IDLDictionary(IDLObjectWithScope):
|
||||||
deps.add(self.parent)
|
deps.add(self.parent)
|
||||||
return deps
|
return deps
|
||||||
|
|
||||||
|
def addPartialDictionary(self, partial):
|
||||||
|
assert self.identifier.name == partial.identifier.name
|
||||||
|
self._partialDictionaries.append(partial)
|
||||||
|
|
||||||
class IDLEnum(IDLObjectWithIdentifier):
|
class IDLEnum(IDLObjectWithIdentifier):
|
||||||
def __init__(self, location, parentScope, name, values):
|
def __init__(self, location, parentScope, name, values):
|
||||||
|
@ -4333,7 +4379,7 @@ class IDLAttribute(IDLInterfaceMember):
|
||||||
[attr.location, self.location])
|
[attr.location, self.location])
|
||||||
elif (identifier == "CrossOriginReadable" or
|
elif (identifier == "CrossOriginReadable" or
|
||||||
identifier == "CrossOriginWritable"):
|
identifier == "CrossOriginWritable"):
|
||||||
if not attr.noArguments() and identifier == "CrossOriginReadable":
|
if not attr.noArguments():
|
||||||
raise WebIDLError("[%s] must take no arguments" % identifier,
|
raise WebIDLError("[%s] must take no arguments" % identifier,
|
||||||
[attr.location])
|
[attr.location])
|
||||||
if self.isStatic():
|
if self.isStatic():
|
||||||
|
@ -4525,7 +4571,7 @@ class IDLArgument(IDLObjectWithIdentifier):
|
||||||
if ((self.type.isDictionary() or
|
if ((self.type.isDictionary() or
|
||||||
self.type.isUnion() and self.type.unroll().hasDictionaryType()) and
|
self.type.isUnion() and self.type.unroll().hasDictionaryType()) and
|
||||||
self.optional and not self.defaultValue and not self.variadic):
|
self.optional and not self.defaultValue and not self.variadic):
|
||||||
# Default optional non-variadic dictionaries to null,
|
# Default optional non-variadic dictionary arguments to null,
|
||||||
# for simplicity, so the codegen doesn't have to special-case this.
|
# for simplicity, so the codegen doesn't have to special-case this.
|
||||||
self.defaultValue = IDLNullValue(self.location)
|
self.defaultValue = IDLNullValue(self.location)
|
||||||
elif self.type.isAny():
|
elif self.type.isAny():
|
||||||
|
@ -5089,6 +5135,10 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||||
if not attr.noArguments():
|
if not attr.noArguments():
|
||||||
raise WebIDLError("[%s] must take no arguments" % identifier,
|
raise WebIDLError("[%s] must take no arguments" % identifier,
|
||||||
[attr.location])
|
[attr.location])
|
||||||
|
if identifier == "CrossOriginCallable" and self.isStatic():
|
||||||
|
raise WebIDLError("[CrossOriginCallable] is only allowed on non-static "
|
||||||
|
"attributes"
|
||||||
|
[attr.location, self.location])
|
||||||
elif identifier == "Pure":
|
elif identifier == "Pure":
|
||||||
if not attr.noArguments():
|
if not attr.noArguments():
|
||||||
raise WebIDLError("[Pure] must take no arguments",
|
raise WebIDLError("[Pure] must take no arguments",
|
||||||
|
@ -5293,7 +5343,7 @@ class Tokenizer(object):
|
||||||
return t
|
return t
|
||||||
|
|
||||||
def t_IDENTIFIER(self, t):
|
def t_IDENTIFIER(self, t):
|
||||||
r'[A-Z_a-z][0-9A-Z_a-z-]*'
|
r'[_-]?[A-Za-z][0-9A-Z_a-z-]*'
|
||||||
t.type = self.keywords.get(t.value, 'IDENTIFIER')
|
t.type = self.keywords.get(t.value, 'IDENTIFIER')
|
||||||
return t
|
return t
|
||||||
|
|
||||||
|
@ -5518,9 +5568,10 @@ class Parser(Tokenizer):
|
||||||
def handleNonPartialObject(self, location, identifier, constructor,
|
def handleNonPartialObject(self, location, identifier, constructor,
|
||||||
constructorArgs, nonPartialArgs):
|
constructorArgs, nonPartialArgs):
|
||||||
"""
|
"""
|
||||||
This handles non-partial objects (interfaces and namespaces) by
|
This handles non-partial objects (interfaces, namespaces and
|
||||||
checking for an existing partial object, and promoting it to
|
dictionaries) by checking for an existing partial object, and promoting
|
||||||
non-partial as needed. The return value is the non-partial object.
|
it to non-partial as needed. The return value is the non-partial
|
||||||
|
object.
|
||||||
|
|
||||||
constructorArgs are all the args for the constructor except the last
|
constructorArgs are all the args for the constructor except the last
|
||||||
one: isKnownNonPartial.
|
one: isKnownNonPartial.
|
||||||
|
@ -5610,6 +5661,7 @@ class Parser(Tokenizer):
|
||||||
"""
|
"""
|
||||||
PartialDefinition : PartialInterface
|
PartialDefinition : PartialInterface
|
||||||
| PartialNamespace
|
| PartialNamespace
|
||||||
|
| PartialDictionary
|
||||||
"""
|
"""
|
||||||
p[0] = p[1]
|
p[0] = p[1]
|
||||||
|
|
||||||
|
@ -5617,17 +5669,17 @@ class Parser(Tokenizer):
|
||||||
nonPartialConstructorArgs,
|
nonPartialConstructorArgs,
|
||||||
partialConstructorArgs):
|
partialConstructorArgs):
|
||||||
"""
|
"""
|
||||||
This handles partial objects (interfaces and namespaces) by checking for
|
This handles partial objects (interfaces, namespaces and dictionaries)
|
||||||
an existing non-partial object, and adding ourselves to it as needed.
|
by checking for an existing non-partial object, and adding ourselves to
|
||||||
The return value is our partial object. For now we just use
|
it as needed. The return value is our partial object. We use
|
||||||
IDLPartialInterfaceOrNamespace for partial objects.
|
IDLPartialInterfaceOrNamespace for partial interfaces or namespaces,
|
||||||
|
and IDLPartialDictionary for partial dictionaries.
|
||||||
|
|
||||||
nonPartialConstructorArgs are all the args for the non-partial
|
nonPartialConstructorArgs are all the args for the non-partial
|
||||||
constructor except the last two: members and isKnownNonPartial.
|
constructor except the last two: members and isKnownNonPartial.
|
||||||
|
|
||||||
partialConstructorArgs are the arguments for the
|
partialConstructorArgs are the arguments for the partial object
|
||||||
IDLPartialInterfaceOrNamespace constructor, except the last one (the
|
constructor, except the last one (the non-partial object).
|
||||||
non-partial object).
|
|
||||||
"""
|
"""
|
||||||
# The name of the class starts with "IDL", so strip that off.
|
# The name of the class starts with "IDL", so strip that off.
|
||||||
# Also, starts with a capital letter after that, so nix that
|
# Also, starts with a capital letter after that, so nix that
|
||||||
|
@ -5652,9 +5704,19 @@ class Parser(Tokenizer):
|
||||||
nonPartialObject = nonPartialConstructor(
|
nonPartialObject = nonPartialConstructor(
|
||||||
# No members, False for isKnownNonPartial
|
# No members, False for isKnownNonPartial
|
||||||
*(nonPartialConstructorArgs + [[], False]))
|
*(nonPartialConstructorArgs + [[], False]))
|
||||||
partialInterface = IDLPartialInterfaceOrNamespace(
|
|
||||||
|
partialObject = None
|
||||||
|
if isinstance(nonPartialObject, IDLDictionary):
|
||||||
|
partialObject = IDLPartialDictionary(
|
||||||
*(partialConstructorArgs + [nonPartialObject]))
|
*(partialConstructorArgs + [nonPartialObject]))
|
||||||
return partialInterface
|
elif isinstance(nonPartialObject, (IDLInterface, IDLNamespace)):
|
||||||
|
partialObject = IDLPartialInterfaceOrNamespace(
|
||||||
|
*(partialConstructorArgs + [nonPartialObject]))
|
||||||
|
else:
|
||||||
|
raise WebIDLError("Unknown partial object type %s" %
|
||||||
|
type(partialObject))
|
||||||
|
|
||||||
|
return partialObject
|
||||||
|
|
||||||
def p_PartialInterface(self, p):
|
def p_PartialInterface(self, p):
|
||||||
"""
|
"""
|
||||||
|
@ -5682,6 +5744,19 @@ class Parser(Tokenizer):
|
||||||
[location, self.globalScope(), identifier],
|
[location, self.globalScope(), identifier],
|
||||||
[location, identifier, members])
|
[location, identifier, members])
|
||||||
|
|
||||||
|
def p_PartialDictionary(self, p):
|
||||||
|
"""
|
||||||
|
PartialDictionary : DICTIONARY IDENTIFIER LBRACE DictionaryMembers RBRACE SEMICOLON
|
||||||
|
"""
|
||||||
|
location = self.getLocation(p, 1)
|
||||||
|
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
|
||||||
|
members = p[4]
|
||||||
|
|
||||||
|
p[0] = self.handlePartialObject(
|
||||||
|
location, identifier, IDLDictionary,
|
||||||
|
[location, self.globalScope(), identifier],
|
||||||
|
[location, identifier, members])
|
||||||
|
|
||||||
def p_Inheritance(self, p):
|
def p_Inheritance(self, p):
|
||||||
"""
|
"""
|
||||||
Inheritance : COLON ScopedName
|
Inheritance : COLON ScopedName
|
||||||
|
@ -6894,16 +6969,13 @@ class Parser(Tokenizer):
|
||||||
logger.reportGrammarErrors()
|
logger.reportGrammarErrors()
|
||||||
|
|
||||||
self._globalScope = IDLScope(BuiltinLocation("<Global Scope>"), None, None)
|
self._globalScope = IDLScope(BuiltinLocation("<Global Scope>"), None, None)
|
||||||
|
|
||||||
# To make our test harness work, pretend like we have a primary global already.
|
# To make our test harness work, pretend like we have a primary global already.
|
||||||
# Note that we _don't_ set _globalScope.primaryGlobalAttr,
|
# Note that we _don't_ set _globalScope.primaryGlobalAttr,
|
||||||
# so we'll still be able to detect multiple PrimaryGlobal extended attributes.
|
# so we'll still be able to detect multiple PrimaryGlobal extended attributes.
|
||||||
self._globalScope.primaryGlobalName = "FakeTestPrimaryGlobal"
|
self._globalScope.primaryGlobalName = "FakeTestPrimaryGlobal"
|
||||||
self._globalScope.globalNames.add("FakeTestPrimaryGlobal")
|
self._globalScope.addIfaceGlobalNames("FakeTestPrimaryGlobal", ["FakeTestPrimaryGlobal"])
|
||||||
self._globalScope.globalNameMapping["FakeTestPrimaryGlobal"].add("FakeTestPrimaryGlobal")
|
|
||||||
# And we add the special-cased "System" global name, which
|
|
||||||
# doesn't have any corresponding interfaces.
|
|
||||||
self._globalScope.globalNames.add("System")
|
|
||||||
self._globalScope.globalNameMapping["System"].add("BackstagePass")
|
|
||||||
self._installBuiltins(self._globalScope)
|
self._installBuiltins(self._globalScope)
|
||||||
self._productions = []
|
self._productions = []
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
--- WebIDL.py
|
--- WebIDL.py
|
||||||
+++ WebIDL.py
|
+++ WebIDL.py
|
||||||
@@ -1744,7 +1744,8 @@
|
@@ -1786,7 +1786,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
||||||
|
identifier == "ProbablyShortLivingWrapper" or
|
||||||
identifier == "LegacyUnenumerableNamedProperties" or
|
identifier == "LegacyUnenumerableNamedProperties" or
|
||||||
identifier == "RunConstructorInCallerCompartment" or
|
identifier == "RunConstructorInCallerCompartment" or
|
||||||
identifier == "WantsEventListenerHooks" or
|
- identifier == "WantsEventListenerHooks"):
|
||||||
- identifier == "NonOrdinaryGetPrototypeOf"):
|
+ identifier == "WantsEventListenerHooks" or
|
||||||
+ identifier == "NonOrdinaryGetPrototypeOf" or
|
|
||||||
+ identifier == "Abstract"):
|
+ identifier == "Abstract"):
|
||||||
# Known extended attributes that do not take values
|
# Known extended attributes that do not take values
|
||||||
if not attr.noArguments():
|
if not attr.noArguments():
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py
|
|
||||||
index da32340..81c52b7 100644
|
|
||||||
--- WebIDL.py
|
--- WebIDL.py
|
||||||
+++ WebIDL.py
|
+++ WebIDL.py
|
||||||
@@ -2170,7 +2170,7 @@ class IDLUnresolvedType(IDLType):
|
@@ -2275,7 +2275,7 @@ class IDLUnresolvedType(IDLType):
|
||||||
return typedefType.complete(scope)
|
return typedefType.complete(scope)
|
||||||
elif obj.isCallback() and not obj.isInterface():
|
elif obj.isCallback() and not obj.isInterface():
|
||||||
assert self.name.name == obj.identifier.name
|
assert self.name.name == obj.identifier.name
|
||||||
- return IDLCallbackType(self.location, obj)
|
- return IDLCallbackType(self.location, obj)
|
||||||
+ return IDLCallbackType(obj.location, obj)
|
+ return IDLCallbackType(obj.location, obj)
|
||||||
|
|
||||||
if self._promiseInnerType and not self._promiseInnerType.isComplete():
|
name = self.name.resolve(scope, None)
|
||||||
self._promiseInnerType = self._promiseInnerType.complete(scope)
|
return IDLWrapperType(self.location, obj)
|
||||||
@@ -6521,7 +6521,7 @@ class Parser(Tokenizer):
|
@@ -6688,7 +6688,7 @@ class Parser(Tokenizer):
|
||||||
type = IDLTypedefType(self.getLocation(p, 1), obj.innerType,
|
type = IDLTypedefType(self.getLocation(p, 1), obj.innerType,
|
||||||
obj.identifier.name)
|
obj.identifier.name)
|
||||||
elif obj.isCallback() and not obj.isInterface():
|
elif obj.isCallback() and not obj.isInterface():
|
||||||
|
@ -19,4 +17,4 @@ index da32340..81c52b7 100644
|
||||||
+ type = IDLCallbackType(obj.location, obj)
|
+ type = IDLCallbackType(obj.location, obj)
|
||||||
else:
|
else:
|
||||||
type = IDLWrapperType(self.getLocation(p, 1), p[1])
|
type = IDLWrapperType(self.getLocation(p, 1), p[1])
|
||||||
p[0] = self.handleModifiers(type, p[2])
|
p[0] = self.handleNullable(type, p[2])
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
--- WebIDL.py
|
--- WebIDL.py
|
||||||
+++ WebIDL.py
|
+++ WebIDL.py
|
||||||
@@ -6823,7 +6823,8 @@ class Parser(Tokenizer):
|
@@ -6959,7 +6959,8 @@ class Parser(Tokenizer):
|
||||||
self.parser = yacc.yacc(module=self,
|
self.parser = yacc.yacc(module=self,
|
||||||
outputdir=outputdir,
|
outputdir=outputdir,
|
||||||
tabmodule='webidlyacc',
|
tabmodule='webidlyacc',
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
--- WebIDL.py
|
--- WebIDL.py
|
||||||
+++ WebIDL.py
|
+++ WebIDL.py
|
||||||
@@ -1695,7 +1695,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
@@ -1787,7 +1787,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
||||||
identifier == "ProbablyShortLivingObject" or
|
|
||||||
identifier == "LegacyUnenumerableNamedProperties" or
|
identifier == "LegacyUnenumerableNamedProperties" or
|
||||||
identifier == "NonOrdinaryGetPrototypeOf" or
|
identifier == "RunConstructorInCallerCompartment" or
|
||||||
|
identifier == "WantsEventListenerHooks" or
|
||||||
- identifier == "Abstract"):
|
- identifier == "Abstract"):
|
||||||
+ identifier == "Abstract" or
|
+ identifier == "Abstract" or
|
||||||
+ identifier == "Inline"):
|
+ identifier == "Inline"):
|
||||||
|
|
|
@ -26,6 +26,31 @@ def WebIDLTest(parser, harness):
|
||||||
harness.check(dict2.members[1].identifier.name, "child",
|
harness.check(dict2.members[1].identifier.name, "child",
|
||||||
"'a' really comes before 'c'")
|
"'a' really comes before 'c'")
|
||||||
|
|
||||||
|
# Test partial dictionary.
|
||||||
|
parser = parser.reset();
|
||||||
|
parser.parse("""
|
||||||
|
dictionary A {
|
||||||
|
long c;
|
||||||
|
long g;
|
||||||
|
};
|
||||||
|
partial dictionary A {
|
||||||
|
long h;
|
||||||
|
long d;
|
||||||
|
};
|
||||||
|
""")
|
||||||
|
results = parser.finish()
|
||||||
|
|
||||||
|
dict1 = results[0];
|
||||||
|
harness.check(len(dict1.members), 4, "Dict1 has four members")
|
||||||
|
harness.check(dict1.members[0].identifier.name, "c",
|
||||||
|
"c should be first")
|
||||||
|
harness.check(dict1.members[1].identifier.name, "d",
|
||||||
|
"d should come after c")
|
||||||
|
harness.check(dict1.members[2].identifier.name, "g",
|
||||||
|
"g should come after d")
|
||||||
|
harness.check(dict1.members[3].identifier.name, "h",
|
||||||
|
"h should be last")
|
||||||
|
|
||||||
# Now reset our parser
|
# Now reset our parser
|
||||||
parser = parser.reset()
|
parser = parser.reset()
|
||||||
threw = False
|
threw = False
|
||||||
|
@ -42,6 +67,24 @@ def WebIDLTest(parser, harness):
|
||||||
|
|
||||||
harness.ok(threw, "Should not allow name duplication in a dictionary")
|
harness.ok(threw, "Should not allow name duplication in a dictionary")
|
||||||
|
|
||||||
|
# Test no name duplication across normal and partial dictionary.
|
||||||
|
parser = parser.reset();
|
||||||
|
threw = False
|
||||||
|
try:
|
||||||
|
parser.parse("""
|
||||||
|
dictionary A {
|
||||||
|
long prop = 5;
|
||||||
|
};
|
||||||
|
partial dictionary A {
|
||||||
|
long prop;
|
||||||
|
};
|
||||||
|
""")
|
||||||
|
results = parser.finish()
|
||||||
|
except:
|
||||||
|
threw = True
|
||||||
|
|
||||||
|
harness.ok(threw, "Should not allow name duplication across normal and partial dictionary")
|
||||||
|
|
||||||
# Now reset our parser again
|
# Now reset our parser again
|
||||||
parser = parser.reset()
|
parser = parser.reset()
|
||||||
threw = False
|
threw = False
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
def should_throw(parser, harness, message, code):
|
def should_throw(parser, harness, message, code):
|
||||||
parser = parser.reset();
|
parser = parser.reset();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
def should_throw(parser, harness, message, code):
|
def should_throw(parser, harness, message, code):
|
||||||
parser = parser.reset();
|
parser = parser.reset();
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
--- WebIDL.py
|
||||||
|
+++ WebIDL.py
|
||||||
|
@@ -4570,8 +4570,7 @@ class IDLArgument(IDLObjectWithIdentifier):
|
||||||
|
|
||||||
|
if ((self.type.isDictionary() or
|
||||||
|
self.type.isUnion() and self.type.unroll().hasDictionaryType()) and
|
||||||
|
- self.optional and not self.defaultValue and not self.variadic and
|
||||||
|
- not self.dictionaryMember):
|
||||||
|
+ self.optional and not self.defaultValue and not self.variadic):
|
||||||
|
# Default optional non-variadic dictionary arguments to null,
|
||||||
|
# for simplicity, so the codegen doesn't have to special-case this.
|
||||||
|
self.defaultValue = IDLNullValue(self.location)
|
|
@ -1,22 +1,22 @@
|
||||||
--- WebIDL.py
|
--- WebIDL.py
|
||||||
+++ WebIDL.py
|
+++ WebIDL.py
|
||||||
@@ -2481,10 +2481,18 @@ class IDLUnionType(IDLType):
|
@@ -2613,10 +2613,18 @@ class IDLUnionType(IDLType):
|
||||||
return type.name
|
return type.name
|
||||||
|
|
||||||
for (i, type) in enumerate(self.memberTypes):
|
for (i, type) in enumerate(self.memberTypes):
|
||||||
|
- if not type.isComplete():
|
||||||
+ # Exclude typedefs because if given "typedef (B or C) test",
|
+ # Exclude typedefs because if given "typedef (B or C) test",
|
||||||
+ # we want AOrTest, not AOrBOrC
|
+ # we want AOrTest, not AOrBOrC
|
||||||
+ if not type.isComplete() and not isinstance(type, IDLTypedefType):
|
+ if not type.isComplete() and not isinstance(type, IDLTypedefType):
|
||||||
+ self.memberTypes[i] = type.complete(scope)
|
self.memberTypes[i] = type.complete(scope)
|
||||||
+
|
|
||||||
+ self.name = "Or".join(typeName(type) for type in self.memberTypes)
|
self.name = "Or".join(typeName(type) for type in self.memberTypes)
|
||||||
+
|
+
|
||||||
+ # We do this again to complete the typedef types
|
+ # We do this again to complete the typedef types
|
||||||
+ for (i, type) in enumerate(self.memberTypes):
|
+ for (i, type) in enumerate(self.memberTypes):
|
||||||
if not type.isComplete():
|
+ if not type.isComplete():
|
||||||
self.memberTypes[i] = type.complete(scope)
|
+ self.memberTypes[i] = type.complete(scope)
|
||||||
|
+
|
||||||
- self.name = "Or".join(typeName(type) for type in self.memberTypes)
|
|
||||||
self.flatMemberTypes = list(self.memberTypes)
|
self.flatMemberTypes = list(self.memberTypes)
|
||||||
i = 0
|
i = 0
|
||||||
while i < len(self.flatMemberTypes):
|
while i < len(self.flatMemberTypes):
|
||||||
|
|
|
@ -5,6 +5,7 @@ patch < pref-main-thread.patch
|
||||||
patch < callback-location.patch
|
patch < callback-location.patch
|
||||||
patch < union-typedef.patch
|
patch < union-typedef.patch
|
||||||
patch < inline.patch
|
patch < inline.patch
|
||||||
|
patch < undo-dictionary-optional.patch
|
||||||
|
|
||||||
wget https://hg.mozilla.org/mozilla-central/archive/tip.tar.gz/dom/bindings/parser/tests/ -O tests.tar.gz
|
wget https://hg.mozilla.org/mozilla-central/archive/tip.tar.gz/dom/bindings/parser/tests/ -O tests.tar.gz
|
||||||
rm -r tests
|
rm -r tests
|
||||||
|
|
|
@ -1,26 +1,25 @@
|
||||||
--- WebIDL.py
|
--- WebIDL.py
|
||||||
+++ WebIDL.py
|
+++ WebIDL.py
|
||||||
@@ -1239,12 +1239,6 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
@@ -1362,12 +1362,6 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
|
||||||
alias,
|
for bindingAlias in member.bindingAliases:
|
||||||
[member.location, m.location])
|
checkDuplicateNames(member, bindingAlias, "BindingAlias")
|
||||||
|
|
||||||
- if (self.getExtendedAttribute("Pref") and
|
-
|
||||||
- self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
|
- if self.getExtendedAttribute("Pref") and self.isExposedOffMainThread():
|
||||||
- raise WebIDLError("[Pref] used on an interface that is not %s-only" %
|
- raise WebIDLError("[Pref] used on an interface that is not "
|
||||||
- self.parentScope.primaryGlobalName,
|
- "main-thread-only",
|
||||||
- [self.location])
|
- [self.location])
|
||||||
-
|
-
|
||||||
# Conditional exposure makes no sense for interfaces with no
|
# Conditional exposure makes no sense for interfaces with no
|
||||||
# interface object, unless they're navigator properties.
|
# interface object, unless they're navigator properties.
|
||||||
# And SecureContext makes sense for interfaces with no interface object,
|
# And SecureContext makes sense for interfaces with no interface object,
|
||||||
@@ -3459,12 +3453,6 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
|
@@ -3619,11 +3613,6 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
|
||||||
IDLExposureMixins.finish(self, scope)
|
IDLExposureMixins.finish(self, scope)
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
- if (self.getExtendedAttribute("Pref") and
|
- if self.getExtendedAttribute("Pref") and self.isExposedOffMainThread():
|
||||||
- self.exposureSet != set([self._globalScope.primaryGlobalName])):
|
|
||||||
- raise WebIDLError("[Pref] used on an interface member that is not "
|
- raise WebIDLError("[Pref] used on an interface member that is not "
|
||||||
- "%s-only" % self._globalScope.primaryGlobalName,
|
- "main-thread-only",
|
||||||
- [self.location])
|
- [self.location])
|
||||||
-
|
-
|
||||||
if self.isAttr() or self.isMethod():
|
if self.isAttr() or self.isMethod():
|
Loading…
Add table
Add a link
Reference in a new issue