Skip to content

Commit 7c13fa1

Browse files
committed
Merge branch 'main' into more-specific-errors
# Conflicts: # Cargo.lock # Cargo.toml
2 parents 4fb6c2d + 7c4a101 commit 7c13fa1

File tree

7 files changed

+151
-92
lines changed

7 files changed

+151
-92
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "deno_graph"
3-
version = "0.85.1"
3+
version = "0.86.3"
44
edition = "2021"
55
description = "Module graph analysis for deno"
66
homepage = "https://deno.land/"
@@ -41,6 +41,7 @@ harness = false
4141

4242
[dependencies]
4343
async-trait = "0.1.68"
44+
capacity_builder = "0.1.0"
4445
data-url = "0.3.0"
4546
deno_ast = { version = "0.44.0", features = ["dep_analysis", "emit"] }
4647
deno_unsync.workspace = true

rust-toolchain.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[toolchain]
2-
channel = "1.80.0"
2+
channel = "1.82.0"
33
components = [ "clippy", "rustfmt" ]

src/ast.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -832,13 +832,16 @@ fn parse_jsdoc_dynamic_import(input: &str) -> monch::ParseResult<JsDocImport> {
832832
use monch::*;
833833
let original_input = input;
834834
let (mut input, _) = ch('{')(input)?;
835-
for (index, c) in input.char_indices() {
836-
if c == '}' {
837-
return ParseError::backtrace();
838-
}
839-
input = &original_input[index..];
840-
if input.starts_with("import") {
841-
break;
835+
{
836+
let original_input = input;
837+
for (index, c) in input.char_indices() {
838+
if c == '}' {
839+
return ParseError::backtrace();
840+
}
841+
input = &original_input[index..];
842+
if input.starts_with("import") {
843+
break;
844+
}
842845
}
843846
}
844847
let (input, _) = tag("import")(input)?;
@@ -1559,6 +1562,7 @@ export {};
15591562

15601563
assert!(parse_jsdoc_dynamic_import("{ import('testing') }").is_ok());
15611564
assert!(parse_jsdoc_dynamic_import("{ Test<import('testing')> }").is_ok());
1565+
assert!(parse_jsdoc_dynamic_import("{ * // … test }").is_err());
15621566
assert_eq!(
15631567
parse_resolution_mode(
15641568
r#"{Set<import("./e.js", { with: { "resolution-mode": "require" } }).F>}"#

src/graph.rs

+40-3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use deno_semver::package::PackageReq;
5151
use deno_semver::package::PackageReqReferenceParseError;
5252
use deno_semver::RangeSetOrTag;
5353
use deno_semver::Version;
54+
use deno_semver::VersionReq;
5455
use futures::future::LocalBoxFuture;
5556
use futures::stream::FuturesOrdered;
5657
use futures::stream::FuturesUnordered;
@@ -224,8 +225,14 @@ pub enum JsrLoadError {
224225
pub enum JsrPackageFormatError {
225226
#[error(transparent)]
226227
JsrPackageParseError(PackageReqReferenceParseError),
227-
#[error("Version tag not supported in jsr specifiers.")]
228-
VersionTagNotSupported,
228+
#[error("Version tag not supported in jsr specifiers ('{}').{}",
229+
.tag,
230+
match .tag.strip_prefix('v').and_then(|v| VersionReq::parse_from_specifier(v).ok().map(|s| s.tag().is_none())).unwrap_or(false) {
231+
true => " Remove leading 'v' before version.",
232+
false => ""
233+
}
234+
)]
235+
VersionTagNotSupported { tag: String },
229236
}
230237

231238
#[derive(Debug, Clone, Error, JsError)]
@@ -5098,7 +5105,9 @@ fn validate_jsr_specifier(
50985105
let package_ref = JsrPackageReqReference::from_specifier(specifier)
50995106
.map_err(JsrPackageFormatError::JsrPackageParseError)?;
51005107
match package_ref.req().version_req.inner() {
5101-
RangeSetOrTag::Tag(_) => Err(JsrPackageFormatError::VersionTagNotSupported),
5108+
RangeSetOrTag::Tag(tag) => {
5109+
Err(JsrPackageFormatError::VersionTagNotSupported { tag: tag.clone() })
5110+
}
51025111
RangeSetOrTag::RangeSet(_) => Ok(package_ref),
51035112
}
51045113
}
@@ -6682,4 +6691,32 @@ mod tests {
66826691
.unwrap();
66836692
assert!(module.external().is_some());
66846693
}
6694+
6695+
#[test]
6696+
fn leading_v_version_tag_err() {
6697+
{
6698+
let err = JsrPackageFormatError::VersionTagNotSupported {
6699+
tag: "v1.2".to_string(),
6700+
};
6701+
assert_eq!(err.to_string(), "Version tag not supported in jsr specifiers ('v1.2'). Remove leading 'v' before version.");
6702+
}
6703+
{
6704+
let err = JsrPackageFormatError::VersionTagNotSupported {
6705+
tag: "latest".to_string(),
6706+
};
6707+
assert_eq!(
6708+
err.to_string(),
6709+
"Version tag not supported in jsr specifiers ('latest')."
6710+
);
6711+
}
6712+
{
6713+
let err = JsrPackageFormatError::VersionTagNotSupported {
6714+
tag: "version".to_string(), // not a vversion with a leading 'v'
6715+
};
6716+
assert_eq!(
6717+
err.to_string(),
6718+
"Version tag not supported in jsr specifiers ('version')."
6719+
);
6720+
}
6721+
}
66856722
}

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 capacity_builder::StringBuilder;
4+
use indexmap::IndexSet;
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

tests/specs/graph/jsr/version_tag_not_supported.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import 'jsr:@scope/a@tag';
4141
},
4242
{
4343
"specifier": "jsr:@scope/a@tag",
44-
"error": "Version tag not supported in jsr specifiers."
44+
"error": "Version tag not supported in jsr specifiers ('tag')."
4545
}
4646
],
4747
"redirects": {}

0 commit comments

Comments
 (0)