Skip to content

Commit

Permalink
Fix deleted directory file handling in LSP mode
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Feb 26, 2024
1 parent 7170e52 commit 36a37a4
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 29 deletions.
1 change: 1 addition & 0 deletions src/aast_utils/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod naming_visitor;

#[derive(Debug)]
pub enum ParserError {
CannotReadFile,
NotAHackFile,
SyntaxError { message: String, pos: HPos },
}
Expand Down
15 changes: 15 additions & 0 deletions src/file_scanner_analyzer/analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,21 @@ fn analyze_file(
},
&None,
),
ParserError::CannotReadFile => Issue::new(
IssueKind::InvalidHackFile,
"Cannot read file".to_string(),
HPos {
file_path,
start_offset: 0,
end_offset: 0,
start_line: 0,
end_line: 0,
start_column: 0,
end_column: 0,
insertion_start: None,
},
&None,
),
ParserError::SyntaxError { message, pos } => {
Issue::new(IssueKind::InvalidHackFile, message, pos, &None)
}
Expand Down
31 changes: 27 additions & 4 deletions src/file_scanner_analyzer/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub enum FileStatus {
Unchanged(u64, u64),
Added(u64, u64),
Deleted,
DeletedDir,
Modified(u64, u64),
}

Expand All @@ -35,10 +36,29 @@ impl VirtualFileSystem {
config: &Config,
files_to_analyze: &mut Vec<String>,
) {
let deleted_folders = language_server_changes
.iter()
.filter(|(_, v)| matches!(v, FileStatus::DeletedDir))
.into_iter()
.map(|(k, _)| k)
.collect::<Vec<_>>();

let mut deleted_files = vec![];

for file in self.file_hashes_and_times.keys() {
let str_path = interner.lookup(&file.0).to_string();

if !language_server_changes.contains_key(&str_path) {
let in_deleted_folder = deleted_folders
.iter()
.any(|f| str_path.starts_with(&(f.to_string() + "/")));

if in_deleted_folder {
deleted_files.push(*file);
} else if let Some(file_status) = language_server_changes.get(&str_path) {
if let FileStatus::Deleted = file_status {
deleted_files.push(*file);
}
} else {
files_to_scan.push(str_path.clone());

if !str_path.starts_with("hsl_embedded") && !str_path.ends_with(".hhi") {
Expand All @@ -53,6 +73,10 @@ impl VirtualFileSystem {
}
}

for deleted_file in deleted_files {
self.file_hashes_and_times.remove(&deleted_file);
}

for (file_path, status) in language_server_changes {
let path = Path::new(&file_path);

Expand All @@ -70,9 +94,8 @@ impl VirtualFileSystem {
files_to_analyze,
);
}
FileStatus::Deleted => {
let file_path = interner.intern(path.to_str().unwrap().to_string());
self.file_hashes_and_times.remove(&FilePath(file_path));
FileStatus::Deleted | FileStatus::DeletedDir => {
// handled above
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/file_scanner_analyzer/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ pub fn get_aast_for_path(
} else {
match fs::read_to_string(file_path_str) {
Ok(str_file) => str_file,
Err(_) => return Err(ParserError::NotAHackFile),
Err(_) => return Err(ParserError::CannotReadFile),
}
};

Expand Down
1 change: 1 addition & 0 deletions src/file_scanner_analyzer/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ pub fn analyze_single_file(
Ok(aast) => aast,
Err(error) => match error {
ParserError::NotAHackFile => return Err("Not a Hack file".to_string()),
ParserError::CannotReadFile => return Err("Cannot read file".to_string()),
ParserError::SyntaxError { message, pos } => {
analysis_result.emitted_issues.insert(
file_path,
Expand Down
61 changes: 37 additions & 24 deletions src/language_server/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,12 @@ impl LanguageServer for Backend {
kind: None,
},
FileSystemWatcher {
glob_pattern: GlobPattern::String("**/index.lock".to_string()),
kind: None,
glob_pattern: GlobPattern::String("**/.git/index.lock".to_string()),
kind: Some(WatchKind::Delete),
},
FileSystemWatcher {
glob_pattern: GlobPattern::String("**/[!.]*/**/".to_string()),
kind: Some(WatchKind::Delete),
},
],
})
Expand All @@ -100,33 +104,42 @@ impl LanguageServer for Backend {
async fn did_change_watched_files(&mut self, params: DidChangeWatchedFilesParams) {
let mut new_file_statuses = FxHashMap::default();

// self.client
// .log_message(
// MessageType::INFO,
// format!("receiving changes {:?}", params.changes),
// )
// .await;

for file_event in params.changes {
//let uri = file_event.uri;
let change_type = file_event.typ;

let file_path = file_event.uri.path().to_string();

match change_type {
FileChangeType::CREATED => {
new_file_statuses.insert(file_path, FileStatus::Added(0, 0));
}
FileChangeType::CHANGED => {
new_file_statuses.insert(file_path, FileStatus::Modified(0, 0));
if file_path.ends_with(".php")
|| file_path.ends_with(".hack")
|| file_path.ends_with(".hhi")
{
match change_type {
FileChangeType::CREATED => {
new_file_statuses.insert(file_path, FileStatus::Added(0, 0));
}
FileChangeType::CHANGED => {
new_file_statuses.insert(file_path, FileStatus::Modified(0, 0));
}
FileChangeType::DELETED => {
new_file_statuses.insert(file_path, FileStatus::Deleted);
}
_ => {}
}
FileChangeType::DELETED => {
new_file_statuses.insert(file_path, FileStatus::Deleted);
} else if Path::new(&file_path).extension().is_none() {
if let FileChangeType::DELETED = change_type {
new_file_statuses.insert(file_path, FileStatus::DeletedDir);
}
_ => {}
}
}

// self.client
// .log_message(
// MessageType::INFO,
// format!("adding changes {:?}", new_file_statuses),
// )
// .await;

if let Some(ref mut existing_file_changes) = self.file_changes {
existing_file_changes.extend(new_file_statuses);
} else {
Expand All @@ -138,12 +151,12 @@ impl LanguageServer for Backend {
.log_message(MessageType::INFO, "Waiting a sec while git is doing stuff")
.await;
} else {
// self.client
// .log_message(
// MessageType::INFO,
// format!("analyzing changes {:?}", self.file_changes),
// )
// .await;
self.client
.log_message(
MessageType::INFO,
format!("analyzing changes {:?}", self.file_changes),
)
.await;
self.do_analysis().await;
self.file_changes = None;
self.emit_issues().await;
Expand Down

0 comments on commit 36a37a4

Please sign in to comment.