aboutsummaryrefslogtreecommitdiffstats
path: root/components/script_bindings
diff options
context:
space:
mode:
authorSebastian C <sebsebmc@gmail.com>2025-04-16 16:00:52 -0500
committerGitHub <noreply@github.com>2025-04-16 21:00:52 +0000
commita1b9949f7563ae6ee30aedc0a3d0c86bb05d02fd (patch)
tree9d236e915635e48d98f29ce11632e24d3127a8e5 /components/script_bindings
parentf2ee40e40bafe5c560f53dcc7231b58e2a7c9bb3 (diff)
downloadservo-a1b9949f7563ae6ee30aedc0a3d0c86bb05d02fd.tar.gz
servo-a1b9949f7563ae6ee30aedc0a3d0c86bb05d02fd.zip
Support static and instance members having the same name in IDLs (#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 <sebsebmc@gmail.com>
Diffstat (limited to 'components/script_bindings')
-rw-r--r--components/script_bindings/codegen/CodegenRust.py46
-rw-r--r--components/script_bindings/codegen/Configuration.py10
2 files changed, 35 insertions, 21 deletions
diff --git a/components/script_bindings/codegen/CodegenRust.py b/components/script_bindings/codegen/CodegenRust.py
index 26e76d9d828..c3e6fe2ee5e 100644
--- a/components/script_bindings/codegen/CodegenRust.py
+++ b/components/script_bindings/codegen/CodegenRust.py
@@ -1745,13 +1745,16 @@ class MethodDefiner(PropertyDefiner):
and (MemberIsLegacyUnforgeable(m, descriptor) == unforgeable or crossorigin)]
else:
methods = []
- self.regular = [{"name": m.identifier.name,
- "methodInfo": not m.isStatic(),
- "length": methodLength(m),
- "flags": "JSPROP_READONLY" if crossorigin else "JSPROP_ENUMERATE",
- "condition": PropertyDefiner.getControllingCondition(m, descriptor),
- "returnsPromise": m.returnsPromise()}
- for m in methods]
+ self.regular = []
+ for m in methods:
+ method = self.methodData(m, descriptor, crossorigin)
+
+ if m.isStatic():
+ method["nativeName"] = CGDictionary.makeMemberName(
+ descriptor.binaryNameFor(m.identifier.name, True)
+ )
+
+ self.regular.append(method)
# TODO: Once iterable is implemented, use tiebreak rules instead of
# failing. Also, may be more tiebreak rules to implement once spec bug
@@ -1841,6 +1844,17 @@ class MethodDefiner(PropertyDefiner):
self.unforgeable = unforgeable
self.crossorigin = crossorigin
+ @staticmethod
+ def methodData(m, descriptor, crossorigin):
+ return {
+ "name": m.identifier.name,
+ "methodInfo": not m.isStatic(),
+ "length": methodLength(m),
+ "flags": "JSPROP_READONLY" if crossorigin else "JSPROP_ENUMERATE",
+ "condition": PropertyDefiner.getControllingCondition(m, descriptor),
+ "returnsPromise": m.returnsPromise()
+ }
+
def generateArray(self, array, name):
if len(array) == 0:
return ""
@@ -4233,7 +4247,7 @@ class CGSpecializedMethod(CGAbstractExternMethod):
if method.underlyingAttr:
return CGSpecializedGetter.makeNativeName(descriptor, method.underlyingAttr)
name = method.identifier.name
- nativeName = descriptor.binaryNameFor(name)
+ nativeName = descriptor.binaryNameFor(name, method.isStatic())
if nativeName == name:
nativeName = descriptor.internalNameFor(name)
return MakeNativeName(nativeName)
@@ -4357,7 +4371,7 @@ class CGStaticMethod(CGAbstractStaticBindingMethod):
"""
def __init__(self, descriptor, method):
self.method = method
- name = method.identifier.name
+ name = descriptor.binaryNameFor(method.identifier.name, True)
CGAbstractStaticBindingMethod.__init__(self, descriptor, name, templateArgs=["D: DomTypes"])
def generate_code(self):
@@ -4395,7 +4409,7 @@ class CGSpecializedGetter(CGAbstractExternMethod):
@staticmethod
def makeNativeName(descriptor, attr):
name = attr.identifier.name
- nativeName = descriptor.binaryNameFor(name)
+ nativeName = descriptor.binaryNameFor(name, attr.isStatic())
if nativeName == name:
nativeName = descriptor.internalNameFor(name)
nativeName = MakeNativeName(nativeName)
@@ -4452,7 +4466,7 @@ class CGSpecializedSetter(CGAbstractExternMethod):
@staticmethod
def makeNativeName(descriptor, attr):
name = attr.identifier.name
- nativeName = descriptor.binaryNameFor(name)
+ nativeName = descriptor.binaryNameFor(name, attr.isStatic())
if nativeName == name:
nativeName = descriptor.internalNameFor(name)
return f"Set{MakeNativeName(nativeName)}"
@@ -5745,7 +5759,7 @@ class CGProxySpecialOperation(CGPerSignatureCall):
(don't use this directly, use the derived classes below).
"""
def __init__(self, descriptor, operation):
- nativeName = MakeNativeName(descriptor.binaryNameFor(operation))
+ nativeName = MakeNativeName(descriptor.binaryNameFor(operation, False))
operation = descriptor.operations[operation]
assert len(operation.signatures()) == 1
signature = operation.signatures()[0]
@@ -6535,7 +6549,7 @@ let global = D::GlobalScope::from_object(JS_CALLEE(*cx, vp).to_object());
else:
ctorName = GetConstructorNameForReporting(self.descriptor, self.constructor)
name = self.constructor.identifier.name
- nativeName = MakeNativeName(self.descriptor.binaryNameFor(name))
+ nativeName = MakeNativeName(self.descriptor.binaryNameFor(name, True))
if len(self.exposureSet) == 1:
args = [
@@ -7988,11 +8002,11 @@ class CGCallback(CGClass):
# We're always fallible
def callbackGetterName(attr, descriptor):
- return f"Get{MakeNativeName(descriptor.binaryNameFor(attr.identifier.name))}"
+ return f"Get{MakeNativeName(descriptor.binaryNameFor(attr.identifier.name, attr.isStatic()))}"
def callbackSetterName(attr, descriptor):
- return f"Set{MakeNativeName(descriptor.binaryNameFor(attr.identifier.name))}"
+ return f"Set{MakeNativeName(descriptor.binaryNameFor(attr.identifier.name, attr.isStatic()))}"
class CGCallbackFunction(CGCallback):
@@ -8332,7 +8346,7 @@ class CallbackOperation(CallbackOperationBase):
jsName = method.identifier.name
CallbackOperationBase.__init__(self, signature,
jsName,
- MakeNativeName(descriptor.binaryNameFor(jsName)),
+ MakeNativeName(descriptor.binaryNameFor(jsName, False)),
descriptor, descriptor.interface.isSingleOperationInterface())
diff --git a/components/script_bindings/codegen/Configuration.py b/components/script_bindings/codegen/Configuration.py
index 636a70197d2..e540b0c3101 100644
--- a/components/script_bindings/codegen/Configuration.py
+++ b/components/script_bindings/codegen/Configuration.py
@@ -353,8 +353,8 @@ class Descriptor(DescriptorProvider):
add('all', [config], attribute)
self._binaryNames = desc.get('binaryNames', {})
- self._binaryNames.setdefault('__legacycaller', 'LegacyCall')
- self._binaryNames.setdefault('__stringifier', 'Stringifier')
+ self._binaryNames.setdefault(('__legacycaller', False), 'LegacyCall')
+ self._binaryNames.setdefault(('__stringifier', False), 'Stringifier')
self._internalNames = desc.get('internalNames', {})
@@ -365,7 +365,7 @@ class Descriptor(DescriptorProvider):
if binaryName:
assert isinstance(binaryName, list)
assert len(binaryName) == 1
- self._binaryNames.setdefault(member.identifier.name,
+ self._binaryNames.setdefault((member.identifier.name, member.isStatic()),
binaryName[0])
self._internalNames.setdefault(member.identifier.name,
member.identifier.name.replace('-', '_'))
@@ -391,8 +391,8 @@ class Descriptor(DescriptorProvider):
return filename
return None
- def binaryNameFor(self, name):
- return self._binaryNames.get(name, name)
+ def binaryNameFor(self, name, isStatic):
+ return self._binaryNames.get((name, isStatic), name)
def internalNameFor(self, name):
return self._internalNames.get(name, name)