auto merge of #2550 : Ms2ger/servo/default-handling, r=jdm

This commit is contained in:
bors-servo 2014-06-02 18:01:22 -04:00
commit 52a809259a
2 changed files with 72 additions and 59 deletions

View file

@ -276,7 +276,7 @@ class CGMethodCall(CGThing):
# The argument at index distinguishingIndex can't possibly # The argument at index distinguishingIndex can't possibly
# be unset here, because we've already checked that argc is # be unset here, because we've already checked that argc is
# large enough that we can examine this argument. # large enough that we can examine this argument.
template, declType, needsRooting = getJSToNativeConversionTemplate( template, _, declType, needsRooting = getJSToNativeConversionTemplate(
type, descriptor, failureCode="break;", isDefinitelyObject=True) type, descriptor, failureCode="break;", isDefinitelyObject=True)
testCode = instantiateJSToNativeConversionTemplate( testCode = instantiateJSToNativeConversionTemplate(
@ -450,14 +450,14 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
substitution performed on it as follows: substitution performed on it as follows:
${val} replaced by an expression for the JS::Value in question ${val} replaced by an expression for the JS::Value in question
${haveValue} replaced by an expression that evaluates to a boolean
for whether we have a JS::Value. Only used when
defaultValue is not None.
2) A CGThing representing the native C++ type we're converting to 2) A string or None representing Rust code for the default value (if any).
3) A CGThing representing the native C++ type we're converting to
(declType). This is allowed to be None if the conversion code is (declType). This is allowed to be None if the conversion code is
supposed to be used as-is. supposed to be used as-is.
3) A boolean indicating whether the caller has to do optional-argument handling.
4) A boolean indicating whether the caller has to root the result.
""" """
# We should not have a defaultValue if we know we're an object # We should not have a defaultValue if we know we're an object
@ -474,12 +474,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
def handleOptional(template, declType, default): def handleOptional(template, declType, default):
assert (defaultValue is None) == (default is None) assert (defaultValue is None) == (default is None)
if default is not None: return (template, default, declType, needsRooting)
template = CGIfElseWrapper("${haveValue}",
CGGeneric(template),
CGGeneric(default)).define()
return (template, declType, needsRooting)
# Unfortunately, .capitalize() on a string will lowercase things inside the # Unfortunately, .capitalize() on a string will lowercase things inside the
# string, which we do not want. # string, which we do not want.
@ -727,9 +722,6 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
if allowTreatNonObjectAsNull and type.treatNonObjectAsNull(): if allowTreatNonObjectAsNull and type.treatNonObjectAsNull():
if not isDefinitelyObject: if not isDefinitelyObject:
haveObject = "${val}.is_object()" haveObject = "${val}.is_object()"
if defaultValue is not None:
assert isinstance(defaultValue, IDLNullValue)
haveObject = "${haveValue} && " + haveObject
template = CGIfElseWrapper(haveObject, template = CGIfElseWrapper(haveObject,
conversion, conversion,
CGGeneric("None")).define() CGGeneric("None")).define()
@ -744,7 +736,17 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
isDefinitelyObject, isDefinitelyObject,
type, type,
failureCode) failureCode)
return (template, declType, needsRooting)
if defaultValue is not None:
assert allowTreatNonObjectAsNull
assert type.treatNonObjectAsNull()
assert type.nullable()
assert isinstance(defaultValue, IDLNullValue)
default = "None"
else:
default = None
return (template, default, declType, needsRooting)
if type.isAny(): if type.isAny():
assert not isEnforceRange and not isClamp assert not isEnforceRange and not isClamp
@ -773,7 +775,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
if type.isVoid(): if type.isVoid():
# This one only happens for return values, and its easy: Just # This one only happens for return values, and its easy: Just
# ignore the jsval. # ignore the jsval.
return ("", None, False) return ("", None, None, False)
if not type.isPrimitive(): if not type.isPrimitive():
raise TypeError("Need conversion for argument type '%s'" % str(type)) raise TypeError("Need conversion for argument type '%s'" % str(type))
@ -893,10 +895,8 @@ class CGArgumentConverter(CGThing):
replacementVariables = { replacementVariables = {
"val": string.Template("(*${argv}.offset(${index}))").substitute(replacer), "val": string.Template("(*${argv}.offset(${index}))").substitute(replacer),
} }
if argument.defaultValue:
replacementVariables["haveValue"] = condition
template, declType, needsRooting = getJSToNativeConversionTemplate( template, default, declType, needsRooting = getJSToNativeConversionTemplate(
argument.type, argument.type,
descriptorProvider, descriptorProvider,
invalidEnumValueFatal=invalidEnumValueFatal, invalidEnumValueFatal=invalidEnumValueFatal,
@ -906,11 +906,20 @@ class CGArgumentConverter(CGThing):
isClamp=argument.clamp, isClamp=argument.clamp,
allowTreatNonObjectAsNull=argument.allowTreatNonCallableAsNull()) allowTreatNonObjectAsNull=argument.allowTreatNonCallableAsNull())
if argument.optional and not argument.defaultValue: if argument.optional:
declType = CGWrapper(declType, pre="Option<", post=">") if argument.defaultValue:
template = CGIfElseWrapper(condition, assert default
CGGeneric("Some(%s)" % template), template = CGIfElseWrapper(condition,
CGGeneric("None")).define() CGGeneric(template),
CGGeneric(default)).define()
else:
assert not default
declType = CGWrapper(declType, pre="Option<", post=">")
template = CGIfElseWrapper(condition,
CGGeneric("Some(%s)" % template),
CGGeneric("None")).define()
else:
assert not default
self.converter = instantiateJSToNativeConversionTemplate( self.converter = instantiateJSToNativeConversionTemplate(
template, replacementVariables, declType, "arg%d" % index, template, replacementVariables, declType, "arg%d" % index,
@ -2717,7 +2726,7 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
name = type.name name = type.name
typeName = "/*" + type.name + "*/" typeName = "/*" + type.name + "*/"
template, _, _ = getJSToNativeConversionTemplate( template, _, _, _ = getJSToNativeConversionTemplate(
type, descriptorProvider, failureCode="return Ok(None);", type, descriptorProvider, failureCode="return Ok(None);",
exceptionCode='return Err(());', exceptionCode='return Err(());',
isDefinitelyObject=True) isDefinitelyObject=True)
@ -3381,7 +3390,7 @@ class CGProxySpecialOperation(CGPerSignatureCall):
if operation.isSetter() or operation.isCreator(): if operation.isSetter() or operation.isCreator():
# arguments[0] is the index or name of the item that we're setting. # arguments[0] is the index or name of the item that we're setting.
argument = arguments[1] argument = arguments[1]
template, declType, needsRooting = getJSToNativeConversionTemplate( template, _, declType, needsRooting = getJSToNativeConversionTemplate(
argument.type, descriptor, treatNullAs=argument.treatNullAs) argument.type, descriptor, treatNullAs=argument.treatNullAs)
templateValues = { templateValues = {
"val": "(*desc).value", "val": "(*desc).value",
@ -4110,30 +4119,34 @@ class CGDictionary(CGThing):
return "/* uh oh */ %s" % name return "/* uh oh */ %s" % name
def getMemberType(self, memberInfo): def getMemberType(self, memberInfo):
_, (_, declType, _) = memberInfo member, (_, _, declType, _) = memberInfo
if not member.defaultValue:
declType = CGWrapper(declType, pre="Option<", post=">")
return declType.define() return declType.define()
def getMemberConversion(self, memberInfo): def getMemberConversion(self, memberInfo):
member, (templateBody, declType, _) = memberInfo def indent(s):
replacements = { "val": "value.unwrap()" } return CGIndenter(CGGeneric(s), 8).define()
if member.defaultValue:
replacements["haveValue"] = "value.is_some()"
propName = member.identifier.name member, (templateBody, default, declType, _) = memberInfo
conversion = CGIndenter( replacements = { "val": "value" }
CGGeneric(string.Template(templateBody).substitute(replacements)), conversion = string.Template(templateBody).substitute(replacements)
8).define()
if not member.defaultValue: assert (member.defaultValue is None) == (default is None)
raise TypeError("We don't support dictionary members without a " if not default:
"default value.") default = "None"
conversion = "Some(%s)" % conversion
conversion = ( conversion = (
"match get_dictionary_property(cx, object, \"%s\") {\n" "match get_dictionary_property(cx, object, \"%s\") {\n"
" Err(()) => return Err(()),\n" " Err(()) => return Err(()),\n"
" Ok(value) => {\n" " Ok(Some(value)) => {\n"
"%s\n" "%s\n"
" },\n" " },\n"
"}") % (propName, conversion) " Ok(None) => {\n"
"%s\n"
" },\n"
"}") % (member.identifier.name, indent(conversion), indent(default))
return CGGeneric(conversion) return CGGeneric(conversion)
@ -4894,7 +4907,7 @@ class CallbackMember(CGNativeMember):
isCallbackReturnValue = "JSImpl" isCallbackReturnValue = "JSImpl"
else: else:
isCallbackReturnValue = "Callback" isCallbackReturnValue = "Callback"
template, declType, needsRooting = getJSToNativeConversionTemplate( template, _, declType, needsRooting = getJSToNativeConversionTemplate(
self.retvalType, self.retvalType,
self.descriptorProvider, self.descriptorProvider,
exceptionCode=self.exceptionCode, exceptionCode=self.exceptionCode,

View file

@ -4,23 +4,23 @@
enum TestEnum { "", "foo", "bar" }; enum TestEnum { "", "foo", "bar" };
/* dictionary TestDictionary { dictionary TestDictionary {
// boolean booleanValue; boolean booleanValue;
// byte byteValue; byte byteValue;
// octet octetValue; octet octetValue;
// short shortValue; short shortValue;
// unsigned short unsignedShortValue; unsigned short unsignedShortValue;
// long longValue; long longValue;
// unsigned long unsignedLongValue; unsigned long unsignedLongValue;
// long long longLongValue; long long longLongValue;
// unsigned long long unsignedLongLongValue; unsigned long long unsignedLongLongValue;
// float floatValue; float floatValue;
// double doubleValue; double doubleValue;
// DOMString stringValue; DOMString stringValue;
// TestEnum enumValue; TestEnum enumValue;
// Blob interfaceValue; Blob interfaceValue;
// any anyValue; any anyValue;
}; */ };
dictionary TestDictionaryDefaults { dictionary TestDictionaryDefaults {
boolean booleanValue = false; boolean booleanValue = false;