Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate the various TypeId enums in codegen #7873

Merged
merged 1 commit into from Oct 14, 2015
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -33,11 +33,9 @@ use inline::{InlineFragmentNodeInfo, LAST_FRAGMENT_OF_ELEMENT};
use list_item::{ListItemFlow, ListStyleTypeContent};
use multicol::MulticolFlow;
use parallel;
use script::dom::characterdata::CharacterDataTypeId;
use script::dom::element::ElementTypeId;
use script::dom::htmlelement::HTMLElementTypeId;
use script::dom::bindings::codegen::InheritTypes::{CharacterDataTypeId, ElementTypeId};
use script::dom::bindings::codegen::InheritTypes::{HTMLElementTypeId, NodeTypeId};
use script::dom::htmlobjectelement::is_image_data;
use script::dom::node::NodeTypeId;
use std::borrow::ToOwned;
use std::collections::LinkedList;
use std::mem;
@@ -10,8 +10,7 @@ use animation;
use context::SharedLayoutContext;
use data::LayoutDataWrapper;
use incremental::{self, RestyleDamage};
use script::dom::characterdata::CharacterDataTypeId;
use script::dom::node::NodeTypeId;
use script::dom::bindings::codegen::InheritTypes::{CharacterDataTypeId, NodeTypeId};
use script::layout_interface::Animation;
use selectors::bloom::BloomFilter;
use selectors::matching::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes};
@@ -40,22 +40,22 @@ use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId;
use opaque_node::OpaqueNodeMethods;
use script::dom::attr::AttrValue;
use script::dom::bindings::codegen::InheritTypes::{CharacterDataCast, ElementCast};
use script::dom::bindings::codegen::InheritTypes::{HTMLCanvasElementCast, HTMLIFrameElementCast};
use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementCast, HTMLInputElementCast};
use script::dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementCast, NodeCast, TextCast};
use script::dom::bindings::codegen::InheritTypes::{CharacterDataCast, CharacterDataTypeId};
use script::dom::bindings::codegen::InheritTypes::{ElementCast, ElementTypeId};
use script::dom::bindings::codegen::InheritTypes::{HTMLCanvasElementCast, HTMLElementTypeId};
use script::dom::bindings::codegen::InheritTypes::{HTMLIFrameElementCast, HTMLImageElementCast};
use script::dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, HTMLTextAreaElementCast};
use script::dom::bindings::codegen::InheritTypes::{NodeCast, NodeTypeId, TextCast};
use script::dom::bindings::js::LayoutJS;
use script::dom::characterdata::{CharacterDataTypeId, LayoutCharacterDataHelpers};
use script::dom::element::{Element, ElementTypeId};
use script::dom::characterdata::LayoutCharacterDataHelpers;
use script::dom::element::Element;
use script::dom::element::{LayoutElementHelpers, RawLayoutElementHelpers};
use script::dom::htmlcanvaselement::LayoutHTMLCanvasElementHelpers;
use script::dom::htmlelement::HTMLElementTypeId;
use script::dom::htmlimageelement::LayoutHTMLImageElementHelpers;
use script::dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
use script::dom::htmltextareaelement::LayoutHTMLTextAreaElementHelpers;
use script::dom::node::{HAS_CHANGED, HAS_DIRTY_DESCENDANTS, HAS_DIRTY_SIBLINGS, IS_DIRTY};
use script::dom::node::{LayoutNodeHelpers, SharedLayoutData};
use script::dom::node::{Node, NodeTypeId};
use script::dom::node::{LayoutNodeHelpers, Node, SharedLayoutData};
use script::dom::text::Text;
use selectors::matching::DeclarationBlock;
use selectors::parser::{AttrSelector, NamespaceConstraint};
@@ -4,6 +4,8 @@

# Common codegen classes.

from collections import defaultdict

import operator
import re
import string
@@ -1722,23 +1724,20 @@ def build(namespaces, child, public=False):
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 @@ def DOMClass(descriptor):
interface_chain: [ %s ],
native_hooks: &sNativePropertyHooks,
type_id: %s,
}""" % (prototypeChainString, EventTargetEnum(descriptor))
}""" % (prototypeChainString, DOMClassTypeId(descriptor))


class CGDOMJSClass(CGThing):
@@ -5815,23 +5814,29 @@ def Bindings(config):
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 @@ def InheritTypes(config):
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 @@ def InheritTypes(config):
'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 @@ def InheritTypes(config):
""" % 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

@@ -318,6 +318,14 @@ def maybeAppendInfallibleToAttrs(attrs, throws):
maybeAppendInfallibleToAttrs(attrs, throws)
return attrs

def getParentName(self):
assert self.interface.parent is not None
return self.interface.parent.identifier.name

def hasDescendants(self):
return (self.interface.getUserData("hasConcreteDescendant", False) or
self.interface.getUserData("hasProxyDescendant", False))

def isGlobal(self):
"""
Returns true if this is the primary interface for a global object
@@ -4,6 +4,7 @@

//! Various utilities to glue JavaScript and the DOM implementation together.

use dom::bindings::codegen::InheritTypes::TopTypeId;
use dom::bindings::codegen::PrototypeList;
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
use dom::bindings::conversions::native_from_handleobject;
@@ -15,7 +16,6 @@ use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
use dom::bindings::trace::trace_object;
use dom::browsercontext;
use dom::eventtarget::EventTargetTypeId;
use dom::window;
use js;
use js::glue::{CallJitGetterOp, CallJitMethodOp, CallJitSetterOp, IsWrapper};
@@ -156,8 +156,8 @@ pub struct DOMClass {
/// derivedness.
pub interface_chain: [PrototypeList::ID; MAX_PROTO_CHAIN_LENGTH],

/// The EventTarget type, if this is derived from an EventTarget.
pub type_id: Option<EventTargetTypeId>,
/// The type ID of that interface.
pub type_id: TopTypeId,

/// The NativePropertyHooks for the interface associated with this class.
pub native_hooks: &'static NativePropertyHooks,
@@ -4,7 +4,7 @@

use dom::bindings::codegen::Bindings::BlobBinding;
use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
use dom::bindings::codegen::InheritTypes::FileDerived;
use dom::bindings::codegen::InheritTypes::{BlobTypeId, FileDerived};
use dom::bindings::error::Fallible;
use dom::bindings::global::{GlobalField, GlobalRef};
use dom::bindings::js::Root;
@@ -17,17 +17,10 @@ use std::cmp::{max, min};
use std::sync::mpsc::Sender;
use util::str::DOMString;

#[derive(JSTraceable, HeapSizeOf)]
pub enum BlobTypeId {
Blob,
File,
}

// http://dev.w3.org/2006/webapi/FileAPI/#blob
#[dom_struct]
pub struct Blob {
reflector_: Reflector,
type_: BlobTypeId,
bytes: Option<Vec<u8>>,
typeString: DOMString,
global: GlobalField,
@@ -41,11 +34,10 @@ fn is_ascii_printable(string: &DOMString) -> bool {
}

impl Blob {
pub fn new_inherited(global: GlobalRef, type_: BlobTypeId,
pub fn new_inherited(global: GlobalRef,
bytes: Option<Vec<u8>>, typeString: &str) -> Blob {
Blob {
reflector_: Reflector::new(),
type_: type_,
bytes: bytes,
typeString: typeString.to_owned(),
global: GlobalField::from_rooted(&global),
@@ -55,7 +47,7 @@ impl Blob {

pub fn new(global: GlobalRef, bytes: Option<Vec<u8>>,
typeString: &str) -> Root<Blob> {
reflect_dom_object(box Blob::new_inherited(global, BlobTypeId::Blob, bytes, typeString),
reflect_dom_object(box Blob::new_inherited(global, bytes, typeString),
global,
BlobBinding::Wrap)
}
@@ -168,9 +160,6 @@ impl BlobMethods for Blob {

impl FileDerived for Blob {
fn is_file(&self) -> bool {
match self.type_ {
BlobTypeId::File => true,
_ => false
}
*self.type_id() == BlobTypeId::File
}
}
@@ -6,15 +6,16 @@

use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
use dom::bindings::codegen::InheritTypes::NodeCast;
use dom::bindings::codegen::InheritTypes::{CharacterDataDerived, ElementCast};
use dom::bindings::codegen::InheritTypes::{CharacterDataDerived, CharacterDataTypeId};
use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetTypeId};
use dom::bindings::codegen::InheritTypes::{NodeCast, NodeTypeId};
use dom::bindings::codegen::UnionTypes::NodeOrString;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::js::{LayoutJS, Root};
use dom::document::Document;
use dom::element::Element;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::node::{Node, NodeDamage, NodeTypeId};
use dom::eventtarget::EventTarget;
use dom::node::{Node, NodeDamage};
use std::borrow::ToOwned;
use std::cell::Ref;
use util::str::DOMString;
@@ -156,15 +157,6 @@ impl CharacterDataMethods for CharacterData {
}
}

/// The different types of CharacterData.
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum CharacterDataTypeId {
Comment,
Text,
ProcessingInstruction,
}


impl CharacterData {
#[inline]
pub fn data(&self) -> Ref<DOMString> {
@@ -10,7 +10,7 @@ use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
use dom::bindings::utils::reflect_dom_object;
use dom::event::{Event, EventBubbles, EventCancelable, EventTypeId};
use dom::event::{Event, EventBubbles, EventCancelable};
use script_task::ScriptChan;
use util::str::DOMString;

@@ -23,10 +23,10 @@ pub struct CloseEvent {
}

impl CloseEvent {
pub fn new_inherited(type_id: EventTypeId, wasClean: bool, code: u16,
pub fn new_inherited(wasClean: bool, code: u16,
reason: DOMString) -> CloseEvent {
CloseEvent {
event: Event::new_inherited(type_id),
event: Event::new_inherited(),
wasClean: wasClean,
code: code,
reason: reason,
@@ -40,8 +40,7 @@ impl CloseEvent {
wasClean: bool,
code: u16,
reason: DOMString) -> Root<CloseEvent> {
let event = box CloseEvent::new_inherited(EventTypeId::CloseEvent,
wasClean, code, reason);
let event = box CloseEvent::new_inherited(wasClean, code, reason);
let ev = reflect_dom_object(event, global, CloseEventBinding::Wrap);
{
let event = EventCast::from_ref(ev.r());
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.