Bug 1063889. Fix the handling of sequences of wrapper types in unions. r=khuey

This commit is contained in:
Boris Zbarsky 2014-09-08 11:28:57 -04:00
parent 92fda10b76
commit 935648f51a
8 changed files with 42 additions and 14 deletions

View File

@ -1216,6 +1216,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, config):
def addHeadersForType(f):
if f.nullable():
headers.add("mozilla/dom/Nullable.h")
isSequence = f.isSequence()
f = f.unroll()
if f.isInterface():
if f.isSpiderMonkeyInterface():
@ -1227,10 +1228,14 @@ def UnionTypes(descriptors, dictionaries, callbacks, config):
typeDesc = p.getDescriptor(f.inner.identifier.name)
except NoSuchDescriptorError:
continue
if typeDesc.interface.isCallback():
if typeDesc.interface.isCallback() or isSequence:
# Callback interfaces always use strong refs, so
# we need to include the right header to be able
# to Release() in our inlined code.
#
# Similarly, sequences always contain strong
# refs, so we'll need the header to handler
# those.
headers.add(typeDesc.headerFile)
else:
declarations.add((typeDesc.nativeType, False))
@ -4651,7 +4656,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if type.isSpiderMonkeyInterface():
assert not isEnforceRange and not isClamp
name = type.name
name = type.unroll().name # unroll() because it may be nullable
arrayType = CGGeneric(name)
declType = arrayType
if type.nullable():
@ -6202,8 +6207,6 @@ def getUnionMemberName(type):
return type.inner.identifier.name
if type.isEnum():
return type.inner.identifier.name
if type.isArray() or type.isSequence() or type.isMozMap():
return str(type)
return type.name
@ -12448,7 +12451,8 @@ class CGNativeMember(ClassMethod):
if not self.typedArraysAreStructs:
return "JS::Handle<JSObject*>", False, False
return type.name, True, True
# Unroll for the name, in case we're nullable.
return type.unroll().name, True, True
if type.isDOMString() or type.isScalarValueString():
if isMember:

View File

@ -1764,7 +1764,10 @@ class IDLNullableType(IDLType):
assert not innerType.isVoid()
assert not innerType == BuiltinTypes[IDLBuiltinType.Types.any]
IDLType.__init__(self, location, innerType.name)
name = innerType.name
if innerType.isComplete():
name += "OrNull"
IDLType.__init__(self, location, name)
self.inner = innerType
self.builtin = False
@ -1877,7 +1880,7 @@ class IDLNullableType(IDLType):
"be a union type that itself has a nullable "
"type as a member type", [self.location])
self.name = self.inner.name
self.name = self.inner.name + "OrNull"
return self
def unroll(self):
@ -1900,6 +1903,10 @@ class IDLSequenceType(IDLType):
IDLType.__init__(self, location, parameterType.name)
self.inner = parameterType
self.builtin = False
# Need to set self.name up front if our inner type is already complete,
# since in that case our .complete() won't be called.
if self.inner.isComplete():
self.name = self.inner.name + "Sequence"
def __eq__(self, other):
return isinstance(other, IDLSequenceType) and self.inner == other.inner
@ -1961,7 +1968,7 @@ class IDLSequenceType(IDLType):
def complete(self, scope):
self.inner = self.inner.complete(scope)
self.name = self.inner.name
self.name = self.inner.name + "Sequence"
return self
def unroll(self):
@ -1987,6 +1994,10 @@ class IDLMozMapType(IDLType):
IDLType.__init__(self, location, parameterType.name)
self.inner = parameterType
self.builtin = False
# Need to set self.name up front if our inner type is already complete,
# since in that case our .complete() won't be called.
if self.inner.isComplete():
self.name = self.inner.name + "MozMap"
def __eq__(self, other):
return isinstance(other, IDLMozMapType) and self.inner == other.inner
@ -2012,7 +2023,7 @@ class IDLMozMapType(IDLType):
def complete(self, scope):
self.inner = self.inner.complete(scope)
self.name = self.inner.name
self.name = self.inner.name + "MozMap"
return self
def unroll(self):
@ -2077,9 +2088,6 @@ class IDLUnionType(IDLType):
return typeName(type._identifier.object())
if isinstance(type, IDLObjectWithIdentifier):
return typeName(type.identifier)
if (isinstance(type, IDLType) and
(type.isArray() or type.isSequence() or type.isMozMap)):
return str(type)
return type.name
for (i, type) in enumerate(self.memberTypes):

View File

@ -90,7 +90,7 @@ def checkEquivalent(iface, harness):
for attr in dir(type1):
if attr.startswith('_') or \
attr in ['nullable', 'builtin', 'filename', 'location',
'inner', 'QName', 'getDeps'] or \
'inner', 'QName', 'getDeps', 'name'] or \
(hasattr(type(type1), attr) and not callable(getattr(type1, attr))):
continue

View File

@ -12,7 +12,7 @@ def WebIDLTest(parser, harness):
results = parser.finish()
harness.check(results[2].members[1].type.name, "Long",
harness.check(results[2].members[1].type.name, "LongOrNull",
"Should expand typedefs")
parser = parser.reset()

View File

@ -603,6 +603,10 @@ public:
void PassUnion20(JSContext*, const ObjectSequenceOrLong&);
void PassUnion21(const LongMozMapOrLong&);
void PassUnion22(JSContext*, const ObjectMozMapOrLong&);
void PassUnion23(const ImageDataSequenceOrLong&);
void PassUnion24(const ImageDataOrNullSequenceOrLong&);
void PassUnion25(const ImageDataSequenceSequenceOrLong&);
void PassUnion26(const ImageDataOrNullSequenceSequenceOrLong&);
void PassUnionWithCallback(const EventHandlerNonNullOrNullOrLong& arg);
void PassUnionWithByteString(const ByteStringOrLong&);
void PassUnionWithMozMap(const StringMozMapOrString&);

View File

@ -567,6 +567,10 @@ interface TestInterface {
void passUnion20(optional (sequence<object> or long) arg = []);
void passUnion21((MozMap<long> or long) arg);
void passUnion22((MozMap<object> or long) arg);
void passUnion23((sequence<ImageData> or long) arg);
void passUnion24((sequence<ImageData?> or long) arg);
void passUnion25((sequence<sequence<ImageData>> or long) arg);
void passUnion26((sequence<sequence<ImageData?>> or long) arg);
void passUnionWithCallback((EventHandler or long) arg);
void passUnionWithByteString((ByteString or long) arg);
void passUnionWithMozMap((MozMap<DOMString> or DOMString) arg);

View File

@ -431,6 +431,10 @@ interface TestExampleInterface {
void passUnion20(optional (sequence<object> or long) arg = []);
void passUnion21((MozMap<long> or long) arg);
void passUnion22((MozMap<object> or long) arg);
void passUnion23((sequence<ImageData> or long) arg);
void passUnion24((sequence<ImageData?> or long) arg);
void passUnion25((sequence<sequence<ImageData>> or long) arg);
void passUnion26((sequence<sequence<ImageData?>> or long) arg);
void passUnionWithCallback((EventHandler or long) arg);
void passUnionWithByteString((ByteString or long) arg);
void passUnionWithMozMap((MozMap<DOMString> or DOMString) arg);

View File

@ -451,6 +451,10 @@ interface TestJSImplInterface {
void passUnion20(optional (sequence<object> or long) arg = []);
void passUnion21((MozMap<long> or long) arg);
void passUnion22((MozMap<object> or long) arg);
void passUnion23((sequence<ImageData> or long) arg);
void passUnion24((sequence<ImageData?> or long) arg);
void passUnion25((sequence<sequence<ImageData>> or long) arg);
void passUnion26((sequence<sequence<ImageData?>> or long) arg);
void passUnionWithCallback((EventHandler or long) arg);
void passUnionWithByteString((ByteString or long) arg);
void passUnionWithMozMap((MozMap<DOMString> or DOMString) arg);