зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1007878 part 1. Add parsing of MozMap to the WebIDL parser. r=khuey
This commit is contained in:
Родитель
900ca9c9b2
Коммит
0cca97fdf1
|
@ -1200,9 +1200,10 @@ class IDLDictionary(IDLObjectWithScope):
|
||||||
None, if the boolean value in the first element is False.
|
None, if the boolean value in the first element is False.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if memberType.nullable() or \
|
if (memberType.nullable() or
|
||||||
memberType.isArray() or \
|
memberType.isArray() or
|
||||||
memberType.isSequence():
|
memberType.isSequence() or
|
||||||
|
memberType.isMozMap()):
|
||||||
return typeContainsDictionary(memberType.inner, dictionary)
|
return typeContainsDictionary(memberType.inner, dictionary)
|
||||||
|
|
||||||
if memberType.isDictionary():
|
if memberType.isDictionary():
|
||||||
|
@ -1320,6 +1321,7 @@ class IDLType(IDLObject):
|
||||||
'callback',
|
'callback',
|
||||||
'union',
|
'union',
|
||||||
'sequence',
|
'sequence',
|
||||||
|
'mozmap',
|
||||||
'array'
|
'array'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1367,6 +1369,9 @@ class IDLType(IDLObject):
|
||||||
def isSequence(self):
|
def isSequence(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def isMozMap(self):
|
||||||
|
return False
|
||||||
|
|
||||||
def isArray(self):
|
def isArray(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -1549,6 +1554,9 @@ class IDLNullableType(IDLType):
|
||||||
def isSequence(self):
|
def isSequence(self):
|
||||||
return self.inner.isSequence()
|
return self.inner.isSequence()
|
||||||
|
|
||||||
|
def isMozMap(self):
|
||||||
|
return self.inner.isMozMap()
|
||||||
|
|
||||||
def isArray(self):
|
def isArray(self):
|
||||||
return self.inner.isArray()
|
return self.inner.isArray()
|
||||||
|
|
||||||
|
@ -1701,6 +1709,60 @@ class IDLSequenceType(IDLType):
|
||||||
def _getDependentObjects(self):
|
def _getDependentObjects(self):
|
||||||
return self.inner._getDependentObjects()
|
return self.inner._getDependentObjects()
|
||||||
|
|
||||||
|
class IDLMozMapType(IDLType):
|
||||||
|
# XXXbz This is pretty similar to IDLSequenceType in various ways.
|
||||||
|
# And maybe to IDLNullableType. Should we have a superclass for
|
||||||
|
# "type containing this other type"? Bug 1015318.
|
||||||
|
def __init__(self, location, parameterType):
|
||||||
|
assert not parameterType.isVoid()
|
||||||
|
|
||||||
|
IDLType.__init__(self, location, parameterType.name)
|
||||||
|
self.inner = parameterType
|
||||||
|
self.builtin = False
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return isinstance(other, IDLMozMapType) and self.inner == other.inner
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.inner.__str__() + "MozMap"
|
||||||
|
|
||||||
|
def isMozMap(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def includesRestrictedFloat(self):
|
||||||
|
return self.inner.includesRestrictedFloat()
|
||||||
|
|
||||||
|
def tag(self):
|
||||||
|
return IDLType.Tags.mozmap
|
||||||
|
|
||||||
|
def resolveType(self, parentScope):
|
||||||
|
assert isinstance(parentScope, IDLScope)
|
||||||
|
self.inner.resolveType(parentScope)
|
||||||
|
|
||||||
|
def isComplete(self):
|
||||||
|
return self.inner.isComplete()
|
||||||
|
|
||||||
|
def complete(self, scope):
|
||||||
|
self.inner = self.inner.complete(scope)
|
||||||
|
self.name = self.inner.name
|
||||||
|
return self
|
||||||
|
|
||||||
|
def unroll(self):
|
||||||
|
# We do not unroll our inner. Just stop at ourselves. That
|
||||||
|
# lets us add headers for both ourselves and our inner as
|
||||||
|
# needed.
|
||||||
|
return self
|
||||||
|
|
||||||
|
def isDistinguishableFrom(self, other):
|
||||||
|
if other.isUnion():
|
||||||
|
# Just forward to the union; it'll deal
|
||||||
|
return other.isDistinguishableFrom(self)
|
||||||
|
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||||
|
other.isDate() or other.isNonCallbackInterface())
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return self.inner._getDependentObjects()
|
||||||
|
|
||||||
class IDLUnionType(IDLType):
|
class IDLUnionType(IDLType):
|
||||||
def __init__(self, location, memberTypes):
|
def __init__(self, location, memberTypes):
|
||||||
IDLType.__init__(self, location, "")
|
IDLType.__init__(self, location, "")
|
||||||
|
@ -1744,7 +1806,8 @@ class IDLUnionType(IDLType):
|
||||||
return typeName(type._identifier.object())
|
return typeName(type._identifier.object())
|
||||||
if isinstance(type, IDLObjectWithIdentifier):
|
if isinstance(type, IDLObjectWithIdentifier):
|
||||||
return typeName(type.identifier)
|
return typeName(type.identifier)
|
||||||
if isinstance(type, IDLType) and (type.isArray() or type.isSequence()):
|
if (isinstance(type, IDLType) and
|
||||||
|
(type.isArray() or type.isSequence() or type.isMozMap)):
|
||||||
return str(type)
|
return str(type)
|
||||||
return type.name
|
return type.name
|
||||||
|
|
||||||
|
@ -1816,6 +1879,9 @@ class IDLArrayType(IDLType):
|
||||||
if parameterType.isSequence():
|
if parameterType.isSequence():
|
||||||
raise WebIDLError("Array type cannot parameterize over a sequence type",
|
raise WebIDLError("Array type cannot parameterize over a sequence type",
|
||||||
[location])
|
[location])
|
||||||
|
if parameterType.isMozMap():
|
||||||
|
raise WebIDLError("Array type cannot parameterize over a MozMap type",
|
||||||
|
[location])
|
||||||
if parameterType.isDictionary():
|
if parameterType.isDictionary():
|
||||||
raise WebIDLError("Array type cannot parameterize over a dictionary type",
|
raise WebIDLError("Array type cannot parameterize over a dictionary type",
|
||||||
[location])
|
[location])
|
||||||
|
@ -1946,6 +2012,9 @@ class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
|
||||||
def isSequence(self):
|
def isSequence(self):
|
||||||
return self.inner.isSequence()
|
return self.inner.isSequence()
|
||||||
|
|
||||||
|
def isMozMap(self):
|
||||||
|
return self.inner.isMozMap()
|
||||||
|
|
||||||
def isArray(self):
|
def isArray(self):
|
||||||
return self.inner.isArray()
|
return self.inner.isArray()
|
||||||
|
|
||||||
|
@ -2100,7 +2169,7 @@ class IDLWrapperType(IDLType):
|
||||||
if self.isEnum():
|
if self.isEnum():
|
||||||
return (other.isPrimitive() or other.isInterface() or other.isObject() or
|
return (other.isPrimitive() or other.isInterface() or other.isObject() or
|
||||||
other.isCallback() or other.isDictionary() or
|
other.isCallback() or other.isDictionary() or
|
||||||
other.isSequence() or other.isArray() or
|
other.isSequence() or other.isMozMap() or other.isArray() or
|
||||||
other.isDate())
|
other.isDate())
|
||||||
if self.isDictionary() and other.nullable():
|
if self.isDictionary() and other.nullable():
|
||||||
return False
|
return False
|
||||||
|
@ -2122,7 +2191,7 @@ class IDLWrapperType(IDLType):
|
||||||
(self.isNonCallbackInterface() or
|
(self.isNonCallbackInterface() or
|
||||||
other.isNonCallbackInterface()))
|
other.isNonCallbackInterface()))
|
||||||
if (other.isDictionary() or other.isCallback() or
|
if (other.isDictionary() or other.isCallback() or
|
||||||
other.isSequence() or other.isArray()):
|
other.isSequence() or other.isMozMap() or other.isArray()):
|
||||||
return self.isNonCallbackInterface()
|
return self.isNonCallbackInterface()
|
||||||
|
|
||||||
# Not much else |other| can be
|
# Not much else |other| can be
|
||||||
|
@ -2296,19 +2365,19 @@ class IDLBuiltinType(IDLType):
|
||||||
return (other.isNumeric() or other.isString() or other.isEnum() or
|
return (other.isNumeric() or other.isString() or other.isEnum() or
|
||||||
other.isInterface() or other.isObject() or
|
other.isInterface() or other.isObject() or
|
||||||
other.isCallback() or other.isDictionary() or
|
other.isCallback() or other.isDictionary() or
|
||||||
other.isSequence() or other.isArray() or
|
other.isSequence() or other.isMozMap() or other.isArray() or
|
||||||
other.isDate())
|
other.isDate())
|
||||||
if self.isNumeric():
|
if self.isNumeric():
|
||||||
return (other.isBoolean() or other.isString() or other.isEnum() or
|
return (other.isBoolean() or other.isString() or other.isEnum() or
|
||||||
other.isInterface() or other.isObject() or
|
other.isInterface() or other.isObject() or
|
||||||
other.isCallback() or other.isDictionary() or
|
other.isCallback() or other.isDictionary() or
|
||||||
other.isSequence() or other.isArray() or
|
other.isSequence() or other.isMozMap() or other.isArray() or
|
||||||
other.isDate())
|
other.isDate())
|
||||||
if self.isString():
|
if self.isString():
|
||||||
return (other.isPrimitive() or other.isInterface() or
|
return (other.isPrimitive() or other.isInterface() or
|
||||||
other.isObject() or
|
other.isObject() or
|
||||||
other.isCallback() or other.isDictionary() or
|
other.isCallback() or other.isDictionary() or
|
||||||
other.isSequence() or other.isArray() or
|
other.isSequence() or other.isMozMap() or other.isArray() or
|
||||||
other.isDate())
|
other.isDate())
|
||||||
if self.isAny():
|
if self.isAny():
|
||||||
# Can't tell "any" apart from anything
|
# Can't tell "any" apart from anything
|
||||||
|
@ -2319,7 +2388,7 @@ class IDLBuiltinType(IDLType):
|
||||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||||
other.isInterface() or other.isCallback() or
|
other.isInterface() or other.isCallback() or
|
||||||
other.isDictionary() or other.isSequence() or
|
other.isDictionary() or other.isSequence() or
|
||||||
other.isArray())
|
other.isMozMap() or other.isArray())
|
||||||
if self.isVoid():
|
if self.isVoid():
|
||||||
return not other.isVoid()
|
return not other.isVoid()
|
||||||
# Not much else we could be!
|
# Not much else we could be!
|
||||||
|
@ -2327,7 +2396,8 @@ class IDLBuiltinType(IDLType):
|
||||||
# Like interfaces, but we know we're not a callback
|
# Like interfaces, but we know we're not a callback
|
||||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||||
other.isCallback() or other.isDictionary() or
|
other.isCallback() or other.isDictionary() or
|
||||||
other.isSequence() or other.isArray() or other.isDate() or
|
other.isSequence() or other.isMozMap() or other.isArray() or
|
||||||
|
other.isDate() or
|
||||||
(other.isInterface() and (
|
(other.isInterface() and (
|
||||||
# ArrayBuffer is distinguishable from everything
|
# ArrayBuffer is distinguishable from everything
|
||||||
# that's not an ArrayBuffer or a callback interface
|
# that's not an ArrayBuffer or a callback interface
|
||||||
|
@ -2710,6 +2780,9 @@ class IDLAttribute(IDLInterfaceMember):
|
||||||
if self.type.isSequence() and not self.getExtendedAttribute("Cached"):
|
if self.type.isSequence() and not self.getExtendedAttribute("Cached"):
|
||||||
raise WebIDLError("A non-cached attribute cannot be of a sequence "
|
raise WebIDLError("A non-cached attribute cannot be of a sequence "
|
||||||
"type", [self.location])
|
"type", [self.location])
|
||||||
|
if self.type.isMozMap() and not self.getExtendedAttribute("Cached"):
|
||||||
|
raise WebIDLError("A non-cached attribute cannot be of a MozMap "
|
||||||
|
"type", [self.location])
|
||||||
if self.type.isUnion():
|
if self.type.isUnion():
|
||||||
for f in self.type.unroll().flatMemberTypes:
|
for f in self.type.unroll().flatMemberTypes:
|
||||||
if f.isDictionary():
|
if f.isDictionary():
|
||||||
|
@ -2724,6 +2797,12 @@ class IDLAttribute(IDLInterfaceMember):
|
||||||
"one of its member types's member "
|
"one of its member types's member "
|
||||||
"types, and so on) is a sequence "
|
"types, and so on) is a sequence "
|
||||||
"type", [self.location, f.location])
|
"type", [self.location, f.location])
|
||||||
|
if f.isMozMap():
|
||||||
|
raise WebIDLError("An attribute cannot be of a union "
|
||||||
|
"type if one of its member types (or "
|
||||||
|
"one of its member types's member "
|
||||||
|
"types, and so on) is a MozMap "
|
||||||
|
"type", [self.location, f.location])
|
||||||
if not self.type.isInterface() and self.getExtendedAttribute("PutForwards"):
|
if not self.type.isInterface() and self.getExtendedAttribute("PutForwards"):
|
||||||
raise WebIDLError("An attribute with [PutForwards] must have an "
|
raise WebIDLError("An attribute with [PutForwards] must have an "
|
||||||
"interface type as its type", [self.location])
|
"interface type as its type", [self.location])
|
||||||
|
@ -2742,9 +2821,11 @@ class IDLAttribute(IDLInterfaceMember):
|
||||||
"getter won't always be called.",
|
"getter won't always be called.",
|
||||||
[self.location])
|
[self.location])
|
||||||
if self.getExtendedAttribute("Frozen"):
|
if self.getExtendedAttribute("Frozen"):
|
||||||
if not self.type.isSequence() and not self.type.isDictionary():
|
if (not self.type.isSequence() and not self.type.isDictionary() and
|
||||||
raise WebIDLError("[Frozen] is only allowed on sequence-valued "
|
not self.type.isMozMap()):
|
||||||
"and dictionary-valued attributes",
|
raise WebIDLError("[Frozen] is only allowed on "
|
||||||
|
"sequence-valued, dictionary-valued, and "
|
||||||
|
"MozMap-valued attributes",
|
||||||
[self.location])
|
[self.location])
|
||||||
|
|
||||||
def handleExtendedAttribute(self, attr):
|
def handleExtendedAttribute(self, attr):
|
||||||
|
@ -3627,6 +3708,7 @@ class Tokenizer(object):
|
||||||
"octet": "OCTET",
|
"octet": "OCTET",
|
||||||
"optional": "OPTIONAL",
|
"optional": "OPTIONAL",
|
||||||
"sequence": "SEQUENCE",
|
"sequence": "SEQUENCE",
|
||||||
|
"MozMap": "MOZMAP",
|
||||||
"short": "SHORT",
|
"short": "SHORT",
|
||||||
"unsigned": "UNSIGNED",
|
"unsigned": "UNSIGNED",
|
||||||
"void": "VOID",
|
"void": "VOID",
|
||||||
|
@ -4523,6 +4605,7 @@ class Parser(Tokenizer):
|
||||||
| OCTET
|
| OCTET
|
||||||
| OPTIONAL
|
| OPTIONAL
|
||||||
| SEQUENCE
|
| SEQUENCE
|
||||||
|
| MOZMAP
|
||||||
| SETTER
|
| SETTER
|
||||||
| SHORT
|
| SHORT
|
||||||
| STATIC
|
| STATIC
|
||||||
|
@ -4632,6 +4715,16 @@ class Parser(Tokenizer):
|
||||||
type = IDLNullableType(self.getLocation(p, 5), type)
|
type = IDLNullableType(self.getLocation(p, 5), type)
|
||||||
p[0] = type
|
p[0] = type
|
||||||
|
|
||||||
|
def p_NonAnyTypeMozMapType(self, p):
|
||||||
|
"""
|
||||||
|
NonAnyType : MOZMAP LT Type GT Null
|
||||||
|
"""
|
||||||
|
innerType = p[3]
|
||||||
|
type = IDLMozMapType(self.getLocation(p, 1), innerType)
|
||||||
|
if p[5]:
|
||||||
|
type = IDLNullableType(self.getLocation(p, 5), type)
|
||||||
|
p[0] = type
|
||||||
|
|
||||||
def p_NonAnyTypeScopedName(self, p):
|
def p_NonAnyTypeScopedName(self, p):
|
||||||
"""
|
"""
|
||||||
NonAnyType : ScopedName TypeSuffix
|
NonAnyType : ScopedName TypeSuffix
|
||||||
|
|
|
@ -158,6 +158,7 @@ def WebIDLTest(parser, harness):
|
||||||
"CallbackInterface?", "CallbackInterface2",
|
"CallbackInterface?", "CallbackInterface2",
|
||||||
"object", "Callback", "Callback2", "optional Dict",
|
"object", "Callback", "Callback2", "optional Dict",
|
||||||
"optional Dict2", "sequence<long>", "sequence<short>",
|
"optional Dict2", "sequence<long>", "sequence<short>",
|
||||||
|
"MozMap<object>", "MozMap<Dict>", "MozMap<long>",
|
||||||
"long[]", "short[]", "Date", "Date?", "any" ]
|
"long[]", "short[]", "Date", "Date?", "any" ]
|
||||||
# When we can parse Date and RegExp, we need to add them here.
|
# When we can parse Date and RegExp, we need to add them here.
|
||||||
|
|
||||||
|
@ -219,6 +220,9 @@ def WebIDLTest(parser, harness):
|
||||||
setDistinguishable("optional Dict2", allBut(nonUserObjects, nullables))
|
setDistinguishable("optional Dict2", allBut(nonUserObjects, nullables))
|
||||||
setDistinguishable("sequence<long>", nonUserObjects)
|
setDistinguishable("sequence<long>", nonUserObjects)
|
||||||
setDistinguishable("sequence<short>", nonUserObjects)
|
setDistinguishable("sequence<short>", nonUserObjects)
|
||||||
|
setDistinguishable("MozMap<object>", nonUserObjects)
|
||||||
|
setDistinguishable("MozMap<Dict>", nonUserObjects)
|
||||||
|
setDistinguishable("MozMap<long>", nonUserObjects)
|
||||||
setDistinguishable("long[]", nonUserObjects)
|
setDistinguishable("long[]", nonUserObjects)
|
||||||
setDistinguishable("short[]", nonUserObjects)
|
setDistinguishable("short[]", nonUserObjects)
|
||||||
setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
|
setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import WebIDL
|
||||||
|
|
||||||
|
def WebIDLTest(parser, harness):
|
||||||
|
parser.parse("""
|
||||||
|
dictionary Dict {};
|
||||||
|
interface MozMapArg {
|
||||||
|
void foo(MozMap<Dict> arg);
|
||||||
|
};
|
||||||
|
""")
|
||||||
|
|
||||||
|
results = parser.finish()
|
||||||
|
|
||||||
|
harness.check(len(results), 2, "Should know about two things");
|
||||||
|
harness.ok(isinstance(results[1], WebIDL.IDLInterface),
|
||||||
|
"Should have an interface here");
|
||||||
|
members = results[1].members
|
||||||
|
harness.check(len(members), 1, "Should have one member")
|
||||||
|
harness.ok(members[0].isMethod(), "Should have method")
|
||||||
|
signature = members[0].signatures()[0]
|
||||||
|
args = signature[1]
|
||||||
|
harness.check(len(args), 1, "Should have one arg")
|
||||||
|
harness.ok(args[0].type.isMozMap(), "Should have a MozMap type here")
|
||||||
|
harness.ok(args[0].type.inner.isDictionary(),
|
||||||
|
"Should have a dictionary inner type")
|
||||||
|
|
||||||
|
parser = parser.reset()
|
||||||
|
threw = False
|
||||||
|
try:
|
||||||
|
parser.parse("""
|
||||||
|
interface MozMapVoidArg {
|
||||||
|
void foo(MozMap<void> arg);
|
||||||
|
};
|
||||||
|
""")
|
||||||
|
|
||||||
|
results = parser.finish()
|
||||||
|
except Exception,x:
|
||||||
|
threw = True
|
||||||
|
|
||||||
|
harness.ok(threw, "Should have thrown.")
|
Загрузка…
Ссылка в новой задаче