Skip to content

Commit 0b1a764

Browse files
authored
Guarantee static_method_of uses the right this (#1795)
This came up during #1760 where `Promise.resolve` must be invoked with `this` as the `Promise` object, but we were erroneously importing it in such a way that it didn't have a shim and `this` was `undefined`.
1 parent 025b1d8 commit 0b1a764

File tree

6 files changed

+32
-2
lines changed

6 files changed

+32
-2
lines changed

crates/cli-support/src/js/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -2269,6 +2269,11 @@ impl<'a> Context<'a> {
22692269
}
22702270
},
22712271

2272+
AuxImport::ValueWithThis(class, name) => {
2273+
let class = self.import_name(class)?;
2274+
Ok(format!("{}.{}({})", class, name, variadic_args(&args)?))
2275+
}
2276+
22722277
AuxImport::Instanceof(js) => {
22732278
assert!(webidl_ty.kind == ast::WebidlFunctionKind::Static);
22742279
assert!(!variadic);

crates/cli-support/src/webidl/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,10 @@ pub enum AuxImport {
278278
/// imported
279279
Value(AuxValue),
280280

281+
/// A static method on a class is being imported, and the `this` of the
282+
/// function call is expected to always be the class.
283+
ValueWithThis(JsImport, String),
284+
281285
/// This import is expected to be a function that takes an `anyref` and
282286
/// returns a `bool`. It's expected that it tests if the argument is an
283287
/// instance of (using `instanceof`) the name specified.
@@ -950,8 +954,7 @@ impl<'a> Context<'a> {
950954
match op.kind {
951955
decode::OperationKind::Regular => {
952956
if op.is_static {
953-
class.fields.push(function.name.to_string());
954-
Ok((AuxImport::Value(AuxValue::Bare(class)), false))
957+
Ok((AuxImport::ValueWithThis(class, function.name.to_string()), false))
955958
} else if structural {
956959
Ok((
957960
AuxImport::StructuralMethod(function.name.to_string()),

crates/cli-support/src/webidl/standard.rs

+3
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,9 @@ fn check_standard_import(import: &AuxImport) -> Result<(), Error> {
574574
| AuxImport::Value(AuxValue::ClassSetter(js, name)) => {
575575
format!("field access of `{}` for {}", name, desc_js(js))
576576
}
577+
AuxImport::ValueWithThis(js, method) => {
578+
format!("method `{}.{}`", desc_js(js), method)
579+
}
577580
AuxImport::Instanceof(js) => format!("instance of check of {}", desc_js(js)),
578581
AuxImport::Static(js) => format!("static js value {}", desc_js(js)),
579582
AuxImport::StructuralMethod(name) => format!("structural method `{}`", name),

guide/src/reference/attributes/on-js-imports/static_method_of.md

+3
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,6 @@ let instant = Date::now();
2323

2424
This is similar to the `js_namespace` attribute, but the usage from within Rust
2525
is different since the method also becomes a static method of the imported type.
26+
Additionally this attribute also specifies that the `this` parameter when
27+
invoking the method is expected to be the JS class, e.g. always invoked as
28+
`Date.now()` instead of `const x = Date.now; x()`.

tests/wasm/imports.js

+8
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,11 @@ exports.import_inside_private_module = function() {};
107107
exports.should_call_undefined_functions = () => false;
108108

109109
exports.STATIC_STRING = 'x';
110+
111+
class StaticMethodCheck {
112+
static static_method_of_right_this() {
113+
assert.ok(this === StaticMethodCheck);
114+
}
115+
}
116+
117+
exports.StaticMethodCheck = StaticMethodCheck;

tests/wasm/imports.rs

+8
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ extern "C" {
5252
fn assert_dead_import_not_generated();
5353
fn should_call_undefined_functions() -> bool;
5454

55+
type StaticMethodCheck;
56+
#[wasm_bindgen(static_method_of = StaticMethodCheck)]
57+
fn static_method_of_right_this();
5558

5659
static STATIC_STRING: String;
5760
}
@@ -240,3 +243,8 @@ fn undefined_function_is_ok() {
240243
fn static_string_ok() {
241244
assert_eq!(*STATIC_STRING, "x");
242245
}
246+
247+
#[wasm_bindgen_test]
248+
fn static_method_of_has_right_this() {
249+
StaticMethodCheck::static_method_of_right_this();
250+
}

0 commit comments

Comments
 (0)