-
Notifications
You must be signed in to change notification settings - Fork 114
Expand file tree
/
Copy pathprocess_file.rs
More file actions
125 lines (111 loc) · 3.68 KB
/
process_file.rs
File metadata and controls
125 lines (111 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
mod check;
pub(crate) mod workspace_file;
use crate::execute::TraversalMode;
use crate::execute::traverse::TraversalOptions;
use check::check_file;
use pglt_diagnostics::Error;
use pglt_fs::PgLTPath;
use std::marker::PhantomData;
use std::ops::Deref;
#[derive(Debug)]
pub(crate) enum FileStatus {
/// File changed and it was a success
Changed,
/// File unchanged, and it was a success
Unchanged,
/// While handling the file, something happened
Message(Message),
/// A match was found while searching a file
SearchResult(usize, Message),
/// File ignored, it should not be count as "handled"
Ignored,
/// Files that belong to other tools and shouldn't be touched
Protected(String),
}
impl FileStatus {
pub const fn is_changed(&self) -> bool {
matches!(self, Self::Changed)
}
}
/// Wrapper type for messages that can be printed during the traversal process
#[derive(Debug)]
pub(crate) enum Message {
SkippedFixes {
/// Suggested fixes skipped during the lint traversal
skipped_suggested_fixes: u32,
},
Failure,
Error(Error),
Diagnostics {
name: String,
content: String,
diagnostics: Vec<Error>,
skipped_diagnostics: u32,
},
}
impl Message {
pub(crate) const fn is_failure(&self) -> bool {
matches!(self, Message::Failure)
}
}
#[derive(Debug)]
pub(crate) enum DiffKind {
Format,
OrganizeImports,
Assists,
}
impl<D> From<D> for Message
where
Error: From<D>,
D: std::fmt::Debug,
{
fn from(err: D) -> Self {
Self::Error(Error::from(err))
}
}
/// The return type for [process_file], with the following semantics:
/// - `Ok(Success)` means the operation was successful (the file is added to
/// the `processed` counter)
/// - `Ok(Message(_))` means the operation was successful but a message still
/// needs to be printed (eg. the diff when not in CI or write mode)
/// - `Ok(Ignored)` means the file was ignored (the file is not added to the
/// `processed` or `skipped` counters)
/// - `Err(_)` means the operation failed and the file should be added to the
/// `skipped` counter
pub(crate) type FileResult = Result<FileStatus, Message>;
/// Data structure that allows to pass [TraversalOptions] to multiple consumers, bypassing the
/// compiler constraints set by the lifetimes of the [TraversalOptions]
pub(crate) struct SharedTraversalOptions<'ctx, 'app> {
inner: &'app TraversalOptions<'ctx, 'app>,
_p: PhantomData<&'app ()>,
}
impl<'ctx, 'app> SharedTraversalOptions<'ctx, 'app> {
fn new(t: &'app TraversalOptions<'ctx, 'app>) -> Self {
Self {
_p: PhantomData,
inner: t,
}
}
}
impl<'ctx, 'app> Deref for SharedTraversalOptions<'ctx, 'app> {
type Target = TraversalOptions<'ctx, 'app>;
fn deref(&self) -> &Self::Target {
self.inner
}
}
/// This function performs the actual processing: it reads the file from disk
/// and parse it; analyze and / or format it; then it either fails if error
/// diagnostics were emitted, or compare the formatted code with the original
/// content of the file and emit a diff or write the new content to the disk if
/// write mode is enabled
pub(crate) fn process_file(ctx: &TraversalOptions, pglt_path: &PgLTPath) -> FileResult {
tracing::trace_span!("process_file", path = ?pglt_path).in_scope(move || {
let shared_context = &SharedTraversalOptions::new(ctx);
match ctx.execution.traversal_mode {
TraversalMode::Dummy => {
unreachable!("The dummy mode should not be called for this file")
}
TraversalMode::Check { .. } => check_file(shared_context, pglt_path),
}
})
}