aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/dom/bindings/codegen/CodegenRust.py
diff options
context:
space:
mode:
authorMs2ger <ms2ger@gmail.com>2014-05-03 14:30:02 +0200
committerMs2ger <ms2ger@gmail.com>2014-05-05 11:29:46 +0200
commit455465f3c62a3e7a545920c6284589f0661317ac (patch)
treee83a42d6739ba481bc3498396e7ede353d4af3b4 /src/components/script/dom/bindings/codegen/CodegenRust.py
parente53c768b9ef765700d40fc153b295d7630f30baf (diff)
downloadservo-455465f3c62a3e7a545920c6284589f0661317ac.tar.gz
servo-455465f3c62a3e7a545920c6284589f0661317ac.zip
Move the handling of default values in getJSToNativeConversionTemplate into handleOptional.
This is a first step towards moving responsibility for default values into the caller, which should improve their code (in particular for the dictionary codegen. This also introduces a Dictionary::empty function, whose implementation is a hack. The implementation will be improved once its codegen has access to the raw default values. Besides dictionaries, this commit does not change the generated code.
Diffstat (limited to 'src/components/script/dom/bindings/codegen/CodegenRust.py')
-rw-r--r--src/components/script/dom/bindings/codegen/CodegenRust.py126
1 files changed, 51 insertions, 75 deletions
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py
index 0a0eb3b19eb..cf7b1908206 100644
--- a/src/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/src/components/script/dom/bindings/codegen/CodegenRust.py
@@ -474,7 +474,8 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
needsRooting = typeNeedsRooting(type, descriptorProvider)
- def handleOptional(template, declType, isOptional):
+ def handleOptional(template, declType, isOptional, default):
+ assert (defaultValue is None) == (default is None)
if isOptional:
template = "Some(%s)" % template
declType = CGWrapper(declType, pre="Option<", post=">")
@@ -482,6 +483,11 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
else:
initialValue = None
+ if default is not None:
+ template = CGIfElseWrapper("${haveValue}",
+ CGGeneric(template),
+ CGGeneric(default)).define()
+
return (template, declType, isOptional, initialValue, needsRooting)
# Unfortunately, .capitalize() on a string will lowercase things inside the
@@ -509,23 +515,17 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
exceptionCode))),
post="\n")
- # A helper function for handling default values. Takes a template
- # body and the C++ code to set the default value and wraps the
- # given template body in handling for the default value.
- def handleDefault(template, setDefault):
+ # A helper function for handling null default values. Checks that the
+ # default value, if it exists, is null.
+ def handleDefaultNull(nullValue):
if defaultValue is None:
- return template
- return CGIfElseWrapper("${haveValue}",
- CGGeneric(template),
- CGGeneric(setDefault)).define()
-
- # A helper function for handling null default values. Much like
- # handleDefault, but checks that the default value, if it exists, is null.
- def handleDefaultNull(template, codeToSetNull):
- if (defaultValue is not None and
- not isinstance(defaultValue, IDLNullValue)):
+ return None
+
+ if not isinstance(defaultValue, IDLNullValue):
raise TypeError("Can't handle non-null default value here")
- return handleDefault(template, codeToSetNull)
+
+ assert type.nullable() or type.isAny() or type.isDictionary()
+ return nullValue
# A helper function for wrapping up the template body for
# possibly-nullable objecty stuff
@@ -545,10 +545,6 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
"} else {\n" +
CGIndenter(onFailureNotAnObject(failureCode)).define() +
"}\n")
- if type.nullable():
- templateBody = handleDefaultNull(templateBody, "None")
- else:
- assert(defaultValue is None)
return templateBody
@@ -569,15 +565,12 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
if type.nullable():
declType = CGWrapper(declType, pre="Option<", post=" >")
- templateBody = CGGeneric("match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n"
- " Ok(value) => value,\n"
- " Err(()) => { %s },\n"
- "}" % exceptionCode)
+ templateBody = ("match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n"
+ " Ok(value) => value,\n"
+ " Err(()) => { %s },\n"
+ "}" % exceptionCode)
- templateBody = handleDefaultNull(templateBody.define(),
- "None")
-
- return handleOptional(templateBody, declType, isOptional)
+ return handleOptional(templateBody, declType, isOptional, handleDefaultNull("None"))
if type.isGeckoInterface():
assert not isEnforceRange and not isClamp
@@ -592,7 +585,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
template = wrapObjectTemplate(conversion, isDefinitelyObject, type,
failureCode)
- return handleOptional(template, declType, isOptional)
+ return handleOptional(template, declType, isOptional, handleDefaultNull("None"))
descriptorType = descriptor.memberType if isMember else descriptor.nativeType
@@ -622,7 +615,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
type, failureCode)
- return handleOptional(templateBody, declType, isOptional)
+ return handleOptional(templateBody, declType, isOptional, handleDefaultNull("None"))
if type.isSpiderMonkeyInterface():
raise TypeError("Can't handle SpiderMonkey interface arguments yet")
@@ -641,20 +634,19 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
else:
nullBehavior = treatAs[treatNullAs]
- def getConversionCode():
- conversionCode = (
- "match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n"
- " Ok(strval) => strval,\n"
- " Err(_) => { %s },\n"
- "}" % (nullBehavior, exceptionCode))
-
- if defaultValue is None:
- return conversionCode
-
- if isinstance(defaultValue, IDLNullValue):
- assert(type.nullable())
- return handleDefault(conversionCode, "None")
+ conversionCode = (
+ "match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n"
+ " Ok(strval) => strval,\n"
+ " Err(_) => { %s },\n"
+ "}" % (nullBehavior, exceptionCode))
+ if defaultValue is None:
+ default = None
+ elif isinstance(defaultValue, IDLNullValue):
+ assert type.nullable()
+ default = "None"
+ else:
+ assert defaultValue.type.tag() == IDLType.Tags.domstring
value = "str::from_utf8(data).unwrap().to_owned()"
if type.nullable():
value = "Some(%s)" % value
@@ -666,13 +658,11 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
", ".join(["'" + char + "' as u8" for char in defaultValue.value] + ["0"]),
value))
- return handleDefault(conversionCode, default)
-
declType = "DOMString"
if type.nullable():
declType = "Option<%s>" % declType
- return handleOptional(getConversionCode(), CGGeneric(declType), isOptional)
+ return handleOptional(conversionCode, CGGeneric(declType), isOptional, default)
if type.isByteString():
assert not isEnforceRange and not isClamp
@@ -686,11 +676,8 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
declType = CGGeneric("ByteString")
if type.nullable():
declType = CGWrapper(declType, pre="Option<", post=">")
- conversionCode = handleDefaultNull(conversionCode, "None")
- else:
- assert defaultValue is None
- return handleOptional(conversionCode, declType, isOptional)
+ return handleOptional(conversionCode, declType, isOptional, handleDefaultNull("None"))
if type.isEnum():
assert not isEnforceRange and not isClamp
@@ -718,12 +705,11 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
if defaultValue is not None:
assert(defaultValue.type.tag() == IDLType.Tags.domstring)
- template = handleDefault(template,
- ("%sValues::%s" %
- (enum,
- getEnumValueName(defaultValue.value))))
+ default = "%sValues::%s" % (enum, getEnumValueName(defaultValue.value))
+ else:
+ default = None
- return handleOptional(template, CGGeneric(enum), isOptional)
+ return handleOptional(template, CGGeneric(enum), isOptional, default)
if type.isCallback():
assert not isEnforceRange and not isClamp
@@ -749,8 +735,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
assert not isEnforceRange and not isClamp
declType = CGGeneric("JSVal")
- templateBody = handleDefaultNull("${val}", "NullValue()")
- return handleOptional(templateBody, declType, isOptional)
+ return handleOptional("${val}", declType, isOptional, handleDefaultNull("NullValue()"))
if type.isObject():
raise TypeError("Can't handle object arguments yet")
@@ -765,23 +750,13 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
assert not isOptional
typeName = CGDictionary.makeDictionaryName(type.inner)
-
declType = CGGeneric(typeName)
-
- # We do manual default value handling here, because we
- # actually do want a jsval, and we only handle null anyway
- if defaultValue is not None:
- assert(isinstance(defaultValue, IDLNullValue))
- val = "if ${haveValue} { ${val} } else { NullValue() }"
- else:
- val = "${val}"
-
- template = ("match %s::new(cx, %s) {\n"
+ template = ("match %s::new(cx, ${val}) {\n"
" Ok(dictionary) => dictionary,\n"
" Err(_) => return 0,\n"
- "}" % (typeName, val))
+ "}" % typeName)
- return handleOptional(template, declType, isOptional)
+ return handleOptional(template, declType, isOptional, handleDefaultNull("%s::empty()" % typeName))
if type.isVoid():
assert not isOptional
@@ -822,12 +797,10 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
if type.nullable():
defaultStr = "Some(%s)" % defaultStr
+ else:
+ defaultStr = None
- template = CGIfElseWrapper("${haveValue}",
- CGGeneric(template),
- CGGeneric(defaultStr)).define()
-
- return handleOptional(template, declType, isOptional)
+ return handleOptional(template, declType, isOptional, defaultStr)
def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
argcAndIndex=None):
@@ -4070,6 +4043,9 @@ class CGDictionary(CGThing):
return string.Template(
"impl<'a, 'b> ${selfName}<'a, 'b> {\n"
+ " pub fn empty() -> ${selfName} {\n"
+ " ${selfName}::new(ptr::null(), NullValue()).unwrap()\n"
+ " }\n"
" pub fn new(cx: *JSContext, val: JSVal) -> Result<${selfName}, ()> {\n"
" let object = if val.is_null_or_undefined() {\n"
" ptr::null()\n"