Bug 1400139 part 1. Add infrastructure for marking WebIDL interface members as non-enumerable. r=qdot

MozReview-Commit-ID: 9F0ZNverS63
This commit is contained in:
Boris Zbarsky 2017-09-18 21:24:37 -04:00
Родитель 82a08c647e
Коммит 005450266e
6 изменённых файлов: 56 добавлений и 19 удалений

Просмотреть файл

@ -2361,6 +2361,12 @@ def IDLToCIdentifier(name):
return name.replace("-", "_")
def EnumerabilityFlags(member):
if member.getExtendedAttribute("NonEnumerable"):
return "0"
return "JSPROP_ENUMERATE"
class MethodDefiner(PropertyDefiner):
"""
A class for defining methods on a prototype object.
@ -2421,18 +2427,11 @@ class MethodDefiner(PropertyDefiner):
})
continue
# Iterable methods should be enumerable, maplike/setlike methods
# should not.
isMaplikeOrSetlikeMethod = (m.isMaplikeOrSetlikeOrIterableMethod() and
(m.maplikeOrSetlikeOrIterable.isMaplike() or
m.maplikeOrSetlikeOrIterable.isSetlike()))
method = {
"name": m.identifier.name,
"methodInfo": not m.isStatic(),
"length": methodLength(m),
# Methods generated for a maplike/setlike declaration are not
# enumerable.
"flags": "JSPROP_ENUMERATE" if not isMaplikeOrSetlikeMethod else "0",
"flags": EnumerabilityFlags(m),
"condition": PropertyDefiner.getControllingCondition(m, descriptor),
"allowCrossOriginThis": m.getExtendedAttribute("CrossOriginCallable"),
"returnsPromise": m.returnsPromise(),
@ -2728,9 +2727,7 @@ class AttrDefiner(PropertyDefiner):
def flags(attr):
unforgeable = " | JSPROP_PERMANENT" if self.unforgeable else ""
# Attributes generated as part of a maplike/setlike declaration are
# not enumerable.
enumerable = " | JSPROP_ENUMERATE" if not attr.isMaplikeOrSetlikeAttr() else ""
enumerable = " | %s" % EnumerabilityFlags(attr)
return ("JSPROP_SHARED" + enumerable + unforgeable)
def getter(attr):

Просмотреть файл

@ -3703,6 +3703,11 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
if isIteratorAlias:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("Alias", "@@iterator"))])
# Methods generated for iterables should be enumerable, but the ones for
# maplike/setlike should not be.
if not self.isIterable():
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("NonEnumerable",))])
members.append(method)
def resolve(self, parentScope):
@ -3826,11 +3831,15 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
specification during parsing.
"""
# Both maplike and setlike have a size attribute
members.append(IDLAttribute(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), "size"),
BuiltinTypes[IDLBuiltinType.Types.unsigned_long],
True,
maplikeOrSetlike=self))
sizeAttr = IDLAttribute(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), "size"),
BuiltinTypes[IDLBuiltinType.Types.unsigned_long],
True,
maplikeOrSetlike=self)
# This should be non-enumerable.
sizeAttr.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("NonEnumerable",))])
members.append(sizeAttr)
self.reserved_ro_names = ["size"]
self.disallowedMemberNames.append("size")
@ -3966,7 +3975,8 @@ class IDLConst(IDLInterfaceMember):
elif (identifier == "Pref" or
identifier == "ChromeOnly" or
identifier == "Func" or
identifier == "SecureContext"):
identifier == "SecureContext" or
identifier == "NonEnumerable"):
# Known attributes that we don't need to do anything with here
pass
else:
@ -4344,7 +4354,8 @@ class IDLAttribute(IDLInterfaceMember):
identifier == "NeedsSubjectPrincipal" or
identifier == "NeedsCallerType" or
identifier == "ReturnValueNeedsContainsHack" or
identifier == "BinaryName"):
identifier == "BinaryName" or
identifier == "NonEnumerable"):
# Known attributes that we don't need to do anything with here
pass
else:
@ -5081,7 +5092,8 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
identifier == "BinaryName" or
identifier == "NeedsSubjectPrincipal" or
identifier == "NeedsCallerType" or
identifier == "StaticClassOverride"):
identifier == "StaticClassOverride" or
identifier == "NonEnumerable"):
# Known attributes that we don't need to do anything with here
pass
else:

Просмотреть файл

@ -978,6 +978,10 @@ public:
int8_t Dashed_attribute();
void Dashed_method();
bool NonEnumerableAttr() const;
void SetNonEnumerableAttr(bool);
void NonEnumerableMethod();
// Methods and properties imported via "implements"
bool ImplementedProperty();
void SetImplementedProperty(bool);

Просмотреть файл

@ -975,6 +975,14 @@ interface TestInterface {
attribute byte dashed-attribute;
void dashed-method();
// [NonEnumerable] tests
[NonEnumerable]
attribute boolean nonEnumerableAttr;
[NonEnumerable]
const boolean nonEnumerableConst = true;
[NonEnumerable]
void nonEnumerableMethod();
// If you add things here, add them to TestExampleGen and TestJSImplGen as well
};

Просмотреть файл

@ -802,6 +802,14 @@ interface TestExampleInterface {
attribute byte dashed-attribute;
void dashed-method();
// [NonEnumerable] tests
[NonEnumerable]
attribute boolean nonEnumerableAttr;
[NonEnumerable]
const boolean nonEnumerableConst = true;
[NonEnumerable]
void nonEnumerableMethod();
// If you add things here, add them to TestCodeGen and TestJSImplGen as well
};

Просмотреть файл

@ -822,6 +822,14 @@ interface TestJSImplInterface {
attribute byte dashed-attribute;
void dashed-method();
// [NonEnumerable] tests
[NonEnumerable]
attribute boolean nonEnumerableAttr;
[NonEnumerable]
const boolean nonEnumerableConst = true;
[NonEnumerable]
void nonEnumerableMethod();
// If you add things here, add them to TestCodeGen as well
};