mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
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:
commit
221db56b08
11 changed files with 183 additions and 21 deletions
|
@ -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])
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue