Skip to content

Commit 56ee26c

Browse files
committed
refactor: move tsconfig resolution related code to its own file (#855)
1 parent a67f304 commit 56ee26c

File tree

3 files changed

+263
-253
lines changed

3 files changed

+263
-253
lines changed

src/lib.rs

Lines changed: 6 additions & 227 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ mod path;
5757
mod resolution;
5858
mod specifier;
5959
mod tsconfig;
60-
mod tsconfig_context;
60+
mod tsconfig_resolver;
6161
#[cfg(target_os = "windows")]
6262
mod windows;
6363

@@ -83,11 +83,7 @@ pub use crate::{
8383
CompilerOptions, CompilerOptionsPathsMap, ExtendsField, ProjectReference, TsConfig,
8484
},
8585
};
86-
use crate::{
87-
context::ResolveContext as Ctx, path::SLASH_START, specifier::Specifier,
88-
tsconfig_context::TsconfigResolveContext,
89-
};
90-
use rustc_hash::FxHashSet;
86+
9187
use std::{
9288
borrow::Cow,
9389
cmp::Ordering,
@@ -97,6 +93,10 @@ use std::{
9793
sync::Arc,
9894
};
9995

96+
use rustc_hash::FxHashSet;
97+
98+
use crate::{context::ResolveContext as Ctx, path::SLASH_START, specifier::Specifier};
99+
100100
type ResolveResult = Result<Option<CachedPath>, ResolveError>;
101101

102102
/// Context returned from the [Resolver::resolve_with_context] API
@@ -187,27 +187,6 @@ impl<Fs: FileSystem> ResolverGeneric<Fs> {
187187
self.resolve_tracing(directory.as_ref(), specifier, &mut ctx)
188188
}
189189

190-
/// Resolve `tsconfig`.
191-
///
192-
/// The path can be:
193-
///
194-
/// * Path to a file with `.json` extension.
195-
/// * Path to a file without `.json` extension, `.json` will be appended to filename.
196-
/// * Path to a directory, where the filename is defaulted to `tsconfig.json`
197-
///
198-
/// # Errors
199-
///
200-
/// * See [ResolveError]
201-
pub fn resolve_tsconfig<P: AsRef<Path>>(&self, path: P) -> Result<Arc<TsConfig>, ResolveError> {
202-
let path = path.as_ref();
203-
self.load_tsconfig(
204-
true,
205-
path,
206-
&TsconfigReferences::Auto,
207-
&mut TsconfigResolveContext::default(),
208-
)
209-
}
210-
211190
/// Resolve `specifier` at absolute `path` with [ResolveContext]
212191
///
213192
/// # Errors
@@ -1331,206 +1310,6 @@ impl<Fs: FileSystem> ResolverGeneric<Fs> {
13311310
None
13321311
}
13331312

1334-
fn load_tsconfig(
1335-
&self,
1336-
root: bool,
1337-
path: &Path,
1338-
references: &TsconfigReferences,
1339-
ctx: &mut TsconfigResolveContext,
1340-
) -> Result<Arc<TsConfig>, ResolveError> {
1341-
self.cache.get_tsconfig(root, path, |tsconfig| {
1342-
let directory = self.cache.value(tsconfig.directory());
1343-
tracing::trace!(tsconfig = ?tsconfig, "load_tsconfig");
1344-
1345-
if ctx.is_already_extended(tsconfig.path()) {
1346-
return Err(ResolveError::TsconfigCircularExtend(
1347-
ctx.get_extended_configs_with(tsconfig.path().to_path_buf()).into(),
1348-
));
1349-
}
1350-
1351-
// Extend tsconfig
1352-
let extended_tsconfig_paths = tsconfig
1353-
.extends()
1354-
.map(|specifier| self.get_extended_tsconfig_path(&directory, tsconfig, specifier))
1355-
.collect::<Result<Vec<_>, _>>()?;
1356-
if !extended_tsconfig_paths.is_empty() {
1357-
ctx.with_extended_file(tsconfig.path().to_owned(), |ctx| {
1358-
for extended_tsconfig_path in extended_tsconfig_paths {
1359-
let extended_tsconfig = self.load_tsconfig(
1360-
/* root */ false,
1361-
&extended_tsconfig_path,
1362-
&TsconfigReferences::Disabled,
1363-
ctx,
1364-
)?;
1365-
tsconfig.extend_tsconfig(&extended_tsconfig);
1366-
}
1367-
Result::Ok::<(), ResolveError>(())
1368-
})?;
1369-
}
1370-
1371-
if tsconfig.load_references(references) {
1372-
let path = tsconfig.path().to_path_buf();
1373-
let directory = tsconfig.directory().to_path_buf();
1374-
for reference in tsconfig.references_mut() {
1375-
let reference_tsconfig_path = directory.normalize_with(reference.path());
1376-
let tsconfig = self.cache.get_tsconfig(
1377-
/* root */ true,
1378-
&reference_tsconfig_path,
1379-
|reference_tsconfig| {
1380-
if reference_tsconfig.path() == path {
1381-
return Err(ResolveError::TsconfigSelfReference(
1382-
reference_tsconfig.path().to_path_buf(),
1383-
));
1384-
}
1385-
self.extend_tsconfig(
1386-
&self.cache.value(reference_tsconfig.directory()),
1387-
reference_tsconfig,
1388-
ctx,
1389-
)?;
1390-
Ok(())
1391-
},
1392-
)?;
1393-
reference.set_tsconfig(tsconfig);
1394-
}
1395-
}
1396-
Ok(())
1397-
})
1398-
}
1399-
1400-
fn extend_tsconfig(
1401-
&self,
1402-
directory: &CachedPath,
1403-
tsconfig: &mut TsConfig,
1404-
ctx: &mut TsconfigResolveContext,
1405-
) -> Result<(), ResolveError> {
1406-
let extended_tsconfig_paths = tsconfig
1407-
.extends()
1408-
.map(|specifier| self.get_extended_tsconfig_path(directory, tsconfig, specifier))
1409-
.collect::<Result<Vec<_>, _>>()?;
1410-
for extended_tsconfig_path in extended_tsconfig_paths {
1411-
let extended_tsconfig = self.load_tsconfig(
1412-
/* root */ false,
1413-
&extended_tsconfig_path,
1414-
&TsconfigReferences::Disabled,
1415-
ctx,
1416-
)?;
1417-
tsconfig.extend_tsconfig(&extended_tsconfig);
1418-
}
1419-
Ok(())
1420-
}
1421-
1422-
fn load_tsconfig_paths(
1423-
&self,
1424-
cached_path: &CachedPath,
1425-
specifier: &str,
1426-
ctx: &mut Ctx,
1427-
) -> ResolveResult {
1428-
if cached_path.inside_node_modules() {
1429-
return Ok(None);
1430-
}
1431-
let tsconfig = match &self.options.tsconfig {
1432-
None => return Ok(None),
1433-
Some(TsconfigDiscovery::Manual(tsconfig_options)) => {
1434-
let tsconfig = self.load_tsconfig(
1435-
/* root */ true,
1436-
&tsconfig_options.config_file,
1437-
&tsconfig_options.references,
1438-
&mut TsconfigResolveContext::default(),
1439-
)?;
1440-
// Cache the loaded tsconfig in the path's directory
1441-
let tsconfig_dir = self.cache.value(tsconfig.directory());
1442-
_ = tsconfig_dir.tsconfig.get_or_init(|| Some(Arc::clone(&tsconfig)));
1443-
tsconfig
1444-
}
1445-
Some(TsconfigDiscovery::Auto) => {
1446-
let Some(tsconfig) = self.find_tsconfig(cached_path, ctx)? else {
1447-
return Ok(None);
1448-
};
1449-
tsconfig
1450-
}
1451-
};
1452-
1453-
let paths = tsconfig.resolve(cached_path.path(), specifier);
1454-
for path in paths {
1455-
let resolved_path = self.cache.value(&path);
1456-
if let Some(resolution) = self.load_as_file_or_directory(&resolved_path, ".", ctx)? {
1457-
// Cache the tsconfig in the resolved path
1458-
_ = resolved_path.tsconfig.get_or_init(|| Some(Arc::clone(&tsconfig)));
1459-
return Ok(Some(resolution));
1460-
}
1461-
}
1462-
Ok(None)
1463-
}
1464-
1465-
/// Find tsconfig.json of a path by traversing parent directories.
1466-
///
1467-
/// # Errors
1468-
///
1469-
/// * [ResolveError::Json]
1470-
pub(crate) fn find_tsconfig(
1471-
&self,
1472-
cached_path: &CachedPath,
1473-
ctx: &mut Ctx,
1474-
) -> Result<Option<Arc<TsConfig>>, ResolveError> {
1475-
// Don't discover tsconfig for paths inside node_modules
1476-
if cached_path.inside_node_modules() {
1477-
return Ok(None);
1478-
}
1479-
// Skip non-absolute paths (e.g. virtual modules)
1480-
if !cached_path.path.is_absolute() {
1481-
return Ok(None);
1482-
}
1483-
1484-
let mut cache_value = Some(cached_path.clone());
1485-
while let Some(cv) = cache_value {
1486-
if let Some(tsconfig) = cv.tsconfig.get_or_try_init(|| {
1487-
let tsconfig_path = cv.path.join("tsconfig.json");
1488-
let tsconfig_path = self.cache.value(&tsconfig_path);
1489-
if self.cache.is_file(&tsconfig_path, ctx) {
1490-
self.resolve_tsconfig(tsconfig_path.path()).map(Some)
1491-
} else {
1492-
Ok(None)
1493-
}
1494-
})? {
1495-
return Ok(Some(Arc::clone(tsconfig)));
1496-
}
1497-
cache_value = cv.parent();
1498-
}
1499-
Ok(None)
1500-
}
1501-
1502-
fn get_extended_tsconfig_path(
1503-
&self,
1504-
directory: &CachedPath,
1505-
tsconfig: &TsConfig,
1506-
specifier: &str,
1507-
) -> Result<PathBuf, ResolveError> {
1508-
match specifier.as_bytes().first() {
1509-
None => Err(ResolveError::Specifier(SpecifierError::Empty(specifier.to_string()))),
1510-
Some(b'/') => Ok(PathBuf::from(specifier)),
1511-
Some(b'.') => Ok(tsconfig.directory().normalize_with(specifier)),
1512-
_ => self
1513-
.clone_with_options(ResolveOptions {
1514-
tsconfig: None,
1515-
extensions: vec![".json".into()],
1516-
main_files: vec!["tsconfig".into()],
1517-
#[cfg(feature = "yarn_pnp")]
1518-
yarn_pnp: self.options.yarn_pnp,
1519-
#[cfg(feature = "yarn_pnp")]
1520-
cwd: self.options.cwd.clone(),
1521-
..ResolveOptions::default()
1522-
})
1523-
.load_package_self_or_node_modules(directory, specifier, &mut Ctx::default())
1524-
.map(|p| p.to_path_buf())
1525-
.map_err(|err| match err {
1526-
ResolveError::NotFound(_) => {
1527-
ResolveError::TsconfigNotFound(PathBuf::from(specifier))
1528-
}
1529-
_ => err,
1530-
}),
1531-
}
1532-
}
1533-
15341313
/// PACKAGE_RESOLVE(packageSpecifier, parentURL)
15351314
fn package_resolve(
15361315
&self,

src/tsconfig_context.rs

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)