Bug 929512. Fix null default values for non-nullable unions containing a nullable type. r=dzbarsky, r=smaug pending

This commit is contained in:
Boris Zbarsky 2013-10-28 00:33:15 -04:00
parent f158da18a1
commit 97c2bf7f74
6 changed files with 52 additions and 7 deletions

View File

@ -3061,14 +3061,21 @@ for (uint32_t i = 0; i < length; ++i) {
typeName = "Nullable<" + typeName + " >"
def handleNull(templateBody, setToNullVar, extraConditionForNull=""):
null = CGGeneric("if (%s${val}.isNullOrUndefined()) {\n"
" %s.SetNull();\n"
"}" % (extraConditionForNull, setToNullVar))
templateBody = CGWrapper(CGIndenter(templateBody), pre="{\n", post="\n}")
return CGList([null, templateBody], " else ")
nullTest = "%s${val}.isNullOrUndefined()" % extraConditionForNull
return CGIfElseWrapper(nullTest,
CGGeneric("%s.SetNull();" % setToNullVar),
templateBody)
if type.hasNullableType:
templateBody = handleNull(templateBody, unionArgumentObj)
assert not nullable
# Make sure to handle a null default value here
if defaultValue and isinstance(defaultValue, IDLNullValue):
assert defaultValue.type == type
extraConditionForNull = "!(${haveValue}) || "
else:
extraConditionForNull = ""
templateBody = handleNull(templateBody, unionArgumentObj,
extraConditionForNull=extraConditionForNull)
declType = CGGeneric(typeName)
holderType = CGGeneric(argumentTypeName) if not isMember else None
@ -3124,6 +3131,22 @@ for (uint32_t i = 0; i < length; ++i) {
extraConditionForNull = ""
templateBody = handleNull(templateBody, declLoc,
extraConditionForNull=extraConditionForNull)
elif (not type.hasNullableType and defaultValue and
isinstance(defaultValue, IDLNullValue)):
assert type.hasDictionaryType
assert defaultValue.type.isDictionary()
if not isMember and typeNeedsRooting(defaultValue.type):
ctorArgs = "cx"
else:
ctorArgs = ""
initDictionaryWithNull = CGIfWrapper(
CGGeneric("return false;"),
('!%s.SetAs%s(%s).Init(cx, JS::NullHandleValue, "Member of %s")'
% (declLoc, getUnionMemberName(defaultValue.type),
ctorArgs, type)))
templateBody = CGIfElseWrapper("!(${haveValue})",
initDictionaryWithNull,
templateBody)
templateBody = CGList([constructDecl, templateBody], "\n")

View File

@ -2440,7 +2440,10 @@ class IDLValue(IDLObject):
# We first check for unions to ensure that even if the union is nullable
# we end up with the right flat member type, not the union's type.
if type.isUnion():
for subtype in type.unroll().memberTypes:
# We use the flat member types here, because if we have a nullable
# member type, or a nested union, we want the type the value
# actually coerces to, not the nullable or nested union type.
for subtype in type.unroll().flatMemberTypes:
try:
coercedValue = self.coerceToType(subtype, location)
# Create a new IDLValue to make sure that we have the
@ -2513,6 +2516,13 @@ class IDLNullValue(IDLObject):
[location])
nullValue = IDLNullValue(self.location)
if type.isUnion() and not type.nullable() and type.hasDictionaryType:
# We're actually a default value for the union's dictionary member.
# Use its type.
for t in type.flatMemberTypes:
if t.isDictionary():
nullValue.type = t
return nullValue
nullValue.type = type
return nullValue

View File

@ -513,6 +513,9 @@ public:
void PassUnion9(JSContext*, const ObjectOrStringOrLongOrBoolean& arg);
void PassUnion10(const EventInitOrLong& arg);
void PassUnion11(JSContext*, const CustomEventInitOrLong& arg);
void PassUnion12(const EventInitOrLong& arg);
void PassUnion13(JSContext*, const ObjectOrLongOrNull& arg);
void PassUnion14(JSContext*, const ObjectOrLongOrNull& arg);
#endif
void PassNullableUnion(JSContext*, const Nullable<ObjectOrLong>&);
void PassOptionalUnion(JSContext*, const Optional<ObjectOrLong>&);

View File

@ -453,6 +453,9 @@ interface TestInterface {
void passUnion9((object or DOMString or long or boolean) arg);
void passUnion10(optional (EventInit or long) arg);
void passUnion11(optional (CustomEventInit or long) arg);
void passUnion12(optional (EventInit or long) arg = 5);
void passUnion13(optional (object or long?) arg = null);
void passUnion14(optional (object or long?) arg = 5);
#endif
void passUnionWithNullable((object? or long) arg);
void passNullableUnion((object or long)? arg);

View File

@ -349,6 +349,9 @@ interface TestExampleInterface {
void passUnion9((object or DOMString or long or boolean) arg);
void passUnion10(optional (EventInit or long) arg);
void passUnion11(optional (CustomEventInit or long) arg);
void passUnion12(optional (EventInit or long) arg = 5);
void passUnion13(optional (object or long?) arg = null);
void passUnion14(optional (object or long?) arg = 5);
#endif
void passUnionWithNullable((object? or long) arg);
void passNullableUnion((object or long)? arg);

View File

@ -371,6 +371,9 @@ interface TestJSImplInterface {
void passUnion9((object or DOMString or long or boolean) arg);
void passUnion10(optional (EventInit or long) arg);
void passUnion11(optional (CustomEventInit or long) arg);
void passUnion12(optional (EventInit or long) arg = 5);
void passUnion13(optional (object or long?) arg = null);
void passUnion14(optional (object or long?) arg = 5);
#endif
void passUnionWithNullable((object? or long) arg);
// FIXME: Bug 863948 Nullable unions not supported yet