diff --git a/cli/diagnostics.rs b/cli/diagnostics.rs
index b9e8c7463efb34..0671dc500ac96d 100644
--- a/cli/diagnostics.rs
+++ b/cli/diagnostics.rs
@@ -367,6 +367,16 @@ 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,
+ {
+ let diagnostics = self.0.clone().into_iter().filter(predicate).collect();
+ Self(diagnostics)
+ }
+
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
diff --git a/cli/emit.rs b/cli/emit.rs
index 9bd005b2aa046a..fdb79db067ce96 100644
--- a/cli/emit.rs
+++ b/cli/emit.rs
@@ -12,6 +12,7 @@ use crate::config_file::ConfigFile;
use crate::config_file::IgnoredCompilerOptions;
use crate::config_file::TsConfig;
use crate::diagnostics::Diagnostics;
+use crate::flags;
use crate::tsc;
use crate::version;
@@ -297,6 +298,9 @@ fn is_emittable(media_type: &MediaType, include_js: bool) -> bool {
/// 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(crate) struct CheckOptions {
+ /// The check flag from the option which can effect the filtering of
+ /// diagnostics in the emit result.
+ pub check: flags::CheckFlag,
/// Set the debug flag on the TypeScript type checker.
pub debug: bool,
/// If true, any files emitted will be cached, even if there are diagnostics
@@ -363,9 +367,20 @@ pub(crate) fn check_and_maybe_emit(
cache.set(CacheType::TypeScriptBuildInfo, root, info.clone())?;
}
}
+ let diagnostics = if options.check == flags::CheckFlag::Local {
+ response.diagnostics.filter(|d| {
+ if let Some(file_name) = &d.file_name {
+ !file_name.starts_with("http")
+ } else {
+ true
+ }
+ })
+ } else {
+ response.diagnostics
+ };
// sometimes we want to emit when there are diagnostics, and sometimes we
// don't. tsc will always return an emit if there are diagnostics
- if (response.diagnostics.is_empty() || options.emit_with_diagnostics)
+ if (diagnostics.is_empty() || options.emit_with_diagnostics)
&& !response.emitted_files.is_empty()
{
for emit in response.emitted_files.into_iter() {
@@ -413,7 +428,7 @@ pub(crate) fn check_and_maybe_emit(
}
Ok(CheckEmitResult {
- diagnostics: response.diagnostics,
+ diagnostics,
stats: response.stats,
})
}
diff --git a/cli/flags.rs b/cli/flags.rs
index 70db0345a381e8..31180a47ee81f8 100644
--- a/cli/flags.rs
+++ b/cli/flags.rs
@@ -188,6 +188,24 @@ impl Default for DenoSubcommand {
}
}
+#[derive(Debug, Clone, PartialEq)]
+pub enum CheckFlag {
+ /// Type check all modules. The default value.
+ All,
+ /// Skip type checking of all modules. Represents `--no-check` on the command
+ /// line.
+ None,
+ /// Only type check local modules. Represents `--no-check=remote` on the
+ /// command line.
+ Local,
+}
+
+impl Default for CheckFlag {
+ fn default() -> Self {
+ Self::All
+ }
+}
+
#[derive(Clone, Debug, PartialEq, Default)]
pub struct Flags {
/// Vector of CLI arguments - these are user script arguments, all Deno
@@ -209,6 +227,7 @@ pub struct Flags {
/// the language server is configured with an explicit cache option.
pub cache_path: Option,
pub cached_only: bool,
+ pub check: CheckFlag,
pub config_path: Option,
pub coverage_dir: Option,
pub enable_testing_features: bool,
@@ -220,7 +239,6 @@ pub struct Flags {
pub lock_write: bool,
pub lock: Option,
pub log_level: Option,
- pub no_check: bool,
pub no_remote: bool,
/// If true, a list of Node built-in modules will be injected into
/// the import map.
@@ -1643,8 +1661,17 @@ Only local files from entry point module graph are watched.",
fn no_check_arg<'a, 'b>() -> Arg<'a, 'b> {
Arg::with_name("no-check")
+ .takes_value(true)
+ .require_equals(true)
+ .min_values(0)
+ .value_name("NO_CHECK_TYPE")
.long("no-check")
.help("Skip type checking modules")
+ .long_help(
+ "Skip type checking of modules.
+If the value of '--no-check=remote' is supplied, diagnostic errors from remote
+modules will be ignored.",
+ )
}
fn script_arg<'a, 'b>() -> Arg<'a, 'b> {
@@ -2334,8 +2361,16 @@ fn compat_arg_parse(flags: &mut Flags, matches: &ArgMatches) {
}
fn no_check_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
- if matches.is_present("no-check") {
- flags.no_check = true;
+ if let Some(cache_type) = matches.value_of("no-check") {
+ match cache_type {
+ "remote" => flags.check = CheckFlag::Local,
+ _ => debug!(
+ "invalid value for 'no-check' of '{}' using default",
+ cache_type
+ ),
+ }
+ } else if matches.is_present("no-check") {
+ flags.check = CheckFlag::None;
}
}
@@ -3131,7 +3166,7 @@ mod tests {
import_map_path: Some("import_map.json".to_string()),
no_remote: true,
config_path: Some("tsconfig.json".to_string()),
- no_check: true,
+ check: CheckFlag::None,
reload: true,
lock: Some(PathBuf::from("lock.json")),
lock_write: true,
@@ -3216,7 +3251,7 @@ mod tests {
import_map_path: Some("import_map.json".to_string()),
no_remote: true,
config_path: Some("tsconfig.json".to_string()),
- no_check: true,
+ check: CheckFlag::None,
reload: true,
lock: Some(PathBuf::from("lock.json")),
lock_write: true,
@@ -3483,7 +3518,7 @@ mod tests {
source_file: "script.ts".to_string(),
out_file: None,
}),
- no_check: true,
+ check: CheckFlag::None,
..Flags::default()
}
);
@@ -3682,7 +3717,7 @@ mod tests {
import_map_path: Some("import_map.json".to_string()),
no_remote: true,
config_path: Some("tsconfig.json".to_string()),
- no_check: true,
+ check: CheckFlag::None,
reload: true,
lock: Some(PathBuf::from("lock.json")),
lock_write: true,
@@ -3833,7 +3868,23 @@ mod tests {
subcommand: DenoSubcommand::Run(RunFlags {
script: "script.ts".to_string(),
}),
- no_check: true,
+ check: CheckFlag::None,
+ ..Flags::default()
+ }
+ );
+ }
+
+ #[test]
+ fn no_check_remote() {
+ let r =
+ flags_from_vec(svec!["deno", "run", "--no-check=remote", "script.ts"]);
+ assert_eq!(
+ r.unwrap(),
+ Flags {
+ subcommand: DenoSubcommand::Run(RunFlags {
+ script: "script.ts".to_string(),
+ }),
+ check: CheckFlag::Local,
..Flags::default()
}
);
@@ -4406,7 +4457,7 @@ mod tests {
import_map_path: Some("import_map.json".to_string()),
no_remote: true,
config_path: Some("tsconfig.json".to_string()),
- no_check: true,
+ check: CheckFlag::None,
reload: true,
lock: Some(PathBuf::from("lock.json")),
lock_write: true,
diff --git a/cli/main.rs b/cli/main.rs
index da7848834641be..772adcaf474d6a 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -40,6 +40,7 @@ use crate::file_fetcher::File;
use crate::file_watcher::ResolutionResult;
use crate::flags::BundleFlags;
use crate::flags::CacheFlags;
+use crate::flags::CheckFlag;
use crate::flags::CompileFlags;
use crate::flags::CompletionsFlags;
use crate::flags::CoverageFlags;
@@ -695,7 +696,7 @@ async fn create_graph_and_maybe_check(
// locker.
emit::lock(graph.as_ref());
- if !ps.flags.no_check {
+ if ps.flags.check != CheckFlag::None {
graph.valid_types_only().map_err(emit::GraphError::from)?;
let lib = if ps.flags.unstable {
emit::TypeLib::UnstableDenoWindow
@@ -722,6 +723,7 @@ async fn create_graph_and_maybe_check(
graph.clone(),
&mut cache,
emit::CheckOptions {
+ check: ps.flags.check.clone(),
debug,
emit_with_diagnostics: false,
maybe_config_specifier,
@@ -749,7 +751,7 @@ fn bundle_module_graph(
ps.maybe_config_file.as_ref(),
None,
)?;
- if flags.no_check {
+ if flags.check == CheckFlag::None {
if let Some(ignored_options) = maybe_ignored_options {
eprintln!("{}", ignored_options);
}
diff --git a/cli/ops/runtime_compiler.rs b/cli/ops/runtime_compiler.rs
index b16fbcf6945428..ee0646197cb41c 100644
--- a/cli/ops/runtime_compiler.rs
+++ b/cli/ops/runtime_compiler.rs
@@ -5,6 +5,7 @@ use crate::config_file::IgnoredCompilerOptions;
use crate::diagnostics::Diagnostics;
use crate::emit;
use crate::errors::get_error_class_name;
+use crate::flags;
use crate::proc_state::ProcState;
use crate::resolver::ImportMapResolver;
use crate::resolver::JsxResolver;
@@ -248,6 +249,7 @@ async fn op_emit(
graph.clone(),
cache.as_mut_cacher(),
emit::CheckOptions {
+ check: flags::CheckFlag::All,
debug,
emit_with_diagnostics: true,
maybe_config_specifier: None,
@@ -267,6 +269,7 @@ async fn op_emit(
graph.clone(),
cache.as_mut_cacher(),
emit::CheckOptions {
+ check: flags::CheckFlag::All,
debug,
emit_with_diagnostics: true,
maybe_config_specifier: None,
diff --git a/cli/proc_state.rs b/cli/proc_state.rs
index ddfd43034771b4..f7b586c5a6660d 100644
--- a/cli/proc_state.rs
+++ b/cli/proc_state.rs
@@ -354,7 +354,7 @@ impl ProcState {
graph_data.modules.keys().cloned().collect()
};
- let config_type = if self.flags.no_check {
+ let config_type = if self.flags.check == flags::CheckFlag::None {
emit::ConfigType::Emit
} else {
emit::ConfigType::Check {
@@ -387,7 +387,7 @@ impl ProcState {
if let Some(ignored_options) = maybe_ignored_options {
log::warn!("{}", ignored_options);
}
- let emit_result = if self.flags.no_check {
+ let emit_result = if self.flags.check == flags::CheckFlag::None {
let options = emit::EmitOptions {
ts_config,
reload_exclusions,
@@ -406,6 +406,7 @@ impl ProcState {
.as_ref()
.map(|cf| ModuleSpecifier::from_file_path(&cf.path).unwrap());
let options = emit::CheckOptions {
+ check: self.flags.check.clone(),
debug: self.flags.log_level == Some(log::Level::Debug),
emit_with_diagnostics: false,
maybe_config_specifier,
diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs
index 214eb8eceee728..21aa225334a6b1 100644
--- a/cli/tests/integration/run_tests.rs
+++ b/cli/tests/integration/run_tests.rs
@@ -902,6 +902,19 @@ itest!(no_check_decorators {
output: "no_check_decorators.ts.out",
});
+itest!(check_remote {
+ args: "run --quiet --reload no_check_remote.ts",
+ output: "no_check_remote.ts.disabled.out",
+ exit_code: 1,
+ http_server: true,
+});
+
+itest!(no_check_remote {
+ args: "run --quiet --reload --no-check=remote no_check_remote.ts",
+ output: "no_check_remote.ts.enabled.out",
+ http_server: true,
+});
+
itest!(runtime_decorators {
args: "run --quiet --reload --no-check runtime_decorators.ts",
output: "runtime_decorators.ts.out",
diff --git a/cli/tests/testdata/no_check_remote.ts b/cli/tests/testdata/no_check_remote.ts
new file mode 100644
index 00000000000000..2ae8c2692cc20c
--- /dev/null
+++ b/cli/tests/testdata/no_check_remote.ts
@@ -0,0 +1,3 @@
+import * as a from "http://localhost:4545/subdir/type_error.ts";
+
+console.log(a.a);
diff --git a/cli/tests/testdata/no_check_remote.ts.disabled.out b/cli/tests/testdata/no_check_remote.ts.disabled.out
new file mode 100644
index 00000000000000..3442646348e6ec
--- /dev/null
+++ b/cli/tests/testdata/no_check_remote.ts.disabled.out
@@ -0,0 +1,4 @@
+error: 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
diff --git a/cli/tests/testdata/no_check_remote.ts.enabled.out b/cli/tests/testdata/no_check_remote.ts.enabled.out
new file mode 100644
index 00000000000000..48082f72f087ce
--- /dev/null
+++ b/cli/tests/testdata/no_check_remote.ts.enabled.out
@@ -0,0 +1 @@
+12
diff --git a/cli/tests/testdata/subdir/type_error.ts b/cli/tests/testdata/subdir/type_error.ts
new file mode 100644
index 00000000000000..cc3c1d29d82612
--- /dev/null
+++ b/cli/tests/testdata/subdir/type_error.ts
@@ -0,0 +1 @@
+export const a: "a" = 12;
diff --git a/cli/tools/installer.rs b/cli/tools/installer.rs
index 18d2d20e740c8b..a426fea0f213ae 100644
--- a/cli/tools/installer.rs
+++ b/cli/tools/installer.rs
@@ -1,4 +1,6 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+
+use crate::flags::CheckFlag;
use crate::flags::Flags;
use crate::fs_util::canonicalize_path;
use deno_core::error::generic_error;
@@ -267,8 +269,12 @@ pub fn install(
}
}
- if flags.no_check {
- executable_args.push("--no-check".to_string());
+ // we should avoid a default branch here to ensure we continue to cover any
+ // changes to this flag.
+ match flags.check {
+ CheckFlag::All => (),
+ CheckFlag::None => executable_args.push("--no-check".to_string()),
+ CheckFlag::Local => executable_args.push("--no-check=remote".to_string()),
}
if flags.unstable {
@@ -687,7 +693,7 @@ mod tests {
Flags {
allow_net: Some(vec![]),
allow_read: Some(vec![]),
- no_check: true,
+ check: CheckFlag::None,
log_level: Some(Level::Error),
..Flags::default()
},
diff --git a/cli/tools/standalone.rs b/cli/tools/standalone.rs
index fb07254aaf8b12..406a3ada1b907b 100644
--- a/cli/tools/standalone.rs
+++ b/cli/tools/standalone.rs
@@ -1,6 +1,7 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
use crate::deno_dir::DenoDir;
+use crate::flags::CheckFlag;
use crate::flags::DenoSubcommand;
use crate::flags::Flags;
use crate::flags::RunFlags;
@@ -226,7 +227,7 @@ pub fn compile_to_runtime_flags(
lock_write: false,
lock: None,
log_level: flags.log_level,
- no_check: false,
+ check: CheckFlag::All,
compat: flags.compat,
unsafely_ignore_certificate_errors: flags
.unsafely_ignore_certificate_errors,