Skip to content

Commit a1b9949

Browse files
authored
Support static and instance members having the same name in IDLs (servo#36523)
This is needed to implement features like `Response.json` which is a static helper added to the fetch spec which overlaps with the `json` instance method `Response` has from `Body`. Partly based these changes on what Firefox does for this same issue. (https://searchfox.org/mozilla-central/source/dom/bindings/Codegen.py and https://searchfox.org/mozilla-central/source/dom/bindings/Configuration.py specifically keying `binaryNameFor` on name and `isStatic`). Testing: I locally updated the Response.webidl to contain the new static `json` and it compiles. Signed-off-by: Sebastian C <[email protected]>
1 parent f2ee40e commit a1b9949

File tree

2 files changed

+35
-21
lines changed

2 files changed

+35
-21
lines changed

components/script_bindings/codegen/CodegenRust.py

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,13 +1745,16 @@ def __init__(self, descriptor, name, static, unforgeable, crossorigin=False):
17451745
and (MemberIsLegacyUnforgeable(m, descriptor) == unforgeable or crossorigin)]
17461746
else:
17471747
methods = []
1748-
self.regular = [{"name": m.identifier.name,
1749-
"methodInfo": not m.isStatic(),
1750-
"length": methodLength(m),
1751-
"flags": "JSPROP_READONLY" if crossorigin else "JSPROP_ENUMERATE",
1752-
"condition": PropertyDefiner.getControllingCondition(m, descriptor),
1753-
"returnsPromise": m.returnsPromise()}
1754-
for m in methods]
1748+
self.regular = []
1749+
for m in methods:
1750+
method = self.methodData(m, descriptor, crossorigin)
1751+
1752+
if m.isStatic():
1753+
method["nativeName"] = CGDictionary.makeMemberName(
1754+
descriptor.binaryNameFor(m.identifier.name, True)
1755+
)
1756+
1757+
self.regular.append(method)
17551758

17561759
# TODO: Once iterable is implemented, use tiebreak rules instead of
17571760
# failing. Also, may be more tiebreak rules to implement once spec bug
@@ -1841,6 +1844,17 @@ def hasIterator(methods, regular):
18411844
self.unforgeable = unforgeable
18421845
self.crossorigin = crossorigin
18431846

1847+
@staticmethod
1848+
def methodData(m, descriptor, crossorigin):
1849+
return {
1850+
"name": m.identifier.name,
1851+
"methodInfo": not m.isStatic(),
1852+
"length": methodLength(m),
1853+
"flags": "JSPROP_READONLY" if crossorigin else "JSPROP_ENUMERATE",
1854+
"condition": PropertyDefiner.getControllingCondition(m, descriptor),
1855+
"returnsPromise": m.returnsPromise()
1856+
}
1857+
18441858
def generateArray(self, array, name):
18451859
if len(array) == 0:
18461860
return ""
@@ -4233,7 +4247,7 @@ def makeNativeName(descriptor, method):
42334247
if method.underlyingAttr:
42344248
return CGSpecializedGetter.makeNativeName(descriptor, method.underlyingAttr)
42354249
name = method.identifier.name
4236-
nativeName = descriptor.binaryNameFor(name)
4250+
nativeName = descriptor.binaryNameFor(name, method.isStatic())
42374251
if nativeName == name:
42384252
nativeName = descriptor.internalNameFor(name)
42394253
return MakeNativeName(nativeName)
@@ -4357,7 +4371,7 @@ class CGStaticMethod(CGAbstractStaticBindingMethod):
43574371
"""
43584372
def __init__(self, descriptor, method):
43594373
self.method = method
4360-
name = method.identifier.name
4374+
name = descriptor.binaryNameFor(method.identifier.name, True)
43614375
CGAbstractStaticBindingMethod.__init__(self, descriptor, name, templateArgs=["D: DomTypes"])
43624376

43634377
def generate_code(self):
@@ -4395,7 +4409,7 @@ def definition_body(self):
43954409
@staticmethod
43964410
def makeNativeName(descriptor, attr):
43974411
name = attr.identifier.name
4398-
nativeName = descriptor.binaryNameFor(name)
4412+
nativeName = descriptor.binaryNameFor(name, attr.isStatic())
43994413
if nativeName == name:
44004414
nativeName = descriptor.internalNameFor(name)
44014415
nativeName = MakeNativeName(nativeName)
@@ -4452,7 +4466,7 @@ def definition_body(self):
44524466
@staticmethod
44534467
def makeNativeName(descriptor, attr):
44544468
name = attr.identifier.name
4455-
nativeName = descriptor.binaryNameFor(name)
4469+
nativeName = descriptor.binaryNameFor(name, attr.isStatic())
44564470
if nativeName == name:
44574471
nativeName = descriptor.internalNameFor(name)
44584472
return f"Set{MakeNativeName(nativeName)}"
@@ -5745,7 +5759,7 @@ class CGProxySpecialOperation(CGPerSignatureCall):
57455759
(don't use this directly, use the derived classes below).
57465760
"""
57475761
def __init__(self, descriptor, operation):
5748-
nativeName = MakeNativeName(descriptor.binaryNameFor(operation))
5762+
nativeName = MakeNativeName(descriptor.binaryNameFor(operation, False))
57495763
operation = descriptor.operations[operation]
57505764
assert len(operation.signatures()) == 1
57515765
signature = operation.signatures()[0]
@@ -6535,7 +6549,7 @@ def definition_body(self):
65356549
else:
65366550
ctorName = GetConstructorNameForReporting(self.descriptor, self.constructor)
65376551
name = self.constructor.identifier.name
6538-
nativeName = MakeNativeName(self.descriptor.binaryNameFor(name))
6552+
nativeName = MakeNativeName(self.descriptor.binaryNameFor(name, True))
65396553

65406554
if len(self.exposureSet) == 1:
65416555
args = [
@@ -7988,11 +8002,11 @@ def deps(self):
79888002

79898003
# We're always fallible
79908004
def callbackGetterName(attr, descriptor):
7991-
return f"Get{MakeNativeName(descriptor.binaryNameFor(attr.identifier.name))}"
8005+
return f"Get{MakeNativeName(descriptor.binaryNameFor(attr.identifier.name, attr.isStatic()))}"
79928006

79938007

79948008
def callbackSetterName(attr, descriptor):
7995-
return f"Set{MakeNativeName(descriptor.binaryNameFor(attr.identifier.name))}"
8009+
return f"Set{MakeNativeName(descriptor.binaryNameFor(attr.identifier.name, attr.isStatic()))}"
79968010

79978011

79988012
class CGCallbackFunction(CGCallback):
@@ -8332,7 +8346,7 @@ def __init__(self, method, signature, descriptor):
83328346
jsName = method.identifier.name
83338347
CallbackOperationBase.__init__(self, signature,
83348348
jsName,
8335-
MakeNativeName(descriptor.binaryNameFor(jsName)),
8349+
MakeNativeName(descriptor.binaryNameFor(jsName, False)),
83368350
descriptor, descriptor.interface.isSingleOperationInterface())
83378351

83388352

components/script_bindings/codegen/Configuration.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,8 @@ def add(key, members, attribute):
353353
add('all', [config], attribute)
354354

355355
self._binaryNames = desc.get('binaryNames', {})
356-
self._binaryNames.setdefault('__legacycaller', 'LegacyCall')
357-
self._binaryNames.setdefault('__stringifier', 'Stringifier')
356+
self._binaryNames.setdefault(('__legacycaller', False), 'LegacyCall')
357+
self._binaryNames.setdefault(('__stringifier', False), 'Stringifier')
358358

359359
self._internalNames = desc.get('internalNames', {})
360360

@@ -365,7 +365,7 @@ def add(key, members, attribute):
365365
if binaryName:
366366
assert isinstance(binaryName, list)
367367
assert len(binaryName) == 1
368-
self._binaryNames.setdefault(member.identifier.name,
368+
self._binaryNames.setdefault((member.identifier.name, member.isStatic()),
369369
binaryName[0])
370370
self._internalNames.setdefault(member.identifier.name,
371371
member.identifier.name.replace('-', '_'))
@@ -391,8 +391,8 @@ def maybeGetSuperModule(self):
391391
return filename
392392
return None
393393

394-
def binaryNameFor(self, name):
395-
return self._binaryNames.get(name, name)
394+
def binaryNameFor(self, name, isStatic):
395+
return self._binaryNames.get((name, isStatic), name)
396396

397397
def internalNameFor(self, name):
398398
return self._internalNames.get(name, name)

0 commit comments

Comments
 (0)