Bug 796850 - Implement WebIDL parser support for Bytestring r=bz

This commit is contained in:
James Kitchener 2013-06-13 01:15:35 -04:00
parent 5f569d0d0e
commit 8740436c04
3 changed files with 135 additions and 5 deletions

View File

@ -384,7 +384,7 @@ class IDLObjectWithIdentifier(IDLObject):
identifier = attr.identifier()
value = attr.value()
if identifier == "TreatNullAs":
if not self.type.isString() or self.type.nullable():
if not self.type.isDOMString() or self.type.nullable():
raise WebIDLError("[TreatNullAs] is only allowed on "
"arguments or attributes whose type is "
"DOMString",
@ -407,7 +407,7 @@ class IDLObjectWithIdentifier(IDLObject):
"allowed on optional arguments",
[self.location])
elif value == 'Null':
if not self.type.isString():
if not self.type.isDOMString():
raise WebIDLError("[TreatUndefinedAs=Null] is only "
"allowed on arguments or "
"attributes whose type is "
@ -418,7 +418,7 @@ class IDLObjectWithIdentifier(IDLObject):
"allowed on arguments whose type "
"is DOMString?", [self.location])
elif value == 'EmptyString':
if not self.type.isString():
if not self.type.isDOMString():
raise WebIDLError("[TreatUndefinedAs=EmptyString] "
"is only allowed on arguments or "
"attributes whose type is "
@ -1217,6 +1217,7 @@ class IDLType(IDLObject):
# Other types
'any',
'domstring',
'bytestring',
'object',
'date',
'void',
@ -1256,6 +1257,12 @@ class IDLType(IDLObject):
def isString(self):
return False
def isByteString(self):
return False
def isDOMString(self):
return False
def isVoid(self):
return self.name == "Void"
@ -1404,6 +1411,12 @@ class IDLNullableType(IDLType):
def isString(self):
return self.inner.isString()
def isByteString(self):
return self.inner.isByteString()
def isDOMString(self):
return self.inner.isDOMString()
def isFloat(self):
return self.inner.isFloat()
@ -1513,6 +1526,12 @@ class IDLSequenceType(IDLType):
def isString(self):
return False;
def isByteString(self):
return False
def isDOMString(self):
return False
def isVoid(self):
return False
@ -1697,6 +1716,12 @@ class IDLArrayType(IDLType):
def isString(self):
return False
def isByteString(self):
return False
def isDOMString(self):
return False
def isVoid(self):
return False
@ -1780,6 +1805,12 @@ class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
def isString(self):
return self.inner.isString()
def isByteString(self):
return self.inner.isByteString()
def isDOMString(self):
return self.inner.isDOMString()
def isVoid(self):
return self.inner.isVoid()
@ -1867,6 +1898,12 @@ class IDLWrapperType(IDLType):
def isString(self):
return False
def isByteString(self):
return False
def isDOMString(self):
return False
def isVoid(self):
return False
@ -1985,6 +2022,7 @@ class IDLBuiltinType(IDLType):
# Other types
'any',
'domstring',
'bytestring',
'object',
'date',
'void',
@ -2018,6 +2056,7 @@ class IDLBuiltinType(IDLType):
Types.double: IDLType.Tags.double,
Types.any: IDLType.Tags.any,
Types.domstring: IDLType.Tags.domstring,
Types.bytestring: IDLType.Tags.bytestring,
Types.object: IDLType.Tags.object,
Types.date: IDLType.Tags.date,
Types.void: IDLType.Tags.void,
@ -2043,6 +2082,13 @@ class IDLBuiltinType(IDLType):
return self._typeTag <= IDLBuiltinType.Types.double
def isString(self):
return self._typeTag == IDLBuiltinType.Types.domstring or \
self._typeTag == IDLBuiltinType.Types.bytestring
def isByteString(self):
return self._typeTag == IDLBuiltinType.Types.bytestring
def isDOMString(self):
return self._typeTag == IDLBuiltinType.Types.domstring
def isInteger(self):
@ -2177,6 +2223,9 @@ BuiltinTypes = {
IDLBuiltinType.Types.domstring:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "String",
IDLBuiltinType.Types.domstring),
IDLBuiltinType.Types.bytestring:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "ByteString",
IDLBuiltinType.Types.bytestring),
IDLBuiltinType.Types.object:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Object",
IDLBuiltinType.Types.object),
@ -3260,6 +3309,7 @@ class Tokenizer(object):
"::": "SCOPE",
"Date": "DATE",
"DOMString": "DOMSTRING",
"ByteString": "BYTESTRING",
"any": "ANY",
"boolean": "BOOLEAN",
"byte": "BYTE",
@ -3817,8 +3867,8 @@ class Parser(Tokenizer):
if len(arguments) != 0:
raise WebIDLError("stringifier has wrong number of arguments",
[self.getLocation(p, 2)])
if not returnType.isString():
raise WebIDLError("stringifier must have string return type",
if not returnType.isDOMString():
raise WebIDLError("stringifier must have DOMString return type",
[self.getLocation(p, 2)])
inOptionalArguments = False
@ -4127,6 +4177,7 @@ class Parser(Tokenizer):
| QUESTIONMARK
| DATE
| DOMSTRING
| BYTESTRING
| ANY
| ATTRIBUTE
| BOOLEAN
@ -4362,6 +4413,12 @@ class Parser(Tokenizer):
"""
p[0] = IDLBuiltinType.Types.domstring
def p_PrimitiveOrStringTypeBytestring(self, p):
"""
PrimitiveOrStringType : BYTESTRING
"""
p[0] = IDLBuiltinType.Types.bytestring
def p_UnsignedIntegerTypeUnsigned(self, p):
"""
UnsignedIntegerType : UNSIGNED IntegerType

View File

@ -0,0 +1,72 @@
# -*- coding: UTF-8 -*-
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestByteString {
attribute ByteString bs;
attribute DOMString ds;
};
""")
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")
iface = results[0]
harness.check(iface.identifier.QName(), "::TestByteString", "Interface has the right QName")
harness.check(iface.identifier.name, "TestByteString", "Interface has the right name")
harness.check(iface.parent, None, "Interface has no parent")
members = iface.members
harness.check(len(members), 2, "Should be two productions")
attr = members[0]
harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute")
harness.check(attr.identifier.QName(), "::TestByteString::bs", "Attr has correct QName")
harness.check(attr.identifier.name, "bs", "Attr has correct name")
harness.check(str(attr.type), "ByteString", "Attr type is the correct name")
harness.ok(attr.type.isByteString(), "Should be ByteString type")
harness.ok(attr.type.isString(), "Should be String collective type")
harness.ok(not attr.type.isDOMString(), "Should be not be DOMString type")
# now check we haven't broken DOMStrings in the process.
attr = members[1]
harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute")
harness.check(attr.identifier.QName(), "::TestByteString::ds", "Attr has correct QName")
harness.check(attr.identifier.name, "ds", "Attr has correct name")
harness.check(str(attr.type), "String", "Attr type is the correct name")
harness.ok(attr.type.isDOMString(), "Should be DOMString type")
harness.ok(attr.type.isString(), "Should be String collective type")
harness.ok(not attr.type.isByteString(), "Should be not be ByteString type")
# Cannot represent constant ByteString in IDL.
threw = False
try:
parser.parse("""
interface ConstByteString {
const ByteString foo = "hello"
};
""")
except WebIDL.WebIDLError:
threw = True
harness.ok(threw, "Should have thrown a WebIDL error")
# Cannot have optional ByteStrings with default values
threw = False
try:
parser.parse("""
interface OptionalByteString {
void passByteString(optional ByteString arg = "hello");
};
""")
results2 = parser.finish();
except WebIDL.WebIDLError:
threw = True
harness.ok(threw, "Should have thrown a WebIDL error")

View File

@ -62,6 +62,7 @@ def WebIDLTest(parser, harness):
"byte",
"octet",
"DOMString",
"ByteString",
#"sequence<float>",
"object",
"ArrayBuffer",