Skip to content

Commit 9b8a7cd

Browse files
authored
perf: improve wasm_module_deps_to_dts (#551)
1 parent a639636 commit 9b8a7cd

File tree

4 files changed

+107
-79
lines changed

4 files changed

+107
-79
lines changed

Cargo.lock

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ harness = false
4040
[dependencies]
4141
anyhow = "1.0.43"
4242
async-trait = "0.1.68"
43+
string_capacity = "0.1.3"
4344
data-url = "0.3.0"
4445
deno_ast = { version = "0.44.0", features = ["dep_analysis", "emit"] }
4546
deno_unsync.workspace = true

src/source/wasm.rs

+94-77
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
// Copyright 2018-2024 the Deno authors. MIT license.
22

3-
use std::borrow::Cow;
4-
use std::collections::HashSet;
5-
3+
use indexmap::IndexSet;
4+
use string_capacity::StringBuilder;
65
use wasm_dep_analyzer::ValueType;
76

87
pub fn wasm_module_to_dts(
@@ -41,87 +40,105 @@ fn wasm_module_deps_to_dts(wasm_deps: &wasm_dep_analyzer::WasmDeps) -> String {
4140
&& deno_ast::swc::ast::Ident::verify_symbol(export_name).is_ok()
4241
}
4342

44-
let mut text = String::new();
45-
let mut internal_names_count = 0;
43+
let is_valid_export_ident_per_export = wasm_deps
44+
.exports
45+
.iter()
46+
.map(|export| is_valid_ident(export.name))
47+
.collect::<Vec<_>>();
48+
let unique_import_modules = wasm_deps
49+
.imports
50+
.iter()
51+
.map(|import| import.module)
52+
.collect::<IndexSet<_>>();
4653

47-
let mut seen_modules = HashSet::with_capacity(wasm_deps.imports.len());
48-
for import in &wasm_deps.imports {
49-
if seen_modules.insert(&import.module) {
50-
text.push_str(&format!("import \"{}\";\n", import.module));
54+
StringBuilder::build(|builder| {
55+
for import_module in &unique_import_modules {
56+
builder.append("import \"");
57+
builder.append(import_module);
58+
builder.append("\";\n");
5159
}
52-
}
5360

54-
for export in &wasm_deps.exports {
55-
let has_valid_export_ident = is_valid_ident(export.name);
56-
let export_name = if has_valid_export_ident {
57-
Cow::Borrowed(export.name)
58-
} else {
59-
let export_name =
60-
format!("__deno_wasm_export_{}__", internal_names_count);
61-
internal_names_count += 1;
62-
Cow::Owned(export_name)
63-
};
64-
if has_valid_export_ident {
65-
text.push_str("export ");
66-
}
67-
let mut add_var = |type_text: &str| {
68-
text.push_str("declare const ");
69-
text.push_str(&export_name);
70-
text.push_str(": ");
71-
text.push_str(type_text);
72-
text.push_str(";\n");
73-
};
61+
for (i, export) in wasm_deps.exports.iter().enumerate() {
62+
let has_valid_export_ident = is_valid_export_ident_per_export[i];
63+
if has_valid_export_ident {
64+
builder.append("export ");
65+
}
66+
fn write_export_name<'a>(
67+
builder: &mut StringBuilder<'a>,
68+
export: &'a wasm_dep_analyzer::Export<'a>,
69+
has_valid_export_ident: bool,
70+
index: usize,
71+
) {
72+
if has_valid_export_ident {
73+
builder.append(export.name);
74+
} else {
75+
builder.append("__deno_wasm_export_");
76+
builder.append(index);
77+
builder.append("__");
78+
}
79+
}
80+
let mut add_var = |type_text: &'static str| {
81+
builder.append("declare const ");
82+
write_export_name(builder, export, has_valid_export_ident, i);
83+
builder.append(": ");
84+
builder.append(type_text);
85+
builder.append(";\n");
86+
};
7487

75-
match &export.export_type {
76-
wasm_dep_analyzer::ExportType::Function(function_signature) => {
77-
match function_signature {
78-
Ok(signature) => {
79-
text.push_str("declare function ");
80-
text.push_str(&export_name);
81-
text.push('(');
82-
for (i, param) in signature.params.iter().enumerate() {
83-
if i > 0 {
84-
text.push_str(", ");
88+
match &export.export_type {
89+
wasm_dep_analyzer::ExportType::Function(function_signature) => {
90+
match function_signature {
91+
Ok(signature) => {
92+
builder.append("declare function ");
93+
write_export_name(builder, export, has_valid_export_ident, i);
94+
builder.append('(');
95+
for (i, param) in signature.params.iter().enumerate() {
96+
if i > 0 {
97+
builder.append(", ");
98+
}
99+
builder.append("arg");
100+
builder.append(i);
101+
builder.append(": ");
102+
builder
103+
.append(value_type_to_ts_type(*param, TypePosition::Input));
85104
}
86-
text.push_str("arg");
87-
text.push_str(i.to_string().as_str());
88-
text.push_str(": ");
89-
text.push_str(value_type_to_ts_type(*param, TypePosition::Input));
105+
builder.append("): ");
106+
builder.append(
107+
signature
108+
.returns
109+
.first()
110+
.map(|t| value_type_to_ts_type(*t, TypePosition::Output))
111+
.unwrap_or("void"),
112+
);
113+
builder.append(";\n");
90114
}
91-
text.push_str("): ");
92-
text.push_str(
93-
signature
94-
.returns
95-
.first()
96-
.map(|t| value_type_to_ts_type(*t, TypePosition::Output))
97-
.unwrap_or("void"),
98-
);
99-
text.push_str(";\n");
115+
Err(_) => add_var("unknown"),
100116
}
101-
Err(_) => add_var("unknown"),
102117
}
118+
wasm_dep_analyzer::ExportType::Table => add_var("WebAssembly.Table"),
119+
wasm_dep_analyzer::ExportType::Memory => add_var("WebAssembly.Memory"),
120+
wasm_dep_analyzer::ExportType::Global(global_type) => match global_type
121+
{
122+
Ok(global_type) => add_var(value_type_to_ts_type(
123+
global_type.value_type,
124+
TypePosition::Output,
125+
)),
126+
Err(_) => add_var("unknown"),
127+
},
128+
wasm_dep_analyzer::ExportType::Tag
129+
| wasm_dep_analyzer::ExportType::Unknown => add_var("unknown"),
103130
}
104-
wasm_dep_analyzer::ExportType::Table => add_var("WebAssembly.Table"),
105-
wasm_dep_analyzer::ExportType::Memory => add_var("WebAssembly.Memory"),
106-
wasm_dep_analyzer::ExportType::Global(global_type) => match global_type {
107-
Ok(global_type) => add_var(value_type_to_ts_type(
108-
global_type.value_type,
109-
TypePosition::Output,
110-
)),
111-
Err(_) => add_var("unknown"),
112-
},
113-
wasm_dep_analyzer::ExportType::Tag
114-
| wasm_dep_analyzer::ExportType::Unknown => add_var("unknown"),
115-
}
116131

117-
if !has_valid_export_ident {
118-
text.push_str(&format!(
119-
"export {{ {} as \"{}\" }};\n",
120-
export_name, export.name
121-
));
132+
if !has_valid_export_ident {
133+
builder.append("export { ");
134+
write_export_name(builder, export, has_valid_export_ident, i);
135+
builder.append(" as \"");
136+
builder.append(export.name);
137+
builder.append("\" };\n");
138+
}
122139
}
123-
}
124-
text
140+
})
141+
.unwrap()
125142
}
126143

127144
#[cfg(test)]
@@ -220,10 +237,10 @@ export declare const name5: WebAssembly.Memory;
220237
export declare const name6: number;
221238
export declare const name7: unknown;
222239
export declare const name8: unknown;
223-
declare const __deno_wasm_export_1__: unknown;
224-
export { __deno_wasm_export_1__ as \"name9--\" };
225-
declare const __deno_wasm_export_2__: unknown;
226-
export { __deno_wasm_export_2__ as \"default\" };
240+
declare const __deno_wasm_export_8__: unknown;
241+
export { __deno_wasm_export_8__ as \"name9--\" };
242+
declare const __deno_wasm_export_9__: unknown;
243+
export { __deno_wasm_export_9__ as \"default\" };
227244
"
228245
);
229246
}

tests/specs/ecosystem/mrii/rocket_io/0_1_3.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ mrii/rocket-io/0.1.3
7373

7474
-- stderr --
7575
error: Uncaught Error: [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './build/esm/socket' is not defined for types by "exports" in '<global_npm_dir>/socket.io-client/4.7.5/package.json' imported from 'file://<tmpdir>/src/types/socket-reserved-events.ts'
76-
at Object.resolveModuleNames (ext:deno_tsc/99_main_compiler.js:742:28)
77-
at actualResolveModuleNamesWorker (ext:deno_tsc/00_typescript.js:125027:142)
76+
at Object.resolveModuleNameLiterals (ext:deno_tsc/99_main_compiler.js:768:28)
7877
at resolveModuleNamesWorker (ext:deno_tsc/00_typescript.js:125466:20)
7978
at resolveNamesReusingOldState (ext:deno_tsc/00_typescript.js:125608:14)
8079
at resolveModuleNamesReusingOldState (ext:deno_tsc/00_typescript.js:125564:12)
@@ -83,4 +82,5 @@ error: Uncaught Error: [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './build/
8382
at findSourceFile (ext:deno_tsc/00_typescript.js:126705:20)
8483
at processImportedModules (ext:deno_tsc/00_typescript.js:127105:11)
8584
at findSourceFileWorker (ext:deno_tsc/00_typescript.js:126854:7)
85+
at findSourceFile (ext:deno_tsc/00_typescript.js:126705:20)
8686

0 commit comments

Comments
 (0)