diff options
author | bors-servo <release+servo@mozilla.com> | 2014-04-06 15:31:30 -0400 |
---|---|---|
committer | bors-servo <release+servo@mozilla.com> | 2014-04-06 15:31:30 -0400 |
commit | 68385dfde6c17e282667213dc04ef8232b584f98 (patch) | |
tree | fd088b923d2a466bc007b03ad879d09f31259d0e /src | |
parent | 4386bae5763802346012c308646d7c39606f68ea (diff) | |
parent | a52cffebebd3607900200b46ac70f03de7062418 (diff) | |
download | servo-68385dfde6c17e282667213dc04ef8232b584f98.tar.gz servo-68385dfde6c17e282667213dc04ef8232b584f98.zip |
auto merge of #2049 : Ms2ger/servo/enum-jsval, r=jdm
Diffstat (limited to 'src')
-rw-r--r-- | src/components/script/dom/bindings/codegen/CodegenRust.py | 69 | ||||
-rw-r--r-- | src/components/script/dom/bindings/utils.rs | 21 | ||||
-rw-r--r-- | src/components/script/dom/testbinding.rs | 4 | ||||
-rw-r--r-- | src/components/script/dom/webidls/TestBinding.webidl | 4 |
4 files changed, 47 insertions, 51 deletions
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index cce35ffce82..6acd0225e25 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1089,18 +1089,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode, return (setValue("(%s).to_jsval(cx)" % result), True) if type.isEnum(): - if type.nullable(): - raise TypeError("We don't support nullable enumerated return types " - "yet") - return ("""assert!((%(result)s as uint) < %(strings)s.len()); -let %(resultStr)s: *JSString = JS_NewStringCopyN(cx, &%(strings)s[%(result)s as u32].value[0] as *i8, %(strings)s[%(result)s as u32].length as libc::size_t); -if %(resultStr)s.is_null() { - return 0; -} -""" % { "result" : result, - "resultStr" : result + "_str", - "strings" : type.inner.identifier.name + "Values::strings" } + - setValue("StringValue(&*(%s_str))" % result), False) + return (setValue("(%s).to_jsval(cx)" % result), True) if type.isCallback(): assert not type.isInterface() @@ -1196,9 +1185,10 @@ def getRetvalDeclarationForType(returnType, descriptorProvider): result = CGWrapper(result, pre="Option<", post=">") return result if returnType.isEnum(): + result = CGGeneric(returnType.unroll().inner.identifier.name) if returnType.nullable(): - raise TypeError("We don't support nullable enum return values") - return CGGeneric(returnType.inner.identifier.name) + result = CGWrapper(result, pre="Option<", post=">") + return result if returnType.isGeckoInterface(): descriptor = descriptorProvider.getDescriptor( returnType.unroll().inner.identifier.name) @@ -1549,7 +1539,7 @@ static NativeHooks: NativePropertyHooks = NativePropertyHooks { resolve_own_prop # We'll want to insert the indent at the beginnings of lines, but we # don't want to indent empty lines. So only indent lines that have a # non-newline character on them. -lineStartDetector = re.compile("^(?=[^\n#])", re.MULTILINE) +lineStartDetector = re.compile("^(?=[^\n])", re.MULTILINE) class CGIndenter(CGThing): """ A class that takes another CGThing and generates code that indents that @@ -2908,20 +2898,37 @@ def getEnumValueName(value): class CGEnum(CGThing): def __init__(self, enum): CGThing.__init__(self) - self.enum = enum + inner = """ +use dom::bindings::conversions::ToJSValConvertible; +use js::jsapi::JSContext; +use js::jsval::JSVal; - def define(self): - return """ - #[repr(uint)] - pub enum valuelist { - %s +#[repr(uint)] +pub enum valuelist { + %s +} + +pub static strings: &'static [&'static str] = &[ + %s, +]; + +impl ToJSValConvertible for valuelist { + fn to_jsval(&self, cx: *JSContext) -> JSVal { + strings[*self as uint].to_owned().to_jsval(cx) } +} +""" % (",\n ".join(map(getEnumValueName, enum.values())), + ",\n ".join(['&"%s"' % val for val in enum.values()])) + + self.cgRoot = CGList([ + CGNamespace.build([enum.identifier.name + "Values"], + CGIndenter(CGGeneric(inner)), public=True), + CGGeneric("pub type %s = self::%sValues::valuelist;\n" % + (enum.identifier.name, enum.identifier.name)), + ]) - pub static strings: &'static [EnumEntry] = &[ - %s, - ]; -""" % (",\n ".join(map(getEnumValueName, self.enum.values())), - ",\n ".join(['EnumEntry {value: &"' + val + '", length: ' + str(len(val)) + '}' for val in self.enum.values()])) + def define(self): + return self.cgRoot.define() def convertConstIDLValueToRust(value): @@ -4656,15 +4663,7 @@ class CGBindingRoot(CGThing): isCallback=True) # Do codegen for all the enums - def makeEnum(e): - return CGNamespace.build([e.identifier.name + "Values"], - CGList([CGGeneric(" use dom::bindings::utils::EnumEntry;"), - CGEnum(e)]), public=True) - def makeEnumTypedef(e): - return CGGeneric("pub type %s = self::%sValues::valuelist;\n" % - (e.identifier.name, e.identifier.name)) - cgthings = [ fun(e) for e in config.getEnums(webIDLFile) - for fun in [makeEnum, makeEnumTypedef] ] + cgthings = [CGEnum(e) for e in config.getEnums(webIDLFile)] # Do codegen for all the dictionaries. We have to be a bit careful # here, because we have to generate these in order from least derived diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index db6cb3290d7..0dce9953c3a 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -566,14 +566,9 @@ pub fn InitIds(cx: *JSContext, specs: &[JSPropertySpec], ids: &mut [jsid]) -> bo true } -pub struct EnumEntry { - value: &'static str, - length: uint -} - pub fn FindEnumStringIndex(cx: *JSContext, v: JSVal, - values: &[EnumEntry]) -> Result<uint, ()> { + values: &[&'static str]) -> Result<uint, ()> { unsafe { let jsstr = JS_ValueToString(cx, v); if jsstr.is_null() { @@ -585,16 +580,10 @@ pub fn FindEnumStringIndex(cx: *JSContext, return Err(()); } for (i, value) in values.iter().enumerate() { - if value.length != length as uint { - continue; - } - let mut equal = true; - for j in range(0, length as int) { - if value.value[j] as u16 != *chars.offset(j) { - equal = false; - break; - } - }; + let equal = value.len() == length as uint && + range(0, length as int).all(|j| { + value[j] as u16 == *chars.offset(j) + }); if equal { return Ok(i); diff --git a/src/components/script/dom/testbinding.rs b/src/components/script/dom/testbinding.rs index 8d7b4ce5c51..c391c44b181 100644 --- a/src/components/script/dom/testbinding.rs +++ b/src/components/script/dom/testbinding.rs @@ -4,6 +4,8 @@ use dom::bindings::js::JS; use dom::bindings::utils::{Reflector, Reflectable}; +use dom::bindings::codegen::TestBindingBinding::TestEnum; +use dom::bindings::codegen::TestBindingBinding::TestEnumValues::_empty; use dom::blob::Blob; use dom::window::Window; use servo_util::str::DOMString; @@ -42,6 +44,7 @@ impl TestBinding { pub fn SetDoubleAttribute(&self, _: f64) {} pub fn StringAttribute(&self) -> DOMString { ~"" } pub fn SetStringAttribute(&self, _: DOMString) {} + pub fn EnumAttribute(&self) -> TestEnum { _empty } pub fn InterfaceAttribute(&self) -> JS<Blob> { Blob::new(&self.window) } pub fn SetInterfaceAttribute(&self, _: &JS<Blob>) {} pub fn AnyAttribute(&self, _: *JSContext) -> JSVal { NullValue() } @@ -71,6 +74,7 @@ impl TestBinding { pub fn SetDoubleAttributeNullable(&self, _: Option<f64>) {} pub fn GetStringAttributeNullable(&self) -> Option<DOMString> { Some(~"") } pub fn SetStringAttributeNullable(&self, _: Option<DOMString>) {} + pub fn GetEnumAttributeNullable(&self) -> Option<TestEnum> { Some(_empty) } pub fn GetInterfaceAttributeNullable(&self) -> Option<JS<Blob>> { Some(Blob::new(&self.window)) } pub fn SetInterfaceAttributeNullable(&self, _: Option<JS<Blob>>) {} diff --git a/src/components/script/dom/webidls/TestBinding.webidl b/src/components/script/dom/webidls/TestBinding.webidl index 4aefa14728f..4cc2fac87f9 100644 --- a/src/components/script/dom/webidls/TestBinding.webidl +++ b/src/components/script/dom/webidls/TestBinding.webidl @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +enum TestEnum { "", "foo", "bar" }; + interface TestBinding { attribute boolean booleanAttribute; attribute byte byteAttribute; @@ -15,6 +17,7 @@ interface TestBinding { attribute float floatAttribute; attribute double doubleAttribute; attribute DOMString stringAttribute; + readonly attribute TestEnum enumAttribute; attribute Blob interfaceAttribute; attribute any anyAttribute; @@ -30,6 +33,7 @@ interface TestBinding { attribute float? floatAttributeNullable; attribute double? doubleAttributeNullable; attribute DOMString? stringAttributeNullable; + readonly attribute TestEnum? enumAttributeNullable; attribute Blob? interfaceAttributeNullable; void passOptionalBoolean(optional boolean arg); |