`) AND:
- ///
- /// * It matches a positive `include` pattern and isn't excluded by a later negative `include` pattern.
- /// * It doesn't match a positive `exclude` pattern or is re-included by a later negative `exclude` pattern.
- ///
- /// ## Note
- ///
- /// This method may return `true` for files that don't end up being included when walking the
- /// project tree because it doesn't consider `.gitignore` and other ignore files when deciding
- /// if a file's included.
- pub(crate) fn is_included(&self, path: &SystemPath) -> bool {
- #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
- enum CheckPathMatch {
- /// The path is a partial match of the checked path (it's a sub path)
- Partial,
-
- /// The path matches a check path exactly.
- Full,
- }
-
- let m = if self.skip_included_paths {
- Some(CheckPathMatch::Partial)
- } else {
- self.included_paths
- .iter()
- .filter_map(|included_path| {
- if let Ok(relative_path) = path.strip_prefix(included_path) {
- // Exact matches are always included
- if relative_path.as_str().is_empty() {
- Some(CheckPathMatch::Full)
- } else {
- Some(CheckPathMatch::Partial)
- }
- } else {
- None
- }
- })
- .max()
- };
-
- match m {
- None => false,
- Some(CheckPathMatch::Partial) => {
- // TODO: For partial matches, only include the file if it is included by the project's include/exclude settings.
- true
- }
- Some(CheckPathMatch::Full) => true,
- }
- }
-}
-
-pub(crate) struct ProjectFilesWalker<'a> {
- walker: WalkDirectoryBuilder,
-
- filter: ProjectFilesFilter<'a>,
-}
-
-impl<'a> ProjectFilesWalker<'a> {
- pub(crate) fn new(db: &'a dyn Db) -> Self {
- let project = db.project();
-
- let mut filter = ProjectFilesFilter::from_project(db, project);
- // It's unnecessary to filter on included paths because it only iterates over those to start with.
- filter.skip_included_paths = true;
-
- Self::from_paths(db, project.included_paths_or_root(db), filter)
- .expect("included_paths_or_root to never return an empty iterator")
- }
-
- /// Creates a walker for indexing the project files incrementally.
- ///
- /// The main difference to a full project walk is that `paths` may contain paths
- /// that aren't part of the included files.
- pub(crate) fn incremental(db: &'a dyn Db, paths: impl IntoIterator- ) -> Option
- where
- P: AsRef,
- {
- let project = db.project();
-
- let filter = ProjectFilesFilter::from_project(db, project);
-
- Self::from_paths(db, paths, filter)
- }
-
- fn from_paths