Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Better TS type formatting for array types
Browse files Browse the repository at this point in the history
RunDevelopment committed Dec 9, 2024
1 parent 83a2ff4 commit 0c86bfb
Showing 5 changed files with 63 additions and 55 deletions.
8 changes: 7 additions & 1 deletion crates/cli-support/src/descriptor.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::char;

use crate::js::identifier::is_valid_ident;

macro_rules! tys {
($($a:ident)*) => (tys! { @ ($($a)*) 0 });
(@ () $v:expr) => {};
@@ -306,7 +308,11 @@ impl VectorKind {
VectorKind::F64 => "Float64Array".to_string(),
VectorKind::Externref => "any[]".to_string(),
VectorKind::NamedExternref(ref name) => {
format!("({})[]", name)
if is_valid_ident(name.as_str()) {
format!("{}[]", name)
} else {
format!("({})[]", name)
}
}
}
}
42 changes: 42 additions & 0 deletions crates/cli-support/src/js/identifier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/// Returns whether a character has the Unicode `ID_Start` properly.
///
/// This is only ever-so-slightly different from `XID_Start` in a few edge
/// cases, so we handle those edge cases manually and delegate everything else
/// to `unicode-ident`.
fn is_id_start(c: char) -> bool {
match c {
'\u{037A}' | '\u{0E33}' | '\u{0EB3}' | '\u{309B}' | '\u{309C}' | '\u{FC5E}'
| '\u{FC5F}' | '\u{FC60}' | '\u{FC61}' | '\u{FC62}' | '\u{FC63}' | '\u{FDFA}'
| '\u{FDFB}' | '\u{FE70}' | '\u{FE72}' | '\u{FE74}' | '\u{FE76}' | '\u{FE78}'
| '\u{FE7A}' | '\u{FE7C}' | '\u{FE7E}' | '\u{FF9E}' | '\u{FF9F}' => true,
_ => unicode_ident::is_xid_start(c),
}
}

/// Returns whether a character has the Unicode `ID_Continue` properly.
///
/// This is only ever-so-slightly different from `XID_Continue` in a few edge
/// cases, so we handle those edge cases manually and delegate everything else
/// to `unicode-ident`.
fn is_id_continue(c: char) -> bool {
match c {
'\u{037A}' | '\u{309B}' | '\u{309C}' | '\u{FC5E}' | '\u{FC5F}' | '\u{FC60}'
| '\u{FC61}' | '\u{FC62}' | '\u{FC63}' | '\u{FDFA}' | '\u{FDFB}' | '\u{FE70}'
| '\u{FE72}' | '\u{FE74}' | '\u{FE76}' | '\u{FE78}' | '\u{FE7A}' | '\u{FE7C}'
| '\u{FE7E}' => true,
_ => unicode_ident::is_xid_continue(c),
}
}

/// Returns whether a string is a valid JavaScript identifier.
/// Defined at https://tc39.es/ecma262/#prod-IdentifierName.
pub fn is_valid_ident(name: &str) -> bool {
!name.is_empty()
&& name.chars().enumerate().all(|(i, char)| {
if i == 0 {
is_id_start(char) || char == '$' || char == '_'
} else {
is_id_continue(char) || char == '$' || char == '\u{200C}' || char == '\u{200D}'
}
})
}
44 changes: 2 additions & 42 deletions crates/cli-support/src/js/mod.rs
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ use crate::wit::{JsImport, JsImportName, NonstandardWitSection, WasmBindgenAux};
use crate::{reset_indentation, Bindgen, EncodeInto, OutputMode, PLACEHOLDER_MODULE};
use anyhow::{anyhow, bail, Context as _, Error};
use binding::TsReference;
use identifier::is_valid_ident;
use std::borrow::Cow;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::fmt;
@@ -19,6 +20,7 @@ use std::path::{Path, PathBuf};
use walrus::{FunctionId, ImportId, MemoryId, Module, TableId, ValType};

mod binding;
pub mod identifier;

pub struct Context<'a> {
globals: String,
@@ -4535,48 +4537,6 @@ fn require_class<'a>(
.or_default()
}

/// Returns whether a character has the Unicode `ID_Start` properly.
///
/// This is only ever-so-slightly different from `XID_Start` in a few edge
/// cases, so we handle those edge cases manually and delegate everything else
/// to `unicode-ident`.
fn is_id_start(c: char) -> bool {
match c {
'\u{037A}' | '\u{0E33}' | '\u{0EB3}' | '\u{309B}' | '\u{309C}' | '\u{FC5E}'
| '\u{FC5F}' | '\u{FC60}' | '\u{FC61}' | '\u{FC62}' | '\u{FC63}' | '\u{FDFA}'
| '\u{FDFB}' | '\u{FE70}' | '\u{FE72}' | '\u{FE74}' | '\u{FE76}' | '\u{FE78}'
| '\u{FE7A}' | '\u{FE7C}' | '\u{FE7E}' | '\u{FF9E}' | '\u{FF9F}' => true,
_ => unicode_ident::is_xid_start(c),
}
}

/// Returns whether a character has the Unicode `ID_Continue` properly.
///
/// This is only ever-so-slightly different from `XID_Continue` in a few edge
/// cases, so we handle those edge cases manually and delegate everything else
/// to `unicode-ident`.
fn is_id_continue(c: char) -> bool {
match c {
'\u{037A}' | '\u{309B}' | '\u{309C}' | '\u{FC5E}' | '\u{FC5F}' | '\u{FC60}'
| '\u{FC61}' | '\u{FC62}' | '\u{FC63}' | '\u{FDFA}' | '\u{FDFB}' | '\u{FE70}'
| '\u{FE72}' | '\u{FE74}' | '\u{FE76}' | '\u{FE78}' | '\u{FE7A}' | '\u{FE7C}'
| '\u{FE7E}' => true,
_ => unicode_ident::is_xid_continue(c),
}
}

/// Returns whether a string is a valid JavaScript identifier.
/// Defined at https://tc39.es/ecma262/#prod-IdentifierName.
fn is_valid_ident(name: &str) -> bool {
name.chars().enumerate().all(|(i, char)| {
if i == 0 {
is_id_start(char) || char == '$' || char == '_'
} else {
is_id_continue(char) || char == '$' || char == '\u{200C}' || char == '\u{200D}'
}
})
}

/// Returns a string to tack on to the end of an expression to access a
/// property named `name` of the object that expression resolves to.
///
8 changes: 4 additions & 4 deletions crates/cli/tests/reference/echo.d.ts
Original file line number Diff line number Diff line change
@@ -33,9 +33,9 @@ export function echo_vec_uninit_u32(a: Uint32Array): Uint32Array;
export function echo_vec_uninit_i32(a: Int32Array): Int32Array;
export function echo_vec_uninit_u64(a: BigUint64Array): BigUint64Array;
export function echo_vec_uninit_i64(a: BigInt64Array): BigInt64Array;
export function echo_vec_string(a: (string)[]): (string)[];
export function echo_vec_string(a: string[]): string[];
export function echo_struct(a: Foo): Foo;
export function echo_vec_struct(a: (Foo)[]): (Foo)[];
export function echo_vec_struct(a: Foo[]): Foo[];
export function echo_option_u8(a?: number | null): number | undefined;
export function echo_option_i8(a?: number | null): number | undefined;
export function echo_option_u16(a?: number | null): number | undefined;
@@ -69,9 +69,9 @@ export function echo_option_vec_uninit_u32(a?: Uint32Array | null): Uint32Array
export function echo_option_vec_uninit_i32(a?: Int32Array | null): Int32Array | undefined;
export function echo_option_vec_uninit_u64(a?: BigUint64Array | null): BigUint64Array | undefined;
export function echo_option_vec_uninit_i64(a?: BigInt64Array | null): BigInt64Array | undefined;
export function echo_option_vec_string(a?: (string)[] | null): (string)[] | undefined;
export function echo_option_vec_string(a?: string[] | null): string[] | undefined;
export function echo_option_struct(a?: Foo | null): Foo | undefined;
export function echo_option_vec_struct(a?: (Foo)[] | null): (Foo)[] | undefined;
export function echo_option_vec_struct(a?: Foo[] | null): Foo[] | undefined;
export class Foo {
private constructor();
free(): void;
16 changes: 8 additions & 8 deletions crates/cli/tests/reference/echo.js
Original file line number Diff line number Diff line change
@@ -685,8 +685,8 @@ function getArrayJsValueFromWasm0(ptr, len) {
return result;
}
/**
* @param {(string)[]} a
* @returns {(string)[]}
* @param {string[]} a
* @returns {string[]}
*/
export function echo_vec_string(a) {
const ptr0 = passArrayJsValueToWasm0(a, wasm.__wbindgen_malloc);
@@ -714,8 +714,8 @@ export function echo_struct(a) {
}

/**
* @param {(Foo)[]} a
* @returns {(Foo)[]}
* @param {Foo[]} a
* @returns {Foo[]}
*/
export function echo_vec_struct(a) {
const ptr0 = passArrayJsValueToWasm0(a, wasm.__wbindgen_malloc);
@@ -1145,8 +1145,8 @@ export function echo_option_vec_uninit_i64(a) {
}

/**
* @param {(string)[] | null} [a]
* @returns {(string)[] | undefined}
* @param {string[] | null} [a]
* @returns {string[] | undefined}
*/
export function echo_option_vec_string(a) {
var ptr0 = isLikeNone(a) ? 0 : passArrayJsValueToWasm0(a, wasm.__wbindgen_malloc);
@@ -1175,8 +1175,8 @@ export function echo_option_struct(a) {
}

/**
* @param {(Foo)[] | null} [a]
* @returns {(Foo)[] | undefined}
* @param {Foo[] | null} [a]
* @returns {Foo[] | undefined}
*/
export function echo_option_vec_struct(a) {
var ptr0 = isLikeNone(a) ? 0 : passArrayJsValueToWasm0(a, wasm.__wbindgen_malloc);

0 comments on commit 0c86bfb

Please sign in to comment.