summaryrefslogtreecommitdiff
path: root/cli/tsc2.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tsc2.rs')
-rw-r--r--cli/tsc2.rs71
1 files changed, 55 insertions, 16 deletions
diff --git a/cli/tsc2.rs b/cli/tsc2.rs
index 54e99a651..44754c030 100644
--- a/cli/tsc2.rs
+++ b/cli/tsc2.rs
@@ -20,8 +20,8 @@ use deno_core::OpFn;
use deno_core::RuntimeOptions;
use deno_core::Snapshot;
use serde::Deserialize;
-use serde::Serialize;
use std::cell::RefCell;
+use std::collections::HashMap;
use std::rc::Rc;
#[derive(Debug, Clone, Default, Eq, PartialEq)]
@@ -32,23 +32,19 @@ pub struct EmittedFile {
}
/// A structure representing a request to be sent to the tsc runtime.
-#[derive(Debug, Serialize)]
-#[serde(rename_all = "camelCase")]
+#[derive(Debug)]
pub struct Request {
/// The TypeScript compiler options which will be serialized and sent to
/// tsc.
pub config: TsConfig,
/// Indicates to the tsc runtime if debug logging should occur.
pub debug: bool,
- #[serde(skip_serializing)]
pub graph: Rc<RefCell<Graph2>>,
- #[serde(skip_serializing)]
pub hash_data: Vec<Vec<u8>>,
- #[serde(skip_serializing)]
pub maybe_tsbuildinfo: Option<String>,
/// A vector of strings that represent the root/entry point modules for the
/// program.
- pub root_names: Vec<String>,
+ pub root_names: Vec<(ModuleSpecifier, MediaType)>,
}
#[derive(Debug, Clone, Eq, PartialEq)]
@@ -69,6 +65,7 @@ struct State {
graph: Rc<RefCell<Graph2>>,
maybe_tsbuildinfo: Option<String>,
maybe_response: Option<RespondArgs>,
+ root_map: HashMap<String, ModuleSpecifier>,
}
impl State {
@@ -76,6 +73,7 @@ impl State {
graph: Rc<RefCell<Graph2>>,
hash_data: Vec<Vec<u8>>,
maybe_tsbuildinfo: Option<String>,
+ root_map: HashMap<String, ModuleSpecifier>,
) -> Self {
State {
hash_data,
@@ -83,6 +81,7 @@ impl State {
graph,
maybe_tsbuildinfo,
maybe_response: None,
+ root_map,
}
}
}
@@ -138,7 +137,13 @@ fn emit(state: &mut State, args: Value) -> Result<Value, AnyError> {
maybe_specifiers: if let Some(specifiers) = &v.maybe_specifiers {
let specifiers = specifiers
.iter()
- .map(|s| ModuleSpecifier::resolve_url_or_path(s).unwrap())
+ .map(|s| {
+ if let Some(remapped_specifier) = state.root_map.get(s) {
+ remapped_specifier.clone()
+ } else {
+ ModuleSpecifier::resolve_url_or_path(s).unwrap()
+ }
+ })
.collect();
Some(specifiers)
} else {
@@ -174,6 +179,12 @@ fn load(state: &mut State, args: Value) -> Result<Value, AnyError> {
Some("declare var a: any;\nexport = a;\n".to_string())
} else {
let graph = state.graph.borrow();
+ let specifier =
+ if let Some(remapped_specifier) = state.root_map.get(&v.specifier) {
+ remapped_specifier.clone()
+ } else {
+ specifier
+ };
let maybe_source = graph.get_source(&specifier);
media_type = if let Some(media_type) = graph.get_media_type(&specifier) {
media_type
@@ -207,9 +218,13 @@ fn 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\".")?;
let mut resolved: Vec<(String, String)> = Vec::new();
- let referrer = ModuleSpecifier::resolve_url_or_path(&v.base).context(
- "Error converting a string module specifier for \"op_resolve\".",
- )?;
+ let referrer = if let Some(remapped_base) = state.root_map.get(&v.base) {
+ remapped_base.clone()
+ } else {
+ ModuleSpecifier::resolve_url_or_path(&v.base).context(
+ "Error converting a string module specifier for \"op_resolve\".",
+ )?
+ };
for specifier in &v.specifiers {
if specifier.starts_with("asset:///") {
resolved.push((
@@ -272,6 +287,25 @@ pub fn exec(
startup_snapshot: Some(snapshot),
..Default::default()
});
+ // tsc cannot handle root specifiers that don't have one of the "acceptable"
+ // extensions. Therefore, we have to check the root modules against their
+ // extensions and remap any that are unacceptable to tsc and add them to the
+ // op state so when requested, we can remap to the original specifier.
+ let mut root_map = HashMap::new();
+ let root_names: Vec<String> = request
+ .root_names
+ .iter()
+ .map(|(s, mt)| {
+ let ext_media_type = MediaType::from(&s.as_str().to_owned());
+ if mt != &ext_media_type {
+ let new_specifier = format!("{}{}", s, mt.as_ts_extension());
+ root_map.insert(new_specifier.clone(), s.clone());
+ new_specifier
+ } else {
+ s.as_str().to_owned()
+ }
+ })
+ .collect();
{
let op_state = runtime.op_state();
@@ -280,6 +314,7 @@ pub fn exec(
request.graph.clone(),
request.hash_data.clone(),
request.maybe_tsbuildinfo.clone(),
+ root_map,
));
}
@@ -290,8 +325,12 @@ pub fn exec(
runtime.register_op("op_respond", op(respond));
let startup_source = "globalThis.startup({ legacyFlag: false })";
- let request_str =
- serde_json::to_string(&request).context("Could not serialize request.")?;
+ let request_value = json!({
+ "config": request.config,
+ "debug": request.debug,
+ "rootNames": root_names,
+ });
+ let request_str = request_value.to_string();
let exec_source = format!("globalThis.exec({})", request_str);
runtime
@@ -354,7 +393,7 @@ mod tests {
.await
.expect("module not inserted");
let graph = Rc::new(RefCell::new(builder.get_graph()));
- State::new(graph, hash_data, maybe_tsbuildinfo)
+ State::new(graph, hash_data, maybe_tsbuildinfo, HashMap::new())
}
#[tokio::test]
@@ -601,7 +640,7 @@ mod tests {
graph,
hash_data,
maybe_tsbuildinfo: None,
- root_names: vec!["https://deno.land/x/a.ts".to_string()],
+ root_names: vec![(specifier, MediaType::TypeScript)],
};
let actual = exec(js::compiler_isolate_init(), request)
.expect("exec should have not errored");
@@ -651,7 +690,7 @@ mod tests {
graph,
hash_data,
maybe_tsbuildinfo: None,
- root_names: vec!["file:///reexports.ts".to_string()],
+ root_names: vec![(specifier, MediaType::TypeScript)],
};
let actual = exec(js::compiler_isolate_init(), request)
.expect("exec should have not errored");