mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 768537 part 2. Allow dictionaries to be initialized with null or undefined, and treat them as dictionaries in which everything has its default value. r=peterv
This commit is contained in:
parent
8e925299c6
commit
fa17d85d47
@ -2058,35 +2058,30 @@ for (uint32_t i = 0; i < length; ++i) {
|
|||||||
if type.isDictionary():
|
if type.isDictionary():
|
||||||
if failureCode is not None:
|
if failureCode is not None:
|
||||||
raise TypeError("Can't handle dictionaries when failureCode is not None")
|
raise TypeError("Can't handle dictionaries when failureCode is not None")
|
||||||
|
# There are no nullable dictionaries
|
||||||
|
assert not type.nullable()
|
||||||
|
# All optional dictionaries always have default values, so we
|
||||||
|
# should be able to assume not isOptional here.
|
||||||
|
assert not isOptional
|
||||||
|
|
||||||
if type.nullable():
|
typeName = CGDictionary.makeDictionaryName(type.inner,
|
||||||
typeName = CGDictionary.makeDictionaryName(type.inner.inner,
|
descriptorProvider.workers)
|
||||||
descriptorProvider.workers)
|
actualTypeName = typeName
|
||||||
actualTypeName = "Nullable<%s>" % typeName
|
selfRef = "${declName}"
|
||||||
selfRef = "const_cast<%s&>(${declName}).SetValue()" % actualTypeName
|
|
||||||
else:
|
|
||||||
typeName = CGDictionary.makeDictionaryName(type.inner,
|
|
||||||
descriptorProvider.workers)
|
|
||||||
actualTypeName = typeName
|
|
||||||
selfRef = "${declName}"
|
|
||||||
|
|
||||||
declType = CGGeneric(actualTypeName)
|
declType = CGGeneric(actualTypeName)
|
||||||
|
|
||||||
# If we're optional or a member of something else, the const
|
# If we're a member of something else, the const
|
||||||
# will come from the Optional or our container.
|
# will come from the Optional or our container.
|
||||||
if not isOptional and not isMember:
|
if not isMember:
|
||||||
declType = CGWrapper(declType, pre="const ")
|
declType = CGWrapper(declType, pre="const ")
|
||||||
selfRef = "const_cast<%s&>(%s)" % (typeName, selfRef)
|
selfRef = "const_cast<%s&>(%s)" % (typeName, selfRef)
|
||||||
|
|
||||||
template = wrapObjectTemplate("if (!%s.Init(cx, &${val}.toObject())) {\n"
|
template = ("if (!%s.Init(cx, ${val})) {\n"
|
||||||
" return false;\n"
|
" return false;\n"
|
||||||
"}" % selfRef,
|
"}" % selfRef)
|
||||||
isDefinitelyObject, type,
|
|
||||||
("const_cast<%s&>(${declName}).SetNull()" %
|
|
||||||
actualTypeName),
|
|
||||||
descriptorProvider.workers, None)
|
|
||||||
|
|
||||||
return (template, declType, None, isOptional)
|
return (template, declType, None, False)
|
||||||
|
|
||||||
if not type.isPrimitive():
|
if not type.isPrimitive():
|
||||||
raise TypeError("Need conversion for argument type '%s'" % type)
|
raise TypeError("Need conversion for argument type '%s'" % type)
|
||||||
@ -2833,6 +2828,13 @@ class CGMethodCall(CGThing):
|
|||||||
|
|
||||||
distinguishingIndex = method.distinguishingIndexForArgCount(argCount)
|
distinguishingIndex = method.distinguishingIndexForArgCount(argCount)
|
||||||
|
|
||||||
|
# We can't handle unions at the distinguishing index.
|
||||||
|
for (returnType, args) in possibleSignatures:
|
||||||
|
if args[distinguishingIndex].type.isUnion():
|
||||||
|
raise TypeError("No support for unions as distinguishing "
|
||||||
|
"arguments yet: %s",
|
||||||
|
args[distinguishingIndex].location)
|
||||||
|
|
||||||
# Convert all our arguments up to the distinguishing index.
|
# Convert all our arguments up to the distinguishing index.
|
||||||
# Doesn't matter which of the possible signatures we use, since
|
# Doesn't matter which of the possible signatures we use, since
|
||||||
# they all have the same types up to that point; just use
|
# they all have the same types up to that point; just use
|
||||||
@ -2863,7 +2865,8 @@ class CGMethodCall(CGThing):
|
|||||||
|
|
||||||
# First check for null or undefined
|
# First check for null or undefined
|
||||||
pickFirstSignature("%s.isNullOrUndefined()" % distinguishingArg,
|
pickFirstSignature("%s.isNullOrUndefined()" % distinguishingArg,
|
||||||
lambda s: s[1][distinguishingIndex].type.nullable())
|
lambda s: (s[1][distinguishingIndex].type.nullable() or
|
||||||
|
s[1][distinguishingIndex].type.isDictionary()))
|
||||||
|
|
||||||
# Now check for distinguishingArg being an object that implements a
|
# Now check for distinguishingArg being an object that implements a
|
||||||
# non-callback interface. That includes typed arrays and
|
# non-callback interface. That includes typed arrays and
|
||||||
@ -3282,6 +3285,8 @@ def getUnionAccessorSignatureType(type, descriptorProvider):
|
|||||||
def getUnionTypeTemplateVars(type, descriptorProvider):
|
def getUnionTypeTemplateVars(type, descriptorProvider):
|
||||||
# For dictionaries and sequences we need to pass None as the failureCode
|
# For dictionaries and sequences we need to pass None as the failureCode
|
||||||
# for getJSToNativeConversionTemplate.
|
# for getJSToNativeConversionTemplate.
|
||||||
|
# Also, for dictionaries we would need to handle conversion of
|
||||||
|
# null/undefined to the dictionary correctly.
|
||||||
if type.isDictionary() or type.isSequence():
|
if type.isDictionary() or type.isSequence():
|
||||||
raise TypeError("Can't handle dictionaries or sequences in unions")
|
raise TypeError("Can't handle dictionaries or sequences in unions")
|
||||||
|
|
||||||
@ -4106,7 +4111,7 @@ class CGDictionary(CGThing):
|
|||||||
return (string.Template(
|
return (string.Template(
|
||||||
"struct ${selfName} ${inheritance}{\n"
|
"struct ${selfName} ${inheritance}{\n"
|
||||||
" ${selfName}() {}\n"
|
" ${selfName}() {}\n"
|
||||||
" bool Init(JSContext* cx, JSObject* obj);\n"
|
" bool Init(JSContext* cx, const JS::Value& val);\n"
|
||||||
"\n" +
|
"\n" +
|
||||||
"\n".join(memberDecls) + "\n"
|
"\n".join(memberDecls) + "\n"
|
||||||
"private:\n"
|
"private:\n"
|
||||||
@ -4126,7 +4131,7 @@ class CGDictionary(CGThing):
|
|||||||
d = self.dictionary
|
d = self.dictionary
|
||||||
if d.parent:
|
if d.parent:
|
||||||
initParent = ("// Per spec, we init the parent's members first\n"
|
initParent = ("// Per spec, we init the parent's members first\n"
|
||||||
"if (!%s::Init(cx, obj)) {\n"
|
"if (!%s::Init(cx, val)) {\n"
|
||||||
" return false;\n"
|
" return false;\n"
|
||||||
"}\n" % self.makeClassName(d.parent))
|
"}\n" % self.makeClassName(d.parent))
|
||||||
else:
|
else:
|
||||||
@ -4160,7 +4165,7 @@ class CGDictionary(CGThing):
|
|||||||
"}\n"
|
"}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"bool\n"
|
"bool\n"
|
||||||
"${selfName}::Init(JSContext* cx, JSObject* obj)\n"
|
"${selfName}::Init(JSContext* cx, const JS::Value& val)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" if (!initedIds && !InitIds(cx)) {\n"
|
" if (!initedIds && !InitIds(cx)) {\n"
|
||||||
" return false;\n"
|
" return false;\n"
|
||||||
@ -4168,6 +4173,10 @@ class CGDictionary(CGThing):
|
|||||||
"${initParent}"
|
"${initParent}"
|
||||||
" JSBool found;\n"
|
" JSBool found;\n"
|
||||||
" JS::Value temp;\n"
|
" JS::Value temp;\n"
|
||||||
|
" bool isNull = val.isNullOrUndefined();\n"
|
||||||
|
" if (!isNull && !val.isObject()) {\n"
|
||||||
|
" return Throw<${isMainThread}>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
|
||||||
|
" }\n"
|
||||||
"\n"
|
"\n"
|
||||||
"${initMembers}\n"
|
"${initMembers}\n"
|
||||||
" return true;\n"
|
" return true;\n"
|
||||||
@ -4175,7 +4184,8 @@ class CGDictionary(CGThing):
|
|||||||
"selfName": self.makeClassName(d),
|
"selfName": self.makeClassName(d),
|
||||||
"initParent": CGIndenter(CGGeneric(initParent)).define(),
|
"initParent": CGIndenter(CGGeneric(initParent)).define(),
|
||||||
"initMembers": "\n\n".join(memberInits),
|
"initMembers": "\n\n".join(memberInits),
|
||||||
"idInit": CGIndenter(idinit).define()
|
"idInit": CGIndenter(idinit).define(),
|
||||||
|
"isMainThread": toStringBool(not self.workers)
|
||||||
})
|
})
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -4222,13 +4232,15 @@ class CGDictionary(CGThing):
|
|||||||
"prop": "(this->%s)" % member.identifier.name,
|
"prop": "(this->%s)" % member.identifier.name,
|
||||||
"convert": string.Template(templateBody).substitute(replacements)
|
"convert": string.Template(templateBody).substitute(replacements)
|
||||||
}
|
}
|
||||||
conversion = ("if (!JS_HasPropertyById(cx, obj, ${propId}, &found)) {\n"
|
conversion = ("if (isNull) {\n"
|
||||||
|
" found = false;\n"
|
||||||
|
"} else if (!JS_HasPropertyById(cx, &val.toObject(), ${propId}, &found)) {\n"
|
||||||
" return false;\n"
|
" return false;\n"
|
||||||
"}\n")
|
"}\n")
|
||||||
if member.defaultValue:
|
if member.defaultValue:
|
||||||
conversion += (
|
conversion += (
|
||||||
"if (found) {\n"
|
"if (found) {\n"
|
||||||
" if (!JS_GetPropertyById(cx, obj, ${propId}, &temp)) {\n"
|
" if (!JS_GetPropertyById(cx, &val.toObject(), ${propId}, &temp)) {\n"
|
||||||
" return false;\n"
|
" return false;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"} else {\n"
|
"} else {\n"
|
||||||
@ -4241,7 +4253,7 @@ class CGDictionary(CGThing):
|
|||||||
conversion += (
|
conversion += (
|
||||||
"if (found) {\n"
|
"if (found) {\n"
|
||||||
" ${prop}.Construct();\n"
|
" ${prop}.Construct();\n"
|
||||||
" if (!JS_GetPropertyById(cx, obj, ${propId}, &temp)) {\n"
|
" if (!JS_GetPropertyById(cx, &val.toObject(), ${propId}, &temp)) {\n"
|
||||||
" return false;\n"
|
" return false;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"${convert}\n"
|
"${convert}\n"
|
||||||
|
@ -348,6 +348,8 @@ public:
|
|||||||
void PassDictionary(const Dict&, ErrorResult&);
|
void PassDictionary(const Dict&, ErrorResult&);
|
||||||
void PassOtherDictionary(const GrandparentDict&, ErrorResult&);
|
void PassOtherDictionary(const GrandparentDict&, ErrorResult&);
|
||||||
void PassSequenceOfDictionaries(const Sequence<Dict>&, ErrorResult&);
|
void PassSequenceOfDictionaries(const Sequence<Dict>&, ErrorResult&);
|
||||||
|
void PassDictionaryOrLong(const Dict&, ErrorResult&);
|
||||||
|
void PassDictionaryOrLong(int32_t, ErrorResult&);
|
||||||
|
|
||||||
// Methods and properties imported via "implements"
|
// Methods and properties imported via "implements"
|
||||||
bool GetImplementedProperty(ErrorResult&);
|
bool GetImplementedProperty(ErrorResult&);
|
||||||
|
@ -264,6 +264,8 @@ interface TestInterface {
|
|||||||
void passDictionary(optional Dict x);
|
void passDictionary(optional Dict x);
|
||||||
void passOtherDictionary(optional GrandparentDict x);
|
void passOtherDictionary(optional GrandparentDict x);
|
||||||
void passSequenceOfDictionaries(sequence<Dict> x);
|
void passSequenceOfDictionaries(sequence<Dict> x);
|
||||||
|
void passDictionaryOrLong(optional Dict x);
|
||||||
|
void passDictionaryOrLong(long x);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface TestNonWrapperCacheInterface {
|
interface TestNonWrapperCacheInterface {
|
||||||
|
Loading…
Reference in New Issue
Block a user