1
1
mirror of https://github.com/oxalica/nil.git synced 2024-09-11 10:36:04 +03:00

Discover all .nix files when running diagnostics

This commit is contained in:
Rebecca Turner 2024-03-01 12:38:17 -08:00
parent 96d47c8d8f
commit 55ccc80b25
No known key found for this signature in database
3 changed files with 87 additions and 18 deletions

40
Cargo.lock generated
View File

@ -128,6 +128,16 @@ version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]]
name = "bstr"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "builtin"
version = "0.0.0"
@ -436,6 +446,19 @@ version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "globset"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1"
dependencies = [
"aho-corasick",
"bstr",
"log",
"regex-automata 0.4.3",
"regex-syntax 0.8.2",
]
[[package]]
name = "half"
version = "1.8.2"
@ -507,6 +530,22 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
[[package]]
name = "ignore"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1"
dependencies = [
"crossbeam-deque",
"globset",
"log",
"memchr",
"regex-automata 0.4.3",
"same-file",
"walkdir",
"winapi-util",
]
[[package]]
name = "indexmap"
version = "1.9.3"
@ -702,6 +741,7 @@ dependencies = [
"async-lsp",
"codespan-reporting",
"ide",
"ignore",
"log",
"lsp-types",
"macro_rules_attribute",

View File

@ -11,6 +11,7 @@ argh = "0.1.10"
async-lsp = { version = "0.2.0", features = ["tokio"] }
codespan-reporting = "0.11.1"
ide = { path = "../ide" }
ignore = "0.4.22"
log = "0.4.17"
lsp-types = "0.95.0"
macro_rules_attribute = "0.2.0"

View File

@ -1,4 +1,3 @@
use anyhow::anyhow;
use anyhow::{Context, Result};
use argh::FromArgs;
use codespan_reporting::diagnostic::Severity;
@ -9,6 +8,8 @@ use ide::FileId;
use ide::FileSet;
use ide::SourceRoot;
use ide::VfsPath;
use ignore::types::TypesBuilder;
use ignore::WalkBuilder;
use std::io::IsTerminal;
use std::path::{Path, PathBuf};
use std::sync::Arc;
@ -83,6 +84,8 @@ fn main() {
return;
}
setup_logger();
if let Some(subcommand) = args.subcommand {
return match subcommand {
Subcommand::Diagnostics(args) => main_diagnostics(args),
@ -91,8 +94,6 @@ fn main() {
};
}
setup_logger();
if !args.stdio && (io::stdin().is_terminal() || io::stdout().is_terminal()) {
// TODO: Make this a hard error.
eprintln!(
@ -136,29 +137,56 @@ fn main_diagnostics(args: DiagnosticsArgs) {
}
}
fn diagnostics_for_files(paths: Vec<PathBuf>) -> Result<Option<ide::Severity>> {
fn diagnostics_for_files(mut roots: Vec<PathBuf>) -> Result<Option<ide::Severity>> {
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
if paths.is_empty() {
return Err(anyhow!("No files given"));
let mut walk = if roots.is_empty() {
WalkBuilder::new(".")
} else {
WalkBuilder::new(roots.pop().expect("non_empty vec has an item"))
};
walk.types({
let mut builder = TypesBuilder::new();
builder
.add("nix", "*.nix")
.expect("parsing glob '*.nix' will never fail");
builder.select("nix");
builder.build().expect("building types will never fail")
});
for root in roots {
walk.add(root);
}
let walk = walk.build();
let mut sources = Vec::new();
let mut file_set = FileSet::default();
let mut change = Change::default();
for (id, path) in paths.iter().enumerate() {
let file = FileId(id as u32);
let src = if path.as_os_str() == "-" {
io::read_to_string(io::stdin().lock()).context("Failed to read from stdin")?
} else {
fs::read_to_string(path).context("Failed to read file")?
for (id, entry) in walk.enumerate() {
let entry = match entry {
Ok(entry) => entry,
Err(err) => {
tracing::error!("{err}");
continue;
}
};
let src: Arc<str> = src.into();
sources.push((file, path, src.clone()));
let file = FileId(id as u32);
let src = if entry.is_stdin() {
io::read_to_string(io::stdin().lock()).context("Failed to read from stdin")?
} else {
if entry.path().is_dir() {
continue;
}
fs::read_to_string(entry.path()).context("Failed to read file")?
};
change.change_file(file, src);
file_set.insert(file, VfsPath::new(path));
let path = entry.into_path();
let src: Arc<str> = src.into();
change.change_file(file, src.clone());
file_set.insert(file, VfsPath::new(&path));
sources.push((file, path, src));
}
change.set_roots(vec![SourceRoot::new_local(file_set, None)]);
@ -172,7 +200,7 @@ fn diagnostics_for_files(paths: Vec<PathBuf>) -> Result<Option<ide::Severity>> {
let mut max_severity = None;
for (id, path, src) in sources {
let diagnostics = snapshot.diagnostics(id).expect("No cancellation");
emit_diagnostics(path, &src, &mut writer, &mut diagnostics.iter().cloned())?;
emit_diagnostics(&path, &src, &mut writer, &mut diagnostics.iter().cloned())?;
max_severity = std::cmp::max(
max_severity,