Skip to content

Commit

Permalink
Bug 1765992 - Support regular and static WebIDL operations with the s…
Browse files Browse the repository at this point in the history
…ame identifier on the same interface. r=edgar

Differential Revision: https://phabricator.services.mozilla.com/D171703
  • Loading branch information
petervanderbeken committed Mar 15, 2023
1 parent 591435a commit dd35b25
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 7 deletions.
53 changes: 51 additions & 2 deletions dom/bindings/parser/WebIDL.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,9 @@ def ensureUnique(self, identifier, object):
self._dict[identifier.name] = replacement
return

self.addNewIdentifier(identifier, object)

def addNewIdentifier(self, identifier, object):
assert object

self._dict[identifier.name] = object
Expand Down Expand Up @@ -727,6 +730,15 @@ def globalNameSetToExposureSet(globalScope, nameSet, exposureSet):
exposureSet.update(globalScope.globalNameMapping[name])


# Because WebIDL allows static and regular operations with the same identifier
# we use a special class to be able to store them both in the scope for the
# same identifier.
class IDLOperations:
def __init__(self, static=None, regular=None):
self.static = static
self.regular = regular


class IDLInterfaceOrInterfaceMixinOrNamespace(IDLObjectWithScope, IDLExposureMixins):
def __init__(self, location, parentScope, name):
assert isinstance(parentScope, IDLScope)
Expand Down Expand Up @@ -756,15 +768,52 @@ def finish(self, scope):
self.addExtendedAttributes(partial.propagatedExtendedAttrs)
self.members.extend(partial.members)

def addNewIdentifier(self, identifier, object):
if isinstance(object, IDLMethod):
if object.isStatic():
object = IDLOperations(static=object)
else:
object = IDLOperations(regular=object)

IDLScope.addNewIdentifier(self, identifier, object)

def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject):
assert isinstance(scope, IDLScope)
assert isinstance(originalObject, IDLInterfaceMember)
assert isinstance(newObject, IDLInterfaceMember)

if isinstance(newObject, IDLMethod):
assert isinstance(originalObject, IDLOperations)

originalOperations = originalObject
if newObject.isStatic():
if originalOperations.static is None:
originalOperations.static = newObject
return originalOperations

originalObject = originalOperations.static
else:
if originalOperations.regular is None:
originalOperations.regular = newObject
return originalOperations

originalObject = originalOperations.regular

assert isinstance(originalObject, IDLMethod)
else:
assert isinstance(originalObject, IDLInterfaceMember)

retval = IDLScope.resolveIdentifierConflict(
self, scope, identifier, originalObject, newObject
)

if isinstance(newObject, IDLMethod):
if newObject.isStatic():
originalOperations.static = retval
else:
originalOperations.regular = retval

retval = originalOperations

# Might be a ctor, which isn't in self.members
if newObject in self.members:
self.members.remove(newObject)
Expand Down Expand Up @@ -995,7 +1044,7 @@ def ctor(self):
self.location, "constructor", allowForbidden=True
)
try:
return self._lookupIdentifier(identifier)
return self._lookupIdentifier(identifier).static
except Exception:
return None

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ def WebIDLTest(parser, harness):
except Exception:
threw = True

harness.ok(threw, "Should have thrown.")
harness.ok(threw, "Should have thrown for IdentifierConflictAcrossMembers1.")

parser = parser.reset()
threw = False
try:
parser.parse(
Expand All @@ -31,8 +32,9 @@ def WebIDLTest(parser, harness):
except Exception:
threw = True

harness.ok(threw, "Should have thrown.")
harness.ok(threw, "Should have thrown for IdentifierConflictAcrossMembers2.")

parser = parser.reset()
threw = False
try:
parser.parse(
Expand All @@ -48,13 +50,14 @@ def WebIDLTest(parser, harness):
except Exception:
threw = True

harness.ok(threw, "Should have thrown.")
harness.ok(threw, "Should have thrown for IdentifierConflictAcrossMembers3.")

parser = parser.reset()
threw = False
try:
parser.parse(
"""
interface IdentifierConflictAcrossMembers1 {
interface IdentifierConflictAcrossMembers4 {
const byte thing1 = 1;
long thing1();
};
Expand All @@ -65,4 +68,101 @@ def WebIDLTest(parser, harness):
except Exception:
threw = True

harness.ok(threw, "Should have thrown.")
harness.ok(threw, "Should have thrown for IdentifierConflictAcrossMembers4.")

parser = parser.reset()
threw = False
try:
parser.parse(
"""
interface IdentifierConflictAcrossMembers5 {
static long thing1();
undefined thing1();
};
"""
)

parser.finish()
except Exception:
threw = True

harness.ok(
not threw, "Should not have thrown for IdentifierConflictAcrossMembers5."
)

parser = parser.reset()
threw = False
try:
parser.parse(
"""
interface mixin IdentifierConflictAcrossMembers6Mixin {
undefined thing1();
};
interface IdentifierConflictAcrossMembers6 {
static long thing1();
};
IdentifierConflictAcrossMembers6 includes IdentifierConflictAcrossMembers6Mixin;
"""
)

parser.finish()
except Exception:
threw = True

harness.ok(
not threw, "Should not have thrown for IdentifierConflictAcrossMembers6."
)

parser = parser.reset()
threw = False
try:
parser.parse(
"""
interface IdentifierConflictAcrossMembers7 {
const byte thing1 = 1;
static readonly attribute long thing1;
};
"""
)

parser.finish()
except Exception:
threw = True

harness.ok(threw, "Should have thrown for IdentifierConflictAcrossMembers7.")

parser = parser.reset()
threw = False
try:
parser.parse(
"""
interface IdentifierConflictAcrossMembers8 {
readonly attribute long thing1 = 1;
static readonly attribute long thing1;
};
"""
)

parser.finish()
except Exception:
threw = True

harness.ok(threw, "Should have thrown for IdentifierConflictAcrossMembers8.")

parser = parser.reset()
threw = False
try:
parser.parse(
"""
interface IdentifierConflictAcrossMembers9 {
void thing1();
static readonly attribute long thing1;
};
"""
)

parser.finish()
except Exception:
threw = True

harness.ok(threw, "Should have thrown for IdentifierConflictAcrossMembers9.")

0 comments on commit dd35b25

Please sign in to comment.