Support sequences of sequences in generated bindings.

unroll recursively gets the inner type of any sequence type encountered, so it's inappropriate for codegen that only wants the immediate inner type. However, if a type identifies as a sequence and is nullable, we need to reach through the nullable wrapper first. Gecko does very similar things.
This commit is contained in:
Josh Matthews 2016-07-21 10:09:52 -04:00
parent 2df5d705e1
commit 9ef848b65e
3 changed files with 24 additions and 5 deletions

View file

@ -87,6 +87,11 @@ def stripTrailingWhitespace(text):
return '\n'.join(lines) + tail
def innerSequenceType(type):
assert type.isSequence()
return type.inner.inner if type.nullable() else type.inner
def MakeNativeName(name):
return name[0].upper() + name[1:]
@ -713,7 +718,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
raise TypeError("Can't handle array arguments yet")
if type.isSequence():
innerInfo = getJSToNativeConversionInfo(type.unroll(), descriptorProvider)
innerInfo = getJSToNativeConversionInfo(innerSequenceType(type), descriptorProvider)
declType = CGWrapper(innerInfo.declType, pre="Vec<", post=">")
config = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs)
@ -1302,8 +1307,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
if returnType.isObject() or returnType.isSpiderMonkeyInterface():
return CGGeneric("*mut JSObject")
if returnType.isSequence():
inner = returnType.unroll()
result = getRetvalDeclarationForType(inner, descriptorProvider)
result = getRetvalDeclarationForType(innerSequenceType(returnType), descriptorProvider)
result = CGWrapper(result, pre="Vec<", post=">")
if returnType.nullable():
result = CGWrapper(result, pre="Option<", post=">")
@ -3743,7 +3747,7 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
typeName = name
elif type.isSequence():
name = type.name
inner = getUnionTypeTemplateVars(type.unroll(), descriptorProvider)
inner = getUnionTypeTemplateVars(innerSequenceType(type), descriptorProvider)
typeName = "Vec<" + inner["typeName"] + ">"
elif type.isArray():
name = str(type)

View file

@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::FunctionBinding::Function;
use dom::bindings::codegen::Bindings::TestBindingBinding;
use dom::bindings::codegen::Bindings::TestBindingBinding::{TestBindingMethods, TestDictionary};
use dom::bindings::codegen::Bindings::TestBindingBinding::{TestDictionaryDefaults, TestEnum};
use dom::bindings::codegen::UnionTypes::{BlobOrBoolean, BlobOrBlobSequence};
use dom::bindings::codegen::UnionTypes::{BlobOrBoolean, BlobOrBlobSequence, LongOrLongSequenceSequence};
use dom::bindings::codegen::UnionTypes::{BlobOrString, BlobOrUnsignedLong, EventOrString};
use dom::bindings::codegen::UnionTypes::{EventOrUSVString, HTMLElementOrLong};
use dom::bindings::codegen::UnionTypes::{HTMLElementOrUnsignedLongOrStringOrBoolean, LongSequenceOrBoolean};
@ -572,6 +572,17 @@ impl TestBindingMethods for TestBinding {
fn FuncControlledMethodDisabled(&self) {}
fn FuncControlledMethodEnabled(&self) {}
fn PassSequenceSequence(&self, _seq: Vec<Vec<i32>>) {}
fn ReturnSequenceSequence(&self) -> Vec<Vec<i32>> { vec![] }
fn PassUnionSequenceSequence(&self, seq: LongOrLongSequenceSequence) {
match seq {
LongOrLongSequenceSequence::Long(_) => (),
LongOrLongSequenceSequence::LongSequenceSequence(seq) => {
let _seq: Vec<Vec<i32>> = seq;
}
}
}
#[allow(unsafe_code)]
fn CrashHard(&self) {
static READ_ONLY_VALUE: i32 = 0;

View file

@ -409,6 +409,10 @@ interface TestBinding {
void passVariadicAny(any... args);
void passVariadicObject(object... args);
void passSequenceSequence(sequence<sequence<long>> seq);
sequence<sequence<long>> returnSequenceSequence();
void passUnionSequenceSequence((long or sequence<sequence<long>>) seq);
static attribute boolean booleanAttributeStatic;
static void receiveVoidStatic();
boolean BooleanMozPreference(DOMString pref_name);