summaryrefslogtreecommitdiff
path: root/cli/graph_util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/graph_util.rs')
-rw-r--r--cli/graph_util.rs300
1 files changed, 204 insertions, 96 deletions
diff --git a/cli/graph_util.rs b/cli/graph_util.rs
index df4e5132d..60b1b80d0 100644
--- a/cli/graph_util.rs
+++ b/cli/graph_util.rs
@@ -6,21 +6,25 @@ use crate::args::TsConfigType;
use crate::args::TsTypeLib;
use crate::args::TypeCheckMode;
use crate::cache;
+use crate::cache::DenoDir;
+use crate::cache::ParsedSourceCache;
use crate::cache::TypeCheckCache;
use crate::colors;
use crate::errors::get_error_class_name;
+use crate::file_fetcher::FileFetcher;
use crate::npm::NpmPackageResolver;
-use crate::proc_state::ProcState;
use crate::resolver::CliGraphResolver;
use crate::tools::check;
use deno_core::anyhow::bail;
use deno_core::error::custom_error;
use deno_core::error::AnyError;
+use deno_core::parking_lot::Mutex;
use deno_core::parking_lot::RwLock;
use deno_core::ModuleSpecifier;
use deno_core::TaskQueue;
use deno_core::TaskQueuePermit;
+use deno_graph::source::Loader;
use deno_graph::Module;
use deno_graph::ModuleError;
use deno_graph::ModuleGraph;
@@ -160,115 +164,215 @@ pub fn graph_lock_or_exit(graph: &ModuleGraph, lockfile: &mut Lockfile) {
}
}
-pub async fn create_graph_and_maybe_check(
- roots: Vec<ModuleSpecifier>,
- ps: &ProcState,
-) -> Result<Arc<deno_graph::ModuleGraph>, AnyError> {
- let mut cache = cache::FetchCacher::new(
- ps.emit_cache.clone(),
- ps.file_fetcher.clone(),
- ps.options.resolve_file_header_overrides(),
- PermissionsContainer::allow_all(),
- PermissionsContainer::allow_all(),
- ps.options.node_modules_dir_specifier(),
- );
- let maybe_imports = ps.options.to_maybe_imports()?;
- let cli_resolver = CliGraphResolver::new(
- ps.options.to_maybe_jsx_import_source_config(),
- ps.maybe_import_map.clone(),
- ps.options.no_npm(),
- ps.npm_api.clone(),
- ps.npm_resolution.clone(),
- ps.package_json_deps_installer.clone(),
- );
- let graph_resolver = cli_resolver.as_graph_resolver();
- let graph_npm_resolver = cli_resolver.as_graph_npm_resolver();
- let analyzer = ps.parsed_source_cache.as_analyzer();
- let mut graph = ModuleGraph::default();
- build_graph_with_npm_resolution(
- &mut graph,
- &cli_resolver,
- &ps.npm_resolver,
- roots,
- &mut cache,
- deno_graph::BuildOptions {
- is_dynamic: false,
- imports: maybe_imports,
- resolver: Some(graph_resolver),
- npm_resolver: Some(graph_npm_resolver),
- module_analyzer: Some(&*analyzer),
- reporter: None,
- },
- )
- .await?;
+pub struct ModuleGraphBuilder {
+ options: Arc<CliOptions>,
+ resolver: Arc<CliGraphResolver>,
+ npm_resolver: Arc<NpmPackageResolver>,
+ parsed_source_cache: Arc<ParsedSourceCache>,
+ lockfile: Option<Arc<Mutex<Lockfile>>>,
+ caches: Arc<cache::Caches>,
+ emit_cache: cache::EmitCache,
+ file_fetcher: Arc<FileFetcher>,
+ deno_dir: DenoDir,
+}
- graph_valid_with_cli_options(&graph, &graph.roots, &ps.options)?;
- let graph = Arc::new(graph);
- if let Some(lockfile) = &ps.lockfile {
- graph_lock_or_exit(&graph, &mut lockfile.lock());
+impl ModuleGraphBuilder {
+ #[allow(clippy::too_many_arguments)]
+ pub fn new(
+ options: Arc<CliOptions>,
+ resolver: Arc<CliGraphResolver>,
+ npm_resolver: Arc<NpmPackageResolver>,
+ parsed_source_cache: Arc<ParsedSourceCache>,
+ lockfile: Option<Arc<Mutex<Lockfile>>>,
+ caches: Arc<cache::Caches>,
+ emit_cache: cache::EmitCache,
+ file_fetcher: Arc<FileFetcher>,
+ deno_dir: DenoDir,
+ ) -> Self {
+ Self {
+ options,
+ resolver,
+ npm_resolver,
+ parsed_source_cache,
+ lockfile,
+ caches,
+ emit_cache,
+ file_fetcher,
+ deno_dir,
+ }
}
- if ps.options.type_check_mode() != TypeCheckMode::None {
- // node built-in specifiers use the @types/node package to determine
- // types, so inject that now after the lockfile has been written
- if graph.has_node_specifier {
- ps.npm_resolver
+ pub async fn create_graph_with_loader(
+ &self,
+ roots: Vec<ModuleSpecifier>,
+ loader: &mut dyn Loader,
+ ) -> Result<deno_graph::ModuleGraph, AnyError> {
+ let maybe_imports = self.options.to_maybe_imports()?;
+
+ let cli_resolver = self.resolver.clone();
+ let graph_resolver = cli_resolver.as_graph_resolver();
+ let graph_npm_resolver = cli_resolver.as_graph_npm_resolver();
+ let analyzer = self.parsed_source_cache.as_analyzer();
+
+ let mut graph = ModuleGraph::default();
+ self
+ .build_graph_with_npm_resolution(
+ &mut graph,
+ roots,
+ loader,
+ deno_graph::BuildOptions {
+ is_dynamic: false,
+ imports: maybe_imports,
+ resolver: Some(graph_resolver),
+ npm_resolver: Some(graph_npm_resolver),
+ module_analyzer: Some(&*analyzer),
+ reporter: None,
+ },
+ )
+ .await?;
+
+ if graph.has_node_specifier
+ && self.options.type_check_mode() != TypeCheckMode::None
+ {
+ self
+ .npm_resolver
.inject_synthetic_types_node_package()
.await?;
}
- let ts_config_result =
- ps.options.resolve_ts_config_for_emit(TsConfigType::Check {
- lib: ps.options.ts_type_lib_window(),
- })?;
- if let Some(ignored_options) = ts_config_result.maybe_ignored_options {
- log::warn!("{}", ignored_options);
+ Ok(graph)
+ }
+
+ pub async fn create_graph_and_maybe_check(
+ &self,
+ roots: Vec<ModuleSpecifier>,
+ ) -> Result<Arc<deno_graph::ModuleGraph>, AnyError> {
+ let mut cache = self.create_graph_loader();
+ let maybe_imports = self.options.to_maybe_imports()?;
+ let cli_resolver = self.resolver.clone();
+ let graph_resolver = cli_resolver.as_graph_resolver();
+ let graph_npm_resolver = cli_resolver.as_graph_npm_resolver();
+ let analyzer = self.parsed_source_cache.as_analyzer();
+ let mut graph = ModuleGraph::default();
+ self
+ .build_graph_with_npm_resolution(
+ &mut graph,
+ roots,
+ &mut cache,
+ deno_graph::BuildOptions {
+ is_dynamic: false,
+ imports: maybe_imports,
+ resolver: Some(graph_resolver),
+ npm_resolver: Some(graph_npm_resolver),
+ module_analyzer: Some(&*analyzer),
+ reporter: None,
+ },
+ )
+ .await?;
+
+ graph_valid_with_cli_options(&graph, &graph.roots, &self.options)?;
+ let graph = Arc::new(graph);
+ if let Some(lockfile) = &self.lockfile {
+ graph_lock_or_exit(&graph, &mut lockfile.lock());
}
- let maybe_config_specifier = ps.options.maybe_config_file_specifier();
- let cache = TypeCheckCache::new(ps.caches.type_checking_cache_db(&ps.dir));
- let check_result = check::check(
- graph.clone(),
- &cache,
- &ps.npm_resolver,
- check::CheckOptions {
- type_check_mode: ps.options.type_check_mode(),
- debug: ps.options.log_level() == Some(log::Level::Debug),
- maybe_config_specifier,
- ts_config: ts_config_result.ts_config,
- log_checks: true,
- reload: ps.options.reload_flag(),
- },
- )?;
- log::debug!("{}", check_result.stats);
- if !check_result.diagnostics.is_empty() {
- return Err(check_result.diagnostics.into());
+
+ if self.options.type_check_mode() != TypeCheckMode::None {
+ // node built-in specifiers use the @types/node package to determine
+ // types, so inject that now after the lockfile has been written
+ if graph.has_node_specifier {
+ self
+ .npm_resolver
+ .inject_synthetic_types_node_package()
+ .await?;
+ }
+
+ let ts_config_result =
+ self
+ .options
+ .resolve_ts_config_for_emit(TsConfigType::Check {
+ lib: self.options.ts_type_lib_window(),
+ })?;
+ if let Some(ignored_options) = ts_config_result.maybe_ignored_options {
+ log::warn!("{}", ignored_options);
+ }
+ let maybe_config_specifier = self.options.maybe_config_file_specifier();
+ let cache =
+ TypeCheckCache::new(self.caches.type_checking_cache_db(&self.deno_dir));
+ let check_result = check::check(
+ graph.clone(),
+ &cache,
+ self.npm_resolver.clone(),
+ check::CheckOptions {
+ type_check_mode: self.options.type_check_mode(),
+ debug: self.options.log_level() == Some(log::Level::Debug),
+ maybe_config_specifier,
+ ts_config: ts_config_result.ts_config,
+ log_checks: true,
+ reload: self.options.reload_flag(),
+ },
+ )?;
+ log::debug!("{}", check_result.stats);
+ if !check_result.diagnostics.is_empty() {
+ return Err(check_result.diagnostics.into());
+ }
}
+
+ Ok(graph)
}
- Ok(graph)
-}
+ pub async fn build_graph_with_npm_resolution<'a>(
+ &self,
+ graph: &mut ModuleGraph,
+ roots: Vec<ModuleSpecifier>,
+ loader: &mut dyn deno_graph::source::Loader,
+ options: deno_graph::BuildOptions<'a>,
+ ) -> Result<(), AnyError> {
+ graph.build(roots, loader, options).await;
+
+ // ensure that the top level package.json is installed if a
+ // specifier was matched in the package.json
+ self
+ .resolver
+ .top_level_package_json_install_if_necessary()
+ .await?;
+
+ // resolve the dependencies of any pending dependencies
+ // that were inserted by building the graph
+ self.npm_resolver.resolve_pending().await?;
-pub async fn build_graph_with_npm_resolution<'a>(
- graph: &mut ModuleGraph,
- cli_graph_resolver: &CliGraphResolver,
- npm_resolver: &NpmPackageResolver,
- roots: Vec<ModuleSpecifier>,
- loader: &mut dyn deno_graph::source::Loader,
- options: deno_graph::BuildOptions<'a>,
-) -> Result<(), AnyError> {
- graph.build(roots, loader, options).await;
+ Ok(())
+ }
- // ensure that the top level package.json is installed if a
- // specifier was matched in the package.json
- cli_graph_resolver
- .top_level_package_json_install_if_necessary()
- .await?;
+ /// Creates the default loader used for creating a graph.
+ pub fn create_graph_loader(&self) -> cache::FetchCacher {
+ self.create_fetch_cacher(
+ PermissionsContainer::allow_all(),
+ PermissionsContainer::allow_all(),
+ )
+ }
- // resolve the dependencies of any pending dependencies
- // that were inserted by building the graph
- npm_resolver.resolve_pending().await?;
+ pub fn create_fetch_cacher(
+ &self,
+ root_permissions: PermissionsContainer,
+ dynamic_permissions: PermissionsContainer,
+ ) -> cache::FetchCacher {
+ cache::FetchCacher::new(
+ self.emit_cache.clone(),
+ self.file_fetcher.clone(),
+ self.options.resolve_file_header_overrides(),
+ root_permissions,
+ dynamic_permissions,
+ self.options.node_modules_dir_specifier(),
+ )
+ }
- Ok(())
+ pub async fn create_graph(
+ &self,
+ roots: Vec<ModuleSpecifier>,
+ ) -> Result<deno_graph::ModuleGraph, AnyError> {
+ let mut cache = self.create_graph_loader();
+ self.create_graph_with_loader(roots, &mut cache).await
+ }
}
pub fn error_for_any_npm_specifier(
@@ -338,7 +442,7 @@ struct GraphData {
}
/// Holds the `ModuleGraph` and what parts of it are type checked.
-#[derive(Clone, Default)]
+#[derive(Default)]
pub struct ModuleGraphContainer {
// Allow only one request to update the graph data at a time,
// but allow other requests to read from it at any time even
@@ -348,6 +452,10 @@ pub struct ModuleGraphContainer {
}
impl ModuleGraphContainer {
+ pub fn clear(&self) {
+ self.graph_data.write().graph = Default::default();
+ }
+
/// Acquires a permit to modify the module graph without other code
/// having the chance to modify it. In the meantime, other code may
/// still read from the existing module graph.