mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 832014 part 1. Add parser support for an [Unforgeable] annotation on WebIDL interfaces. r=peterv
This commit is contained in:
parent
317399940c
commit
ee5c456d8a
@ -669,8 +669,36 @@ class IDLInterface(IDLObjectWithScope):
|
||||
for ancestorConsequential in ancestor.getConsequentialInterfaces():
|
||||
ancestorConsequential.interfacesBasedOnSelf.add(self)
|
||||
|
||||
# Deal with interfaces marked [Unforgeable], now that we have our full
|
||||
# member list, except unforgeables pulled in from parents. We want to
|
||||
# do this before we set "originatingInterface" on our unforgeable
|
||||
# members.
|
||||
if self.getExtendedAttribute("Unforgeable"):
|
||||
# Check that the interface already has all the things the
|
||||
# spec would otherwise require us to synthesize and is
|
||||
# missing the ones we plan to synthesize.
|
||||
if not any(m.isMethod() and m.isStringifier() for m in self.members):
|
||||
raise WebIDLError("Unforgeable interface %s does not have a "
|
||||
"stringifier" % self.identifier.name,
|
||||
[self.location])
|
||||
|
||||
for m in self.members:
|
||||
if ((m.isMethod() and m.isJsonifier()) or
|
||||
m.identifier.name == "toJSON"):
|
||||
raise WebIDLError("Unforgeable interface %s has a "
|
||||
"jsonifier so we won't be able to add "
|
||||
"one ourselves" % self.identifier.name,
|
||||
[self.location, m.location])
|
||||
|
||||
if m.identifier.name == "valueOf" and not m.isStatic():
|
||||
raise WebIDLError("Unforgeable interface %s has a valueOf "
|
||||
"member so we won't be able to add one "
|
||||
"ourselves" % self.identifier.name,
|
||||
[self.location, m.location])
|
||||
|
||||
for member in self.members:
|
||||
if (member.isAttr() and member.isUnforgeable() and
|
||||
if ((member.isAttr() or member.isMethod()) and
|
||||
member.isUnforgeable() and
|
||||
not hasattr(member, "originatingInterface")):
|
||||
member.originatingInterface = self
|
||||
|
||||
@ -693,16 +721,16 @@ class IDLInterface(IDLObjectWithScope):
|
||||
# worry about anything other than our parent, because it has already
|
||||
# imported its ancestors unforgeable attributes into its member
|
||||
# list.
|
||||
for unforgeableAttr in (attr for attr in self.parent.members if
|
||||
attr.isAttr() and not attr.isStatic() and
|
||||
attr.isUnforgeable()):
|
||||
for unforgeableMember in (member for member in self.parent.members if
|
||||
(member.isAttr() or member.isMethod()) and
|
||||
member.isUnforgeable()):
|
||||
shadows = [ m for m in self.members if
|
||||
(m.isAttr() or m.isMethod()) and
|
||||
not m.isStatic() and
|
||||
m.identifier.name == unforgeableAttr.identifier.name ]
|
||||
m.identifier.name == unforgeableMember.identifier.name ]
|
||||
if len(shadows) != 0:
|
||||
locs = [unforgeableAttr.location] + [ s.location for s
|
||||
in shadows ]
|
||||
locs = [unforgeableMember.location] + [ s.location for s
|
||||
in shadows ]
|
||||
raise WebIDLError("Interface %s shadows [Unforgeable] "
|
||||
"members of %s" %
|
||||
(self.identifier.name,
|
||||
@ -711,10 +739,10 @@ class IDLInterface(IDLObjectWithScope):
|
||||
# And now just stick it in our members, since we won't be
|
||||
# inheriting this down the proto chain. If we really cared we
|
||||
# could try to do something where we set up the unforgeable
|
||||
# attributes of ancestor interfaces, with their corresponding
|
||||
# getters, on our interface, but that gets pretty complicated
|
||||
# and seems unnecessary.
|
||||
self.members.append(unforgeableAttr)
|
||||
# attributes/methods of ancestor interfaces, with their
|
||||
# corresponding getters, on our interface, but that gets pretty
|
||||
# complicated and seems unnecessary.
|
||||
self.members.append(unforgeableMember)
|
||||
|
||||
# Ensure that there's at most one of each {named,indexed}
|
||||
# {getter,setter,creator,deleter}, at most one stringifier,
|
||||
@ -785,6 +813,26 @@ class IDLInterface(IDLObjectWithScope):
|
||||
parent = parent.parent
|
||||
|
||||
def validate(self):
|
||||
# We don't support consequential unforgeable interfaces. Need to check
|
||||
# this here, becaue in finish() an interface might not know yet that
|
||||
# it's consequential.
|
||||
if self.getExtendedAttribute("Unforgeable") and self.isConsequential():
|
||||
raise WebIDLError(
|
||||
"%s is an unforgeable consequential interface" %
|
||||
self.identifier.name,
|
||||
[self.location] +
|
||||
list(i.location for i in
|
||||
(self.interfacesBasedOnSelf - { self }) ))
|
||||
|
||||
# We also don't support inheriting from unforgeable interfaces.
|
||||
if self.getExtendedAttribute("Unforgeable") and self.hasChildInterfaces():
|
||||
raise WebIDLError("%s is an unforgeable ancestor interface" %
|
||||
self.identifier.name,
|
||||
[self.location] +
|
||||
list(i.location for i in
|
||||
self.interfacesBasedOnSelf if i.parent == self))
|
||||
|
||||
|
||||
for member in self.members:
|
||||
member.validate()
|
||||
|
||||
@ -992,6 +1040,7 @@ class IDLInterface(IDLObjectWithScope):
|
||||
elif (identifier == "NeedNewResolve" or
|
||||
identifier == "OverrideBuiltins" or
|
||||
identifier == "ChromeOnly" or
|
||||
identifier == "Unforgeable" or
|
||||
identifier == "LegacyEventInit"):
|
||||
# Known extended attributes that do not take values
|
||||
if not attr.noArguments():
|
||||
@ -2889,9 +2938,6 @@ class IDLAttribute(IDLInterfaceMember):
|
||||
[attr.location, self.location])
|
||||
self.lenientThis = True
|
||||
elif identifier == "Unforgeable":
|
||||
if not self.readonly:
|
||||
raise WebIDLError("[Unforgeable] is only allowed on readonly "
|
||||
"attributes", [attr.location, self.location])
|
||||
if self.isStatic():
|
||||
raise WebIDLError("[Unforgeable] is only allowed on non-static "
|
||||
"attributes", [attr.location, self.location])
|
||||
|
@ -79,6 +79,25 @@ def WebIDLTest(parser, harness):
|
||||
"Should have thrown when shadowing unforgeable attribute on "
|
||||
"parent with operation.")
|
||||
|
||||
parser = parser.reset();
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Child : Parent {
|
||||
void foo();
|
||||
};
|
||||
interface Parent {
|
||||
[Unforgeable] void foo();
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
harness.ok(threw,
|
||||
"Should have thrown when shadowing unforgeable operation on "
|
||||
"parent with operation.")
|
||||
|
||||
parser = parser.reset();
|
||||
threw = False
|
||||
try:
|
||||
@ -98,6 +117,25 @@ def WebIDLTest(parser, harness):
|
||||
"Should have thrown when shadowing unforgeable attribute on "
|
||||
"parent with attribute.")
|
||||
|
||||
parser = parser.reset();
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface Child : Parent {
|
||||
attribute short foo;
|
||||
};
|
||||
interface Parent {
|
||||
[Unforgeable] void foo();
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except Exception,x:
|
||||
threw = True
|
||||
harness.ok(threw,
|
||||
"Should have thrown when shadowing unforgeable operation on "
|
||||
"parent with attribute.")
|
||||
|
||||
parser = parser.reset();
|
||||
parser.parse("""
|
||||
interface Child : Parent {
|
||||
@ -166,16 +204,38 @@ def WebIDLTest(parser, harness):
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface iface {
|
||||
[Unforgeable] attribute long foo;
|
||||
interface Child : Parent {
|
||||
};
|
||||
interface Parent : GrandParent {};
|
||||
interface GrandParent {};
|
||||
interface Consequential {
|
||||
[Unforgeable] void foo();
|
||||
};
|
||||
GrandParent implements Consequential;
|
||||
interface ChildConsequential {
|
||||
void foo();
|
||||
};
|
||||
Child implements ChildConsequential;
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown for writable [Unforgeable] attribute.")
|
||||
harness.ok(threw,
|
||||
"Should have thrown when our consequential interface shadows unforgeable operation "
|
||||
"of ancestor's consequential interface.")
|
||||
|
||||
parser = parser.reset();
|
||||
parser.parse("""
|
||||
interface iface {
|
||||
[Unforgeable] attribute long foo;
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
harness.check(len(results), 1,
|
||||
"Should allow writable [Unforgeable] attribute.")
|
||||
|
||||
parser = parser.reset();
|
||||
threw = False
|
||||
|
@ -11,8 +11,7 @@
|
||||
* and create derivative works of this document.
|
||||
*/
|
||||
|
||||
// No support for [Unforgeable] on interfaces yet
|
||||
//[Unforgeable]
|
||||
[Unforgeable]
|
||||
interface Location {
|
||||
void assign(DOMString url);
|
||||
void replace(DOMString url);
|
||||
|
Loading…
Reference in New Issue
Block a user