aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorbors-servo <release+servo@mozilla.com>2014-04-06 15:31:30 -0400
committerbors-servo <release+servo@mozilla.com>2014-04-06 15:31:30 -0400
commit68385dfde6c17e282667213dc04ef8232b584f98 (patch)
treefd088b923d2a466bc007b03ad879d09f31259d0e /src
parent4386bae5763802346012c308646d7c39606f68ea (diff)
parenta52cffebebd3607900200b46ac70f03de7062418 (diff)
downloadservo-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.py69
-rw-r--r--src/components/script/dom/bindings/utils.rs21
-rw-r--r--src/components/script/dom/testbinding.rs4
-rw-r--r--src/components/script/dom/webidls/TestBinding.webidl4
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);