mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Generate the TypeId enums in codegen
This commit is contained in:
parent
55769b2fbf
commit
aab2c40389
107 changed files with 678 additions and 774 deletions
|
@ -4,6 +4,8 @@
|
|||
|
||||
# Common codegen classes.
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
import operator
|
||||
import re
|
||||
import string
|
||||
|
@ -1722,23 +1724,20 @@ class CGNamespace(CGWrapper):
|
|||
return CGNamespace(namespaces[0], inner, public=public)
|
||||
|
||||
|
||||
def EventTargetEnum(desc):
|
||||
def DOMClassTypeId(desc):
|
||||
protochain = desc.prototypeChain
|
||||
if protochain[0] != "EventTarget" or desc.interface.getExtendedAttribute("Abstract"):
|
||||
return "None"
|
||||
|
||||
inner = ""
|
||||
name = desc.interface.identifier.name
|
||||
if desc.interface.getUserData("hasConcreteDescendant", False):
|
||||
inner = "(::dom::%s::%sTypeId::%s)" % (name.lower(), name, name)
|
||||
prev_proto = ""
|
||||
for proto in reversed(protochain):
|
||||
if prev_proto != "":
|
||||
inner = "(::dom::%s::%sTypeId::%s%s)" % (proto.lower(), proto, prev_proto, inner)
|
||||
prev_proto = proto
|
||||
if inner == "":
|
||||
return "None"
|
||||
return "Some%s" % inner
|
||||
if desc.hasDescendants():
|
||||
if desc.interface.getExtendedAttribute("Abstract"):
|
||||
return "::dom::bindings::codegen::InheritTypes::TopTypeId::Abstract"
|
||||
name = desc.interface.identifier.name
|
||||
inner = "(::dom::bindings::codegen::InheritTypes::%sTypeId::%s)" % (name, name)
|
||||
elif len(protochain) == 1:
|
||||
return "::dom::bindings::codegen::InheritTypes::TopTypeId::Alone"
|
||||
reversed_protochain = list(reversed(protochain))
|
||||
for (child, parent) in zip(reversed_protochain, reversed_protochain[1:]):
|
||||
inner = "(::dom::bindings::codegen::InheritTypes::%sTypeId::%s%s)" % (parent, child, inner)
|
||||
return "::dom::bindings::codegen::InheritTypes::TopTypeId::%s%s" % (protochain[0], inner)
|
||||
|
||||
|
||||
def DOMClass(descriptor):
|
||||
|
@ -1754,7 +1753,7 @@ DOMClass {
|
|||
interface_chain: [ %s ],
|
||||
native_hooks: &sNativePropertyHooks,
|
||||
type_id: %s,
|
||||
}""" % (prototypeChainString, EventTargetEnum(descriptor))
|
||||
}""" % (prototypeChainString, DOMClassTypeId(descriptor))
|
||||
|
||||
|
||||
class CGDOMJSClass(CGThing):
|
||||
|
@ -5815,23 +5814,29 @@ class GlobalGenRoots():
|
|||
def InheritTypes(config):
|
||||
|
||||
descriptors = config.getDescriptors(register=True, isCallback=False)
|
||||
allprotos = [CGGeneric("use dom::types::*;\n"),
|
||||
CGGeneric("use dom::bindings::js::{JS, LayoutJS, Root};\n"),
|
||||
CGGeneric("use dom::bindings::trace::JSTraceable;\n"),
|
||||
CGGeneric("use dom::bindings::utils::Reflectable;\n"),
|
||||
CGGeneric("use js::jsapi::JSTracer;\n\n"),
|
||||
CGGeneric("use std::mem;\n\n")]
|
||||
imports = [CGGeneric("use dom::types::*;\n"),
|
||||
CGGeneric("use dom::bindings::conversions::get_dom_class;\n"),
|
||||
CGGeneric("use dom::bindings::js::{JS, LayoutJS, Root};\n"),
|
||||
CGGeneric("use dom::bindings::trace::JSTraceable;\n"),
|
||||
CGGeneric("use dom::bindings::utils::Reflectable;\n"),
|
||||
CGGeneric("use js::jsapi::JSTracer;\n\n"),
|
||||
CGGeneric("use std::mem;\n\n")]
|
||||
allprotos = []
|
||||
topTypes = []
|
||||
hierarchy = defaultdict(list)
|
||||
for descriptor in descriptors:
|
||||
name = descriptor.name
|
||||
chain = descriptor.prototypeChain
|
||||
upcast = (descriptor.interface.getUserData("hasConcreteDescendant", False) or
|
||||
descriptor.interface.getUserData("hasProxyDescendant", False))
|
||||
upcast = descriptor.hasDescendants()
|
||||
downcast = len(chain) != 1
|
||||
|
||||
if upcast or downcast:
|
||||
# Define a dummy structure to hold the cast functions.
|
||||
allprotos.append(CGGeneric("pub struct %sCast;\n\n" % name))
|
||||
|
||||
if upcast and not downcast:
|
||||
topTypes.append(name)
|
||||
|
||||
if upcast:
|
||||
# Define a `FooBase` trait for subclasses to implement, as well as the
|
||||
# `FooCast::from_*` methods that use it.
|
||||
|
@ -5872,6 +5877,7 @@ impl %(name)sCast {
|
|||
allprotos.append(CGGeneric("\n"))
|
||||
|
||||
if downcast:
|
||||
hierarchy[descriptor.getParentName()].append(name)
|
||||
# Define a `FooDerived` trait for superclasses to implement,
|
||||
# as well as the `FooCast::to_*` methods that use it.
|
||||
allprotos.append(CGGeneric("""\
|
||||
|
@ -5922,7 +5928,7 @@ impl %(name)sCast {
|
|||
'baseName': baseName,
|
||||
'derivedTrait': name + 'Derived',
|
||||
'methodName': 'is_' + name.lower(),
|
||||
'parentName': config.getDescriptor(baseName).prototypeChain[-2],
|
||||
'parentName': config.getDescriptor(baseName).getParentName(),
|
||||
}
|
||||
allprotos.append(CGGeneric("""\
|
||||
impl %(derivedTrait)s for %(baseName)s {
|
||||
|
@ -5934,7 +5940,54 @@ impl %(derivedTrait)s for %(baseName)s {
|
|||
|
||||
""" % args))
|
||||
|
||||
curr = CGList(allprotos)
|
||||
typeIdCode = []
|
||||
topTypeVariants = [
|
||||
("ID used by abstract interfaces.", "Abstract"),
|
||||
("ID used by interfaces that are not castable.", "Alone"),
|
||||
]
|
||||
topTypeVariants += [
|
||||
("ID used by interfaces that derive from %s." % name, "%s(%sTypeId)" % (name, name))
|
||||
for name in topTypes
|
||||
]
|
||||
topTypeVariantsAsStrings = [CGGeneric("/// %s\n%s," % variant) for variant in topTypeVariants]
|
||||
typeIdCode.append(CGWrapper(CGIndenter(CGList(topTypeVariantsAsStrings, "\n"), 4),
|
||||
pre="#[derive(Clone, Copy, Debug)]\npub enum TopTypeId {\n",
|
||||
post="\n}\n\n"))
|
||||
|
||||
def type_id_variant(name):
|
||||
# If `name` is present in the hierarchy keys', that means some other interfaces
|
||||
# derive from it and this enum variant should have an argument with its own
|
||||
# TypeId enum.
|
||||
return "%s(%sTypeId)" % (name, name) if name in hierarchy else name
|
||||
|
||||
for base, derived in hierarchy.iteritems():
|
||||
variants = []
|
||||
if not config.getInterface(base).getExtendedAttribute("Abstract"):
|
||||
variants.append(CGGeneric(base))
|
||||
variants += [CGGeneric(type_id_variant(name)) for name in derived]
|
||||
derives = "Clone, Copy, Debug"
|
||||
if base != 'EventTarget' and base != 'HTMLElement':
|
||||
derives += ", PartialEq"
|
||||
typeIdCode.append(CGWrapper(CGIndenter(CGList(variants, ",\n"), 4),
|
||||
pre="#[derive(%s)]\npub enum %sTypeId {\n" % (derives, base),
|
||||
post="\n}\n\n"))
|
||||
if base in topTypes:
|
||||
typeIdCode.append(CGGeneric("""\
|
||||
impl %(base)s {
|
||||
pub fn type_id(&self) -> &'static %(base)sTypeId {
|
||||
let domclass = unsafe {
|
||||
get_dom_class(self.reflector().get_jsobject().get()).unwrap()
|
||||
};
|
||||
match domclass.type_id {
|
||||
TopTypeId::%(base)s(ref type_id) => type_id,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
""" % {'base': base}))
|
||||
|
||||
curr = CGList(imports + typeIdCode + allprotos)
|
||||
curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
|
||||
return curr
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue