Bug 1449861 - Add UTF8String to the WebIDL parser. r=bzbarsky

Differential Revision: https://phabricator.services.mozilla.com/D58628

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2020-01-04 10:35:21 +00:00
parent 405eddfd81
commit b58f2e72e8
3 changed files with 52 additions and 12 deletions

View File

@ -2085,6 +2085,7 @@ class IDLType(IDLObject):
'domstring',
'bytestring',
'usvstring',
'utf8string',
'jsstring',
'object',
'date',
@ -2147,6 +2148,9 @@ class IDLType(IDLObject):
def isUSVString(self):
return False
def isUTF8String(self):
return False
def isJSString(self):
return False
@ -2378,6 +2382,9 @@ class IDLNullableType(IDLParametrizedType):
def isUSVString(self):
return self.inner.isUSVString()
def isUTF8String(self):
return self.inner.isUTF8String()
def isJSString(self):
return self.inner.isJSString()
@ -2525,6 +2532,9 @@ class IDLSequenceType(IDLParametrizedType):
def isUSVString(self):
return False
def isUTF8String(self):
return False
def isJSString(self):
return False
@ -2781,6 +2791,9 @@ class IDLTypedefType(IDLType):
def isUSVString(self):
return self.inner.isUSVString()
def isUTF8String(self):
return self.inner.isUTF8String()
def isJSString(self):
return self.inner.isJSString()
@ -2914,6 +2927,9 @@ class IDLWrapperType(IDLType):
def isUSVString(self):
return False
def isUTF8String(self):
return False
def isJSString(self):
return False
@ -3117,6 +3133,7 @@ class IDLBuiltinType(IDLType):
'domstring',
'bytestring',
'usvstring',
'utf8string',
'jsstring',
'object',
'date',
@ -3155,6 +3172,7 @@ class IDLBuiltinType(IDLType):
Types.domstring: IDLType.Tags.domstring,
Types.bytestring: IDLType.Tags.bytestring,
Types.usvstring: IDLType.Tags.usvstring,
Types.utf8string: IDLType.Tags.utf8string,
Types.jsstring: IDLType.Tags.jsstring,
Types.object: IDLType.Tags.object,
Types.date: IDLType.Tags.date,
@ -3199,7 +3217,7 @@ class IDLBuiltinType(IDLType):
self._extendedAttrDict["EnforceRange"] = True
elif clamp or enforceRange:
raise WebIDLError("Non-integer types cannot be [Clamp] or [EnforceRange]", attrLocation)
if self.isDOMString():
if self.isDOMString() or self.isUTF8String():
if treatNullAsEmpty:
self.treatNullAsEmpty = True
self.name = "NullIsEmpty" + self.name
@ -3241,6 +3259,7 @@ class IDLBuiltinType(IDLType):
return (self._typeTag == IDLBuiltinType.Types.domstring or
self._typeTag == IDLBuiltinType.Types.bytestring or
self._typeTag == IDLBuiltinType.Types.usvstring or
self._typeTag == IDLBuiltinType.Types.utf8string or
self._typeTag == IDLBuiltinType.Types.jsstring)
def isByteString(self):
@ -3252,6 +3271,9 @@ class IDLBuiltinType(IDLType):
def isUSVString(self):
return self._typeTag == IDLBuiltinType.Types.usvstring
def isUTF8String(self):
return self._typeTag == IDLBuiltinType.Types.utf8string
def isJSString(self):
return self._typeTag == IDLBuiltinType.Types.jsstring
@ -3387,8 +3409,8 @@ class IDLBuiltinType(IDLType):
[self.location, attribute.location])
ret = self.rangeEnforced([self.location, attribute.location])
elif identifier == "TreatNullAs":
if not self.isDOMString():
raise WebIDLError("[TreatNullAs] only allowed on DOMStrings",
if not (self.isDOMString() or self.isUTF8String()):
raise WebIDLError("[TreatNullAs] only allowed on DOMStrings and UTF8Strings",
[self.location, attribute.location])
assert not self.nullable()
if not attribute.hasValue():
@ -3457,6 +3479,9 @@ BuiltinTypes = {
IDLBuiltinType.Types.usvstring:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "USVString",
IDLBuiltinType.Types.usvstring),
IDLBuiltinType.Types.utf8string:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "UTF8String",
IDLBuiltinType.Types.utf8string),
IDLBuiltinType.Types.jsstring:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "JSString",
IDLBuiltinType.Types.jsstring),
@ -3626,8 +3651,9 @@ class IDLValue(IDLObject):
# TreatNullAsEmpty is a different type for resolution reasons,
# however once you have a value it doesn't matter
return self
elif self.type.isString() and (type.isByteString() or type.isJSString()):
# Allow ByteStrings and JSStrings to use a default value like DOMString.
elif self.type.isString() and (type.isByteString() or type.isJSString() or type.isUTF8String()):
# Allow ByteStrings, UTF8String, and JSStrings 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.
@ -5695,6 +5721,7 @@ class Tokenizer(object):
"ByteString": "BYTESTRING",
"USVString": "USVSTRING",
"JSString": "JSSTRING",
"UTF8String": "UTF8STRING",
"any": "ANY",
"boolean": "BOOLEAN",
"byte": "BYTE",
@ -6958,6 +6985,7 @@ class Parser(Tokenizer):
| DOMSTRING
| BYTESTRING
| USVSTRING
| UTF8STRING
| JSSTRING
| PROMISE
| ANY
@ -7230,6 +7258,12 @@ class Parser(Tokenizer):
"""
p[0] = IDLBuiltinType.Types.usvstring
def p_BuiltinStringTypeUTF8String(self, p):
"""
BuiltinStringType : UTF8STRING
"""
p[0] = IDLBuiltinType.Types.utf8string
def p_BuiltinStringTypeJSString(self, p):
"""
BuiltinStringType : JSSTRING

View File

@ -149,7 +149,7 @@ def WebIDLTest(parser, harness):
# Now let's test our whole distinguishability table
argTypes = [ "long", "short", "long?", "short?", "boolean",
"boolean?", "DOMString", "ByteString", "Enum", "Enum2",
"boolean?", "DOMString", "ByteString", "UTF8String", "Enum", "Enum2",
"Interface", "Interface?",
"AncestorInterface", "UnrelatedInterface", "CallbackInterface",
"CallbackInterface?", "CallbackInterface2",
@ -158,6 +158,7 @@ def WebIDLTest(parser, harness):
"record<DOMString, object>",
"record<USVString, Dict>",
"record<ByteString, long>",
"record<UTF8String, long>",
"Date", "Date?", "any",
"Promise<any>", "Promise<any>?",
"USVString", "JSString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer",
@ -177,7 +178,7 @@ def WebIDLTest(parser, harness):
primitives = numerics + booleans
nonNumerics = allBut(argTypes, numerics + unions)
nonBooleans = allBut(argTypes, booleans)
strings = [ "DOMString", "ByteString", "Enum", "Enum2", "USVString", "JSString" ]
strings = [ "DOMString", "ByteString", "Enum", "Enum2", "USVString", "JSString", "UTF8String" ]
nonStrings = allBut(argTypes, strings)
nonObjects = primitives + strings
objects = allBut(argTypes, nonObjects )
@ -196,7 +197,7 @@ def WebIDLTest(parser, harness):
notRelatedInterfaces = (nonObjects + ["UnrelatedInterface"] +
otherObjects + dates + sequences + bufferSourceTypes + sharedBufferSourceTypes)
records = [ "record<DOMString, object>", "record<USVString, Dict>",
"record<ByteString, long>" ] # JSString not supported in records
"record<ByteString, long>", "record<UTF8String, long>" ] # JSString not supported in records
# Build a representation of the distinguishability table as a dict
# of dicts, holding True values where needed, holes elsewhere.
@ -215,6 +216,7 @@ def WebIDLTest(parser, harness):
setDistinguishable("boolean?", allBut(nonBooleans, nullables))
setDistinguishable("DOMString", nonStrings)
setDistinguishable("ByteString", nonStrings)
setDistinguishable("UTF8String", nonStrings)
setDistinguishable("USVString", nonStrings)
setDistinguishable("JSString", nonStrings)
setDistinguishable("Enum", nonStrings)
@ -240,6 +242,7 @@ def WebIDLTest(parser, harness):
setDistinguishable("record<USVString, Dict>", nonUserObjects)
# JSString not supported in records
setDistinguishable("record<ByteString, long>", nonUserObjects)
setDistinguishable("record<UTF8String, long>", nonUserObjects)
setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
setDistinguishable("Date?", allBut(argTypes, dates + nullables + ["object"]))
setDistinguishable("any", [])

View File

@ -85,7 +85,7 @@ def WebIDLTest(parser, harness):
JsonTypes = [ "byte", "octet", "short", "unsigned short", "long", "unsigned long", "long long",
"unsigned long long", "float", "unrestricted float", "double", "unrestricted double", "boolean",
"DOMString", "ByteString", "USVString", "Enum", "InterfaceWithToJSON", "object" ]
"DOMString", "ByteString", "UTF8String", "USVString", "Enum", "InterfaceWithToJSON", "object" ]
nonJsonTypes = [ "InterfaceWithoutToJSON", "any", "Int8Array", "Int16Array", "Int32Array","Uint8Array",
"Uint16Array", "Uint32Array", "Uint8ClampedArray", "Float32Array", "Float64Array", "ArrayBuffer" ]
@ -129,9 +129,12 @@ def WebIDLTest(parser, harness):
doTest("interface Test { record<DOMString, %s> toJSON(); };" % type, False,
"record<DOMString, %s> should be a JSON type" % type)
doTest("interface Test { record<ByteString, %s> toJSON(); };" % type, False,
doTest("interface Test { record<ByteString, %s> toJSON(); };" % type, False,
"record<ByteString, %s> should be a JSON type" % type)
doTest("interface Test { record<UTF8String, %s> toJSON(); };" % type, False,
"record<UTF8String, %s> should be a JSON type" % type)
doTest("interface Test { record<USVString, %s> toJSON(); };" % type, False,
"record<USVString, %s> should be a JSON type" % type)
@ -174,12 +177,12 @@ def WebIDLTest(parser, harness):
doTest("interface Test { record<USVString, %s> toJSON(); };" % type, True,
"record<USVString, %s> should not be a JSON type" % type)
if type != "any":
doTest("interface Foo { object toJSON(); }; "
"interface Test { (Foo or %s) toJSON(); };" % type, True,
"union containing a non-JSON type (%s) should not be a JSON type" % type)
doTest("interface test { %s? toJSON(); };" % type, True,
"Nullable type (%s) should not be a JSON type" % type)