mirror of
https://github.com/denoland/deno.git
synced 2025-02-01 12:16:11 -05:00
fix(check): compiler options from workspace members (#27785)
Co-authored-by: Nayeem Rahman <nayeemrmn99@gmail.com>
This commit is contained in:
parent
9931fb5cad
commit
4648fc4570
163 changed files with 1681 additions and 716 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -1514,9 +1514,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_config"
|
||||
version = "0.45.0"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47a47412627aa0d08414eca0e8329128013ab70bdb2cdfdc5456c2214cf24c8f"
|
||||
checksum = "08fe512a72c4300bd997c6849450a1f050da0c909a2a4fbdc44891647392bacf"
|
||||
dependencies = [
|
||||
"boxed_error",
|
||||
"capacity_builder 0.5.0",
|
||||
|
@ -1782,9 +1782,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_graph"
|
||||
version = "0.87.0"
|
||||
version = "0.87.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f56d4eb4b7c81ae920b6d18c45a1866924f93110caee80bbbc362dc28143f2bb"
|
||||
checksum = "e4766f426e4258c481c3af019fb4bba31e3108e80b8b2a48bbeb68bfadcc8c18"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"capacity_builder 0.5.0",
|
||||
|
|
|
@ -54,7 +54,7 @@ deno_ast = { version = "=0.44.0", features = ["transpiling"] }
|
|||
deno_core = { version = "0.333.0" }
|
||||
|
||||
deno_bench_util = { version = "0.181.0", path = "./bench_util" }
|
||||
deno_config = { version = "=0.45.0", features = ["workspace"] }
|
||||
deno_config = { version = "=0.46.0", features = ["workspace"] }
|
||||
deno_lockfile = "=0.24.0"
|
||||
deno_media_type = { version = "=0.2.5", features = ["module_specifier"] }
|
||||
deno_npm = "=0.27.2"
|
||||
|
|
|
@ -72,7 +72,7 @@ deno_config = { workspace = true, features = ["sync", "workspace"] }
|
|||
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||
deno_doc = { version = "=0.164.0", features = ["rust", "comrak"] }
|
||||
deno_error.workspace = true
|
||||
deno_graph = { version = "=0.87.0" }
|
||||
deno_graph = { version = "=0.87.2" }
|
||||
deno_lib.workspace = true
|
||||
deno_lint = { version = "0.70.0" }
|
||||
deno_lockfile.workspace = true
|
||||
|
|
|
@ -1,12 +1,28 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_config::deno_json::TsConfigForEmit;
|
||||
use deno_ast::SourceMapOption;
|
||||
use deno_config::deno_json::CompilerOptionsParseError;
|
||||
use deno_config::deno_json::TsConfig;
|
||||
use deno_config::deno_json::TsConfigType;
|
||||
use deno_config::deno_json::TsConfigWithIgnoredOptions;
|
||||
use deno_config::deno_json::TsTypeLib;
|
||||
use deno_config::workspace::Workspace;
|
||||
use deno_config::workspace::WorkspaceDirectory;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::unsync::sync::AtomicFlag;
|
||||
use deno_core::url::Url;
|
||||
use deno_lib::util::hash::FastInsecureHasher;
|
||||
use deno_lint::linter::LintConfig as DenoLintConfig;
|
||||
use deno_semver::jsr::JsrDepPackageReq;
|
||||
use deno_semver::jsr::JsrPackageReqReference;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
use crate::util::collections::FolderScopedMap;
|
||||
|
||||
pub fn import_map_deps(
|
||||
import_map: &serde_json::Value,
|
||||
|
@ -102,17 +118,261 @@ fn value_to_dep_req(value: &str) -> Option<JsrDepPackageReq> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn check_warn_tsconfig(ts_config: &TsConfigForEmit) {
|
||||
if let Some(ignored_options) = &ts_config.maybe_ignored_options {
|
||||
log::warn!("{}", ignored_options);
|
||||
fn check_warn_tsconfig(
|
||||
ts_config: &TsConfigWithIgnoredOptions,
|
||||
logged_warnings: &LoggedWarnings,
|
||||
) {
|
||||
for ignored_options in &ts_config.ignored_options {
|
||||
if ignored_options
|
||||
.maybe_specifier
|
||||
.as_ref()
|
||||
.map(|s| logged_warnings.folders.insert(s.clone()))
|
||||
.unwrap_or(true)
|
||||
{
|
||||
log::warn!("{}", ignored_options);
|
||||
}
|
||||
}
|
||||
let serde_json::Value::Object(obj) = &ts_config.ts_config.0 else {
|
||||
return;
|
||||
};
|
||||
if obj.get("experimentalDecorators") == Some(&serde_json::Value::Bool(true)) {
|
||||
if obj.get("experimentalDecorators") == Some(&serde_json::Value::Bool(true))
|
||||
&& logged_warnings.experimental_decorators.raise()
|
||||
{
|
||||
log::warn!(
|
||||
"{} experimentalDecorators compiler option is deprecated and may be removed at any time",
|
||||
deno_runtime::colors::yellow("Warning"),
|
||||
);
|
||||
"{} experimentalDecorators compiler option is deprecated and may be removed at any time",
|
||||
deno_runtime::colors::yellow("Warning"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TranspileAndEmitOptions {
|
||||
pub transpile: deno_ast::TranspileOptions,
|
||||
pub emit: deno_ast::EmitOptions,
|
||||
// stored ahead of time so we don't have to recompute this a lot
|
||||
pub pre_computed_hash: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct LoggedWarnings {
|
||||
experimental_decorators: AtomicFlag,
|
||||
folders: dashmap::DashSet<Url>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
struct MemoizedValues {
|
||||
deno_window_check_tsconfig: OnceCell<Arc<TsConfig>>,
|
||||
deno_worker_check_tsconfig: OnceCell<Arc<TsConfig>>,
|
||||
emit_tsconfig: OnceCell<Arc<TsConfig>>,
|
||||
transpile_options: OnceCell<Arc<TranspileAndEmitOptions>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TsConfigFolderInfo {
|
||||
pub dir: WorkspaceDirectory,
|
||||
logged_warnings: Arc<LoggedWarnings>,
|
||||
memoized: MemoizedValues,
|
||||
}
|
||||
|
||||
impl TsConfigFolderInfo {
|
||||
pub fn lib_tsconfig(
|
||||
&self,
|
||||
lib: TsTypeLib,
|
||||
) -> Result<&Arc<TsConfig>, CompilerOptionsParseError> {
|
||||
let cell = match lib {
|
||||
TsTypeLib::DenoWindow => &self.memoized.deno_window_check_tsconfig,
|
||||
TsTypeLib::DenoWorker => &self.memoized.deno_worker_check_tsconfig,
|
||||
};
|
||||
|
||||
cell.get_or_try_init(|| {
|
||||
let tsconfig_result = self
|
||||
.dir
|
||||
.to_resolved_ts_config(TsConfigType::Check { lib })?;
|
||||
check_warn_tsconfig(&tsconfig_result, &self.logged_warnings);
|
||||
Ok(Arc::new(tsconfig_result.ts_config))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn emit_tsconfig(
|
||||
&self,
|
||||
) -> Result<&Arc<TsConfig>, CompilerOptionsParseError> {
|
||||
self.memoized.emit_tsconfig.get_or_try_init(|| {
|
||||
let tsconfig_result =
|
||||
self.dir.to_resolved_ts_config(TsConfigType::Emit)?;
|
||||
check_warn_tsconfig(&tsconfig_result, &self.logged_warnings);
|
||||
Ok(Arc::new(tsconfig_result.ts_config))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn transpile_options(
|
||||
&self,
|
||||
) -> Result<&Arc<TranspileAndEmitOptions>, CompilerOptionsParseError> {
|
||||
self.memoized.transpile_options.get_or_try_init(|| {
|
||||
let ts_config = self.emit_tsconfig()?;
|
||||
ts_config_to_transpile_and_emit_options(ts_config.as_ref().clone())
|
||||
.map(Arc::new)
|
||||
.map_err(|source| CompilerOptionsParseError {
|
||||
specifier: self
|
||||
.dir
|
||||
.maybe_deno_json()
|
||||
.map(|d| d.specifier.clone())
|
||||
.unwrap_or_else(|| {
|
||||
// will never happen because each dir should have a
|
||||
// deno.json if we got here
|
||||
debug_assert!(false);
|
||||
self.dir.dir_url().as_ref().clone()
|
||||
}),
|
||||
source,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TsConfigResolver {
|
||||
map: FolderScopedMap<TsConfigFolderInfo>,
|
||||
}
|
||||
|
||||
impl TsConfigResolver {
|
||||
pub fn from_workspace(workspace: &Arc<Workspace>) -> Self {
|
||||
// separate the workspace into directories that have a tsconfig
|
||||
let root_dir = workspace.resolve_member_dir(workspace.root_dir());
|
||||
let logged_warnings = Arc::new(LoggedWarnings::default());
|
||||
let mut map = FolderScopedMap::new(TsConfigFolderInfo {
|
||||
dir: root_dir,
|
||||
logged_warnings: logged_warnings.clone(),
|
||||
memoized: Default::default(),
|
||||
});
|
||||
for (url, folder) in workspace.config_folders() {
|
||||
let folder_has_compiler_options = folder
|
||||
.deno_json
|
||||
.as_ref()
|
||||
.map(|d| d.json.compiler_options.is_some())
|
||||
.unwrap_or(false);
|
||||
if url != workspace.root_dir() && folder_has_compiler_options {
|
||||
let dir = workspace.resolve_member_dir(url);
|
||||
map.insert(
|
||||
url.clone(),
|
||||
TsConfigFolderInfo {
|
||||
dir,
|
||||
logged_warnings: logged_warnings.clone(),
|
||||
memoized: Default::default(),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Self { map }
|
||||
}
|
||||
|
||||
pub fn check_js_for_specifier(&self, specifier: &Url) -> bool {
|
||||
self.folder_for_specifier(specifier).dir.check_js()
|
||||
}
|
||||
|
||||
pub fn deno_lint_config(
|
||||
&self,
|
||||
specifier: &Url,
|
||||
) -> Result<DenoLintConfig, AnyError> {
|
||||
let transpile_options =
|
||||
&self.transpile_and_emit_options(specifier)?.transpile;
|
||||
// don't bother storing this in a cell because deno_lint requires an owned value
|
||||
Ok(DenoLintConfig {
|
||||
default_jsx_factory: (!transpile_options.jsx_automatic)
|
||||
.then(|| transpile_options.jsx_factory.clone()),
|
||||
default_jsx_fragment_factory: (!transpile_options.jsx_automatic)
|
||||
.then(|| transpile_options.jsx_fragment_factory.clone()),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn transpile_and_emit_options(
|
||||
&self,
|
||||
specifier: &Url,
|
||||
) -> Result<&Arc<TranspileAndEmitOptions>, CompilerOptionsParseError> {
|
||||
let value = self.map.get_for_specifier(specifier);
|
||||
value.transpile_options()
|
||||
}
|
||||
|
||||
pub fn folder_for_specifier(&self, specifier: &Url) -> &TsConfigFolderInfo {
|
||||
self.folder_for_specifier_str(specifier.as_str())
|
||||
}
|
||||
|
||||
pub fn folder_for_specifier_str(
|
||||
&self,
|
||||
specifier: &str,
|
||||
) -> &TsConfigFolderInfo {
|
||||
self.map.get_for_specifier_str(specifier)
|
||||
}
|
||||
|
||||
pub fn folder_count(&self) -> usize {
|
||||
self.map.count()
|
||||
}
|
||||
}
|
||||
|
||||
impl deno_graph::CheckJsResolver for TsConfigResolver {
|
||||
fn resolve(&self, specifier: &deno_graph::ModuleSpecifier) -> bool {
|
||||
self.check_js_for_specifier(specifier)
|
||||
}
|
||||
}
|
||||
|
||||
fn ts_config_to_transpile_and_emit_options(
|
||||
config: deno_config::deno_json::TsConfig,
|
||||
) -> Result<TranspileAndEmitOptions, serde_json::Error> {
|
||||
let options: deno_config::deno_json::EmitConfigOptions =
|
||||
serde_json::from_value(config.0)?;
|
||||
let imports_not_used_as_values =
|
||||
match options.imports_not_used_as_values.as_str() {
|
||||
"preserve" => deno_ast::ImportsNotUsedAsValues::Preserve,
|
||||
"error" => deno_ast::ImportsNotUsedAsValues::Error,
|
||||
_ => deno_ast::ImportsNotUsedAsValues::Remove,
|
||||
};
|
||||
let (transform_jsx, jsx_automatic, jsx_development, precompile_jsx) =
|
||||
match options.jsx.as_str() {
|
||||
"react" => (true, false, false, false),
|
||||
"react-jsx" => (true, true, false, false),
|
||||
"react-jsxdev" => (true, true, true, false),
|
||||
"precompile" => (false, false, false, true),
|
||||
_ => (false, false, false, false),
|
||||
};
|
||||
let source_map = if options.inline_source_map {
|
||||
SourceMapOption::Inline
|
||||
} else if options.source_map {
|
||||
SourceMapOption::Separate
|
||||
} else {
|
||||
SourceMapOption::None
|
||||
};
|
||||
let transpile = deno_ast::TranspileOptions {
|
||||
use_ts_decorators: options.experimental_decorators,
|
||||
use_decorators_proposal: !options.experimental_decorators,
|
||||
emit_metadata: options.emit_decorator_metadata,
|
||||
imports_not_used_as_values,
|
||||
jsx_automatic,
|
||||
jsx_development,
|
||||
jsx_factory: options.jsx_factory,
|
||||
jsx_fragment_factory: options.jsx_fragment_factory,
|
||||
jsx_import_source: options.jsx_import_source,
|
||||
precompile_jsx,
|
||||
precompile_jsx_skip_elements: options.jsx_precompile_skip_elements,
|
||||
precompile_jsx_dynamic_props: None,
|
||||
transform_jsx,
|
||||
var_decl_imports: false,
|
||||
// todo(dsherret): support verbatim_module_syntax here properly
|
||||
verbatim_module_syntax: false,
|
||||
};
|
||||
let emit = deno_ast::EmitOptions {
|
||||
inline_sources: options.inline_sources,
|
||||
remove_comments: false,
|
||||
source_map,
|
||||
source_map_base: None,
|
||||
source_map_file: None,
|
||||
};
|
||||
let transpile_and_emit_options_hash = {
|
||||
let mut hasher = FastInsecureHasher::new_without_deno_version();
|
||||
hasher.write_hashable(&transpile);
|
||||
hasher.write_hashable(&emit);
|
||||
hasher.finish()
|
||||
};
|
||||
Ok(TranspileAndEmitOptions {
|
||||
transpile,
|
||||
emit,
|
||||
pre_computed_hash: transpile_and_emit_options_hash,
|
||||
})
|
||||
}
|
||||
|
|
107
cli/args/mod.rs
107
cli/args/mod.rs
|
@ -17,11 +17,9 @@ use std::sync::Arc;
|
|||
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_ast::SourceMapOption;
|
||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||
pub use deno_config::deno_json::BenchConfig;
|
||||
pub use deno_config::deno_json::ConfigFile;
|
||||
use deno_config::deno_json::ConfigFileError;
|
||||
use deno_config::deno_json::FmtConfig;
|
||||
pub use deno_config::deno_json::FmtOptionsConfig;
|
||||
use deno_config::deno_json::LintConfig;
|
||||
|
@ -30,8 +28,6 @@ use deno_config::deno_json::NodeModulesDirMode;
|
|||
pub use deno_config::deno_json::ProseWrap;
|
||||
use deno_config::deno_json::TestConfig;
|
||||
pub use deno_config::deno_json::TsConfig;
|
||||
pub use deno_config::deno_json::TsConfigForEmit;
|
||||
pub use deno_config::deno_json::TsConfigType;
|
||||
pub use deno_config::deno_json::TsTypeLib;
|
||||
pub use deno_config::glob::FilePatterns;
|
||||
use deno_config::workspace::Workspace;
|
||||
|
@ -44,14 +40,12 @@ use deno_core::resolve_url_or_path;
|
|||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
use deno_graph::GraphKind;
|
||||
pub use deno_json::check_warn_tsconfig;
|
||||
use deno_lib::args::has_flag_env_var;
|
||||
use deno_lib::args::npm_pkg_req_ref_to_binary_command;
|
||||
use deno_lib::args::CaData;
|
||||
use deno_lib::args::NPM_PROCESS_STATE;
|
||||
use deno_lib::version::DENO_VERSION_INFO;
|
||||
use deno_lib::worker::StorageKeyResolver;
|
||||
use deno_lint::linter::LintConfig as DenoLintConfig;
|
||||
use deno_npm::NpmSystemInfo;
|
||||
use deno_runtime::deno_permissions::PermissionsOptions;
|
||||
use deno_runtime::inspector_server::InspectorServer;
|
||||
|
@ -114,62 +108,6 @@ pub fn jsr_api_url() -> &'static Url {
|
|||
&JSR_API_URL
|
||||
}
|
||||
|
||||
pub fn ts_config_to_transpile_and_emit_options(
|
||||
config: deno_config::deno_json::TsConfig,
|
||||
) -> Result<(deno_ast::TranspileOptions, deno_ast::EmitOptions), AnyError> {
|
||||
let options: deno_config::deno_json::EmitConfigOptions =
|
||||
serde_json::from_value(config.0)
|
||||
.context("Failed to parse compilerOptions")?;
|
||||
let imports_not_used_as_values =
|
||||
match options.imports_not_used_as_values.as_str() {
|
||||
"preserve" => deno_ast::ImportsNotUsedAsValues::Preserve,
|
||||
"error" => deno_ast::ImportsNotUsedAsValues::Error,
|
||||
_ => deno_ast::ImportsNotUsedAsValues::Remove,
|
||||
};
|
||||
let (transform_jsx, jsx_automatic, jsx_development, precompile_jsx) =
|
||||
match options.jsx.as_str() {
|
||||
"react" => (true, false, false, false),
|
||||
"react-jsx" => (true, true, false, false),
|
||||
"react-jsxdev" => (true, true, true, false),
|
||||
"precompile" => (false, false, false, true),
|
||||
_ => (false, false, false, false),
|
||||
};
|
||||
let source_map = if options.inline_source_map {
|
||||
SourceMapOption::Inline
|
||||
} else if options.source_map {
|
||||
SourceMapOption::Separate
|
||||
} else {
|
||||
SourceMapOption::None
|
||||
};
|
||||
Ok((
|
||||
deno_ast::TranspileOptions {
|
||||
use_ts_decorators: options.experimental_decorators,
|
||||
use_decorators_proposal: !options.experimental_decorators,
|
||||
emit_metadata: options.emit_decorator_metadata,
|
||||
imports_not_used_as_values,
|
||||
jsx_automatic,
|
||||
jsx_development,
|
||||
jsx_factory: options.jsx_factory,
|
||||
jsx_fragment_factory: options.jsx_fragment_factory,
|
||||
jsx_import_source: options.jsx_import_source,
|
||||
precompile_jsx,
|
||||
precompile_jsx_skip_elements: options.jsx_precompile_skip_elements,
|
||||
precompile_jsx_dynamic_props: None,
|
||||
transform_jsx,
|
||||
var_decl_imports: false,
|
||||
// todo(dsherret): support verbatim_module_syntax here properly
|
||||
verbatim_module_syntax: false,
|
||||
},
|
||||
deno_ast::EmitOptions {
|
||||
inline_sources: options.inline_sources,
|
||||
remove_comments: false,
|
||||
source_map,
|
||||
source_map_base: None,
|
||||
source_map_file: None,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ExternalImportMap {
|
||||
pub path: PathBuf,
|
||||
|
@ -751,13 +689,6 @@ impl CliOptions {
|
|||
self.workspace().vendor_dir_path()
|
||||
}
|
||||
|
||||
pub fn resolve_ts_config_for_emit(
|
||||
&self,
|
||||
config_type: TsConfigType,
|
||||
) -> Result<TsConfigForEmit, ConfigFileError> {
|
||||
self.workspace().resolve_ts_config_for_emit(config_type)
|
||||
}
|
||||
|
||||
pub fn resolve_inspector_server(
|
||||
&self,
|
||||
) -> Result<Option<InspectorServer>, AnyError> {
|
||||
|
@ -781,23 +712,6 @@ impl CliOptions {
|
|||
self.maybe_lockfile.as_ref()
|
||||
}
|
||||
|
||||
pub fn to_compiler_option_types(
|
||||
&self,
|
||||
) -> Result<Vec<deno_graph::ReferrerImports>, serde_json::Error> {
|
||||
self
|
||||
.workspace()
|
||||
.to_compiler_option_types()
|
||||
.map(|maybe_imports| {
|
||||
maybe_imports
|
||||
.into_iter()
|
||||
.map(|(referrer, imports)| deno_graph::ReferrerImports {
|
||||
referrer,
|
||||
imports,
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn resolve_fmt_options_for_members(
|
||||
&self,
|
||||
fmt_flags: &FmtFlags,
|
||||
|
@ -849,23 +763,6 @@ impl CliOptions {
|
|||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn resolve_deno_lint_config(&self) -> Result<DenoLintConfig, AnyError> {
|
||||
let ts_config_result =
|
||||
self.resolve_ts_config_for_emit(TsConfigType::Emit)?;
|
||||
|
||||
let (transpile_options, _) =
|
||||
crate::args::ts_config_to_transpile_and_emit_options(
|
||||
ts_config_result.ts_config,
|
||||
)?;
|
||||
|
||||
Ok(DenoLintConfig {
|
||||
default_jsx_factory: (!transpile_options.jsx_automatic)
|
||||
.then_some(transpile_options.jsx_factory),
|
||||
default_jsx_fragment_factory: (!transpile_options.jsx_automatic)
|
||||
.then_some(transpile_options.jsx_fragment_factory),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn resolve_workspace_test_options(
|
||||
&self,
|
||||
test_flags: &TestFlags,
|
||||
|
@ -927,10 +824,6 @@ impl CliOptions {
|
|||
&self.flags.ca_stores
|
||||
}
|
||||
|
||||
pub fn check_js(&self) -> bool {
|
||||
self.workspace().check_js()
|
||||
}
|
||||
|
||||
pub fn coverage_dir(&self) -> Option<String> {
|
||||
match &self.flags.subcommand {
|
||||
DenoSubcommand::Test(test) => test
|
||||
|
|
95
cli/emit.rs
95
cli/emit.rs
|
@ -22,6 +22,8 @@ use deno_graph::Module;
|
|||
use deno_graph::ModuleGraph;
|
||||
use deno_lib::util::hash::FastInsecureHasher;
|
||||
|
||||
use crate::args::deno_json::TranspileAndEmitOptions;
|
||||
use crate::args::deno_json::TsConfigResolver;
|
||||
use crate::cache::EmitCache;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
use crate::resolver::CliCjsTracker;
|
||||
|
@ -31,10 +33,7 @@ pub struct Emitter {
|
|||
cjs_tracker: Arc<CliCjsTracker>,
|
||||
emit_cache: Arc<EmitCache>,
|
||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||
transpile_and_emit_options:
|
||||
Arc<(deno_ast::TranspileOptions, deno_ast::EmitOptions)>,
|
||||
// cached hash of the transpile and emit options
|
||||
transpile_and_emit_options_hash: u64,
|
||||
tsconfig_resolver: Arc<TsConfigResolver>,
|
||||
}
|
||||
|
||||
impl Emitter {
|
||||
|
@ -42,21 +41,13 @@ impl Emitter {
|
|||
cjs_tracker: Arc<CliCjsTracker>,
|
||||
emit_cache: Arc<EmitCache>,
|
||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||
transpile_options: deno_ast::TranspileOptions,
|
||||
emit_options: deno_ast::EmitOptions,
|
||||
tsconfig_resolver: Arc<TsConfigResolver>,
|
||||
) -> Self {
|
||||
let transpile_and_emit_options_hash = {
|
||||
let mut hasher = FastInsecureHasher::new_without_deno_version();
|
||||
hasher.write_hashable(&transpile_options);
|
||||
hasher.write_hashable(&emit_options);
|
||||
hasher.finish()
|
||||
};
|
||||
Self {
|
||||
cjs_tracker,
|
||||
emit_cache,
|
||||
parsed_source_cache,
|
||||
transpile_and_emit_options: Arc::new((transpile_options, emit_options)),
|
||||
transpile_and_emit_options_hash,
|
||||
tsconfig_resolver,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,9 +94,13 @@ impl Emitter {
|
|||
specifier: &ModuleSpecifier,
|
||||
module_kind: deno_ast::ModuleKind,
|
||||
source: &str,
|
||||
) -> Option<String> {
|
||||
let source_hash = self.get_source_hash(module_kind, source);
|
||||
self.emit_cache.get_emit_code(specifier, source_hash)
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
let transpile_and_emit_options = self
|
||||
.tsconfig_resolver
|
||||
.transpile_and_emit_options(specifier)?;
|
||||
let source_hash =
|
||||
self.get_source_hash(module_kind, transpile_and_emit_options, source);
|
||||
Ok(self.emit_cache.get_emit_code(specifier, source_hash))
|
||||
}
|
||||
|
||||
pub async fn emit_parsed_source(
|
||||
|
@ -115,14 +110,21 @@ impl Emitter {
|
|||
module_kind: ModuleKind,
|
||||
source: &Arc<str>,
|
||||
) -> Result<String, EmitParsedSourceHelperError> {
|
||||
let transpile_and_emit_options = self
|
||||
.tsconfig_resolver
|
||||
.transpile_and_emit_options(specifier)?;
|
||||
// Note: keep this in sync with the sync version below
|
||||
let helper = EmitParsedSourceHelper(self);
|
||||
match helper.pre_emit_parsed_source(specifier, module_kind, source) {
|
||||
match helper.pre_emit_parsed_source(
|
||||
specifier,
|
||||
module_kind,
|
||||
transpile_and_emit_options,
|
||||
source,
|
||||
) {
|
||||
PreEmitResult::Cached(emitted_text) => Ok(emitted_text),
|
||||
PreEmitResult::NotCached { source_hash } => {
|
||||
let parsed_source_cache = self.parsed_source_cache.clone();
|
||||
let transpile_and_emit_options =
|
||||
self.transpile_and_emit_options.clone();
|
||||
let transpile_and_emit_options = transpile_and_emit_options.clone();
|
||||
let transpiled_source = deno_core::unsync::spawn_blocking({
|
||||
let specifier = specifier.clone();
|
||||
let source = source.clone();
|
||||
|
@ -133,8 +135,8 @@ impl Emitter {
|
|||
media_type,
|
||||
module_kind,
|
||||
source.clone(),
|
||||
&transpile_and_emit_options.0,
|
||||
&transpile_and_emit_options.1,
|
||||
&transpile_and_emit_options.transpile,
|
||||
&transpile_and_emit_options.emit,
|
||||
)
|
||||
.map(|r| r.text)
|
||||
}
|
||||
|
@ -158,9 +160,17 @@ impl Emitter {
|
|||
module_kind: deno_ast::ModuleKind,
|
||||
source: &Arc<str>,
|
||||
) -> Result<String, EmitParsedSourceHelperError> {
|
||||
let transpile_and_emit_options = self
|
||||
.tsconfig_resolver
|
||||
.transpile_and_emit_options(specifier)?;
|
||||
// Note: keep this in sync with the async version above
|
||||
let helper = EmitParsedSourceHelper(self);
|
||||
match helper.pre_emit_parsed_source(specifier, module_kind, source) {
|
||||
match helper.pre_emit_parsed_source(
|
||||
specifier,
|
||||
module_kind,
|
||||
transpile_and_emit_options,
|
||||
source,
|
||||
) {
|
||||
PreEmitResult::Cached(emitted_text) => Ok(emitted_text),
|
||||
PreEmitResult::NotCached { source_hash } => {
|
||||
let transpiled_source = EmitParsedSourceHelper::transpile(
|
||||
|
@ -169,8 +179,8 @@ impl Emitter {
|
|||
media_type,
|
||||
module_kind,
|
||||
source.clone(),
|
||||
&self.transpile_and_emit_options.0,
|
||||
&self.transpile_and_emit_options.1,
|
||||
&transpile_and_emit_options.transpile,
|
||||
&transpile_and_emit_options.emit,
|
||||
)?
|
||||
.text;
|
||||
helper.post_emit_parsed_source(
|
||||
|
@ -190,7 +200,10 @@ impl Emitter {
|
|||
module_kind: deno_ast::ModuleKind,
|
||||
source: &Arc<str>,
|
||||
) -> Result<(String, String), AnyError> {
|
||||
let mut emit_options = self.transpile_and_emit_options.1.clone();
|
||||
let transpile_and_emit_options = self
|
||||
.tsconfig_resolver
|
||||
.transpile_and_emit_options(specifier)?;
|
||||
let mut emit_options = transpile_and_emit_options.emit.clone();
|
||||
emit_options.inline_sources = false;
|
||||
emit_options.source_map = SourceMapOption::Separate;
|
||||
// strip off the path to have more deterministic builds as we don't care
|
||||
|
@ -202,7 +215,7 @@ impl Emitter {
|
|||
media_type,
|
||||
module_kind,
|
||||
source.clone(),
|
||||
&self.transpile_and_emit_options.0,
|
||||
&transpile_and_emit_options.transpile,
|
||||
&emit_options,
|
||||
)?;
|
||||
Ok((source.text, source.source_map.unwrap()))
|
||||
|
@ -232,7 +245,11 @@ impl Emitter {
|
|||
// HMR doesn't work with embedded source maps for some reason, so set
|
||||
// the option to not use them (though you should test this out because
|
||||
// this statement is probably wrong)
|
||||
let mut options = self.transpile_and_emit_options.1.clone();
|
||||
let transpile_and_emit_options = self
|
||||
.tsconfig_resolver
|
||||
.transpile_and_emit_options(specifier)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
let mut options = transpile_and_emit_options.emit.clone();
|
||||
options.source_map = SourceMapOption::None;
|
||||
let is_cjs = self
|
||||
.cjs_tracker
|
||||
|
@ -244,7 +261,7 @@ impl Emitter {
|
|||
.map_err(JsErrorBox::from_err)?;
|
||||
let transpiled_source = parsed_source
|
||||
.transpile(
|
||||
&self.transpile_and_emit_options.0,
|
||||
&transpile_and_emit_options.transpile,
|
||||
&deno_ast::TranspileModuleOptions {
|
||||
module_kind: Some(ModuleKind::from_is_cjs(is_cjs)),
|
||||
},
|
||||
|
@ -275,10 +292,15 @@ impl Emitter {
|
|||
/// A hashing function that takes the source code and uses the global emit
|
||||
/// options then generates a string hash which can be stored to
|
||||
/// determine if the cached emit is valid or not.
|
||||
fn get_source_hash(&self, module_kind: ModuleKind, source_text: &str) -> u64 {
|
||||
fn get_source_hash(
|
||||
&self,
|
||||
module_kind: ModuleKind,
|
||||
transpile_and_emit: &TranspileAndEmitOptions,
|
||||
source_text: &str,
|
||||
) -> u64 {
|
||||
FastInsecureHasher::new_without_deno_version() // stored in the transpile_and_emit_options_hash
|
||||
.write_str(source_text)
|
||||
.write_u64(self.transpile_and_emit_options_hash)
|
||||
.write_u64(transpile_and_emit.pre_computed_hash)
|
||||
.write_hashable(module_kind)
|
||||
.finish()
|
||||
}
|
||||
|
@ -291,6 +313,11 @@ enum PreEmitResult {
|
|||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum EmitParsedSourceHelperError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
CompilerOptionsParse(
|
||||
#[from] deno_config::deno_json::CompilerOptionsParseError,
|
||||
),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ParseDiagnostic(#[from] deno_ast::ParseDiagnostic),
|
||||
|
@ -310,9 +337,13 @@ impl<'a> EmitParsedSourceHelper<'a> {
|
|||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
module_kind: deno_ast::ModuleKind,
|
||||
transpile_and_emit_options: &TranspileAndEmitOptions,
|
||||
source: &Arc<str>,
|
||||
) -> PreEmitResult {
|
||||
let source_hash = self.0.get_source_hash(module_kind, source);
|
||||
let source_hash =
|
||||
self
|
||||
.0
|
||||
.get_source_hash(module_kind, transpile_and_emit_options, source);
|
||||
|
||||
if let Some(emit_code) =
|
||||
self.0.emit_cache.get_emit_code(specifier, source_hash)
|
||||
|
|
|
@ -7,6 +7,7 @@ use std::path::PathBuf;
|
|||
use std::sync::Arc;
|
||||
|
||||
use deno_cache_dir::npm::NpmCacheDir;
|
||||
use deno_config::workspace::Workspace;
|
||||
use deno_config::workspace::WorkspaceDirectory;
|
||||
use deno_config::workspace::WorkspaceResolver;
|
||||
use deno_core::anyhow::Context;
|
||||
|
@ -50,13 +51,12 @@ use node_resolver::analyze::NodeCodeTranslator;
|
|||
use once_cell::sync::OnceCell;
|
||||
use sys_traits::EnvCurrentDir;
|
||||
|
||||
use crate::args::check_warn_tsconfig;
|
||||
use crate::args::deno_json::TsConfigResolver;
|
||||
use crate::args::CliOptions;
|
||||
use crate::args::ConfigFlag;
|
||||
use crate::args::DenoSubcommand;
|
||||
use crate::args::Flags;
|
||||
use crate::args::NpmInstallDepsProvider;
|
||||
use crate::args::TsConfigType;
|
||||
use crate::args::WorkspaceExternalImportMapLoader;
|
||||
use crate::cache::Caches;
|
||||
use crate::cache::CodeCache;
|
||||
|
@ -296,6 +296,7 @@ struct CliFactoryServices {
|
|||
root_cert_store_provider: Deferred<Arc<dyn RootCertStoreProvider>>,
|
||||
root_permissions_container: Deferred<PermissionsContainer>,
|
||||
text_only_progress_bar: Deferred<ProgressBar>,
|
||||
tsconfig_resolver: Deferred<Arc<TsConfigResolver>>,
|
||||
type_checker: Deferred<Arc<TypeChecker>>,
|
||||
workspace_factory: Deferred<Arc<CliWorkspaceFactory>>,
|
||||
workspace_external_import_map_loader:
|
||||
|
@ -675,6 +676,10 @@ impl CliFactory {
|
|||
self.resolver_factory()?.sloppy_imports_resolver()
|
||||
}
|
||||
|
||||
pub fn workspace(&self) -> Result<&Arc<Workspace>, AnyError> {
|
||||
Ok(&self.workspace_directory()?.workspace)
|
||||
}
|
||||
|
||||
pub fn workspace_directory(
|
||||
&self,
|
||||
) -> Result<&Arc<WorkspaceDirectory>, AnyError> {
|
||||
|
@ -773,20 +778,11 @@ impl CliFactory {
|
|||
|
||||
pub fn emitter(&self) -> Result<&Arc<Emitter>, AnyError> {
|
||||
self.services.emitter.get_or_try_init(|| {
|
||||
let cli_options = self.cli_options()?;
|
||||
let ts_config_result =
|
||||
cli_options.resolve_ts_config_for_emit(TsConfigType::Emit)?;
|
||||
check_warn_tsconfig(&ts_config_result);
|
||||
let (transpile_options, emit_options) =
|
||||
crate::args::ts_config_to_transpile_and_emit_options(
|
||||
ts_config_result.ts_config,
|
||||
)?;
|
||||
Ok(Arc::new(Emitter::new(
|
||||
self.cjs_tracker()?.clone(),
|
||||
self.emit_cache()?.clone(),
|
||||
self.parsed_source_cache().clone(),
|
||||
transpile_options,
|
||||
emit_options,
|
||||
self.tsconfig_resolver()?.clone(),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
@ -857,6 +853,13 @@ impl CliFactory {
|
|||
Ok(self.resolver_factory()?.pkg_json_resolver())
|
||||
}
|
||||
|
||||
pub fn tsconfig_resolver(&self) -> Result<&Arc<TsConfigResolver>, AnyError> {
|
||||
self.services.tsconfig_resolver.get_or_try_init(|| {
|
||||
let workspace = self.workspace()?;
|
||||
Ok(Arc::new(TsConfigResolver::from_workspace(workspace)))
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn type_checker(&self) -> Result<&Arc<TypeChecker>, AnyError> {
|
||||
self
|
||||
.services
|
||||
|
@ -875,6 +878,7 @@ impl CliFactory {
|
|||
self.npm_installer_if_managed()?.cloned(),
|
||||
self.npm_resolver().await?.clone(),
|
||||
self.sys(),
|
||||
self.tsconfig_resolver()?.clone(),
|
||||
)))
|
||||
})
|
||||
.await
|
||||
|
@ -905,6 +909,7 @@ impl CliFactory {
|
|||
self.resolver().await?.clone(),
|
||||
self.root_permissions_container()?.clone(),
|
||||
self.sys(),
|
||||
self.tsconfig_resolver()?.clone(),
|
||||
)))
|
||||
})
|
||||
.await
|
||||
|
|
|
@ -585,7 +585,7 @@ mod tests {
|
|||
// in deno_graph
|
||||
async fn test_fetch_remote_encoded(
|
||||
fixture: &str,
|
||||
charset: &str,
|
||||
expected_charset: &str,
|
||||
expected: &str,
|
||||
) {
|
||||
let url_str = format!("http://127.0.0.1:4545/encoding/{fixture}");
|
||||
|
@ -597,15 +597,20 @@ mod tests {
|
|||
Some(&headers),
|
||||
);
|
||||
assert_eq!(
|
||||
deno_graph::source::decode_source(&specifier, file.source, maybe_charset)
|
||||
.unwrap()
|
||||
.as_ref(),
|
||||
deno_media_type::encoding::decode_arc_source(
|
||||
maybe_charset.unwrap_or_else(|| {
|
||||
deno_media_type::encoding::detect_charset(&specifier, &file.source)
|
||||
}),
|
||||
file.source
|
||||
)
|
||||
.unwrap()
|
||||
.as_ref(),
|
||||
expected
|
||||
);
|
||||
assert_eq!(media_type, MediaType::TypeScript);
|
||||
assert_eq!(
|
||||
headers.get("content-type").unwrap(),
|
||||
&format!("application/typescript;charset={charset}")
|
||||
&format!("application/typescript;charset={expected_charset}")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -614,9 +619,12 @@ mod tests {
|
|||
let specifier = ModuleSpecifier::from_file_path(p).unwrap();
|
||||
let (file, _) = test_fetch(&specifier).await;
|
||||
assert_eq!(
|
||||
deno_graph::source::decode_source(&specifier, file.source, None)
|
||||
.unwrap()
|
||||
.as_ref(),
|
||||
deno_media_type::encoding::decode_arc_source(
|
||||
deno_media_type::encoding::detect_charset(&specifier, &file.source),
|
||||
file.source
|
||||
)
|
||||
.unwrap()
|
||||
.as_ref(),
|
||||
expected
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashSet;
|
||||
use std::error::Error;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_config::deno_json;
|
||||
use deno_config::deno_json::CompilerOptionTypesDeserializeError;
|
||||
use deno_config::deno_json::JsxImportSourceConfig;
|
||||
use deno_config::deno_json::NodeModulesDirMode;
|
||||
use deno_config::workspace::JsrPackageConfig;
|
||||
|
@ -19,6 +21,7 @@ use deno_graph::source::Loader;
|
|||
use deno_graph::source::LoaderChecksum;
|
||||
use deno_graph::source::ResolutionKind;
|
||||
use deno_graph::source::ResolveError;
|
||||
use deno_graph::CheckJsOption;
|
||||
use deno_graph::FillFromLockfileOptions;
|
||||
use deno_graph::GraphKind;
|
||||
use deno_graph::JsrLoadError;
|
||||
|
@ -40,6 +43,7 @@ use deno_semver::package::PackageNv;
|
|||
use deno_semver::SmallStackString;
|
||||
|
||||
use crate::args::config_to_deno_graph_workspace_member;
|
||||
use crate::args::deno_json::TsConfigResolver;
|
||||
use crate::args::jsr_url;
|
||||
use crate::args::CliLockfile;
|
||||
use crate::args::CliOptions;
|
||||
|
@ -67,8 +71,8 @@ use crate::util::file_watcher::WatcherCommunicator;
|
|||
use crate::util::fs::canonicalize_path;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GraphValidOptions {
|
||||
pub check_js: bool,
|
||||
pub struct GraphValidOptions<'a> {
|
||||
pub check_js: CheckJsOption<'a>,
|
||||
pub kind: GraphKind,
|
||||
/// Whether to exit the process for integrity check errors such as
|
||||
/// lockfile checksum mismatches and JSR integrity failures.
|
||||
|
@ -136,8 +140,8 @@ pub fn fill_graph_from_lockfile(
|
|||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GraphWalkErrorsOptions {
|
||||
pub check_js: bool,
|
||||
pub struct GraphWalkErrorsOptions<'a> {
|
||||
pub check_js: CheckJsOption<'a>,
|
||||
pub kind: GraphKind,
|
||||
}
|
||||
|
||||
|
@ -147,7 +151,7 @@ pub fn graph_walk_errors<'a>(
|
|||
graph: &'a ModuleGraph,
|
||||
sys: &'a CliSys,
|
||||
roots: &'a [ModuleSpecifier],
|
||||
options: GraphWalkErrorsOptions,
|
||||
options: GraphWalkErrorsOptions<'a>,
|
||||
) -> impl Iterator<Item = JsErrorBox> + 'a {
|
||||
graph
|
||||
.walk(
|
||||
|
@ -455,7 +459,6 @@ impl ModuleGraphCreator {
|
|||
check::CheckOptions {
|
||||
build_fast_check_graph: true,
|
||||
lib: self.options.ts_type_lib_window(),
|
||||
log_ignored_options: true,
|
||||
reload: self.options.reload_flag(),
|
||||
type_check_mode: self.options.type_check_mode(),
|
||||
},
|
||||
|
@ -472,6 +475,9 @@ pub struct BuildFastCheckGraphOptions<'a> {
|
|||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum BuildGraphWithNpmResolutionError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
CompilerOptionTypesDeserialize(#[from] CompilerOptionTypesDeserializeError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
SerdeJson(#[from] serde_json::Error),
|
||||
|
@ -508,6 +514,7 @@ pub struct ModuleGraphBuilder {
|
|||
resolver: Arc<CliResolver>,
|
||||
root_permissions_container: PermissionsContainer,
|
||||
sys: CliSys,
|
||||
tsconfig_resolver: Arc<TsConfigResolver>,
|
||||
}
|
||||
|
||||
impl ModuleGraphBuilder {
|
||||
|
@ -529,6 +536,7 @@ impl ModuleGraphBuilder {
|
|||
resolver: Arc<CliResolver>,
|
||||
root_permissions_container: PermissionsContainer,
|
||||
sys: CliSys,
|
||||
tsconfig_resolver: Arc<TsConfigResolver>,
|
||||
) -> Self {
|
||||
Self {
|
||||
caches,
|
||||
|
@ -547,6 +555,7 @@ impl ModuleGraphBuilder {
|
|||
resolver,
|
||||
root_permissions_container,
|
||||
sys,
|
||||
tsconfig_resolver,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -631,7 +640,16 @@ impl ModuleGraphBuilder {
|
|||
}
|
||||
|
||||
let maybe_imports = if options.graph_kind.include_types() {
|
||||
self.cli_options.to_compiler_option_types()?
|
||||
// Resolve all the imports from every deno.json. We'll separate
|
||||
// them later based on the folder we're type checking.
|
||||
let mut imports = Vec::new();
|
||||
for deno_json in self.cli_options.workspace().deno_jsons() {
|
||||
let maybe_imports = deno_json.to_compiler_option_types()?;
|
||||
imports.extend(maybe_imports.into_iter().map(|(referrer, imports)| {
|
||||
deno_graph::ReferrerImports { referrer, imports }
|
||||
}));
|
||||
}
|
||||
imports
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
@ -847,7 +865,7 @@ impl ModuleGraphBuilder {
|
|||
} else {
|
||||
GraphKind::CodeOnly
|
||||
},
|
||||
check_js: self.cli_options.check_js(),
|
||||
check_js: CheckJsOption::Custom(self.tsconfig_resolver.as_ref()),
|
||||
exit_integrity_errors: true,
|
||||
},
|
||||
)
|
||||
|
@ -857,14 +875,23 @@ impl ModuleGraphBuilder {
|
|||
&self,
|
||||
) -> Result<CliGraphResolver, deno_json::ToMaybeJsxImportSourceConfigError>
|
||||
{
|
||||
let jsx_import_source_config = self
|
||||
let jsx_import_source_config_unscoped = self
|
||||
.cli_options
|
||||
.workspace()
|
||||
.start_dir
|
||||
.to_maybe_jsx_import_source_config()?;
|
||||
let mut jsx_import_source_config_by_scope = BTreeMap::default();
|
||||
for (dir_url, _) in self.cli_options.workspace().config_folders() {
|
||||
let dir = self.cli_options.workspace().resolve_member_dir(dir_url);
|
||||
let jsx_import_source_config_unscoped =
|
||||
dir.to_maybe_jsx_import_source_config()?;
|
||||
jsx_import_source_config_by_scope
|
||||
.insert(dir_url.clone(), jsx_import_source_config_unscoped);
|
||||
}
|
||||
Ok(CliGraphResolver {
|
||||
cjs_tracker: &self.cjs_tracker,
|
||||
resolver: &self.resolver,
|
||||
jsx_import_source_config,
|
||||
jsx_import_source_config_unscoped,
|
||||
jsx_import_source_config_by_scope,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1100,7 +1127,7 @@ pub fn has_graph_root_local_dependent_changed(
|
|||
follow_dynamic: true,
|
||||
kind: GraphKind::All,
|
||||
prefer_fast_check_graph: true,
|
||||
check_js: true,
|
||||
check_js: CheckJsOption::True,
|
||||
},
|
||||
);
|
||||
while let Some((s, _)) = dependent_specifiers.next() {
|
||||
|
@ -1227,28 +1254,47 @@ fn format_deno_graph_error(err: &dyn Error) -> String {
|
|||
struct CliGraphResolver<'a> {
|
||||
cjs_tracker: &'a CliCjsTracker,
|
||||
resolver: &'a CliResolver,
|
||||
jsx_import_source_config: Option<JsxImportSourceConfig>,
|
||||
jsx_import_source_config_unscoped: Option<JsxImportSourceConfig>,
|
||||
jsx_import_source_config_by_scope:
|
||||
BTreeMap<Arc<ModuleSpecifier>, Option<JsxImportSourceConfig>>,
|
||||
}
|
||||
|
||||
impl<'a> CliGraphResolver<'a> {
|
||||
fn resolve_jsx_import_source_config(
|
||||
&self,
|
||||
referrer: &ModuleSpecifier,
|
||||
) -> Option<&JsxImportSourceConfig> {
|
||||
self
|
||||
.jsx_import_source_config_by_scope
|
||||
.iter()
|
||||
.rfind(|(s, _)| referrer.as_str().starts_with(s.as_str()))
|
||||
.map(|(_, c)| c.as_ref())
|
||||
.unwrap_or(self.jsx_import_source_config_unscoped.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> deno_graph::source::Resolver for CliGraphResolver<'a> {
|
||||
fn default_jsx_import_source(&self) -> Option<String> {
|
||||
fn default_jsx_import_source(
|
||||
&self,
|
||||
referrer: &ModuleSpecifier,
|
||||
) -> Option<String> {
|
||||
self
|
||||
.jsx_import_source_config
|
||||
.as_ref()
|
||||
.resolve_jsx_import_source_config(referrer)
|
||||
.and_then(|c| c.default_specifier.clone())
|
||||
}
|
||||
|
||||
fn default_jsx_import_source_types(&self) -> Option<String> {
|
||||
fn default_jsx_import_source_types(
|
||||
&self,
|
||||
referrer: &ModuleSpecifier,
|
||||
) -> Option<String> {
|
||||
self
|
||||
.jsx_import_source_config
|
||||
.as_ref()
|
||||
.resolve_jsx_import_source_config(referrer)
|
||||
.and_then(|c| c.default_types_specifier.clone())
|
||||
}
|
||||
|
||||
fn jsx_import_source_module(&self) -> &str {
|
||||
fn jsx_import_source_module(&self, referrer: &ModuleSpecifier) -> &str {
|
||||
self
|
||||
.jsx_import_source_config
|
||||
.as_ref()
|
||||
.resolve_jsx_import_source_config(referrer)
|
||||
.map(|c| c.module.as_str())
|
||||
.unwrap_or(deno_graph::source::DEFAULT_JSX_IMPORT_SOURCE_MODULE)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use std::hash::Hasher;
|
||||
|
||||
/// A very fast insecure hasher that uses the xxHash algorithm.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FastInsecureHasher(twox_hash::XxHash64);
|
||||
|
||||
impl FastInsecureHasher {
|
||||
|
|
|
@ -18,6 +18,7 @@ use deno_config::deno_json::LintConfig;
|
|||
use deno_config::deno_json::NodeModulesDirMode;
|
||||
use deno_config::deno_json::TestConfig;
|
||||
use deno_config::deno_json::TsConfig;
|
||||
use deno_config::deno_json::TsConfigWithIgnoredOptions;
|
||||
use deno_config::glob::FilePatterns;
|
||||
use deno_config::glob::PathOrPatternSet;
|
||||
use deno_config::workspace::CreateResolverOptions;
|
||||
|
@ -1168,14 +1169,13 @@ impl Default for LspTsConfig {
|
|||
}
|
||||
|
||||
impl LspTsConfig {
|
||||
pub fn new(config_file: Option<&ConfigFile>) -> Self {
|
||||
let mut ts_config = Self::default();
|
||||
match ts_config.inner.merge_tsconfig_from_config_file(config_file) {
|
||||
Ok(Some(ignored_options)) => lsp_warn!("{}", ignored_options),
|
||||
Err(err) => lsp_warn!("{}", err),
|
||||
_ => {}
|
||||
pub fn new(raw_ts_config: TsConfigWithIgnoredOptions) -> Self {
|
||||
let mut base_ts_config = Self::default();
|
||||
for ignored_options in &raw_ts_config.ignored_options {
|
||||
lsp_warn!("{}", ignored_options)
|
||||
}
|
||||
ts_config
|
||||
base_ts_config.inner.merge_mut(raw_ts_config.ts_config);
|
||||
base_ts_config
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1425,9 +1425,10 @@ impl ConfigData {
|
|||
.unwrap_or_default(),
|
||||
);
|
||||
|
||||
let ts_config = LspTsConfig::new(
|
||||
member_dir.workspace.root_deno_json().map(|c| c.as_ref()),
|
||||
);
|
||||
let ts_config = member_dir
|
||||
.to_raw_user_provided_tsconfig()
|
||||
.map(LspTsConfig::new)
|
||||
.unwrap_or_default();
|
||||
|
||||
let deno_lint_config =
|
||||
if ts_config.inner.0.get("jsx").and_then(|v| v.as_str()) == Some("react")
|
||||
|
@ -1673,7 +1674,6 @@ impl ConfigData {
|
|||
) -> Option<JsxImportSourceConfig> {
|
||||
self
|
||||
.member_dir
|
||||
.workspace
|
||||
.to_maybe_jsx_import_source_config()
|
||||
.ok()
|
||||
.flatten()
|
||||
|
|
|
@ -23,6 +23,7 @@ use deno_core::unsync::spawn;
|
|||
use deno_core::url;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::CheckJsOption;
|
||||
use deno_graph::GraphKind;
|
||||
use deno_graph::Resolution;
|
||||
use deno_lib::args::get_root_cert_store;
|
||||
|
@ -279,7 +280,7 @@ impl LanguageServer {
|
|||
&roots,
|
||||
graph_util::GraphValidOptions {
|
||||
kind: GraphKind::All,
|
||||
check_js: false,
|
||||
check_js: CheckJsOption::False,
|
||||
exit_integrity_errors: false,
|
||||
},
|
||||
)?;
|
||||
|
|
|
@ -153,7 +153,7 @@ impl LspScopeResolver {
|
|||
let maybe_jsx_import_source_config =
|
||||
config_data.and_then(|d| d.maybe_jsx_import_source_config());
|
||||
let graph_imports = config_data
|
||||
.and_then(|d| d.member_dir.workspace.to_compiler_option_types().ok())
|
||||
.and_then(|d| d.member_dir.to_compiler_option_types().ok())
|
||||
.map(|imports| {
|
||||
Arc::new(
|
||||
imports
|
||||
|
@ -988,19 +988,25 @@ pub struct SingleReferrerGraphResolver<'a> {
|
|||
}
|
||||
|
||||
impl<'a> deno_graph::source::Resolver for SingleReferrerGraphResolver<'a> {
|
||||
fn default_jsx_import_source(&self) -> Option<String> {
|
||||
fn default_jsx_import_source(
|
||||
&self,
|
||||
_referrer: &ModuleSpecifier,
|
||||
) -> Option<String> {
|
||||
self
|
||||
.jsx_import_source_config
|
||||
.and_then(|c| c.default_specifier.clone())
|
||||
}
|
||||
|
||||
fn default_jsx_import_source_types(&self) -> Option<String> {
|
||||
fn default_jsx_import_source_types(
|
||||
&self,
|
||||
_referrer: &ModuleSpecifier,
|
||||
) -> Option<String> {
|
||||
self
|
||||
.jsx_import_source_config
|
||||
.and_then(|c| c.default_types_specifier.clone())
|
||||
}
|
||||
|
||||
fn jsx_import_source_module(&self) -> &str {
|
||||
fn jsx_import_source_module(&self, _referrer: &ModuleSpecifier) -> &str {
|
||||
self
|
||||
.jsx_import_source_config
|
||||
.map(|c| c.module.as_str())
|
||||
|
|
|
@ -219,7 +219,6 @@ impl ModuleLoadPreparer {
|
|||
check::CheckOptions {
|
||||
build_fast_check_graph: true,
|
||||
lib,
|
||||
log_ignored_options: false,
|
||||
reload: self.options.reload_flag(),
|
||||
type_check_mode: self.options.type_check_mode(),
|
||||
},
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -20,7 +20,6 @@ use deno_terminal::colors;
|
|||
use rand::Rng;
|
||||
|
||||
use super::installer::infer_name_from_url;
|
||||
use crate::args::check_warn_tsconfig;
|
||||
use crate::args::CompileFlags;
|
||||
use crate::args::Flags;
|
||||
use crate::factory::CliFactory;
|
||||
|
@ -84,9 +83,6 @@ pub async fn compile(
|
|||
graph
|
||||
};
|
||||
|
||||
let ts_config_for_emit = cli_options
|
||||
.resolve_ts_config_for_emit(deno_config::deno_json::TsConfigType::Emit)?;
|
||||
check_warn_tsconfig(&ts_config_for_emit);
|
||||
log::info!(
|
||||
"{} {} to {}",
|
||||
colors::green("Compile"),
|
||||
|
|
|
@ -608,7 +608,7 @@ pub fn cover_files(
|
|||
let module_kind = ModuleKind::from_is_cjs(
|
||||
cjs_tracker.is_maybe_cjs(&file.specifier, file.media_type)?,
|
||||
);
|
||||
Some(match emitter.maybe_cached_emit(&file.specifier, module_kind, &file.source) {
|
||||
Some(match emitter.maybe_cached_emit(&file.specifier, module_kind, &file.source)? {
|
||||
Some(code) => code,
|
||||
None => {
|
||||
return Err(anyhow!(
|
||||
|
|
|
@ -16,6 +16,7 @@ use deno_doc::html::UrlResolveKind;
|
|||
use deno_doc::html::UsageComposer;
|
||||
use deno_doc::html::UsageComposerEntry;
|
||||
use deno_graph::source::NullFileSystem;
|
||||
use deno_graph::CheckJsOption;
|
||||
use deno_graph::EsParser;
|
||||
use deno_graph::GraphKind;
|
||||
use deno_graph::ModuleAnalyzer;
|
||||
|
@ -148,7 +149,7 @@ pub async fn doc(
|
|||
&sys,
|
||||
&module_specifiers,
|
||||
GraphWalkErrorsOptions {
|
||||
check_js: false,
|
||||
check_js: CheckJsOption::False,
|
||||
kind: GraphKind::TypesOnly,
|
||||
},
|
||||
);
|
||||
|
|
|
@ -68,6 +68,7 @@ pub async fn kernel(
|
|||
let permissions =
|
||||
PermissionsContainer::allow_all(factory.permission_desc_parser()?.clone());
|
||||
let npm_installer = factory.npm_installer_if_managed()?.cloned();
|
||||
let tsconfig_resolver = factory.tsconfig_resolver()?;
|
||||
let resolver = factory.resolver().await?.clone();
|
||||
let worker_factory = factory.create_cli_main_worker_factory().await?;
|
||||
let (stdio_tx, stdio_rx) = mpsc::unbounded_channel();
|
||||
|
@ -117,6 +118,7 @@ pub async fn kernel(
|
|||
cli_options,
|
||||
npm_installer,
|
||||
resolver,
|
||||
tsconfig_resolver,
|
||||
worker,
|
||||
main_module,
|
||||
test_event_receiver,
|
||||
|
|
|
@ -27,12 +27,12 @@ use deno_core::unsync::future::LocalFutureExt;
|
|||
use deno_core::unsync::future::SharedLocal;
|
||||
use deno_graph::ModuleGraph;
|
||||
use deno_lint::diagnostic::LintDiagnostic;
|
||||
use deno_lint::linter::LintConfig as DenoLintConfig;
|
||||
use log::debug;
|
||||
use reporters::create_reporter;
|
||||
use reporters::LintReporter;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::args::deno_json::TsConfigResolver;
|
||||
use crate::args::CliOptions;
|
||||
use crate::args::Flags;
|
||||
use crate::args::LintFlags;
|
||||
|
@ -86,7 +86,7 @@ pub async fn lint(
|
|||
let cli_options = factory.cli_options()?;
|
||||
let lint_rule_provider = factory.lint_rule_provider().await?;
|
||||
let is_stdin = lint_flags.is_stdin();
|
||||
let deno_lint_config = cli_options.resolve_deno_lint_config()?;
|
||||
let tsconfig_resolver = factory.tsconfig_resolver()?;
|
||||
let workspace_lint_options =
|
||||
cli_options.resolve_workspace_lint_options(&lint_flags)?;
|
||||
let success = if is_stdin {
|
||||
|
@ -95,13 +95,14 @@ pub async fn lint(
|
|||
lint_rule_provider,
|
||||
workspace_lint_options,
|
||||
lint_flags,
|
||||
deno_lint_config,
|
||||
tsconfig_resolver,
|
||||
)?
|
||||
} else {
|
||||
let mut linter = WorkspaceLinter::new(
|
||||
factory.caches()?.clone(),
|
||||
lint_rule_provider,
|
||||
factory.module_graph_creator().await?.clone(),
|
||||
tsconfig_resolver.clone(),
|
||||
cli_options.start_dir.clone(),
|
||||
&workspace_lint_options,
|
||||
);
|
||||
|
@ -112,7 +113,6 @@ pub async fn lint(
|
|||
.lint_files(
|
||||
cli_options,
|
||||
paths_with_options.options,
|
||||
deno_lint_config.clone(),
|
||||
paths_with_options.dir,
|
||||
paths_with_options.paths,
|
||||
)
|
||||
|
@ -135,7 +135,6 @@ async fn lint_with_watch_inner(
|
|||
) -> Result<(), AnyError> {
|
||||
let factory = CliFactory::from_flags(flags);
|
||||
let cli_options = factory.cli_options()?;
|
||||
let lint_config = cli_options.resolve_deno_lint_config()?;
|
||||
let mut paths_with_options_batches =
|
||||
resolve_paths_with_options_batches(cli_options, &lint_flags)?;
|
||||
for paths_with_options in &mut paths_with_options_batches {
|
||||
|
@ -162,6 +161,7 @@ async fn lint_with_watch_inner(
|
|||
factory.caches()?.clone(),
|
||||
factory.lint_rule_provider().await?,
|
||||
factory.module_graph_creator().await?.clone(),
|
||||
factory.tsconfig_resolver()?.clone(),
|
||||
cli_options.start_dir.clone(),
|
||||
&cli_options.resolve_workspace_lint_options(&lint_flags)?,
|
||||
);
|
||||
|
@ -170,7 +170,6 @@ async fn lint_with_watch_inner(
|
|||
.lint_files(
|
||||
cli_options,
|
||||
paths_with_options.options,
|
||||
lint_config.clone(),
|
||||
paths_with_options.dir,
|
||||
paths_with_options.paths,
|
||||
)
|
||||
|
@ -242,6 +241,7 @@ struct WorkspaceLinter {
|
|||
caches: Arc<Caches>,
|
||||
lint_rule_provider: LintRuleProvider,
|
||||
module_graph_creator: Arc<ModuleGraphCreator>,
|
||||
tsconfig_resolver: Arc<TsConfigResolver>,
|
||||
workspace_dir: Arc<WorkspaceDirectory>,
|
||||
reporter_lock: Arc<Mutex<Box<dyn LintReporter + Send>>>,
|
||||
workspace_module_graph: Option<WorkspaceModuleGraphFuture>,
|
||||
|
@ -254,6 +254,7 @@ impl WorkspaceLinter {
|
|||
caches: Arc<Caches>,
|
||||
lint_rule_provider: LintRuleProvider,
|
||||
module_graph_creator: Arc<ModuleGraphCreator>,
|
||||
tsconfig_resolver: Arc<TsConfigResolver>,
|
||||
workspace_dir: Arc<WorkspaceDirectory>,
|
||||
workspace_options: &WorkspaceLintOptions,
|
||||
) -> Self {
|
||||
|
@ -263,6 +264,7 @@ impl WorkspaceLinter {
|
|||
caches,
|
||||
lint_rule_provider,
|
||||
module_graph_creator,
|
||||
tsconfig_resolver,
|
||||
workspace_dir,
|
||||
reporter_lock,
|
||||
workspace_module_graph: None,
|
||||
|
@ -275,7 +277,6 @@ impl WorkspaceLinter {
|
|||
&mut self,
|
||||
cli_options: &Arc<CliOptions>,
|
||||
lint_options: LintOptions,
|
||||
lint_config: DenoLintConfig,
|
||||
member_dir: WorkspaceDirectory,
|
||||
paths: Vec<PathBuf>,
|
||||
) -> Result<(), AnyError> {
|
||||
|
@ -297,7 +298,9 @@ impl WorkspaceLinter {
|
|||
let linter = Arc::new(CliLinter::new(CliLinterOptions {
|
||||
configured_rules: lint_rules,
|
||||
fix: lint_options.fix,
|
||||
deno_lint_config: lint_config,
|
||||
deno_lint_config: self
|
||||
.tsconfig_resolver
|
||||
.deno_lint_config(member_dir.dir_url())?,
|
||||
}));
|
||||
|
||||
let has_error = self.has_error.clone();
|
||||
|
@ -530,7 +533,7 @@ fn lint_stdin(
|
|||
lint_rule_provider: LintRuleProvider,
|
||||
workspace_lint_options: WorkspaceLintOptions,
|
||||
lint_flags: LintFlags,
|
||||
deno_lint_config: DenoLintConfig,
|
||||
tsconfig_resolver: &TsConfigResolver,
|
||||
) -> Result<bool, AnyError> {
|
||||
let start_dir = &cli_options.start_dir;
|
||||
let reporter_lock = Arc::new(Mutex::new(create_reporter(
|
||||
|
@ -538,6 +541,8 @@ fn lint_stdin(
|
|||
)));
|
||||
let lint_config = start_dir
|
||||
.to_lint_config(FilePatterns::new_with_base(start_dir.dir_path()))?;
|
||||
let deno_lint_config =
|
||||
tsconfig_resolver.deno_lint_config(start_dir.dir_url())?;
|
||||
let lint_options = LintOptions::resolve(lint_config, &lint_flags);
|
||||
let configured_rules = lint_rule_provider.resolve_lint_rules_err_empty(
|
||||
lint_options.rules,
|
||||
|
|
|
@ -123,7 +123,7 @@ impl GraphDiagnosticsCollector {
|
|||
};
|
||||
|
||||
let options = WalkOptions {
|
||||
check_js: true,
|
||||
check_js: deno_graph::CheckJsOption::True,
|
||||
follow_dynamic: true,
|
||||
// search the entire graph and not just the fast check subset
|
||||
prefer_fast_check_graph: false,
|
||||
|
|
|
@ -364,14 +364,13 @@ impl PublishPreparer {
|
|||
} else {
|
||||
// fast check passed, type check the output as a temporary measure
|
||||
// until we know that it's reliable and stable
|
||||
let (graph, check_diagnostics) = self
|
||||
let mut diagnostics_by_folder = self
|
||||
.type_checker
|
||||
.check_diagnostics(
|
||||
graph,
|
||||
CheckOptions {
|
||||
build_fast_check_graph: false, // already built
|
||||
lib: self.cli_options.ts_type_lib_window(),
|
||||
log_ignored_options: false,
|
||||
reload: self.cli_options.reload_flag(),
|
||||
type_check_mode: self.cli_options.type_check_mode(),
|
||||
},
|
||||
|
@ -379,20 +378,23 @@ impl PublishPreparer {
|
|||
.await?;
|
||||
// ignore unused parameter diagnostics that may occur due to fast check
|
||||
// not having function body implementations
|
||||
let check_diagnostics =
|
||||
check_diagnostics.filter(|d| d.include_when_remote());
|
||||
if !check_diagnostics.is_empty() {
|
||||
bail!(
|
||||
concat!(
|
||||
"Failed ensuring public API type output is valid.\n\n",
|
||||
"{:#}\n\n",
|
||||
"You may have discovered a bug in Deno. Please open an issue at: ",
|
||||
"https://github.com/denoland/deno/issues/"
|
||||
),
|
||||
check_diagnostics
|
||||
);
|
||||
for result in diagnostics_by_folder.by_ref() {
|
||||
let check_diagnostics = result?;
|
||||
let check_diagnostics =
|
||||
check_diagnostics.filter(|d| d.include_when_remote());
|
||||
if check_diagnostics.has_diagnostic() {
|
||||
bail!(
|
||||
concat!(
|
||||
"Failed ensuring public API type output is valid.\n\n",
|
||||
"{:#}\n\n",
|
||||
"You may have discovered a bug in Deno. Please open an issue at: ",
|
||||
"https://github.com/denoland/deno/issues/"
|
||||
),
|
||||
check_diagnostics
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(graph)
|
||||
Ok(diagnostics_by_folder.into_graph())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,6 +168,7 @@ pub async fn run(
|
|||
let npm_installer = factory.npm_installer_if_managed()?.cloned();
|
||||
let resolver = factory.resolver().await?.clone();
|
||||
let file_fetcher = factory.file_fetcher()?;
|
||||
let tsconfig_resolver = factory.tsconfig_resolver()?;
|
||||
let worker_factory = factory.create_cli_main_worker_factory().await?;
|
||||
let history_file_path = factory
|
||||
.deno_dir()
|
||||
|
@ -190,6 +191,7 @@ pub async fn run(
|
|||
cli_options,
|
||||
npm_installer,
|
||||
resolver,
|
||||
tsconfig_resolver,
|
||||
worker,
|
||||
main_module.clone(),
|
||||
test_event_receiver,
|
||||
|
|
|
@ -42,6 +42,7 @@ use regex::Match;
|
|||
use regex::Regex;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::args::deno_json::TsConfigResolver;
|
||||
use crate::args::CliOptions;
|
||||
use crate::cdp;
|
||||
use crate::colors;
|
||||
|
@ -203,6 +204,7 @@ impl ReplSession {
|
|||
cli_options: &CliOptions,
|
||||
npm_installer: Option<Arc<NpmInstaller>>,
|
||||
resolver: Arc<CliResolver>,
|
||||
tsconfig_resolver: &TsConfigResolver,
|
||||
mut worker: MainWorker,
|
||||
main_module: ModuleSpecifier,
|
||||
test_event_receiver: TestEventReceiver,
|
||||
|
@ -258,13 +260,10 @@ impl ReplSession {
|
|||
cli_options.initial_cwd().to_string_lossy(),
|
||||
)
|
||||
})?;
|
||||
let ts_config_for_emit = cli_options
|
||||
.resolve_ts_config_for_emit(deno_config::deno_json::TsConfigType::Emit)?;
|
||||
let (transpile_options, _) =
|
||||
crate::args::ts_config_to_transpile_and_emit_options(
|
||||
ts_config_for_emit.ts_config,
|
||||
)?;
|
||||
let experimental_decorators = transpile_options.use_ts_decorators;
|
||||
let experimental_decorators = tsconfig_resolver
|
||||
.transpile_and_emit_options(&cwd_url)?
|
||||
.transpile
|
||||
.use_ts_decorators;
|
||||
let mut repl_session = ReplSession {
|
||||
npm_installer,
|
||||
resolver,
|
||||
|
|
|
@ -351,16 +351,17 @@ impl Diagnostics {
|
|||
|
||||
/// Return a set of diagnostics where only the values where the predicate
|
||||
/// returns `true` are included.
|
||||
pub fn filter<P>(self, predicate: P) -> Self
|
||||
where
|
||||
P: FnMut(&Diagnostic) -> bool,
|
||||
{
|
||||
pub fn filter(self, predicate: impl FnMut(&Diagnostic) -> bool) -> Self {
|
||||
let diagnostics = self.0.into_iter().filter(predicate).collect();
|
||||
Self(diagnostics)
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
pub fn retain(&mut self, predicate: impl FnMut(&Diagnostic) -> bool) {
|
||||
self.0.retain(predicate);
|
||||
}
|
||||
|
||||
pub fn has_diagnostic(&self) -> bool {
|
||||
!self.0.is_empty()
|
||||
}
|
||||
|
||||
/// Modifies all the diagnostics to have their display positions
|
||||
|
@ -430,23 +431,27 @@ impl Serialize for Diagnostics {
|
|||
|
||||
impl fmt::Display for Diagnostics {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut i = 0;
|
||||
for item in &self.0 {
|
||||
if i > 0 {
|
||||
write!(f, "\n\n")?;
|
||||
}
|
||||
write!(f, "{item}")?;
|
||||
i += 1;
|
||||
display_diagnostics(f, self)?;
|
||||
if self.0.len() > 1 {
|
||||
write!(f, "\n\nFound {} errors.", self.0.len())?;
|
||||
}
|
||||
|
||||
if i > 1 {
|
||||
write!(f, "\n\nFound {i} errors.")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn display_diagnostics(
|
||||
f: &mut fmt::Formatter,
|
||||
diagnostics: &Diagnostics,
|
||||
) -> fmt::Result {
|
||||
for (i, item) in diagnostics.0.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(f, "\n\n")?;
|
||||
}
|
||||
write!(f, "{item}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl Error for Diagnostics {}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -366,7 +366,7 @@ pub struct RequestNpmState {
|
|||
pub struct Request {
|
||||
/// The TypeScript compiler options which will be serialized and sent to
|
||||
/// tsc.
|
||||
pub config: TsConfig,
|
||||
pub config: Arc<TsConfig>,
|
||||
/// Indicates to the tsc runtime if debug logging should occur.
|
||||
pub debug: bool,
|
||||
pub graph: Arc<ModuleGraph>,
|
||||
|
@ -1279,7 +1279,7 @@ mod tests {
|
|||
graph
|
||||
.build(vec![specifier.clone()], &loader, Default::default())
|
||||
.await;
|
||||
let config = TsConfig::new(json!({
|
||||
let config = Arc::new(TsConfig::new(json!({
|
||||
"allowJs": true,
|
||||
"checkJs": false,
|
||||
"esModuleInterop": true,
|
||||
|
@ -1294,7 +1294,7 @@ mod tests {
|
|||
"strict": true,
|
||||
"target": "esnext",
|
||||
"tsBuildInfoFile": "internal:///.tsbuildinfo",
|
||||
}));
|
||||
})));
|
||||
let request = Request {
|
||||
config,
|
||||
debug: false,
|
||||
|
@ -1529,7 +1529,7 @@ mod tests {
|
|||
let actual = test_exec(&specifier)
|
||||
.await
|
||||
.expect("exec should not have errored");
|
||||
assert!(actual.diagnostics.is_empty());
|
||||
assert!(!actual.diagnostics.has_diagnostic());
|
||||
assert!(actual.maybe_tsbuildinfo.is_some());
|
||||
assert_eq!(actual.stats.0.len(), 12);
|
||||
}
|
||||
|
@ -1540,7 +1540,7 @@ mod tests {
|
|||
let actual = test_exec(&specifier)
|
||||
.await
|
||||
.expect("exec should not have errored");
|
||||
assert!(actual.diagnostics.is_empty());
|
||||
assert!(!actual.diagnostics.has_diagnostic());
|
||||
assert!(actual.maybe_tsbuildinfo.is_some());
|
||||
assert_eq!(actual.stats.0.len(), 12);
|
||||
}
|
||||
|
@ -1551,6 +1551,6 @@ mod tests {
|
|||
let actual = test_exec(&specifier)
|
||||
.await
|
||||
.expect("exec should not have errored");
|
||||
assert!(actual.diagnostics.is_empty());
|
||||
assert!(!actual.diagnostics.has_diagnostic());
|
||||
}
|
||||
}
|
||||
|
|
70
cli/util/collections.rs
Normal file
70
cli/util/collections.rs
Normal file
|
@ -0,0 +1,70 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_core::url::Url;
|
||||
|
||||
/// A map that stores values scoped to a specific directory
|
||||
/// on the file system.
|
||||
///
|
||||
/// The root directory is considered "unscoped" so values that
|
||||
/// fall outside the other directories land here (ex. remote modules).
|
||||
pub struct FolderScopedMap<TValue> {
|
||||
unscoped: TValue,
|
||||
scoped: BTreeMap<Arc<Url>, TValue>,
|
||||
}
|
||||
|
||||
impl<TValue> std::fmt::Debug for FolderScopedMap<TValue>
|
||||
where
|
||||
TValue: std::fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("FolderScopedMap")
|
||||
.field("unscoped", &self.unscoped)
|
||||
.field("scoped", &self.scoped)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<TValue> Default for FolderScopedMap<TValue>
|
||||
where
|
||||
TValue: Default,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self::new(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<TValue> FolderScopedMap<TValue> {
|
||||
pub fn new(unscoped: TValue) -> Self {
|
||||
Self {
|
||||
unscoped,
|
||||
scoped: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn count(&self) -> usize {
|
||||
// +1 for unscoped
|
||||
self.scoped.len() + 1
|
||||
}
|
||||
|
||||
pub fn get_for_specifier(&self, specifier: &Url) -> &TValue {
|
||||
self.get_for_specifier_str(specifier.as_str())
|
||||
}
|
||||
|
||||
pub fn get_for_specifier_str(&self, specifier: &str) -> &TValue {
|
||||
self
|
||||
.scoped
|
||||
.iter()
|
||||
.rfind(|(s, _)| specifier.starts_with(s.as_str()))
|
||||
.map(|(_, v)| v)
|
||||
.unwrap_or(&self.unscoped)
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, dir_url: Arc<Url>, value: TValue) {
|
||||
debug_assert!(dir_url.path().ends_with("/")); // must be a dir url
|
||||
debug_assert_eq!(dir_url.scheme(), "file");
|
||||
self.scoped.insert(dir_url, value);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
// Note: Only add code in this folder that has no application specific logic
|
||||
pub mod archive;
|
||||
pub mod collections;
|
||||
pub mod console;
|
||||
pub mod diff;
|
||||
pub mod display;
|
||||
|
|
|
@ -146,7 +146,7 @@ fn check_error_in_dep_then_fix() {
|
|||
let check_command = test_context.new_command().args_vec(["check", "main.ts"]);
|
||||
|
||||
let output = check_command.run();
|
||||
output.assert_matches_text("Check [WILDCARD]main.ts\nerror: TS234[WILDCARD]");
|
||||
output.assert_matches_text("Check [WILDCARD]main.ts\nTS234[WILDCARD]");
|
||||
output.assert_exit_code(1);
|
||||
|
||||
temp_dir.write("greet.ts", correct_code);
|
||||
|
@ -155,7 +155,7 @@ fn check_error_in_dep_then_fix() {
|
|||
|
||||
temp_dir.write("greet.ts", incorrect_code);
|
||||
let output = check_command.run();
|
||||
output.assert_matches_text("Check [WILDCARD]main.ts\nerror: TS234[WILDCARD]");
|
||||
output.assert_matches_text("Check [WILDCARD]main.ts\nTS234[WILDCARD]");
|
||||
output.assert_exit_code(1);
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ fn json_module_check_then_error() {
|
|||
temp_dir.write("test.json", incorrect_code);
|
||||
check_command
|
||||
.run()
|
||||
.assert_matches_text("Check [WILDCARD]main.ts\nerror: TS2551[WILDCARD]")
|
||||
.assert_matches_text("Check [WILDCARD]main.ts\nTS2551[WILDCARD]")
|
||||
.assert_exit_code(1);
|
||||
}
|
||||
|
||||
|
@ -242,6 +242,6 @@ fn npm_module_check_then_error() {
|
|||
|
||||
check_command
|
||||
.run()
|
||||
.assert_matches_text("Check [WILDCARD]main.ts\nerror: TS2305[WILDCARD]has no exported member 'oldName'[WILDCARD]")
|
||||
.assert_matches_text("Check [WILDCARD]main.ts\nTS2305[WILDCARD]has no exported member 'oldName'[WILDCARD]")
|
||||
.assert_exit_code(1);
|
||||
}
|
||||
|
|
|
@ -495,7 +495,7 @@ fn check_local_by_default2() {
|
|||
])
|
||||
.run()
|
||||
.assert_matches_text(
|
||||
r#"[WILDCARD]error: TS2322 [ERROR]: Type '12' is not assignable to type '"b"'.[WILDCARD]"#,
|
||||
r#"[WILDCARD]TS2322 [ERROR]: Type '12' is not assignable to type '"b"'.[WILDCARD]"#,
|
||||
)
|
||||
.assert_exit_code(1);
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ fn fast_check_cache() {
|
|||
|
||||
// ensure cache works
|
||||
let output = check_debug_cmd.run();
|
||||
assert_contains!(output.combined_output(), "Already type checked.");
|
||||
assert_contains!(output.combined_output(), "Already type checked");
|
||||
|
||||
// now validated
|
||||
type_check_cache_path.remove_file();
|
||||
|
@ -97,10 +97,12 @@ fn fast_check_cache() {
|
|||
.run()
|
||||
.assert_matches_text(
|
||||
"Check file:///[WILDCARD]main.ts
|
||||
error: TS2322 [ERROR]: Type 'string' is not assignable to type 'number'.
|
||||
TS2322 [ERROR]: Type 'string' is not assignable to type 'number'.
|
||||
export function asdf(a: number) { let err: number = ''; return Math.random(); }
|
||||
~~~
|
||||
at http://127.0.0.1:4250/@denotest/add/1.0.0/other.ts:2:39
|
||||
|
||||
error: Type checking failed.
|
||||
",
|
||||
)
|
||||
.assert_exit_code(1);
|
||||
|
|
|
@ -2158,7 +2158,7 @@ fn ts_dependency_recompilation() {
|
|||
let stdout_output = std::str::from_utf8(&output.stdout).unwrap().trim();
|
||||
let stderr_output = std::str::from_utf8(&output.stderr).unwrap().trim();
|
||||
|
||||
// error: TS2345 [ERROR]: Argument of type '5' is not assignable to parameter of type 'string'.
|
||||
// TS2345 [ERROR]: Argument of type '5' is not assignable to parameter of type 'string'.
|
||||
assert!(stderr_output.contains("TS2345"));
|
||||
assert!(!output.status.success());
|
||||
assert!(stdout_output.is_empty());
|
||||
|
|
|
@ -1148,7 +1148,7 @@ async fn test_watch_doc() {
|
|||
);
|
||||
assert_eq!(
|
||||
next_line(&mut stderr_lines).await.unwrap(),
|
||||
"error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'."
|
||||
"TS2322 [ERROR]: Type 'number' is not assignable to type 'string'."
|
||||
);
|
||||
assert_eq!(
|
||||
next_line(&mut stderr_lines).await.unwrap(),
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
error: TS2322 [ERROR]: Type '12' is not assignable to type '"b"'.
|
||||
TS2322 [ERROR]: Type '12' is not assignable to type '"b"'.
|
||||
const b: "b" = 12;
|
||||
^
|
||||
at [WILDCARD]/check_local_by_default2.ts:3:7
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Check [WILDCARD]/no_run.ts
|
||||
error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
const _value: string = 1;
|
||||
~~~~~~
|
||||
at [WILDCARD]/no_run.ts:1:7
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
error: TS2322 [ERROR]: Type '12' is not assignable to type '"a"'.
|
||||
TS2322 [ERROR]: Type '12' is not assignable to type '"a"'.
|
||||
export const a: "a" = 12;
|
||||
^
|
||||
at http://localhost:4545/subdir/type_error.ts:1:14
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
error: TS2304 [ERROR]: Cannot find name 'Deno'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'deno.ns' or add a triple-slash directive to the top of your entrypoint (main file): /// <reference lib="deno.ns" />
|
||||
TS2304 [ERROR]: Cannot find name 'Deno'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'deno.ns' or add a triple-slash directive to the top of your entrypoint (main file): /// <reference lib="deno.ns" />
|
||||
Deno;
|
||||
~~~~
|
||||
at file:///[WILDCARD]/deno_not_found/main.ts:4:1
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
error: TS1039 [ERROR]: Initializers are not allowed in ambient contexts.
|
||||
TS1039 [ERROR]: Initializers are not allowed in ambient contexts.
|
||||
export const a: string = Deno.version.deno;
|
||||
~~~~~~~~~~~~~~~~~
|
||||
at file:///[WILDCARD]/check_dts.d.ts:2:26
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
error: TS2304 [ERROR]: Cannot find name 'nothing'.
|
||||
TS2304 [ERROR]: Cannot find name 'nothing'.
|
||||
export { nothing };
|
||||
~~~~~~~
|
||||
at [WILDCARD]
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
error: TS2304 [ERROR]: Cannot find name 'nothing'.
|
||||
TS2304 [ERROR]: Cannot find name 'nothing'.
|
||||
export { nothing };
|
||||
~~~~~~~
|
||||
at [WILDCARD]
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: TS2322 [ERROR]: Type '{ propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propertyWithAnExceedinglyLongName3: string; propertyWithAnExceedinglyLongName4: string; propertyWithAnExceedinglyLongName5: string; propertyWithAnExceedinglyLongName6: string; propertyWithAnExceedinglyLongName7: string; propertyWithAnExceedinglyLongName8: string; }' is not assignable to type 'string'.
|
||||
TS2322 [ERROR]: Type '{ propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propertyWithAnExceedinglyLongName3: string; propertyWithAnExceedinglyLongName4: string; propertyWithAnExceedinglyLongName5: string; propertyWithAnExceedinglyLongName6: string; propertyWithAnExceedinglyLongName7: string; propertyWithAnExceedinglyLongName8: string; }' is not assignable to type 'string'.
|
||||
const _s: string = x;
|
||||
~~
|
||||
at file:///[WILDCARD]/no_error_truncation/main.ts:12:7
|
||||
|
@ -9,3 +9,5 @@ const _s: string = x;
|
|||
at file:///[WILDCARD]/no_error_truncation/main.ts:12:20
|
||||
|
||||
Found 2 errors.
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
error: TS2769 [ERROR]: No overload matches this call.
|
||||
TS2769 [ERROR]: No overload matches this call.
|
||||
[WILDCARD]
|
||||
const _data = fs.readFileSync("./node_builtin.js", 123);
|
||||
~~~
|
||||
at file:///[WILDCARD]/mod.js:3:52
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: TS2769 [ERROR]: No overload matches this call.
|
||||
TS2769 [ERROR]: No overload matches this call.
|
||||
[WILDCARD]
|
||||
const _data = fs.readFileSync("./node_builtin.js", 123);
|
||||
~~~
|
||||
|
@ -11,3 +11,5 @@ const _testString: number[] = builtinModules;
|
|||
at file:///[WILDCARD]/mod.ts:9:7
|
||||
|
||||
Found 2 errors.
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: TS2581 [ERROR]: Cannot find name '$'. Did you mean to import jQuery? Try adding `import $ from "npm:jquery";`.
|
||||
TS2581 [ERROR]: Cannot find name '$'. Did you mean to import jQuery? Try adding `import $ from "npm:jquery";`.
|
||||
$;
|
||||
^
|
||||
at file:///[WILDCARD]/npm_install_diagnostics/main.ts:1:1
|
||||
|
@ -9,3 +9,5 @@ process;
|
|||
at file:///[WILDCARD]/npm_install_diagnostics/main.ts:2:1
|
||||
|
||||
Found 2 errors.
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
14
tests/specs/check/check_workspace/__test__.jsonc
Normal file
14
tests/specs/check/check_workspace/__test__.jsonc
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"tests": {
|
||||
"discover": {
|
||||
"args": "check main.ts member/mod.ts",
|
||||
"output": "check_discover.out",
|
||||
"exitCode": 1
|
||||
},
|
||||
"config_flag": {
|
||||
"args": "check --config deno.json main.ts member/mod.ts",
|
||||
"output": "check_config_flag.out",
|
||||
"exitCode": 1
|
||||
}
|
||||
}
|
||||
}
|
20
tests/specs/check/check_workspace/check_config_flag.out
Normal file
20
tests/specs/check/check_workspace/check_config_flag.out
Normal file
|
@ -0,0 +1,20 @@
|
|||
Check file:///[WILDLINE]/main.ts
|
||||
TS2304 [ERROR]: Cannot find name 'onmessage'.
|
||||
onmessage;
|
||||
~~~~~~~~~
|
||||
at file:///[WILDLINE]/main.ts:8:1
|
||||
|
||||
TS2304 [ERROR]: Cannot find name 'onmessage'.
|
||||
onmessage;
|
||||
~~~~~~~~~
|
||||
at file:///[WILDLINE]/member/mod.ts:5:1
|
||||
|
||||
Found 2 errors.
|
||||
|
||||
Check file:///[WILDLINE]/member/mod.ts
|
||||
TS2304 [ERROR]: Cannot find name 'localStorage'.
|
||||
localStorage;
|
||||
~~~~~~~~~~~~
|
||||
at file:///[WILDLINE]/member/mod.ts:2:1
|
||||
|
||||
error: Type checking failed.
|
20
tests/specs/check/check_workspace/check_discover.out
Normal file
20
tests/specs/check/check_workspace/check_discover.out
Normal file
|
@ -0,0 +1,20 @@
|
|||
Check file:///[WILDLINE]/main.ts
|
||||
TS2304 [ERROR]: Cannot find name 'onmessage'.
|
||||
onmessage;
|
||||
~~~~~~~~~
|
||||
at file:///[WILDLINE]/main.ts:8:1
|
||||
|
||||
TS2304 [ERROR]: Cannot find name 'onmessage'.
|
||||
onmessage;
|
||||
~~~~~~~~~
|
||||
at file:///[WILDLINE]/member/mod.ts:5:1
|
||||
|
||||
Found 2 errors.
|
||||
|
||||
Check file:///[WILDLINE]/member/mod.ts
|
||||
TS2304 [ERROR]: Cannot find name 'localStorage'.
|
||||
localStorage;
|
||||
~~~~~~~~~~~~
|
||||
at file:///[WILDLINE]/member/mod.ts:2:1
|
||||
|
||||
error: Type checking failed.
|
3
tests/specs/check/check_workspace/deno.json
Normal file
3
tests/specs/check/check_workspace/deno.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"workspace": ["member"]
|
||||
}
|
8
tests/specs/check/check_workspace/main.ts
Normal file
8
tests/specs/check/check_workspace/main.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
// We should get diagnostics from this import under this check scope.
|
||||
import "./member/mod.ts";
|
||||
|
||||
// Only defined for window.
|
||||
localStorage;
|
||||
|
||||
// Only defined for worker.
|
||||
onmessage;
|
5
tests/specs/check/check_workspace/member/deno.json
Normal file
5
tests/specs/check/check_workspace/member/deno.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["deno.worker"]
|
||||
}
|
||||
}
|
5
tests/specs/check/check_workspace/member/mod.ts
Normal file
5
tests/specs/check/check_workspace/member/mod.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
// Only defined for window.
|
||||
localStorage;
|
||||
|
||||
// Only defined for worker.
|
||||
onmessage;
|
|
@ -1,7 +1,9 @@
|
|||
Download http://localhost:4260/@denotest%2fcjs-default-export
|
||||
Download http://localhost:4260/@denotest/cjs-default-export/1.0.0.tgz
|
||||
Check file:///[WILDCARD]/main.ts
|
||||
error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
export const Test: string = cjsDefault.default();
|
||||
~~~~
|
||||
at file:///[WILDCARD]/main.ts:4:14
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Check file:///[WILDLINE]/exists_and_try_uses.ts
|
||||
error: TS1192 [ERROR]: Module '"file:///[WILDLINE]/app.css"' has no default export.
|
||||
TS1192 [ERROR]: Module '"file:///[WILDLINE]/app.css"' has no default export.
|
||||
import test from "./app.css";
|
||||
~~~~
|
||||
at file:///[WILDLINE]/exists_and_try_uses.ts:1:8
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
Check [WILDLINE]exists.ts
|
||||
error: TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/not_exists.css'.
|
||||
TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/not_exists.css'.
|
||||
at file:///[WILDLINE]/not_exists.ts:1:8
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
Check file:///[WILDLINE]/dts_importing_non_existent/index.js
|
||||
error: TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/test'.
|
||||
TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/test'.
|
||||
at file:///[WILDLINE]/index.d.ts:1:22
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -12,12 +12,12 @@
|
|||
},
|
||||
"glob_star": {
|
||||
"args": "check **/*.ts",
|
||||
"output": "Check [WILDLINE]main.ts\nCheck [WILDLINE]sub_dir/main.ts\nerror: TS2322[WILDCARD]",
|
||||
"output": "Check [WILDLINE]main.ts\nCheck [WILDLINE]sub_dir/main.ts\nTS2322[WILDCARD]",
|
||||
"exitCode": 1
|
||||
},
|
||||
"sub_dir": {
|
||||
"args": "check sub_dir",
|
||||
"output": "Check [WILDLINE]sub_dir/main.ts\nerror: TS2322[WILDCARD]",
|
||||
"output": "Check [WILDLINE]sub_dir/main.ts\nTS2322[WILDCARD]",
|
||||
"exitCode": 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Download http://localhost:4545/check/import_non_existent.ts
|
||||
Download http://localhost:4545/check/non-existent-module.ts
|
||||
Check file:///[WILDLINE]/import_remote.ts
|
||||
error: TS2307 [ERROR]: Cannot find module 'http://localhost:4545/check/non-existent-module.ts'.
|
||||
TS2307 [ERROR]: Cannot find module 'http://localhost:4545/check/non-existent-module.ts'.
|
||||
at http://localhost:4545/check/import_non_existent.ts:1:22
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
Download http://localhost:4545/add.ts
|
||||
Check file:///[WILDLINE]main.js
|
||||
error: TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type '(a: number, b: number) => number'.
|
||||
TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type '(a: number, b: number) => number'.
|
||||
addHere("");
|
||||
~~
|
||||
at file:///[WILDLINE]main.js:12:9
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -7,7 +7,9 @@ Download http://localhost:4260/loose-envify/loose-envify-1.4.0.tgz
|
|||
Download http://localhost:4260/js-tokens/js-tokens-4.0.0.tgz
|
||||
[UNORDERED_END]
|
||||
Check file:///[WILDCARD]/jsx_not_checked/main.jsx
|
||||
error: TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
console.log(add("1", "2"));
|
||||
~~~
|
||||
at file:///[WILDCARD]/other.ts:5:17
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: TS2769 [ERROR]: No overload matches this call.
|
||||
TS2769 [ERROR]: No overload matches this call.
|
||||
Overload 1 of 3, '(s: string, b: boolean): void', gave the following error.
|
||||
Argument of type 'number' is not assignable to parameter of type 'boolean'.
|
||||
Overload 2 of 3, '(ss: string[], b: boolean): void', gave the following error.
|
||||
|
@ -8,3 +8,5 @@ error: TS2769 [ERROR]: No overload matches this call.
|
|||
foo("hello", 42);
|
||||
~~~
|
||||
at [WILDLINE]/message_chain_formatting.ts:8:1
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
Download http://localhost:4545/remote.ts
|
||||
Check file:///[WILDLINE]/module_not_found/main.ts
|
||||
error: TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/other.js'.
|
||||
TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/other.js'.
|
||||
at file:///[WILDLINE]/main.ts:1:22
|
||||
|
||||
TS2307 [ERROR]: Cannot find module 'http://localhost:4545/remote.ts'.
|
||||
at file:///[WILDLINE]/main.ts:2:24
|
||||
|
||||
Found 2 errors.
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
Check file:///[WILDLINE]/non_existent.ts
|
||||
error: TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/non_existent.ts'.
|
||||
TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/non_existent.ts'.
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
Download http://localhost:4545/missing_non_existent.ts
|
||||
Check http://localhost:4545/missing_non_existent.ts
|
||||
error: TS2307 [ERROR]: Cannot find module 'http://localhost:4545/missing_non_existent.ts'.
|
||||
TS2307 [ERROR]: Cannot find module 'http://localhost:4545/missing_non_existent.ts'.
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Check file:///[WILDCARD]/main.ts
|
||||
error: TS4114 [ERROR]: This member must have an 'override' modifier because it overrides a member in the base class 'Greet'.
|
||||
TS4114 [ERROR]: This member must have an 'override' modifier because it overrides a member in the base class 'Greet'.
|
||||
greet() {}
|
||||
~~~~~
|
||||
at file:///[WILDCARD]/no_implicit_override/main.ts:6:3
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Check file:///[WILDLINE]/index.ts
|
||||
error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
const result: string = add(1, 2);
|
||||
~~~~~~
|
||||
at file:///[WILDLINE]/index.ts:4:7
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
const _test: string = getValue();
|
||||
~~~~~
|
||||
at file:///[WILDCARD]/fail_check.ts:3:7
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
const _strValue1: string = NUMBER_VALUE;
|
||||
~~~~~~~~~~
|
||||
at file:///[WILDCARD]/main.ts:8:7
|
||||
|
@ -9,3 +9,5 @@ const _strValue2: string = test.getValue();
|
|||
at file:///[WILDCARD]/main.ts:9:7
|
||||
|
||||
Found 2 errors.
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Check [WILDCARD]/main.ts
|
||||
error: TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'AsyncIterable<string> | (Iterable<string | PromiseLike<string>> & object)'.
|
||||
TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'AsyncIterable<string> | (Iterable<string | PromiseLike<string>> & object)'.
|
||||
ReadableStream.from("string");
|
||||
~~~~~~~~
|
||||
at [WILDCARD]/main.ts:1:21
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
Check [WILDCARD]/mod.ts
|
||||
Check [WILDCARD]/mod.ts$2-5.ts
|
||||
error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
const sum: string = add(1, 2);
|
||||
~~~
|
||||
at [WILDCARD]/mod.ts$2-5.ts:2:7
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
Check [WILDCARD]/markdown.md$11-14.js
|
||||
Check [WILDCARD]/markdown.md$17-20.ts
|
||||
Check [WILDCARD]/markdown.md$29-32.ts
|
||||
error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
const a: string = 42;
|
||||
^
|
||||
at [WILDCARD]/markdown.md$29-32.ts:1:7
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
[# It should be resolving relative the config in sub_dir instead of the cwd]
|
||||
Check file:///[WILDLINE]/main.ts
|
||||
error: TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/sub_dir/a.d.ts'.
|
||||
TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/sub_dir/a.d.ts'.
|
||||
at file:///[WILDLINE]/sub_dir/deno.json:1:1
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Check file:///[WILDLINE]main.ts
|
||||
error: TS2339 [ERROR]: Property 'listenDatagram' does not exist on type 'typeof Deno'. 'Deno.listenDatagram' is an unstable API. If not, try changing the 'lib' compiler option to include 'deno.unstable' or add a triple-slash directive to the top of your entrypoint (main file): /// <reference lib="deno.unstable" />
|
||||
TS2339 [ERROR]: Property 'listenDatagram' does not exist on type 'typeof Deno'. 'Deno.listenDatagram' is an unstable API. If not, try changing the 'lib' compiler option to include 'deno.unstable' or add a triple-slash directive to the top of your entrypoint (main file): /// <reference lib="deno.unstable" />
|
||||
Deno.listenDatagram({
|
||||
~~~~~~~~~~~~~~
|
||||
at file:///[WILDLINE]/main.ts:5:6
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Check file:///[WILDLINE]/no_default_lib.ts
|
||||
error: TS2304 [ERROR]: Cannot find name 'Deno'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'deno.ns' or add a triple-slash directive to the top of your entrypoint (main file): /// <reference lib="deno.ns" />
|
||||
TS2304 [ERROR]: Cannot find name 'Deno'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'deno.ns' or add a triple-slash directive to the top of your entrypoint (main file): /// <reference lib="deno.ns" />
|
||||
console.log(Deno);
|
||||
~~~~
|
||||
at file:///[WILDLINE]/no_default_lib.ts:5:13
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Check file:///[WILDCARD]/main.ts
|
||||
error: TS18046 [ERROR]: 'e' is of type 'unknown'.
|
||||
TS18046 [ERROR]: 'e' is of type 'unknown'.
|
||||
console.log(e.message);
|
||||
^
|
||||
at file://[WILDCARD]/use_unknown_in_catch_variables/main.ts:4:15
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
Download http://localhost:4545/wasm/math.wasm
|
||||
Check file:///[WILDLINE]/main.ts
|
||||
error: TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
console.log(add(1, ""));
|
||||
~~
|
||||
at file:///[WILDLINE]/main.ts:3:20
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"tests": {
|
||||
"root": {
|
||||
// todo(dsherret): should be possible to not provide args here
|
||||
"args": "check package-a/mod.ts package-b/mod.ts",
|
||||
"args": "check package-a/mod.ts package-b/mod.ts package-c/mod.ts package-d/mod.ts",
|
||||
"output": "root.out",
|
||||
"exitCode": 1
|
||||
},
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"workspace": [
|
||||
"./package-a",
|
||||
"./package-b"
|
||||
"./package-b",
|
||||
"./package-c",
|
||||
"./package-d"
|
||||
]
|
||||
}
|
||||
|
|
1
tests/specs/check/workspace/package-c/check.js
Normal file
1
tests/specs/check/workspace/package-c/check.js
Normal file
|
@ -0,0 +1 @@
|
|||
console.log(Math.pow(""));
|
5
tests/specs/check/workspace/package-c/deno.json
Normal file
5
tests/specs/check/workspace/package-c/deno.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"checkJs": true
|
||||
}
|
||||
}
|
1
tests/specs/check/workspace/package-c/mod.ts
Normal file
1
tests/specs/check/workspace/package-c/mod.ts
Normal file
|
@ -0,0 +1 @@
|
|||
import "./check.js";
|
1
tests/specs/check/workspace/package-d/check.js
Normal file
1
tests/specs/check/workspace/package-d/check.js
Normal file
|
@ -0,0 +1 @@
|
|||
console.log(Math.pow(""));
|
5
tests/specs/check/workspace/package-d/deno.json
Normal file
5
tests/specs/check/workspace/package-d/deno.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"checkJs": false
|
||||
}
|
||||
}
|
1
tests/specs/check/workspace/package-d/mod.ts
Normal file
1
tests/specs/check/workspace/package-d/mod.ts
Normal file
|
@ -0,0 +1 @@
|
|||
import "./check.js";
|
|
@ -1,5 +1,7 @@
|
|||
Check file:///[WILDLINE]/package-b/mod.ts
|
||||
error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
const test: string = add(1, 2);
|
||||
~~~~
|
||||
at [WILDLINE]
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
Check file:///[WILDLINE]/package-a/mod.ts
|
||||
Check file:///[WILDLINE]/package-b/mod.ts
|
||||
error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
Check file:///[WILDLINE]/package-d/mod.ts
|
||||
TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
|
||||
const test: string = add(1, 2);
|
||||
~~~~
|
||||
at [WILDLINE]
|
||||
at file:///[WILDLINE]/package-b/mod.ts:3:7
|
||||
|
||||
Check file:///[WILDLINE]/package-c/mod.ts
|
||||
TS2554 [ERROR]: Expected 2 arguments, but got 1.
|
||||
console.log(Math.pow(""));
|
||||
~~~
|
||||
at file:///[WILDLINE]/package-c/check.js:1:18
|
||||
|
||||
An argument for 'y' was not provided.
|
||||
pow(x: number, y: number): number;
|
||||
~~~~~~~~~
|
||||
at asset:///lib.es5.d.ts:744:20
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"tests": {
|
||||
"root": {
|
||||
"args": "check package-a/mod.ts package-b/mod.ts package-c/mod.ts",
|
||||
"output": "root.out",
|
||||
"exitCode": 1
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"workspace": [
|
||||
"./package-a",
|
||||
"./package-b",
|
||||
"./package-c"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"types": [
|
||||
"./globals.d.ts",
|
||||
"./other-globals.d.ts"
|
||||
]
|
||||
}
|
||||
}
|
1
tests/specs/check/workspace_compiler_option_types/package-a/globals.d.ts
vendored
Normal file
1
tests/specs/check/workspace_compiler_option_types/package-a/globals.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
declare var myPackageAGlobal: string;
|
|
@ -0,0 +1,2 @@
|
|||
console.log(myPackageAGlobal);
|
||||
console.log(myPackageBGlobal);
|
0
tests/specs/check/workspace_compiler_option_types/package-a/other-globals.d.ts
vendored
Normal file
0
tests/specs/check/workspace_compiler_option_types/package-a/other-globals.d.ts
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"types": [
|
||||
"./globals.d.ts"
|
||||
]
|
||||
}
|
||||
}
|
1
tests/specs/check/workspace_compiler_option_types/package-b/globals.d.ts
vendored
Normal file
1
tests/specs/check/workspace_compiler_option_types/package-b/globals.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
declare var myPackageBGlobal: string;
|
|
@ -0,0 +1,2 @@
|
|||
console.log(myPackageAGlobal);
|
||||
console.log(myPackageBGlobal);
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
// the config for this package should be grouped together with
|
||||
// package-a because it's the same
|
||||
"compilerOptions": {
|
||||
"types": [
|
||||
// these are swapped with what's in package-a and Deno should
|
||||
// still handle type checking them together because the config
|
||||
// is the same
|
||||
"../package-a/other-globals.d.ts",
|
||||
"../package-a/globals.d.ts"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
console.log(myPackageAGlobal);
|
24
tests/specs/check/workspace_compiler_option_types/root.out
Normal file
24
tests/specs/check/workspace_compiler_option_types/root.out
Normal file
|
@ -0,0 +1,24 @@
|
|||
Check file:///[WILDLINE]/package-a/mod.ts
|
||||
Check file:///[WILDLINE]/package-c/mod.ts
|
||||
TS2552 [ERROR]: Cannot find name 'myPackageBGlobal'. Did you mean 'myPackageAGlobal'?
|
||||
console.log(myPackageBGlobal);
|
||||
~~~~~~~~~~~~~~~~
|
||||
at file:///[WILDLINE]/package-a/mod.ts:2:13
|
||||
|
||||
'myPackageAGlobal' is declared here.
|
||||
declare var myPackageAGlobal: string;
|
||||
~~~~~~~~~~~~~~~~
|
||||
at file:///[WILDLINE]/package-a/globals.d.ts:1:13
|
||||
|
||||
Check file:///[WILDLINE]/package-b/mod.ts
|
||||
TS2552 [ERROR]: Cannot find name 'myPackageAGlobal'. Did you mean 'myPackageBGlobal'?
|
||||
console.log(myPackageAGlobal);
|
||||
~~~~~~~~~~~~~~~~
|
||||
at file:///[WILDLINE]/package-b/mod.ts:1:13
|
||||
|
||||
'myPackageBGlobal' is declared here.
|
||||
declare var myPackageBGlobal: string;
|
||||
~~~~~~~~~~~~~~~~
|
||||
at file:///[WILDLINE]/package-b/globals.d.ts:1:13
|
||||
|
||||
error: Type checking failed.
|
|
@ -9,7 +9,7 @@ Download http://127.0.0.1:4250/@denotest/subset-type-graph/0.1.0/mod.ts
|
|||
Download http://127.0.0.1:4250/@denotest/subset-type-graph-invalid/0.1.0/mod.ts
|
||||
[UNORDERED_END]
|
||||
Check file:///[WILDCARD]/subset_type_graph/main.ts
|
||||
error: TS2322 [ERROR]: Type 'string' is not assignable to type 'number'.
|
||||
TS2322 [ERROR]: Type 'string' is not assignable to type 'number'.
|
||||
const invalidTypeCheck: number = "";
|
||||
~~~~~~~~~~~~~~~~
|
||||
at http://127.0.0.1:4250/@denotest/subset-type-graph-invalid/0.1.0/mod.ts:11:7
|
||||
|
@ -45,3 +45,5 @@ new Foo2().method2();
|
|||
at http://127.0.0.1:4250/@denotest/subset-type-graph-invalid/0.1.0/mod.ts:2:3
|
||||
|
||||
Found 5 errors.
|
||||
|
||||
error: Type checking failed.
|
||||
|
|
|
@ -1,16 +1,5 @@
|
|||
{
|
||||
"steps": [
|
||||
{
|
||||
"args": "lint",
|
||||
"cwd": "./react",
|
||||
"output": "react.out",
|
||||
"exitCode": 0
|
||||
},
|
||||
{
|
||||
"args": "lint",
|
||||
"cwd": "./react-jsx",
|
||||
"output": "react-jsx.out",
|
||||
"exitCode": 1
|
||||
}
|
||||
]
|
||||
"args": "lint",
|
||||
"output": "lint.out",
|
||||
"exitCode": 1
|
||||
}
|
||||
|
|
6
tests/specs/lint/jsx/deno.json
Normal file
6
tests/specs/lint/jsx/deno.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"workspace": [
|
||||
"react",
|
||||
"react-jsx"
|
||||
]
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue