Skip to content

Commit

Permalink
Support sequences of sequences in generated bindings.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jdm committed Jul 21, 2016
1 parent 2df5d70 commit 9ef848b
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 5 deletions.
12 changes: 8 additions & 4 deletions components/script/dom/bindings/codegen/CodegenRust.py
Expand Up @@ -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:]

Expand Down Expand Up @@ -713,7 +718,7 @@ def wrapObjectTemplate(templateBody, nullValue, isDefinitelyObject, type,
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)

Expand Down Expand Up @@ -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=">")
Expand Down Expand Up @@ -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)
Expand Down
13 changes: 12 additions & 1 deletion components/script/dom/testbinding.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions components/script/dom/webidls/TestBinding.webidl
Expand Up @@ -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);
Expand Down

0 comments on commit 9ef848b

Please sign in to comment.