summaryrefslogtreecommitdiff
path: root/cli/tsc
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tsc')
-rw-r--r--cli/tsc/99_main_compiler.js2
-rw-r--r--cli/tsc/diagnostics.rs2
-rw-r--r--cli/tsc/mod.rs153
3 files changed, 117 insertions, 40 deletions
diff --git a/cli/tsc/99_main_compiler.js b/cli/tsc/99_main_compiler.js
index 6011dece7..bdc4340e3 100644
--- a/cli/tsc/99_main_compiler.js
+++ b/cli/tsc/99_main_compiler.js
@@ -845,6 +845,8 @@ delete Object.prototype.__proto__;
jqueryMessage,
"Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slash_2592":
jqueryMessage,
+ "Module_0_was_resolved_to_1_but_allowArbitraryExtensions_is_not_set_6263":
+ "Module '{0}' was resolved to '{1}', but importing these modules is not supported.",
};
})());
diff --git a/cli/tsc/diagnostics.rs b/cli/tsc/diagnostics.rs
index b0394ec17..d3795706e 100644
--- a/cli/tsc/diagnostics.rs
+++ b/cli/tsc/diagnostics.rs
@@ -323,7 +323,7 @@ impl Diagnostics {
// todo(dsherret): use a short lived cache to prevent parsing
// source maps so often
if let Ok(source_map) =
- SourceMap::from_slice(&fast_check_module.source_map)
+ SourceMap::from_slice(fast_check_module.source_map.as_bytes())
{
if let Some(start) = d.start.as_mut() {
let maybe_token = source_map
diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs
index de91889b6..dc7fc38f7 100644
--- a/cli/tsc/mod.rs
+++ b/cli/tsc/mod.rs
@@ -3,9 +3,11 @@
use crate::args::TsConfig;
use crate::args::TypeCheckMode;
use crate::cache::FastInsecureHasher;
+use crate::cache::ModuleInfoCache;
use crate::node;
use crate::npm::CliNpmResolver;
use crate::npm::ResolvePkgFolderFromDenoReqError;
+use crate::resolver::CjsTracker;
use crate::util::checksum;
use crate::util::path::mapped_specifier_for_tsc;
@@ -32,13 +34,13 @@ use deno_graph::GraphKind;
use deno_graph::Module;
use deno_graph::ModuleGraph;
use deno_graph::ResolutionResolved;
+use deno_runtime::deno_fs;
use deno_runtime::deno_node::NodeResolver;
use deno_semver::npm::NpmPackageReqReference;
use node_resolver::errors::NodeJsErrorCode;
use node_resolver::errors::NodeJsErrorCoded;
-use node_resolver::errors::ResolvePkgSubpathFromDenoModuleError;
+use node_resolver::errors::PackageSubpathResolveError;
use node_resolver::NodeModuleKind;
-use node_resolver::NodeResolution;
use node_resolver::NodeResolutionMode;
use once_cell::sync::Lazy;
use std::borrow::Cow;
@@ -302,8 +304,76 @@ pub struct EmittedFile {
pub media_type: MediaType,
}
+pub fn into_specifier_and_media_type(
+ specifier: Option<ModuleSpecifier>,
+) -> (ModuleSpecifier, MediaType) {
+ match specifier {
+ Some(specifier) => {
+ let media_type = MediaType::from_specifier(&specifier);
+
+ (specifier, media_type)
+ }
+ None => (
+ Url::parse("internal:///missing_dependency.d.ts").unwrap(),
+ MediaType::Dts,
+ ),
+ }
+}
+
+#[derive(Debug)]
+pub struct TypeCheckingCjsTracker {
+ cjs_tracker: Arc<CjsTracker>,
+ module_info_cache: Arc<ModuleInfoCache>,
+}
+
+impl TypeCheckingCjsTracker {
+ pub fn new(
+ cjs_tracker: Arc<CjsTracker>,
+ module_info_cache: Arc<ModuleInfoCache>,
+ ) -> Self {
+ Self {
+ cjs_tracker,
+ module_info_cache,
+ }
+ }
+
+ pub fn is_cjs(
+ &self,
+ specifier: &ModuleSpecifier,
+ media_type: MediaType,
+ code: &Arc<str>,
+ ) -> bool {
+ if let Some(module_kind) =
+ self.cjs_tracker.get_known_kind(specifier, media_type)
+ {
+ module_kind.is_cjs()
+ } else {
+ let maybe_is_script = self
+ .module_info_cache
+ .as_module_analyzer()
+ .analyze_sync(specifier, media_type, code)
+ .ok()
+ .map(|info| info.is_script);
+ maybe_is_script
+ .and_then(|is_script| {
+ self
+ .cjs_tracker
+ .is_cjs_with_known_is_script(specifier, media_type, is_script)
+ .ok()
+ })
+ .unwrap_or_else(|| {
+ self
+ .cjs_tracker
+ .is_maybe_cjs(specifier, media_type)
+ .unwrap_or(false)
+ })
+ }
+ }
+}
+
#[derive(Debug)]
pub struct RequestNpmState {
+ pub cjs_tracker: Arc<TypeCheckingCjsTracker>,
pub node_resolver: Arc<NodeResolver>,
pub npm_resolver: Arc<dyn CliNpmResolver>,
}
@@ -456,7 +526,7 @@ pub fn as_ts_script_kind(media_type: MediaType) -> i32 {
MediaType::Tsx => 4,
MediaType::Json => 6,
MediaType::SourceMap
- | MediaType::TsBuildInfo
+ | MediaType::Css
| MediaType::Wasm
| MediaType::Unknown => 0,
}
@@ -489,25 +559,22 @@ fn op_load_inner(
) -> Result<Option<LoadResponse>, AnyError> {
fn load_from_node_modules(
specifier: &ModuleSpecifier,
- node_resolver: Option<&NodeResolver>,
+ npm_state: Option<&RequestNpmState>,
media_type: &mut MediaType,
is_cjs: &mut bool,
) -> Result<String, AnyError> {
*media_type = MediaType::from_specifier(specifier);
- *is_cjs = node_resolver
- .map(|node_resolver| {
- match node_resolver.url_to_node_resolution(specifier.clone()) {
- Ok(NodeResolution::CommonJs(_)) => true,
- Ok(NodeResolution::Esm(_))
- | Ok(NodeResolution::BuiltIn(_))
- | Err(_) => false,
- }
- })
- .unwrap_or(false);
let file_path = specifier.to_file_path().unwrap();
let code = std::fs::read_to_string(&file_path)
.with_context(|| format!("Unable to load {}", file_path.display()))?;
- Ok(code)
+ let code: Arc<str> = code.into();
+ *is_cjs = npm_state
+ .map(|npm_state| {
+ npm_state.cjs_tracker.is_cjs(specifier, *media_type, &code)
+ })
+ .unwrap_or(false);
+ // todo(dsherret): how to avoid cloning here?
+ Ok(code.to_string())
}
let state = state.borrow_mut::<State>();
@@ -560,6 +627,9 @@ fn op_load_inner(
match module {
Module::Js(module) => {
media_type = module.media_type;
+ if matches!(media_type, MediaType::Cjs | MediaType::Cts) {
+ is_cjs = true;
+ }
let source = module
.fast_check_module()
.map(|m| &*m.source)
@@ -573,11 +643,13 @@ fn op_load_inner(
Module::Npm(_) | Module::Node(_) => None,
Module::External(module) => {
// means it's Deno code importing an npm module
- let specifier =
- node::resolve_specifier_into_node_modules(&module.specifier);
+ let specifier = node::resolve_specifier_into_node_modules(
+ &module.specifier,
+ &deno_fs::RealFs,
+ );
Some(Cow::Owned(load_from_node_modules(
&specifier,
- state.maybe_npm.as_ref().map(|n| n.node_resolver.as_ref()),
+ state.maybe_npm.as_ref(),
&mut media_type,
&mut is_cjs,
)?))
@@ -590,7 +662,7 @@ fn op_load_inner(
{
Some(Cow::Owned(load_from_node_modules(
specifier,
- Some(npm.node_resolver.as_ref()),
+ Some(npm),
&mut media_type,
&mut is_cjs,
)?))
@@ -739,7 +811,13 @@ fn op_resolve_inner(
}
}
};
- (specifier_str, media_type.as_ts_extension())
+ (
+ specifier_str,
+ match media_type {
+ MediaType::Css => ".js", // surface these as .js for typescript
+ media_type => media_type.as_ts_extension(),
+ },
+ )
}
None => (
MISSING_DEPENDENCY_SPECIFIER.to_string(),
@@ -810,29 +888,27 @@ fn resolve_graph_specifier_types(
Some(referrer),
NodeResolutionMode::Types,
);
- let maybe_resolution = match res_result {
- Ok(res) => Some(res),
+ let maybe_url = match res_result {
+ Ok(url) => Some(url),
Err(err) => match err.code() {
NodeJsErrorCode::ERR_TYPES_NOT_FOUND
| NodeJsErrorCode::ERR_MODULE_NOT_FOUND => None,
_ => return Err(err.into()),
},
};
- Ok(Some(NodeResolution::into_specifier_and_media_type(
- maybe_resolution,
- )))
+ Ok(Some(into_specifier_and_media_type(maybe_url)))
} else {
Ok(None)
}
}
Some(Module::External(module)) => {
// we currently only use "External" for when the module is in an npm package
- Ok(state.maybe_npm.as_ref().map(|npm| {
- let specifier =
- node::resolve_specifier_into_node_modules(&module.specifier);
- NodeResolution::into_specifier_and_media_type(
- npm.node_resolver.url_to_node_resolution(specifier).ok(),
- )
+ Ok(state.maybe_npm.as_ref().map(|_| {
+ let specifier = node::resolve_specifier_into_node_modules(
+ &module.specifier,
+ &deno_fs::RealFs,
+ );
+ into_specifier_and_media_type(Some(specifier))
}))
}
Some(Module::Node(_)) | None => Ok(None),
@@ -844,7 +920,7 @@ enum ResolveNonGraphSpecifierTypesError {
#[error(transparent)]
ResolvePkgFolderFromDenoReq(#[from] ResolvePkgFolderFromDenoReqError),
#[error(transparent)]
- ResolvePkgSubpathFromDenoModule(#[from] ResolvePkgSubpathFromDenoModuleError),
+ PackageSubpathResolve(#[from] PackageSubpathResolveError),
}
fn resolve_non_graph_specifier_types(
@@ -863,7 +939,7 @@ fn resolve_non_graph_specifier_types(
let node_resolver = &npm.node_resolver;
if node_resolver.in_npm_package(referrer) {
// we're in an npm package, so use node resolution
- Ok(Some(NodeResolution::into_specifier_and_media_type(
+ Ok(Some(into_specifier_and_media_type(
node_resolver
.resolve(
raw_specifier,
@@ -871,7 +947,8 @@ fn resolve_non_graph_specifier_types(
referrer_kind,
NodeResolutionMode::Types,
)
- .ok(),
+ .ok()
+ .map(|res| res.into_url()),
)))
} else if let Ok(npm_req_ref) =
NpmPackageReqReference::from_str(raw_specifier)
@@ -890,17 +967,15 @@ fn resolve_non_graph_specifier_types(
Some(referrer),
NodeResolutionMode::Types,
);
- let maybe_resolution = match res_result {
- Ok(res) => Some(res),
+ let maybe_url = match res_result {
+ Ok(url) => Some(url),
Err(err) => match err.code() {
NodeJsErrorCode::ERR_TYPES_NOT_FOUND
| NodeJsErrorCode::ERR_MODULE_NOT_FOUND => None,
_ => return Err(err.into()),
},
};
- Ok(Some(NodeResolution::into_specifier_and_media_type(
- maybe_resolution,
- )))
+ Ok(Some(into_specifier_and_media_type(maybe_url)))
} else {
Ok(None)
}