From 4648fc457069e7d5862299a6d1b8e2590f781f09 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Tue, 28 Jan 2025 10:49:58 -0500 Subject: [PATCH] fix(check): compiler options from workspace members (#27785) Co-authored-by: Nayeem Rahman --- Cargo.lock | 8 +- Cargo.toml | 2 +- cli/Cargo.toml | 2 +- cli/args/deno_json.rs | 276 +++++- cli/args/mod.rs | 107 --- cli/emit.rs | 95 +- cli/factory.rs | 29 +- cli/file_fetcher.rs | 24 +- cli/graph_util.rs | 90 +- cli/lib/util/hash.rs | 1 + cli/lsp/config.rs | 22 +- cli/lsp/language_server.rs | 3 +- cli/lsp/resolver.rs | 14 +- cli/module_loader.rs | 1 - cli/tools/check.rs | 896 ++++++++++++------ cli/tools/compile.rs | 4 - cli/tools/coverage/mod.rs | 2 +- cli/tools/doc.rs | 3 +- cli/tools/jupyter/mod.rs | 2 + cli/tools/lint/mod.rs | 23 +- cli/tools/registry/graph.rs | 2 +- cli/tools/registry/mod.rs | 32 +- cli/tools/repl/mod.rs | 2 + cli/tools/repl/session.rs | 13 +- cli/tsc/diagnostics.rs | 41 +- cli/tsc/mod.rs | 12 +- cli/util/collections.rs | 70 ++ cli/util/mod.rs | 1 + tests/integration/check_tests.rs | 8 +- tests/integration/compile_tests.rs | 2 +- tests/integration/jsr_tests.rs | 6 +- tests/integration/run_tests.rs | 2 +- tests/integration/watcher_tests.rs | 2 +- .../check_local_by_default2.out | 4 +- tests/specs/bench/no_run/no_run.out | 4 +- tests/specs/check/check_all/check_all.out | 4 +- .../deno_not_found/main.out | 4 +- tests/specs/check/check_dts/dts/check_dts.out | 4 +- .../exclude_option.ts.error.out | 4 +- .../exclude_option.ts.error.out | 4 +- .../no_error_truncation/main.out | 4 +- .../check_node_builtin_modules/mod.js.out | 4 +- .../check_node_builtin_modules/mod.ts.out | 4 +- .../npm_install_diagnostics/main.out | 4 +- .../check/check_workspace/__test__.jsonc | 14 + .../check_workspace/check_config_flag.out | 20 + .../check/check_workspace/check_discover.out | 20 + tests/specs/check/check_workspace/deno.json | 3 + tests/specs/check/check_workspace/main.ts | 8 + .../check/check_workspace/member/deno.json | 5 + .../specs/check/check_workspace/member/mod.ts | 5 + tests/specs/check/cjs_default_export/main.out | 4 +- .../check/css_import/exists_and_try_uses.out | 4 +- tests/specs/check/css_import/not_exists.out | 4 +- .../dts_importing_non_existent/check.out | 4 +- tests/specs/check/globbing/__test__.jsonc | 4 +- .../check_all.out | 4 +- tests/specs/check/jsdoc_import_decl/check.out | 4 +- .../jsx_not_checked/jsx_not_checked/main.out | 4 +- .../message_chain_formatting.out | 4 +- tests/specs/check/module_not_found/main.out | 4 +- .../module_not_found/missing_local_root.out | 4 +- .../module_not_found/missing_remote_root.out | 4 +- .../specs/check/no_implicit_override/main.out | 4 +- .../check/npm_pkg_empty_main_entry/check.out | 4 +- .../package_json_fail_check/fail_check.out | 4 +- .../package_json_with_deno_json/check.out | 4 +- .../main.out | 4 +- .../specs/check/typecheck_doc_failure/mod.out | 4 +- .../typecheck_doc_in_markdown/markdown.out | 4 +- .../types_resolved_relative_config/main.out | 4 +- .../specs/check/unstable_suggestion/main.out | 4 +- .../unstable_suggestion/no_default_lib.out | 4 +- .../use_unknown_in_catch_variables/main.out | 4 +- tests/specs/check/wasm/check.out | 4 +- tests/specs/check/workspace/__test__.jsonc | 2 +- tests/specs/check/workspace/deno.json | 4 +- .../specs/check/workspace/package-c/check.js | 1 + .../specs/check/workspace/package-c/deno.json | 5 + tests/specs/check/workspace/package-c/mod.ts | 1 + .../specs/check/workspace/package-d/check.js | 1 + .../specs/check/workspace/package-d/deno.json | 5 + tests/specs/check/workspace/package-d/mod.ts | 1 + tests/specs/check/workspace/package_b.out | 4 +- tests/specs/check/workspace/root.out | 18 +- .../__test__.jsonc | 9 + .../workspace_compiler_option_types/deno.json | 7 + .../package-a/deno.json | 8 + .../package-a/globals.d.ts | 1 + .../package-a/mod.ts | 2 + .../package-a/other-globals.d.ts | 0 .../package-b/deno.json | 7 + .../package-b/globals.d.ts | 1 + .../package-b/mod.ts | 2 + .../package-c/deno.jsonc | 13 + .../package-c/mod.ts | 1 + .../workspace_compiler_option_types/root.out | 24 + .../jsr/subset_type_graph/main.check.out | 4 +- tests/specs/lint/jsx/__test__.jsonc | 17 +- tests/specs/lint/jsx/deno.json | 6 + .../lint/jsx/{react-jsx.out => lint.out} | 2 +- tests/specs/lint/jsx/react.out | 1 - .../dynamic_import_and_require_dual/check.out | 4 +- .../jsdoc_import_decl.out | 4 +- .../resolution_mode_import.out | 4 +- .../resolution_mode_require.out | 4 +- .../resolution_mode_require_jsdoc.out | 4 +- tests/specs/npm/check_all_local/main_all.out | 4 +- .../specs/npm/check_all_local/main_local.out | 4 +- .../file_dts_dmts_dcts/main.out | 4 +- .../expected.out | 4 +- .../npm/check_types_in_types_pkg/expected.out | 4 +- tests/specs/npm/cjs_import_dual/check.out | 4 +- .../main.out | 4 +- .../npm/dual_cjs_esm/cjs_referrer/check.out | 4 +- .../ts_referrer_type_cjs/check.out | 4 +- .../npm/node_modules_import/main_check.out | 4 +- .../node_modules_import_auto/main_check.out | 4 +- .../types_ambient_module/main.out | 4 +- .../types_ambient_module/main_import_map.out | 4 +- .../types_entry_value_not_exists/main.out | 4 +- .../types_exports_import_types/main.out | 4 +- tests/specs/npm/types_general/main.out | 4 +- .../types_no_types_entry/main.out | 4 +- .../sloppy_imports_not_enabled.out | 4 +- .../specs/run/_038_checkjs/038_checkjs.js.out | 4 +- .../091_use_define_for_class_fields.ts.out | 2 +- .../check_js_points_to_ts/test.js.out | 4 +- .../no_check_remote.ts.disabled.out | 4 +- tests/specs/run/cts/cjs_import_cts/check.out | 4 +- .../import_export_equals/mod.mts.check.out | 4 +- .../error_003_typescript.ts.out | 4 +- .../error_003_typescript.ts.out | 4 +- .../error_017_hide_long_source_ts.ts.out | 4 +- .../error_for_await/error_for_await.ts.out | 4 +- .../type_check.out | 4 +- tests/specs/run/invalid_emit_options/main.out | 2 +- .../js_root_with_ts_check.js.out | 4 +- .../jsx_import_source_error.out | 4 +- .../no_auto_discovery.out | 4 +- .../reference_types_error.js.out | 4 +- .../reference_types_error.js.out | 4 +- tests/specs/run/sloppy_imports/no_sloppy.out | 4 +- .../ts_type_imports/ts_type_imports.ts.out | 4 +- .../type_definitions_for_export.ts.out | 4 +- .../import_file_not_found/check.out | 4 +- .../import_named_export_not_found/check.out | 4 +- .../wasm_module/table_global_memory/check.out | 4 +- tests/specs/serve/type_check/main.out | 4 +- tests/specs/serve/type_check2/main.out | 4 +- .../test/check_local_by_default2/main.out | 4 +- tests/specs/test/doc/main.out | 4 +- tests/specs/test/markdown/main.out | 4 +- .../test/markdown_full_block_names/main.out | 4 +- .../markdown_ignore_html_comment/main.out | 4 +- tests/specs/test/markdown_windows/main.out | 4 +- tests/specs/test/no_run/main.out | 4 +- tests/specs/test/type_check_with_doc/main.out | 4 +- .../workspaces/non_fatal_diagnostics/lint.out | 2 +- .../non_fatal_diagnostics/sub/deno.json | 4 +- .../bench/check_local_by_default2.out | 4 +- tests/testdata/bench/no_run.out | 4 +- .../testdata/import_attributes/type_check.out | 4 +- 163 files changed, 1681 insertions(+), 716 deletions(-) create mode 100644 cli/util/collections.rs create mode 100644 tests/specs/check/check_workspace/__test__.jsonc create mode 100644 tests/specs/check/check_workspace/check_config_flag.out create mode 100644 tests/specs/check/check_workspace/check_discover.out create mode 100644 tests/specs/check/check_workspace/deno.json create mode 100644 tests/specs/check/check_workspace/main.ts create mode 100644 tests/specs/check/check_workspace/member/deno.json create mode 100644 tests/specs/check/check_workspace/member/mod.ts create mode 100644 tests/specs/check/workspace/package-c/check.js create mode 100644 tests/specs/check/workspace/package-c/deno.json create mode 100644 tests/specs/check/workspace/package-c/mod.ts create mode 100644 tests/specs/check/workspace/package-d/check.js create mode 100644 tests/specs/check/workspace/package-d/deno.json create mode 100644 tests/specs/check/workspace/package-d/mod.ts create mode 100644 tests/specs/check/workspace_compiler_option_types/__test__.jsonc create mode 100644 tests/specs/check/workspace_compiler_option_types/deno.json create mode 100644 tests/specs/check/workspace_compiler_option_types/package-a/deno.json create mode 100644 tests/specs/check/workspace_compiler_option_types/package-a/globals.d.ts create mode 100644 tests/specs/check/workspace_compiler_option_types/package-a/mod.ts create mode 100644 tests/specs/check/workspace_compiler_option_types/package-a/other-globals.d.ts create mode 100644 tests/specs/check/workspace_compiler_option_types/package-b/deno.json create mode 100644 tests/specs/check/workspace_compiler_option_types/package-b/globals.d.ts create mode 100644 tests/specs/check/workspace_compiler_option_types/package-b/mod.ts create mode 100644 tests/specs/check/workspace_compiler_option_types/package-c/deno.jsonc create mode 100644 tests/specs/check/workspace_compiler_option_types/package-c/mod.ts create mode 100644 tests/specs/check/workspace_compiler_option_types/root.out create mode 100644 tests/specs/lint/jsx/deno.json rename tests/specs/lint/jsx/{react-jsx.out => lint.out} (94%) delete mode 100644 tests/specs/lint/jsx/react.out diff --git a/Cargo.lock b/Cargo.lock index 3af0277809..2119da05fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/Cargo.toml b/Cargo.toml index e68db18432..8490a92d25 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 32bf639250..e8671d9211 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -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 diff --git a/cli/args/deno_json.rs b/cli/args/deno_json.rs index c27b1d3924..3121380251 100644 --- a/cli/args/deno_json.rs +++ b/cli/args/deno_json.rs @@ -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 { } } -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, +} + +#[derive(Default, Debug)] +struct MemoizedValues { + deno_window_check_tsconfig: OnceCell>, + deno_worker_check_tsconfig: OnceCell>, + emit_tsconfig: OnceCell>, + transpile_options: OnceCell>, +} + +#[derive(Debug)] +pub struct TsConfigFolderInfo { + pub dir: WorkspaceDirectory, + logged_warnings: Arc, + memoized: MemoizedValues, +} + +impl TsConfigFolderInfo { + pub fn lib_tsconfig( + &self, + lib: TsTypeLib, + ) -> Result<&Arc, 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, 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, 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, +} + +impl TsConfigResolver { + pub fn from_workspace(workspace: &Arc) -> 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 { + 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, 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 { + 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, + }) +} diff --git a/cli/args/mod.rs b/cli/args/mod.rs index 1f03cdfc19..03ca2814a7 100644 --- a/cli/args/mod.rs +++ b/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 { - self.workspace().resolve_ts_config_for_emit(config_type) - } - pub fn resolve_inspector_server( &self, ) -> Result, AnyError> { @@ -781,23 +712,6 @@ impl CliOptions { self.maybe_lockfile.as_ref() } - pub fn to_compiler_option_types( - &self, - ) -> Result, 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 { - 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 { match &self.flags.subcommand { DenoSubcommand::Test(test) => test diff --git a/cli/emit.rs b/cli/emit.rs index 5e39df2874..2e5ca33939 100644 --- a/cli/emit.rs +++ b/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, emit_cache: Arc, parsed_source_cache: Arc, - 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, } impl Emitter { @@ -42,21 +41,13 @@ impl Emitter { cjs_tracker: Arc, emit_cache: Arc, parsed_source_cache: Arc, - transpile_options: deno_ast::TranspileOptions, - emit_options: deno_ast::EmitOptions, + tsconfig_resolver: Arc, ) -> 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 { - let source_hash = self.get_source_hash(module_kind, source); - self.emit_cache.get_emit_code(specifier, source_hash) + ) -> Result, 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, ) -> Result { + 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, ) -> Result { + 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, ) -> 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, ) -> 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) diff --git a/cli/factory.rs b/cli/factory.rs index fb08bbcbc0..e41fa1b73e 100644 --- a/cli/factory.rs +++ b/cli/factory.rs @@ -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>, root_permissions_container: Deferred, text_only_progress_bar: Deferred, + tsconfig_resolver: Deferred>, type_checker: Deferred>, workspace_factory: Deferred>, workspace_external_import_map_loader: @@ -675,6 +676,10 @@ impl CliFactory { self.resolver_factory()?.sloppy_imports_resolver() } + pub fn workspace(&self) -> Result<&Arc, AnyError> { + Ok(&self.workspace_directory()?.workspace) + } + pub fn workspace_directory( &self, ) -> Result<&Arc, AnyError> { @@ -773,20 +778,11 @@ impl CliFactory { pub fn emitter(&self) -> Result<&Arc, 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, 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, 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 diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs index 723571649a..cc9cf38425 100644 --- a/cli/file_fetcher.rs +++ b/cli/file_fetcher.rs @@ -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 ); } diff --git a/cli/graph_util.rs b/cli/graph_util.rs index e57fcf8a94..6a640b7cb0 100644 --- a/cli/graph_util.rs +++ b/cli/graph_util.rs @@ -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 + '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, root_permissions_container: PermissionsContainer, sys: CliSys, + tsconfig_resolver: Arc, } impl ModuleGraphBuilder { @@ -529,6 +536,7 @@ impl ModuleGraphBuilder { resolver: Arc, root_permissions_container: PermissionsContainer, sys: CliSys, + tsconfig_resolver: Arc, ) -> 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 { - 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, + jsx_import_source_config_unscoped: Option, + jsx_import_source_config_by_scope: + BTreeMap, Option>, +} + +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 { + fn default_jsx_import_source( + &self, + referrer: &ModuleSpecifier, + ) -> Option { 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 { + fn default_jsx_import_source_types( + &self, + referrer: &ModuleSpecifier, + ) -> Option { 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) } diff --git a/cli/lib/util/hash.rs b/cli/lib/util/hash.rs index da607a27f2..213c83ba5b 100644 --- a/cli/lib/util/hash.rs +++ b/cli/lib/util/hash.rs @@ -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 { diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs index b94e71806f..4ca4255fea 100644 --- a/cli/lsp/config.rs +++ b/cli/lsp/config.rs @@ -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 { self .member_dir - .workspace .to_maybe_jsx_import_source_config() .ok() .flatten() diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 76982fb332..012cdd1e45 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -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, }, )?; diff --git a/cli/lsp/resolver.rs b/cli/lsp/resolver.rs index 7f544719a7..f0ab45f5ae 100644 --- a/cli/lsp/resolver.rs +++ b/cli/lsp/resolver.rs @@ -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 { + fn default_jsx_import_source( + &self, + _referrer: &ModuleSpecifier, + ) -> Option { self .jsx_import_source_config .and_then(|c| c.default_specifier.clone()) } - fn default_jsx_import_source_types(&self) -> Option { + fn default_jsx_import_source_types( + &self, + _referrer: &ModuleSpecifier, + ) -> Option { 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()) diff --git a/cli/module_loader.rs b/cli/module_loader.rs index 7e023f0fa6..fda17d6b5e 100644 --- a/cli/module_loader.rs +++ b/cli/module_loader.rs @@ -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(), }, diff --git a/cli/tools/check.rs b/cli/tools/check.rs index d3796cb740..223dadd6c9 100644 --- a/cli/tools/check.rs +++ b/cli/tools/check.rs @@ -1,13 +1,18 @@ // Copyright 2018-2025 the Deno authors. MIT license. +use std::collections::HashMap; use std::collections::HashSet; use std::collections::VecDeque; +use std::rc::Rc; use std::sync::Arc; use deno_ast::MediaType; use deno_ast::ModuleSpecifier; use deno_config::deno_json; +use deno_config::deno_json::CompilerOptionTypesDeserializeError; +use deno_config::workspace::WorkspaceDirectory; use deno_core::error::AnyError; +use deno_core::url::Url; use deno_error::JsErrorBox; use deno_graph::Module; use deno_graph::ModuleError; @@ -16,15 +21,15 @@ use deno_graph::ModuleLoadError; use deno_lib::util::hash::FastInsecureHasher; use deno_semver::npm::NpmPackageNvReference; use deno_terminal::colors; +use indexmap::IndexMap; use once_cell::sync::Lazy; use regex::Regex; -use crate::args::check_warn_tsconfig; +use crate::args::deno_json::TsConfigResolver; use crate::args::CheckFlags; use crate::args::CliOptions; use crate::args::Flags; use crate::args::TsConfig; -use crate::args::TsConfigType; use crate::args::TsTypeLib; use crate::args::TypeCheckMode; use crate::cache::CacheDBHash; @@ -87,6 +92,35 @@ pub async fn check( .await } +#[derive(Debug, thiserror::Error, deno_error::JsError)] +#[class(type)] +#[error("Type checking failed.")] +pub struct FailedTypeCheckingError; + +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum CheckError { + #[class(inherit)] + #[error(transparent)] + FailedTypeChecking(#[from] FailedTypeCheckingError), + #[class(inherit)] + #[error(transparent)] + ToMaybeJsxImportSourceConfig( + #[from] deno_json::ToMaybeJsxImportSourceConfigError, + ), + #[class(inherit)] + #[error(transparent)] + TscExec(#[from] tsc::ExecError), + #[class(inherit)] + #[error(transparent)] + CompilerOptionTypesDeserialize(#[from] CompilerOptionTypesDeserializeError), + #[class(inherit)] + #[error(transparent)] + CompilerOptionsParse(#[from] deno_json::CompilerOptionsParseError), + #[class(inherit)] + #[error(transparent)] + Other(#[from] JsErrorBox), +} + /// Options for performing a check of a module graph. Note that the decision to /// emit or not is determined by the `ts_config` settings. pub struct CheckOptions { @@ -97,8 +131,6 @@ pub struct CheckOptions { pub build_fast_check_graph: bool, /// Default type library to type check with. pub lib: TsTypeLib, - /// Whether to log about any ignored compiler options. - pub log_ignored_options: bool, /// If true, valid `.tsbuildinfo` files will be ignored and type checking /// will always occur. pub reload: bool, @@ -115,27 +147,7 @@ pub struct TypeChecker { node_resolver: Arc, npm_resolver: CliNpmResolver, sys: CliSys, -} - -#[derive(Debug, thiserror::Error, deno_error::JsError)] -pub enum CheckError { - #[class(inherit)] - #[error(transparent)] - Diagnostics(#[from] Diagnostics), - #[class(inherit)] - #[error(transparent)] - ConfigFile(#[from] deno_json::ConfigFileError), - #[class(inherit)] - #[error(transparent)] - ToMaybeJsxImportSourceConfig( - #[from] deno_json::ToMaybeJsxImportSourceConfigError, - ), - #[class(inherit)] - #[error(transparent)] - TscExec(#[from] tsc::ExecError), - #[class(inherit)] - #[error(transparent)] - Other(#[from] JsErrorBox), + tsconfig_resolver: Arc, } impl TypeChecker { @@ -149,6 +161,7 @@ impl TypeChecker { npm_installer: Option>, npm_resolver: CliNpmResolver, sys: CliSys, + tsconfig_resolver: Arc, ) -> Self { Self { caches, @@ -159,6 +172,7 @@ impl TypeChecker { npm_installer, npm_resolver, sys, + tsconfig_resolver, } } @@ -171,13 +185,20 @@ impl TypeChecker { graph: ModuleGraph, options: CheckOptions, ) -> Result, CheckError> { - let (graph, mut diagnostics) = - self.check_diagnostics(graph, options).await?; - diagnostics.emit_warnings(); - if diagnostics.is_empty() { - Ok(graph) + let mut diagnostics = self.check_diagnostics(graph, options).await?; + let mut failed = false; + for result in diagnostics.by_ref() { + let mut diagnostics = result?; + diagnostics.emit_warnings(); + if diagnostics.has_diagnostic() { + failed = true; + log::error!("{}\n", diagnostics); + } + } + if failed { + Err(FailedTypeCheckingError.into()) } else { - Err(diagnostics.into()) + Ok(diagnostics.into_graph()) } } @@ -189,7 +210,7 @@ impl TypeChecker { &self, mut graph: ModuleGraph, options: CheckOptions, - ) -> Result<(Arc, Diagnostics), CheckError> { + ) -> Result { fn check_state_hash(resolver: &CliNpmResolver) -> Option { match resolver { CliNpmResolver::Byonm(_) => { @@ -214,7 +235,9 @@ impl TypeChecker { } if !options.type_check_mode.is_true() || graph.roots.is_empty() { - return Ok((graph.into(), Default::default())); + return Ok(DiagnosticsByFolderIterator( + DiagnosticsByFolderIteratorInner::Empty(Arc::new(graph)), + )); } // node built-in specifiers use the @types/node package to determine @@ -226,18 +249,7 @@ impl TypeChecker { } } - log::debug!("Type checking."); - let ts_config_result = self - .cli_options - .resolve_ts_config_for_emit(TsConfigType::Check { lib: options.lib })?; - if options.log_ignored_options { - check_warn_tsconfig(&ts_config_result); - } - - let type_check_mode = options.type_check_mode; - let ts_config = ts_config_result.ts_config; - let cache = TypeCheckCache::new(self.caches.type_checking_cache_db()); - let check_js = ts_config.get_check_js(); + log::debug!("Type checking"); // add fast check to the graph before getting the roots if options.build_fast_check_graph { @@ -249,72 +261,299 @@ impl TypeChecker { )?; } - let filter_remote_diagnostics = |d: &tsc::Diagnostic| { - if self.is_remote_diagnostic(d) { - type_check_mode == TypeCheckMode::All && d.include_when_remote() - } else { - true + let graph = Arc::new(graph); + + // split the roots by what we can send to the ts compiler all at once + let grouped_roots = + self.group_roots_by_compiler_options(&graph, options.lib)?; + + Ok(DiagnosticsByFolderIterator( + DiagnosticsByFolderIteratorInner::Real(DiagnosticsByFolderRealIterator { + graph, + sys: &self.sys, + cjs_tracker: &self.cjs_tracker, + node_resolver: &self.node_resolver, + npm_resolver: &self.npm_resolver, + tsconfig_resolver: &self.tsconfig_resolver, + log_level: self.cli_options.log_level(), + npm_check_state_hash: check_state_hash(&self.npm_resolver), + type_check_cache: TypeCheckCache::new( + self.caches.type_checking_cache_db(), + ), + grouped_roots, + options, + seen_diagnotics: Default::default(), + }), + )) + } + + /// Groups the roots based on the compiler options, which includes the + /// resolved TsConfig and resolved compilerOptions.types + fn group_roots_by_compiler_options<'a>( + &'a self, + graph: &ModuleGraph, + lib: TsTypeLib, + ) -> Result, CheckGroupInfo>, CheckError> { + let mut imports_for_specifier: HashMap, Rc>> = + HashMap::with_capacity(self.tsconfig_resolver.folder_count()); + let mut roots_by_config: IndexMap<_, CheckGroupInfo> = + IndexMap::with_capacity(self.tsconfig_resolver.folder_count()); + for root in &graph.roots { + let folder = self.tsconfig_resolver.folder_for_specifier(root); + let imports = + match imports_for_specifier.entry(folder.dir.dir_url().clone()) { + std::collections::hash_map::Entry::Occupied(entry) => { + entry.get().clone() + } + std::collections::hash_map::Entry::Vacant(vacant_entry) => { + let value = Rc::new(resolve_graph_imports_for_workspace_dir( + graph, + &folder.dir, + )); + vacant_entry.insert(value.clone()); + value + } + }; + let tsconfig = folder.lib_tsconfig(lib)?; + let key = CheckGroupKey { + ts_config: tsconfig, + imports, + }; + let entry = roots_by_config.entry(key); + let entry = match entry { + indexmap::map::Entry::Occupied(entry) => entry.into_mut(), + indexmap::map::Entry::Vacant(entry) => entry.insert(CheckGroupInfo { + roots: Default::default(), + // this is slightly hacky. It's used as the referrer for resolving + // npm imports in the key + referrer: folder + .dir + .maybe_deno_json() + .map(|d| d.specifier.clone()) + .unwrap_or_else(|| folder.dir.dir_url().as_ref().clone()), + }), + }; + entry.roots.push(root.clone()); + } + Ok(roots_by_config) + } +} + +fn resolve_graph_imports_for_workspace_dir( + graph: &ModuleGraph, + dir: &WorkspaceDirectory, +) -> Vec { + fn resolve_graph_imports_for_referrer<'a>( + graph: &'a ModuleGraph, + referrer: &'a Url, + ) -> Option + 'a> { + let imports = graph.imports.get(referrer)?; + Some( + imports + .dependencies + .values() + .filter_map(|dep| dep.get_type().or_else(|| dep.get_code())) + .map(|url| graph.resolve(url)) + .cloned(), + ) + } + + let root_deno_json = dir.workspace.root_deno_json(); + let member_deno_json = dir.maybe_deno_json().filter(|c| { + Some(&c.specifier) != root_deno_json.as_ref().map(|c| &c.specifier) + }); + let mut specifiers = root_deno_json + .map(|c| resolve_graph_imports_for_referrer(graph, &c.specifier)) + .into_iter() + .flatten() + .flatten() + .chain( + member_deno_json + .map(|c| resolve_graph_imports_for_referrer(graph, &c.specifier)) + .into_iter() + .flatten() + .flatten(), + ) + .collect::>(); + specifiers.sort(); + specifiers +} + +/// Key to use to group roots together by config. +#[derive(Debug, Hash, PartialEq, Eq)] +struct CheckGroupKey<'a> { + ts_config: &'a Arc, + imports: Rc>, +} + +struct CheckGroupInfo { + roots: Vec, + referrer: Url, +} + +pub struct DiagnosticsByFolderIterator<'a>( + DiagnosticsByFolderIteratorInner<'a>, +); + +impl<'a> DiagnosticsByFolderIterator<'a> { + pub fn into_graph(self) -> Arc { + match self.0 { + DiagnosticsByFolderIteratorInner::Empty(module_graph) => module_graph, + DiagnosticsByFolderIteratorInner::Real(r) => r.graph, + } + } +} + +impl<'a> Iterator for DiagnosticsByFolderIterator<'a> { + type Item = Result; + + fn next(&mut self) -> Option { + match &mut self.0 { + DiagnosticsByFolderIteratorInner::Empty(_) => None, + DiagnosticsByFolderIteratorInner::Real(r) => r.next(), + } + } +} + +enum DiagnosticsByFolderIteratorInner<'a> { + Empty(Arc), + Real(DiagnosticsByFolderRealIterator<'a>), +} + +struct DiagnosticsByFolderRealIterator<'a> { + graph: Arc, + sys: &'a CliSys, + cjs_tracker: &'a Arc, + node_resolver: &'a Arc, + npm_resolver: &'a CliNpmResolver, + tsconfig_resolver: &'a TsConfigResolver, + type_check_cache: TypeCheckCache, + grouped_roots: IndexMap, CheckGroupInfo>, + log_level: Option, + npm_check_state_hash: Option, + seen_diagnotics: HashSet, + options: CheckOptions, +} + +impl<'a> Iterator for DiagnosticsByFolderRealIterator<'a> { + type Item = Result; + + fn next(&mut self) -> Option { + let (group_key, group_info) = self.grouped_roots.shift_remove_index(0)?; + let mut result = self.check_diagnostics_in_folder(&group_key, group_info); + if let Ok(diagnostics) = &mut result { + diagnostics.retain(|d| { + if let (Some(file_name), Some(start)) = (&d.file_name, &d.start) { + let data = format!( + "{}{}:{}:{}{}", + d.code, + file_name, + start.line, + start.character, + d.message_text.as_deref().unwrap_or_default() + ); + self.seen_diagnotics.insert(data) + } else { + // show these for each type of config + true + } + }); + } + Some(result) + } +} + +impl<'a> DiagnosticsByFolderRealIterator<'a> { + #[allow(clippy::too_many_arguments)] + fn check_diagnostics_in_folder( + &self, + group_key: &'a CheckGroupKey<'a>, + group_info: CheckGroupInfo, + ) -> Result { + fn log_provided_roots(provided_roots: &[Url]) { + for root in provided_roots { + log::info!( + "{} {}", + colors::green("Check"), + to_percent_decoded_str(root.as_str()) + ); } - }; + } + + // walk the graph + let ts_config = group_key.ts_config; + let mut graph_walker = GraphWalker::new( + &self.graph, + self.sys, + self.node_resolver, + self.npm_resolver, + self.tsconfig_resolver, + self.npm_check_state_hash, + ts_config.as_ref(), + self.options.type_check_mode, + ); + let mut provided_roots = group_info.roots; + for import in group_key.imports.iter() { + graph_walker.add_config_import(import, &group_info.referrer); + } + + for root in &provided_roots { + graph_walker.add_root(root); + } + let TscRoots { roots: root_names, missing_diagnostics, maybe_check_hash, - } = get_tsc_roots( - &self.sys, - &self.npm_resolver, - &self.node_resolver, - &graph, - check_js, - check_state_hash(&self.npm_resolver), - type_check_mode, - &ts_config, - ); + } = graph_walker.into_tsc_roots(); - let missing_diagnostics = - missing_diagnostics.filter(filter_remote_diagnostics); + let mut missing_diagnostics = missing_diagnostics.filter(|d| { + self.should_include_diagnostic(self.options.type_check_mode, d) + }); + missing_diagnostics.apply_fast_check_source_maps(&self.graph); - if root_names.is_empty() && missing_diagnostics.is_empty() { - return Ok((graph.into(), Default::default())); + if root_names.is_empty() { + if missing_diagnostics.has_diagnostic() { + log_provided_roots(&provided_roots); + } + return Ok(missing_diagnostics); } - if !options.reload { + + if !self.options.reload && !missing_diagnostics.has_diagnostic() { // do not type check if we know this is type checked if let Some(check_hash) = maybe_check_hash { - if cache.has_check_hash(check_hash) { - log::debug!("Already type checked."); - return Ok((graph.into(), Default::default())); + if self.type_check_cache.has_check_hash(check_hash) { + log::debug!("Already type checked {}", group_info.referrer); + return Ok(Default::default()); } } } - for root in &graph.roots { - let root_str = root.as_str(); - log::info!( - "{} {}", - colors::green("Check"), - to_percent_decoded_str(root_str) - ); - } + // log out the roots that we're checking + log_provided_roots(&provided_roots); + + // the first root will always either be the specifier that the user provided + // or the first specifier in a directory + let first_root = provided_roots.remove(0); // while there might be multiple roots, we can't "merge" the build info, so we // try to retrieve the build info for first root, which is the most common use // case. - let maybe_tsbuildinfo = if options.reload { + let maybe_tsbuildinfo = if self.options.reload { None } else { - cache.get_tsbuildinfo(&graph.roots[0]) + self.type_check_cache.get_tsbuildinfo(&first_root) }; // to make tsc build info work, we need to consistently hash modules, so that // tsc can better determine if an emit is still valid or not, so we provide // that data here. let tsconfig_hash_data = FastInsecureHasher::new_deno_versioned() - .write(&ts_config.as_bytes()) + .write_hashable(ts_config) .finish(); - let graph = Arc::new(graph); let response = tsc::exec(tsc::Request { - config: ts_config, - debug: self.cli_options.log_level() == Some(log::Level::Debug), - graph: graph.clone(), + config: ts_config.clone(), + debug: self.log_level == Some(log::Level::Debug), + graph: self.graph.clone(), hash_data: tsconfig_hash_data, maybe_npm: Some(tsc::RequestNpmState { cjs_tracker: self.cjs_tracker.clone(), @@ -323,30 +562,46 @@ impl TypeChecker { }), maybe_tsbuildinfo, root_names, - check_mode: type_check_mode, + check_mode: self.options.type_check_mode, })?; - let response_diagnostics = - response.diagnostics.filter(filter_remote_diagnostics); - + let mut response_diagnostics = response.diagnostics.filter(|d| { + self.should_include_diagnostic(self.options.type_check_mode, d) + }); + response_diagnostics.apply_fast_check_source_maps(&self.graph); let mut diagnostics = missing_diagnostics; diagnostics.extend(response_diagnostics); - diagnostics.apply_fast_check_source_maps(&graph); - if let Some(tsbuildinfo) = response.maybe_tsbuildinfo { - cache.set_tsbuildinfo(&graph.roots[0], &tsbuildinfo); + self + .type_check_cache + .set_tsbuildinfo(&first_root, &tsbuildinfo); } - if diagnostics.is_empty() { + if !diagnostics.has_diagnostic() { if let Some(check_hash) = maybe_check_hash { - cache.add_check_hash(check_hash); + self.type_check_cache.add_check_hash(check_hash); } } log::debug!("{}", response.stats); - Ok((graph, diagnostics)) + Ok(diagnostics) + } + + fn should_include_diagnostic( + &self, + type_check_mode: TypeCheckMode, + d: &tsc::Diagnostic, + ) -> bool { + // this shouldn't check for duplicate diagnostics across folders because + // we don't want to accidentally mark a folder as being successful and save + // to the check cache if a previous folder caused a diagnostic + if self.is_remote_diagnostic(d) { + type_check_mode == TypeCheckMode::All && d.include_when_remote() + } else { + true + } } fn is_remote_diagnostic(&self, d: &tsc::Diagnostic) -> bool { @@ -370,27 +625,201 @@ struct TscRoots { maybe_check_hash: Option, } -/// Transform the graph into root specifiers that we can feed `tsc`. We have to -/// provide the media type for root modules because `tsc` does not "resolve" the -/// media type like other modules, as well as a root specifier needs any -/// redirects resolved. We need to include all the emittable files in -/// the roots, so they get type checked and optionally emitted, -/// otherwise they would be ignored if only imported into JavaScript. -#[allow(clippy::too_many_arguments)] -fn get_tsc_roots( - sys: &CliSys, - npm_resolver: &CliNpmResolver, - node_resolver: &CliNodeResolver, - graph: &ModuleGraph, - check_js: bool, - npm_cache_state_hash: Option, - type_check_mode: TypeCheckMode, - ts_config: &TsConfig, -) -> TscRoots { +struct GraphWalker<'a> { + graph: &'a ModuleGraph, + sys: &'a CliSys, + node_resolver: &'a CliNodeResolver, + npm_resolver: &'a CliNpmResolver, + tsconfig_resolver: &'a TsConfigResolver, + maybe_hasher: Option, + seen: HashSet<&'a Url>, + pending: VecDeque<(&'a Url, bool)>, + has_seen_node_builtin: bool, + roots: Vec<(ModuleSpecifier, MediaType)>, + missing_diagnostics: tsc::Diagnostics, +} + +impl<'a> GraphWalker<'a> { + #[allow(clippy::too_many_arguments)] + pub fn new( + graph: &'a ModuleGraph, + sys: &'a CliSys, + node_resolver: &'a CliNodeResolver, + npm_resolver: &'a CliNpmResolver, + tsconfig_resolver: &'a TsConfigResolver, + npm_cache_state_hash: Option, + ts_config: &TsConfig, + type_check_mode: TypeCheckMode, + ) -> Self { + let maybe_hasher = npm_cache_state_hash.map(|npm_cache_state_hash| { + let mut hasher = FastInsecureHasher::new_deno_versioned(); + hasher.write_hashable(npm_cache_state_hash); + hasher.write_u8(match type_check_mode { + TypeCheckMode::All => 0, + TypeCheckMode::Local => 1, + TypeCheckMode::None => 2, + }); + hasher.write_hashable(graph.has_node_specifier); + hasher.write_hashable(ts_config); + hasher + }); + Self { + graph, + sys, + node_resolver, + npm_resolver, + tsconfig_resolver, + maybe_hasher, + seen: HashSet::with_capacity( + graph.imports.len() + graph.specifiers_count(), + ), + pending: VecDeque::new(), + has_seen_node_builtin: false, + roots: Vec::with_capacity(graph.imports.len() + graph.specifiers_count()), + missing_diagnostics: Default::default(), + } + } + + pub fn add_config_import(&mut self, specifier: &'a Url, referrer: &Url) { + let specifier = self.graph.resolve(specifier); + if self.seen.insert(specifier) { + if let Ok(nv_ref) = NpmPackageNvReference::from_specifier(specifier) { + match self.resolve_npm_nv_ref(&nv_ref, referrer) { + Some(resolved) => { + let mt = MediaType::from_specifier(&resolved); + self.roots.push((resolved, mt)); + } + None => { + self + .missing_diagnostics + .push(tsc::Diagnostic::from_missing_error( + specifier, + None, + maybe_additional_sloppy_imports_message(self.sys, specifier), + )); + } + } + } else { + self.pending.push_back((specifier, false)); + self.resolve_pending(); + } + } + } + + pub fn add_root(&mut self, root: &'a Url) { + let specifier = self.graph.resolve(root); + if self.seen.insert(specifier) { + self.pending.push_back((specifier, false)); + } + + self.resolve_pending() + } + + /// Transform the graph into root specifiers that we can feed `tsc`. We have to + /// provide the media type for root modules because `tsc` does not "resolve" the + /// media type like other modules, as well as a root specifier needs any + /// redirects resolved. We need to include all the emittable files in + /// the roots, so they get type checked and optionally emitted, + /// otherwise they would be ignored if only imported into JavaScript. + pub fn into_tsc_roots(self) -> TscRoots { + TscRoots { + roots: self.roots, + missing_diagnostics: self.missing_diagnostics, + maybe_check_hash: self.maybe_hasher.map(|h| CacheDBHash::new(h.finish())), + } + } + + fn resolve_pending(&mut self) { + while let Some((specifier, is_dynamic)) = self.pending.pop_front() { + let module = match self.graph.try_get(specifier) { + Ok(Some(module)) => module, + Ok(None) => continue, + Err(ModuleError::Missing(specifier, maybe_range)) => { + if !is_dynamic { + self + .missing_diagnostics + .push(tsc::Diagnostic::from_missing_error( + specifier, + maybe_range.as_ref(), + maybe_additional_sloppy_imports_message(self.sys, specifier), + )); + } + continue; + } + Err(ModuleError::LoadingErr( + specifier, + maybe_range, + ModuleLoadError::Loader(_), + )) => { + // these will be errors like attempting to load a directory + if !is_dynamic { + self + .missing_diagnostics + .push(tsc::Diagnostic::from_missing_error( + specifier, + maybe_range.as_ref(), + maybe_additional_sloppy_imports_message(self.sys, specifier), + )); + } + continue; + } + Err(_) => continue, + }; + if is_dynamic && !self.seen.insert(specifier) { + continue; + } + if let Some(entry) = self.maybe_get_check_entry(module) { + self.roots.push(entry); + } + + let mut maybe_module_dependencies = None; + let mut maybe_types_dependency = None; + match module { + Module::Js(module) => { + maybe_module_dependencies = + Some(module.dependencies_prefer_fast_check()); + maybe_types_dependency = module + .maybe_types_dependency + .as_ref() + .and_then(|d| d.dependency.ok()); + } + Module::Wasm(module) => { + maybe_module_dependencies = Some(&module.dependencies); + } + Module::Json(_) | Module::Npm(_) | Module::External(_) => {} + Module::Node(_) => { + if !self.has_seen_node_builtin { + self.has_seen_node_builtin = true; + // inject a specifier that will resolve node types + self.roots.push(( + ModuleSpecifier::parse("asset:///node_types.d.ts").unwrap(), + MediaType::Dts, + )); + } + } + } + + if let Some(deps) = maybe_module_dependencies { + for dep in deps.values() { + // walk both the code and type dependencies + if let Some(specifier) = dep.get_code() { + self.handle_specifier(specifier, dep.is_dynamic); + } + if let Some(specifier) = dep.get_type() { + self.handle_specifier(specifier, dep.is_dynamic); + } + } + } + + if let Some(dep) = maybe_types_dependency { + self.handle_specifier(&dep.specifier, false); + } + } + } + fn maybe_get_check_entry( + &mut self, module: &deno_graph::Module, - check_js: bool, - hasher: Option<&mut FastInsecureHasher>, ) -> Option<(ModuleSpecifier, MediaType)> { match module { Module::Js(module) => { @@ -408,7 +837,11 @@ fn get_tsc_roots( | MediaType::Mjs | MediaType::Cjs | MediaType::Jsx => { - if check_js || has_ts_check(module.media_type, &module.source) { + if self + .tsconfig_resolver + .check_js_for_specifier(&module.specifier) + || has_ts_check(module.media_type, &module.source) + { Some((module.specifier.clone(), module.media_type)) } else { None @@ -421,7 +854,7 @@ fn get_tsc_roots( | MediaType::Unknown => None, }; if result.is_some() { - if let Some(hasher) = hasher { + if let Some(hasher) = &mut self.maybe_hasher { hasher.write_str(module.specifier.as_str()); hasher.write_str( // the fast check module will only be set when publishing @@ -446,21 +879,21 @@ fn get_tsc_roots( None } Module::Json(module) => { - if let Some(hasher) = hasher { + if let Some(hasher) = &mut self.maybe_hasher { hasher.write_str(module.specifier.as_str()); hasher.write_str(&module.source); } None } Module::Wasm(module) => { - if let Some(hasher) = hasher { + if let Some(hasher) = &mut self.maybe_hasher { hasher.write_str(module.specifier.as_str()); hasher.write_str(&module.source_dts); } Some((module.specifier.clone(), MediaType::Dmts)) } Module::External(module) => { - if let Some(hasher) = hasher { + if let Some(hasher) = &mut self.maybe_hasher { hasher.write_str(module.specifier.as_str()); } @@ -469,205 +902,44 @@ fn get_tsc_roots( } } - let mut result = TscRoots { - roots: Vec::with_capacity(graph.specifiers_count()), - missing_diagnostics: Default::default(), - maybe_check_hash: None, - }; - let mut maybe_hasher = npm_cache_state_hash.map(|npm_cache_state_hash| { - let mut hasher = FastInsecureHasher::new_deno_versioned(); - hasher.write_hashable(npm_cache_state_hash); - hasher.write_u8(match type_check_mode { - TypeCheckMode::All => 0, - TypeCheckMode::Local => 1, - TypeCheckMode::None => 2, - }); - hasher.write_hashable(graph.has_node_specifier); - hasher.write(&ts_config.as_bytes()); - hasher - }); - - if graph.has_node_specifier { - // inject a specifier that will resolve node types - result.roots.push(( - ModuleSpecifier::parse("asset:///node_types.d.ts").unwrap(), - MediaType::Dts, - )); - } - - let mut seen = - HashSet::with_capacity(graph.imports.len() + graph.specifiers_count()); - let mut pending = VecDeque::new(); - - // put in the global types first so that they're resolved before anything else - for (referrer, import) in graph.imports.iter() { - for specifier in import - .dependencies - .values() - .filter_map(|dep| dep.get_type().or_else(|| dep.get_code())) - { - let specifier = graph.resolve(specifier); - if seen.insert(specifier) { - if let Ok(nv_ref) = NpmPackageNvReference::from_specifier(specifier) { - let Some(resolved) = - resolve_npm_nv_ref(npm_resolver, node_resolver, &nv_ref, referrer) - else { - result.missing_diagnostics.push( - tsc::Diagnostic::from_missing_error( - specifier, - None, - maybe_additional_sloppy_imports_message(sys, specifier), - ), - ); - continue; - }; - let mt = MediaType::from_specifier(&resolved); - result.roots.push((resolved, mt)); - } else { - pending.push_back((specifier, false)); - } + fn handle_specifier( + &mut self, + specifier: &'a ModuleSpecifier, + is_dynamic: bool, + ) { + let specifier = self.graph.resolve(specifier); + if is_dynamic { + if !self.seen.contains(specifier) { + self.pending.push_back((specifier, true)); } + } else if self.seen.insert(specifier) { + self.pending.push_back((specifier, false)); } } - // then the roots - for root in &graph.roots { - let specifier = graph.resolve(root); - if seen.insert(specifier) { - pending.push_back((specifier, false)); - } + fn resolve_npm_nv_ref( + &self, + nv_ref: &NpmPackageNvReference, + referrer: &ModuleSpecifier, + ) -> Option { + let pkg_dir = self + .npm_resolver + .as_managed() + .unwrap() + .resolve_pkg_folder_from_deno_module(nv_ref.nv()) + .ok()?; + let resolved = self + .node_resolver + .resolve_package_subpath_from_deno_module( + &pkg_dir, + nv_ref.sub_path(), + Some(referrer), + node_resolver::ResolutionMode::Import, + node_resolver::NodeResolutionKind::Types, + ) + .ok()?; + resolved.into_url().ok() } - - // now walk the graph that only includes the fast check dependencies - while let Some((specifier, is_dynamic)) = pending.pop_front() { - let module = match graph.try_get(specifier) { - Ok(Some(module)) => module, - Ok(None) => continue, - Err(ModuleError::Missing(specifier, maybe_range)) => { - if !is_dynamic { - result - .missing_diagnostics - .push(tsc::Diagnostic::from_missing_error( - specifier, - maybe_range.as_ref(), - maybe_additional_sloppy_imports_message(sys, specifier), - )); - } - continue; - } - Err(ModuleError::LoadingErr( - specifier, - maybe_range, - ModuleLoadError::Loader(_), - )) => { - // these will be errors like attempting to load a directory - if !is_dynamic { - result - .missing_diagnostics - .push(tsc::Diagnostic::from_missing_error( - specifier, - maybe_range.as_ref(), - maybe_additional_sloppy_imports_message(sys, specifier), - )); - } - continue; - } - Err(_) => continue, - }; - if is_dynamic && !seen.insert(specifier) { - continue; - } - if let Some(entry) = - maybe_get_check_entry(module, check_js, maybe_hasher.as_mut()) - { - result.roots.push(entry); - } - - let mut maybe_module_dependencies = None; - let mut maybe_types_dependency = None; - if let Module::Js(module) = module { - maybe_module_dependencies = Some(module.dependencies_prefer_fast_check()); - maybe_types_dependency = module - .maybe_types_dependency - .as_ref() - .and_then(|d| d.dependency.ok()); - } else if let Module::Wasm(module) = module { - maybe_module_dependencies = Some(&module.dependencies); - } - - fn handle_specifier<'a>( - graph: &'a ModuleGraph, - seen: &mut HashSet<&'a ModuleSpecifier>, - pending: &mut VecDeque<(&'a ModuleSpecifier, bool)>, - specifier: &'a ModuleSpecifier, - is_dynamic: bool, - ) { - let specifier = graph.resolve(specifier); - if is_dynamic { - if !seen.contains(specifier) { - pending.push_back((specifier, true)); - } - } else if seen.insert(specifier) { - pending.push_back((specifier, false)); - } - } - - if let Some(deps) = maybe_module_dependencies { - for dep in deps.values() { - // walk both the code and type dependencies - if let Some(specifier) = dep.get_code() { - handle_specifier( - graph, - &mut seen, - &mut pending, - specifier, - dep.is_dynamic, - ); - } - if let Some(specifier) = dep.get_type() { - handle_specifier( - graph, - &mut seen, - &mut pending, - specifier, - dep.is_dynamic, - ); - } - } - } - - if let Some(dep) = maybe_types_dependency { - handle_specifier(graph, &mut seen, &mut pending, &dep.specifier, false); - } - } - - result.maybe_check_hash = - maybe_hasher.map(|hasher| CacheDBHash::new(hasher.finish())); - - result -} - -fn resolve_npm_nv_ref( - npm_resolver: &CliNpmResolver, - node_resolver: &CliNodeResolver, - nv_ref: &NpmPackageNvReference, - referrer: &ModuleSpecifier, -) -> Option { - let pkg_dir = npm_resolver - .as_managed() - .unwrap() - .resolve_pkg_folder_from_deno_module(nv_ref.nv()) - .ok()?; - let resolved = node_resolver - .resolve_package_subpath_from_deno_module( - &pkg_dir, - nv_ref.sub_path(), - Some(referrer), - node_resolver::ResolutionMode::Import, - node_resolver::NodeResolutionKind::Types, - ) - .ok()?; - resolved.into_url().ok() } /// Matches the `@ts-check` pragma. diff --git a/cli/tools/compile.rs b/cli/tools/compile.rs index 96dd6798f5..75a36e7896 100644 --- a/cli/tools/compile.rs +++ b/cli/tools/compile.rs @@ -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"), diff --git a/cli/tools/coverage/mod.rs b/cli/tools/coverage/mod.rs index 53c08191f7..31c41126ec 100644 --- a/cli/tools/coverage/mod.rs +++ b/cli/tools/coverage/mod.rs @@ -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!( diff --git a/cli/tools/doc.rs b/cli/tools/doc.rs index ebb90c08e9..ef45d08191 100644 --- a/cli/tools/doc.rs +++ b/cli/tools/doc.rs @@ -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, }, ); diff --git a/cli/tools/jupyter/mod.rs b/cli/tools/jupyter/mod.rs index 67c604118c..211f3b90ee 100644 --- a/cli/tools/jupyter/mod.rs +++ b/cli/tools/jupyter/mod.rs @@ -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, diff --git a/cli/tools/lint/mod.rs b/cli/tools/lint/mod.rs index 29ae3e7a3f..49a5c6896b 100644 --- a/cli/tools/lint/mod.rs +++ b/cli/tools/lint/mod.rs @@ -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, lint_rule_provider: LintRuleProvider, module_graph_creator: Arc, + tsconfig_resolver: Arc, workspace_dir: Arc, reporter_lock: Arc>>, workspace_module_graph: Option, @@ -254,6 +254,7 @@ impl WorkspaceLinter { caches: Arc, lint_rule_provider: LintRuleProvider, module_graph_creator: Arc, + tsconfig_resolver: Arc, workspace_dir: Arc, 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, lint_options: LintOptions, - lint_config: DenoLintConfig, member_dir: WorkspaceDirectory, paths: Vec, ) -> 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 { 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, diff --git a/cli/tools/registry/graph.rs b/cli/tools/registry/graph.rs index 7152675ff8..0d60fa672e 100644 --- a/cli/tools/registry/graph.rs +++ b/cli/tools/registry/graph.rs @@ -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, diff --git a/cli/tools/registry/mod.rs b/cli/tools/registry/mod.rs index ea457f8a71..c2ed94e847 100644 --- a/cli/tools/registry/mod.rs +++ b/cli/tools/registry/mod.rs @@ -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()) } } } diff --git a/cli/tools/repl/mod.rs b/cli/tools/repl/mod.rs index 6a42688aca..579c24fcd4 100644 --- a/cli/tools/repl/mod.rs +++ b/cli/tools/repl/mod.rs @@ -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, diff --git a/cli/tools/repl/session.rs b/cli/tools/repl/session.rs index 2d969123ab..58f441eff0 100644 --- a/cli/tools/repl/session.rs +++ b/cli/tools/repl/session.rs @@ -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>, resolver: Arc, + 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, diff --git a/cli/tsc/diagnostics.rs b/cli/tsc/diagnostics.rs index 3780f65e77..73d2015942 100644 --- a/cli/tsc/diagnostics.rs +++ b/cli/tsc/diagnostics.rs @@ -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

(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)] diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index 943c202af5..1a3e1b11e9 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -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, /// Indicates to the tsc runtime if debug logging should occur. pub debug: bool, pub graph: Arc, @@ -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()); } } diff --git a/cli/util/collections.rs b/cli/util/collections.rs new file mode 100644 index 0000000000..995f1d66a1 --- /dev/null +++ b/cli/util/collections.rs @@ -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 { + unscoped: TValue, + scoped: BTreeMap, TValue>, +} + +impl std::fmt::Debug for FolderScopedMap +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 Default for FolderScopedMap +where + TValue: Default, +{ + fn default() -> Self { + Self::new(Default::default()) + } +} + +impl FolderScopedMap { + 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, 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); + } +} diff --git a/cli/util/mod.rs b/cli/util/mod.rs index 13c2eee5cb..6a5e9979f7 100644 --- a/cli/util/mod.rs +++ b/cli/util/mod.rs @@ -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; diff --git a/tests/integration/check_tests.rs b/tests/integration/check_tests.rs index 15a2d96d04..b9f444a879 100644 --- a/tests/integration/check_tests.rs +++ b/tests/integration/check_tests.rs @@ -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); } diff --git a/tests/integration/compile_tests.rs b/tests/integration/compile_tests.rs index dd4ce3ea9a..503538d24a 100644 --- a/tests/integration/compile_tests.rs +++ b/tests/integration/compile_tests.rs @@ -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); } diff --git a/tests/integration/jsr_tests.rs b/tests/integration/jsr_tests.rs index 683c8ef85d..2ba3bc84d6 100644 --- a/tests/integration/jsr_tests.rs +++ b/tests/integration/jsr_tests.rs @@ -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); diff --git a/tests/integration/run_tests.rs b/tests/integration/run_tests.rs index a5d9273e28..5485c6e4eb 100644 --- a/tests/integration/run_tests.rs +++ b/tests/integration/run_tests.rs @@ -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()); diff --git a/tests/integration/watcher_tests.rs b/tests/integration/watcher_tests.rs index a180be2fb3..3ad89c6420 100644 --- a/tests/integration/watcher_tests.rs +++ b/tests/integration/watcher_tests.rs @@ -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(), diff --git a/tests/specs/bench/check_local_by_default2/check_local_by_default2.out b/tests/specs/bench/check_local_by_default2/check_local_by_default2.out index 089b17f4b8..7ebc39c48a 100644 --- a/tests/specs/bench/check_local_by_default2/check_local_by_default2.out +++ b/tests/specs/bench/check_local_by_default2/check_local_by_default2.out @@ -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. diff --git a/tests/specs/bench/no_run/no_run.out b/tests/specs/bench/no_run/no_run.out index 77ce18366a..c048f2b1d8 100644 --- a/tests/specs/bench/no_run/no_run.out +++ b/tests/specs/bench/no_run/no_run.out @@ -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. diff --git a/tests/specs/check/check_all/check_all.out b/tests/specs/check/check_all/check_all.out index 3442646348..dc733677fa 100644 --- a/tests/specs/check/check_all/check_all.out +++ b/tests/specs/check/check_all/check_all.out @@ -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. diff --git a/tests/specs/check/check_deno_not_found/deno_not_found/main.out b/tests/specs/check/check_deno_not_found/deno_not_found/main.out index 2b6f44d1e2..de6c5ce8bd 100644 --- a/tests/specs/check/check_deno_not_found/deno_not_found/main.out +++ b/tests/specs/check/check_deno_not_found/deno_not_found/main.out @@ -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): /// +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): /// Deno; ~~~~ at file:///[WILDCARD]/deno_not_found/main.ts:4:1 + +error: Type checking failed. diff --git a/tests/specs/check/check_dts/dts/check_dts.out b/tests/specs/check/check_dts/dts/check_dts.out index e7ff9a0090..4d16207807 100644 --- a/tests/specs/check/check_dts/dts/check_dts.out +++ b/tests/specs/check/check_dts/dts/check_dts.out @@ -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. diff --git a/tests/specs/check/check_exclude_option/exclude_option.ts.error.out b/tests/specs/check/check_exclude_option/exclude_option.ts.error.out index abd1c12586..bfe5bf08bc 100644 --- a/tests/specs/check/check_exclude_option/exclude_option.ts.error.out +++ b/tests/specs/check/check_exclude_option/exclude_option.ts.error.out @@ -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. diff --git a/tests/specs/check/check_imported_files_listed_in_exclude_option/exclude_option/exclude_option.ts.error.out b/tests/specs/check/check_imported_files_listed_in_exclude_option/exclude_option/exclude_option.ts.error.out index abd1c12586..bfe5bf08bc 100644 --- a/tests/specs/check/check_imported_files_listed_in_exclude_option/exclude_option/exclude_option.ts.error.out +++ b/tests/specs/check/check_imported_files_listed_in_exclude_option/exclude_option/exclude_option.ts.error.out @@ -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. diff --git a/tests/specs/check/check_no_error_truncation/no_error_truncation/main.out b/tests/specs/check/check_no_error_truncation/no_error_truncation/main.out index 13fd5aae44..760d9c9553 100644 --- a/tests/specs/check/check_no_error_truncation/no_error_truncation/main.out +++ b/tests/specs/check/check_no_error_truncation/no_error_truncation/main.out @@ -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. diff --git a/tests/specs/check/check_node_builtin_modules/mod.js.out b/tests/specs/check/check_node_builtin_modules/mod.js.out index 646a2e5cc4..830fe4a4a8 100644 --- a/tests/specs/check/check_node_builtin_modules/mod.js.out +++ b/tests/specs/check/check_node_builtin_modules/mod.js.out @@ -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. diff --git a/tests/specs/check/check_node_builtin_modules/mod.ts.out b/tests/specs/check/check_node_builtin_modules/mod.ts.out index 38eef5edc7..638dd640d4 100644 --- a/tests/specs/check/check_node_builtin_modules/mod.ts.out +++ b/tests/specs/check/check_node_builtin_modules/mod.ts.out @@ -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. diff --git a/tests/specs/check/check_npm_install_diagnostics/npm_install_diagnostics/main.out b/tests/specs/check/check_npm_install_diagnostics/npm_install_diagnostics/main.out index fe46f0e423..bd9f5aae4e 100644 --- a/tests/specs/check/check_npm_install_diagnostics/npm_install_diagnostics/main.out +++ b/tests/specs/check/check_npm_install_diagnostics/npm_install_diagnostics/main.out @@ -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. diff --git a/tests/specs/check/check_workspace/__test__.jsonc b/tests/specs/check/check_workspace/__test__.jsonc new file mode 100644 index 0000000000..19677cbb7f --- /dev/null +++ b/tests/specs/check/check_workspace/__test__.jsonc @@ -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 + } + } +} diff --git a/tests/specs/check/check_workspace/check_config_flag.out b/tests/specs/check/check_workspace/check_config_flag.out new file mode 100644 index 0000000000..6aaa6cded3 --- /dev/null +++ b/tests/specs/check/check_workspace/check_config_flag.out @@ -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. diff --git a/tests/specs/check/check_workspace/check_discover.out b/tests/specs/check/check_workspace/check_discover.out new file mode 100644 index 0000000000..6aaa6cded3 --- /dev/null +++ b/tests/specs/check/check_workspace/check_discover.out @@ -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. diff --git a/tests/specs/check/check_workspace/deno.json b/tests/specs/check/check_workspace/deno.json new file mode 100644 index 0000000000..c914638468 --- /dev/null +++ b/tests/specs/check/check_workspace/deno.json @@ -0,0 +1,3 @@ +{ + "workspace": ["member"] +} diff --git a/tests/specs/check/check_workspace/main.ts b/tests/specs/check/check_workspace/main.ts new file mode 100644 index 0000000000..478e266dd3 --- /dev/null +++ b/tests/specs/check/check_workspace/main.ts @@ -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; diff --git a/tests/specs/check/check_workspace/member/deno.json b/tests/specs/check/check_workspace/member/deno.json new file mode 100644 index 0000000000..00feda1e44 --- /dev/null +++ b/tests/specs/check/check_workspace/member/deno.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "lib": ["deno.worker"] + } +} diff --git a/tests/specs/check/check_workspace/member/mod.ts b/tests/specs/check/check_workspace/member/mod.ts new file mode 100644 index 0000000000..846c13a74a --- /dev/null +++ b/tests/specs/check/check_workspace/member/mod.ts @@ -0,0 +1,5 @@ +// Only defined for window. +localStorage; + +// Only defined for worker. +onmessage; diff --git a/tests/specs/check/cjs_default_export/main.out b/tests/specs/check/cjs_default_export/main.out index 6c5f18b632..a5252c4434 100644 --- a/tests/specs/check/cjs_default_export/main.out +++ b/tests/specs/check/cjs_default_export/main.out @@ -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. diff --git a/tests/specs/check/css_import/exists_and_try_uses.out b/tests/specs/check/css_import/exists_and_try_uses.out index b51ea2391a..16b67b4c3e 100644 --- a/tests/specs/check/css_import/exists_and_try_uses.out +++ b/tests/specs/check/css_import/exists_and_try_uses.out @@ -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. diff --git a/tests/specs/check/css_import/not_exists.out b/tests/specs/check/css_import/not_exists.out index 1e9dce6b70..85e8edbf52 100644 --- a/tests/specs/check/css_import/not_exists.out +++ b/tests/specs/check/css_import/not_exists.out @@ -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. diff --git a/tests/specs/check/dts_importing_non_existent/check.out b/tests/specs/check/dts_importing_non_existent/check.out index 65e27bce83..5e1f49452d 100644 --- a/tests/specs/check/dts_importing_non_existent/check.out +++ b/tests/specs/check/dts_importing_non_existent/check.out @@ -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. diff --git a/tests/specs/check/globbing/__test__.jsonc b/tests/specs/check/globbing/__test__.jsonc index 92d9f4d807..73df1de4d1 100644 --- a/tests/specs/check/globbing/__test__.jsonc +++ b/tests/specs/check/globbing/__test__.jsonc @@ -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 } } diff --git a/tests/specs/check/import_non_existent_in_remote/check_all.out b/tests/specs/check/import_non_existent_in_remote/check_all.out index a3c3b1759c..3fb2e0101a 100644 --- a/tests/specs/check/import_non_existent_in_remote/check_all.out +++ b/tests/specs/check/import_non_existent_in_remote/check_all.out @@ -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. diff --git a/tests/specs/check/jsdoc_import_decl/check.out b/tests/specs/check/jsdoc_import_decl/check.out index 657569bcd4..5757dfe40f 100644 --- a/tests/specs/check/jsdoc_import_decl/check.out +++ b/tests/specs/check/jsdoc_import_decl/check.out @@ -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. diff --git a/tests/specs/check/jsx_not_checked/jsx_not_checked/main.out b/tests/specs/check/jsx_not_checked/jsx_not_checked/main.out index 25165044ca..3ac9eb8d31 100644 --- a/tests/specs/check/jsx_not_checked/jsx_not_checked/main.out +++ b/tests/specs/check/jsx_not_checked/jsx_not_checked/main.out @@ -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. diff --git a/tests/specs/check/message_chain_formatting/message_chain_formatting.out b/tests/specs/check/message_chain_formatting/message_chain_formatting.out index ca5c646ccb..69104c8c6a 100644 --- a/tests/specs/check/message_chain_formatting/message_chain_formatting.out +++ b/tests/specs/check/message_chain_formatting/message_chain_formatting.out @@ -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. diff --git a/tests/specs/check/module_not_found/main.out b/tests/specs/check/module_not_found/main.out index 6c16183560..b7d99c70e3 100644 --- a/tests/specs/check/module_not_found/main.out +++ b/tests/specs/check/module_not_found/main.out @@ -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. diff --git a/tests/specs/check/module_not_found/missing_local_root.out b/tests/specs/check/module_not_found/missing_local_root.out index 34b150c9a3..a22ab9cc3b 100644 --- a/tests/specs/check/module_not_found/missing_local_root.out +++ b/tests/specs/check/module_not_found/missing_local_root.out @@ -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. diff --git a/tests/specs/check/module_not_found/missing_remote_root.out b/tests/specs/check/module_not_found/missing_remote_root.out index e408938e41..7eae8d2c1b 100644 --- a/tests/specs/check/module_not_found/missing_remote_root.out +++ b/tests/specs/check/module_not_found/missing_remote_root.out @@ -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. diff --git a/tests/specs/check/no_implicit_override/main.out b/tests/specs/check/no_implicit_override/main.out index 6fd6573419..465a7d575e 100644 --- a/tests/specs/check/no_implicit_override/main.out +++ b/tests/specs/check/no_implicit_override/main.out @@ -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. diff --git a/tests/specs/check/npm_pkg_empty_main_entry/check.out b/tests/specs/check/npm_pkg_empty_main_entry/check.out index 9fcc4b290f..de1c9c921f 100644 --- a/tests/specs/check/npm_pkg_empty_main_entry/check.out +++ b/tests/specs/check/npm_pkg_empty_main_entry/check.out @@ -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. diff --git a/tests/specs/check/package_json_fail_check/fail_check.out b/tests/specs/check/package_json_fail_check/fail_check.out index 03997a0518..c09fae56c2 100644 --- a/tests/specs/check/package_json_fail_check/fail_check.out +++ b/tests/specs/check/package_json_fail_check/fail_check.out @@ -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. diff --git a/tests/specs/check/package_json_with_deno_json/check.out b/tests/specs/check/package_json_with_deno_json/check.out index 53b6869c03..482f319b3d 100644 --- a/tests/specs/check/package_json_with_deno_json/check.out +++ b/tests/specs/check/package_json_with_deno_json/check.out @@ -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. diff --git a/tests/specs/check/reject_string_in_readable_stream_from/main.out b/tests/specs/check/reject_string_in_readable_stream_from/main.out index 577c1fb059..0f21164de8 100644 --- a/tests/specs/check/reject_string_in_readable_stream_from/main.out +++ b/tests/specs/check/reject_string_in_readable_stream_from/main.out @@ -1,5 +1,7 @@ Check [WILDCARD]/main.ts -error: TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'AsyncIterable | (Iterable> & object)'. +TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'AsyncIterable | (Iterable> & object)'. ReadableStream.from("string"); ~~~~~~~~ at [WILDCARD]/main.ts:1:21 + +error: Type checking failed. diff --git a/tests/specs/check/typecheck_doc_failure/mod.out b/tests/specs/check/typecheck_doc_failure/mod.out index 61fd5499e5..fb35b5128a 100644 --- a/tests/specs/check/typecheck_doc_failure/mod.out +++ b/tests/specs/check/typecheck_doc_failure/mod.out @@ -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. diff --git a/tests/specs/check/typecheck_doc_in_markdown/markdown.out b/tests/specs/check/typecheck_doc_in_markdown/markdown.out index acc05dc818..f8299c3b03 100644 --- a/tests/specs/check/typecheck_doc_in_markdown/markdown.out +++ b/tests/specs/check/typecheck_doc_in_markdown/markdown.out @@ -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. diff --git a/tests/specs/check/types_resolved_relative_config/main.out b/tests/specs/check/types_resolved_relative_config/main.out index 5763d3298c..f624bd880a 100644 --- a/tests/specs/check/types_resolved_relative_config/main.out +++ b/tests/specs/check/types_resolved_relative_config/main.out @@ -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. diff --git a/tests/specs/check/unstable_suggestion/main.out b/tests/specs/check/unstable_suggestion/main.out index 9926c9e3cc..d6d57e2635 100644 --- a/tests/specs/check/unstable_suggestion/main.out +++ b/tests/specs/check/unstable_suggestion/main.out @@ -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): /// +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): /// Deno.listenDatagram({ ~~~~~~~~~~~~~~ at file:///[WILDLINE]/main.ts:5:6 + +error: Type checking failed. diff --git a/tests/specs/check/unstable_suggestion/no_default_lib.out b/tests/specs/check/unstable_suggestion/no_default_lib.out index 1ec2ae3e5d..9de20d5673 100644 --- a/tests/specs/check/unstable_suggestion/no_default_lib.out +++ b/tests/specs/check/unstable_suggestion/no_default_lib.out @@ -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): /// +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): /// console.log(Deno); ~~~~ at file:///[WILDLINE]/no_default_lib.ts:5:13 + +error: Type checking failed. diff --git a/tests/specs/check/use_unknown_in_catch_variables/main.out b/tests/specs/check/use_unknown_in_catch_variables/main.out index 28236849e3..a7ad6dedc1 100644 --- a/tests/specs/check/use_unknown_in_catch_variables/main.out +++ b/tests/specs/check/use_unknown_in_catch_variables/main.out @@ -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. diff --git a/tests/specs/check/wasm/check.out b/tests/specs/check/wasm/check.out index b3a23646db..05f4697ec6 100644 --- a/tests/specs/check/wasm/check.out +++ b/tests/specs/check/wasm/check.out @@ -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. diff --git a/tests/specs/check/workspace/__test__.jsonc b/tests/specs/check/workspace/__test__.jsonc index 5df2fd70ec..762149c13a 100644 --- a/tests/specs/check/workspace/__test__.jsonc +++ b/tests/specs/check/workspace/__test__.jsonc @@ -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 }, diff --git a/tests/specs/check/workspace/deno.json b/tests/specs/check/workspace/deno.json index b72d884428..151cbc398b 100644 --- a/tests/specs/check/workspace/deno.json +++ b/tests/specs/check/workspace/deno.json @@ -1,6 +1,8 @@ { "workspace": [ "./package-a", - "./package-b" + "./package-b", + "./package-c", + "./package-d" ] } diff --git a/tests/specs/check/workspace/package-c/check.js b/tests/specs/check/workspace/package-c/check.js new file mode 100644 index 0000000000..1112ff9af4 --- /dev/null +++ b/tests/specs/check/workspace/package-c/check.js @@ -0,0 +1 @@ +console.log(Math.pow("")); diff --git a/tests/specs/check/workspace/package-c/deno.json b/tests/specs/check/workspace/package-c/deno.json new file mode 100644 index 0000000000..08ac60b6cd --- /dev/null +++ b/tests/specs/check/workspace/package-c/deno.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "checkJs": true + } +} diff --git a/tests/specs/check/workspace/package-c/mod.ts b/tests/specs/check/workspace/package-c/mod.ts new file mode 100644 index 0000000000..2bdd1f1756 --- /dev/null +++ b/tests/specs/check/workspace/package-c/mod.ts @@ -0,0 +1 @@ +import "./check.js"; diff --git a/tests/specs/check/workspace/package-d/check.js b/tests/specs/check/workspace/package-d/check.js new file mode 100644 index 0000000000..1112ff9af4 --- /dev/null +++ b/tests/specs/check/workspace/package-d/check.js @@ -0,0 +1 @@ +console.log(Math.pow("")); diff --git a/tests/specs/check/workspace/package-d/deno.json b/tests/specs/check/workspace/package-d/deno.json new file mode 100644 index 0000000000..11af7daa41 --- /dev/null +++ b/tests/specs/check/workspace/package-d/deno.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "checkJs": false + } +} diff --git a/tests/specs/check/workspace/package-d/mod.ts b/tests/specs/check/workspace/package-d/mod.ts new file mode 100644 index 0000000000..2bdd1f1756 --- /dev/null +++ b/tests/specs/check/workspace/package-d/mod.ts @@ -0,0 +1 @@ +import "./check.js"; diff --git a/tests/specs/check/workspace/package_b.out b/tests/specs/check/workspace/package_b.out index 8db6c5476c..c8c839d7f2 100644 --- a/tests/specs/check/workspace/package_b.out +++ b/tests/specs/check/workspace/package_b.out @@ -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. diff --git a/tests/specs/check/workspace/root.out b/tests/specs/check/workspace/root.out index 21ae7acd3f..d71afaeae7 100644 --- a/tests/specs/check/workspace/root.out +++ b/tests/specs/check/workspace/root.out @@ -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. diff --git a/tests/specs/check/workspace_compiler_option_types/__test__.jsonc b/tests/specs/check/workspace_compiler_option_types/__test__.jsonc new file mode 100644 index 0000000000..b2455f3175 --- /dev/null +++ b/tests/specs/check/workspace_compiler_option_types/__test__.jsonc @@ -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 + } + } +} diff --git a/tests/specs/check/workspace_compiler_option_types/deno.json b/tests/specs/check/workspace_compiler_option_types/deno.json new file mode 100644 index 0000000000..f263275bea --- /dev/null +++ b/tests/specs/check/workspace_compiler_option_types/deno.json @@ -0,0 +1,7 @@ +{ + "workspace": [ + "./package-a", + "./package-b", + "./package-c" + ] +} diff --git a/tests/specs/check/workspace_compiler_option_types/package-a/deno.json b/tests/specs/check/workspace_compiler_option_types/package-a/deno.json new file mode 100644 index 0000000000..c7c6ba9662 --- /dev/null +++ b/tests/specs/check/workspace_compiler_option_types/package-a/deno.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "types": [ + "./globals.d.ts", + "./other-globals.d.ts" + ] + } +} diff --git a/tests/specs/check/workspace_compiler_option_types/package-a/globals.d.ts b/tests/specs/check/workspace_compiler_option_types/package-a/globals.d.ts new file mode 100644 index 0000000000..13cae718f3 --- /dev/null +++ b/tests/specs/check/workspace_compiler_option_types/package-a/globals.d.ts @@ -0,0 +1 @@ +declare var myPackageAGlobal: string; diff --git a/tests/specs/check/workspace_compiler_option_types/package-a/mod.ts b/tests/specs/check/workspace_compiler_option_types/package-a/mod.ts new file mode 100644 index 0000000000..da05b077cd --- /dev/null +++ b/tests/specs/check/workspace_compiler_option_types/package-a/mod.ts @@ -0,0 +1,2 @@ +console.log(myPackageAGlobal); +console.log(myPackageBGlobal); diff --git a/tests/specs/check/workspace_compiler_option_types/package-a/other-globals.d.ts b/tests/specs/check/workspace_compiler_option_types/package-a/other-globals.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/specs/check/workspace_compiler_option_types/package-b/deno.json b/tests/specs/check/workspace_compiler_option_types/package-b/deno.json new file mode 100644 index 0000000000..a8ab0fbaf1 --- /dev/null +++ b/tests/specs/check/workspace_compiler_option_types/package-b/deno.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "types": [ + "./globals.d.ts" + ] + } +} diff --git a/tests/specs/check/workspace_compiler_option_types/package-b/globals.d.ts b/tests/specs/check/workspace_compiler_option_types/package-b/globals.d.ts new file mode 100644 index 0000000000..ed74848c9b --- /dev/null +++ b/tests/specs/check/workspace_compiler_option_types/package-b/globals.d.ts @@ -0,0 +1 @@ +declare var myPackageBGlobal: string; diff --git a/tests/specs/check/workspace_compiler_option_types/package-b/mod.ts b/tests/specs/check/workspace_compiler_option_types/package-b/mod.ts new file mode 100644 index 0000000000..da05b077cd --- /dev/null +++ b/tests/specs/check/workspace_compiler_option_types/package-b/mod.ts @@ -0,0 +1,2 @@ +console.log(myPackageAGlobal); +console.log(myPackageBGlobal); diff --git a/tests/specs/check/workspace_compiler_option_types/package-c/deno.jsonc b/tests/specs/check/workspace_compiler_option_types/package-c/deno.jsonc new file mode 100644 index 0000000000..db2c2f5f3c --- /dev/null +++ b/tests/specs/check/workspace_compiler_option_types/package-c/deno.jsonc @@ -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" + ] + } +} diff --git a/tests/specs/check/workspace_compiler_option_types/package-c/mod.ts b/tests/specs/check/workspace_compiler_option_types/package-c/mod.ts new file mode 100644 index 0000000000..197c5c5fbb --- /dev/null +++ b/tests/specs/check/workspace_compiler_option_types/package-c/mod.ts @@ -0,0 +1 @@ +console.log(myPackageAGlobal); diff --git a/tests/specs/check/workspace_compiler_option_types/root.out b/tests/specs/check/workspace_compiler_option_types/root.out new file mode 100644 index 0000000000..772aa02009 --- /dev/null +++ b/tests/specs/check/workspace_compiler_option_types/root.out @@ -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. diff --git a/tests/specs/jsr/subset_type_graph/main.check.out b/tests/specs/jsr/subset_type_graph/main.check.out index 35890e57f3..7ede0e4033 100644 --- a/tests/specs/jsr/subset_type_graph/main.check.out +++ b/tests/specs/jsr/subset_type_graph/main.check.out @@ -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. diff --git a/tests/specs/lint/jsx/__test__.jsonc b/tests/specs/lint/jsx/__test__.jsonc index b929e12d45..d1783f1dcf 100644 --- a/tests/specs/lint/jsx/__test__.jsonc +++ b/tests/specs/lint/jsx/__test__.jsonc @@ -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 } diff --git a/tests/specs/lint/jsx/deno.json b/tests/specs/lint/jsx/deno.json new file mode 100644 index 0000000000..a4e08fc04f --- /dev/null +++ b/tests/specs/lint/jsx/deno.json @@ -0,0 +1,6 @@ +{ + "workspace": [ + "react", + "react-jsx" + ] +} diff --git a/tests/specs/lint/jsx/react-jsx.out b/tests/specs/lint/jsx/lint.out similarity index 94% rename from tests/specs/lint/jsx/react-jsx.out rename to tests/specs/lint/jsx/lint.out index 3aba846e67..0435136e32 100644 --- a/tests/specs/lint/jsx/react-jsx.out +++ b/tests/specs/lint/jsx/lint.out @@ -9,4 +9,4 @@ error[no-unused-vars]: `React` is never used Found 1 problem -Checked 1 file +Checked 2 files diff --git a/tests/specs/lint/jsx/react.out b/tests/specs/lint/jsx/react.out deleted file mode 100644 index c05ac45a1e..0000000000 --- a/tests/specs/lint/jsx/react.out +++ /dev/null @@ -1 +0,0 @@ -Checked 1 file diff --git a/tests/specs/node/dynamic_import_and_require_dual/check.out b/tests/specs/node/dynamic_import_and_require_dual/check.out index bbea340cce..b5c0a7e2f7 100644 --- a/tests/specs/node/dynamic_import_and_require_dual/check.out +++ b/tests/specs/node/dynamic_import_and_require_dual/check.out @@ -1,5 +1,7 @@ Check file:///[WILDLINE]/index.cts -error: TS2322 [ERROR]: Type '"mjs"' is not assignable to type '"value"'. +TS2322 [ERROR]: Type '"mjs"' is not assignable to type '"value"'. const value: "value" = mod.kind; ~~~~~ at file:///[WILDLINE]/index.cts:3:9 + +error: Type checking failed. diff --git a/tests/specs/node/dynamic_import_and_require_dual/jsdoc_import_decl.out b/tests/specs/node/dynamic_import_and_require_dual/jsdoc_import_decl.out index 655d47117f..9b8d5095b6 100644 --- a/tests/specs/node/dynamic_import_and_require_dual/jsdoc_import_decl.out +++ b/tests/specs/node/dynamic_import_and_require_dual/jsdoc_import_decl.out @@ -1,5 +1,7 @@ Check file:///[WILDLINE]/jsdoc_import_decl.js -error: TS2345 [ERROR]: Argument of type '"value"' is not assignable to parameter of type '"mjs"'. +TS2345 [ERROR]: Argument of type '"value"' is not assignable to parameter of type '"mjs"'. log("value"); ~~~~~~~ at file:///[WILDLINE]/jsdoc_import_decl.js:12:5 + +error: Type checking failed. diff --git a/tests/specs/node/dynamic_import_and_require_dual/resolution_mode_import.out b/tests/specs/node/dynamic_import_and_require_dual/resolution_mode_import.out index 735cfe53ac..2db0bdc621 100644 --- a/tests/specs/node/dynamic_import_and_require_dual/resolution_mode_import.out +++ b/tests/specs/node/dynamic_import_and_require_dual/resolution_mode_import.out @@ -1,5 +1,7 @@ Check file:///[WILDLINE]/resolution_mode_import.mts -error: TS2322 [ERROR]: Type '"other"' is not assignable to type '"mjs"'. +TS2322 [ERROR]: Type '"other"' is not assignable to type '"mjs"'. const test: typeof kind = "other"; ~~~~ at file:///[WILDLINE]/resolution_mode_import.mts:5:7 + +error: Type checking failed. diff --git a/tests/specs/node/dynamic_import_and_require_dual/resolution_mode_require.out b/tests/specs/node/dynamic_import_and_require_dual/resolution_mode_require.out index 32cdd86f0d..f2ba7f58aa 100644 --- a/tests/specs/node/dynamic_import_and_require_dual/resolution_mode_require.out +++ b/tests/specs/node/dynamic_import_and_require_dual/resolution_mode_require.out @@ -1,5 +1,7 @@ Check file:///[WILDLINE]/resolution_mode_require.mts -error: TS2322 [ERROR]: Type '"other"' is not assignable to type '"cjs"'. +TS2322 [ERROR]: Type '"other"' is not assignable to type '"cjs"'. const test: typeof kind = "other"; ~~~~ at file:///[WILDLINE]/resolution_mode_require.mts:5:7 + +error: Type checking failed. diff --git a/tests/specs/node/dynamic_import_and_require_dual/resolution_mode_require_jsdoc.out b/tests/specs/node/dynamic_import_and_require_dual/resolution_mode_require_jsdoc.out index 924681fe80..1cfc55a191 100644 --- a/tests/specs/node/dynamic_import_and_require_dual/resolution_mode_require_jsdoc.out +++ b/tests/specs/node/dynamic_import_and_require_dual/resolution_mode_require_jsdoc.out @@ -1,5 +1,7 @@ Check file:///[WILDLINE]/resolution_mode_require_jsdoc.js -error: TS2345 [ERROR]: Argument of type '"value"' is not assignable to parameter of type '"cjs"'. +TS2345 [ERROR]: Argument of type '"value"' is not assignable to parameter of type '"cjs"'. log("value"); ~~~~~~~ at file:///[WILDLINE]/resolution_mode_require_jsdoc.js:12:5 + +error: Type checking failed. diff --git a/tests/specs/npm/check_all_local/main_all.out b/tests/specs/npm/check_all_local/main_all.out index a418396ee5..6b4531abd0 100644 --- a/tests/specs/npm/check_all_local/main_all.out +++ b/tests/specs/npm/check_all_local/main_all.out @@ -1,7 +1,7 @@ Download http://localhost:4260/@denotest%2fcheck-error Download http://localhost:4260/@denotest/check-error/1.0.0.tgz Check file:///[WILDCARD]/main.ts -error: TS2506 [ERROR]: 'Class1' is referenced directly or indirectly in its own base expression. +TS2506 [ERROR]: 'Class1' is referenced directly or indirectly in its own base expression. export class Class1 extends Class2 { ~~~~~~ at file:///[WILDCARD]/1.0.0/index.d.ts:2:14 @@ -17,3 +17,5 @@ console.log(test.Asdf); // should error at file:///[WILDCARD]/main.ts:3:18 Found 3 errors. + +error: Type checking failed. diff --git a/tests/specs/npm/check_all_local/main_local.out b/tests/specs/npm/check_all_local/main_local.out index 24b183b7ad..6101ad6ab9 100644 --- a/tests/specs/npm/check_all_local/main_local.out +++ b/tests/specs/npm/check_all_local/main_local.out @@ -1,7 +1,9 @@ Download http://localhost:4260/@denotest%2fcheck-error Download http://localhost:4260/@denotest/check-error/1.0.0.tgz Check file:///[WILDCARD]/main.ts -error: TS2339 [ERROR]: Property 'Asdf' does not exist on type 'typeof import("file:///[WILDCARD]/@denotest/check-error/1.0.0/index.d.ts")'. +TS2339 [ERROR]: Property 'Asdf' does not exist on type 'typeof import("file:///[WILDCARD]/@denotest/check-error/1.0.0/index.d.ts")'. console.log(test.Asdf); // should error ~~~~ at file:///[WILDCARD]/main.ts:3:18 + +error: Type checking failed. diff --git a/tests/specs/npm/check_package_file_dts_dmts_dcts/file_dts_dmts_dcts/main.out b/tests/specs/npm/check_package_file_dts_dmts_dcts/file_dts_dmts_dcts/main.out index 6ab72f53b7..f91263d77e 100644 --- a/tests/specs/npm/check_package_file_dts_dmts_dcts/file_dts_dmts_dcts/main.out +++ b/tests/specs/npm/check_package_file_dts_dmts_dcts/file_dts_dmts_dcts/main.out @@ -1,7 +1,7 @@ Download http://localhost:4260/@denotest%2ffile-dts-dmts-dcts Download http://localhost:4260/@denotest/file-dts-dmts-dcts/1.0.0.tgz Check file:///[WILDCARD]/main.ts -error: TS2322 [ERROR]: Type '5' is not assignable to type '"dts"'. +TS2322 [ERROR]: Type '5' is not assignable to type '"dts"'. const value1: Dts1 = 5; ~~~~~~ at file:///[WILDCARD] @@ -22,3 +22,5 @@ const value4: Cts1 = 5; at file:///[WILDCARD] Found 4 errors. + +error: Type checking failed. diff --git a/tests/specs/npm/check_prefers_non_types_node_pkg/expected.out b/tests/specs/npm/check_prefers_non_types_node_pkg/expected.out index 37d41aae29..0fd8353022 100644 --- a/tests/specs/npm/check_prefers_non_types_node_pkg/expected.out +++ b/tests/specs/npm/check_prefers_non_types_node_pkg/expected.out @@ -1,4 +1,6 @@ -error: TS2345 [ERROR]: Argument of type 'number' is not assignable to parameter of type 'string'. +TS2345 [ERROR]: Argument of type 'number' is not assignable to parameter of type 'string'. console.log(compressToEncodedURIComponent(123)); ~~~ at file:///[WILDLINE] + +error: Type checking failed. diff --git a/tests/specs/npm/check_types_in_types_pkg/expected.out b/tests/specs/npm/check_types_in_types_pkg/expected.out index 37d41aae29..0fd8353022 100644 --- a/tests/specs/npm/check_types_in_types_pkg/expected.out +++ b/tests/specs/npm/check_types_in_types_pkg/expected.out @@ -1,4 +1,6 @@ -error: TS2345 [ERROR]: Argument of type 'number' is not assignable to parameter of type 'string'. +TS2345 [ERROR]: Argument of type 'number' is not assignable to parameter of type 'string'. console.log(compressToEncodedURIComponent(123)); ~~~ at file:///[WILDLINE] + +error: Type checking failed. diff --git a/tests/specs/npm/cjs_import_dual/check.out b/tests/specs/npm/cjs_import_dual/check.out index c2d1daa17b..ff13fbaee6 100644 --- a/tests/specs/npm/cjs_import_dual/check.out +++ b/tests/specs/npm/cjs_import_dual/check.out @@ -3,7 +3,9 @@ Download http://localhost:4260/@denotest%2fdual-cjs-esm Download http://localhost:4260/@denotest/cjs-import-dual/1.0.0.tgz Download http://localhost:4260/@denotest/dual-cjs-esm/1.0.0.tgz Check file:///[WILDLINE]/cjs_import_dual/main.ts -error: TS2322 [ERROR]: Type '"cjs"' is not assignable to type '"esm"'. +TS2322 [ERROR]: Type '"cjs"' is not assignable to type '"esm"'. const kind: "esm" = getKind(); // should cause a type error ~~~~ at file:///[WILDLINE]/cjs_import_dual/main.ts:3:7 + +error: Type checking failed. diff --git a/tests/specs/npm/cjs_internal_types_default_export/main.out b/tests/specs/npm/cjs_internal_types_default_export/main.out index 66ec3f37b0..6fd094c194 100644 --- a/tests/specs/npm/cjs_internal_types_default_export/main.out +++ b/tests/specs/npm/cjs_internal_types_default_export/main.out @@ -1,5 +1,7 @@ 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'. add(1, "test"); // should error ~~~~~~ at file:///[WILDLINE]/main.ts:3:8 + +error: Type checking failed. diff --git a/tests/specs/npm/dual_cjs_esm/cjs_referrer/check.out b/tests/specs/npm/dual_cjs_esm/cjs_referrer/check.out index 267d31fb75..e99ace9800 100644 --- a/tests/specs/npm/dual_cjs_esm/cjs_referrer/check.out +++ b/tests/specs/npm/dual_cjs_esm/cjs_referrer/check.out @@ -2,7 +2,9 @@ Download http://localhost:4260/@denotest%2fdual-cjs-esm Download http://localhost:4260/@denotest/dual-cjs-esm/1.0.0.tgz Initialize @denotest/dual-cjs-esm@1.0.0 Check file:///[WILDLINE]/main.cts -error: TS2322 [ERROR]: Type '"cjs"' is not assignable to type '"other"'. +TS2322 [ERROR]: Type '"cjs"' is not assignable to type '"other"'. const kind: "other" = mod.getKind(); ~~~~ at file:///[WILDLINE]/main.cts:3:7 + +error: Type checking failed. diff --git a/tests/specs/npm/dual_cjs_esm/ts_referrer_type_cjs/check.out b/tests/specs/npm/dual_cjs_esm/ts_referrer_type_cjs/check.out index cbd7740a9f..e9159eade0 100644 --- a/tests/specs/npm/dual_cjs_esm/ts_referrer_type_cjs/check.out +++ b/tests/specs/npm/dual_cjs_esm/ts_referrer_type_cjs/check.out @@ -2,7 +2,9 @@ Download http://localhost:4260/@denotest%2fdual-cjs-esm Download http://localhost:4260/@denotest/dual-cjs-esm/1.0.0.tgz Initialize @denotest/dual-cjs-esm@1.0.0 Check file:///[WILDLINE]/main.ts -error: TS2322 [ERROR]: Type '"cjs"' is not assignable to type '"other"'. +TS2322 [ERROR]: Type '"cjs"' is not assignable to type '"other"'. const kind: "other" = mod.getKind(); ~~~~ at file:///[WILDLINE]/main.ts:3:7 + +error: Type checking failed. diff --git a/tests/specs/npm/node_modules_import/main_check.out b/tests/specs/npm/node_modules_import/main_check.out index 7fd7013fc4..7e312345fb 100644 --- a/tests/specs/npm/node_modules_import/main_check.out +++ b/tests/specs/npm/node_modules_import/main_check.out @@ -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 value1: string = myImport1.getValue(); ~~~~~~ at file:///[WILDCARD]/main.ts:9:7 @@ -14,3 +14,5 @@ const value3: string = myImport3.getValue(); at file:///[WILDCARD]/main.ts:11:7 Found 3 errors. + +error: Type checking failed. diff --git a/tests/specs/npm/node_modules_import_auto/main_check.out b/tests/specs/npm/node_modules_import_auto/main_check.out index 093b0c051a..015acaf8e9 100644 --- a/tests/specs/npm/node_modules_import_auto/main_check.out +++ b/tests/specs/npm/node_modules_import_auto/main_check.out @@ -2,7 +2,7 @@ Download http://localhost:4260/@denotest%2fesm-basic Download http://localhost:4260/@denotest/esm-basic/1.0.0.tgz Initialize @denotest/esm-basic@1.0.0 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'. const value1: string = myImport1.getValue(); ~~~~~~ at file:///[WILDCARD]/main.ts:9:7 @@ -18,3 +18,5 @@ const value3: string = myImport3.getValue(); at file:///[WILDCARD]/main.ts:11:7 Found 3 errors. + +error: Type checking failed. diff --git a/tests/specs/npm/types_ambient_module/types_ambient_module/main.out b/tests/specs/npm/types_ambient_module/types_ambient_module/main.out index c84130707e..040053d382 100644 --- a/tests/specs/npm/types_ambient_module/types_ambient_module/main.out +++ b/tests/specs/npm/types_ambient_module/types_ambient_module/main.out @@ -1,4 +1,4 @@ -error: TS2551 [ERROR]: Property 'Test2' does not exist on type 'typeof import("@denotest/types-ambient")'. Did you mean 'Test'? +TS2551 [ERROR]: Property 'Test2' does not exist on type 'typeof import("@denotest/types-ambient")'. Did you mean 'Test'? console.log(import1.Test2); // should error ~~~~~ at file:///[WILDCARD]/types_ambient_module/main.ts:5:21 @@ -19,3 +19,5 @@ console.log(import2.Test2); // should error at file:///[WILDCARD]/@denotest/types-ambient/1.0.0/index.d.ts:7:9 Found 2 errors. + +error: Type checking failed. diff --git a/tests/specs/npm/types_ambient_module/types_ambient_module/main_import_map.out b/tests/specs/npm/types_ambient_module/types_ambient_module/main_import_map.out index 548f9b479c..2de8a4fe9f 100644 --- a/tests/specs/npm/types_ambient_module/types_ambient_module/main_import_map.out +++ b/tests/specs/npm/types_ambient_module/types_ambient_module/main_import_map.out @@ -1,4 +1,4 @@ -error: TS2551 [ERROR]: Property 'Test2' does not exist on type 'typeof import("@denotest/types-ambient")'. Did you mean 'Test'? +TS2551 [ERROR]: Property 'Test2' does not exist on type 'typeof import("@denotest/types-ambient")'. Did you mean 'Test'? console.log(mod.Test2); // should error ~~~~~ at file:///[WILDCARD]/main_import_map.ts:4:17 @@ -7,3 +7,5 @@ console.log(mod.Test2); // should error class Test { ~~~~ at file:///[WILDCARD]/@denotest/types-ambient/1.0.0/index.d.ts:7:9 + +error: Type checking failed. diff --git a/tests/specs/npm/types_entry_value_not_exists/types_entry_value_not_exists/main.out b/tests/specs/npm/types_entry_value_not_exists/types_entry_value_not_exists/main.out index 62ef51d9f1..cdc69eab3d 100644 --- a/tests/specs/npm/types_entry_value_not_exists/types_entry_value_not_exists/main.out +++ b/tests/specs/npm/types_entry_value_not_exists/types_entry_value_not_exists/main.out @@ -1,7 +1,9 @@ Download http://localhost:4260/@denotest%2ftypes-entry-value-not-exists Download http://localhost:4260/@denotest/types-entry-value-not-exists/1.0.0.tgz Check file://[WILDCARD]/types_entry_value_not_exists/main.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 = getValue(); ~~~~~~ at file:///[WILDCARD]/main.ts:4:7 + +error: Type checking failed. diff --git a/tests/specs/npm/types_exports_import_types/types_exports_import_types/main.out b/tests/specs/npm/types_exports_import_types/types_exports_import_types/main.out index bb69bf86fb..8be8f1eeaf 100644 --- a/tests/specs/npm/types_exports_import_types/types_exports_import_types/main.out +++ b/tests/specs/npm/types_exports_import_types/types_exports_import_types/main.out @@ -1,7 +1,9 @@ Download http://localhost:4260/@denotest%2ftypes-exports-import-types Download http://localhost:4260/@denotest/types-exports-import-types/1.0.0.tgz Check file://[WILDCARD]/types_exports_import_types/main.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 = getValue(); ~~~~~~ at file:///[WILDCARD]/main.ts:4:7 + +error: Type checking failed. diff --git a/tests/specs/npm/types_general/main.out b/tests/specs/npm/types_general/main.out index edc83f2a26..80f3e5ad3e 100644 --- a/tests/specs/npm/types_general/main.out +++ b/tests/specs/npm/types_general/main.out @@ -7,7 +7,7 @@ Download http://localhost:4260/@denotest/types-exports-subpaths/1.0.0.tgz Download http://localhost:4260/@denotest/types/1.0.0.tgz [UNORDERED_END] Check file:///[WILDLINE]/main.ts -error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'. +TS2322 [ERROR]: Type 'number' is not assignable to type 'string'. bar: 1, ~~~ at [WILDCARD]/main.ts:[WILDCARD] @@ -78,3 +78,5 @@ const valueD: "test4" = entryTypes(); at file:///[WILDCARD]/main.ts:[WILDCARD] Found 9 errors. + +error: Type checking failed. diff --git a/tests/specs/npm/types_no_types_entry/types_no_types_entry/main.out b/tests/specs/npm/types_no_types_entry/types_no_types_entry/main.out index c867253ad9..ab2e46b299 100644 --- a/tests/specs/npm/types_no_types_entry/types_no_types_entry/main.out +++ b/tests/specs/npm/types_no_types_entry/types_no_types_entry/main.out @@ -7,7 +7,9 @@ Download http://localhost:4260/@denotest/types-entry-value-not-exists/1.0.0.tgz Download http://localhost:4260/@denotest/types-no-types-entry/1.0.0.tgz [UNORDERED_END] Check file://[WILDCARD]/types_no_types_entry/main.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 = getValue(); ~~~~~~ at file:///[WILDCARD]/main.ts:4:7 + +error: Type checking failed. diff --git a/tests/specs/publish/sloppy_imports/sloppy_imports_not_enabled.out b/tests/specs/publish/sloppy_imports/sloppy_imports_not_enabled.out index 8388e4751e..b531c0e6e2 100644 --- a/tests/specs/publish/sloppy_imports/sloppy_imports_not_enabled.out +++ b/tests/specs/publish/sloppy_imports/sloppy_imports_not_enabled.out @@ -1,3 +1,5 @@ Check file:///[WILDLINE]/mod.ts -error: TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/b'. Maybe specify path to 'index.ts' file in directory instead or run with --unstable-sloppy-imports +TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/b'. Maybe specify path to 'index.ts' file in directory instead or run with --unstable-sloppy-imports at file:///[WILDLINE]/mod.ts:1:20 + +error: Type checking failed. diff --git a/tests/specs/run/_038_checkjs/038_checkjs.js.out b/tests/specs/run/_038_checkjs/038_checkjs.js.out index 4ea473e4ff..2601f27172 100644 --- a/tests/specs/run/_038_checkjs/038_checkjs.js.out +++ b/tests/specs/run/_038_checkjs/038_checkjs.js.out @@ -1,5 +1,5 @@ [WILDCARD] -error: TS2552 [ERROR]: Cannot find name 'consol'. Did you mean 'console'? +TS2552 [ERROR]: Cannot find name 'consol'. Did you mean 'console'? consol.log("hello world!"); ~~~~~~ at [WILDCARD]/038_checkjs.js:2:1 @@ -20,3 +20,5 @@ const foo = new Foo(); at [WILDCARD]/038_checkjs.js:5:7 Found 2 errors. + +error: Type checking failed. diff --git a/tests/specs/run/_091_use_define_for_class_fields/091_use_define_for_class_fields.ts.out b/tests/specs/run/_091_use_define_for_class_fields/091_use_define_for_class_fields.ts.out index 08f94a9671..c3c48212b5 100644 --- a/tests/specs/run/_091_use_define_for_class_fields/091_use_define_for_class_fields.ts.out +++ b/tests/specs/run/_091_use_define_for_class_fields/091_use_define_for_class_fields.ts.out @@ -1,4 +1,4 @@ -[WILDCARD]error: TS2729 [ERROR]: Property 'a' is used before its initialization. +[WILDCARD]TS2729 [ERROR]: Property 'a' is used before its initialization. b = this.a; ^ [WILDCARD] diff --git a/tests/specs/run/check_js_points_to_ts/check_js_points_to_ts/test.js.out b/tests/specs/run/check_js_points_to_ts/check_js_points_to_ts/test.js.out index 67cda9a65b..ad9d41c8b4 100644 --- a/tests/specs/run/check_js_points_to_ts/check_js_points_to_ts/test.js.out +++ b/tests/specs/run/check_js_points_to_ts/check_js_points_to_ts/test.js.out @@ -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'. return 42; ~~~~~~ at [WILDCARD] + +error: Type checking failed. diff --git a/tests/specs/run/check_remote/no_check_remote.ts.disabled.out b/tests/specs/run/check_remote/no_check_remote.ts.disabled.out index 06c046072d..94bab0a59b 100644 --- a/tests/specs/run/check_remote/no_check_remote.ts.disabled.out +++ b/tests/specs/run/check_remote/no_check_remote.ts.disabled.out @@ -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 [WILDCARD]/type_error.ts:1:14 + +error: Type checking failed. diff --git a/tests/specs/run/cts/cjs_import_cts/check.out b/tests/specs/run/cts/cjs_import_cts/check.out index a27e8d7af7..6c9eeb1232 100644 --- a/tests/specs/run/cts/cjs_import_cts/check.out +++ b/tests/specs/run/cts/cjs_import_cts/check.out @@ -1,5 +1,5 @@ Check file:///[WILDLINE]main.js -error: TS2580 [ERROR]: Cannot find name 'module'. +TS2580 [ERROR]: Cannot find name 'module'. module.exports.add = function (a, b) { ~~~~~~ at file:///[WILDLINE] @@ -15,3 +15,5 @@ module.exports.add = function (a, b) { at file:///[WILDLINE] Found 3 errors. + +error: Type checking failed. diff --git a/tests/specs/run/cts/import_export_equals/mod.mts.check.out b/tests/specs/run/cts/import_export_equals/mod.mts.check.out index 8703539019..2042919623 100644 --- a/tests/specs/run/cts/import_export_equals/mod.mts.check.out +++ b/tests/specs/run/cts/import_export_equals/mod.mts.check.out @@ -1,5 +1,7 @@ Check file:///[WILDLINE]/mod.mts -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, "test")); ~~~~~~ at file:///[WILDLINE]/mod.mts:3:20 + +error: Type checking failed. diff --git a/tests/specs/run/error_003_typescript/error_003_typescript.ts.out b/tests/specs/run/error_003_typescript/error_003_typescript.ts.out index bbb2ec4708..58e88bbd28 100644 --- a/tests/specs/run/error_003_typescript/error_003_typescript.ts.out +++ b/tests/specs/run/error_003_typescript/error_003_typescript.ts.out @@ -1,7 +1,9 @@ [WILDCARD] -error: TS2322 [ERROR]: Type '{ a: { b: { c(): { d: number; }; }; }; }' is not assignable to type '{ a: { b: { c(): { d: string; }; }; }; }'. +TS2322 [ERROR]: Type '{ a: { b: { c(): { d: number; }; }; }; }' is not assignable to type '{ a: { b: { c(): { d: string; }; }; }; }'. The types of 'a.b.c().d' are incompatible between these types. Type 'number' is not assignable to type 'string'. x = y; ^ at [WILDCARD]/error_003_typescript.ts:20:1 + +error: Type checking failed. diff --git a/tests/specs/run/error_003_typescript2/error_003_typescript.ts.out b/tests/specs/run/error_003_typescript2/error_003_typescript.ts.out index bbb2ec4708..58e88bbd28 100644 --- a/tests/specs/run/error_003_typescript2/error_003_typescript.ts.out +++ b/tests/specs/run/error_003_typescript2/error_003_typescript.ts.out @@ -1,7 +1,9 @@ [WILDCARD] -error: TS2322 [ERROR]: Type '{ a: { b: { c(): { d: number; }; }; }; }' is not assignable to type '{ a: { b: { c(): { d: string; }; }; }; }'. +TS2322 [ERROR]: Type '{ a: { b: { c(): { d: number; }; }; }; }' is not assignable to type '{ a: { b: { c(): { d: string; }; }; }; }'. The types of 'a.b.c().d' are incompatible between these types. Type 'number' is not assignable to type 'string'. x = y; ^ at [WILDCARD]/error_003_typescript.ts:20:1 + +error: Type checking failed. diff --git a/tests/specs/run/error_017_hide_long_source_ts/error_017_hide_long_source_ts.ts.out b/tests/specs/run/error_017_hide_long_source_ts/error_017_hide_long_source_ts.ts.out index 917061ab9c..714f654267 100644 --- a/tests/specs/run/error_017_hide_long_source_ts/error_017_hide_long_source_ts.ts.out +++ b/tests/specs/run/error_017_hide_long_source_ts/error_017_hide_long_source_ts.ts.out @@ -1,3 +1,5 @@ [WILDCARD] -error: TS2532 [ERROR]: Object is possibly 'undefined'. +TS2532 [ERROR]: Object is possibly 'undefined'. at [WILDCARD]/error_017_hide_long_source_ts.ts:3:1 + +error: Type checking failed. diff --git a/tests/specs/run/error_for_await/error_for_await.ts.out b/tests/specs/run/error_for_await/error_for_await.ts.out index db3cdecb4a..0e7a3f5d18 100644 --- a/tests/specs/run/error_for_await/error_for_await.ts.out +++ b/tests/specs/run/error_for_await/error_for_await.ts.out @@ -1,5 +1,5 @@ [WILDCARD] -error: TS1103 [ERROR]: 'for await' loops are only allowed within async functions and at the top levels of modules. +TS1103 [ERROR]: 'for await' loops are only allowed within async functions and at the top levels of modules. for await (const event of httpConn) { ~~~~~ at [WILDCARD]error_for_await.ts:9:7 @@ -8,3 +8,5 @@ TS1356 [ERROR]: Did you mean to mark this function as 'async'? function handleConn(conn: Deno.Conn) { ~~~~~~~~~~ at [WILDCARD]error_for_await.ts:7:10 + +error: Type checking failed. diff --git a/tests/specs/run/import_attributes_type_check/type_check.out b/tests/specs/run/import_attributes_type_check/type_check.out index 2fc26dae36..5d5c95ebb7 100644 --- a/tests/specs/run/import_attributes_type_check/type_check.out +++ b/tests/specs/run/import_attributes_type_check/type_check.out @@ -1,5 +1,5 @@ Check file:///[WILDCARD]/type_check.ts -error: TS2339 [ERROR]: Property 'foo' does not exist on type '{ a: string; c: { d: number; }; }'. +TS2339 [ERROR]: Property 'foo' does not exist on type '{ a: string; c: { d: number; }; }'. console.log(data1.foo); ~~~ at [WILDCARD]type_check.ts:5:19 @@ -10,3 +10,5 @@ console.log(data2.foo); at [WILDCARD]type_check.ts:6:19 Found 2 errors. + +error: Type checking failed. diff --git a/tests/specs/run/invalid_emit_options/main.out b/tests/specs/run/invalid_emit_options/main.out index 21a2735d8c..f71c779c26 100644 --- a/tests/specs/run/invalid_emit_options/main.out +++ b/tests/specs/run/invalid_emit_options/main.out @@ -1,4 +1,4 @@ -error: Failed to parse compilerOptions +error: compilerOptions should be an object at 'file:///[WILDLINE]/deno.json' Caused by: invalid type: integer `1234`, expected a string diff --git a/tests/specs/run/js_root_with_ts_check/js_root_with_ts_check.js.out b/tests/specs/run/js_root_with_ts_check/js_root_with_ts_check.js.out index 34e2fa61ea..09402bc381 100644 --- a/tests/specs/run/js_root_with_ts_check/js_root_with_ts_check.js.out +++ b/tests/specs/run/js_root_with_ts_check/js_root_with_ts_check.js.out @@ -1,4 +1,6 @@ -error: TS2322 [ERROR]: Type 'string' is not assignable to type 'number'. +TS2322 [ERROR]: Type 'string' is not assignable to type 'number'. const a = ""; ^ at [WILDCARD] + +error: Type checking failed. diff --git a/tests/specs/run/jsx_import_source/jsx_import_source_error.out b/tests/specs/run/jsx_import_source/jsx_import_source_error.out index cb673c6bc9..0847f13ef2 100644 --- a/tests/specs/run/jsx_import_source/jsx_import_source_error.out +++ b/tests/specs/run/jsx_import_source/jsx_import_source_error.out @@ -1,3 +1,5 @@ Check file:///[WILDLINE]/jsx_import_source_no_pragma.tsx -error: TS2307 [ERROR]: Cannot find module 'file:///[WILDCARD]/nonexistent/jsx-runtime'. +TS2307 [ERROR]: Cannot find module 'file:///[WILDCARD]/nonexistent/jsx-runtime'. at file:///[WILDLINE]/jsx_import_source_no_pragma.tsx:1:1 + +error: Type checking failed. diff --git a/tests/specs/run/no_config_auto_discovery_for_local_script/no_auto_discovery.out b/tests/specs/run/no_config_auto_discovery_for_local_script/no_auto_discovery.out index f45a1097c7..dbfb3d8133 100644 --- a/tests/specs/run/no_config_auto_discovery_for_local_script/no_auto_discovery.out +++ b/tests/specs/run/no_config_auto_discovery_for_local_script/no_auto_discovery.out @@ -1,4 +1,6 @@ -error: TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'. +TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'. console.log(document); ~~~~~~~~ at [WILDCARD]frontend_work.ts:2:15 + +error: Type checking failed. diff --git a/tests/specs/run/reference_types_error/reference_types_error.js.out b/tests/specs/run/reference_types_error/reference_types_error.js.out index 3f22354915..1c9e9a4b8a 100644 --- a/tests/specs/run/reference_types_error/reference_types_error.js.out +++ b/tests/specs/run/reference_types_error/reference_types_error.js.out @@ -1,3 +1,5 @@ Check file:///[WILDLINE]/reference_types_error.js -error: TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/nonexistent.d.ts'. +TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/nonexistent.d.ts'. at file:///[WILDLINE]/reference_types_error.js:1:22 + +error: Type checking failed. diff --git a/tests/specs/run/reference_types_error_vendor_dir/reference_types_error.js.out b/tests/specs/run/reference_types_error_vendor_dir/reference_types_error.js.out index 3f22354915..1c9e9a4b8a 100644 --- a/tests/specs/run/reference_types_error_vendor_dir/reference_types_error.js.out +++ b/tests/specs/run/reference_types_error_vendor_dir/reference_types_error.js.out @@ -1,3 +1,5 @@ Check file:///[WILDLINE]/reference_types_error.js -error: TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/nonexistent.d.ts'. +TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/nonexistent.d.ts'. at file:///[WILDLINE]/reference_types_error.js:1:22 + +error: Type checking failed. diff --git a/tests/specs/run/sloppy_imports/no_sloppy.out b/tests/specs/run/sloppy_imports/no_sloppy.out index f28d9181ff..1f88cab635 100644 --- a/tests/specs/run/sloppy_imports/no_sloppy.out +++ b/tests/specs/run/sloppy_imports/no_sloppy.out @@ -1,5 +1,5 @@ Check file:///[WILDLINE]/main.ts -error: TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/a.js'. Maybe change the extension to '.ts' or run with --unstable-sloppy-imports +TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/a.js'. Maybe change the extension to '.ts' or run with --unstable-sloppy-imports at file:///[WILDLINE]/main.ts:1:20 TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/b'. Maybe add a '.js' extension or run with --unstable-sloppy-imports @@ -24,3 +24,5 @@ TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/dir'. Maybe specify path at file:///[WILDLINE]/main.ts:8:20 Found 8 errors. + +error: Type checking failed. diff --git a/tests/specs/run/ts_type_imports/ts_type_imports.ts.out b/tests/specs/run/ts_type_imports/ts_type_imports.ts.out index 3972d6a97e..54592beac1 100644 --- a/tests/specs/run/ts_type_imports/ts_type_imports.ts.out +++ b/tests/specs/run/ts_type_imports/ts_type_imports.ts.out @@ -1,6 +1,8 @@ Check [WILDCARD]ts_type_imports.ts -error: TS2322 [ERROR]: Type 'Map' is not assignable to type 'Foo'. +TS2322 [ERROR]: Type 'Map' is not assignable to type 'Foo'. Type 'string' is not assignable to type 'number'. const foo: Foo = new Map(); ~~~ at [WILDCARD]ts_type_imports.ts:5:7 + +error: Type checking failed. diff --git a/tests/specs/run/type_definitions_for_export/type_definitions_for_export.ts.out b/tests/specs/run/type_definitions_for_export/type_definitions_for_export.ts.out index 8f1240bc7a..4138dbf823 100644 --- a/tests/specs/run/type_definitions_for_export/type_definitions_for_export.ts.out +++ b/tests/specs/run/type_definitions_for_export/type_definitions_for_export.ts.out @@ -1,5 +1,7 @@ Check [WILDCARD]type_definitions_for_export.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'. bar(foo); ~~~ at [WILDCARD]type_definitions_for_export.ts:7:5 + +error: Type checking failed. diff --git a/tests/specs/run/wasm_module/import_file_not_found/check.out b/tests/specs/run/wasm_module/import_file_not_found/check.out index 59c052297c..0740f7476c 100644 --- a/tests/specs/run/wasm_module/import_file_not_found/check.out +++ b/tests/specs/run/wasm_module/import_file_not_found/check.out @@ -1,4 +1,6 @@ Download http://localhost:4545/wasm/math_with_import.wasm Check file:///[WILDLINE]/main.js -error: TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/local_math.ts'. +TS2307 [ERROR]: Cannot find module 'file:///[WILDLINE]/local_math.ts'. at http://localhost:4545/wasm/math_with_import.wasm:1:87 + +error: Type checking failed. diff --git a/tests/specs/run/wasm_module/import_named_export_not_found/check.out b/tests/specs/run/wasm_module/import_named_export_not_found/check.out index d7cc2ea0fb..24c08a1c4c 100644 --- a/tests/specs/run/wasm_module/import_named_export_not_found/check.out +++ b/tests/specs/run/wasm_module/import_named_export_not_found/check.out @@ -1,9 +1,11 @@ Download http://localhost:4545/wasm/math_with_import.wasm Check file:///[WILDLINE]/main.js -error: TS2305 [ERROR]: Module '"file:///[WILDLINE]/local_math.ts"' has no exported member '"add"'. +TS2305 [ERROR]: Module '"file:///[WILDLINE]/local_math.ts"' has no exported member '"add"'. at http://localhost:4545/wasm/math_with_import.wasm:1:1 TS2305 [ERROR]: Module '"file:///[WILDLINE]/local_math.ts"' has no exported member '"subtract"'. at http://localhost:4545/wasm/math_with_import.wasm:1:1 Found 2 errors. + +error: Type checking failed. diff --git a/tests/specs/run/wasm_module/table_global_memory/check.out b/tests/specs/run/wasm_module/table_global_memory/check.out index e335a7c907..b14c95d91f 100644 --- a/tests/specs/run/wasm_module/table_global_memory/check.out +++ b/tests/specs/run/wasm_module/table_global_memory/check.out @@ -1,5 +1,5 @@ Check file:///[WILDLINE]/check.ts -error: TS2322 [ERROR]: Type 'Function | null' is not assignable to type 'number'. +TS2322 [ERROR]: Type 'Function | null' is not assignable to type 'number'. Type 'null' is not assignable to type 'number'. const value1: number = table.get(0); ~~~~~~ @@ -12,3 +12,5 @@ const value2: number = memory.buffer; at file:///[WILDLINE]/check.ts:3:7 Found 2 errors. + +error: Type checking failed. diff --git a/tests/specs/serve/type_check/main.out b/tests/specs/serve/type_check/main.out index 4613ef265c..b584c58985 100644 --- a/tests/specs/serve/type_check/main.out +++ b/tests/specs/serve/type_check/main.out @@ -1,5 +1,7 @@ Check [WILDCARD] -error: TS2353 [ERROR]: Object literal may only specify known properties, and 'bad' does not exist in type 'ServeDefaultExport'. +TS2353 [ERROR]: Object literal may only specify known properties, and 'bad' does not exist in type 'ServeDefaultExport'. bad() { ~~~ at [WILDCARD]main.ts:2:3 + +error: Type checking failed. diff --git a/tests/specs/serve/type_check2/main.out b/tests/specs/serve/type_check2/main.out index 259acb85b7..bc72afd9a5 100644 --- a/tests/specs/serve/type_check2/main.out +++ b/tests/specs/serve/type_check2/main.out @@ -1,5 +1,7 @@ Check [WILDCARD] -error: TS2339 [ERROR]: Property 'doesnt_exist' does not exist on type 'Request'. +TS2339 [ERROR]: Property 'doesnt_exist' does not exist on type 'Request'. console.log(request.doesnt_exist); ~~~~~~~~~~~~ at [WILDCARD]main.ts:3:25 + +error: Type checking failed. diff --git a/tests/specs/test/check_local_by_default2/main.out b/tests/specs/test/check_local_by_default2/main.out index 5b145afd25..92973d6919 100644 --- a/tests/specs/test/check_local_by_default2/main.out +++ b/tests/specs/test/check_local_by_default2/main.out @@ -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]/main.ts:3:7 + +error: Type checking failed. diff --git a/tests/specs/test/doc/main.out b/tests/specs/test/doc/main.out index a255823708..8ffc033d14 100644 --- a/tests/specs/test/doc/main.out +++ b/tests/specs/test/doc/main.out @@ -3,7 +3,9 @@ Check [WILDCARD]/main.ts$10-13.jsx Check [WILDCARD]/main.ts$14-17.ts Check [WILDCARD]/main.ts$18-21.tsx Check [WILDCARD]/main.ts$30-35.ts -error: TS2367 [ERROR]: This comparison appears to be unintentional because the types 'string' and 'number' have no overlap. +TS2367 [ERROR]: This comparison appears to be unintentional because the types 'string' and 'number' have no overlap. console.assert(check() == 42); ~~~~~~~~~~~~~ at [WILDCARD]/main.ts$30-35.ts:3:20 + +error: Type checking failed. diff --git a/tests/specs/test/markdown/main.out b/tests/specs/test/markdown/main.out index bdbd4325f0..4536680651 100644 --- a/tests/specs/test/markdown/main.out +++ b/tests/specs/test/markdown/main.out @@ -1,7 +1,9 @@ Check [WILDCARD]/main.md$11-14.js Check [WILDCARD]/main.md$17-20.ts Check [WILDCARD]/main.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]/main.md$29-32.ts:2:11 + +error: Type checking failed. diff --git a/tests/specs/test/markdown_full_block_names/main.out b/tests/specs/test/markdown_full_block_names/main.out index d7e991ce10..b270bfe047 100644 --- a/tests/specs/test/markdown_full_block_names/main.out +++ b/tests/specs/test/markdown_full_block_names/main.out @@ -1,6 +1,8 @@ Check [WILDCARD]/main.md$5-8.js Check [WILDCARD]/main.md$17-20.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]/main.md$17-20.ts:2:11 + +error: Type checking failed. diff --git a/tests/specs/test/markdown_ignore_html_comment/main.out b/tests/specs/test/markdown_ignore_html_comment/main.out index d30ba7822b..cc52f5530f 100644 --- a/tests/specs/test/markdown_ignore_html_comment/main.out +++ b/tests/specs/test/markdown_ignore_html_comment/main.out @@ -1,5 +1,7 @@ Check [WILDCARD]/main.md$34-37.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]/main.md$34-37.ts:2:11 + +error: Type checking failed. diff --git a/tests/specs/test/markdown_windows/main.out b/tests/specs/test/markdown_windows/main.out index bdbd4325f0..4536680651 100644 --- a/tests/specs/test/markdown_windows/main.out +++ b/tests/specs/test/markdown_windows/main.out @@ -1,7 +1,9 @@ Check [WILDCARD]/main.md$11-14.js Check [WILDCARD]/main.md$17-20.ts Check [WILDCARD]/main.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]/main.md$29-32.ts:2:11 + +error: Type checking failed. diff --git a/tests/specs/test/no_run/main.out b/tests/specs/test/no_run/main.out index ff98849433..3124c7229b 100644 --- a/tests/specs/test/no_run/main.out +++ b/tests/specs/test/no_run/main.out @@ -1,5 +1,7 @@ Check [WILDCARD]/main.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]/main.ts:1:7 + +error: Type checking failed. diff --git a/tests/specs/test/type_check_with_doc/main.out b/tests/specs/test/type_check_with_doc/main.out index 56b7ba9e8b..54fcdade1d 100644 --- a/tests/specs/test/type_check_with_doc/main.out +++ b/tests/specs/test/type_check_with_doc/main.out @@ -1,6 +1,6 @@ Check [WILDCARD]/main.ts Check [WILDCARD]/main.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 a: string = 1; ^ at file://[WILDCARD]/main.ts:8:7 @@ -11,3 +11,5 @@ TS2322 [ERROR]: Type 'string' is not assignable to type 'number'. at file://[WILDCARD]/main.ts$2-5.ts:2:11 Found 2 errors. + +error: Type checking failed. diff --git a/tests/specs/workspaces/non_fatal_diagnostics/lint.out b/tests/specs/workspaces/non_fatal_diagnostics/lint.out index 864dc47ac4..8b4ae8edfc 100644 --- a/tests/specs/workspaces/non_fatal_diagnostics/lint.out +++ b/tests/specs/workspaces/non_fatal_diagnostics/lint.out @@ -1,4 +1,4 @@ -Warning "compilerOptions" field can only be specified in the workspace root deno.json file. +Warning "lock" field can only be specified in the workspace root deno.json file. at file:///[WILDLINE]/sub/deno.json Warning "lint.report" field can only be specified in the workspace root deno.json file. at file:///[WILDLINE]/sub/deno.json diff --git a/tests/specs/workspaces/non_fatal_diagnostics/sub/deno.json b/tests/specs/workspaces/non_fatal_diagnostics/sub/deno.json index 0a21df89f7..b0375f79af 100644 --- a/tests/specs/workspaces/non_fatal_diagnostics/sub/deno.json +++ b/tests/specs/workspaces/non_fatal_diagnostics/sub/deno.json @@ -2,7 +2,5 @@ "lint": { "report": "compact" }, - "compilerOptions": { - "strict": true - } + "lock": false } diff --git a/tests/testdata/bench/check_local_by_default2.out b/tests/testdata/bench/check_local_by_default2.out index 01aeda6363..3311da0a67 100644 --- a/tests/testdata/bench/check_local_by_default2.out +++ b/tests/testdata/bench/check_local_by_default2.out @@ -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]bench/check_local_by_default2.ts:3:7 + +error: Type checking failed. diff --git a/tests/testdata/bench/no_run.out b/tests/testdata/bench/no_run.out index 5d40f1d3b4..d02769abc0 100644 --- a/tests/testdata/bench/no_run.out +++ b/tests/testdata/bench/no_run.out @@ -1,5 +1,7 @@ Check [WILDCARD]/bench/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]/bench/no_run.ts:1:7 + +error: Type checking failed. diff --git a/tests/testdata/import_attributes/type_check.out b/tests/testdata/import_attributes/type_check.out index 2fc26dae36..5d5c95ebb7 100644 --- a/tests/testdata/import_attributes/type_check.out +++ b/tests/testdata/import_attributes/type_check.out @@ -1,5 +1,5 @@ Check file:///[WILDCARD]/type_check.ts -error: TS2339 [ERROR]: Property 'foo' does not exist on type '{ a: string; c: { d: number; }; }'. +TS2339 [ERROR]: Property 'foo' does not exist on type '{ a: string; c: { d: number; }; }'. console.log(data1.foo); ~~~ at [WILDCARD]type_check.ts:5:19 @@ -10,3 +10,5 @@ console.log(data2.foo); at [WILDCARD]type_check.ts:6:19 Found 2 errors. + +error: Type checking failed.