Use Option<T> to return from getters

This removes the cumbersome &mut bool argument and offers overall
a more readable code.
This commit is contained in:
Anthony Ramine 2016-08-29 00:55:29 +02:00
parent 6e1523f4ae
commit 7dfb336be8
22 changed files with 72 additions and 109 deletions

View file

@ -18,6 +18,7 @@ from WebIDL import (
BuiltinTypes, BuiltinTypes,
IDLBuiltinType, IDLBuiltinType,
IDLNullValue, IDLNullValue,
IDLNullableType,
IDLType, IDLType,
IDLInterfaceMember, IDLInterfaceMember,
IDLUndefinedValue, IDLUndefinedValue,
@ -4555,6 +4556,8 @@ class CGProxySpecialOperation(CGPerSignatureCall):
signature = operation.signatures()[0] signature = operation.signatures()[0]
(returnType, arguments) = signature (returnType, arguments) = signature
if operation.isGetter() and not returnType.nullable():
returnType = IDLNullableType(returnType.location, returnType)
# We pass len(arguments) as the final argument so that the # We pass len(arguments) as the final argument so that the
# CGPerSignatureCall won't do any argument conversion of its own. # CGPerSignatureCall won't do any argument conversion of its own.
@ -4577,8 +4580,6 @@ class CGProxySpecialOperation(CGPerSignatureCall):
self.cgRoot.prepend(instantiateJSToNativeConversionTemplate( self.cgRoot.prepend(instantiateJSToNativeConversionTemplate(
template, templateValues, declType, argument.identifier.name)) template, templateValues, declType, argument.identifier.name))
self.cgRoot.prepend(CGGeneric("rooted!(in(cx) let value = desc.value);")) self.cgRoot.prepend(CGGeneric("rooted!(in(cx) let value = desc.value);"))
elif operation.isGetter():
self.cgRoot.prepend(CGGeneric("let mut found = false;"))
def getArguments(self): def getArguments(self):
def process(arg): def process(arg):
@ -4587,10 +4588,6 @@ class CGProxySpecialOperation(CGPerSignatureCall):
argVal += ".r()" argVal += ".r()"
return argVal return argVal
args = [(a, process(a)) for a in self.arguments] args = [(a, process(a)) for a in self.arguments]
if self.idlNode.isGetter():
args.append((FakeArgument(BuiltinTypes[IDLBuiltinType.Types.boolean],
self.idlNode),
"&mut found"))
return args return args
def wrap_return_value(self): def wrap_return_value(self):
@ -4598,7 +4595,7 @@ class CGProxySpecialOperation(CGPerSignatureCall):
return "" return ""
wrap = CGGeneric(wrapForType(**self.templateValues)) wrap = CGGeneric(wrapForType(**self.templateValues))
wrap = CGIfWrapper("found", wrap) wrap = CGIfWrapper("let Some(result) = result", wrap)
return "\n" + wrap.define() return "\n" + wrap.define()
@ -4974,7 +4971,7 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod):
" let this = UnwrapProxy(proxy);\n" + " let this = UnwrapProxy(proxy);\n" +
" let this = &*this;\n" + " let this = &*this;\n" +
CGIndenter(CGProxyIndexedGetter(self.descriptor)).define() + "\n" + CGIndenter(CGProxyIndexedGetter(self.descriptor)).define() + "\n" +
" *bp = found;\n" + " *bp = result.is_some();\n" +
" return true;\n" + " return true;\n" +
"}\n\n") "}\n\n")
else: else:
@ -4990,7 +4987,7 @@ if RUST_JSID_IS_STRING(id) {
} }
if !has_on_proto { if !has_on_proto {
%s %s
*bp = found; *bp = result.is_some();
return true; return true;
} }
} }
@ -5274,7 +5271,9 @@ class CGInterfaceTrait(CGThing):
infallible = 'infallible' in descriptor.getExtendedAttributes(operation) infallible = 'infallible' in descriptor.getExtendedAttributes(operation)
if operation.isGetter(): if operation.isGetter():
arguments = method_arguments(descriptor, rettype, arguments, trailing=("found", "&mut bool")) if not rettype.nullable():
rettype = IDLNullableType(rettype.location, rettype)
arguments = method_arguments(descriptor, rettype, arguments)
# If this interface 'supports named properties', then we # If this interface 'supports named properties', then we
# should be able to access 'supported property names' # should be able to access 'supported property names'

View file

@ -100,18 +100,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-item // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-item
fn Item(&self, index: u32) -> DOMString { fn Item(&self, index: u32) -> DOMString {
let index = index as usize; self.IndexedGetter(index).unwrap_or_default()
let elem = self.owner.upcast::<Element>();
let style_attribute = elem.style_attribute().borrow();
style_attribute.as_ref().and_then(|declarations| {
declarations.declarations.get(index)
}).map(|&(ref declaration, importance)| {
let mut css = declaration.to_css_string();
if importance.important() {
css += " !important";
}
DOMString::from(css)
}).unwrap_or_else(DOMString::new)
} }
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
@ -333,10 +322,19 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
} }
// https://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface // https://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
fn IndexedGetter(&self, index: u32, found: &mut bool) -> DOMString { fn IndexedGetter(&self, index: u32) -> Option<DOMString> {
let rval = self.Item(index); let index = index as usize;
*found = index < self.Length(); let elem = self.owner.upcast::<Element>();
rval let style_attribute = elem.style_attribute().borrow();
style_attribute.as_ref().and_then(|declarations| {
declarations.declarations.get(index)
}).map(|&(ref declaration, importance)| {
let mut css = declaration.to_css_string();
if importance.important() {
css += " !important";
}
DOMString::from(css)
})
} }
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext

View file

@ -91,7 +91,7 @@ use euclid::point::Point2D;
use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks, QuirksMode}; use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks, QuirksMode};
use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::JS_GetRuntime; use js::jsapi::JS_GetRuntime;
use js::jsapi::{JSContext, JSObject, JSRuntime, JS_NewPlainObject}; use js::jsapi::{JSContext, JSObject, JSRuntime};
use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER}; use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER};
use msg::constellation_msg::{Key, KeyModifiers, KeyState}; use msg::constellation_msg::{Key, KeyModifiers, KeyState};
use msg::constellation_msg::{PipelineId, ReferrerPolicy, SubpageId}; use msg::constellation_msg::{PipelineId, ReferrerPolicy, SubpageId};
@ -2691,8 +2691,7 @@ impl DocumentMethods for Document {
#[allow(unsafe_code)] #[allow(unsafe_code)]
// https://html.spec.whatwg.org/multipage/#dom-tree-accessors:dom-document-nameditem-filter // https://html.spec.whatwg.org/multipage/#dom-tree-accessors:dom-document-nameditem-filter
fn NamedGetter(&self, cx: *mut JSContext, name: DOMString, found: &mut bool) fn NamedGetter(&self, _cx: *mut JSContext, name: DOMString) -> Option<NonZero<*mut JSObject>> {
-> NonZero<*mut JSObject> {
#[derive(JSTraceable, HeapSizeOf)] #[derive(JSTraceable, HeapSizeOf)]
struct NamedElementFilter { struct NamedElementFilter {
name: Atom, name: Atom,
@ -2758,28 +2757,23 @@ impl DocumentMethods for Document {
.peekable(); .peekable();
if let Some(first) = elements.next() { if let Some(first) = elements.next() {
if elements.peek().is_none() { if elements.peek().is_none() {
*found = true;
// TODO: Step 2. // TODO: Step 2.
// Step 3. // Step 3.
return unsafe { return unsafe {
NonZero::new(first.reflector().get_jsobject().get()) Some(NonZero::new(first.reflector().get_jsobject().get()))
}; };
} }
} else { } else {
*found = false; return None;
return unsafe {
NonZero::new(JS_NewPlainObject(cx))
};
} }
} }
// Step 4. // Step 4.
*found = true;
let filter = NamedElementFilter { let filter = NamedElementFilter {
name: name, name: name,
}; };
let collection = HTMLCollection::create(self.window(), root, box filter); let collection = HTMLCollection::create(self.window(), root, box filter);
unsafe { unsafe {
NonZero::new(collection.reflector().get_jsobject().get()) Some(NonZero::new(collection.reflector().get_jsobject().get()))
} }
} }

View file

@ -52,8 +52,7 @@ impl DOMRectListMethods for DOMRectList {
} }
// check-tidy: no specs after this line // check-tidy: no specs after this line
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<DOMRect>> { fn IndexedGetter(&self, index: u32) -> Option<Root<DOMRect>> {
*found = index < self.rects.len() as u32;
self.Item(index) self.Item(index)
} }
} }

View file

@ -47,10 +47,8 @@ impl DOMStringMapMethods for DOMStringMap {
} }
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-nameditem // https://html.spec.whatwg.org/multipage/#dom-domstringmap-nameditem
fn NamedGetter(&self, name: DOMString, found: &mut bool) -> DOMString { fn NamedGetter(&self, name: DOMString) -> Option<DOMString> {
let attr = self.element.get_custom_attr(name); self.element.get_custom_attr(name)
*found = attr.is_some();
attr.unwrap_or_default()
} }
// https://html.spec.whatwg.org/multipage/#the-domstringmap-interface:supported-property-names // https://html.spec.whatwg.org/multipage/#the-domstringmap-interface:supported-property-names

View file

@ -171,9 +171,7 @@ impl DOMTokenListMethods for DOMTokenList {
} }
// check-tidy: no specs after this line // check-tidy: no specs after this line
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<DOMString> { fn IndexedGetter(&self, index: u32) -> Option<DOMString> {
let item = self.Item(index); self.Item(index)
*found = item.is_some();
item
} }
} }

View file

@ -55,9 +55,7 @@ impl FileListMethods for FileList {
} }
// check-tidy: no specs after this line // check-tidy: no specs after this line
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<File>> { fn IndexedGetter(&self, index: u32) -> Option<Root<File>> {
let item = self.Item(index); self.Item(index)
*found = item.is_some();
item
} }
} }

View file

@ -317,17 +317,13 @@ impl HTMLCollectionMethods for HTMLCollection {
} }
// https://dom.spec.whatwg.org/#dom-htmlcollection-item // https://dom.spec.whatwg.org/#dom-htmlcollection-item
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<Element>> { fn IndexedGetter(&self, index: u32) -> Option<Root<Element>> {
let maybe_elem = self.Item(index); self.Item(index)
*found = maybe_elem.is_some();
maybe_elem
} }
// check-tidy: no specs after this line // check-tidy: no specs after this line
fn NamedGetter(&self, name: DOMString, found: &mut bool) -> Option<Root<Element>> { fn NamedGetter(&self, name: DOMString) -> Option<Root<Element>> {
let maybe_elem = self.NamedItem(name); self.NamedItem(name)
*found = maybe_elem.is_some();
maybe_elem
} }
// https://dom.spec.whatwg.org/#interface-htmlcollection // https://dom.spec.whatwg.org/#interface-htmlcollection

View file

@ -77,10 +77,8 @@ impl HTMLFormControlsCollectionMethods for HTMLFormControlsCollection {
} }
// https://html.spec.whatwg.org/multipage/#dom-htmlformcontrolscollection-nameditem // https://html.spec.whatwg.org/multipage/#dom-htmlformcontrolscollection-nameditem
fn NamedGetter(&self, name: DOMString, found: &mut bool) -> Option<RadioNodeListOrElement> { fn NamedGetter(&self, name: DOMString) -> Option<RadioNodeListOrElement> {
let maybe_elem = self.NamedItem(name); self.NamedItem(name)
*found = maybe_elem.is_some();
maybe_elem
} }
// https://html.spec.whatwg.org/multipage/#the-htmlformcontrolscollection-interface:supported-property-names // https://html.spec.whatwg.org/multipage/#the-htmlformcontrolscollection-interface:supported-property-names
@ -93,7 +91,7 @@ impl HTMLFormControlsCollectionMethods for HTMLFormControlsCollection {
// https://github.com/servo/servo/issues/5875 // https://github.com/servo/servo/issues/5875
// //
// https://dom.spec.whatwg.org/#dom-htmlcollection-item // https://dom.spec.whatwg.org/#dom-htmlcollection-item
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<Element>> { fn IndexedGetter(&self, index: u32) -> Option<Root<Element>> {
self.collection.IndexedGetter(index, found) self.collection.IndexedGetter(index)
} }
} }

View file

@ -230,9 +230,9 @@ impl HTMLFormElementMethods for HTMLFormElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-form-item // https://html.spec.whatwg.org/multipage/#dom-form-item
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<Element>> { fn IndexedGetter(&self, index: u32) -> Option<Root<Element>> {
let elements = self.Elements(); let elements = self.Elements();
elements.IndexedGetter(index, found) elements.IndexedGetter(index)
} }
} }

View file

@ -46,12 +46,12 @@ impl MimeTypeArrayMethods for MimeTypeArray {
} }
// https://html.spec.whatwg.org/multipage/#dom-mimetypearray-item // https://html.spec.whatwg.org/multipage/#dom-mimetypearray-item
fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<Root<MimeType>> { fn IndexedGetter(&self, _index: u32) -> Option<Root<MimeType>> {
None None
} }
// check-tidy: no specs after this line // check-tidy: no specs after this line
fn NamedGetter(&self, _name: DOMString, _found: &mut bool) -> Option<Root<MimeType>> { fn NamedGetter(&self, _name: DOMString) -> Option<Root<MimeType>> {
None None
} }

View file

@ -85,17 +85,13 @@ impl NamedNodeMapMethods for NamedNodeMap {
} }
// https://dom.spec.whatwg.org/#dom-namednodemap-item // https://dom.spec.whatwg.org/#dom-namednodemap-item
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<Attr>> { fn IndexedGetter(&self, index: u32) -> Option<Root<Attr>> {
let item = self.Item(index); self.Item(index)
*found = item.is_some();
item
} }
// check-tidy: no specs after this line // check-tidy: no specs after this line
fn NamedGetter(&self, name: DOMString, found: &mut bool) -> Option<Root<Attr>> { fn NamedGetter(&self, name: DOMString) -> Option<Root<Attr>> {
let item = self.GetNamedItem(name); self.GetNamedItem(name)
*found = item.is_some();
item
} }
// https://heycam.github.io/webidl/#dfn-supported-property-names // https://heycam.github.io/webidl/#dfn-supported-property-names

View file

@ -75,10 +75,8 @@ impl NodeListMethods for NodeList {
} }
// https://dom.spec.whatwg.org/#dom-nodelist-item // https://dom.spec.whatwg.org/#dom-nodelist-item
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<Node>> { fn IndexedGetter(&self, index: u32) -> Option<Root<Node>> {
let item = self.Item(index); self.Item(index)
*found = item.is_some();
item
} }
} }

View file

@ -45,12 +45,12 @@ impl PluginMethods for Plugin {
} }
// https://html.spec.whatwg.org/multipage/#dom-plugin-item // https://html.spec.whatwg.org/multipage/#dom-plugin-item
fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<Root<MimeType>> { fn IndexedGetter(&self, _index: u32) -> Option<Root<MimeType>> {
unreachable!() unreachable!()
} }
// check-tidy: no specs after this line // check-tidy: no specs after this line
fn NamedGetter(&self, _name: DOMString, _found: &mut bool) -> Option<Root<MimeType>> { fn NamedGetter(&self, _name: DOMString) -> Option<Root<MimeType>> {
unreachable!() unreachable!()
} }

View file

@ -50,12 +50,12 @@ impl PluginArrayMethods for PluginArray {
} }
// https://html.spec.whatwg.org/multipage/#dom-pluginarray-item // https://html.spec.whatwg.org/multipage/#dom-pluginarray-item
fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<Root<Plugin>> { fn IndexedGetter(&self, _index: u32) -> Option<Root<Plugin>> {
None None
} }
// check-tidy: no specs after this line // check-tidy: no specs after this line
fn NamedGetter(&self, _name: DOMString, _found: &mut bool) -> Option<Root<Plugin>> { fn NamedGetter(&self, _name: DOMString) -> Option<Root<Plugin>> {
None None
} }

View file

@ -105,7 +105,7 @@ impl RadioNodeListMethods for RadioNodeList {
// https://github.com/servo/servo/issues/5875 // https://github.com/servo/servo/issues/5875
// //
// https://dom.spec.whatwg.org/#dom-nodelist-item // https://dom.spec.whatwg.org/#dom-nodelist-item
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<Node>> { fn IndexedGetter(&self, index: u32) -> Option<Root<Node>> {
self.node_list.IndexedGetter(index, found) self.node_list.IndexedGetter(index)
} }
} }

View file

@ -136,10 +136,8 @@ impl StorageMethods for Storage {
} }
// check-tidy: no specs after this line // check-tidy: no specs after this line
fn NamedGetter(&self, name: DOMString, found: &mut bool) -> Option<DOMString> { fn NamedGetter(&self, name: DOMString) -> Option<DOMString> {
let item = self.GetItem(name); self.GetItem(name)
*found = item.is_some();
item
} }
fn NamedSetter(&self, name: DOMString, value: DOMString) -> ErrorResult { fn NamedSetter(&self, name: DOMString, value: DOMString) -> ErrorResult {

View file

@ -46,9 +46,7 @@ impl StyleSheetListMethods for StyleSheetList {
} }
// check-tidy: no specs after this line // check-tidy: no specs after this line
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<StyleSheet>>{ fn IndexedGetter(&self, index: u32) -> Option<Root<StyleSheet>> {
let item = self.Item(index); self.Item(index)
*found = item.is_some();
item
} }
} }

View file

@ -34,10 +34,8 @@ impl TestBindingIterable {
impl TestBindingIterableMethods for TestBindingIterable { impl TestBindingIterableMethods for TestBindingIterable {
fn Add(&self, v: DOMString) { self.vals.borrow_mut().push(v); } fn Add(&self, v: DOMString) { self.vals.borrow_mut().push(v); }
fn Length(&self) -> u32 { self.vals.borrow().len() as u32 } fn Length(&self) -> u32 { self.vals.borrow().len() as u32 }
fn GetItem(&self, n: u32) -> DOMString { self.vals.borrow().get(n as usize).unwrap().clone() } fn GetItem(&self, n: u32) -> DOMString { self.IndexedGetter(n).unwrap_or_default() }
fn IndexedGetter(&self, n: u32, found: &mut bool) -> DOMString { fn IndexedGetter(&self, n: u32) -> Option<DOMString> {
let s = self.GetItem(n); self.vals.borrow().get(n as usize).cloned()
*found = true;
s
} }
} }

View file

@ -23,10 +23,10 @@ impl TestBindingProxyMethods for TestBindingProxy {
fn SetItem(&self, _: u32, _: DOMString) -> () {} fn SetItem(&self, _: u32, _: DOMString) -> () {}
fn RemoveItem(&self, _: DOMString) -> () {} fn RemoveItem(&self, _: DOMString) -> () {}
fn Stringifier(&self) -> DOMString { DOMString::new() } fn Stringifier(&self) -> DOMString { DOMString::new() }
fn IndexedGetter(&self, _: u32, _: &mut bool) -> DOMString { DOMString::new() } fn IndexedGetter(&self, _: u32) -> Option<DOMString> { None }
fn NamedDeleter(&self, _: DOMString) -> () {} fn NamedDeleter(&self, _: DOMString) -> () {}
fn IndexedSetter(&self, _: u32, _: DOMString) -> () {} fn IndexedSetter(&self, _: u32, _: DOMString) -> () {}
fn NamedSetter(&self, _: DOMString, _: DOMString) -> () {} fn NamedSetter(&self, _: DOMString, _: DOMString) -> () {}
fn NamedGetter(&self, _: DOMString, _: &mut bool) -> DOMString { DOMString::new() } fn NamedGetter(&self, _: DOMString) -> Option<DOMString> { None }
} }

View file

@ -42,9 +42,7 @@ impl TouchListMethods for TouchList {
} }
/// https://w3c.github.io/touch-events/#widl-TouchList-item-getter-Touch-unsigned-long-index /// https://w3c.github.io/touch-events/#widl-TouchList-item-getter-Touch-unsigned-long-index
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<Touch>> { fn IndexedGetter(&self, index: u32) -> Option<Root<Touch>> {
let item = self.Item(index); self.Item(index)
*found = item.is_some();
item
} }
} }

View file

@ -88,8 +88,7 @@ impl XMLDocumentMethods for XMLDocument {
} }
// https://html.spec.whatwg.org/multipage/#dom-tree-accessors:dom-document-nameditem-filter // https://html.spec.whatwg.org/multipage/#dom-tree-accessors:dom-document-nameditem-filter
fn NamedGetter(&self, _cx: *mut JSContext, name: DOMString, found: &mut bool) fn NamedGetter(&self, _cx: *mut JSContext, name: DOMString) -> Option<NonZero<*mut JSObject>> {
-> NonZero<*mut JSObject> { self.upcast::<Document>().NamedGetter(_cx, name)
self.upcast::<Document>().NamedGetter(_cx, name, found)
} }
} }