Bug 1292293 - Part 1: Update the WebIDL Parser to allow default values for ByteString, r=bz

--HG--
extra : rebase_source : 8d031a5a34e4bb75a3432e23e625370cbcea0dae
This commit is contained in:
Michael Layzell 2016-08-05 17:46:54 -04:00
parent 97989b02e7
commit 164944c0c0
7 changed files with 132 additions and 24 deletions

View File

@ -4235,17 +4235,19 @@ def getHandleDefault(defaultValue):
def handleDefaultStringValue(defaultValue, method):
"""
Returns a string which ends up calling 'method' with a (char16_t*, length)
Returns a string which ends up calling 'method' with a (char_t*, length)
pair that sets this string default value. This string is suitable for
passing as the second argument of handleDefault; in particular it does not
end with a ';'
"""
assert defaultValue.type.isDOMString()
return ("static const char16_t data[] = { %s };\n"
"%s(data, ArrayLength(data) - 1)" %
(", ".join(["'" + char + "'" for char in
defaultValue.value] + ["0"]),
method))
assert defaultValue.type.isDOMString() or defaultValue.type.isByteString()
return ("static const %(char_t)s data[] = { %(data)s };\n"
"%(method)s(data, ArrayLength(data) - 1)") % {
'char_t': "char" if defaultValue.type.isByteString() else "char16_t",
'method': method,
'data': ", ".join(["'" + char + "'" for char in
defaultValue.value] + ["0"])
}
# If this function is modified, modify CGNativeMember.getArg and
@ -5462,8 +5464,14 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
nullable=nullable,
exceptionCode=exceptionCode)
# ByteString arguments cannot have a default value.
assert defaultValue is None
if defaultValue is not None:
if isinstance(defaultValue, IDLNullValue):
assert(type.nullable())
defaultCode = "${declName}.SetIsVoid(true)"
else:
defaultCode = handleDefaultStringValue(defaultValue,
"${declName}.Rebind")
conversionCode = handleDefault(conversionCode, defaultCode + ";\n")
return JSToNativeConversionInfo(
conversionCode,
@ -9604,9 +9612,14 @@ class CGUnionStruct(CGThing):
if self.ownsMembers:
methods.append(vars["setter"])
# Provide a SetStringData() method to support string defaults.
# Exclude ByteString here because it does not support defaults
# and only supports narrow nsCString.
if t.isString() and not t.isByteString():
if t.isByteString():
methods.append(
ClassMethod("SetStringData", "void",
[Argument("const nsCString::char_type*", "aData"),
Argument("nsCString::size_type", "aLength")],
inline=True, bodyInHeader=True,
body="RawSetAs%s().Assign(aData, aLength);\n" % t.name))
elif t.isString():
methods.append(
ClassMethod("SetStringData", "void",
[Argument("const nsString::char_type*", "aData"),
@ -9867,9 +9880,14 @@ class CGUnionConversionStruct(CGThing):
body=body,
visibility="private"))
# Provide a SetStringData() method to support string defaults.
# Exclude ByteString here because it does not support defaults
# and only supports narrow nsCString.
if t.isString() and not t.isByteString():
if t.isByteString():
methods.append(
ClassMethod("SetStringData", "void",
[Argument("const nsDependentCString::char_type*", "aData"),
Argument("nsDependentCString::size_type", "aLength")],
inline=True, bodyInHeader=True,
body="RawSetAs%s().Rebind(aData, aLength);\n" % t.name))
elif t.isString():
methods.append(
ClassMethod("SetStringData", "void",
[Argument("const nsDependentString::char_type*", "aData"),

View File

@ -9,6 +9,7 @@ import re
import os
import traceback
import math
import string
from collections import defaultdict
# Machinery
@ -3384,6 +3385,20 @@ class IDLValue(IDLObject):
# extra normalization step.
assert self.type.isDOMString()
return self
elif self.type.isString() and type.isByteString():
# Allow ByteStrings to use a default value like DOMString.
# No coercion is required as Codegen.py will handle the
# extra steps. We want to make sure that our string contains
# only valid characters, so we check that here.
valid_ascii_lit = " " + string.ascii_letters + string.digits + string.punctuation
for idx, c in enumerate(self.value):
if c not in valid_ascii_lit:
raise WebIDLError("Coercing this string literal %s to a ByteString is not supported yet. "
"Coercion failed due to an unsupported byte %d at index %d."
% (self.value.__repr__(), ord(c), idx), [location])
return IDLValue(self.location, type, self.value)
raise WebIDLError("Cannot coerce type %s to type %s." %
(self.type, type), [location])

View File

@ -13,7 +13,7 @@ def WebIDLTest(parser, harness):
results = parser.finish();
harness.ok(True, "TestByteString interface parsed without error.")
harness.check(len(results), 1, "Should be one production")
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
"Should be an IDLInterface")
@ -54,10 +54,9 @@ def WebIDLTest(parser, harness):
""")
except WebIDL.WebIDLError:
threw = True
harness.ok(threw, "Should have thrown a WebIDL error")
harness.ok(threw, "Should have thrown a WebIDL error for ByteString default in interface")
# Cannot have optional ByteStrings with default values
threw = False
# Can have optional ByteStrings with default values
try:
parser.parse("""
interface OptionalByteString {
@ -65,8 +64,36 @@ def WebIDLTest(parser, harness):
};
""")
results2 = parser.finish();
except WebIDL.WebIDLError:
except WebIDL.WebIDLError as e:
harness.ok(False,
"Should not have thrown a WebIDL error for ByteString "
"default in dictionary. " + str(e))
# Can have a default ByteString value in a dictionary
try:
parser.parse("""
dictionary OptionalByteStringDict {
ByteString item = "some string";
};
""")
results3 = parser.finish();
except WebIDL.WebIDLError as e:
harness.ok(False,
"Should not have thrown a WebIDL error for ByteString "
"default in dictionary. " + str(e))
# Don't allow control characters in ByteString literals
threw = False
try:
parser.parse("""
dictionary OptionalByteStringDict2 {
ByteString item = "\x03";
};
""")
results4 = parser.finish()
except WebIDL.WebIDLError as e:
threw = True
harness.ok(threw, "Should have thrown a WebIDL error")
harness.ok(threw,
"Should have thrown a WebIDL error for invalid ByteString "
"default in dictionary")

View File

@ -497,8 +497,12 @@ public:
void PassByteString(const nsCString&);
void PassNullableByteString(const nsCString&);
void PassOptionalByteString(const Optional<nsCString>&);
void PassOptionalByteStringWithDefaultValue(const nsCString&);
void PassOptionalNullableByteString(const Optional<nsCString>&);
void PassOptionalNullableByteStringWithDefaultValue(const nsCString&);
void PassVariadicByteString(const Sequence<nsCString>&);
void PassOptionalUnionByteString(const Optional<ByteStringOrLong>&);
void PassOptionalUnionByteStringWithDefaultValue(const ByteStringOrLong&);
// USVString types
void PassUSVS(const nsAString&);
@ -686,7 +690,9 @@ public:
void PassUnionWithDefaultValue11(const UnrestrictedFloatOrString& arg);
void PassUnionWithDefaultValue12(const UnrestrictedFloatOrString& arg);
void PassUnionWithDefaultValue13(const UnrestrictedFloatOrString& arg);
void PassUnionWithDefaultValue14(const UnrestrictedFloatOrString& arg);
void PassUnionWithDefaultValue14(const DoubleOrByteString& arg);
void PassUnionWithDefaultValue15(const DoubleOrByteString& arg);
void PassUnionWithDefaultValue16(const DoubleOrByteString& arg);
void PassNullableUnionWithDefaultValue1(const Nullable<DoubleOrString>& arg);
void PassNullableUnionWithDefaultValue2(const Nullable<DoubleOrString>& arg);
@ -700,6 +706,10 @@ public:
void PassNullableUnionWithDefaultValue10(const Nullable<UnrestrictedFloatOrString>& arg);
void PassNullableUnionWithDefaultValue11(const Nullable<UnrestrictedFloatOrString>& arg);
void PassNullableUnionWithDefaultValue12(const Nullable<UnrestrictedFloatOrString>& arg);
void PassNullableUnionWithDefaultValue13(const Nullable<DoubleOrByteString>& arg);
void PassNullableUnionWithDefaultValue14(const Nullable<DoubleOrByteString>& arg);
void PassNullableUnionWithDefaultValue15(const Nullable<DoubleOrByteString>& arg);
void PassNullableUnionWithDefaultValue16(const Nullable<DoubleOrByteString>& arg);
void PassSequenceOfUnions(const Sequence<OwningCanvasPatternOrCanvasGradient>&);
void PassSequenceOfUnions2(JSContext*, const Sequence<OwningObjectOrLong>&);
@ -1089,7 +1099,9 @@ private:
void PassByteString(nsCString&) = delete;
void PassNullableByteString(nsCString&) = delete;
void PassOptionalByteString(Optional<nsCString>&) = delete;
void PassOptionalByteStringWithDefaultValue(nsCString&) = delete;
void PassOptionalNullableByteString(Optional<nsCString>&) = delete;
void PassOptionalNullableByteStringWithDefaultValue(nsCString&) = delete;
void PassVariadicByteString(Sequence<nsCString>&) = delete;
// Make sure dictionary arguments are always const

View File

@ -480,8 +480,12 @@ interface TestInterface {
void passByteString(ByteString arg);
void passNullableByteString(ByteString? arg);
void passOptionalByteString(optional ByteString arg);
void passOptionalByteStringWithDefaultValue(optional ByteString arg = "abc");
void passOptionalNullableByteString(optional ByteString? arg);
void passOptionalNullableByteStringWithDefaultValue(optional ByteString? arg = null);
void passVariadicByteString(ByteString... arg);
void passOptionalUnionByteString(optional (ByteString or long) arg);
void passOptionalUnionByteStringWithDefaultValue(optional (ByteString or long) arg = "abc");
// USVString types
void passUSVS(USVString arg);
@ -660,6 +664,9 @@ interface TestInterface {
void passUnionWithDefaultValue11(optional (unrestricted float or DOMString) arg = "");
void passUnionWithDefaultValue12(optional (unrestricted float or DOMString) arg = 1);
void passUnionWithDefaultValue13(optional (unrestricted float or DOMString) arg = Infinity);
void passUnionWithDefaultValue14(optional (double or ByteString) arg = "");
void passUnionWithDefaultValue15(optional (double or ByteString) arg = 1);
void passUnionWithDefaultValue16(optional (double or ByteString) arg = 1.5);
void passNullableUnionWithDefaultValue1(optional (double or DOMString)? arg = "");
void passNullableUnionWithDefaultValue2(optional (double or DOMString)? arg = 1);
@ -673,6 +680,10 @@ interface TestInterface {
void passNullableUnionWithDefaultValue10(optional (unrestricted float or DOMString)? arg = "");
void passNullableUnionWithDefaultValue11(optional (unrestricted float or DOMString)? arg = 1);
void passNullableUnionWithDefaultValue12(optional (unrestricted float or DOMString)? arg = null);
void passNullableUnionWithDefaultValue13(optional (double or ByteString)? arg = "");
void passNullableUnionWithDefaultValue14(optional (double or ByteString)? arg = 1);
void passNullableUnionWithDefaultValue15(optional (double or ByteString)? arg = 1.5);
void passNullableUnionWithDefaultValue16(optional (double or ByteString)? arg = null);
void passSequenceOfUnions(sequence<(CanvasPattern or CanvasGradient)> arg);
void passSequenceOfUnions2(sequence<(object or long)> arg);
@ -1009,6 +1020,9 @@ dictionary Dict : ParentDict {
DOMString otherStr = "def";
DOMString? yetAnotherStr = null;
DOMString template;
ByteString byteStr;
ByteString emptyByteStr = "";
ByteString otherByteStr = "def";
object someObj;
boolean prototype;
object? anotherObj = null;

View File

@ -343,9 +343,13 @@ interface TestExampleInterface {
void passByteString(ByteString arg);
void passNullableByteString(ByteString? arg);
void passOptionalByteString(optional ByteString arg);
void passOptionalByteStringWithDefaultValue(optional ByteString arg = "abc");
void passOptionalNullableByteString(optional ByteString? arg);
void passOptionalNullableByteStringWithDefaultValue(optional ByteString? arg = null);
void passVariadicByteString(ByteString... arg);
void passUnionByteString((ByteString or long) arg);
void passOptionalUnionByteString(optional (ByteString or long) arg);
void passOptionalUnionByteStringWithDefaultValue(optional (ByteString or long) arg = "abc");
// USVString types
void passSVS(USVString arg);
@ -495,6 +499,9 @@ interface TestExampleInterface {
void passUnionWithDefaultValue11(optional (unrestricted float or DOMString) arg = "");
void passUnionWithDefaultValue12(optional (unrestricted float or DOMString) arg = 1);
void passUnionWithDefaultValue13(optional (unrestricted float or DOMString) arg = Infinity);
void passUnionWithDefaultValue14(optional (double or ByteString) arg = "");
void passUnionWithDefaultValue15(optional (double or ByteString) arg = 1);
void passUnionWithDefaultValue16(optional (double or ByteString) arg = 1.5);
void passNullableUnionWithDefaultValue1(optional (double or DOMString)? arg = "");
void passNullableUnionWithDefaultValue2(optional (double or DOMString)? arg = 1);
@ -508,6 +515,10 @@ interface TestExampleInterface {
void passNullableUnionWithDefaultValue10(optional (unrestricted float or DOMString)? arg = "");
void passNullableUnionWithDefaultValue11(optional (unrestricted float or DOMString)? arg = 1);
void passNullableUnionWithDefaultValue12(optional (unrestricted float or DOMString)? arg = null);
void passNullableUnionWithDefaultValue13(optional (double or ByteString)? arg = "");
void passNullableUnionWithDefaultValue14(optional (double or ByteString)? arg = 1);
void passNullableUnionWithDefaultValue15(optional (double or ByteString)? arg = 1.5);
void passNullableUnionWithDefaultValue16(optional (double or ByteString)? arg = null);
void passSequenceOfUnions(sequence<(CanvasPattern or CanvasGradient)> arg);
void passSequenceOfUnions2(sequence<(object or long)> arg);

View File

@ -354,9 +354,13 @@ interface TestJSImplInterface {
void passByteString(ByteString arg);
void passNullableByteString(ByteString? arg);
void passOptionalByteString(optional ByteString arg);
void passOptionalByteStringWithDefaultValue(optional ByteString arg = "abc");
void passOptionalNullableByteString(optional ByteString? arg);
void passOptionalNullableByteStringWithDefaultValue(optional ByteString? arg = null);
void passVariadicByteString(ByteString... arg);
void PassUnionByteString((ByteString or long) arg);
void passUnionByteString((ByteString or long) arg);
void passOptionalUnionByteString(optional (ByteString or long) arg);
void passOptionalUnionByteStringWithDefaultValue(optional (ByteString or long) arg = "abc");
// USVString types
void passSVS(USVString arg);
@ -507,6 +511,9 @@ interface TestJSImplInterface {
void passUnionWithDefaultValue11(optional (unrestricted float or DOMString) arg = "");
void passUnionWithDefaultValue12(optional (unrestricted float or DOMString) arg = 1);
void passUnionWithDefaultValue13(optional (unrestricted float or DOMString) arg = Infinity);
void passUnionWithDefaultValue14(optional (double or ByteString) arg = "");
void passUnionWithDefaultValue15(optional (double or ByteString) arg = 1);
void passUnionWithDefaultValue16(optional (double or ByteString) arg = 1.5);
void passNullableUnionWithDefaultValue1(optional (double or DOMString)? arg = "");
void passNullableUnionWithDefaultValue2(optional (double or DOMString)? arg = 1);
@ -520,6 +527,10 @@ interface TestJSImplInterface {
void passNullableUnionWithDefaultValue10(optional (unrestricted float or DOMString)? arg = "");
void passNullableUnionWithDefaultValue11(optional (unrestricted float or DOMString)? arg = 1);
void passNullableUnionWithDefaultValue12(optional (unrestricted float or DOMString)? arg = null);
void passNullableUnionWithDefaultValue13(optional (double or ByteString)? arg = "");
void passNullableUnionWithDefaultValue14(optional (double or ByteString)? arg = 1);
void passNullableUnionWithDefaultValue15(optional (double or ByteString)? arg = 1.5);
void passNullableUnionWithDefaultValue16(optional (double or ByteString)? arg = null);
void passSequenceOfUnions(sequence<(CanvasPattern or CanvasGradient)> arg);
void passSequenceOfUnions2(sequence<(object or long)> arg);