зеркало из https://github.com/mozilla/gecko-dev.git
Bug 819845. Update WebIDL bindings to spec change: sequences/arrays are no longer distinguishable from dictionaries, and conversion to a sequence works on arbitrary objects. r=khuey
This commit is contained in:
Родитель
b323555284
Коммит
eabd327329
|
@ -210,9 +210,8 @@ IsArrayLike(JSContext* cx, JSObject* obj)
|
|||
ac.construct(cx, obj);
|
||||
}
|
||||
|
||||
// XXXbz need to detect platform objects (including listbinding
|
||||
// ones) with indexGetters here!
|
||||
return JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj);
|
||||
// Everything except dates and regexps is arraylike
|
||||
return !JS_ObjectIsDate(cx, obj) && !JS_ObjectIsRegExp(cx, obj);
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
|
|
@ -2313,9 +2313,6 @@ for (uint32_t i = 0; i < length; ++i) {
|
|||
memberType = arrayObjectMemberTypes[0]
|
||||
name = memberType.name
|
||||
arrayObject = CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${obj}, ${val}, ${valPtr}, tryNext)) || !tryNext;" % (unionArgumentObj, name))
|
||||
# XXX Now we're supposed to check for an array or a platform object
|
||||
# that supports indexed properties... skip that last for now. It's a
|
||||
# bit of a pain.
|
||||
arrayObject = CGWrapper(CGIndenter(arrayObject),
|
||||
pre="if (IsArrayLike(cx, &argObj)) {\n",
|
||||
post="}")
|
||||
|
|
|
@ -1287,8 +1287,7 @@ class IDLSequenceType(IDLType):
|
|||
# Just forward to the union; it'll deal
|
||||
return other.isDistinguishableFrom(self)
|
||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||
other.isDictionary() or other.isDate() or
|
||||
other.isNonCallbackInterface())
|
||||
other.isDate() or other.isNonCallbackInterface())
|
||||
|
||||
class IDLUnionType(IDLType):
|
||||
def __init__(self, location, memberTypes):
|
||||
|
@ -1452,8 +1451,7 @@ class IDLArrayType(IDLType):
|
|||
# Just forward to the union; it'll deal
|
||||
return other.isDistinguishableFrom(self)
|
||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||
other.isDictionary() or other.isDate() or
|
||||
other.isNonCallbackInterface())
|
||||
other.isDate() or other.isNonCallbackInterface())
|
||||
|
||||
class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
|
||||
def __init__(self, location, innerType, name):
|
||||
|
@ -1618,16 +1616,14 @@ class IDLWrapperType(IDLType):
|
|||
other.isCallback() or other.isDictionary() or
|
||||
other.isSequence() or other.isArray() or
|
||||
other.isDate())
|
||||
if self.isDictionary() and other.nullable():
|
||||
return False
|
||||
if other.isPrimitive() or other.isString() or other.isEnum() or other.isDate():
|
||||
return True
|
||||
if self.isDictionary():
|
||||
return (not other.nullable() and
|
||||
(other.isNonCallbackInterface() or other.isSequence() or
|
||||
other.isArray()))
|
||||
return other.isNonCallbackInterface()
|
||||
|
||||
assert self.isInterface()
|
||||
# XXXbz need to check that the interfaces can't be implemented
|
||||
# by the same object
|
||||
if other.isInterface():
|
||||
if other.isSpiderMonkeyInterface():
|
||||
# Just let |other| handle things
|
||||
|
|
|
@ -148,3 +148,109 @@ def WebIDLTest(parser, harness):
|
|||
threw = True
|
||||
|
||||
harness.ok(threw, "Should throw when there is no distinguishing index")
|
||||
|
||||
# Now let's test our whole distinguishability table
|
||||
argTypes = [ "long", "short", "long?", "short?", "DOMString", "Enum",
|
||||
"Enum2", "Interface", "Interface?",
|
||||
"AncestorInterface", "UnrelatedInterface",
|
||||
"ImplementedInterface", "CallbackInterface",
|
||||
"CallbackInterface?", "CallbackInterface2",
|
||||
"object", "Callback", "Callback2", "optional Dict",
|
||||
"optional Dict2", "sequence<long>", "sequence<short>",
|
||||
"long[]", "short[]" ]
|
||||
# When we can parse Date and RegExp, we need to add them here.
|
||||
|
||||
# Try to categorize things a bit to keep list lengths down
|
||||
def allBut(list1, list2):
|
||||
return [a for a in list1 if a not in list2]
|
||||
primitives = [ "long", "short", "long?", "short?", "DOMString",
|
||||
"Enum", "Enum2" ]
|
||||
nonPrimitives = allBut(argTypes, primitives)
|
||||
interfaces = [ "Interface", "Interface?", "AncestorInterface",
|
||||
"UnrelatedInterface", "ImplementedInterface" ]
|
||||
nullables = ["long?", "short?", "Interface?", "CallbackInterface?",
|
||||
"optional Dict", "optional Dict2"]
|
||||
nonUserObjects = primitives + interfaces
|
||||
otherObjects = allBut(argTypes, nonUserObjects + ["object"])
|
||||
notRelatedInterfaces = primitives + ["UnrelatedInterface"] + otherObjects
|
||||
|
||||
# Build a representation of the distinguishability table as a dict
|
||||
# of dicts, holding True values where needed, holes elsewhere.
|
||||
data = dict();
|
||||
for type in argTypes:
|
||||
data[type] = dict()
|
||||
def setDistinguishable(type, types):
|
||||
for other in types:
|
||||
data[type][other] = True
|
||||
|
||||
setDistinguishable("long", nonPrimitives)
|
||||
setDistinguishable("short", nonPrimitives)
|
||||
setDistinguishable("long?", allBut(nonPrimitives, nullables))
|
||||
setDistinguishable("short?", allBut(nonPrimitives, nullables))
|
||||
setDistinguishable("DOMString", nonPrimitives)
|
||||
setDistinguishable("Enum", nonPrimitives)
|
||||
setDistinguishable("Enum2", nonPrimitives)
|
||||
setDistinguishable("Interface", notRelatedInterfaces)
|
||||
setDistinguishable("Interface?", allBut(notRelatedInterfaces, nullables))
|
||||
setDistinguishable("AncestorInterface", notRelatedInterfaces)
|
||||
setDistinguishable("UnrelatedInterface",
|
||||
allBut(argTypes, ["object", "UnrelatedInterface"]))
|
||||
setDistinguishable("ImplementedInterface", notRelatedInterfaces)
|
||||
setDistinguishable("CallbackInterface", nonUserObjects)
|
||||
setDistinguishable("CallbackInterface?", allBut(nonUserObjects, nullables))
|
||||
setDistinguishable("CallbackInterface2", nonUserObjects)
|
||||
setDistinguishable("object", primitives)
|
||||
setDistinguishable("Callback", nonUserObjects)
|
||||
setDistinguishable("Callback2", nonUserObjects)
|
||||
setDistinguishable("optional Dict", allBut(nonUserObjects, nullables))
|
||||
setDistinguishable("optional Dict2", allBut(nonUserObjects, nullables))
|
||||
setDistinguishable("sequence<long>", nonUserObjects)
|
||||
setDistinguishable("sequence<short>", nonUserObjects)
|
||||
setDistinguishable("long[]", nonUserObjects)
|
||||
setDistinguishable("short[]", nonUserObjects)
|
||||
|
||||
def areDistinguishable(type1, type2):
|
||||
return data[type1].get(type2, False)
|
||||
|
||||
def checkDistinguishability(parser, type1, type2):
|
||||
idlTemplate = """
|
||||
enum Enum { "a", "b" };
|
||||
enum Enum2 { "c", "d" };
|
||||
interface Interface : AncestorInterface {};
|
||||
interface AncestorInterface {};
|
||||
interface UnrelatedInterface {};
|
||||
interface ImplementedInterface {};
|
||||
Interface implements ImplementedInterface;
|
||||
callback interface CallbackInterface {};
|
||||
callback interface CallbackInterface2 {};
|
||||
callback Callback = any();
|
||||
callback Callback2 = long(short arg);
|
||||
dictionary Dict {};
|
||||
dictionary Dict2 {};
|
||||
interface TestInterface {%s
|
||||
};
|
||||
"""
|
||||
methodTemplate = """
|
||||
void myMethod(%s arg);"""
|
||||
methods = (methodTemplate % type1) + (methodTemplate % type2)
|
||||
idl = idlTemplate % methods
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse(idl)
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
if areDistinguishable(type1, type2):
|
||||
harness.ok(not threw,
|
||||
"Should not throw for '%s' and '%s' because they are distinguishable" % (type1, type2))
|
||||
else:
|
||||
harness.ok(threw,
|
||||
"Should throw for '%s' and '%s' because they are not distinguishable" % (type1, type2))
|
||||
|
||||
# Enumerate over everything in both orders, since order matters in
|
||||
# terms of our implementation of distinguishability checks
|
||||
for type1 in argTypes:
|
||||
for type2 in argTypes:
|
||||
checkDistinguishability(parser, type1, type2)
|
||||
|
|
Загрузка…
Ссылка в новой задаче