diff options
Diffstat (limited to 'bin')
-rw-r--r-- | bin/src/lint.rs | 36 | ||||
-rw-r--r-- | bin/src/main.rs | 43 | ||||
-rw-r--r-- | bin/src/traits.rs | 18 |
3 files changed, 49 insertions, 48 deletions
diff --git a/bin/src/lint.rs b/bin/src/lint.rs new file mode 100644 index 0000000..76b2b8c --- /dev/null +++ b/bin/src/lint.rs | |||
@@ -0,0 +1,36 @@ | |||
1 | use crate::err::LintErr; | ||
2 | |||
3 | use lib::{LINTS, Report}; | ||
4 | use rnix::WalkEvent; | ||
5 | use vfs::{VfsEntry, FileId}; | ||
6 | |||
7 | #[derive(Debug)] | ||
8 | pub struct LintResult { | ||
9 | pub file_id: FileId, | ||
10 | pub reports: Vec<Report>, | ||
11 | } | ||
12 | |||
13 | pub fn lint(vfs_entry: VfsEntry) -> Result<LintResult, LintErr> { | ||
14 | let source = vfs_entry.contents; | ||
15 | let parsed = rnix::parse(source) | ||
16 | .as_result() | ||
17 | .map_err(|e| LintErr::Parse(vfs_entry.file_path.to_path_buf(), e))?; | ||
18 | let reports = parsed | ||
19 | .node() | ||
20 | .preorder_with_tokens() | ||
21 | .filter_map(|event| match event { | ||
22 | WalkEvent::Enter(child) => LINTS.get(&child.kind()).map(|rules| { | ||
23 | rules | ||
24 | .iter() | ||
25 | .filter_map(|rule| rule.validate(&child)) | ||
26 | .collect::<Vec<_>>() | ||
27 | }), | ||
28 | _ => None, | ||
29 | }) | ||
30 | .flatten() | ||
31 | .collect(); | ||
32 | Ok(LintResult { | ||
33 | file_id: vfs_entry.file_id, | ||
34 | reports, | ||
35 | }) | ||
36 | } | ||
diff --git a/bin/src/main.rs b/bin/src/main.rs index b26151d..a3f04d7 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs | |||
@@ -1,57 +1,26 @@ | |||
1 | #![feature(path_try_exists)] | ||
2 | |||
3 | mod config; | 1 | mod config; |
4 | mod err; | 2 | mod err; |
3 | mod lint; | ||
5 | mod traits; | 4 | mod traits; |
6 | 5 | ||
7 | use std::io; | 6 | use std::io; |
8 | 7 | ||
9 | use crate::{ | 8 | use crate::{err::StatixErr, traits::WriteDiagnostic}; |
10 | err::{LintErr, StatixErr}, | ||
11 | traits::{LintResult, WriteDiagnostic}, | ||
12 | }; | ||
13 | 9 | ||
14 | use clap::Clap; | 10 | use clap::Clap; |
15 | use config::{LintConfig, Opts, SubCommand}; | 11 | use config::{LintConfig, Opts, SubCommand}; |
16 | use lib::LINTS; | ||
17 | use rnix::WalkEvent; | ||
18 | use vfs::VfsEntry; | ||
19 | |||
20 | fn analyze<'ρ>(vfs_entry: VfsEntry<'ρ>) -> Result<LintResult, LintErr> { | ||
21 | let source = vfs_entry.contents; | ||
22 | let parsed = rnix::parse(source) | ||
23 | .as_result() | ||
24 | .map_err(|e| LintErr::Parse(vfs_entry.file_path.to_path_buf(), e))?; | ||
25 | let reports = parsed | ||
26 | .node() | ||
27 | .preorder_with_tokens() | ||
28 | .filter_map(|event| match event { | ||
29 | WalkEvent::Enter(child) => LINTS.get(&child.kind()).map(|rules| { | ||
30 | rules | ||
31 | .iter() | ||
32 | .filter_map(|rule| rule.validate(&child)) | ||
33 | .collect::<Vec<_>>() | ||
34 | }), | ||
35 | _ => None, | ||
36 | }) | ||
37 | .flatten() | ||
38 | .collect(); | ||
39 | Ok(LintResult { | ||
40 | file_id: vfs_entry.file_id, | ||
41 | reports, | ||
42 | }) | ||
43 | } | ||
44 | 12 | ||
45 | fn _main() -> Result<(), StatixErr> { | 13 | fn _main() -> Result<(), StatixErr> { |
46 | // TODO: accept cli args, construct a CLI config with a list of files to analyze | ||
47 | let opts = Opts::parse(); | 14 | let opts = Opts::parse(); |
48 | match opts.subcmd { | 15 | match opts.subcmd { |
49 | Some(SubCommand::Fix(_)) => {} | 16 | Some(SubCommand::Fix(_)) => { |
17 | eprintln!("`fix` not yet supported"); | ||
18 | } | ||
50 | None => { | 19 | None => { |
51 | let lint_config = LintConfig::from_opts(opts)?; | 20 | let lint_config = LintConfig::from_opts(opts)?; |
52 | let vfs = lint_config.vfs()?; | 21 | let vfs = lint_config.vfs()?; |
53 | let (reports, errors): (Vec<_>, Vec<_>) = | 22 | let (reports, errors): (Vec<_>, Vec<_>) = |
54 | vfs.iter().map(analyze).partition(Result::is_ok); | 23 | vfs.iter().map(lint::lint).partition(Result::is_ok); |
55 | let lint_results: Vec<_> = reports.into_iter().map(Result::unwrap).collect(); | 24 | let lint_results: Vec<_> = reports.into_iter().map(Result::unwrap).collect(); |
56 | let errors: Vec<_> = errors.into_iter().map(Result::unwrap_err).collect(); | 25 | let errors: Vec<_> = errors.into_iter().map(Result::unwrap_err).collect(); |
57 | 26 | ||
diff --git a/bin/src/traits.rs b/bin/src/traits.rs index 1807ad0..c3427df 100644 --- a/bin/src/traits.rs +++ b/bin/src/traits.rs | |||
@@ -3,19 +3,14 @@ use std::{ | |||
3 | str, | 3 | str, |
4 | }; | 4 | }; |
5 | 5 | ||
6 | use crate::lint::LintResult; | ||
7 | |||
6 | use ariadne::{ | 8 | use ariadne::{ |
7 | CharSet, Color, Config as CliConfig, Label, LabelAttach, Report as CliReport, | 9 | CharSet, Color, Config as CliConfig, Fmt, Label, LabelAttach, Report as CliReport, |
8 | ReportKind as CliReportKind, Source, Fmt | 10 | ReportKind as CliReportKind, Source, |
9 | }; | 11 | }; |
10 | use lib::Report; | ||
11 | use rnix::TextRange; | 12 | use rnix::TextRange; |
12 | use vfs::{FileId, ReadOnlyVfs}; | 13 | use vfs::ReadOnlyVfs; |
13 | |||
14 | #[derive(Debug)] | ||
15 | pub struct LintResult { | ||
16 | pub file_id: FileId, | ||
17 | pub reports: Vec<Report>, | ||
18 | } | ||
19 | 14 | ||
20 | pub trait WriteDiagnostic { | 15 | pub trait WriteDiagnostic { |
21 | fn write(&mut self, report: &LintResult, vfs: &ReadOnlyVfs) -> io::Result<()>; | 16 | fn write(&mut self, report: &LintResult, vfs: &ReadOnlyVfs) -> io::Result<()>; |
@@ -69,7 +64,8 @@ where | |||
69 | 64 | ||
70 | // everything within backticks is colorized, backticks are removed | 65 | // everything within backticks is colorized, backticks are removed |
71 | fn colorize(message: &str) -> String { | 66 | fn colorize(message: &str) -> String { |
72 | message.split('`') | 67 | message |
68 | .split('`') | ||
73 | .enumerate() | 69 | .enumerate() |
74 | .map(|(idx, part)| { | 70 | .map(|(idx, part)| { |
75 | if idx % 2 == 1 { | 71 | if idx % 2 == 1 { |