summaryrefslogtreecommitdiff
path: root/cli/tsc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tsc.rs')
-rw-r--r--cli/tsc.rs178
1 files changed, 98 insertions, 80 deletions
diff --git a/cli/tsc.rs b/cli/tsc.rs
index f76fb18fb..e87cb7c7d 100644
--- a/cli/tsc.rs
+++ b/cli/tsc.rs
@@ -3,6 +3,8 @@
use crate::config_file::TsConfig;
use crate::diagnostics::Diagnostics;
use crate::emit;
+use crate::graph_util::GraphData;
+use crate::graph_util::ModuleEntry;
use deno_ast::MediaType;
use deno_core::anyhow::anyhow;
@@ -10,6 +12,7 @@ use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::located_script_name;
use deno_core::op_sync;
+use deno_core::parking_lot::RwLock;
use deno_core::resolve_url_or_path;
use deno_core::serde::de;
use deno_core::serde::Deserialize;
@@ -22,7 +25,6 @@ use deno_core::ModuleSpecifier;
use deno_core::OpFn;
use deno_core::RuntimeOptions;
use deno_core::Snapshot;
-use deno_graph::ModuleGraph;
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
@@ -185,7 +187,7 @@ pub struct Request {
pub config: TsConfig,
/// Indicates to the tsc runtime if debug logging should occur.
pub debug: bool,
- pub graph: Arc<ModuleGraph>,
+ pub(crate) graph_data: Arc<RwLock<GraphData>>,
pub hash_data: Vec<Vec<u8>>,
pub maybe_config_specifier: Option<ModuleSpecifier>,
pub maybe_tsbuildinfo: Option<String>,
@@ -211,7 +213,7 @@ struct State {
data_url_map: HashMap<String, ModuleSpecifier>,
hash_data: Vec<Vec<u8>>,
emitted_files: Vec<EmittedFile>,
- graph: Arc<ModuleGraph>,
+ graph_data: Arc<RwLock<GraphData>>,
maybe_config_specifier: Option<ModuleSpecifier>,
maybe_tsbuildinfo: Option<String>,
maybe_response: Option<RespondArgs>,
@@ -220,7 +222,7 @@ struct State {
impl State {
pub fn new(
- graph: Arc<ModuleGraph>,
+ graph_data: Arc<RwLock<GraphData>>,
hash_data: Vec<Vec<u8>>,
maybe_config_specifier: Option<ModuleSpecifier>,
maybe_tsbuildinfo: Option<String>,
@@ -231,7 +233,7 @@ impl State {
data_url_map,
hash_data,
emitted_files: Default::default(),
- graph,
+ graph_data,
maybe_config_specifier,
maybe_tsbuildinfo,
maybe_response: None,
@@ -335,11 +337,15 @@ struct ExistsArgs {
}
fn op_exists(state: &mut State, args: ExistsArgs) -> Result<bool, AnyError> {
+ let graph_data = state.graph_data.read();
if let Ok(specifier) = normalize_specifier(&args.specifier) {
if specifier.scheme() == "asset" || specifier.scheme() == "data" {
Ok(true)
} else {
- Ok(state.graph.contains(&specifier))
+ Ok(matches!(
+ graph_data.get(&graph_data.follow_redirect(&specifier)),
+ Some(ModuleEntry::Module { .. })
+ ))
}
} else {
Ok(false)
@@ -401,9 +407,16 @@ fn op_load(state: &mut State, args: Value) -> Result<Value, AnyError> {
} else {
specifier
};
- let maybe_source = if let Some(module) = state.graph.get(&specifier) {
- media_type = *module.media_type();
- module.maybe_source().map(String::from)
+ let graph_data = state.graph_data.read();
+ let maybe_source = if let Some(ModuleEntry::Module {
+ code,
+ media_type: mt,
+ ..
+ }) =
+ graph_data.get(&graph_data.follow_redirect(&specifier))
+ {
+ media_type = *mt;
+ Some(code.as_ref().clone())
} else {
media_type = MediaType::Unknown;
None
@@ -427,27 +440,6 @@ pub struct ResolveArgs {
pub specifiers: Vec<String>,
}
-fn resolve_specifier(
- state: &mut State,
- specifier: &ModuleSpecifier,
-) -> (String, String) {
- let media_type = state
- .graph
- .get(specifier)
- .map_or(&MediaType::Unknown, |m| m.media_type());
- let specifier_str = match specifier.scheme() {
- "data" | "blob" => {
- let specifier_str = hash_url(specifier, media_type);
- state
- .data_url_map
- .insert(specifier_str.clone(), specifier.clone());
- specifier_str
- }
- _ => specifier.to_string(),
- };
- (specifier_str, media_type.as_ts_extension().into())
-}
-
fn op_resolve(state: &mut State, args: Value) -> Result<Value, AnyError> {
let v: ResolveArgs = serde_json::from_value(args)
.context("Invalid request from JavaScript for \"op_resolve\".")?;
@@ -468,32 +460,62 @@ fn op_resolve(state: &mut State, args: Value) -> Result<Value, AnyError> {
MediaType::from(specifier).as_ts_extension().to_string(),
));
} else {
- // here, we try to resolve the specifier via the referrer, but if we can't
- // we will try to resolve the specifier via the configuration file, if
- // present, finally defaulting to a "placeholder" specifier. This handles
- // situations like the jsxImportSource, which tsc tries to resolve the
- // import source from a JSX module, but the module graph only contains the
- // import as a dependency of the configuration file.
- let resolved_dependency = if let Some(resolved_specifier) = state
- .graph
- .resolve_dependency(specifier, &referrer, true)
- .cloned()
- {
- resolve_specifier(state, &resolved_specifier)
- } else if let Some(resolved_specifier) = state
- .maybe_config_specifier
- .as_ref()
- .map(|cf| state.graph.resolve_dependency(specifier, cf, true).cloned())
- .flatten()
- {
- resolve_specifier(state, &resolved_specifier)
- } else {
- (
+ let graph_data = state.graph_data.read();
+ let referrer = graph_data.follow_redirect(&referrer);
+ let resolved_dep = match graph_data.get(&referrer) {
+ Some(ModuleEntry::Module { dependencies, .. }) => {
+ dependencies.get(specifier).and_then(|d| {
+ d.maybe_type.as_ref().or_else(|| d.maybe_code.as_ref())
+ })
+ }
+ Some(ModuleEntry::Configuration { dependencies }) => {
+ dependencies.get(specifier)
+ }
+ _ => None,
+ };
+ let maybe_result = match resolved_dep {
+ Some(Ok((specifier, _))) => {
+ let specifier = graph_data.follow_redirect(specifier);
+ match graph_data.get(&specifier) {
+ Some(ModuleEntry::Module {
+ media_type,
+ maybe_types,
+ ..
+ }) => match maybe_types {
+ Some(Ok((types, _))) => {
+ let types = graph_data.follow_redirect(types);
+ match graph_data.get(&types) {
+ Some(ModuleEntry::Module { media_type, .. }) => {
+ Some((types, media_type))
+ }
+ _ => None,
+ }
+ }
+ _ => Some((specifier, media_type)),
+ },
+ _ => None,
+ }
+ }
+ _ => None,
+ };
+ let result = match maybe_result {
+ Some((specifier, media_type)) => {
+ let specifier_str = match specifier.scheme() {
+ "data" | "blob" => {
+ let specifier_str = hash_url(&specifier, media_type);
+ state.data_url_map.insert(specifier_str.clone(), specifier);
+ specifier_str
+ }
+ _ => specifier.to_string(),
+ };
+ (specifier_str, media_type.as_ts_extension().into())
+ }
+ None => (
"deno:///missing_dependency.d.ts".to_string(),
".d.ts".to_string(),
- )
+ ),
};
- resolved.push(resolved_dependency);
+ resolved.push(result);
}
}
@@ -553,7 +575,7 @@ pub(crate) fn exec(request: Request) -> Result<Response, AnyError> {
let op_state = runtime.op_state();
let mut op_state = op_state.borrow_mut();
op_state.put(State::new(
- request.graph,
+ request.graph_data,
request.hash_data.clone(),
request.maybe_config_specifier.clone(),
request.maybe_tsbuildinfo.clone(),
@@ -656,20 +678,18 @@ mod tests {
let hash_data = maybe_hash_data.unwrap_or_else(|| vec![b"".to_vec()]);
let fixtures = test_util::testdata_path().join("tsc2");
let mut loader = MockLoader { fixtures };
- let graph = Arc::new(
- deno_graph::create_graph(
- vec![specifier],
- false,
- None,
- &mut loader,
- None,
- None,
- None,
- )
- .await,
- );
+ let graph = deno_graph::create_graph(
+ vec![specifier],
+ false,
+ None,
+ &mut loader,
+ None,
+ None,
+ None,
+ )
+ .await;
State::new(
- graph,
+ Arc::new(RwLock::new((&graph).into())),
hash_data,
None,
maybe_tsbuildinfo,
@@ -684,18 +704,16 @@ mod tests {
let hash_data = vec![b"something".to_vec()];
let fixtures = test_util::testdata_path().join("tsc2");
let mut loader = MockLoader { fixtures };
- let graph = Arc::new(
- deno_graph::create_graph(
- vec![specifier.clone()],
- false,
- None,
- &mut loader,
- None,
- None,
- None,
- )
- .await,
- );
+ let graph = deno_graph::create_graph(
+ vec![specifier.clone()],
+ false,
+ None,
+ &mut loader,
+ None,
+ None,
+ None,
+ )
+ .await;
let config = TsConfig::new(json!({
"allowJs": true,
"checkJs": false,
@@ -716,7 +734,7 @@ mod tests {
let request = Request {
config,
debug: false,
- graph,
+ graph_data: Arc::new(RwLock::new((&graph).into())),
hash_data,
maybe_config_specifier: None,
maybe_tsbuildinfo: None,