Merge pull request #511 from alexcrichton/tweak-types

Add support for more slice types in WebIDL
This commit is contained in:
Nick Fitzgerald 2018-07-19 11:08:09 -07:00 committed by GitHub
commit 3e2d1e6519
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 169 additions and 24 deletions

View File

@ -129,6 +129,17 @@ impl<'a> FirstPassRecord<'a> {
if ty.nullable {
return None;
}
let array = |base_ty: &str| {
match pos {
TypePosition::Argument => {
shared_ref(slice_ty(ident_ty(raw_ident(base_ty))))
}
TypePosition::Return => {
vec_ty(ident_ty(raw_ident(base_ty)))
}
}
};
Some(match ty.kind {
// `any` becomes `::wasm_bindgen::JsValue`.
webidl::ast::TypeKind::Any => {
@ -172,21 +183,30 @@ impl<'a> FirstPassRecord<'a> {
webidl::ast::TypeKind::UnsignedLongLong => ident_ty(raw_ident("u64")),
webidl::ast::TypeKind::UnsignedShort => ident_ty(raw_ident("u16")),
// `DOMString -> `&str` for arguments
webidl::ast::TypeKind::DOMString if pos == TypePosition::Argument => {
shared_ref(ident_ty(raw_ident("str")))
}
webidl::ast::TypeKind::DOMString => {
ident_ty(raw_ident("String"))
},
webidl::ast::TypeKind::Float32Array => array("f32"),
webidl::ast::TypeKind::Float64Array => array("f64"),
webidl::ast::TypeKind::Int8Array => array("i8"),
webidl::ast::TypeKind::Int16Array => array("i16"),
webidl::ast::TypeKind::Int32Array => array("i32"),
webidl::ast::TypeKind::Uint8Array => array("u8"),
webidl::ast::TypeKind::Uint8ClampedArray => array("u8"),
webidl::ast::TypeKind::Uint16Array => array("u16"),
webidl::ast::TypeKind::Uint32Array => array("u32"),
// `ByteString -> `&[u8]` for arguments
webidl::ast::TypeKind::ByteString if pos == TypePosition::Argument => {
shared_ref(slice_ty(ident_ty(raw_ident("u8"))))
}
// ... and `Vec<u8>` for arguments
webidl::ast::TypeKind::ByteString => {
vec_ty(ident_ty(raw_ident("u8")))
// strings -> `&str` for arguments and `String` for return
//
// Note that DOMString mostly makes sense here, ByteString maps to
// String in JS [1], along with USVString
//
// [1]: https://developer.mozilla.org/en-US/docs/Web/API/ByteString
// [2]: https://developer.mozilla.org/en-US/docs/Web/API/USVString
webidl::ast::TypeKind::DOMString
| webidl::ast::TypeKind::ByteString
| webidl::ast::TypeKind::USVString => {
match pos {
TypePosition::Argument => shared_ref(ident_ty(raw_ident("str"))),
TypePosition::Return => ident_ty(raw_ident("String")),
}
}
// Support for these types is not yet implemented, so skip
@ -194,22 +214,12 @@ impl<'a> FirstPassRecord<'a> {
webidl::ast::TypeKind::ArrayBuffer
| webidl::ast::TypeKind::DataView
| webidl::ast::TypeKind::Error
| webidl::ast::TypeKind::Float32Array
| webidl::ast::TypeKind::Float64Array
| webidl::ast::TypeKind::FrozenArray(_)
| webidl::ast::TypeKind::Int16Array
| webidl::ast::TypeKind::Int32Array
| webidl::ast::TypeKind::Int8Array
| webidl::ast::TypeKind::Object
| webidl::ast::TypeKind::Promise(_)
| webidl::ast::TypeKind::Record(..)
| webidl::ast::TypeKind::Sequence(_)
| webidl::ast::TypeKind::Symbol
| webidl::ast::TypeKind::USVString
| webidl::ast::TypeKind::Uint16Array
| webidl::ast::TypeKind::Uint32Array
| webidl::ast::TypeKind::Uint8Array
| webidl::ast::TypeKind::Uint8ClampedArray
| webidl::ast::TypeKind::Union(_) => {
return None;
}

View File

@ -0,0 +1,134 @@
use super::project;
#[test]
fn take_and_return_a_bunch_of_slices() {
project()
.file(
"foo.webidl",
r#"
[Constructor()]
interface Foo {
DOMString strings(DOMString arg1);
ByteString byteStrings(ByteString arg1);
USVString usvStrings(USVString arg1);
Float32Array f32(Float32Array a);
Float64Array f64(Float64Array a);
Int8Array i8(Int8Array a);
Int16Array i16(Int16Array a);
Int32Array i32(Int32Array a);
Uint8Array u8(Uint8Array a);
Uint8ClampedArray u8Clamped(Uint8ClampedArray a);
Uint16Array u16(Uint16Array a);
Uint32Array u32(Uint32Array a);
};
"#,
)
.file(
"foo.js",
r#"
import { strictEqual } from "assert";
export class Foo {
strings(x) {
strictEqual(x, 'y');
return 'x';
}
byteStrings(x) {
strictEqual(x, 'yz');
return 'xx';
}
usvStrings(x) {
strictEqual(x, 'abc');
return 'efg';
}
f32(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Float32Array([3, 4, 5]);
}
f64(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Float64Array([3, 4, 5]);
}
i8(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Int8Array([3, 4, 5]);
}
i16(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Int16Array([3, 4, 5]);
}
i32(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Int32Array([3, 4, 5]);
}
u8(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Uint8Array([3, 4, 5]);
}
u8Clamped(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Uint8ClampedArray([3, 4, 5]);
}
u16(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Uint16Array([3, 4, 5]);
}
u32(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Uint32Array([3, 4, 5]);
}
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(use_extern_macros, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod foo;
use foo::Foo;
#[wasm_bindgen]
pub fn test() {
let f = Foo::new().unwrap();
assert_eq!(f.strings("y"), "x");
assert_eq!(f.byte_strings("yz"), "xx");
assert_eq!(f.usv_strings("abc"), "efg");
assert_eq!(f.f32(&[1.0, 2.0]), [3.0, 4.0, 5.0]);
assert_eq!(f.f64(&[1.0, 2.0]), [3.0, 4.0, 5.0]);
assert_eq!(f.i8(&[1, 2]), [3, 4, 5]);
assert_eq!(f.i16(&[1, 2]), [3, 4, 5]);
assert_eq!(f.i32(&[1, 2]), [3, 4, 5]);
assert_eq!(f.u8(&[1, 2]), [3, 4, 5]);
assert_eq!(f.u8_clamped(&[1, 2]), [3, 4, 5]);
assert_eq!(f.u16(&[1, 2]), [3, 4, 5]);
assert_eq!(f.u32(&[1, 2]), [3, 4, 5]);
}
"#,
)
.test();
}

View File

@ -5,3 +5,4 @@ mod consts;
mod enums;
mod simple;
mod throws;
mod array;