mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 12:19:12 +00:00

- Each workspace directory is probed for a `tsconfig.json`. - These and any that are included by their `references` are put into a list ordered by priority. - A tsconfig has lower priority than its `references`. - An earlier listed entry in `references` has higher priority than a later one. - A probed tsconfig in an inner directory has higher priority than an outer one. Their `references` would be interspersed between them. - Each tsconfig has a filter based on its `files`, `include` and `exclude` fields. If it doesn't have `files` or `include`, it will match any path in its containing directory not exempted by `exclude`. - For type-checking, each root path will be allocated compiler options based on the first tsconfig it whose filter it matches from this list. - Only if it doesn't match any tsconfig, it will fall back to using the nearest `deno.json`. If it's a workspace member and the root `deno.json` has `compilerOptions`, these will be merged using the same logic from `extends`. Inheritance between configs strictly occurs via `extends` in a `tsconfig.json`, and between workspace member and root `deno.json`s' `compilerOptions`. There is no implicit inheritance between `tsconfig.json` and `deno.json`. The default compiler options currently applied against tsconfigs are Deno's normal defaults, with the exception of `lib`. The default value for `lib` is `["deno.window", "deno.unstable", "dom"]` for files in the scope of a tsconfig with `lib` unspecified. This behaviour is depended on by, for example, the template project created by `create-vite -> svelte`. I expect we'll add more such exceptions over time with other fields.
104 lines
2.5 KiB
Rust
104 lines
2.5 KiB
Rust
// Copyright 2018-2025 the Deno authors. MIT license.
|
|
|
|
use std::collections::BTreeMap;
|
|
|
|
use url::Url;
|
|
|
|
#[allow(clippy::disallowed_types)]
|
|
type UrlRc = crate::sync::MaybeArc<Url>;
|
|
|
|
/// A map that stores values scoped to a specific directory
|
|
/// on the file system.
|
|
///
|
|
/// The root directory is considered "unscoped" so values that
|
|
/// fall outside the other directories land here (ex. remote modules).
|
|
pub struct FolderScopedMap<TValue> {
|
|
pub unscoped: TValue,
|
|
scoped: BTreeMap<UrlRc, TValue>,
|
|
}
|
|
|
|
impl<TValue> std::fmt::Debug for FolderScopedMap<TValue>
|
|
where
|
|
TValue: std::fmt::Debug,
|
|
{
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
f.debug_struct("FolderScopedMap")
|
|
.field("unscoped", &self.unscoped)
|
|
.field("scoped", &self.scoped)
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
impl<TValue> Default for FolderScopedMap<TValue>
|
|
where
|
|
TValue: Default,
|
|
{
|
|
fn default() -> Self {
|
|
Self::new(Default::default())
|
|
}
|
|
}
|
|
|
|
impl<TValue> FolderScopedMap<TValue> {
|
|
pub fn new(unscoped: TValue) -> Self {
|
|
Self {
|
|
unscoped,
|
|
scoped: Default::default(),
|
|
}
|
|
}
|
|
|
|
pub fn count(&self) -> usize {
|
|
// +1 for unscoped
|
|
self.scoped.len() + 1
|
|
}
|
|
|
|
pub fn get_for_specifier(&self, specifier: &Url) -> &TValue {
|
|
self.get_for_specifier_str(specifier.as_str())
|
|
}
|
|
|
|
pub fn get_for_specifier_str(&self, specifier: &str) -> &TValue {
|
|
self
|
|
.scoped
|
|
.iter()
|
|
.rfind(|(s, _)| specifier.starts_with(s.as_str()))
|
|
.map(|(_, v)| v)
|
|
.unwrap_or(&self.unscoped)
|
|
}
|
|
|
|
pub fn entry_for_specifier(
|
|
&self,
|
|
specifier: &Url,
|
|
) -> (Option<&UrlRc>, &TValue) {
|
|
self
|
|
.scoped
|
|
.iter()
|
|
.rfind(|(s, _)| specifier.as_str().starts_with(s.as_str()))
|
|
.map(|(s, v)| (Some(s), v))
|
|
.unwrap_or((None, &self.unscoped))
|
|
}
|
|
|
|
pub fn entries(&self) -> impl Iterator<Item = (Option<&UrlRc>, &TValue)> {
|
|
[(None, &self.unscoped)]
|
|
.into_iter()
|
|
.chain(self.scoped.iter().map(|(s, v)| (Some(s), v)))
|
|
}
|
|
|
|
pub fn insert(&mut self, dir_url: UrlRc, value: TValue) {
|
|
debug_assert!(dir_url.path().ends_with("/")); // must be a dir url
|
|
debug_assert_eq!(dir_url.scheme(), "file");
|
|
self.scoped.insert(dir_url, value);
|
|
}
|
|
|
|
pub fn try_map<B, E>(
|
|
&self,
|
|
mut f: impl FnMut(&TValue) -> Result<B, E>,
|
|
) -> Result<FolderScopedMap<B>, E> {
|
|
Ok(FolderScopedMap {
|
|
unscoped: f(&self.unscoped)?,
|
|
scoped: self
|
|
.scoped
|
|
.iter()
|
|
.map(|(s, v)| Ok((s.clone(), f(v)?)))
|
|
.collect::<Result<_, _>>()?,
|
|
})
|
|
}
|
|
}
|