diff --git a/crates/backend/src/ast.rs b/crates/backend/src/ast.rs index 57869a89..634e6e4e 100644 --- a/crates/backend/src/ast.rs +++ b/crates/backend/src/ast.rs @@ -346,7 +346,9 @@ impl ImportFunction { /// for a setter in javascript (in this case `xxx`, so you can write `obj.xxx = val`) fn infer_setter_property(&self) -> String { let name = self.function.name.to_string(); - assert!(name.starts_with("set_"), "setters must start with `set_`"); + if !name.starts_with("set_") { + panic!("error: setters must start with `set_`, found: {}", name); + } name[4..].to_string() } diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 7734a987..bf3c9704 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -250,6 +250,40 @@ extern "C" { #[wasm_bindgen(method)] pub fn map(this: &Array, predicate: &mut FnMut(JsValue, u32, Array) -> JsValue) -> Array; + /// The `Array.of()` method creates a new Array instance with a variable + /// number of arguments, regardless of number or type of the arguments. + /// + /// The difference between `Array.of()` and the `Array` constructor is in the + /// handling of integer arguments: `Array.of(7)` creates an array with a single + /// element, `7`, whereas `Array(7)` creates an empty array with a `length` + /// property of `7` (Note: this implies an array of 7 empty slots, not slots + /// with actual undefined values). + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of + /// + /// # Notes + /// + /// There are a few bindings to `of` in `js-sys`: `of1`, `of2`, etc... + /// with different arities. + #[wasm_bindgen(static_method_of = Array, js_name = of)] + pub fn of1(a: &JsValue) -> Array; + + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of + #[wasm_bindgen(static_method_of = Array, js_name = of)] + pub fn of2(a: &JsValue, b: &JsValue) -> Array; + + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of + #[wasm_bindgen(static_method_of = Array, js_name = of)] + pub fn of3(a: &JsValue, b: &JsValue, c: &JsValue) -> Array; + + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of + #[wasm_bindgen(static_method_of = Array, js_name = of)] + pub fn of4(a: &JsValue, b: &JsValue, c: &JsValue, d: &JsValue) -> Array; + + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of + #[wasm_bindgen(static_method_of = Array, js_name = of)] + pub fn of5(a: &JsValue, b: &JsValue, c: &JsValue, d: &JsValue, e: &JsValue) -> Array; + /// The pop() method removes the last element from an array and returns that /// element. This method changes the length of the array. /// @@ -646,7 +680,6 @@ extern "C" { pub fn new(message: &str) -> EvalError; } - // Float32Array #[wasm_bindgen] extern "C" { @@ -1857,6 +1890,37 @@ extern "C" { #[derive(Clone, Debug)] pub type Object; + /// The Object.assign() method is used to copy the values of all enumerable + /// own properties from one or more source objects to a target object. It + /// will return the target object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + #[wasm_bindgen(static_method_of = Object)] + pub fn assign(target: &Object, source: &Object) -> Object; + + /// The Object.assign() method is used to copy the values of all enumerable + /// own properties from one or more source objects to a target object. It + /// will return the target object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + #[wasm_bindgen(static_method_of = Object, js_name = assign)] + pub fn assign2(target: &Object, source1: &Object, source2: &Object) -> Object; + + /// The Object.assign() method is used to copy the values of all enumerable + /// own properties from one or more source objects to a target object. It + /// will return the target object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + #[wasm_bindgen(static_method_of = Object, js_name = assign)] + pub fn assign3(target: &Object, source1: &Object, source2: &Object, source3: &Object) -> Object; + + /// The Object.create() method creates a new object, using an existing + /// object to provide the newly created object's prototype. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create + #[wasm_bindgen(static_method_of = Object)] + pub fn create(prototype: &Object) -> Object; + /// The `Object.freeze()` method freezes an object: that is, prevents new /// properties from being added to it; prevents existing properties from /// being removed; and prevents existing properties, or their enumerability, @@ -2020,6 +2084,44 @@ extern { pub fn revocable(target: &JsValue, handler: &Object) -> Object; } +// RangeError +#[wasm_bindgen] +extern { + /// The RangeError object indicates an error when a value is not in the set + /// or range of allowed values. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError + #[wasm_bindgen(extends = Error)] + #[derive(Clone, Debug)] + pub type RangeError; + + /// The RangeError object indicates an error when a value is not in the set + /// or range of allowed values. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError + #[wasm_bindgen(constructor)] + pub fn new(message: &str) -> RangeError; +} + +// ReferenceError +#[wasm_bindgen] +extern { + /// The ReferenceError object represents an error when a non-existent + /// variable is referenced. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError + #[wasm_bindgen(extends = Error)] + #[derive(Clone, Debug)] + pub type ReferenceError; + + /// The ReferenceError object represents an error when a non-existent + /// variable is referenced. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError + #[wasm_bindgen(constructor)] + pub fn new(message: &str) -> ReferenceError; +} + // Reflect #[wasm_bindgen] extern "C" { @@ -2178,6 +2280,20 @@ extern { #[wasm_bindgen(static_method_of = RegExp, getter)] pub fn input() -> JsString; + /// The lastIndex is a read/write integer property of regular expression + /// instances that specifies the index at which to start the next match. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex + #[wasm_bindgen(structural, getter = lastIndex, method)] + pub fn last_index(this: &RegExp) -> u32; + + /// The lastIndex is a read/write integer property of regular expression + /// instances that specifies the index at which to start the next match. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex + #[wasm_bindgen(structural, setter = lastIndex, method)] + pub fn set_last_index(this: &RegExp, index: u32); + /// The non-standard lastMatch property is a static and read-only /// property of regular expressions that contains the last matched /// characters. RegExp.$& is an alias for this property. @@ -2380,6 +2496,46 @@ extern { pub fn values(set: &Set) -> Iterator; } +// SyntaxError +#[wasm_bindgen] +extern { + /// A SyntaxError is thrown when the JavaScript engine encounters tokens or + /// token order that does not conform to the syntax of the language when + /// parsing code. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError + #[wasm_bindgen(extends = Error)] + #[derive(Clone, Debug)] + pub type SyntaxError; + + /// A SyntaxError is thrown when the JavaScript engine encounters tokens or + /// token order that does not conform to the syntax of the language when + /// parsing code. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError + #[wasm_bindgen(constructor)] + pub fn new(message: &str) -> SyntaxError; +} + +// TypeError +#[wasm_bindgen] +extern { + /// The TypeError object represents an error when a value is not of the + /// expected type. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError + #[wasm_bindgen(extends = Error)] + #[derive(Clone, Debug)] + pub type TypeError; + + /// The TypeError object represents an error when a value is not of the + /// expected type. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError + #[wasm_bindgen(constructor)] + pub fn new(message: &str) -> TypeError; +} + // Uint8Array #[wasm_bindgen] extern "C" { @@ -2590,6 +2746,25 @@ extern "C" { pub fn byte_offset(this: &Uint32Array) -> u32; } +// URIError +#[wasm_bindgen] +extern { + /// The URIError object represents an error when a global URI handling + /// function was used in a wrong way. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/URIError + #[wasm_bindgen(extends = Error, js_name = URIError)] + #[derive(Clone, Debug)] + pub type UriError; + + /// The URIError object represents an error when a global URI handling + /// function was used in a wrong way. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/URIError + #[wasm_bindgen(constructor, js_class = "URIError")] + pub fn new(message: &str) -> UriError; +} + // WeakMap #[wasm_bindgen] extern "C" { @@ -3112,6 +3287,14 @@ extern "C" { #[wasm_bindgen(method, js_name = toString)] pub fn to_string(this: &Symbol) -> JsString; + /// The Symbol.unscopables well-known symbol is used to specify an object + /// value of whose own and inherited property names are excluded from the + /// with environment bindings of the associated object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/unscopables + #[wasm_bindgen(static_method_of = Symbol, getter, structural)] + pub fn unscopables() -> Symbol; + /// The valueOf() method returns the primitive value of a Symbol object. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/valueOf @@ -3119,19 +3302,65 @@ extern "C" { pub fn value_of(this: &Symbol) -> Symbol; } -// Intl -#[wasm_bindgen] -extern "C" { - #[derive(Clone, Debug)] - pub type Intl; +#[allow(non_snake_case)] +pub mod Intl { + use super::*; - /// The `Intl.getCanonicalLocales()` method returns an array containing - /// the canonical locale names. Duplicates will be omitted and elements - /// will be validated as structurally valid language tags. - /// - /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/getCanonicalLocales - #[wasm_bindgen(static_method_of = Intl, js_name = getCanonicalLocales)] - pub fn get_canonical_locales(s: &JsValue) -> Array; + // Intl + #[wasm_bindgen] + extern "C" { + /// The `Intl.getCanonicalLocales()` method returns an array containing + /// the canonical locale names. Duplicates will be omitted and elements + /// will be validated as structurally valid language tags. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/getCanonicalLocales + #[wasm_bindgen(js_name = getCanonicalLocales, js_namespace = Intl)] + pub fn get_canonical_locales(s: &JsValue) -> Array; + } + + // Intl.Collator + #[wasm_bindgen] + extern "C" { + /// The Intl.Collator object is a constructor for collators, objects + /// that enable language sensitive string comparison. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator + #[wasm_bindgen(js_namespace = Intl)] + #[derive(Clone, Debug)] + pub type Collator; + + /// The Intl.Collator object is a constructor for collators, objects + /// that enable language sensitive string comparison. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator + #[wasm_bindgen(constructor, js_namespace = Intl)] + pub fn new(locales: &Array, options: &Object) -> Collator; + + /// The Intl.Collator.prototype.compare property returns a function that + /// compares two strings according to the sort order of this Collator + /// object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator/compare + #[wasm_bindgen(method, getter, js_class = "Intl.Collator")] + pub fn compare(this: &Collator) -> Function; + + /// The Intl.Collator.prototype.resolvedOptions() method returns a new + /// object with properties reflecting the locale and collation options + /// computed during initialization of this Collator object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator/resolvedOptions + #[wasm_bindgen(method, js_namespace = Intl, js_name = resolvedOptions)] + pub fn resolved_options(this: &Collator) -> Object; + + /// The Intl.Collator.supportedLocalesOf() method returns an array + /// containing those of the provided locales that are supported in + /// collation without having to fall back to the runtime's default + /// locale. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator/supportedLocalesOf + #[wasm_bindgen(static_method_of = Collator, js_namespace = Intl, js_name = supportedLocalesOf)] + pub fn supported_locales_of(locales: &Array, options: &Object) -> Array; + } } // Promise diff --git a/crates/js-sys/tests/wasm/Array.rs b/crates/js-sys/tests/wasm/Array.rs index 15c2d463..604bbf85 100644 --- a/crates/js-sys/tests/wasm/Array.rs +++ b/crates/js-sys/tests/wasm/Array.rs @@ -126,6 +126,19 @@ fn copy_within() { assert_eq!(to_rust(&characters)[5], JsValue::from(3)); } +#[wasm_bindgen_test] +fn of() { + let a = JsValue::from("a"); + let b = JsValue::from("b"); + let c = JsValue::from("c"); + let arr = Array::of3(&a, &b, &c); + let vec = to_rust(&arr); + assert_eq!(vec.len(), 3); + assert_eq!(vec[0], a); + assert_eq!(vec[1], b); + assert_eq!(vec[2], c); +} + #[wasm_bindgen_test] fn pop() { let characters = js_array![8, 5, 4, 3, 1, 2]; diff --git a/crates/js-sys/tests/wasm/Intl.rs b/crates/js-sys/tests/wasm/Intl.rs index a739656b..e037fdfd 100644 --- a/crates/js-sys/tests/wasm/Intl.rs +++ b/crates/js-sys/tests/wasm/Intl.rs @@ -1,4 +1,4 @@ -use wasm_bindgen::JsValue; +use wasm_bindgen::{JsCast, JsValue}; use wasm_bindgen_test::*; use js_sys::*; @@ -23,3 +23,16 @@ fn get_canonical_locales() { assert_eq!(l, "en-US"); }); } + +#[wasm_bindgen_test] +fn collator() { + let locales = Array::of1(&JsValue::from("en-US")); + let opts = Object::new(); + + let c = Intl::Collator::new(&locales, &opts); + assert!(c.compare().is_instance_of::()); + assert!(c.resolved_options().is_instance_of::()); + + let a = Intl::Collator::supported_locales_of(&locales, &opts); + assert!(a.is_instance_of::()); +} diff --git a/crates/js-sys/tests/wasm/Object.rs b/crates/js-sys/tests/wasm/Object.rs index da245a97..97cc7b6a 100644 --- a/crates/js-sys/tests/wasm/Object.rs +++ b/crates/js-sys/tests/wasm/Object.rs @@ -1,17 +1,18 @@ -use wasm_bindgen::prelude::*; -use wasm_bindgen_test::*; -use std::f64::NAN; use js_sys::*; +use std::f64::NAN; +use wasm_bindgen::prelude::*; +use wasm_bindgen::JsCast; +use wasm_bindgen_test::*; #[wasm_bindgen] -extern { +extern "C" { type Foo42; #[wasm_bindgen(method, setter, structural)] fn set_foo(this: &Foo42, val: JsValue); } #[wasm_bindgen(module = "tests/wasm/Object.js")] -extern { +extern "C" { fn map_with_symbol_key() -> Object; fn symbol_key() -> JsValue; @@ -36,6 +37,42 @@ fn new() { assert!(JsValue::from(Object::new()).is_object()); } +#[wasm_bindgen_test] +fn assign() { + let a = JsValue::from("a"); + let b = JsValue::from("b"); + let c = JsValue::from("c"); + + let target = Object::new(); + Reflect::set(target.as_ref(), a.as_ref(), a.as_ref()); + + let src1 = Object::new(); + Reflect::set(src1.as_ref(), &a, &c); + + let src2 = Object::new(); + Reflect::set(src2.as_ref(), &b, &b); + + let src3 = Object::new(); + Reflect::set(src3.as_ref(), &c, &c); + + let res = Object::assign3(&target, &src1, &src2, &src3); + + assert!(Object::is(target.as_ref(), res.as_ref())); + assert_eq!(Reflect::get(target.as_ref(), &a), c); + assert_eq!(Reflect::get(target.as_ref(), &b), b); + assert_eq!(Reflect::get(target.as_ref(), &c), c); +} + +#[wasm_bindgen_test] +fn create() { + let array_proto = eval("Array.prototype") + .unwrap() + .dyn_into::() + .unwrap(); + let my_array = Object::create(&array_proto); + assert!(my_array.is_instance_of::()); +} + #[wasm_bindgen_test] fn has_own_property() { assert!(foo_42().has_own_property(&"foo".into())); diff --git a/crates/js-sys/tests/wasm/RangeError.rs b/crates/js-sys/tests/wasm/RangeError.rs new file mode 100644 index 00000000..c3470d26 --- /dev/null +++ b/crates/js-sys/tests/wasm/RangeError.rs @@ -0,0 +1,14 @@ +use wasm_bindgen::JsValue; +use wasm_bindgen_test::*; +use wasm_bindgen::JsCast; +use js_sys::*; + +#[wasm_bindgen_test] +fn range_error() { + let error = RangeError::new("out of range yo"); + assert!(error.is_instance_of::()); + assert!(error.is_instance_of::()); + + let base: &Error = error.as_ref(); + assert_eq!(JsValue::from(base.message()), "out of range yo"); +} diff --git a/crates/js-sys/tests/wasm/ReferenceError.rs b/crates/js-sys/tests/wasm/ReferenceError.rs new file mode 100644 index 00000000..22e2518c --- /dev/null +++ b/crates/js-sys/tests/wasm/ReferenceError.rs @@ -0,0 +1,14 @@ +use wasm_bindgen::JsValue; +use wasm_bindgen_test::*; +use wasm_bindgen::JsCast; +use js_sys::*; + +#[wasm_bindgen_test] +fn reference_error() { + let error = ReferenceError::new("bad reference, fool"); + assert!(error.is_instance_of::()); + assert!(error.is_instance_of::()); + + let base: &Error = error.as_ref(); + assert_eq!(JsValue::from(base.message()), "bad reference, fool"); +} diff --git a/crates/js-sys/tests/wasm/RegExp.rs b/crates/js-sys/tests/wasm/RegExp.rs index edaf5c92..a77d4892 100644 --- a/crates/js-sys/tests/wasm/RegExp.rs +++ b/crates/js-sys/tests/wasm/RegExp.rs @@ -56,6 +56,15 @@ fn input() { assert_eq!(RegExp::input(), "hi there!"); } +#[wasm_bindgen_test] +fn last_index() { + let re = RegExp::new("hi", "g"); + assert_eq!(re.last_index(), 0); + + re.set_last_index(42); + assert_eq!(re.last_index(), 42); +} + #[wasm_bindgen_test] fn last_match() { let re = RegExp::new("hi", "g"); diff --git a/crates/js-sys/tests/wasm/Symbol.rs b/crates/js-sys/tests/wasm/Symbol.rs index fbaacf2a..876e1d88 100644 --- a/crates/js-sys/tests/wasm/Symbol.rs +++ b/crates/js-sys/tests/wasm/Symbol.rs @@ -1,6 +1,5 @@ use wasm_bindgen::prelude::*; use wasm_bindgen_test::*; -use wasm_bindgen::JsCast; use js_sys::*; #[wasm_bindgen(module = "tests/wasm/Symbol.js")] @@ -100,6 +99,11 @@ fn to_string() { assert_eq!(gensym("desc".into()).to_string(), "Symbol(desc)"); } +#[wasm_bindgen_test] +fn unscopables() { + assert_eq!(Symbol::unscopables().to_string(), "Symbol(Symbol.unscopables)"); +} + #[wasm_bindgen_test] fn value_of() { let a = Symbol::for_("foo"); diff --git a/crates/js-sys/tests/wasm/SyntaxError.rs b/crates/js-sys/tests/wasm/SyntaxError.rs new file mode 100644 index 00000000..57d86371 --- /dev/null +++ b/crates/js-sys/tests/wasm/SyntaxError.rs @@ -0,0 +1,14 @@ +use wasm_bindgen::JsValue; +use wasm_bindgen_test::*; +use wasm_bindgen::JsCast; +use js_sys::*; + +#[wasm_bindgen_test] +fn syntax_error() { + let error = SyntaxError::new("msg"); + assert!(error.is_instance_of::()); + assert!(error.is_instance_of::()); + + let base: &Error = error.as_ref(); + assert_eq!(JsValue::from(base.message()), "msg"); +} diff --git a/crates/js-sys/tests/wasm/TypeError.rs b/crates/js-sys/tests/wasm/TypeError.rs new file mode 100644 index 00000000..e82cf091 --- /dev/null +++ b/crates/js-sys/tests/wasm/TypeError.rs @@ -0,0 +1,14 @@ +use wasm_bindgen::JsValue; +use wasm_bindgen_test::*; +use wasm_bindgen::JsCast; +use js_sys::*; + +#[wasm_bindgen_test] +fn type_error() { + let error = TypeError::new("msg"); + assert!(error.is_instance_of::()); + assert!(error.is_instance_of::()); + + let base: &Error = error.as_ref(); + assert_eq!(JsValue::from(base.message()), "msg"); +} diff --git a/crates/js-sys/tests/wasm/UriError.rs b/crates/js-sys/tests/wasm/UriError.rs new file mode 100644 index 00000000..86ff417e --- /dev/null +++ b/crates/js-sys/tests/wasm/UriError.rs @@ -0,0 +1,14 @@ +use wasm_bindgen::JsValue; +use wasm_bindgen_test::*; +use wasm_bindgen::JsCast; +use js_sys::*; + +#[wasm_bindgen_test] +fn uri_error() { + let error = UriError::new("msg"); + assert!(error.is_instance_of::()); + assert!(error.is_instance_of::()); + + let base: &Error = error.as_ref(); + assert_eq!(JsValue::from(base.message()), "msg"); +} diff --git a/crates/js-sys/tests/wasm/main.rs b/crates/js-sys/tests/wasm/main.rs index b37e5c57..36271531 100755 --- a/crates/js-sys/tests/wasm/main.rs +++ b/crates/js-sys/tests/wasm/main.rs @@ -26,12 +26,17 @@ pub mod Math; pub mod Number; pub mod Object; pub mod Proxy; +pub mod RangeError; +pub mod ReferenceError; pub mod Reflect; pub mod RegExp; pub mod Set; pub mod SetIterator; pub mod Symbol; +pub mod SyntaxError; +pub mod TypeError; pub mod TypedArray; +pub mod UriError; pub mod WeakMap; pub mod WeakSet; pub mod WebAssembly; diff --git a/crates/macro-support/src/parser.rs b/crates/macro-support/src/parser.rs index 5cc1f0c6..ae7815d5 100644 --- a/crates/macro-support/src/parser.rs +++ b/crates/macro-support/src/parser.rs @@ -166,7 +166,7 @@ impl BindgenAttrs { }).next() } - /// Get the first js_name attribute + /// Get the first js_class attribute fn js_class(&self) -> Option<&str> { self.attrs .iter() @@ -495,6 +495,10 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option)> for syn::ForeignItemFn _ => bail_span!(self, "return value of constructor must be a bare path"), }; let class_name = extract_path_ident(class_name)?; + let class_name = opts + .js_class() + .map(Into::into) + .unwrap_or_else(|| class_name.to_string()); ast::ImportFunctionKind::Method { class: class_name.to_string(),