mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Assert that DOM structs have the correct first field
DOM structs embed their parent type as their first field. This introduces a `.parent()` method to the DOM struct that returns its first field, and codegens a type assert that ensures that `.parent()` returns the parent struct. This generates: On `#[dom_struct]`: ```rust impl HasParent for Type { type Parent = ParentType; fn as_parent(&self) -> ParentType { &self.first_field } } ``` In the codegen files: ```rust impl Type { fn __assert_parent_type(&self) { let _: &ParentType = self.as_parent(); } } ````
This commit is contained in:
parent
e2fca1b228
commit
ad198993b1
6 changed files with 109 additions and 9 deletions
|
@ -2116,6 +2116,10 @@ class CGDOMJSClass(CGThing):
|
|||
self.descriptor = descriptor
|
||||
|
||||
def define(self):
|
||||
parentName = self.descriptor.getParentName()
|
||||
if not parentName:
|
||||
parentName = "::dom::bindings::reflector::Reflector"
|
||||
|
||||
args = {
|
||||
"domClass": DOMClass(self.descriptor),
|
||||
"enumerateHook": "None",
|
||||
|
@ -2161,7 +2165,51 @@ static Class: DOMJSClass = DOMJSClass {
|
|||
reserved: [0 as *mut _; 3],
|
||||
},
|
||||
dom_class: %(domClass)s
|
||||
};""" % args
|
||||
};
|
||||
""" % args
|
||||
|
||||
|
||||
class CGAssertInheritance(CGThing):
|
||||
"""
|
||||
Generate a type assertion for inheritance
|
||||
"""
|
||||
def __init__(self, descriptor):
|
||||
CGThing.__init__(self)
|
||||
self.descriptor = descriptor
|
||||
|
||||
def define(self):
|
||||
parent = self.descriptor.interface.parent
|
||||
parentName = ""
|
||||
if parent:
|
||||
parentName = parent.identifier.name
|
||||
else:
|
||||
parentName = "::dom::bindings::reflector::Reflector"
|
||||
|
||||
selfName = self.descriptor.interface.identifier.name
|
||||
|
||||
if selfName == "PaintRenderingContext2D":
|
||||
# PaintRenderingContext2D embeds a CanvasRenderingContext2D
|
||||
# instead of a Reflector as an optimization,
|
||||
# but this is fine since CanvasRenderingContext2D
|
||||
# also has a reflector
|
||||
#
|
||||
# FIXME *RenderingContext2D should use Inline
|
||||
parentName = "::dom::canvasrenderingcontext2d::CanvasRenderingContext2D"
|
||||
args = {
|
||||
"parentName": parentName,
|
||||
"selfName": selfName,
|
||||
}
|
||||
|
||||
return """\
|
||||
impl %(selfName)s {
|
||||
fn __assert_parent_type(&self) {
|
||||
use dom::bindings::inheritance::HasParent;
|
||||
// If this type assertion fails, make sure the first field of your
|
||||
// DOM struct is of the correct type -- it must be the parent class.
|
||||
let _: &%(parentName)s = self.as_parent();
|
||||
}
|
||||
}
|
||||
""" % args
|
||||
|
||||
|
||||
def str_to_const_array(s):
|
||||
|
@ -6011,6 +6059,8 @@ class CGDescriptor(CGThing):
|
|||
pass
|
||||
else:
|
||||
cgThings.append(CGDOMJSClass(descriptor))
|
||||
if not descriptor.interface.isIteratorInterface():
|
||||
cgThings.append(CGAssertInheritance(descriptor))
|
||||
pass
|
||||
|
||||
if descriptor.isGlobal():
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue