mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Auto merge of #22934 - Manishearth:update-webidl, r=nox
Update WebIDL.py I'm working on getting [attributes on types landed in upstream webidl](https://bugzilla.mozilla.org/show_bug.cgi?id=1359269). In preparation for that, I'd like to update WebIDL.py and deal with all the conflicts first so that updating for that bug is easier. (This PR doesn't need to be reviewed and landed right now, I can just roll it into the PR for implementing attributes on types, but I suspect it would be easier to land this first) Probably should squash before landing, the steps are separated out for ease of review. r? @nox @jdm <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22934) <!-- Reviewable:end -->
This commit is contained in:
commit
27f443fd00
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
|
||||
# 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. """
|
||||
|
||||
|
@ -248,8 +248,14 @@ class IDLScope(IDLObject):
|
|||
return self.QName()
|
||||
|
||||
def QName(self):
|
||||
if self._name:
|
||||
return self._name.QName() + "::"
|
||||
# It's possible for us to be called before __init__ has been called, for
|
||||
# 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 "::"
|
||||
|
||||
def ensureUnique(self, identifier, object):
|
||||
|
@ -327,6 +333,13 @@ class IDLScope(IDLObject):
|
|||
assert identifier.scope == self
|
||||
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):
|
||||
def __init__(self, location, scope, name):
|
||||
|
@ -504,8 +517,10 @@ class IDLExposureMixins():
|
|||
return 'Window' in self.exposureSet
|
||||
|
||||
def isExposedOnMainThread(self):
|
||||
return (self.isExposedInWindow() or
|
||||
self.isExposedInSystemGlobals())
|
||||
return self.isExposedInWindow()
|
||||
|
||||
def isExposedOffMainThread(self):
|
||||
return len(self.exposureSet - {'Window', 'FakeTestPrimaryGlobal'}) > 0
|
||||
|
||||
def isExposedInAnyWorker(self):
|
||||
return len(self.getWorkerExposureSet()) > 0
|
||||
|
@ -516,9 +531,6 @@ class IDLExposureMixins():
|
|||
def isExposedInAnyWorklet(self):
|
||||
return len(self.getWorkletExposureSet()) > 0
|
||||
|
||||
def isExposedInSystemGlobals(self):
|
||||
return 'BackstagePass' in self.exposureSet
|
||||
|
||||
def isExposedInSomeButNotAllWorkers(self):
|
||||
"""
|
||||
Returns true if the Exposed extended attribute for this interface
|
||||
|
@ -597,6 +609,34 @@ class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
|
|||
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):
|
||||
def __init__(self, location, name, members, nonPartialInterfaceOrNamespace):
|
||||
assert isinstance(name, IDLUnresolvedIdentifier)
|
||||
|
@ -1322,7 +1362,6 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
|
|||
for bindingAlias in member.bindingAliases:
|
||||
checkDuplicateNames(member, bindingAlias, "BindingAlias")
|
||||
|
||||
|
||||
# Conditional exposure makes no sense for interfaces with no
|
||||
# interface object, unless they're navigator properties.
|
||||
# And SecureContext makes sense for interfaces with no interface object,
|
||||
|
@ -1704,9 +1743,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
|||
self.globalNames = attr.args()
|
||||
else:
|
||||
self.globalNames = [self.identifier.name]
|
||||
self.parentScope.globalNames.update(self.globalNames)
|
||||
for globalName in self.globalNames:
|
||||
self.parentScope.globalNameMapping[globalName].add(self.identifier.name)
|
||||
self.parentScope.addIfaceGlobalNames(self.identifier.name,
|
||||
self.globalNames)
|
||||
self._isOnGlobalProtoChain = True
|
||||
elif identifier == "PrimaryGlobal":
|
||||
if not attr.noArguments():
|
||||
|
@ -1719,8 +1757,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
|||
self.parentScope.primaryGlobalAttr.location])
|
||||
self.parentScope.primaryGlobalAttr = attr
|
||||
self.parentScope.primaryGlobalName = self.identifier.name
|
||||
self.parentScope.globalNames.add(self.identifier.name)
|
||||
self.parentScope.globalNameMapping[self.identifier.name].add(self.identifier.name)
|
||||
self.parentScope.addIfaceGlobalNames(self.identifier.name,
|
||||
[self.identifier.name])
|
||||
self._isOnGlobalProtoChain = True
|
||||
elif identifier == "SecureContext":
|
||||
if not attr.noArguments():
|
||||
|
@ -1743,7 +1781,6 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
|||
identifier == "LegacyUnenumerableNamedProperties" or
|
||||
identifier == "RunConstructorInCallerCompartment" or
|
||||
identifier == "WantsEventListenerHooks" or
|
||||
identifier == "NonOrdinaryGetPrototypeOf" or
|
||||
identifier == "Abstract" or
|
||||
identifier == "Inline"):
|
||||
# Known extended attributes that do not take values
|
||||
|
@ -1805,7 +1842,7 @@ class IDLNamespace(IDLInterfaceOrNamespace):
|
|||
if not attr.noArguments():
|
||||
raise WebIDLError("[%s] must not have arguments" % identifier,
|
||||
[attr.location])
|
||||
elif identifier == "Pref":
|
||||
elif identifier == "Pref" or identifier == "Func":
|
||||
# Known extended attributes that take a string value
|
||||
if not attr.hasValue():
|
||||
raise WebIDLError("[%s] must have a value" % identifier,
|
||||
|
@ -1828,6 +1865,7 @@ class IDLDictionary(IDLObjectWithScope):
|
|||
self.parent = parent
|
||||
self._finished = False
|
||||
self.members = list(members)
|
||||
self._partialDictionaries = []
|
||||
|
||||
IDLObjectWithScope.__init__(self, location, parentScope, name)
|
||||
|
||||
|
@ -1864,6 +1902,11 @@ class IDLDictionary(IDLObjectWithScope):
|
|||
# looking at them.
|
||||
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:
|
||||
member.resolve(self)
|
||||
if not member.isComplete():
|
||||
|
@ -1968,6 +2011,9 @@ class IDLDictionary(IDLObjectWithScope):
|
|||
deps.add(self.parent)
|
||||
return deps
|
||||
|
||||
def addPartialDictionary(self, partial):
|
||||
assert self.identifier.name == partial.identifier.name
|
||||
self._partialDictionaries.append(partial)
|
||||
|
||||
class IDLEnum(IDLObjectWithIdentifier):
|
||||
def __init__(self, location, parentScope, name, values):
|
||||
|
@ -4333,7 +4379,7 @@ class IDLAttribute(IDLInterfaceMember):
|
|||
[attr.location, self.location])
|
||||
elif (identifier == "CrossOriginReadable" or
|
||||
identifier == "CrossOriginWritable"):
|
||||
if not attr.noArguments() and identifier == "CrossOriginReadable":
|
||||
if not attr.noArguments():
|
||||
raise WebIDLError("[%s] must take no arguments" % identifier,
|
||||
[attr.location])
|
||||
if self.isStatic():
|
||||
|
@ -4525,7 +4571,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):
|
||||
# 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.
|
||||
self.defaultValue = IDLNullValue(self.location)
|
||||
elif self.type.isAny():
|
||||
|
@ -5089,6 +5135,10 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
|||
if not attr.noArguments():
|
||||
raise WebIDLError("[%s] must take no arguments" % identifier,
|
||||
[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":
|
||||
if not attr.noArguments():
|
||||
raise WebIDLError("[Pure] must take no arguments",
|
||||
|
@ -5293,7 +5343,7 @@ class Tokenizer(object):
|
|||
return 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')
|
||||
return t
|
||||
|
||||
|
@ -5518,9 +5568,10 @@ class Parser(Tokenizer):
|
|||
def handleNonPartialObject(self, location, identifier, constructor,
|
||||
constructorArgs, nonPartialArgs):
|
||||
"""
|
||||
This handles non-partial objects (interfaces and namespaces) by
|
||||
checking for an existing partial object, and promoting it to
|
||||
non-partial as needed. The return value is the non-partial object.
|
||||
This handles non-partial objects (interfaces, namespaces and
|
||||
dictionaries) by checking for an existing partial object, and promoting
|
||||
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
|
||||
one: isKnownNonPartial.
|
||||
|
@ -5610,6 +5661,7 @@ class Parser(Tokenizer):
|
|||
"""
|
||||
PartialDefinition : PartialInterface
|
||||
| PartialNamespace
|
||||
| PartialDictionary
|
||||
"""
|
||||
p[0] = p[1]
|
||||
|
||||
|
@ -5617,17 +5669,17 @@ class Parser(Tokenizer):
|
|||
nonPartialConstructorArgs,
|
||||
partialConstructorArgs):
|
||||
"""
|
||||
This handles partial objects (interfaces and namespaces) by checking for
|
||||
an existing non-partial object, and adding ourselves to it as needed.
|
||||
The return value is our partial object. For now we just use
|
||||
IDLPartialInterfaceOrNamespace for partial objects.
|
||||
This handles partial objects (interfaces, namespaces and dictionaries)
|
||||
by checking for an existing non-partial object, and adding ourselves to
|
||||
it as needed. The return value is our partial object. We use
|
||||
IDLPartialInterfaceOrNamespace for partial interfaces or namespaces,
|
||||
and IDLPartialDictionary for partial dictionaries.
|
||||
|
||||
nonPartialConstructorArgs are all the args for the non-partial
|
||||
constructor except the last two: members and isKnownNonPartial.
|
||||
|
||||
partialConstructorArgs are the arguments for the
|
||||
IDLPartialInterfaceOrNamespace constructor, except the last one (the
|
||||
non-partial object).
|
||||
partialConstructorArgs are the arguments for the partial object
|
||||
constructor, except the last one (the non-partial object).
|
||||
"""
|
||||
# The name of the class starts with "IDL", so strip that off.
|
||||
# Also, starts with a capital letter after that, so nix that
|
||||
|
@ -5652,9 +5704,19 @@ class Parser(Tokenizer):
|
|||
nonPartialObject = nonPartialConstructor(
|
||||
# No members, False for isKnownNonPartial
|
||||
*(nonPartialConstructorArgs + [[], False]))
|
||||
partialInterface = IDLPartialInterfaceOrNamespace(
|
||||
*(partialConstructorArgs + [nonPartialObject]))
|
||||
return partialInterface
|
||||
|
||||
partialObject = None
|
||||
if isinstance(nonPartialObject, IDLDictionary):
|
||||
partialObject = IDLPartialDictionary(
|
||||
*(partialConstructorArgs + [nonPartialObject]))
|
||||
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):
|
||||
"""
|
||||
|
@ -5682,6 +5744,19 @@ class Parser(Tokenizer):
|
|||
[location, self.globalScope(), identifier],
|
||||
[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):
|
||||
"""
|
||||
Inheritance : COLON ScopedName
|
||||
|
@ -6894,16 +6969,13 @@ class Parser(Tokenizer):
|
|||
logger.reportGrammarErrors()
|
||||
|
||||
self._globalScope = IDLScope(BuiltinLocation("<Global Scope>"), None, None)
|
||||
|
||||
# To make our test harness work, pretend like we have a primary global already.
|
||||
# Note that we _don't_ set _globalScope.primaryGlobalAttr,
|
||||
# so we'll still be able to detect multiple PrimaryGlobal extended attributes.
|
||||
self._globalScope.primaryGlobalName = "FakeTestPrimaryGlobal"
|
||||
self._globalScope.globalNames.add("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._globalScope.addIfaceGlobalNames("FakeTestPrimaryGlobal", ["FakeTestPrimaryGlobal"])
|
||||
|
||||
self._installBuiltins(self._globalScope)
|
||||
self._productions = []
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
--- WebIDL.py
|
||||
+++ WebIDL.py
|
||||
@@ -1744,7 +1744,8 @@
|
||||
@@ -1786,7 +1786,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
||||
identifier == "ProbablyShortLivingWrapper" or
|
||||
identifier == "LegacyUnenumerableNamedProperties" or
|
||||
identifier == "RunConstructorInCallerCompartment" or
|
||||
identifier == "WantsEventListenerHooks" or
|
||||
- identifier == "NonOrdinaryGetPrototypeOf"):
|
||||
+ identifier == "NonOrdinaryGetPrototypeOf" or
|
||||
- identifier == "WantsEventListenerHooks"):
|
||||
+ identifier == "WantsEventListenerHooks" or
|
||||
+ identifier == "Abstract"):
|
||||
# Known extended attributes that do not take values
|
||||
if not attr.noArguments():
|
||||
raise WebIDLError("[%s] must take no arguments" % identifier,
|
||||
raise WebIDLError("[%s] must take no arguments" % identifier,
|
|
@ -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
|
||||
@@ -2170,7 +2170,7 @@ class IDLUnresolvedType(IDLType):
|
||||
@@ -2275,7 +2275,7 @@ class IDLUnresolvedType(IDLType):
|
||||
return typedefType.complete(scope)
|
||||
elif obj.isCallback() and not obj.isInterface():
|
||||
assert self.name.name == obj.identifier.name
|
||||
- return IDLCallbackType(self.location, obj)
|
||||
+ return IDLCallbackType(obj.location, obj)
|
||||
|
||||
if self._promiseInnerType and not self._promiseInnerType.isComplete():
|
||||
self._promiseInnerType = self._promiseInnerType.complete(scope)
|
||||
@@ -6521,7 +6521,7 @@ class Parser(Tokenizer):
|
||||
|
||||
name = self.name.resolve(scope, None)
|
||||
return IDLWrapperType(self.location, obj)
|
||||
@@ -6688,7 +6688,7 @@ class Parser(Tokenizer):
|
||||
type = IDLTypedefType(self.getLocation(p, 1), obj.innerType,
|
||||
obj.identifier.name)
|
||||
elif obj.isCallback() and not obj.isInterface():
|
||||
|
@ -19,4 +17,4 @@ index da32340..81c52b7 100644
|
|||
+ type = IDLCallbackType(obj.location, obj)
|
||||
else:
|
||||
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
|
||||
@@ -6823,7 +6823,8 @@ class Parser(Tokenizer):
|
||||
@@ -6959,7 +6959,8 @@ class Parser(Tokenizer):
|
||||
self.parser = yacc.yacc(module=self,
|
||||
outputdir=outputdir,
|
||||
tabmodule='webidlyacc',
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
--- WebIDL.py
|
||||
+++ WebIDL.py
|
||||
@@ -1695,7 +1695,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
||||
identifier == "ProbablyShortLivingObject" or
|
||||
@@ -1787,7 +1787,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
||||
identifier == "LegacyUnenumerableNamedProperties" or
|
||||
identifier == "NonOrdinaryGetPrototypeOf" or
|
||||
identifier == "RunConstructorInCallerCompartment" or
|
||||
identifier == "WantsEventListenerHooks" or
|
||||
- identifier == "Abstract"):
|
||||
+ identifier == "Abstract" or
|
||||
+ identifier == "Inline"):
|
||||
|
|
|
@ -26,6 +26,31 @@ def WebIDLTest(parser, harness):
|
|||
harness.check(dict2.members[1].identifier.name, "child",
|
||||
"'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
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
|
@ -42,6 +67,24 @@ def WebIDLTest(parser, harness):
|
|||
|
||||
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
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# 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
|
||||
# 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):
|
||||
parser = parser.reset();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# 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
|
||||
# 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):
|
||||
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
|
||||
@@ -2481,10 +2481,18 @@ class IDLUnionType(IDLType):
|
||||
@@ -2613,10 +2613,18 @@ class IDLUnionType(IDLType):
|
||||
return type.name
|
||||
|
||||
for (i, type) in enumerate(self.memberTypes):
|
||||
- if not type.isComplete():
|
||||
+ # Exclude typedefs because if given "typedef (B or C) test",
|
||||
+ # we want AOrTest, not AOrBOrC
|
||||
+ if not type.isComplete() and not isinstance(type, IDLTypedefType):
|
||||
+ self.memberTypes[i] = type.complete(scope)
|
||||
+
|
||||
+ self.name = "Or".join(typeName(type) for type in self.memberTypes)
|
||||
self.memberTypes[i] = type.complete(scope)
|
||||
|
||||
self.name = "Or".join(typeName(type) for type in self.memberTypes)
|
||||
+
|
||||
+ # We do this again to complete the typedef types
|
||||
+ for (i, type) in enumerate(self.memberTypes):
|
||||
if not type.isComplete():
|
||||
self.memberTypes[i] = type.complete(scope)
|
||||
|
||||
- self.name = "Or".join(typeName(type) for type in self.memberTypes)
|
||||
+ if not type.isComplete():
|
||||
+ self.memberTypes[i] = type.complete(scope)
|
||||
+
|
||||
self.flatMemberTypes = list(self.memberTypes)
|
||||
i = 0
|
||||
while i < len(self.flatMemberTypes):
|
||||
|
|
|
@ -5,6 +5,7 @@ patch < pref-main-thread.patch
|
|||
patch < callback-location.patch
|
||||
patch < union-typedef.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
|
||||
rm -r tests
|
||||
|
|
|
@ -1,26 +1,25 @@
|
|||
--- WebIDL.py
|
||||
+++ WebIDL.py
|
||||
@@ -1239,12 +1239,6 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||
alias,
|
||||
[member.location, m.location])
|
||||
@@ -1362,12 +1362,6 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
|
||||
for bindingAlias in member.bindingAliases:
|
||||
checkDuplicateNames(member, bindingAlias, "BindingAlias")
|
||||
|
||||
- if (self.getExtendedAttribute("Pref") and
|
||||
- self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
|
||||
- raise WebIDLError("[Pref] used on an interface that is not %s-only" %
|
||||
- self.parentScope.primaryGlobalName,
|
||||
-
|
||||
- if self.getExtendedAttribute("Pref") and self.isExposedOffMainThread():
|
||||
- raise WebIDLError("[Pref] used on an interface that is not "
|
||||
- "main-thread-only",
|
||||
- [self.location])
|
||||
-
|
||||
# Conditional exposure makes no sense for interfaces with no
|
||||
# interface object, unless they're navigator properties.
|
||||
# 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)
|
||||
|
||||
def validate(self):
|
||||
- if (self.getExtendedAttribute("Pref") and
|
||||
- self.exposureSet != set([self._globalScope.primaryGlobalName])):
|
||||
- if self.getExtendedAttribute("Pref") and self.isExposedOffMainThread():
|
||||
- raise WebIDLError("[Pref] used on an interface member that is not "
|
||||
- "%s-only" % self._globalScope.primaryGlobalName,
|
||||
- "main-thread-only",
|
||||
- [self.location])
|
||||
-
|
||||
if self.isAttr() or self.isMethod():
|
Loading…
Add table
Add a link
Reference in a new issue