mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Update the WebIDL parser
This commit is contained in:
parent
aa8c835d3b
commit
c9af465ae8
7 changed files with 244 additions and 56 deletions
|
@ -578,8 +578,8 @@ class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
|
||||||
def isProbablyShortLivingObject(self):
|
def isProbablyShortLivingObject(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def getNavigatorProperty(self):
|
def isNavigatorProperty(self):
|
||||||
return None
|
return False
|
||||||
|
|
||||||
def _getDependentObjects(self):
|
def _getDependentObjects(self):
|
||||||
return set()
|
return set()
|
||||||
|
@ -1078,11 +1078,22 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
|
|
||||||
specialMembersSeen[memberType] = member
|
specialMembersSeen[memberType] = member
|
||||||
|
|
||||||
if (self.getExtendedAttribute("LegacyUnenumerableNamedProperties") and
|
if self.getExtendedAttribute("LegacyUnenumerableNamedProperties"):
|
||||||
"named getters" not in specialMembersSeen):
|
# Check that we have a named getter.
|
||||||
raise WebIDLError("[LegacyUnenumerableNamedProperties] used on an interface "
|
if "named getters" not in specialMembersSeen:
|
||||||
"without a named getter",
|
raise WebIDLError(
|
||||||
[self.location])
|
"Interface with [LegacyUnenumerableNamedProperties] does "
|
||||||
|
"not have a named getter",
|
||||||
|
[self.location])
|
||||||
|
ancestor = self.parent
|
||||||
|
while ancestor:
|
||||||
|
if ancestor.getExtendedAttribute("LegacyUnenumerableNamedProperties"):
|
||||||
|
raise WebIDLError(
|
||||||
|
"Interface with [LegacyUnenumerableNamedProperties] "
|
||||||
|
"inherits from another interface with "
|
||||||
|
"[LegacyUnenumerableNamedProperties]",
|
||||||
|
[self.location, ancestor.location])
|
||||||
|
ancestor = ancestor.parent
|
||||||
|
|
||||||
if self._isOnGlobalProtoChain:
|
if self._isOnGlobalProtoChain:
|
||||||
# Make sure we have no named setters, creators, or deleters
|
# Make sure we have no named setters, creators, or deleters
|
||||||
|
@ -1246,7 +1257,7 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
# interface object, unless they're navigator properties.
|
# interface object, unless they're navigator properties.
|
||||||
if (self.isExposedConditionally() and
|
if (self.isExposedConditionally() and
|
||||||
not self.hasInterfaceObject() and
|
not self.hasInterfaceObject() and
|
||||||
not self.getNavigatorProperty()):
|
not self.isNavigatorProperty()):
|
||||||
raise WebIDLError("Interface with no interface object is "
|
raise WebIDLError("Interface with no interface object is "
|
||||||
"exposed conditionally",
|
"exposed conditionally",
|
||||||
[self.location])
|
[self.location])
|
||||||
|
@ -1471,8 +1482,9 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
identifier == "UnsafeInPrerendering" or
|
identifier == "UnsafeInPrerendering" or
|
||||||
identifier == "LegacyEventInit" or
|
identifier == "LegacyEventInit" or
|
||||||
identifier == "ProbablyShortLivingObject" or
|
identifier == "ProbablyShortLivingObject" or
|
||||||
identifier == "Abstract" or
|
identifier == "LegacyUnenumerableNamedProperties" or
|
||||||
identifier == "LegacyUnenumerableNamedProperties"):
|
identifier == "NonOrdinaryGetPrototypeOf" or
|
||||||
|
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():
|
||||||
raise WebIDLError("[%s] must take no arguments" % identifier,
|
raise WebIDLError("[%s] must take no arguments" % identifier,
|
||||||
|
@ -1594,6 +1606,15 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
current = current.parent
|
current = current.parent
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def isNavigatorProperty(self):
|
||||||
|
naviProp = self.getExtendedAttribute("NavigatorProperty")
|
||||||
|
if not naviProp:
|
||||||
|
return False
|
||||||
|
assert len(naviProp) == 1
|
||||||
|
assert isinstance(naviProp, list)
|
||||||
|
assert len(naviProp[0]) != 0
|
||||||
|
return True
|
||||||
|
|
||||||
def getNavigatorProperty(self):
|
def getNavigatorProperty(self):
|
||||||
naviProp = self.getExtendedAttribute("NavigatorProperty")
|
naviProp = self.getExtendedAttribute("NavigatorProperty")
|
||||||
if not naviProp:
|
if not naviProp:
|
||||||
|
@ -1601,7 +1622,22 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
assert len(naviProp) == 1
|
assert len(naviProp) == 1
|
||||||
assert isinstance(naviProp, list)
|
assert isinstance(naviProp, list)
|
||||||
assert len(naviProp[0]) != 0
|
assert len(naviProp[0]) != 0
|
||||||
return naviProp[0]
|
conditionExtendedAttributes = self._extendedAttrDict.viewkeys() & IDLInterface.conditionExtendedAttributes
|
||||||
|
attr = IDLAttribute(self.location,
|
||||||
|
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), naviProp[0]),
|
||||||
|
IDLUnresolvedType(self.location, IDLUnresolvedIdentifier(self.location, self.identifier.name)),
|
||||||
|
True,
|
||||||
|
extendedAttrDict={ a: self._extendedAttrDict[a] for a in conditionExtendedAttributes },
|
||||||
|
navigatorObjectGetter=True)
|
||||||
|
attr._exposureGlobalNames = self._exposureGlobalNames
|
||||||
|
# We're abusing Constant a little bit here, because we need Cached. The
|
||||||
|
# getter will create a new object every time, but we're never going to
|
||||||
|
# clear the cached value.
|
||||||
|
extendedAttrs = [ IDLExtendedAttribute(self.location, ("Throws", )),
|
||||||
|
IDLExtendedAttribute(self.location, ("Cached", )),
|
||||||
|
IDLExtendedAttribute(self.location, ("Constant", )) ]
|
||||||
|
attr.addExtendedAttributes(extendedAttrs)
|
||||||
|
return attr
|
||||||
|
|
||||||
def hasChildInterfaces(self):
|
def hasChildInterfaces(self):
|
||||||
return self._hasChildInterfaces
|
return self._hasChildInterfaces
|
||||||
|
@ -1619,13 +1655,11 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
def hasMembersInSlots(self):
|
def hasMembersInSlots(self):
|
||||||
return self._ownMembersInSlots != 0
|
return self._ownMembersInSlots != 0
|
||||||
|
|
||||||
|
conditionExtendedAttributes = [ "Pref", "ChromeOnly", "Func", "AvailableIn",
|
||||||
|
"CheckAnyPermissions",
|
||||||
|
"CheckAllPermissions" ]
|
||||||
def isExposedConditionally(self):
|
def isExposedConditionally(self):
|
||||||
return (self.getExtendedAttribute("Pref") or
|
return any(self.getExtendedAttribute(a) for a in self.conditionExtendedAttributes)
|
||||||
self.getExtendedAttribute("ChromeOnly") or
|
|
||||||
self.getExtendedAttribute("Func") or
|
|
||||||
self.getExtendedAttribute("AvailableIn") or
|
|
||||||
self.getExtendedAttribute("CheckAnyPermissions") or
|
|
||||||
self.getExtendedAttribute("CheckAllPermissions"))
|
|
||||||
|
|
||||||
|
|
||||||
class IDLDictionary(IDLObjectWithScope):
|
class IDLDictionary(IDLObjectWithScope):
|
||||||
|
@ -3380,11 +3414,14 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
|
||||||
AffectsValues = ("Nothing", "Everything")
|
AffectsValues = ("Nothing", "Everything")
|
||||||
DependsOnValues = ("Nothing", "DOMState", "DeviceState", "Everything")
|
DependsOnValues = ("Nothing", "DOMState", "DeviceState", "Everything")
|
||||||
|
|
||||||
def __init__(self, location, identifier, tag):
|
def __init__(self, location, identifier, tag, extendedAttrDict=None):
|
||||||
IDLObjectWithIdentifier.__init__(self, location, None, identifier)
|
IDLObjectWithIdentifier.__init__(self, location, None, identifier)
|
||||||
IDLExposureMixins.__init__(self, location)
|
IDLExposureMixins.__init__(self, location)
|
||||||
self.tag = tag
|
self.tag = tag
|
||||||
self._extendedAttrDict = {}
|
if extendedAttrDict is None:
|
||||||
|
self._extendedAttrDict = {}
|
||||||
|
else:
|
||||||
|
self._extendedAttrDict = extendedAttrDict
|
||||||
|
|
||||||
def isMethod(self):
|
def isMethod(self):
|
||||||
return self.tag == IDLInterfaceMember.Tags.Method
|
return self.tag == IDLInterfaceMember.Tags.Method
|
||||||
|
@ -3868,9 +3905,11 @@ class IDLConst(IDLInterfaceMember):
|
||||||
|
|
||||||
class IDLAttribute(IDLInterfaceMember):
|
class IDLAttribute(IDLInterfaceMember):
|
||||||
def __init__(self, location, identifier, type, readonly, inherit=False,
|
def __init__(self, location, identifier, type, readonly, inherit=False,
|
||||||
static=False, stringifier=False, maplikeOrSetlike=None):
|
static=False, stringifier=False, maplikeOrSetlike=None,
|
||||||
|
extendedAttrDict=None, navigatorObjectGetter=False):
|
||||||
IDLInterfaceMember.__init__(self, location, identifier,
|
IDLInterfaceMember.__init__(self, location, identifier,
|
||||||
IDLInterfaceMember.Tags.Attr)
|
IDLInterfaceMember.Tags.Attr,
|
||||||
|
extendedAttrDict=extendedAttrDict)
|
||||||
|
|
||||||
assert isinstance(type, IDLType)
|
assert isinstance(type, IDLType)
|
||||||
self.type = type
|
self.type = type
|
||||||
|
@ -3887,6 +3926,7 @@ class IDLAttribute(IDLInterfaceMember):
|
||||||
self.maplikeOrSetlike = maplikeOrSetlike
|
self.maplikeOrSetlike = maplikeOrSetlike
|
||||||
self.dependsOn = "Everything"
|
self.dependsOn = "Everything"
|
||||||
self.affects = "Everything"
|
self.affects = "Everything"
|
||||||
|
self.navigatorObjectGetter = navigatorObjectGetter
|
||||||
|
|
||||||
if static and identifier.name == "prototype":
|
if static and identifier.name == "prototype":
|
||||||
raise WebIDLError("The identifier of a static attribute must not be 'prototype'",
|
raise WebIDLError("The identifier of a static attribute must not be 'prototype'",
|
||||||
|
@ -4041,6 +4081,24 @@ class IDLAttribute(IDLInterfaceMember):
|
||||||
raise WebIDLError("[PutForwards] and [Replaceable] can't both "
|
raise WebIDLError("[PutForwards] and [Replaceable] can't both "
|
||||||
"appear on the same attribute",
|
"appear on the same attribute",
|
||||||
[attr.location, self.location])
|
[attr.location, self.location])
|
||||||
|
elif identifier == "LenientSetter":
|
||||||
|
if not attr.noArguments():
|
||||||
|
raise WebIDLError("[LenientSetter] must take no arguments",
|
||||||
|
[attr.location])
|
||||||
|
if not self.readonly:
|
||||||
|
raise WebIDLError("[LenientSetter] is only allowed on readonly "
|
||||||
|
"attributes", [attr.location, self.location])
|
||||||
|
if self.isStatic():
|
||||||
|
raise WebIDLError("[LenientSetter] is only allowed on non-static "
|
||||||
|
"attributes", [attr.location, self.location])
|
||||||
|
if self.getExtendedAttribute("PutForwards") is not None:
|
||||||
|
raise WebIDLError("[LenientSetter] and [PutForwards] can't both "
|
||||||
|
"appear on the same attribute",
|
||||||
|
[attr.location, self.location])
|
||||||
|
if self.getExtendedAttribute("Replaceable") is not None:
|
||||||
|
raise WebIDLError("[LenientSetter] and [Replaceable] can't both "
|
||||||
|
"appear on the same attribute",
|
||||||
|
[attr.location, self.location])
|
||||||
elif identifier == "LenientFloat":
|
elif identifier == "LenientFloat":
|
||||||
if self.readonly:
|
if self.readonly:
|
||||||
raise WebIDLError("[LenientFloat] used on a readonly attribute",
|
raise WebIDLError("[LenientFloat] used on a readonly attribute",
|
||||||
|
@ -4116,6 +4174,14 @@ class IDLAttribute(IDLInterfaceMember):
|
||||||
raise WebIDLError("[UseCounter] must not be used on a "
|
raise WebIDLError("[UseCounter] must not be used on a "
|
||||||
"stringifier attribute",
|
"stringifier attribute",
|
||||||
[attr.location, self.location])
|
[attr.location, self.location])
|
||||||
|
elif identifier == "Unscopable":
|
||||||
|
if not attr.noArguments():
|
||||||
|
raise WebIDLError("[Unscopable] must take no arguments",
|
||||||
|
[attr.location])
|
||||||
|
if self.isStatic():
|
||||||
|
raise WebIDLError("[Unscopable] is only allowed on non-static "
|
||||||
|
"attributes and operations",
|
||||||
|
[attr.location, self.location])
|
||||||
elif (identifier == "Pref" or
|
elif (identifier == "Pref" or
|
||||||
identifier == "Deprecated" or
|
identifier == "Deprecated" or
|
||||||
identifier == "SetterThrows" or
|
identifier == "SetterThrows" or
|
||||||
|
@ -4771,6 +4837,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||||
elif identifier == "PutForwards":
|
elif identifier == "PutForwards":
|
||||||
raise WebIDLError("Only attributes support [PutForwards]",
|
raise WebIDLError("Only attributes support [PutForwards]",
|
||||||
[attr.location, self.location])
|
[attr.location, self.location])
|
||||||
|
elif identifier == "LenientSetter":
|
||||||
|
raise WebIDLError("Only attributes support [LenientSetter]",
|
||||||
|
[attr.location, self.location])
|
||||||
elif identifier == "LenientFloat":
|
elif identifier == "LenientFloat":
|
||||||
# This is called before we've done overload resolution
|
# This is called before we've done overload resolution
|
||||||
assert len(self.signatures()) == 1
|
assert len(self.signatures()) == 1
|
||||||
|
@ -4816,6 +4885,14 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||||
raise WebIDLError("[UseCounter] must not be used on a special "
|
raise WebIDLError("[UseCounter] must not be used on a special "
|
||||||
"operation",
|
"operation",
|
||||||
[attr.location, self.location])
|
[attr.location, self.location])
|
||||||
|
elif identifier == "Unscopable":
|
||||||
|
if not attr.noArguments():
|
||||||
|
raise WebIDLError("[Unscopable] must take no arguments",
|
||||||
|
[attr.location])
|
||||||
|
if self.isStatic():
|
||||||
|
raise WebIDLError("[Unscopable] is only allowed on non-static "
|
||||||
|
"attributes and operations",
|
||||||
|
[attr.location, self.location])
|
||||||
elif (identifier == "Throws" or
|
elif (identifier == "Throws" or
|
||||||
identifier == "NewObject" or
|
identifier == "NewObject" or
|
||||||
identifier == "ChromeOnly" or
|
identifier == "ChromeOnly" or
|
||||||
|
@ -5098,10 +5175,11 @@ class SqueakyCleanLogger(object):
|
||||||
info = debug
|
info = debug
|
||||||
|
|
||||||
def warning(self, msg, *args, **kwargs):
|
def warning(self, msg, *args, **kwargs):
|
||||||
if msg == "%s:%d: Rule '%s' defined, but not used":
|
if msg == "%s:%d: Rule %r defined, but not used" or \
|
||||||
|
msg == "%s:%d: Rule '%s' defined, but not used":
|
||||||
# Munge things so we don't have to hardcode filenames and
|
# Munge things so we don't have to hardcode filenames and
|
||||||
# line numbers in our whitelist.
|
# line numbers in our whitelist.
|
||||||
whitelistmsg = "Rule '%s' defined, but not used"
|
whitelistmsg = "Rule %r defined, but not used"
|
||||||
whitelistargs = args[2:]
|
whitelistargs = args[2:]
|
||||||
else:
|
else:
|
||||||
whitelistmsg = msg
|
whitelistmsg = msg
|
||||||
|
@ -6588,11 +6666,26 @@ class Parser(Tokenizer):
|
||||||
def finish(self):
|
def finish(self):
|
||||||
# If we have interfaces that are iterable, create their
|
# If we have interfaces that are iterable, create their
|
||||||
# iterator interfaces and add them to the productions array.
|
# iterator interfaces and add them to the productions array.
|
||||||
interfaceStatements = [p for p in self._productions if
|
interfaceStatements = []
|
||||||
isinstance(p, IDLInterface)]
|
for p in self._productions:
|
||||||
|
if isinstance(p, IDLInterface):
|
||||||
|
interfaceStatements.append(p)
|
||||||
|
if p.identifier.name == "Navigator":
|
||||||
|
navigatorInterface = p
|
||||||
|
|
||||||
iterableIteratorIface = None
|
iterableIteratorIface = None
|
||||||
for iface in interfaceStatements:
|
for iface in interfaceStatements:
|
||||||
|
navigatorProperty = iface.getNavigatorProperty()
|
||||||
|
if navigatorProperty:
|
||||||
|
# We're generating a partial interface to add a readonly
|
||||||
|
# property to the Navigator interface for every interface
|
||||||
|
# annotated with NavigatorProperty.
|
||||||
|
partialInterface = IDLPartialInterface(iface.location,
|
||||||
|
IDLUnresolvedIdentifier(iface.location, "Navigator"),
|
||||||
|
[ navigatorProperty ],
|
||||||
|
navigatorInterface)
|
||||||
|
self._productions.append(partialInterface)
|
||||||
|
|
||||||
iterable = None
|
iterable = None
|
||||||
# We haven't run finish() on the interface yet, so we don't know
|
# We haven't run finish() on the interface yet, so we don't know
|
||||||
# whether our interface is maplike/setlike/iterable or not. This
|
# whether our interface is maplike/setlike/iterable or not. This
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
--- WebIDL.py
|
--- WebIDL.py
|
||||||
+++ WebIDL.py
|
+++ WebIDL.py
|
||||||
@@ -1416,7 +1416,8 @@
|
@@ -1416,7 +1416,8 @@
|
||||||
identifier == "Unforgeable" or
|
|
||||||
identifier == "UnsafeInPrerendering" or
|
|
||||||
identifier == "LegacyEventInit" or
|
identifier == "LegacyEventInit" or
|
||||||
- identifier == "ProbablyShortLivingObject"):
|
identifier == "ProbablyShortLivingObject" or
|
||||||
+ identifier == "ProbablyShortLivingObject" or
|
identifier == "LegacyUnenumerableNamedProperties" or
|
||||||
|
- identifier == "NonOrdinaryGetPrototypeOf"):
|
||||||
|
+ 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,25 +0,0 @@
|
||||||
--- WebIDL.py
|
|
||||||
+++ WebIDL.py
|
|
||||||
@@ -1069,6 +1069,12 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
|
||||||
|
|
||||||
specialMembersSeen[memberType] = member
|
|
||||||
|
|
||||||
+ if (self.getExtendedAttribute("LegacyUnenumerableNamedProperties") and
|
|
||||||
+ "named getters" not in specialMembersSeen):
|
|
||||||
+ raise WebIDLError("[LegacyUnenumerableNamedProperties] used on an interface "
|
|
||||||
+ "without a named getter",
|
|
||||||
+ [self.location])
|
|
||||||
+
|
|
||||||
if self._isOnGlobalProtoChain:
|
|
||||||
# Make sure we have no named setters, creators, or deleters
|
|
||||||
for memberType in ["setter", "creator", "deleter"]:
|
|
||||||
@@ -1417,7 +1423,8 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
|
||||||
identifier == "UnsafeInPrerendering" or
|
|
||||||
identifier == "LegacyEventInit" or
|
|
||||||
identifier == "ProbablyShortLivingObject" or
|
|
||||||
- identifier == "Abstract"):
|
|
||||||
+ identifier == "Abstract" or
|
|
||||||
+ identifier == "LegacyUnenumerableNamedProperties"):
|
|
||||||
# Known extended attributes that do not take values
|
|
||||||
if not attr.noArguments():
|
|
||||||
raise WebIDLError("[%s] must take no arguments" % identifier,
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
# 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 http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
def should_throw(parser, harness, message, code):
|
||||||
|
parser = parser.reset();
|
||||||
|
threw = False
|
||||||
|
try:
|
||||||
|
parser.parse(code)
|
||||||
|
parser.finish()
|
||||||
|
except:
|
||||||
|
threw = True
|
||||||
|
|
||||||
|
harness.ok(threw, "Should have thrown: %s" % message)
|
||||||
|
|
||||||
|
|
||||||
|
def WebIDLTest(parser, harness):
|
||||||
|
# The [LenientSetter] extended attribute MUST take no arguments.
|
||||||
|
should_throw(parser, harness, "no arguments", """
|
||||||
|
interface I {
|
||||||
|
[LenientSetter=X] readonly attribute long A;
|
||||||
|
};
|
||||||
|
""")
|
||||||
|
|
||||||
|
# An attribute with the [LenientSetter] extended attribute MUST NOT
|
||||||
|
# also be declared with the [PutForwards] extended attribute.
|
||||||
|
should_throw(parser, harness, "PutForwards", """
|
||||||
|
interface I {
|
||||||
|
[PutForwards=B, LenientSetter] readonly attribute J A;
|
||||||
|
};
|
||||||
|
interface J {
|
||||||
|
attribute long B;
|
||||||
|
};
|
||||||
|
""")
|
||||||
|
|
||||||
|
# An attribute with the [LenientSetter] extended attribute MUST NOT
|
||||||
|
# also be declared with the [Replaceable] extended attribute.
|
||||||
|
should_throw(parser, harness, "Replaceable", """
|
||||||
|
interface I {
|
||||||
|
[Replaceable, LenientSetter] readonly attribute J A;
|
||||||
|
};
|
||||||
|
""")
|
||||||
|
|
||||||
|
# The [LenientSetter] extended attribute MUST NOT be used on an
|
||||||
|
# attribute that is not read only.
|
||||||
|
should_throw(parser, harness, "writable attribute", """
|
||||||
|
interface I {
|
||||||
|
[LenientSetter] attribute long A;
|
||||||
|
};
|
||||||
|
""")
|
||||||
|
|
||||||
|
# The [LenientSetter] extended attribute MUST NOT be used on a
|
||||||
|
# static attribute.
|
||||||
|
should_throw(parser, harness, "static attribute", """
|
||||||
|
interface I {
|
||||||
|
[LenientSetter] static readonly attribute long A;
|
||||||
|
};
|
||||||
|
""")
|
|
@ -0,0 +1,64 @@
|
||||||
|
def WebIDLTest(parser, harness):
|
||||||
|
|
||||||
|
parser.parse(
|
||||||
|
"""
|
||||||
|
interface Foo {};
|
||||||
|
[LegacyUnenumerableNamedProperties]
|
||||||
|
interface Bar : Foo {
|
||||||
|
getter long(DOMString name);
|
||||||
|
};
|
||||||
|
interface Baz : Bar {
|
||||||
|
getter long(DOMString name);
|
||||||
|
};
|
||||||
|
""");
|
||||||
|
results = parser.finish();
|
||||||
|
harness.check(len(results), 3, "Should have three interfaces")
|
||||||
|
|
||||||
|
parser = parser.reset()
|
||||||
|
threw = False
|
||||||
|
try:
|
||||||
|
parser.parse("""
|
||||||
|
[LegacyUnenumerableNamedProperties]
|
||||||
|
interface NoNamedGetter {
|
||||||
|
};
|
||||||
|
""")
|
||||||
|
|
||||||
|
results = parser.finish()
|
||||||
|
except Exception, x:
|
||||||
|
threw = True
|
||||||
|
harness.ok(threw, "Should have thrown.")
|
||||||
|
|
||||||
|
parser = parser.reset()
|
||||||
|
threw = False
|
||||||
|
try:
|
||||||
|
parser.parse("""
|
||||||
|
[LegacyUnenumerableNamedProperties=Foo]
|
||||||
|
interface ShouldNotHaveArg {
|
||||||
|
getter long(DOMString name);
|
||||||
|
};
|
||||||
|
""")
|
||||||
|
|
||||||
|
results = parser.finish()
|
||||||
|
except Exception, x:
|
||||||
|
threw = True
|
||||||
|
harness.ok(threw, "Should have thrown.")
|
||||||
|
|
||||||
|
parser = parser.reset()
|
||||||
|
threw = False
|
||||||
|
try:
|
||||||
|
parser.parse("""
|
||||||
|
[LegacyUnenumerableNamedProperties]
|
||||||
|
interface Foo {
|
||||||
|
getter long(DOMString name);
|
||||||
|
};
|
||||||
|
interface Bar : Foo {};
|
||||||
|
[LegacyUnenumerableNamedProperties]
|
||||||
|
interface Baz : Bar {
|
||||||
|
getter long(DOMString name);
|
||||||
|
};
|
||||||
|
""")
|
||||||
|
|
||||||
|
results = parser.finish()
|
||||||
|
except Exception, x:
|
||||||
|
threw = True
|
||||||
|
harness.ok(threw, "Should have thrown.")
|
|
@ -1,7 +1,6 @@
|
||||||
wget https://mxr.mozilla.org/mozilla-central/source/dom/bindings/parser/WebIDL.py?raw=1 -O WebIDL.py
|
wget https://mxr.mozilla.org/mozilla-central/source/dom/bindings/parser/WebIDL.py?raw=1 -O WebIDL.py
|
||||||
patch < abstract.patch
|
patch < abstract.patch
|
||||||
patch < debug.patch
|
patch < debug.patch
|
||||||
patch < legacy-unenumerable-named-properties.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
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#htmlformcontrolscollection
|
// https://html.spec.whatwg.org/multipage/#htmlformcontrolscollection
|
||||||
[LegacyUnenumerableNamedProperties]
|
|
||||||
interface HTMLFormControlsCollection : HTMLCollection {
|
interface HTMLFormControlsCollection : HTMLCollection {
|
||||||
// inherits length and item()
|
// inherits length and item()
|
||||||
getter (RadioNodeList or Element)? namedItem(DOMString name); // shadows inherited namedItem()
|
getter (RadioNodeList or Element)? namedItem(DOMString name); // shadows inherited namedItem()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue