mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-12-15 12:44:31 +03:00
Merge branch 'master' into reexporting_in_2018
This commit is contained in:
commit
42c1cdd8bf
@ -79,6 +79,7 @@ pub struct Import {
|
||||
pub enum ImportModule {
|
||||
None,
|
||||
Named(String, Span),
|
||||
RawNamed(String, Span),
|
||||
Inline(usize, Span),
|
||||
}
|
||||
|
||||
@ -96,6 +97,10 @@ impl Hash for ImportModule {
|
||||
2u8.hash(h);
|
||||
idx.hash(h);
|
||||
}
|
||||
ImportModule::RawNamed(name, _) => {
|
||||
3u8.hash(h);
|
||||
name.hash(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -844,6 +844,18 @@ impl ToTokens for ast::ImportEnum {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::all)]
|
||||
impl wasm_bindgen::convert::OptionIntoWasmAbi for #name {
|
||||
#[inline]
|
||||
fn none() -> Self::Abi { Object::none() }
|
||||
}
|
||||
|
||||
#[allow(clippy::all)]
|
||||
impl wasm_bindgen::convert::OptionFromWasmAbi for #name {
|
||||
#[inline]
|
||||
fn is_none(abi: &Self::Abi) -> bool { Object::is_none(abi) }
|
||||
}
|
||||
|
||||
#[allow(clippy::all)]
|
||||
impl From<#name> for wasm_bindgen::JsValue {
|
||||
fn from(obj: #name) -> wasm_bindgen::JsValue {
|
||||
|
@ -208,6 +208,7 @@ fn shared_import<'a>(i: &'a ast::Import, intern: &'a Interner) -> Result<Import<
|
||||
ast::ImportModule::Named(m, span) => {
|
||||
ImportModule::Named(intern.resolve_import_module(m, *span)?)
|
||||
}
|
||||
ast::ImportModule::RawNamed(m, _span) => ImportModule::RawNamed(intern.intern_str(m)),
|
||||
ast::ImportModule::Inline(idx, _) => ImportModule::Inline(*idx as u32),
|
||||
ast::ImportModule::None => ImportModule::None,
|
||||
},
|
||||
|
@ -2836,6 +2836,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
// not sure how to import them.
|
||||
let is_local_snippet = match import.module {
|
||||
decode::ImportModule::Named(s) => self.cx.local_modules.contains_key(s),
|
||||
decode::ImportModule::RawNamed(_) => false,
|
||||
decode::ImportModule::Inline(_) => true,
|
||||
decode::ImportModule::None => false,
|
||||
};
|
||||
@ -2921,11 +2922,13 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
name,
|
||||
field,
|
||||
},
|
||||
decode::ImportModule::Named(module) => Import::Module {
|
||||
module,
|
||||
name,
|
||||
field,
|
||||
},
|
||||
decode::ImportModule::Named(module) | decode::ImportModule::RawNamed(module) => {
|
||||
Import::Module {
|
||||
module,
|
||||
name,
|
||||
field,
|
||||
}
|
||||
}
|
||||
decode::ImportModule::Inline(idx) => {
|
||||
let offset = *self
|
||||
.cx
|
||||
|
@ -33,6 +33,7 @@ macro_rules! attrgen {
|
||||
(static_method_of, StaticMethodOf(Span, Ident)),
|
||||
(js_namespace, JsNamespace(Span, Ident)),
|
||||
(module, Module(Span, String, Span)),
|
||||
(raw_module, RawModule(Span, String, Span)),
|
||||
(inline_js, InlineJs(Span, String, Span)),
|
||||
(getter, Getter(Span, Option<Ident>)),
|
||||
(setter, Setter(Span, Option<Ident>)),
|
||||
@ -1085,24 +1086,28 @@ impl MacroParse<BindgenAttrs> for syn::ItemForeignMod {
|
||||
));
|
||||
}
|
||||
}
|
||||
let module = match opts.module() {
|
||||
Some((name, span)) => {
|
||||
if opts.inline_js().is_some() {
|
||||
let msg = "cannot specify both `module` and `inline_js`";
|
||||
errors.push(Diagnostic::span_error(span, msg));
|
||||
}
|
||||
ast::ImportModule::Named(name.to_string(), span)
|
||||
let module = if let Some((name, span)) = opts.module() {
|
||||
if opts.inline_js().is_some() {
|
||||
let msg = "cannot specify both `module` and `inline_js`";
|
||||
errors.push(Diagnostic::span_error(span, msg));
|
||||
}
|
||||
None => {
|
||||
match opts.inline_js() {
|
||||
Some((js, span)) => {
|
||||
let i = program.inline_js.len();
|
||||
program.inline_js.push(js.to_string());
|
||||
ast::ImportModule::Inline(i, span)
|
||||
}
|
||||
None => ast::ImportModule::None
|
||||
}
|
||||
if opts.raw_module().is_some() {
|
||||
let msg = "cannot specify both `module` and `raw_module`";
|
||||
errors.push(Diagnostic::span_error(span, msg));
|
||||
}
|
||||
ast::ImportModule::Named(name.to_string(), span)
|
||||
} else if let Some((name, span)) = opts.raw_module() {
|
||||
if opts.inline_js().is_some() {
|
||||
let msg = "cannot specify both `raw_module` and `inline_js`";
|
||||
errors.push(Diagnostic::span_error(span, msg));
|
||||
}
|
||||
ast::ImportModule::RawNamed(name.to_string(), span)
|
||||
} else if let Some((js, span)) = opts.inline_js() {
|
||||
let i = program.inline_js.len();
|
||||
program.inline_js.push(js.to_string());
|
||||
ast::ImportModule::Inline(i, span)
|
||||
} else {
|
||||
ast::ImportModule::None
|
||||
};
|
||||
for item in self.items.into_iter() {
|
||||
if let Err(e) = item.macro_parse(program, module.clone()) {
|
||||
|
@ -28,6 +28,7 @@ macro_rules! shared_api {
|
||||
enum ImportModule<'a> {
|
||||
None,
|
||||
Named(&'a str),
|
||||
RawNamed(&'a str),
|
||||
Inline(u32),
|
||||
}
|
||||
|
||||
|
@ -1,11 +0,0 @@
|
||||
import * as wbg from './pkg/typescript_tests';
|
||||
import * as wasm from './pkg/typescript_tests_bg';
|
||||
|
||||
const a1: (a: string) => void = wbg.greet;
|
||||
const a2: (a: number, b: number) => void = wasm.greet;
|
||||
const a3: WebAssembly.Memory = wasm.memory;
|
||||
|
||||
const c = new wbg.A();
|
||||
wbg.A.other();
|
||||
c.foo();
|
||||
c.free();
|
11
crates/typescript-tests/src/custom_section.rs
Normal file
11
crates/typescript-tests/src/custom_section.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(typescript_custom_section)]
|
||||
const TS_INTERFACE_EXPORT: &'static str = r"
|
||||
interface Height { height: number; }
|
||||
";
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct Person {
|
||||
pub height: u32,
|
||||
}
|
3
crates/typescript-tests/src/custom_section.ts
Normal file
3
crates/typescript-tests/src/custom_section.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import * as wbg from '../pkg/typescript_tests';
|
||||
|
||||
const height: wbg.Height = new wbg.Person();
|
@ -1,20 +1,4 @@
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn greet(_: &str) {}
|
||||
|
||||
#[wasm_bindgen]
|
||||
struct A {
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl A {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new() -> A {
|
||||
A {}
|
||||
}
|
||||
|
||||
pub fn other() {}
|
||||
|
||||
pub fn foo(&self) {}
|
||||
}
|
||||
mod custom_section;
|
||||
mod opt_args_and_ret;
|
||||
mod simple_fn;
|
||||
mod simple_struct;
|
3
crates/typescript-tests/src/memory.ts
Normal file
3
crates/typescript-tests/src/memory.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import * as wasm from '../pkg/typescript_tests_bg';
|
||||
|
||||
const memory: WebAssembly.Memory = wasm.memory;
|
6
crates/typescript-tests/src/opt_args_and_ret.rs
Normal file
6
crates/typescript-tests/src/opt_args_and_ret.rs
Normal file
@ -0,0 +1,6 @@
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn opt_fn(_a: Option<i32>) -> Option<i32> {
|
||||
None
|
||||
}
|
3
crates/typescript-tests/src/opt_args_and_ret.ts
Normal file
3
crates/typescript-tests/src/opt_args_and_ret.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import * as wbg from '../pkg/typescript_tests';
|
||||
|
||||
const opt_fn: (a: number | undefined) => number | undefined = wbg.opt_fn;
|
4
crates/typescript-tests/src/simple_fn.rs
Normal file
4
crates/typescript-tests/src/simple_fn.rs
Normal file
@ -0,0 +1,4 @@
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn greet(_: &str) {}
|
5
crates/typescript-tests/src/simple_fn.ts
Normal file
5
crates/typescript-tests/src/simple_fn.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import * as wbg from '../pkg/typescript_tests';
|
||||
import * as wasm from '../pkg/typescript_tests_bg';
|
||||
|
||||
const wbg_greet: (a: string) => void = wbg.greet;
|
||||
const wasm_greet: (a: number, b: number) => void = wasm.greet;
|
17
crates/typescript-tests/src/simple_struct.rs
Normal file
17
crates/typescript-tests/src/simple_struct.rs
Normal file
@ -0,0 +1,17 @@
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct A {
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl A {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new() -> A {
|
||||
A {}
|
||||
}
|
||||
|
||||
pub fn other() {}
|
||||
|
||||
pub fn foo(&self) {}
|
||||
}
|
6
crates/typescript-tests/src/simple_struct.ts
Normal file
6
crates/typescript-tests/src/simple_struct.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import * as wbg from '../pkg/typescript_tests';
|
||||
|
||||
const a = new wbg.A();
|
||||
wbg.A.other();
|
||||
a.foo();
|
||||
a.free();
|
@ -9,6 +9,6 @@
|
||||
"baseUrl": "."
|
||||
},
|
||||
"include": [
|
||||
"index.ts"
|
||||
"src/*.ts"
|
||||
]
|
||||
}
|
||||
|
@ -814,6 +814,9 @@ RtcRtpSender = []
|
||||
RtcRtpSourceEntry = []
|
||||
RtcRtpSourceEntryType = []
|
||||
RtcRtpSynchronizationSource = []
|
||||
RtcRtpTransceiver = []
|
||||
RtcRtpTransceiverDirection = []
|
||||
RtcRtpTransceiverInit = []
|
||||
RtcRtxParameters = []
|
||||
RtcSdpType = []
|
||||
RtcSessionDescription = []
|
||||
@ -826,6 +829,7 @@ RtcStatsReport = []
|
||||
RtcStatsReportInternal = []
|
||||
RtcStatsType = []
|
||||
RtcTrackEvent = []
|
||||
RtcTrackEventInit = []
|
||||
RtcTransportStats = []
|
||||
RtcdtmfSender = []
|
||||
RtcdtmfToneChangeEvent = []
|
||||
|
@ -48,6 +48,7 @@ pub mod pre_element;
|
||||
pub mod progress_element;
|
||||
pub mod quote_element;
|
||||
pub mod response;
|
||||
pub mod rtc_rtp_transceiver_direction;
|
||||
pub mod script_element;
|
||||
pub mod select_element;
|
||||
pub mod slot_element;
|
||||
|
92
crates/web-sys/tests/wasm/rtc_rtp_transceiver_direction.rs
Normal file
92
crates/web-sys/tests/wasm/rtc_rtp_transceiver_direction.rs
Normal file
@ -0,0 +1,92 @@
|
||||
use wasm_bindgen::{prelude::*, JsCast};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
use futures::{
|
||||
future::{ok, IntoFuture},
|
||||
Future,
|
||||
};
|
||||
|
||||
use web_sys::{
|
||||
RtcPeerConnection, RtcRtpTransceiver, RtcRtpTransceiverDirection, RtcRtpTransceiverInit,
|
||||
RtcSessionDescriptionInit,
|
||||
};
|
||||
|
||||
#[wasm_bindgen(
|
||||
inline_js = "export function is_unified_avail() { return Object.keys(RTCRtpTransceiver.prototype).indexOf('currentDirection')>-1; }"
|
||||
)]
|
||||
extern "C" {
|
||||
/// Available in FF since forever, in Chrome since 72, in Safari since 12.1
|
||||
fn is_unified_avail() -> bool;
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test(async)]
|
||||
fn rtc_rtp_transceiver_direction() -> Box<dyn Future<Item = (), Error = JsValue>> {
|
||||
if !is_unified_avail() {
|
||||
return Box::new(Ok(()).into_future());
|
||||
}
|
||||
|
||||
let mut tr_init: RtcRtpTransceiverInit = RtcRtpTransceiverInit::new();
|
||||
|
||||
let pc1: RtcPeerConnection = RtcPeerConnection::new().unwrap();
|
||||
|
||||
let tr1: RtcRtpTransceiver = pc1.add_transceiver_with_str_and_init(
|
||||
"audio",
|
||||
tr_init.direction(RtcRtpTransceiverDirection::Sendonly),
|
||||
);
|
||||
assert_eq!(tr1.direction(), RtcRtpTransceiverDirection::Sendonly);
|
||||
assert_eq!(tr1.current_direction(), None);
|
||||
|
||||
let pc2: RtcPeerConnection = RtcPeerConnection::new().unwrap();
|
||||
|
||||
let r = exchange_sdps(pc1, pc2).and_then(move |(_, p2)| {
|
||||
assert_eq!(tr1.direction(), RtcRtpTransceiverDirection::Sendonly);
|
||||
assert_eq!(
|
||||
tr1.current_direction(),
|
||||
Some(RtcRtpTransceiverDirection::Sendonly)
|
||||
);
|
||||
|
||||
let tr2: RtcRtpTransceiver = js_sys::try_iter(&p2.get_transceivers())
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.next()
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.unchecked_into();
|
||||
|
||||
assert_eq!(tr2.direction(), RtcRtpTransceiverDirection::Recvonly);
|
||||
assert_eq!(
|
||||
tr2.current_direction(),
|
||||
Some(RtcRtpTransceiverDirection::Recvonly)
|
||||
);
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
Box::new(r)
|
||||
}
|
||||
|
||||
fn exchange_sdps(
|
||||
p1: RtcPeerConnection,
|
||||
p2: RtcPeerConnection,
|
||||
) -> impl Future<Item = (RtcPeerConnection, RtcPeerConnection), Error = JsValue> {
|
||||
JsFuture::from(p1.create_offer())
|
||||
.and_then(move |offer| {
|
||||
let offer = offer.unchecked_into::<RtcSessionDescriptionInit>();
|
||||
JsFuture::from(p1.set_local_description(&offer)).join4(
|
||||
JsFuture::from(p2.set_remote_description(&offer)),
|
||||
Ok(p1),
|
||||
Ok(p2),
|
||||
)
|
||||
})
|
||||
.and_then(|(_, _, p1, p2)| JsFuture::from(p2.create_answer()).join3(Ok(p1), Ok(p2)))
|
||||
.and_then(|(answer, p1, p2)| {
|
||||
let answer = answer.unchecked_into::<RtcSessionDescriptionInit>();
|
||||
JsFuture::from(p2.set_local_description(&answer)).join4(
|
||||
JsFuture::from(p1.set_remote_description(&answer)),
|
||||
Ok(p1),
|
||||
Ok(p2),
|
||||
)
|
||||
})
|
||||
.and_then(|(_, _, p1, p2)| Ok((p1, p2)))
|
||||
}
|
@ -18,4 +18,12 @@ global.Shape = class Shape {
|
||||
getShape() {
|
||||
return this.kind;
|
||||
}
|
||||
|
||||
get shapeTypeNone() {
|
||||
return null;
|
||||
}
|
||||
|
||||
get shapeTypeSome() {
|
||||
return this.kind;
|
||||
}
|
||||
};
|
||||
|
@ -35,3 +35,17 @@ fn invalid_enum_return() {
|
||||
_ => {} // Success
|
||||
};
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn read_optional_enum_attribute_none() {
|
||||
let shape = Shape::new(ShapeType::Circle).unwrap();
|
||||
let shape_type: Option<ShapeType> = shape.shape_type_none();
|
||||
assert_eq!(shape_type, None);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn read_optional_enum_attribute_some() {
|
||||
let shape = Shape::new(ShapeType::Circle).unwrap();
|
||||
let shape_type: Option<ShapeType> = shape.shape_type_some();
|
||||
assert_eq!(shape_type, Some(ShapeType::Circle));
|
||||
}
|
||||
|
4
crates/webidl-tests/enums.webidl
vendored
4
crates/webidl-tests/enums.webidl
vendored
@ -12,4 +12,8 @@ interface Shape {
|
||||
|
||||
[Pure]
|
||||
ShapeType getShape();
|
||||
|
||||
readonly attribute ShapeType? shapeTypeNone;
|
||||
|
||||
readonly attribute ShapeType? shapeTypeSome;
|
||||
};
|
||||
|
@ -66,6 +66,7 @@
|
||||
- [`js_namespace`](./reference/attributes/on-js-imports/js_namespace.md)
|
||||
- [`method`](./reference/attributes/on-js-imports/method.md)
|
||||
- [`module = "blah"`](./reference/attributes/on-js-imports/module.md)
|
||||
- [`raw_module = "blah"`](./reference/attributes/on-js-imports/raw_module.md)
|
||||
- [`static_method_of = Blah`](./reference/attributes/on-js-imports/static_method_of.md)
|
||||
- [`structural`](./reference/attributes/on-js-imports/structural.md)
|
||||
- [`variadic`](./reference/attributes/on-js-imports/variadic.md)
|
||||
|
@ -31,3 +31,8 @@ generates JavaScript import glue like:
|
||||
```js
|
||||
let illmatic = this.illmatic;
|
||||
```
|
||||
|
||||
Note that if the string specified with `module` starts with `./`, `../`, or `/`
|
||||
then it's interpreted as a path to a [local JS snippet](../../js-snippets.html).
|
||||
If this doesn't work for your use case you might be interested in the
|
||||
[`raw_module` attribute](raw_module.html)
|
||||
|
19
guide/src/reference/attributes/on-js-imports/raw_module.md
Normal file
19
guide/src/reference/attributes/on-js-imports/raw_module.md
Normal file
@ -0,0 +1,19 @@
|
||||
# `raw_module = "blah"`
|
||||
|
||||
This attribute performs exactly the same purpose as the [`module`
|
||||
attribute](module.html) on JS imports, but it does not attempt to interpret
|
||||
paths starting with `./`, `../`, or `/` as JS snippets. For example:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(raw_module = "./some/js/file.js")]
|
||||
extern "C" {
|
||||
fn the_function();
|
||||
}
|
||||
```
|
||||
|
||||
Note that if you use this attribute with a relative or absolute path, it's
|
||||
likely up to the final bundler or project to assign meaning to that path. This
|
||||
typically means that the JS file or module will be resolved relative to the
|
||||
final location of the wasm file itself. That means that `raw_module` is likely
|
||||
unsuitable for libraries on crates.io, but may be usable within end-user
|
||||
applications.
|
@ -4,7 +4,7 @@
|
||||
"serve": "webpack-dev-server -p"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@wasm-tool/wasm-pack-plugin": "0.2.5",
|
||||
"@wasm-tool/wasm-pack-plugin": "0.2.7",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"text-encoding": "^0.7.0",
|
||||
"webpack": "^4.29.4",
|
||||
|
Loading…
Reference in New Issue
Block a user