Skip to content

Commit

Permalink
Merge branch 'main' into more-specific-errors
Browse files Browse the repository at this point in the history
# Conflicts:
#	Cargo.lock
#	Cargo.toml
  • Loading branch information
crowlKats committed Dec 12, 2024
2 parents 4fb6c2d + 7c4a101 commit 7c13fa1
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 92 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "deno_graph"
version = "0.85.1"
version = "0.86.3"
edition = "2021"
description = "Module graph analysis for deno"
homepage = "https://deno.land/"
Expand Down Expand Up @@ -41,6 +41,7 @@ harness = false

[dependencies]
async-trait = "0.1.68"
capacity_builder = "0.1.0"
data-url = "0.3.0"
deno_ast = { version = "0.44.0", features = ["dep_analysis", "emit"] }
deno_unsync.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "1.80.0"
channel = "1.82.0"
components = [ "clippy", "rustfmt" ]
18 changes: 11 additions & 7 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -832,13 +832,16 @@ fn parse_jsdoc_dynamic_import(input: &str) -> monch::ParseResult<JsDocImport> {
use monch::*;
let original_input = input;
let (mut input, _) = ch('{')(input)?;
for (index, c) in input.char_indices() {
if c == '}' {
return ParseError::backtrace();
}
input = &original_input[index..];
if input.starts_with("import") {
break;
{
let original_input = input;
for (index, c) in input.char_indices() {
if c == '}' {
return ParseError::backtrace();
}
input = &original_input[index..];
if input.starts_with("import") {
break;
}
}
}
let (input, _) = tag("import")(input)?;
Expand Down Expand Up @@ -1559,6 +1562,7 @@ export {};

assert!(parse_jsdoc_dynamic_import("{ import('testing') }").is_ok());
assert!(parse_jsdoc_dynamic_import("{ Test<import('testing')> }").is_ok());
assert!(parse_jsdoc_dynamic_import("{ * // … test }").is_err());
assert_eq!(
parse_resolution_mode(
r#"{Set<import("./e.js", { with: { "resolution-mode": "require" } }).F>}"#
Expand Down
43 changes: 40 additions & 3 deletions src/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ use deno_semver::package::PackageReq;
use deno_semver::package::PackageReqReferenceParseError;
use deno_semver::RangeSetOrTag;
use deno_semver::Version;
use deno_semver::VersionReq;
use futures::future::LocalBoxFuture;
use futures::stream::FuturesOrdered;
use futures::stream::FuturesUnordered;
Expand Down Expand Up @@ -224,8 +225,14 @@ pub enum JsrLoadError {
pub enum JsrPackageFormatError {
#[error(transparent)]
JsrPackageParseError(PackageReqReferenceParseError),
#[error("Version tag not supported in jsr specifiers.")]
VersionTagNotSupported,
#[error("Version tag not supported in jsr specifiers ('{}').{}",
.tag,
match .tag.strip_prefix('v').and_then(|v| VersionReq::parse_from_specifier(v).ok().map(|s| s.tag().is_none())).unwrap_or(false) {
true => " Remove leading 'v' before version.",
false => ""
}
)]
VersionTagNotSupported { tag: String },
}

#[derive(Debug, Clone, Error, JsError)]
Expand Down Expand Up @@ -5098,7 +5105,9 @@ fn validate_jsr_specifier(
let package_ref = JsrPackageReqReference::from_specifier(specifier)
.map_err(JsrPackageFormatError::JsrPackageParseError)?;
match package_ref.req().version_req.inner() {
RangeSetOrTag::Tag(_) => Err(JsrPackageFormatError::VersionTagNotSupported),
RangeSetOrTag::Tag(tag) => {
Err(JsrPackageFormatError::VersionTagNotSupported { tag: tag.clone() })
}
RangeSetOrTag::RangeSet(_) => Ok(package_ref),
}
}
Expand Down Expand Up @@ -6682,4 +6691,32 @@ mod tests {
.unwrap();
assert!(module.external().is_some());
}

#[test]
fn leading_v_version_tag_err() {
{
let err = JsrPackageFormatError::VersionTagNotSupported {
tag: "v1.2".to_string(),
};
assert_eq!(err.to_string(), "Version tag not supported in jsr specifiers ('v1.2'). Remove leading 'v' before version.");
}
{
let err = JsrPackageFormatError::VersionTagNotSupported {
tag: "latest".to_string(),
};
assert_eq!(
err.to_string(),
"Version tag not supported in jsr specifiers ('latest')."
);
}
{
let err = JsrPackageFormatError::VersionTagNotSupported {
tag: "version".to_string(), // not a vversion with a leading 'v'
};
assert_eq!(
err.to_string(),
"Version tag not supported in jsr specifiers ('version')."
);
}
}
}
171 changes: 94 additions & 77 deletions src/source/wasm.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// Copyright 2018-2024 the Deno authors. MIT license.

use std::borrow::Cow;
use std::collections::HashSet;

use capacity_builder::StringBuilder;
use indexmap::IndexSet;
use wasm_dep_analyzer::ValueType;

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

let mut text = String::new();
let mut internal_names_count = 0;
let is_valid_export_ident_per_export = wasm_deps
.exports
.iter()
.map(|export| is_valid_ident(export.name))
.collect::<Vec<_>>();
let unique_import_modules = wasm_deps
.imports
.iter()
.map(|import| import.module)
.collect::<IndexSet<_>>();

let mut seen_modules = HashSet::with_capacity(wasm_deps.imports.len());
for import in &wasm_deps.imports {
if seen_modules.insert(&import.module) {
text.push_str(&format!("import \"{}\";\n", import.module));
StringBuilder::build(|builder| {
for import_module in &unique_import_modules {
builder.append("import \"");
builder.append(import_module);
builder.append("\";\n");
}
}

for export in &wasm_deps.exports {
let has_valid_export_ident = is_valid_ident(export.name);
let export_name = if has_valid_export_ident {
Cow::Borrowed(export.name)
} else {
let export_name =
format!("__deno_wasm_export_{}__", internal_names_count);
internal_names_count += 1;
Cow::Owned(export_name)
};
if has_valid_export_ident {
text.push_str("export ");
}
let mut add_var = |type_text: &str| {
text.push_str("declare const ");
text.push_str(&export_name);
text.push_str(": ");
text.push_str(type_text);
text.push_str(";\n");
};
for (i, export) in wasm_deps.exports.iter().enumerate() {
let has_valid_export_ident = is_valid_export_ident_per_export[i];
if has_valid_export_ident {
builder.append("export ");
}
fn write_export_name<'a>(
builder: &mut StringBuilder<'a>,
export: &'a wasm_dep_analyzer::Export<'a>,
has_valid_export_ident: bool,
index: usize,
) {
if has_valid_export_ident {
builder.append(export.name);
} else {
builder.append("__deno_wasm_export_");
builder.append(index);
builder.append("__");
}
}
let mut add_var = |type_text: &'static str| {
builder.append("declare const ");
write_export_name(builder, export, has_valid_export_ident, i);
builder.append(": ");
builder.append(type_text);
builder.append(";\n");
};

match &export.export_type {
wasm_dep_analyzer::ExportType::Function(function_signature) => {
match function_signature {
Ok(signature) => {
text.push_str("declare function ");
text.push_str(&export_name);
text.push('(');
for (i, param) in signature.params.iter().enumerate() {
if i > 0 {
text.push_str(", ");
match &export.export_type {
wasm_dep_analyzer::ExportType::Function(function_signature) => {
match function_signature {
Ok(signature) => {
builder.append("declare function ");
write_export_name(builder, export, has_valid_export_ident, i);
builder.append('(');
for (i, param) in signature.params.iter().enumerate() {
if i > 0 {
builder.append(", ");
}
builder.append("arg");
builder.append(i);
builder.append(": ");
builder
.append(value_type_to_ts_type(*param, TypePosition::Input));
}
text.push_str("arg");
text.push_str(i.to_string().as_str());
text.push_str(": ");
text.push_str(value_type_to_ts_type(*param, TypePosition::Input));
builder.append("): ");
builder.append(
signature
.returns
.first()
.map(|t| value_type_to_ts_type(*t, TypePosition::Output))
.unwrap_or("void"),
);
builder.append(";\n");
}
text.push_str("): ");
text.push_str(
signature
.returns
.first()
.map(|t| value_type_to_ts_type(*t, TypePosition::Output))
.unwrap_or("void"),
);
text.push_str(";\n");
Err(_) => add_var("unknown"),
}
Err(_) => add_var("unknown"),
}
wasm_dep_analyzer::ExportType::Table => add_var("WebAssembly.Table"),
wasm_dep_analyzer::ExportType::Memory => add_var("WebAssembly.Memory"),
wasm_dep_analyzer::ExportType::Global(global_type) => match global_type
{
Ok(global_type) => add_var(value_type_to_ts_type(
global_type.value_type,
TypePosition::Output,
)),
Err(_) => add_var("unknown"),
},
wasm_dep_analyzer::ExportType::Tag
| wasm_dep_analyzer::ExportType::Unknown => add_var("unknown"),
}
wasm_dep_analyzer::ExportType::Table => add_var("WebAssembly.Table"),
wasm_dep_analyzer::ExportType::Memory => add_var("WebAssembly.Memory"),
wasm_dep_analyzer::ExportType::Global(global_type) => match global_type {
Ok(global_type) => add_var(value_type_to_ts_type(
global_type.value_type,
TypePosition::Output,
)),
Err(_) => add_var("unknown"),
},
wasm_dep_analyzer::ExportType::Tag
| wasm_dep_analyzer::ExportType::Unknown => add_var("unknown"),
}

if !has_valid_export_ident {
text.push_str(&format!(
"export {{ {} as \"{}\" }};\n",
export_name, export.name
));
if !has_valid_export_ident {
builder.append("export { ");
write_export_name(builder, export, has_valid_export_ident, i);
builder.append(" as \"");
builder.append(export.name);
builder.append("\" };\n");
}
}
}
text
})
.unwrap()
}

#[cfg(test)]
Expand Down Expand Up @@ -220,10 +237,10 @@ export declare const name5: WebAssembly.Memory;
export declare const name6: number;
export declare const name7: unknown;
export declare const name8: unknown;
declare const __deno_wasm_export_1__: unknown;
export { __deno_wasm_export_1__ as \"name9--\" };
declare const __deno_wasm_export_2__: unknown;
export { __deno_wasm_export_2__ as \"default\" };
declare const __deno_wasm_export_8__: unknown;
export { __deno_wasm_export_8__ as \"name9--\" };
declare const __deno_wasm_export_9__: unknown;
export { __deno_wasm_export_9__ as \"default\" };
"
);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/specs/ecosystem/mrii/rocket_io/0_1_3.test
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ mrii/rocket-io/0.1.3

-- stderr --
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'
at Object.resolveModuleNames (ext:deno_tsc/99_main_compiler.js:742:28)
at actualResolveModuleNamesWorker (ext:deno_tsc/00_typescript.js:125027:142)
at Object.resolveModuleNameLiterals (ext:deno_tsc/99_main_compiler.js:768:28)
at resolveModuleNamesWorker (ext:deno_tsc/00_typescript.js:125466:20)
at resolveNamesReusingOldState (ext:deno_tsc/00_typescript.js:125608:14)
at resolveModuleNamesReusingOldState (ext:deno_tsc/00_typescript.js:125564:12)
Expand All @@ -83,4 +82,5 @@ error: Uncaught Error: [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './build/
at findSourceFile (ext:deno_tsc/00_typescript.js:126705:20)
at processImportedModules (ext:deno_tsc/00_typescript.js:127105:11)
at findSourceFileWorker (ext:deno_tsc/00_typescript.js:126854:7)
at findSourceFile (ext:deno_tsc/00_typescript.js:126705:20)

2 changes: 1 addition & 1 deletion tests/specs/graph/jsr/version_tag_not_supported.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import 'jsr:@scope/a@tag';
},
{
"specifier": "jsr:@scope/a@tag",
"error": "Version tag not supported in jsr specifiers."
"error": "Version tag not supported in jsr specifiers ('tag')."
}
],
"redirects": {}
Expand Down

0 comments on commit 7c13fa1

Please sign in to comment.