Auto merge of #11155 - emilio:codegen-dict-keyword, r=Ms2ger

codegen: Fix dictionary handling and semantics

Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data:
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #11152 (github issue number if applicable).

Either:
- [x] There are tests for these changes OR
- [ ] These changes do not require tests because _____

Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process.

Fixes #11152

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11155)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-05-13 02:47:08 -07:00
commit 221db56b08
11 changed files with 183 additions and 21 deletions

View file

@ -662,12 +662,17 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
'%s' % (firstCap(sourceDescription), exceptionCode))),
post="\n")
def onFailureInvalidEnumValue(failureCode, passedVarName):
return CGGeneric(
failureCode or
('throw_type_error(cx, &format!("\'{}\' is not a valid enum value for enumeration \'%s\'.", %s)); %s'
% (type.name, passedVarName, exceptionCode)))
def onFailureNotCallable(failureCode):
return CGWrapper(
CGGeneric(
failureCode or
('throw_type_error(cx, \"%s is not callable.\");\n'
'%s' % (firstCap(sourceDescription), exceptionCode))))
return CGGeneric(
failureCode or
('throw_type_error(cx, \"%s is not callable.\");\n'
'%s' % (firstCap(sourceDescription), exceptionCode)))
# A helper function for handling null default values. Checks that the
# default value, if it exists, is null.
@ -868,15 +873,15 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
"yet")
enum = type.inner.identifier.name
if invalidEnumValueFatal:
handleInvalidEnumValueCode = exceptionCode
handleInvalidEnumValueCode = onFailureInvalidEnumValue(failureCode, 'search').define()
else:
handleInvalidEnumValueCode = "return true;"
template = (
"match find_enum_string_index(cx, ${val}, %(values)s) {\n"
" Err(_) => { %(exceptionCode)s },\n"
" Ok(None) => { %(handleInvalidEnumValueCode)s },\n"
" Ok(Some(index)) => {\n"
" Ok((None, search)) => { %(handleInvalidEnumValueCode)s },\n"
" Ok((Some(index), _)) => {\n"
" //XXXjdm need some range checks up in here.\n"
" mem::transmute(index)\n"
" },\n"
@ -5295,14 +5300,23 @@ class CGDictionary(CGThing):
conversion = self.getMemberConversion(memberInfo, member.type)
return CGGeneric("%s: %s,\n" % (name, conversion.define()))
def varInsert(varName, dictionaryName):
insertion = ("let mut %s_js = RootedValue::new(cx, UndefinedValue());\n"
"%s.to_jsval(cx, %s_js.handle_mut());\n"
"set_dictionary_property(cx, obj.handle(), \"%s\", %s_js.handle()).unwrap();"
% (varName, varName, varName, dictionaryName, varName))
return CGGeneric(insertion)
def memberInsert(memberInfo):
member, _ = memberInfo
name = self.makeMemberName(member.identifier.name)
insertion = ("let mut %s = RootedValue::new(cx, UndefinedValue());\n"
"self.%s.to_jsval(cx, %s.handle_mut());\n"
"set_dictionary_property(cx, obj.handle(), \"%s\", %s.handle()).unwrap();"
% (name, name, name, name, name))
return CGGeneric("%s\n" % insertion)
if member.optional and not member.defaultValue:
insertion = CGIfWrapper("let Some(ref %s) = self.%s" % (name, name),
varInsert(name, member.identifier.name))
else:
insertion = CGGeneric("let %s = &self.%s;\n%s" %
(name, name, varInsert(name, member.identifier.name).define()))
return CGGeneric("%s\n" % insertion.define())
memberInits = CGList([memberInit(m) for m in self.memberInfo])
memberInserts = CGList([memberInsert(m) for m in self.memberInfo])

View file

@ -39,6 +39,7 @@ use std::ptr;
use std::slice;
use util::non_geckolib::jsstring_to_str;
use util::prefs;
use util::str::DOMString;
/// Proxy handler for a WindowProxy.
pub struct WindowProxyHandler(pub *const libc::c_void);
@ -182,18 +183,18 @@ pub fn get_array_index_from_id(_cx: *mut JSContext, id: HandleId) -> Option<u32>
/// Find the index of a string given by `v` in `values`.
/// Returns `Err(())` on JSAPI failure (there is a pending exception), and
/// `Ok(None)` if there was no matching string.
/// `Ok((None, value))` if there was no matching string.
pub unsafe fn find_enum_string_index(cx: *mut JSContext,
v: HandleValue,
values: &[&'static str])
-> Result<Option<usize>, ()> {
-> Result<(Option<usize>, DOMString), ()> {
let jsstr = ToString(cx, v);
if jsstr.is_null() {
return Err(());
}
let search = jsstring_to_str(cx, jsstr);
Ok(values.iter().position(|value| search == *value))
Ok((values.iter().position(|value| search == *value), search))
}
/// Returns wether `obj` is a platform object