script: Include constructors and static methods in generated DOM traits (#33665)

* Add all constructors, special operations, and static methods to generated DOM interface traits.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* Move all constructors and static methods defined in bare impl blocks inside FooMethods trait impls.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* Add missing doc links.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

---------

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Josh Matthews 2024-10-07 21:51:58 -04:00 committed by GitHub
parent 946fa9cdee
commit 7d931e673a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
133 changed files with 1479 additions and 1438 deletions

View file

@ -2176,6 +2176,7 @@ class CGImports(CGWrapper):
types += componentTypes(returnType)
for arg in arguments:
types += componentTypes(arg.type)
return types
def getIdentifier(t):
@ -2198,6 +2199,7 @@ class CGImports(CGWrapper):
return normalized
types = []
descriptorProvider = config.getDescriptorProvider()
for d in descriptors:
if not d.interface.isCallback():
types += [d.interface]
@ -2216,6 +2218,11 @@ class CGImports(CGWrapper):
for m in members:
if m.isMethod():
types += relatedTypesForSignatures(m)
if m.isStatic():
types += [
descriptorProvider.getDescriptor(iface).interface
for iface in d.interface.exposureSet
]
elif m.isAttr():
types += componentTypes(m.type)
@ -6292,7 +6299,7 @@ class CGDOMJSProxyHandlerDOMClass(CGThing):
class CGInterfaceTrait(CGThing):
def __init__(self, descriptor):
def __init__(self, descriptor, descriptorProvider):
CGThing.__init__(self)
def attribute_arguments(needCx, argument=None, inRealm=False, canGc=False):
@ -6310,7 +6317,7 @@ class CGInterfaceTrait(CGThing):
def members():
for m in descriptor.interface.members:
if (m.isMethod() and not m.isStatic()
if (m.isMethod()
and not m.isMaplikeOrSetlikeOrIterableMethod()
and (not m.isIdentifierLess() or (m.isStringifier() and not m.underlyingAttr))
and not m.isDefaultToJSON()):
@ -6321,8 +6328,8 @@ class CGInterfaceTrait(CGThing):
inRealm=name in descriptor.inRealmMethods,
canGc=name in descriptor.canGcMethods)
rettype = return_type(descriptor, rettype, infallible)
yield f"{name}{'_' * idx}", arguments, rettype
elif m.isAttr() and not m.isStatic():
yield f"{name}{'_' * idx}", arguments, rettype, m.isStatic()
elif m.isAttr():
name = CGSpecializedGetter.makeNativeName(descriptor, m)
infallible = 'infallible' in descriptor.getExtendedAttributes(m, getter=True)
yield (name,
@ -6331,7 +6338,8 @@ class CGInterfaceTrait(CGThing):
inRealm=name in descriptor.inRealmMethods,
canGc=name in descriptor.canGcMethods
),
return_type(descriptor, m.type, infallible))
return_type(descriptor, m.type, infallible),
m.isStatic())
if not m.readonly:
name = CGSpecializedSetter.makeNativeName(descriptor, m)
@ -6347,7 +6355,8 @@ class CGInterfaceTrait(CGThing):
inRealm=name in descriptor.inRealmMethods,
canGc=name in descriptor.canGcMethods
),
rettype)
rettype,
m.isStatic())
if descriptor.proxy or descriptor.isGlobal():
for name, operation in descriptor.operations.items():
@ -6371,18 +6380,19 @@ class CGInterfaceTrait(CGThing):
# WebIDL, Second Draft, section 3.2.4.5
# https://heycam.github.io/webidl/#idl-named-properties
if operation.isNamed():
yield "SupportedPropertyNames", [], "Vec<DOMString>"
yield "SupportedPropertyNames", [], "Vec<DOMString>", False
else:
arguments = method_arguments(descriptor, rettype, arguments,
inRealm=name in descriptor.inRealmMethods,
canGc=name in descriptor.canGcMethods)
rettype = return_type(descriptor, rettype, infallible)
yield name, arguments, rettype
yield name, arguments, rettype, False
def fmt(arguments):
def fmt(arguments, leadingComma=True):
keywords = {"async"}
return "".join(
f", {name if name not in keywords else f'r#{name}'}: {type_}"
prefix = "" if not leadingComma else ", "
return prefix + ", ".join(
f"{name if name not in keywords else f'r#{name}'}: {type_}"
for name, type_ in arguments
)
@ -6392,11 +6402,54 @@ class CGInterfaceTrait(CGThing):
return functools.reduce((lambda x, y: x or y[1] == '*mut JSContext'), arguments, False)
methods = []
for name, arguments, rettype in members():
exposureSet = list(descriptor.interface.exposureSet)
exposedGlobal = "GlobalScope" if len(exposureSet) > 1 else exposureSet[0]
hasLength = False
for name, arguments, rettype, isStatic in members():
if name == "Length":
hasLength = True
arguments = list(arguments)
unsafe = 'unsafe ' if contains_unsafe_arg(arguments) else ''
returnType = f" -> {rettype}" if rettype != '()' else ''
methods.append(CGGeneric(f"{unsafe}fn {name}(&self{fmt(arguments)}){returnType};\n"))
selfArg = "&self" if not isStatic else ""
extra = [("global", f"&{exposedGlobal}")] if isStatic else []
if arguments and arguments[0][0] == "cx":
arguments = [arguments[0]] + extra + arguments[1:]
else:
arguments = extra + arguments
methods.append(CGGeneric(
f"{unsafe}fn {name}({selfArg}"
f"{fmt(arguments, leadingComma=not isStatic)}){returnType};\n"
))
def ctorMethod(ctor, baseName=None):
infallible = 'infallible' in descriptor.getExtendedAttributes(ctor)
for (i, (rettype, arguments)) in enumerate(ctor.signatures()):
name = (baseName or ctor.identifier.name) + ('_' * i)
args = list(method_arguments(descriptor, rettype, arguments))
extra = [
("global", f"&{exposedGlobal}"),
("proto", "Option<HandleObject>"),
("can_gc", "CanGc"),
]
if args and args[0][0] == "cx":
args = [args[0]] + extra + args[1:]
else:
args = extra + args
yield CGGeneric(
f"fn {name}({fmt(args, leadingComma=False)}) -> "
f"{return_type(descriptorProvider, rettype, infallible)};\n"
)
ctor = descriptor.interface.ctor()
if ctor and not ctor.isHTMLConstructor():
methods.extend(list(ctorMethod(ctor, "Constructor")))
for ctor in descriptor.interface.legacyFactoryFunctions:
methods.extend(list(ctorMethod(ctor)))
if descriptor.operations['IndexedGetter'] and not hasLength:
methods.append(CGGeneric("fn Length(&self) -> u32;\n"))
if methods:
self.cgRoot = CGWrapper(CGIndenter(CGList(methods, "")),
@ -6572,14 +6625,15 @@ class CGDescriptor(CGThing):
if descriptor.concrete or descriptor.hasDescendants():
cgThings.append(CGIDLInterface(descriptor))
interfaceTrait = CGInterfaceTrait(descriptor)
if descriptor.weakReferenceable:
cgThings.append(CGWeakReferenceableTrait(descriptor))
if not descriptor.interface.isCallback():
interfaceTrait = CGInterfaceTrait(descriptor, config.getDescriptorProvider())
cgThings.append(interfaceTrait)
if not interfaceTrait.empty:
reexports.append(f'{descriptor.name}Methods')
if descriptor.weakReferenceable:
cgThings.append(CGWeakReferenceableTrait(descriptor))
legacyWindowAliases = descriptor.interface.legacyWindowAliases
haveLegacyWindowAliases = len(legacyWindowAliases) != 0
if haveLegacyWindowAliases: