зеркало из https://github.com/mozilla/gecko-dev.git
Bug 829248. Implement basic support for [TreatUndefinedAs=Missing] in WebIDL. r=khuey
This does not add support for [TreatUndefinedAs=Missing] in overloaded methods, since it's not clear what that should really look like. This also does not require that [TreatUndefinedAs=Missing] on an argument force it on all later arguments, since it's not clear that we want that long-term.
This commit is contained in:
Родитель
29483ee344
Коммит
c9eca87821
|
@ -2433,7 +2433,8 @@ class JSToNativeConversionInfo():
|
|||
${declName} replaced by the declaration's name
|
||||
${haveValue} replaced by an expression that evaluates to a boolean
|
||||
for whether we have a JS::Value. Only used when
|
||||
defaultValue is not None.
|
||||
defaultValue is not None or when True is passed for
|
||||
checkForValue to instantiateJSToNativeConversion.
|
||||
|
||||
declType: A CGThing representing the native C++ type we're converting
|
||||
to. This is allowed to be None if the conversion code is
|
||||
|
@ -3197,7 +3198,10 @@ for (uint32_t i = 0; i < length; ++i) {
|
|||
treatAs = {
|
||||
"Default": "eStringify",
|
||||
"EmptyString": "eEmpty",
|
||||
"Null": "eNull"
|
||||
"Null": "eNull",
|
||||
# For Missing it doesn't matter what we use here, since we'll never
|
||||
# call ConvertJSValueToString on undefined in that case.
|
||||
"Missing": "eStringify"
|
||||
}
|
||||
if type.nullable():
|
||||
# For nullable strings null becomes a null string.
|
||||
|
@ -3207,8 +3211,6 @@ for (uint32_t i = 0; i < length; ++i) {
|
|||
if treatUndefinedAs == "Default":
|
||||
treatUndefinedAs = "Null"
|
||||
nullBehavior = treatAs[treatNullAs]
|
||||
if treatUndefinedAs == "Missing":
|
||||
raise TypeError("We don't support [TreatUndefinedAs=Missing]")
|
||||
undefinedBehavior = treatAs[treatUndefinedAs]
|
||||
|
||||
def getConversionCode(varName):
|
||||
|
@ -3559,22 +3561,21 @@ for (uint32_t i = 0; i < length; ++i) {
|
|||
return JSToNativeConversionInfo(template, declType=declType,
|
||||
dealWithOptional=isOptional)
|
||||
|
||||
def instantiateJSToNativeConversion(info, replacements, argcAndIndex=None):
|
||||
def instantiateJSToNativeConversion(info, replacements, checkForValue=False):
|
||||
"""
|
||||
Take a JSToNativeConversionInfo as returned by getJSToNativeConversionInfo
|
||||
and a set of replacements as required by the strings in such an object, and
|
||||
generate code to convert into stack C++ types.
|
||||
|
||||
If argcAndIndex is not None it must be a dict that can be used to
|
||||
replace ${argc} and ${index}, where ${index} is the index of this
|
||||
argument (0-based) and ${argc} is the total number of arguments.
|
||||
If checkForValue is True, then the conversion will get wrapped in
|
||||
a check for ${haveValue}.
|
||||
"""
|
||||
(templateBody, declType, holderType, dealWithOptional) = (
|
||||
info.template, info.declType, info.holderType, info.dealWithOptional)
|
||||
|
||||
if dealWithOptional and argcAndIndex is None:
|
||||
if dealWithOptional and not checkForValue:
|
||||
raise TypeError("Have to deal with optional things, but don't know how")
|
||||
if argcAndIndex is not None and declType is None:
|
||||
if checkForValue and declType is None:
|
||||
raise TypeError("Need to predeclare optional things, so they will be "
|
||||
"outside the check for big enough arg count!");
|
||||
|
||||
|
@ -3623,7 +3624,7 @@ def instantiateJSToNativeConversion(info, replacements, argcAndIndex=None):
|
|||
string.Template(templateBody).substitute(replacements)
|
||||
)
|
||||
|
||||
if argcAndIndex is not None:
|
||||
if checkForValue:
|
||||
if dealWithOptional:
|
||||
declConstruct = CGIndenter(
|
||||
CGGeneric("%s.Construct(%s);" %
|
||||
|
@ -3644,8 +3645,8 @@ def instantiateJSToNativeConversion(info, replacements, argcAndIndex=None):
|
|||
|
||||
conversion = CGList(
|
||||
[CGGeneric(
|
||||
string.Template("if (${index} < ${argc}) {").substitute(
|
||||
argcAndIndex
|
||||
string.Template("if (${haveValue}) {").substitute(
|
||||
replacements
|
||||
)),
|
||||
declConstruct,
|
||||
holderConstruct,
|
||||
|
@ -3710,9 +3711,12 @@ class CGArgumentConverter(CGThing):
|
|||
self.replacementVariables["valMutableHandle"] = (
|
||||
"JS::MutableHandle<JS::Value>::fromMarkedLocation(%s)" %
|
||||
self.replacementVariables["valPtr"])
|
||||
if argument.defaultValue:
|
||||
self.replacementVariables["haveValue"] = string.Template(
|
||||
"${index} < ${argc}").substitute(replacer)
|
||||
haveValueCheck = string.Template("${index} < ${argc}").substitute(replacer)
|
||||
if argument.treatUndefinedAs == "Missing":
|
||||
haveValueCheck = (haveValueCheck +
|
||||
(" && !%s.isUndefined()" %
|
||||
self.replacementVariables["valHandle"]))
|
||||
self.replacementVariables["haveValue"] = haveValueCheck
|
||||
self.descriptorProvider = descriptorProvider
|
||||
if self.argument.optional and not self.argument.defaultValue:
|
||||
self.argcAndIndex = replacer
|
||||
|
@ -3742,7 +3746,7 @@ class CGArgumentConverter(CGThing):
|
|||
return instantiateJSToNativeConversion(
|
||||
typeConversion,
|
||||
self.replacementVariables,
|
||||
self.argcAndIndex).define()
|
||||
self.argcAndIndex is not None).define()
|
||||
|
||||
# Variadic arguments get turned into a sequence.
|
||||
if typeConversion.dealWithOptional:
|
||||
|
@ -4707,6 +4711,15 @@ class CGMethodCall(CGThing):
|
|||
CGWrapper(CGIndenter(CGGeneric(code)), pre="\n", post="\n"))
|
||||
return
|
||||
|
||||
# We don't handle [TreatUndefinedAs=Missing] arguments in overload
|
||||
# resolution yet.
|
||||
for (_, sigArgs) in signatures:
|
||||
for arg in sigArgs:
|
||||
if arg.treatUndefinedAs == "Missing":
|
||||
raise TypeError("No support for [TreatUndefinedAs=Missing] "
|
||||
"handling in overload resolution yet: %s" %
|
||||
arg.location)
|
||||
|
||||
# Need to find the right overload
|
||||
maxArgCount = method.maxArgCount
|
||||
allowedArgCounts = method.allowedArgCounts
|
||||
|
|
|
@ -398,25 +398,33 @@ class IDLObjectWithIdentifier(IDLObject):
|
|||
[self.location])
|
||||
self.treatNullAs = value
|
||||
elif identifier == "TreatUndefinedAs":
|
||||
if not self.type.isString():
|
||||
raise WebIDLError("[TreatUndefinedAs] is only allowed on "
|
||||
"arguments or attributes whose type is "
|
||||
"DOMString or DOMString?",
|
||||
[self.location])
|
||||
if isDictionaryMember:
|
||||
raise WebIDLError("[TreatUndefinedAs] is not allowed for "
|
||||
"dictionary members", [self.location])
|
||||
if value == 'Null':
|
||||
if not self.type.nullable():
|
||||
raise WebIDLError("[TreatUndefinedAs=Null] is only "
|
||||
"allowed on arguments whose type is "
|
||||
"DOMString?", [self.location])
|
||||
elif value == 'Missing':
|
||||
if value == 'Missing':
|
||||
if not isOptional:
|
||||
raise WebIDLError("[TreatUndefinedAs=Missing] is only "
|
||||
"allowed on optional arguments",
|
||||
[self.location])
|
||||
elif value != 'EmptyString':
|
||||
elif value == 'Null':
|
||||
if not self.type.isString():
|
||||
raise WebIDLError("[TreatUndefinedAs=Null] is only "
|
||||
"allowed on arguments or "
|
||||
"attributes whose type is "
|
||||
"DOMString or DOMString?",
|
||||
[self.location])
|
||||
if not self.type.nullable():
|
||||
raise WebIDLError("[TreatUndefinedAs=Null] is only "
|
||||
"allowed on arguments whose type "
|
||||
"is DOMString?", [self.location])
|
||||
elif value == 'EmptyString':
|
||||
if not self.type.isString():
|
||||
raise WebIDLError("[TreatUndefinedAs=EmptyString] "
|
||||
"is only allowed on arguments or "
|
||||
"attributes whose type is "
|
||||
"DOMString or DOMString?",
|
||||
[self.location])
|
||||
else:
|
||||
raise WebIDLError("[TreatUndefinedAs] must take the "
|
||||
"identifiers EmptyString or Null or "
|
||||
"Missing", [self.location])
|
||||
|
|
|
@ -156,7 +156,9 @@ public:
|
|||
void PassByte(int8_t);
|
||||
int8_t ReceiveByte();
|
||||
void PassOptionalByte(const Optional<int8_t>&);
|
||||
void PassOptionalUndefinedMissingByte(const Optional<int8_t>&);
|
||||
void PassOptionalByteWithDefault(int8_t);
|
||||
void PassOptionalUndefinedMissingByteWithDefault(int8_t);
|
||||
void PassNullableByte(const Nullable<int8_t>&);
|
||||
void PassOptionalNullableByte(const Optional< Nullable<int8_t> >&);
|
||||
void PassVariadicByte(const Sequence<int8_t>&);
|
||||
|
@ -400,7 +402,9 @@ public:
|
|||
void PassString(const nsAString&);
|
||||
void PassNullableString(const nsAString&);
|
||||
void PassOptionalString(const Optional<nsAString>&);
|
||||
void PassOptionalUndefinedMissingString(const Optional<nsAString>&);
|
||||
void PassOptionalStringWithDefaultValue(const nsAString&);
|
||||
void PassOptionalUndefinedMissingStringWithDefaultValue(const nsAString&);
|
||||
void PassOptionalNullableString(const Optional<nsAString>&);
|
||||
void PassOptionalNullableStringWithDefaultValue(const nsAString&);
|
||||
void PassVariadicString(const Sequence<nsString>&);
|
||||
|
|
|
@ -118,7 +118,9 @@ interface TestInterface {
|
|||
void passByte(byte arg);
|
||||
byte receiveByte();
|
||||
void passOptionalByte(optional byte arg);
|
||||
void passOptionalUndefinedMissingByte([TreatUndefinedAs=Missing] optional byte arg);
|
||||
void passOptionalByteWithDefault(optional byte arg = 0);
|
||||
void passOptionalUndefinedMissingByteWithDefault([TreatUndefinedAs=Missing] optional byte arg = 0);
|
||||
void passNullableByte(byte? arg);
|
||||
void passOptionalNullableByte(optional byte? arg);
|
||||
void passVariadicByte(byte... arg);
|
||||
|
@ -368,7 +370,9 @@ interface TestInterface {
|
|||
void passString(DOMString arg);
|
||||
void passNullableString(DOMString? arg);
|
||||
void passOptionalString(optional DOMString arg);
|
||||
void passOptionalUndefinedMissingString([TreatUndefinedAs=Missing] optional DOMString arg);
|
||||
void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
|
||||
void passOptionalUndefinedMissingStringWithDefaultValue([TreatUndefinedAs=Missing] optional DOMString arg = "abc");
|
||||
void passOptionalNullableString(optional DOMString? arg);
|
||||
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
|
||||
void passVariadicString(DOMString... arg);
|
||||
|
|
|
@ -23,7 +23,9 @@ interface TestExampleInterface {
|
|||
void passByte(byte arg);
|
||||
byte receiveByte();
|
||||
void passOptionalByte(optional byte arg);
|
||||
void passOptionalUndefinedMissingByte([TreatUndefinedAs=Missing] optional byte arg);
|
||||
void passOptionalByteWithDefault(optional byte arg = 0);
|
||||
void passOptionalUndefinedMissingByteWithDefault([TreatUndefinedAs=Missing] optional byte arg = 0);
|
||||
void passNullableByte(byte? arg);
|
||||
void passOptionalNullableByte(optional byte? arg);
|
||||
void passVariadicByte(byte... arg);
|
||||
|
@ -266,7 +268,9 @@ interface TestExampleInterface {
|
|||
void passString(DOMString arg);
|
||||
void passNullableString(DOMString? arg);
|
||||
void passOptionalString(optional DOMString arg);
|
||||
void passOptionalUndefinedMissingString([TreatUndefinedAs=Missing] optional DOMString arg);
|
||||
void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
|
||||
void passOptionalUndefinedMissingStringWithDefaultValue([TreatUndefinedAs=Missing] optional DOMString arg = "abc");
|
||||
void passOptionalNullableString(optional DOMString? arg);
|
||||
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
|
||||
void passVariadicString(DOMString... arg);
|
||||
|
|
|
@ -35,7 +35,9 @@ interface TestJSImplInterface {
|
|||
void passByte(byte arg);
|
||||
byte receiveByte();
|
||||
void passOptionalByte(optional byte arg);
|
||||
void passOptionalUndefinedMissingByte([TreatUndefinedAs=Missing] optional byte arg);
|
||||
void passOptionalByteWithDefault(optional byte arg = 0);
|
||||
void passOptionalUndefinedMissingByteWithDefault([TreatUndefinedAs=Missing] optional byte arg = 0);
|
||||
void passNullableByte(byte? arg);
|
||||
void passOptionalNullableByte(optional byte? arg);
|
||||
void passVariadicByte(byte... arg);
|
||||
|
@ -289,7 +291,9 @@ interface TestJSImplInterface {
|
|||
void passString(DOMString arg);
|
||||
void passNullableString(DOMString? arg);
|
||||
void passOptionalString(optional DOMString arg);
|
||||
void passOptionalUndefinedMissingString([TreatUndefinedAs=Missing] optional DOMString arg);
|
||||
void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
|
||||
void passOptionalUndefinedMissingStringWithDefaultValue([TreatUndefinedAs=Missing] optional DOMString arg = "abc");
|
||||
void passOptionalNullableString(optional DOMString? arg);
|
||||
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
|
||||
void passVariadicString(DOMString... arg);
|
||||
|
|
Загрузка…
Ссылка в новой задаче