From 34858e15e0f44511e7050c5ba4f1499ab6814b28 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Mon, 29 Jul 2024 18:58:30 +0200 Subject: [PATCH] Allow ex/importing more raw identifier names (#4025) --- CHANGELOG.md | 3 + crates/backend/src/encode.rs | 3 +- crates/cli/tests/reference/raw.d.ts | 21 +++++ crates/cli/tests/reference/raw.js | 120 ++++++++++++++++++++++++++++ crates/cli/tests/reference/raw.rs | 24 ++++++ crates/cli/tests/reference/raw.wat | 14 ++++ crates/macro-support/src/lib.rs | 6 +- crates/macro-support/src/parser.rs | 6 +- 8 files changed, 192 insertions(+), 5 deletions(-) create mode 100644 crates/cli/tests/reference/raw.d.ts create mode 100644 crates/cli/tests/reference/raw.js create mode 100644 crates/cli/tests/reference/raw.rs create mode 100644 crates/cli/tests/reference/raw.wat diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e3864eca31..647f6383254 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -139,6 +139,9 @@ * Fix byte order for big-endian platforms. [#4015](https://github.com/rustwasm/wasm-bindgen/pull/4015) +* Allow ex/importing structs, functions and parameters named with raw identifiers. + [#4025](https://github.com/rustwasm/wasm-bindgen/pull/4025) + -------------------------------------------------------------------------------- ## [0.2.92](https://github.com/rustwasm/wasm-bindgen/compare/0.2.91...0.2.92) diff --git a/crates/backend/src/encode.rs b/crates/backend/src/encode.rs index 4bf9047300c..b571d046dfe 100644 --- a/crates/backend/src/encode.rs +++ b/crates/backend/src/encode.rs @@ -5,6 +5,7 @@ use std::collections::HashMap; use std::env; use std::fs; use std::path::PathBuf; +use syn::ext::IdentExt; use crate::ast; use crate::Diagnostic; @@ -212,7 +213,7 @@ fn shared_function<'a>(func: &'a ast::Function, _intern: &'a Interner) -> Functi .enumerate() .map(|(idx, arg)| { if let syn::Pat::Ident(x) = &*arg.pat { - return x.ident.to_string(); + return x.ident.unraw().to_string(); } format!("arg{}", idx) }) diff --git a/crates/cli/tests/reference/raw.d.ts b/crates/cli/tests/reference/raw.d.ts new file mode 100644 index 00000000000..944af97ab04 --- /dev/null +++ b/crates/cli/tests/reference/raw.d.ts @@ -0,0 +1,21 @@ +/* tslint:disable */ +/* eslint-disable */ +/** +* @param {number} test +* @returns {number} +*/ +export function test1(test: number): number; +/** +*/ +export class Test { + free(): void; +/** +* @param {number} test +* @returns {Test} +*/ + static test1(test: number): Test; +/** +* @param {number} test +*/ + test2(test: number): void; +} diff --git a/crates/cli/tests/reference/raw.js b/crates/cli/tests/reference/raw.js new file mode 100644 index 00000000000..3432d150366 --- /dev/null +++ b/crates/cli/tests/reference/raw.js @@ -0,0 +1,120 @@ +import { test2 } from 'test'; + +let wasm; +export function __wbg_set_wasm(val) { + wasm = val; +} + + +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +let cachedUint8ArrayMemory0 = null; + +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + +const heap = new Array(128).fill(undefined); + +heap.push(undefined, null, true, false); + +function getObject(idx) { return heap[idx]; } + +let heap_next = heap.length; + +function dropObject(idx) { + if (idx < 132) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} +/** +* @param {number} test +* @returns {number} +*/ +export function test1(test) { + const ret = wasm.test1(test); + return ret >>> 0; +} + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} + +const TestFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_test_free(ptr >>> 0, 1)); +/** +*/ +export class Test { + + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(Test.prototype); + obj.__wbg_ptr = ptr; + TestFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + TestFinalization.unregister(this); + return ptr; + } + + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_test_free(ptr, 0); + } + /** + * @param {number} test + * @returns {Test} + */ + static test1(test) { + const ret = wasm.test_test1(test); + return Test.__wrap(ret); + } + /** + * @param {number} test + */ + test2(test) { + wasm.test_test2(this.__wbg_ptr, test); + } +} + +export function __wbg_test2_39fe629b9aa739cf() { + const ret = test2(); + return addHeapObject(ret); +}; + +export function __wbindgen_throw(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); +}; + +export function __wbindgen_object_drop_ref(arg0) { + takeObject(arg0); +}; + diff --git a/crates/cli/tests/reference/raw.rs b/crates/cli/tests/reference/raw.rs new file mode 100644 index 00000000000..7c49eba5b04 --- /dev/null +++ b/crates/cli/tests/reference/raw.rs @@ -0,0 +1,24 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn r#test1(r#test: u32) -> u32 { + r#test2(); + r#test +} + +#[wasm_bindgen] +pub struct r#Test; + +#[wasm_bindgen] +impl r#Test { + pub fn r#test1(r#test: u32) -> Self { + Self + } + + pub fn r#test2(&self, r#test: u32) {} +} + +#[wasm_bindgen(module = "test")] +extern "C" { + fn r#test2() -> JsValue; +} diff --git a/crates/cli/tests/reference/raw.wat b/crates/cli/tests/reference/raw.wat new file mode 100644 index 00000000000..0b4ec6cc732 --- /dev/null +++ b/crates/cli/tests/reference/raw.wat @@ -0,0 +1,14 @@ +(module $reference_test.wasm + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32 i32))) + (func $test_test2 (;0;) (type 1) (param i32 i32)) + (func $test1 (;1;) (type 0) (param i32) (result i32)) + (func $test_test1 (;2;) (type 0) (param i32) (result i32)) + (func $__wbg_test_free (;3;) (type 1) (param i32 i32)) + (memory (;0;) 17) + (export "memory" (memory 0)) + (export "test1" (func $test1)) + (export "__wbg_test_free" (func $__wbg_test_free)) + (export "test_test1" (func $test_test1)) + (export "test_test2" (func $test_test2)) +) diff --git a/crates/macro-support/src/lib.rs b/crates/macro-support/src/lib.rs index 21d66305c38..dd609f42260 100644 --- a/crates/macro-support/src/lib.rs +++ b/crates/macro-support/src/lib.rs @@ -115,7 +115,11 @@ impl Parse for ClassMarker { fn parse(input: ParseStream) -> SynResult { let class = input.parse::()?; input.parse::()?; - let js_class = input.parse::()?.value(); + let mut js_class = input.parse::()?.value(); + js_class = js_class + .strip_prefix("r#") + .map(String::from) + .unwrap_or(js_class); let mut wasm_bindgen = None; let mut wasm_bindgen_futures = None; diff --git a/crates/macro-support/src/parser.rs b/crates/macro-support/src/parser.rs index dd581b2700d..376c15b1133 100644 --- a/crates/macro-support/src/parser.rs +++ b/crates/macro-support/src/parser.rs @@ -417,7 +417,7 @@ impl<'a> ConvertToAst<(&ast::Program, BindgenAttrs)> for &'a mut syn::ItemStruct let js_name = attrs .js_name() .map(|s| s.0.to_string()) - .unwrap_or(self.ident.to_string()); + .unwrap_or(self.ident.unraw().to_string()); let is_inspectable = attrs.inspectable().is_some(); let getter_with_clone = attrs.getter_with_clone(); for (i, field) in self.fields.iter_mut().enumerate() { @@ -921,9 +921,9 @@ fn function_from_decl( && opts.method().is_none() && is_js_keyword(&decl_name.to_string(), skip_keywords) { - format!("_{}", decl_name) + format!("_{}", decl_name.unraw()) } else { - decl_name.to_string() + decl_name.unraw().to_string() }; (name, decl_name.span(), false) };