chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

View File

@@ -0,0 +1,151 @@
use alloc::string::String;
/// Returns whether a character is a valid JS identifier start character.
///
/// 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,
'$' | '_' => true,
_ => unicode_ident::is_xid_start(c),
}
}
/// Returns whether a character is a valid JS identifier continue character.
///
/// 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,
'$' | '\u{200C}' | '\u{200D}' => true,
_ => unicode_ident::is_xid_continue(c),
}
}
fn maybe_valid_chars(name: &str) -> impl Iterator<Item = Option<char>> + '_ {
let mut chars = name.chars();
// Always emit at least one `None` item - that way `is_valid_ident` can fail without
// a separate check for empty strings, and `to_valid_ident` will always produce at least
// one underscore.
core::iter::once(chars.next().filter(|&c| is_id_start(c))).chain(chars.map(|c| {
if is_id_continue(c) {
Some(c)
} else {
None
}
}))
}
/// Javascript keywords.
///
/// Note that some of these keywords are only reserved in strict mode. Since we
/// generate strict mode JS code, we treat all of these as reserved.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#reserved_words
const JS_KEYWORDS: [&str; 47] = [
"arguments",
"break",
"case",
"catch",
"class",
"const",
"continue",
"debugger",
"default",
"delete",
"do",
"else",
"enum",
"eval",
"export",
"extends",
"false",
"finally",
"for",
"function",
"if",
"implements",
"import",
"in",
"instanceof",
"interface",
"let",
"new",
"null",
"package",
"private",
"protected",
"public",
"return",
"static",
"super",
"switch",
"this",
"throw",
"true",
"try",
"typeof",
"var",
"void",
"while",
"with",
"yield",
];
/// Javascript keywords that behave like values in that they can be called like
/// functions or have properties accessed on them.
///
/// Naturally, this list is a subset of `JS_KEYWORDS`.
const VALUE_LIKE_JS_KEYWORDS: [&str; 7] = [
"eval", // eval is a function-like keyword, so e.g. `eval(...)` is valid
"false", // false resolves to a boolean value, so e.g. `false.toString()` is valid
"import", // import.meta and import()
"new", // new.target
"super", // super can be used for a function call (`super(...)`) or property lookup (`super.prop`)
"this", // this obviously can be used as a value
"true", // true resolves to a boolean value, so e.g. `false.toString()` is valid
];
/// Returns whether the given string is a JS keyword.
pub fn is_js_keyword(keyword: &str) -> bool {
JS_KEYWORDS.contains(&keyword)
}
/// Returns whether the given string is a JS keyword that does NOT behave like
/// a value.
///
/// Value-like keywords can be called like functions or have properties
/// accessed, which makes it possible to use them in imports. In general,
/// imports should use this function to check for reserved keywords.
pub fn is_non_value_js_keyword(keyword: &str) -> bool {
JS_KEYWORDS.contains(&keyword) && !VALUE_LIKE_JS_KEYWORDS.contains(&keyword)
}
/// 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 {
maybe_valid_chars(name).all(|opt| opt.is_some())
}
/// Converts a string to a valid JavaScript identifier by replacing invalid
/// characters with underscores.
pub fn to_valid_ident(name: &str) -> String {
let result: String = maybe_valid_chars(name)
.map(|opt| opt.unwrap_or('_'))
.collect();
if is_js_keyword(&result) || is_non_value_js_keyword(&result) {
alloc::format!("_{result}")
} else {
result
}
}

291
vendor/wasm-bindgen-shared/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,291 @@
#![doc(html_root_url = "https://docs.rs/wasm-bindgen-shared/0.2")]
#![no_std]
extern crate alloc;
use alloc::string::{String, ToString};
pub mod identifier;
#[cfg(test)]
mod schema_hash_approval;
pub mod tys;
// This gets changed whenever our schema changes.
// At this time versions of wasm-bindgen and wasm-bindgen-cli are required to have the exact same
// SCHEMA_VERSION in order to work together.
pub const SCHEMA_VERSION: &str = "0.2.114";
#[macro_export]
macro_rules! shared_api {
($mac:ident) => {
$mac! {
struct Program<'a> {
exports: Vec<Export<'a>>,
enums: Vec<Enum<'a>>,
imports: Vec<Import<'a>>,
structs: Vec<Struct<'a>>,
// NOTE: Originally typescript_custom_sections are just some strings
// But the expression type can only be parsed into a string during compilation
// So when encoding, LitOrExpr contains two types, one is that expressions are parsed into strings during compilation, and the other is can be parsed directly.
// When decoding, LitOrExpr can be decoded as a string.
typescript_custom_sections: Vec<LitOrExpr<'a>>,
local_modules: Vec<LocalModule<'a>>,
inline_js: Vec<&'a str>,
unique_crate_identifier: &'a str,
package_json: Option<&'a str>,
linked_modules: Vec<LinkedModule<'a>>,
}
struct Import<'a> {
module: Option<ImportModule<'a>>,
js_namespace: Option<Vec<String>>,
reexport: Option<String>,
kind: ImportKind<'a>,
}
struct LinkedModule<'a> {
module: ImportModule<'a>,
link_function_name: &'a str,
}
enum ImportModule<'a> {
Named(&'a str),
RawNamed(&'a str),
Inline(u32),
}
enum ImportKind<'a> {
Function(ImportFunction<'a>),
Static(ImportStatic<'a>),
String(ImportString<'a>),
Type(ImportType<'a>),
Enum(StringEnum<'a>),
}
struct ImportFunction<'a> {
shim: &'a str,
catch: bool,
variadic: bool,
assert_no_shim: bool,
method: Option<MethodData<'a>>,
structural: bool,
function: Function<'a>,
}
struct MethodData<'a> {
class: &'a str,
kind: MethodKind<'a>,
}
enum MethodKind<'a> {
Constructor,
Operation(Operation<'a>),
}
struct Operation<'a> {
is_static: bool,
kind: OperationKind<'a>,
}
enum OperationKind<'a> {
Regular,
RegularThis,
Getter(&'a str),
Setter(&'a str),
IndexingGetter,
IndexingSetter,
IndexingDeleter,
}
struct ImportStatic<'a> {
name: &'a str,
shim: &'a str,
}
struct ImportString<'a> {
shim: &'a str,
string: &'a str,
}
struct ImportType<'a> {
name: &'a str,
instanceof_shim: &'a str,
vendor_prefixes: Vec<&'a str>,
}
struct StringEnum<'a> {
name: &'a str,
variant_values: Vec<&'a str>,
comments: Vec<&'a str>,
generate_typescript: bool,
js_namespace: Option<Vec<&'a str>>,
}
struct Export<'a> {
class: Option<&'a str>,
comments: Vec<&'a str>,
consumed: bool,
function: Function<'a>,
js_namespace: Option<Vec<&'a str>>,
method_kind: MethodKind<'a>,
start: bool,
}
struct Enum<'a> {
name: &'a str,
signed: bool,
variants: Vec<EnumVariant<'a>>,
comments: Vec<&'a str>,
generate_typescript: bool,
js_namespace: Option<Vec<&'a str>>,
private: bool,
}
struct EnumVariant<'a> {
name: &'a str,
value: u32,
comments: Vec<&'a str>,
}
struct Function<'a> {
args: Vec<FunctionArgumentData<'a>>,
asyncness: bool,
name: &'a str,
generate_typescript: bool,
generate_jsdoc: bool,
variadic: bool,
ret_ty_override: Option<&'a str>,
ret_desc: Option<&'a str>,
}
struct FunctionArgumentData<'a> {
name: String,
ty_override: Option<&'a str>,
optional: bool,
desc: Option<&'a str>,
}
struct Struct<'a> {
name: &'a str,
rust_name: &'a str,
fields: Vec<StructField<'a>>,
comments: Vec<&'a str>,
is_inspectable: bool,
generate_typescript: bool,
js_namespace: Option<Vec<&'a str>>,
private: bool,
}
struct StructField<'a> {
name: &'a str,
readonly: bool,
comments: Vec<&'a str>,
generate_typescript: bool,
generate_jsdoc: bool,
}
struct LocalModule<'a> {
identifier: &'a str,
contents: &'a str,
linked_module: bool,
}
}
}; // end of mac case
} // end of mac definition
/// Compute a "qualified name" by prepending the namespace (joined with `__`) to the js_name.
/// When there is no namespace, this returns the js_name unchanged.
/// This is used to disambiguate internal wasm symbols when the same js_name
/// appears in different namespaces. `__` is used as the separator because
/// double underscores are unlikely to appear in user-defined names.
pub fn qualified_name(js_namespace: Option<&[impl AsRef<str>]>, js_name: &str) -> String {
match js_namespace {
Some(ns) if !ns.is_empty() => {
let mut name = ns
.iter()
.map(|s| s.as_ref())
.collect::<alloc::vec::Vec<_>>()
.join("__");
name.push_str("__");
name.push_str(js_name);
name
}
_ => js_name.to_string(),
}
}
pub fn new_function(struct_name: &str) -> String {
let mut name = "__wbg_".to_string();
name.extend(struct_name.chars().flat_map(|s| s.to_lowercase()));
name.push_str("_new");
name
}
pub fn free_function(struct_name: &str) -> String {
let mut name = "__wbg_".to_string();
name.extend(struct_name.chars().flat_map(|s| s.to_lowercase()));
name.push_str("_free");
name
}
pub fn unwrap_function(struct_name: &str) -> String {
let mut name = "__wbg_".to_string();
name.extend(struct_name.chars().flat_map(|s| s.to_lowercase()));
name.push_str("_unwrap");
name
}
pub fn free_function_export_name(function_name: &str) -> String {
function_name.to_string()
}
pub fn struct_function_export_name(struct_: &str, f: &str) -> String {
let mut name = struct_
.chars()
.flat_map(|s| s.to_lowercase())
.collect::<String>();
name.push('_');
name.push_str(f);
name
}
pub fn struct_field_get(struct_: &str, f: &str) -> String {
let mut name = String::from("__wbg_get_");
name.extend(struct_.chars().flat_map(|s| s.to_lowercase()));
name.push('_');
name.push_str(f);
name
}
pub fn struct_field_set(struct_: &str, f: &str) -> String {
let mut name = String::from("__wbg_set_");
name.extend(struct_.chars().flat_map(|s| s.to_lowercase()));
name.push('_');
name.push_str(f);
name
}
pub fn version() -> String {
let mut v = env!("CARGO_PKG_VERSION").to_string();
if let Some(s) = option_env!("WBG_VERSION") {
v.push_str(" (");
v.push_str(s);
v.push(')');
}
v
}
pub fn escape_string(s: &str) -> String {
let mut result = String::with_capacity(s.len());
for c in s.chars() {
match c {
'\\' => result.push_str("\\\\"),
'\n' => result.push_str("\\n"),
'\r' => result.push_str("\\r"),
'\'' => result.push_str("\\'"),
'"' => result.push_str("\\\""),
_ => result.push(c),
}
}
result
}

View File

@@ -0,0 +1,16 @@
// Whenever the lib.rs changes, the SCHEMA_FILE_HASH environment variable will change and the
// schema_version test below will fail.
// Proceed as follows:
//
// If the schema in this library has changed then:
// 1. Change this APPROVED_SCHEMA_FILE_HASH to the new hash.
//
// If the schema in this library has changed then:
// 1. Bump the version in `crates/shared/Cargo.toml`
// 2. Change the `SCHEMA_VERSION` in this library to this new Cargo.toml version
const APPROVED_SCHEMA_FILE_HASH: &str = "4279711543728568852";
#[test]
fn schema_version() {
assert_eq!(env!("SCHEMA_FILE_HASH"), APPROVED_SCHEMA_FILE_HASH)
}

44
vendor/wasm-bindgen-shared/src/tys.rs vendored Normal file
View File

@@ -0,0 +1,44 @@
macro_rules! tys {
($($a:ident)*) => (tys! { @ ($($a)*) 0 });
(@ () $v:expr) => {};
(@ ($a:ident $($b:ident)*) $v:expr) => {
pub const $a: u32 = $v;
tys!(@ ($($b)*) $v+1);
}
}
tys! {
I8
U8
I16
U16
I32
U32
I64
U64
I128
U128
F32
F64
BOOLEAN
FUNCTION
CLOSURE
CACHED_STRING
STRING
REF
REFMUT
LONGREF
SLICE
VECTOR
EXTERNREF
NAMED_EXTERNREF
ENUM
STRING_ENUM
RUST_STRUCT
CHAR
OPTIONAL
RESULT
UNIT
CLAMPED
NONNULL
}