mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
auto merge of #2049 : Ms2ger/servo/enum-jsval, r=jdm
This commit is contained in:
commit
68385dfde6
4 changed files with 48 additions and 52 deletions
|
@ -1089,18 +1089,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
|
||||||
return (setValue("(%s).to_jsval(cx)" % result), True)
|
return (setValue("(%s).to_jsval(cx)" % result), True)
|
||||||
|
|
||||||
if type.isEnum():
|
if type.isEnum():
|
||||||
if type.nullable():
|
return (setValue("(%s).to_jsval(cx)" % result), True)
|
||||||
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)
|
|
||||||
|
|
||||||
if type.isCallback():
|
if type.isCallback():
|
||||||
assert not type.isInterface()
|
assert not type.isInterface()
|
||||||
|
@ -1196,9 +1185,10 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
|
||||||
result = CGWrapper(result, pre="Option<", post=">")
|
result = CGWrapper(result, pre="Option<", post=">")
|
||||||
return result
|
return result
|
||||||
if returnType.isEnum():
|
if returnType.isEnum():
|
||||||
|
result = CGGeneric(returnType.unroll().inner.identifier.name)
|
||||||
if returnType.nullable():
|
if returnType.nullable():
|
||||||
raise TypeError("We don't support nullable enum return values")
|
result = CGWrapper(result, pre="Option<", post=">")
|
||||||
return CGGeneric(returnType.inner.identifier.name)
|
return result
|
||||||
if returnType.isGeckoInterface():
|
if returnType.isGeckoInterface():
|
||||||
descriptor = descriptorProvider.getDescriptor(
|
descriptor = descriptorProvider.getDescriptor(
|
||||||
returnType.unroll().inner.identifier.name)
|
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
|
# 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
|
# don't want to indent empty lines. So only indent lines that have a
|
||||||
# non-newline character on them.
|
# non-newline character on them.
|
||||||
lineStartDetector = re.compile("^(?=[^\n#])", re.MULTILINE)
|
lineStartDetector = re.compile("^(?=[^\n])", re.MULTILINE)
|
||||||
class CGIndenter(CGThing):
|
class CGIndenter(CGThing):
|
||||||
"""
|
"""
|
||||||
A class that takes another CGThing and generates code that indents that
|
A class that takes another CGThing and generates code that indents that
|
||||||
|
@ -2908,20 +2898,37 @@ def getEnumValueName(value):
|
||||||
class CGEnum(CGThing):
|
class CGEnum(CGThing):
|
||||||
def __init__(self, enum):
|
def __init__(self, enum):
|
||||||
CGThing.__init__(self)
|
CGThing.__init__(self)
|
||||||
self.enum = enum
|
inner = """
|
||||||
|
use dom::bindings::conversions::ToJSValConvertible;
|
||||||
|
use js::jsapi::JSContext;
|
||||||
|
use js::jsval::JSVal;
|
||||||
|
|
||||||
|
#[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)),
|
||||||
|
])
|
||||||
|
|
||||||
def define(self):
|
def define(self):
|
||||||
return """
|
return self.cgRoot.define()
|
||||||
#[repr(uint)]
|
|
||||||
pub enum valuelist {
|
|
||||||
%s
|
|
||||||
}
|
|
||||||
|
|
||||||
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 convertConstIDLValueToRust(value):
|
def convertConstIDLValueToRust(value):
|
||||||
|
@ -4656,15 +4663,7 @@ class CGBindingRoot(CGThing):
|
||||||
isCallback=True)
|
isCallback=True)
|
||||||
|
|
||||||
# Do codegen for all the enums
|
# Do codegen for all the enums
|
||||||
def makeEnum(e):
|
cgthings = [CGEnum(e) for e in config.getEnums(webIDLFile)]
|
||||||
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] ]
|
|
||||||
|
|
||||||
# Do codegen for all the dictionaries. We have to be a bit careful
|
# 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
|
# here, because we have to generate these in order from least derived
|
||||||
|
|
|
@ -566,14 +566,9 @@ pub fn InitIds(cx: *JSContext, specs: &[JSPropertySpec], ids: &mut [jsid]) -> bo
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EnumEntry {
|
|
||||||
value: &'static str,
|
|
||||||
length: uint
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn FindEnumStringIndex(cx: *JSContext,
|
pub fn FindEnumStringIndex(cx: *JSContext,
|
||||||
v: JSVal,
|
v: JSVal,
|
||||||
values: &[EnumEntry]) -> Result<uint, ()> {
|
values: &[&'static str]) -> Result<uint, ()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let jsstr = JS_ValueToString(cx, v);
|
let jsstr = JS_ValueToString(cx, v);
|
||||||
if jsstr.is_null() {
|
if jsstr.is_null() {
|
||||||
|
@ -585,16 +580,10 @@ pub fn FindEnumStringIndex(cx: *JSContext,
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
for (i, value) in values.iter().enumerate() {
|
for (i, value) in values.iter().enumerate() {
|
||||||
if value.length != length as uint {
|
let equal = value.len() == length as uint &&
|
||||||
continue;
|
range(0, length as int).all(|j| {
|
||||||
}
|
value[j] as u16 == *chars.offset(j)
|
||||||
let mut equal = true;
|
});
|
||||||
for j in range(0, length as int) {
|
|
||||||
if value.value[j] as u16 != *chars.offset(j) {
|
|
||||||
equal = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if equal {
|
if equal {
|
||||||
return Ok(i);
|
return Ok(i);
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
use dom::bindings::js::JS;
|
use dom::bindings::js::JS;
|
||||||
use dom::bindings::utils::{Reflector, Reflectable};
|
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::blob::Blob;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
@ -42,6 +44,7 @@ impl TestBinding {
|
||||||
pub fn SetDoubleAttribute(&self, _: f64) {}
|
pub fn SetDoubleAttribute(&self, _: f64) {}
|
||||||
pub fn StringAttribute(&self) -> DOMString { ~"" }
|
pub fn StringAttribute(&self) -> DOMString { ~"" }
|
||||||
pub fn SetStringAttribute(&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 InterfaceAttribute(&self) -> JS<Blob> { Blob::new(&self.window) }
|
||||||
pub fn SetInterfaceAttribute(&self, _: &JS<Blob>) {}
|
pub fn SetInterfaceAttribute(&self, _: &JS<Blob>) {}
|
||||||
pub fn AnyAttribute(&self, _: *JSContext) -> JSVal { NullValue() }
|
pub fn AnyAttribute(&self, _: *JSContext) -> JSVal { NullValue() }
|
||||||
|
@ -71,6 +74,7 @@ impl TestBinding {
|
||||||
pub fn SetDoubleAttributeNullable(&self, _: Option<f64>) {}
|
pub fn SetDoubleAttributeNullable(&self, _: Option<f64>) {}
|
||||||
pub fn GetStringAttributeNullable(&self) -> Option<DOMString> { Some(~"") }
|
pub fn GetStringAttributeNullable(&self) -> Option<DOMString> { Some(~"") }
|
||||||
pub fn SetStringAttributeNullable(&self, _: Option<DOMString>) {}
|
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 GetInterfaceAttributeNullable(&self) -> Option<JS<Blob>> { Some(Blob::new(&self.window)) }
|
||||||
pub fn SetInterfaceAttributeNullable(&self, _: Option<JS<Blob>>) {}
|
pub fn SetInterfaceAttributeNullable(&self, _: Option<JS<Blob>>) {}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
enum TestEnum { "", "foo", "bar" };
|
||||||
|
|
||||||
interface TestBinding {
|
interface TestBinding {
|
||||||
attribute boolean booleanAttribute;
|
attribute boolean booleanAttribute;
|
||||||
attribute byte byteAttribute;
|
attribute byte byteAttribute;
|
||||||
|
@ -15,6 +17,7 @@ interface TestBinding {
|
||||||
attribute float floatAttribute;
|
attribute float floatAttribute;
|
||||||
attribute double doubleAttribute;
|
attribute double doubleAttribute;
|
||||||
attribute DOMString stringAttribute;
|
attribute DOMString stringAttribute;
|
||||||
|
readonly attribute TestEnum enumAttribute;
|
||||||
attribute Blob interfaceAttribute;
|
attribute Blob interfaceAttribute;
|
||||||
attribute any anyAttribute;
|
attribute any anyAttribute;
|
||||||
|
|
||||||
|
@ -30,6 +33,7 @@ interface TestBinding {
|
||||||
attribute float? floatAttributeNullable;
|
attribute float? floatAttributeNullable;
|
||||||
attribute double? doubleAttributeNullable;
|
attribute double? doubleAttributeNullable;
|
||||||
attribute DOMString? stringAttributeNullable;
|
attribute DOMString? stringAttributeNullable;
|
||||||
|
readonly attribute TestEnum? enumAttributeNullable;
|
||||||
attribute Blob? interfaceAttributeNullable;
|
attribute Blob? interfaceAttributeNullable;
|
||||||
|
|
||||||
void passOptionalBoolean(optional boolean arg);
|
void passOptionalBoolean(optional boolean arg);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue