Skip to content

Commit 28d7da4

Browse files
committed
chore: trim verbose VFS and host comments
Keep short module docs and non-obvious behavior notes; drop fork narratives, outdated identity comments, and redundant restatements.
1 parent f833f34 commit 28d7da4

11 files changed

Lines changed: 27 additions & 138 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ utils = { workspace = true, features = ["test-support"] }
138138

139139
[features]
140140
default = ["server-file-watcher"]
141-
# OS notify-based server file watching (disable for wasm / headless client-only).
141+
# Server OS file watching (off for wasm).
142142
server-file-watcher = ["vfs/notify-backend"]
143143
profile-trace = ["dep:tracing-chrome"]
144144
user-config-schema = ["dep:schemars"]

crates/project-model/src/lib.rs

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ pub struct WorkspaceRoot {
6262
pub extra_files: Vec<AbsPathBuf>,
6363
/// Include/search roots loaded as headers and passed to preprocessing.
6464
pub include_dirs: Vec<AbsPathBuf>,
65-
/// Absolute directory prefixes excluded from directory loads (expanded from
66-
/// manifest exclude globs before the loader sees them).
65+
/// Exclude directory prefixes for loader `Directories` (from manifest
66+
/// globs).
6767
pub exclude_prefixes: Vec<AbsPathBuf>,
68-
/// Glob matcher retained for FileSet classification of opened files.
68+
/// Exclude globs for FileSet classification.
6969
pub exclude_globs: Option<PathGlobMatcher>,
7070
}
7171

@@ -459,11 +459,8 @@ fn compile_manifest_globs(
459459
.with_context(|| format!("failed to compile manifest {field} glob patterns"))
460460
}
461461

462-
/// Expand exclude globs into absolute directory prefixes for the loader.
463-
///
464-
/// Patterns that are pure wildcards (e.g. `**/*.sv`) are skipped here; those
465-
/// still participate in FileSet classification via
466-
/// [`WorkspaceRoot::exclude_globs`].
462+
/// Expand exclude globs to directory prefixes; skip pure wildcards (e.g.
463+
/// `**/*.sv`).
467464
fn exclude_prefixes_from_patterns(
468465
workspace_root: &AbsPathBuf,
469466
patterns: &[String],
@@ -664,8 +661,6 @@ pub fn get_workspace_folder(
664661
exclude_paths.push(excl.clone());
665662
}
666663
}
667-
// Manifest exclude globs are expanded to directory prefixes before
668-
// the loader (r-a-shaped Directories has no glob field).
669664
exclude_paths.extend(root.exclude_prefixes.iter().cloned());
670665
sort_and_remove_subfolders(&mut exclude_paths);
671666
let mut include = Vec::new();
@@ -700,9 +695,6 @@ pub fn get_workspace_folder(
700695
load_entries.push(vfs::loader::Entry::Files(source_files));
701696
}
702697

703-
// Recursive loads: include_dirs + pure root matchers.
704-
// Glob source patterns (e.g. `rtl/*.sv`) are expanded to Entry::Files
705-
// so the r-a-style loader does not need glob semantics.
706698
let mut directory_include = root.include_dirs.clone();
707699
if !root.source_directories.is_empty() {
708700
if root.source_directories.prefers_recursive_directory_load() {
@@ -1305,7 +1297,6 @@ include_dirs = []
13051297
let (load, _, _, _) = get_workspace_folder(&model.workspaces, &[]);
13061298

13071299
assert!(errors.is_empty(), "{errors:#?}");
1308-
// Shallow globs expand to Entry::Files (loader has no glob depth rules).
13091300
let files = match load.iter().find_map(|entry| match entry {
13101301
vfs::loader::Entry::Files(files) => Some(files),
13111302
_ => None,
@@ -1432,17 +1423,12 @@ exclude = ["**/*_bb.v"]
14321423
let (load, _, source_root_config, _) = get_workspace_folder(&model.workspaces, &[]);
14331424

14341425
assert!(errors.is_empty(), "{errors:#?}");
1435-
// Filename globs like `**/*_bb.v` cannot be expressed as loader directory
1436-
// prefixes (r-a-shaped Directories). They still classify via FileSet.
14371426
let dirs = match &load[0] {
14381427
vfs::loader::Entry::Directories(dirs) => dirs,
14391428
other => panic!("expected directory loader entry, got {other:?}"),
14401429
};
14411430
assert!(dirs.contains_file(top.as_path()));
1442-
assert!(
1443-
dirs.contains_file(blackbox.as_path()),
1444-
"loader may still discover filename-glob matches; FileSet drops them"
1445-
);
1431+
assert!(dirs.contains_file(blackbox.as_path()));
14461432

14471433
let mut vfs = Vfs::default();
14481434
for file in [&top, &blackbox] {

crates/vfs/src/dummy.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
//! In-memory / no-OS loader used when the notify backend is disabled (e.g.
2-
//! wasm).
3-
//!
4-
//! Does not scan the real filesystem or install watchers. Configuration scans
5-
//! complete immediately with empty file batches so the host can still drive
6-
//! readiness from Progress. File contents must come from the client (mem docs)
7-
//! or explicit `invalidate` / `load_sync` against whatever FS the host
8-
//! provides.
1+
//! Loader with no OS file watching (e.g. wasm).
92
103
use std::fmt;
114

@@ -32,7 +25,6 @@ impl loader::Handle for DummyHandle {
3225
dir: None,
3326
config_version,
3427
});
35-
// No disk scan: report empty loads so Progress can finish.
3628
for _ in &config.load {
3729
let _ = self.sender.send(loader::Message::Loaded { files: Vec::new() });
3830
}

crates/vfs/src/file_set.rs

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@ use utils::paths::{AbsPath, AbsPathBuf};
55

66
use crate::{AnchoredPath, FileId, Vfs, VfsPath, path_glob::PathGlobMatcher};
77

8-
/// Bidirectional path map for a single source root.
9-
///
10-
/// A `FileSet` stores the path spelling selected during source-root
11-
/// partitioning. That spelling may be a VFS alias rather than the primary path
12-
/// if the alias is the one that belongs to this root.
8+
/// Files belonging to one source root.
139
#[derive(Debug, Default, Clone, Eq, PartialEq)]
1410
pub struct FileSet {
1511
files: FxHashMap<VfsPath, FileId>,
@@ -50,35 +46,23 @@ impl FileSet {
5046
}
5147
}
5248

53-
/// Rules for partitioning VFS files into ordered source roots.
54-
///
55-
/// Root order is significant. For one VFS file with several aliases,
56-
/// classification evaluates every alias and chooses the earliest non-ignored
57-
/// root. Within a single alias, normal prefix matching still picks the most
58-
/// specific configured root.
49+
/// Partitions VFS files into ordered source roots (earlier roots win).
5950
#[derive(Debug)]
6051
pub struct FileSetConfig {
61-
// Number of sets that can partition into.
62-
// This should be `self.map.len() + 1` for files that don't fit in any defined set.
52+
/// `map` size + 1 for files that match no root.
6353
len: usize,
64-
// Encoded paths -> sets they belong to.
6554
map: fst::Map<Vec<u8>>,
6655
filters: Vec<FileSetFilter>,
6756
}
6857

69-
/// A source-root partition plus the subset that matched semantic source rules.
58+
/// One partition: all files in the root, plus optional semantic source subset.
7059
#[derive(Debug, Default, Clone, Eq, PartialEq)]
7160
pub struct PartitionedFileSet {
7261
pub file_set: FileSet,
7362
pub source_files: Option<FxHashSet<FileId>>,
7463
}
7564

76-
/// Matcher used separately for source classification, directory scans, and
77-
/// include/search roots.
78-
///
79-
/// Keeping those roles separate lets exact source files participate in source
80-
/// ownership without forcing the loader or watcher to scan their parent
81-
/// directories recursively.
65+
/// Path include rule: recursive roots and/or a glob.
8266
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
8367
pub struct PathMatcher {
8468
scan_roots: Vec<AbsPathBuf>,
@@ -126,11 +110,8 @@ impl PathMatcher {
126110
self.scan_roots.iter()
127111
}
128112

129-
/// Whether the loader may use recursive `Directories` for this matcher.
130-
///
131-
/// - `AllUnderRoots` → yes
132-
/// - Glob patterns that contain `**` (e.g. `rtl/**`) → yes (prefix roots)
133-
/// - Shallow globs like `rtl/*.sv` → no; expand to `Entry::Files` instead
113+
/// True if this can be loaded as recursive directory roots (`**` globs or
114+
/// plain roots).
134115
pub fn prefers_recursive_directory_load(&self) -> bool {
135116
match &self.kind {
136117
PathMatcherKind::AllUnderRoots => true,
@@ -140,9 +121,7 @@ impl PathMatcher {
140121
}
141122
}
142123

143-
/// Walk `scan_roots` and collect absolute files that match this matcher and
144-
/// one of `extensions` (no leading dot). Used to expand shallow globs like
145-
/// `rtl/*.sv` without putting glob logic inside the loader.
124+
/// Files under `scan_roots` matching this rule and `extensions`.
146125
pub fn collect_matching_files(&self, extensions: &[&str]) -> Vec<AbsPathBuf> {
147126
let mut files = Vec::new();
148127
for root in &self.scan_roots {
@@ -265,8 +244,6 @@ impl FileSetConfig {
265244
primary_path: &'a VfsPath,
266245
scratch_space: &mut Vec<u8>,
267246
) -> (usize, &'a VfsPath) {
268-
// Path identity aliases were removed with the r-a VFS fork; classify the
269-
// primary interned spelling only.
270247
(self.classify(primary_path, scratch_space), primary_path)
271248
}
272249

crates/vfs/src/lib.rs

Lines changed: 7 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,12 @@
1-
//! Owned fork of rust-analyzer's virtual file system (tinymist-style).
1+
//! Virtual file system: interned paths, content change log, and loader
2+
//! interface.
23
//!
3-
//! Upstream: <https://github.com/rust-lang/rust-analyzer/tree/master/crates/vfs>
4-
//!
5-
//! # Virtual File System
6-
//!
7-
//! VFS records all file changes pushed to it via [`set_file_contents`].
8-
//! As such it only ever stores changes, not the actual content of a file at any
9-
//! given moment. All file changes are logged, and can be retrieved via
10-
//! [`take_changes`] method. The pack of changes is then pushed to `salsa` and
11-
//! triggers incremental recomputation.
12-
//!
13-
//! Files in VFS are identified with [`FileId`]s -- interned paths. The notion
14-
//! of the path, [`VfsPath`] is somewhat abstract: at the moment, it is
15-
//! represented as an [`std::path::PathBuf`] internally, but this is an
16-
//! implementation detail.
17-
//!
18-
//! VFS doesn't do IO or file watching itself. For that, see the [`loader`]
19-
//! module. [`loader::Handle`] is an object-safe trait which abstracts both file
20-
//! loading and file watching. [`Handle`] is dynamically configured with a set
21-
//! of directory entries which should be scanned and watched. [`Handle`] then
22-
//! asynchronously pushes file changes. Directory entries are configured in
23-
//! free-form via list of globs, it's up to the [`Handle`] to interpret the
24-
//! globs in any specific way.
25-
//!
26-
//! VFS stores a flat list of files. [`file_set::FileSet`] can partition this
27-
//! list of files into disjoint sets of files. Traversal-like operations
28-
//! (including getting the neighbor file by the relative path) are handled by
29-
//! the [`FileSet`]. [`FileSet`]s are also pushed to salsa and cause it to
30-
//! re-check `mod foo;` declarations when files are created or deleted.
31-
//!
32-
//! [`FileSet`] and [`loader::Entry`] play similar, but different roles.
33-
//! Both specify the "set of paths/files", one is geared towards file watching,
34-
//! the other towards salsa changes. In particular, single [`FileSet`]
35-
//! may correspond to several [`loader::Entry`]. For example, a crate from
36-
//! crates.io which uses code generation would have two [`Entries`] -- for
37-
//! sources in `~/.cargo`, and for generated code in `./target/debug/build`. It
38-
//! will have a single [`FileSet`] which unions the two sources.
4+
//! Based on rust-analyzer's `vfs` crate
5+
//! (<https://github.com/rust-lang/rust-analyzer/tree/master/crates/vfs>).
6+
//! IO and watching live in [`loader`] backends ([`notify`], [`dummy`]).
397
//!
408
//! [`set_file_contents`]: Vfs::set_file_contents
419
//! [`take_changes`]: Vfs::take_changes
42-
//! [`FileSet`]: file_set::FileSet
43-
//! [`Handle`]: loader::Handle
44-
//! [`Entries`]: loader::Entry
4510
4611
mod anchored_path;
4712
pub mod dummy;
@@ -81,12 +46,9 @@ fn hash_once<Hasher: std::hash::Hasher + Default>(thing: impl std::hash::Hash) -
8146
h.finish()
8247
}
8348

84-
/// Handle to a file in [`Vfs`]
85-
///
86-
/// Most functions in rust-analyzer use this when they need to refer to a file.
49+
/// Interned file identity in [`Vfs`].
8750
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
8851
pub struct FileId(u32);
89-
// pub struct FileId(NonMaxU32);
9052

9153
impl FileId {
9254
const MAX: u32 = 0x7fff_ffff;
@@ -166,7 +128,7 @@ impl ChangedFile {
166128
}
167129
}
168130

169-
/// UTF-8 file text for analysis; invalid UTF-8 becomes empty.
131+
/// UTF-8 text; invalid UTF-8 becomes empty.
170132
pub fn text(&self) -> Option<triomphe::Arc<str>> {
171133
let bytes = match &self.change {
172134
Change::Create(bytes, _) | Change::Modify(bytes, _) => bytes.as_slice(),
@@ -176,29 +138,25 @@ impl ChangedFile {
176138
Some(triomphe::Arc::<str>::from(text))
177139
}
178140

179-
/// Bytes for Create/Modify; `None` for Delete.
180141
pub fn contents(&self) -> Option<&[u8]> {
181142
match &self.change {
182143
Change::Create(bytes, _) | Change::Modify(bytes, _) => Some(bytes.as_slice()),
183144
Change::Delete => None,
184145
}
185146
}
186147

187-
/// Test/host helper: create a file with UTF-8 text contents.
188148
pub fn create(file_id: FileId, text: impl AsRef<str>) -> Self {
189149
let bytes = text.as_ref().as_bytes().to_vec();
190150
let hash = hash_once::<FxHasher>(&*bytes);
191151
Self { file_id, change: Change::Create(bytes, hash) }
192152
}
193153

194-
/// Test/host helper: modify a file with UTF-8 text contents.
195154
pub fn modify(file_id: FileId, text: impl AsRef<str>) -> Self {
196155
let bytes = text.as_ref().as_bytes().to_vec();
197156
let hash = hash_once::<FxHasher>(&*bytes);
198157
Self { file_id, change: Change::Modify(bytes, hash) }
199158
}
200159

201-
/// Test/host helper: delete a file.
202160
pub fn delete(file_id: FileId) -> Self {
203161
Self { file_id, change: Change::Delete }
204162
}
@@ -339,7 +297,6 @@ impl Vfs {
339297
}
340298
// shouldn't occur, but collapse into `Create`
341299
(change @ Delete, Modify(new, new_hash)) => {
342-
// Shouldn't occur; collapse into Create like upstream.
343300
*change = Create(new, new_hash);
344301
}
345302
// shouldn't occur, but keep the Create

crates/vfs/src/loader.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
//! Dynamically compatible interface for file watching and reading.
2-
//!
3-
//! Owned fork of rust-analyzer `vfs::loader`. SystemVerilog extensions and
4-
//! exclude prefixes are supplied by callers (`project-model`); glob expansion
5-
//! happens before `set_config`, not inside the loader.
1+
//! File loading and watching interface used by the VFS.
62
use std::fmt;
73

84
use utils::paths::{AbsPath, AbsPathBuf};
95

10-
/// File extensions loaded from recursive directory entries for SystemVerilog.
6+
/// Extensions for recursive directory loads (SystemVerilog sources).
117
pub const SOURCE_FILE_EXTENSIONS: &[&str] = &["v", "sv", "vh", "svh", "svi", "map"];
128

139
/// A set of files on the file system.

crates/vfs/src/notify.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,4 @@
1-
//! Owned fork of rust-analyzer `vfs-notify`.
2-
//!
3-
//! Upstream: <https://github.com/rust-lang/rust-analyzer/tree/master/crates/vfs-notify>
4-
//!
5-
//! An implementation of `loader::Handle`, based on `walkdir` and `notify`.
6-
//!
7-
//! The file watching bits here are untested and quite probably buggy. For this
8-
//! reason, by default we don't watch files and rely on editor's file watching
9-
//! capabilities.
10-
//!
11-
//! Hopefully, one day a reliable file watching/walking crate appears on
12-
//! crates.io, and we can reduce this to trivial glue code.
1+
//! `loader::Handle` backed by `walkdir` and OS `notify` (best-effort).
132
143
use std::{
154
fs,

crates/vfs/src/vfs_path.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ impl VfsPath {
4040
}
4141
}
4242

43-
/// Alias kept for vide call sites (rust-analyzer name is `as_path`).
4443
pub fn as_abs_path(&self) -> Option<&AbsPath> {
4544
self.as_path()
4645
}

src/global_state/event_loop.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,7 @@ impl GlobalState {
371371
return;
372372
};
373373

374-
// Empty loads still flip readiness via Finished Progress, but do not
375-
// spam the client with a 0/0 work-done sequence.
374+
// Ready already updated; skip empty 0/0 client progress.
376375
if progress.n_total == 0 {
377376
return;
378377
}
@@ -396,8 +395,6 @@ impl GlobalState {
396395
}
397396
}
398397
}
399-
// rust-analyzer style: content batches have no config_version; only
400-
// Progress gates generation readiness.
401398
vfs_loader::Message::Loaded { files } => {
402399
self.process_vfs_files(files, VfsFileSource::ConfigScan);
403400
}

src/global_state/main_loop.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,6 @@ mod tests {
318318

319319
#[test]
320320
fn content_batches_apply_without_generation_token() {
321-
// rust-analyzer style: Loaded/Changed carry no config_version. Generation
322-
// readiness is gated only by Progress; content batches always apply.
323321
let root = TestDir::new("content-batches-apply");
324322
let root_path = root.path().to_path_buf();
325323
let file_path = root_path.join("file.sv");

0 commit comments

Comments
 (0)