diff options
author | Aleksey Kladov <[email protected]> | 2021-03-02 12:01:48 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-03-02 12:08:20 +0000 |
commit | 3038579c8ed446b296ff8afbe51ffcfa9c1869a2 (patch) | |
tree | 0944b063e9ea128a111027d83bc0411004af9fe4 | |
parent | 61c73caa307a4972e8cc42a607d6974388d44d59 (diff) |
Switch from pico-args to xflags
-rw-r--r-- | Cargo.lock | 16 | ||||
-rw-r--r-- | crates/rust-analyzer/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/bin/args.rs | 274 | ||||
-rw-r--r-- | crates/rust-analyzer/src/bin/flags.rs | 251 | ||||
-rw-r--r-- | crates/rust-analyzer/src/bin/main.rs | 85 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli/analysis_bench.rs | 1 |
6 files changed, 317 insertions, 312 deletions
diff --git a/Cargo.lock b/Cargo.lock index b6f75aad0..625c61883 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -1115,12 +1115,6 @@ dependencies = [ | |||
1115 | ] | 1115 | ] |
1116 | 1116 | ||
1117 | [[package]] | 1117 | [[package]] |
1118 | name = "pico-args" | ||
1119 | version = "0.4.0" | ||
1120 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1121 | checksum = "d70072c20945e1ab871c472a285fc772aefd4f5407723c206242f2c6f94595d6" | ||
1122 | |||
1123 | [[package]] | ||
1124 | name = "pin-project-lite" | 1118 | name = "pin-project-lite" |
1125 | version = "0.2.4" | 1119 | version = "0.2.4" |
1126 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1120 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1339,7 +1333,6 @@ dependencies = [ | |||
1339 | "mimalloc", | 1333 | "mimalloc", |
1340 | "oorandom", | 1334 | "oorandom", |
1341 | "parking_lot", | 1335 | "parking_lot", |
1342 | "pico-args", | ||
1343 | "proc_macro_srv", | 1336 | "proc_macro_srv", |
1344 | "profile", | 1337 | "profile", |
1345 | "project_model", | 1338 | "project_model", |
@@ -1361,6 +1354,7 @@ dependencies = [ | |||
1361 | "vfs", | 1354 | "vfs", |
1362 | "vfs-notify", | 1355 | "vfs-notify", |
1363 | "winapi", | 1356 | "winapi", |
1357 | "xflags", | ||
1364 | ] | 1358 | ] |
1365 | 1359 | ||
1366 | [[package]] | 1360 | [[package]] |
@@ -1914,18 +1908,18 @@ checksum = "06069a848f95fceae3e5e03c0ddc8cb78452b56654ee0c8e68f938cf790fb9e3" | |||
1914 | 1908 | ||
1915 | [[package]] | 1909 | [[package]] |
1916 | name = "xflags" | 1910 | name = "xflags" |
1917 | version = "0.1.2" | 1911 | version = "0.1.3" |
1918 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1912 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1919 | checksum = "1a6292b9528efc06cb25a41b8a0814dd3a9590c0fe2cd95341fe41bbe034fafb" | 1913 | checksum = "ddb4b07c0db813f8e2b5e1b2189ef56fcddb27a6f9ef71314dbf8cc50096a5db" |
1920 | dependencies = [ | 1914 | dependencies = [ |
1921 | "xflags-macros", | 1915 | "xflags-macros", |
1922 | ] | 1916 | ] |
1923 | 1917 | ||
1924 | [[package]] | 1918 | [[package]] |
1925 | name = "xflags-macros" | 1919 | name = "xflags-macros" |
1926 | version = "0.1.2" | 1920 | version = "0.1.3" |
1927 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1921 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1928 | checksum = "ba2108d40e49a0653f2ee4eda59f51447e0cab5cc2cc197a5abd96525c6bd89e" | 1922 | checksum = "f8e168a99d6ce9d5dd0d0913f1bded279377843952dd8ff83f81b862a1dad0e1" |
1929 | dependencies = [ | 1923 | dependencies = [ |
1930 | "proc-macro2", | 1924 | "proc-macro2", |
1931 | ] | 1925 | ] |
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index b881cc229..8789f0852 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml | |||
@@ -24,7 +24,7 @@ jod-thread = "0.1.0" | |||
24 | log = "0.4.8" | 24 | log = "0.4.8" |
25 | lsp-types = { version = "0.88.0", features = ["proposed"] } | 25 | lsp-types = { version = "0.88.0", features = ["proposed"] } |
26 | parking_lot = "0.11.0" | 26 | parking_lot = "0.11.0" |
27 | pico-args = "0.4.0" | 27 | xflags = "0.1.2" |
28 | oorandom = "11.1.2" | 28 | oorandom = "11.1.2" |
29 | rustc-hash = "1.1.0" | 29 | rustc-hash = "1.1.0" |
30 | serde = { version = "1.0.106", features = ["derive"] } | 30 | serde = { version = "1.0.106", features = ["derive"] } |
diff --git a/crates/rust-analyzer/src/bin/args.rs b/crates/rust-analyzer/src/bin/args.rs deleted file mode 100644 index 164d94a30..000000000 --- a/crates/rust-analyzer/src/bin/args.rs +++ /dev/null | |||
@@ -1,274 +0,0 @@ | |||
1 | //! Command like parsing for rust-analyzer. | ||
2 | //! | ||
3 | //! If run started args, we run the LSP server loop. With a subcommand, we do a | ||
4 | //! one-time batch processing. | ||
5 | |||
6 | use std::{env, path::PathBuf}; | ||
7 | |||
8 | use anyhow::{bail, format_err, Result}; | ||
9 | use ide_ssr::{SsrPattern, SsrRule}; | ||
10 | use pico_args::Arguments; | ||
11 | use rust_analyzer::cli::{AnalysisStatsCmd, BenchCmd, BenchWhat, Position, Verbosity}; | ||
12 | use vfs::AbsPathBuf; | ||
13 | |||
14 | pub(crate) struct Args { | ||
15 | pub(crate) verbosity: Verbosity, | ||
16 | pub(crate) log_file: Option<PathBuf>, | ||
17 | pub(crate) no_buffering: bool, | ||
18 | pub(crate) command: Command, | ||
19 | #[allow(unused)] | ||
20 | pub(crate) wait_dbg: bool, | ||
21 | } | ||
22 | |||
23 | pub(crate) enum Command { | ||
24 | Parse { no_dump: bool }, | ||
25 | Symbols, | ||
26 | Highlight { rainbow: bool }, | ||
27 | AnalysisStats(AnalysisStatsCmd), | ||
28 | Bench(BenchCmd), | ||
29 | Diagnostics { path: PathBuf, load_output_dirs: bool, with_proc_macro: bool }, | ||
30 | Ssr { rules: Vec<SsrRule> }, | ||
31 | StructuredSearch { debug_snippet: Option<String>, patterns: Vec<SsrPattern> }, | ||
32 | ProcMacro, | ||
33 | RunServer, | ||
34 | PrintConfigSchema, | ||
35 | Version, | ||
36 | Help, | ||
37 | } | ||
38 | |||
39 | const HELP: &str = "\ | ||
40 | rust-analyzer | ||
41 | |||
42 | USAGE: | ||
43 | rust-analyzer [FLAGS] [COMMAND] [COMMAND_OPTIONS] | ||
44 | |||
45 | FLAGS: | ||
46 | --version Print version | ||
47 | -h, --help Print this help | ||
48 | |||
49 | -v, --verbose | ||
50 | -vv, --spammy | ||
51 | -q, --quiet Set verbosity | ||
52 | |||
53 | --print-config-schema | ||
54 | Dump a LSP config JSON schema | ||
55 | --log-file <PATH> Log to the specified file instead of stderr | ||
56 | --no-log-buffering | ||
57 | Flush log records to the file immediately | ||
58 | |||
59 | --wait-dbg Wait until a debugger is attached to. | ||
60 | The flag is valid for debug builds only | ||
61 | |||
62 | ENVIRONMENTAL VARIABLES: | ||
63 | RA_LOG Set log filter in env_logger format | ||
64 | RA_PROFILE Enable hierarchical profiler | ||
65 | RA_WAIT_DBG If set acts like a --wait-dbg flag | ||
66 | |||
67 | COMMANDS: | ||
68 | |||
69 | not specified Launch LSP server | ||
70 | |||
71 | parse < main.rs Parse tree | ||
72 | --no-dump Suppress printing | ||
73 | |||
74 | symbols < main.rs Parse input an print the list of symbols | ||
75 | |||
76 | highlight < main.rs Highlight input as html | ||
77 | --rainbow Enable rainbow highlighting of identifiers | ||
78 | |||
79 | analysis-stats <PATH> Batch typecheck project and print summary statistics | ||
80 | <PATH> Directory with Cargo.toml | ||
81 | --randomize Randomize order in which crates, modules, and items are processed | ||
82 | --parallel Run type inference in parallel | ||
83 | --memory-usage Collect memory usage statistics | ||
84 | -o, --only <PATH> Only analyze items matching this path | ||
85 | --with-deps Also analyze all dependencies | ||
86 | --load-output-dirs | ||
87 | Load OUT_DIR values by running `cargo check` before analysis | ||
88 | --with-proc-macro Use proc-macro-srv for proc-macro expanding | ||
89 | |||
90 | analysis-bench <PATH> Benchmark specific analysis operation | ||
91 | <PATH> Directory with Cargo.toml | ||
92 | --highlight <PATH> | ||
93 | Compute syntax highlighting for this file | ||
94 | --complete <PATH:LINE:COLUMN> | ||
95 | Compute completions at this location | ||
96 | --goto-def <PATH:LINE:COLUMN> | ||
97 | Compute goto definition at this location | ||
98 | --memory-usage Collect memory usage statistics | ||
99 | --load-output-dirs | ||
100 | Load OUT_DIR values by running `cargo check` before analysis | ||
101 | --with-proc-macro Use proc-macro-srv for proc-macro expanding | ||
102 | |||
103 | diagnostics <PATH> | ||
104 | <PATH> Directory with Cargo.toml | ||
105 | --load-output-dirs | ||
106 | Load OUT_DIR values by running `cargo check` before analysis | ||
107 | --with-proc-macro Use proc-macro-srv for proc-macro expanding | ||
108 | |||
109 | ssr [RULE...] | ||
110 | <RULE> A structured search replace rule (`$a.foo($b) ==> bar($a, $b)`) | ||
111 | |||
112 | search [PATTERN..] | ||
113 | <PATTERN> A structured search replace pattern (`$a.foo($b)`) | ||
114 | --debug <snippet> Prints debug information for any nodes with source exactly | ||
115 | equal to <snippet> | ||
116 | "; | ||
117 | |||
118 | impl Args { | ||
119 | pub(crate) fn parse() -> Result<Args> { | ||
120 | let mut matches = Arguments::from_env(); | ||
121 | |||
122 | if matches.contains("--version") { | ||
123 | finish_args(matches)?; | ||
124 | return Ok(Args { | ||
125 | verbosity: Verbosity::Normal, | ||
126 | log_file: None, | ||
127 | command: Command::Version, | ||
128 | no_buffering: false, | ||
129 | wait_dbg: false, | ||
130 | }); | ||
131 | } | ||
132 | |||
133 | let verbosity = match ( | ||
134 | matches.contains(["-vv", "--spammy"]), | ||
135 | matches.contains(["-v", "--verbose"]), | ||
136 | matches.contains(["-q", "--quiet"]), | ||
137 | ) { | ||
138 | (true, _, true) => bail!("Invalid flags: -q conflicts with -vv"), | ||
139 | (true, _, false) => Verbosity::Spammy, | ||
140 | (false, false, false) => Verbosity::Normal, | ||
141 | (false, false, true) => Verbosity::Quiet, | ||
142 | (false, true, false) => Verbosity::Verbose, | ||
143 | (false, true, true) => bail!("Invalid flags: -q conflicts with -v"), | ||
144 | }; | ||
145 | let log_file = matches.opt_value_from_str("--log-file")?; | ||
146 | let no_buffering = matches.contains("--no-log-buffering"); | ||
147 | let wait_dbg = matches.contains("--wait-dbg"); | ||
148 | |||
149 | if matches.contains(["-h", "--help"]) { | ||
150 | eprintln!("{}", HELP); | ||
151 | return Ok(Args { | ||
152 | verbosity, | ||
153 | log_file: None, | ||
154 | command: Command::Help, | ||
155 | no_buffering, | ||
156 | wait_dbg, | ||
157 | }); | ||
158 | } | ||
159 | |||
160 | if matches.contains("--print-config-schema") { | ||
161 | return Ok(Args { | ||
162 | verbosity, | ||
163 | log_file, | ||
164 | command: Command::PrintConfigSchema, | ||
165 | no_buffering, | ||
166 | wait_dbg, | ||
167 | }); | ||
168 | } | ||
169 | |||
170 | let subcommand = match matches.subcommand()? { | ||
171 | Some(it) => it, | ||
172 | None => { | ||
173 | finish_args(matches)?; | ||
174 | return Ok(Args { | ||
175 | verbosity, | ||
176 | log_file, | ||
177 | command: Command::RunServer, | ||
178 | no_buffering, | ||
179 | wait_dbg, | ||
180 | }); | ||
181 | } | ||
182 | }; | ||
183 | let command = match subcommand.as_str() { | ||
184 | "parse" => Command::Parse { no_dump: matches.contains("--no-dump") }, | ||
185 | "symbols" => Command::Symbols, | ||
186 | "highlight" => Command::Highlight { rainbow: matches.contains("--rainbow") }, | ||
187 | "analysis-stats" => Command::AnalysisStats(AnalysisStatsCmd { | ||
188 | randomize: matches.contains("--randomize"), | ||
189 | parallel: matches.contains("--parallel"), | ||
190 | memory_usage: matches.contains("--memory-usage"), | ||
191 | only: matches.opt_value_from_str(["-o", "--only"])?, | ||
192 | with_deps: matches.contains("--with-deps"), | ||
193 | load_output_dirs: matches.contains("--load-output-dirs"), | ||
194 | with_proc_macro: matches.contains("--with-proc-macro"), | ||
195 | path: matches | ||
196 | .opt_free_from_str()? | ||
197 | .ok_or_else(|| format_err!("expected positional argument"))?, | ||
198 | }), | ||
199 | "analysis-bench" => Command::Bench(BenchCmd { | ||
200 | what: { | ||
201 | let highlight_path: Option<String> = | ||
202 | matches.opt_value_from_str("--highlight")?; | ||
203 | let complete_path: Option<Position> = | ||
204 | matches.opt_value_from_str("--complete")?; | ||
205 | let goto_def_path: Option<Position> = | ||
206 | matches.opt_value_from_str("--goto-def")?; | ||
207 | match (highlight_path, complete_path, goto_def_path) { | ||
208 | (Some(path), None, None) => { | ||
209 | let path = env::current_dir().unwrap().join(path); | ||
210 | BenchWhat::Highlight { path: AbsPathBuf::assert(path) } | ||
211 | } | ||
212 | (None, Some(position), None) => BenchWhat::Complete(position), | ||
213 | (None, None, Some(position)) => BenchWhat::GotoDef(position), | ||
214 | _ => panic!( | ||
215 | "exactly one of `--highlight`, `--complete` or `--goto-def` must be set" | ||
216 | ), | ||
217 | } | ||
218 | }, | ||
219 | memory_usage: matches.contains("--memory-usage"), | ||
220 | load_output_dirs: matches.contains("--load-output-dirs"), | ||
221 | with_proc_macro: matches.contains("--with-proc-macro"), | ||
222 | path: matches | ||
223 | .opt_free_from_str()? | ||
224 | .ok_or_else(|| format_err!("expected positional argument"))?, | ||
225 | }), | ||
226 | "diagnostics" => Command::Diagnostics { | ||
227 | load_output_dirs: matches.contains("--load-output-dirs"), | ||
228 | with_proc_macro: matches.contains("--with-proc-macro"), | ||
229 | path: matches | ||
230 | .opt_free_from_str()? | ||
231 | .ok_or_else(|| format_err!("expected positional argument"))?, | ||
232 | }, | ||
233 | "proc-macro" => Command::ProcMacro, | ||
234 | "ssr" => Command::Ssr { | ||
235 | rules: { | ||
236 | let mut acc = Vec::new(); | ||
237 | while let Some(rule) = matches.opt_free_from_str()? { | ||
238 | acc.push(rule); | ||
239 | } | ||
240 | acc | ||
241 | }, | ||
242 | }, | ||
243 | "search" => Command::StructuredSearch { | ||
244 | debug_snippet: matches.opt_value_from_str("--debug")?, | ||
245 | patterns: { | ||
246 | let mut acc = Vec::new(); | ||
247 | while let Some(rule) = matches.opt_free_from_str()? { | ||
248 | acc.push(rule); | ||
249 | } | ||
250 | acc | ||
251 | }, | ||
252 | }, | ||
253 | _ => { | ||
254 | eprintln!("{}", HELP); | ||
255 | return Ok(Args { | ||
256 | verbosity, | ||
257 | log_file: None, | ||
258 | command: Command::Help, | ||
259 | no_buffering, | ||
260 | wait_dbg, | ||
261 | }); | ||
262 | } | ||
263 | }; | ||
264 | finish_args(matches)?; | ||
265 | Ok(Args { verbosity, log_file, command, no_buffering, wait_dbg }) | ||
266 | } | ||
267 | } | ||
268 | |||
269 | fn finish_args(args: Arguments) -> Result<()> { | ||
270 | if !args.finish().is_empty() { | ||
271 | bail!("Unused arguments."); | ||
272 | } | ||
273 | Ok(()) | ||
274 | } | ||
diff --git a/crates/rust-analyzer/src/bin/flags.rs b/crates/rust-analyzer/src/bin/flags.rs new file mode 100644 index 000000000..244912d26 --- /dev/null +++ b/crates/rust-analyzer/src/bin/flags.rs | |||
@@ -0,0 +1,251 @@ | |||
1 | //! Grammar for the command-line arguments. | ||
2 | #![allow(unreachable_pub)] | ||
3 | use std::{env, path::PathBuf}; | ||
4 | |||
5 | use ide_ssr::{SsrPattern, SsrRule}; | ||
6 | use rust_analyzer::cli::{BenchWhat, Position, Verbosity}; | ||
7 | use vfs::AbsPathBuf; | ||
8 | |||
9 | xflags::args_parser! { | ||
10 | /// LSP server for the Rust programming language. | ||
11 | cmd rust-analyzer { | ||
12 | /// Verbosity level, can be repeated multiple times. | ||
13 | repeated -v, --verbose | ||
14 | /// Verbosity level. | ||
15 | optional -q, --quiet | ||
16 | |||
17 | /// Log to the specified file instead of stderr. | ||
18 | optional --log-file path: PathBuf | ||
19 | /// Flush log records to the file immediately. | ||
20 | optional --no-log-buffering | ||
21 | |||
22 | /// Wait until a debugger is attached to (requires debug build). | ||
23 | optional --wait-dbg | ||
24 | |||
25 | default cmd lsp-server { | ||
26 | /// Print version. | ||
27 | optional --version | ||
28 | /// Print help. | ||
29 | optional -h, --help | ||
30 | |||
31 | /// Dump a LSP config JSON schema. | ||
32 | optional --print-config-schema | ||
33 | } | ||
34 | |||
35 | /// Parse stdin. | ||
36 | cmd parse { | ||
37 | /// Suppress printing. | ||
38 | optional --no-dump | ||
39 | } | ||
40 | |||
41 | /// Parse stdin and print the list of symbols. | ||
42 | cmd symbols {} | ||
43 | |||
44 | /// Highlight stdin as html. | ||
45 | cmd highlight { | ||
46 | /// Enable rainbow highlighting of identifiers. | ||
47 | optional --rainbow | ||
48 | } | ||
49 | |||
50 | /// Batch typecheck project and print summary statistics | ||
51 | cmd analysis-stats | ||
52 | /// Directory with Cargo.toml. | ||
53 | required path: PathBuf | ||
54 | { | ||
55 | /// Randomize order in which crates, modules, and items are processed. | ||
56 | optional --randomize | ||
57 | /// Run type inference in parallel. | ||
58 | optional --parallel | ||
59 | /// Collect memory usage statistics. | ||
60 | optional --memory-usage | ||
61 | |||
62 | /// Only analyze items matching this path. | ||
63 | optional -o, --only path: String | ||
64 | /// Also analyze all dependencies. | ||
65 | optional --with-deps | ||
66 | |||
67 | /// Load OUT_DIR values by running `cargo check` before analysis. | ||
68 | optional --load-output-dirs | ||
69 | /// Use proc-macro-srv for proc-macro expanding. | ||
70 | optional --with-proc-macro | ||
71 | } | ||
72 | |||
73 | /// Benchmark specific analysis operation | ||
74 | cmd analysis-bench | ||
75 | /// Directory with Cargo.toml. | ||
76 | required path: PathBuf | ||
77 | { | ||
78 | /// Collect memory usage statistics. | ||
79 | optional --memory-usage | ||
80 | |||
81 | /// Compute syntax highlighting for this file | ||
82 | optional --highlight path: PathBuf | ||
83 | /// Compute completions at file:line:column location. | ||
84 | optional --complete location: Position | ||
85 | /// Compute goto definition at file:line:column location. | ||
86 | optional --goto-def location: Position | ||
87 | |||
88 | /// Load OUT_DIR values by running `cargo check` before analysis. | ||
89 | optional --load-output-dirs | ||
90 | /// Use proc-macro-srv for proc-macro expanding. | ||
91 | optional --with-proc-macro | ||
92 | } | ||
93 | |||
94 | cmd diagnostics | ||
95 | /// Directory with Cargo.toml. | ||
96 | required path: PathBuf | ||
97 | { | ||
98 | /// Load OUT_DIR values by running `cargo check` before analysis. | ||
99 | optional --load-output-dirs | ||
100 | /// Use proc-macro-srv for proc-macro expanding. | ||
101 | optional --with-proc-macro | ||
102 | } | ||
103 | |||
104 | cmd ssr | ||
105 | /// A structured search replace rule (`$a.foo($b) ==> bar($a, $b)`) | ||
106 | repeated rule: SsrRule | ||
107 | {} | ||
108 | |||
109 | cmd search | ||
110 | /// A structured search replace pattern (`$a.foo($b)`) | ||
111 | repeated pattern: SsrPattern | ||
112 | { | ||
113 | /// Prints debug information for any nodes with source exactly equal to snippet. | ||
114 | optional --debug snippet: String | ||
115 | } | ||
116 | |||
117 | cmd proc-macro {} | ||
118 | } | ||
119 | } | ||
120 | |||
121 | // generated start | ||
122 | // The following code is generated by `xflags` macro. | ||
123 | // Run `env XFLAGS_DUMP= cargo build` to regenerate. | ||
124 | #[derive(Debug)] | ||
125 | pub struct RustAnalyzer { | ||
126 | pub verbose: u32, | ||
127 | pub quiet: bool, | ||
128 | pub log_file: Option<PathBuf>, | ||
129 | pub no_log_buffering: bool, | ||
130 | pub wait_dbg: bool, | ||
131 | pub subcommand: RustAnalyzerCmd, | ||
132 | } | ||
133 | |||
134 | #[derive(Debug)] | ||
135 | pub enum RustAnalyzerCmd { | ||
136 | LspServer(LspServer), | ||
137 | Parse(Parse), | ||
138 | Symbols(Symbols), | ||
139 | Highlight(Highlight), | ||
140 | AnalysisStats(AnalysisStats), | ||
141 | AnalysisBench(AnalysisBench), | ||
142 | Diagnostics(Diagnostics), | ||
143 | Ssr(Ssr), | ||
144 | Search(Search), | ||
145 | ProcMacro(ProcMacro), | ||
146 | } | ||
147 | |||
148 | #[derive(Debug)] | ||
149 | pub struct LspServer { | ||
150 | pub version: bool, | ||
151 | pub help: bool, | ||
152 | pub print_config_schema: bool, | ||
153 | } | ||
154 | |||
155 | #[derive(Debug)] | ||
156 | pub struct Parse { | ||
157 | pub no_dump: bool, | ||
158 | } | ||
159 | |||
160 | #[derive(Debug)] | ||
161 | pub struct Symbols {} | ||
162 | |||
163 | #[derive(Debug)] | ||
164 | pub struct Highlight { | ||
165 | pub rainbow: bool, | ||
166 | } | ||
167 | |||
168 | #[derive(Debug)] | ||
169 | pub struct AnalysisStats { | ||
170 | pub path: PathBuf, | ||
171 | |||
172 | pub randomize: bool, | ||
173 | pub parallel: bool, | ||
174 | pub memory_usage: bool, | ||
175 | pub only: Option<String>, | ||
176 | pub with_deps: bool, | ||
177 | pub load_output_dirs: bool, | ||
178 | pub with_proc_macro: bool, | ||
179 | } | ||
180 | |||
181 | #[derive(Debug)] | ||
182 | pub struct AnalysisBench { | ||
183 | pub path: PathBuf, | ||
184 | |||
185 | pub memory_usage: bool, | ||
186 | pub highlight: Option<PathBuf>, | ||
187 | pub complete: Option<Position>, | ||
188 | pub goto_def: Option<Position>, | ||
189 | pub load_output_dirs: bool, | ||
190 | pub with_proc_macro: bool, | ||
191 | } | ||
192 | |||
193 | #[derive(Debug)] | ||
194 | pub struct Diagnostics { | ||
195 | pub path: PathBuf, | ||
196 | |||
197 | pub load_output_dirs: bool, | ||
198 | pub with_proc_macro: bool, | ||
199 | } | ||
200 | |||
201 | #[derive(Debug)] | ||
202 | pub struct Ssr { | ||
203 | pub rule: Vec<SsrRule>, | ||
204 | } | ||
205 | |||
206 | #[derive(Debug)] | ||
207 | pub struct Search { | ||
208 | pub pattern: Vec<SsrPattern>, | ||
209 | |||
210 | pub debug: Option<String>, | ||
211 | } | ||
212 | |||
213 | #[derive(Debug)] | ||
214 | pub struct ProcMacro {} | ||
215 | |||
216 | impl RustAnalyzer { | ||
217 | pub const HELP: &'static str = Self::_HELP; | ||
218 | |||
219 | pub fn from_env() -> xflags::Result<Self> { | ||
220 | let mut p = xflags::rt::Parser::new_from_env(); | ||
221 | Self::_parse(&mut p) | ||
222 | } | ||
223 | } | ||
224 | // generated end | ||
225 | |||
226 | impl RustAnalyzer { | ||
227 | pub(crate) fn verbosity(&self) -> Verbosity { | ||
228 | if self.quiet { | ||
229 | return Verbosity::Quiet; | ||
230 | } | ||
231 | match self.verbose { | ||
232 | 0 => Verbosity::Normal, | ||
233 | 1 => Verbosity::Verbose, | ||
234 | _ => Verbosity::Spammy, | ||
235 | } | ||
236 | } | ||
237 | } | ||
238 | |||
239 | impl AnalysisBench { | ||
240 | pub(crate) fn what(&self) -> BenchWhat { | ||
241 | match (&self.highlight, &self.complete, &self.goto_def) { | ||
242 | (Some(path), None, None) => { | ||
243 | let path = env::current_dir().unwrap().join(path); | ||
244 | BenchWhat::Highlight { path: AbsPathBuf::assert(path) } | ||
245 | } | ||
246 | (None, Some(position), None) => BenchWhat::Complete(position.clone()), | ||
247 | (None, None, Some(position)) => BenchWhat::GotoDef(position.clone()), | ||
248 | _ => panic!("exactly one of `--highlight`, `--complete` or `--goto-def` must be set"), | ||
249 | } | ||
250 | } | ||
251 | } | ||
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index 89482b952..288847980 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs | |||
@@ -1,14 +1,20 @@ | |||
1 | //! Driver for rust-analyzer. | 1 | //! Driver for rust-analyzer. |
2 | //! | 2 | //! |
3 | //! Based on cli flags, either spawns an LSP server, or runs a batch analysis | 3 | //! Based on cli flags, either spawns an LSP server, or runs a batch analysis |
4 | mod args; | 4 | mod flags; |
5 | mod logger; | 5 | mod logger; |
6 | 6 | ||
7 | use std::{convert::TryFrom, env, fs, path::PathBuf, process}; | 7 | use std::{convert::TryFrom, env, fs, path::Path, process}; |
8 | 8 | ||
9 | use lsp_server::Connection; | 9 | use lsp_server::Connection; |
10 | use project_model::ProjectManifest; | 10 | use project_model::ProjectManifest; |
11 | use rust_analyzer::{cli, config::Config, from_json, lsp_ext::supports_utf8, Result}; | 11 | use rust_analyzer::{ |
12 | cli::{self, AnalysisStatsCmd, BenchCmd}, | ||
13 | config::Config, | ||
14 | from_json, | ||
15 | lsp_ext::supports_utf8, | ||
16 | Result, | ||
17 | }; | ||
12 | use vfs::AbsPathBuf; | 18 | use vfs::AbsPathBuf; |
13 | 19 | ||
14 | #[cfg(all(feature = "mimalloc"))] | 20 | #[cfg(all(feature = "mimalloc"))] |
@@ -28,10 +34,10 @@ fn main() { | |||
28 | } | 34 | } |
29 | 35 | ||
30 | fn try_main() -> Result<()> { | 36 | fn try_main() -> Result<()> { |
31 | let args = args::Args::parse()?; | 37 | let flags = flags::RustAnalyzer::from_env()?; |
32 | 38 | ||
33 | #[cfg(debug_assertions)] | 39 | #[cfg(debug_assertions)] |
34 | if args.wait_dbg || env::var("RA_WAIT_DBG").is_ok() { | 40 | if flags.wait_dbg || env::var("RA_WAIT_DBG").is_ok() { |
35 | #[allow(unused_mut)] | 41 | #[allow(unused_mut)] |
36 | let mut d = 4; | 42 | let mut d = 4; |
37 | while d == 4 { | 43 | while d == 4 { |
@@ -39,35 +45,62 @@ fn try_main() -> Result<()> { | |||
39 | } | 45 | } |
40 | } | 46 | } |
41 | 47 | ||
42 | setup_logging(args.log_file, args.no_buffering)?; | 48 | setup_logging(flags.log_file.as_deref(), flags.no_log_buffering)?; |
43 | match args.command { | 49 | let verbosity = flags.verbosity(); |
44 | args::Command::RunServer => run_server()?, | 50 | |
45 | args::Command::PrintConfigSchema => { | 51 | match flags.subcommand { |
46 | println!("{:#}", Config::json_schema()); | 52 | flags::RustAnalyzerCmd::LspServer(cmd) => { |
53 | if cmd.print_config_schema { | ||
54 | println!("{:#}", Config::json_schema()); | ||
55 | return Ok(()); | ||
56 | } | ||
57 | if cmd.version { | ||
58 | println!("rust-analyzer {}", env!("REV")); | ||
59 | return Ok(()); | ||
60 | } | ||
61 | if cmd.help { | ||
62 | println!("{}", flags::RustAnalyzer::HELP); | ||
63 | return Ok(()); | ||
64 | } | ||
65 | run_server()? | ||
47 | } | 66 | } |
48 | args::Command::ProcMacro => proc_macro_srv::cli::run()?, | 67 | flags::RustAnalyzerCmd::ProcMacro(_) => proc_macro_srv::cli::run()?, |
49 | 68 | flags::RustAnalyzerCmd::Parse(cmd) => cli::parse(cmd.no_dump)?, | |
50 | args::Command::Parse { no_dump } => cli::parse(no_dump)?, | 69 | flags::RustAnalyzerCmd::Symbols(_) => cli::symbols()?, |
51 | args::Command::Symbols => cli::symbols()?, | 70 | flags::RustAnalyzerCmd::Highlight(cmd) => cli::highlight(cmd.rainbow)?, |
52 | args::Command::Highlight { rainbow } => cli::highlight(rainbow)?, | 71 | flags::RustAnalyzerCmd::AnalysisStats(cmd) => AnalysisStatsCmd { |
53 | args::Command::AnalysisStats(cmd) => cmd.run(args.verbosity)?, | 72 | randomize: cmd.randomize, |
54 | args::Command::Bench(cmd) => cmd.run(args.verbosity)?, | 73 | parallel: cmd.parallel, |
55 | args::Command::Diagnostics { path, load_output_dirs, with_proc_macro } => { | 74 | memory_usage: cmd.memory_usage, |
56 | cli::diagnostics(path.as_ref(), load_output_dirs, with_proc_macro)? | 75 | only: cmd.only, |
76 | with_deps: cmd.with_deps, | ||
77 | path: cmd.path, | ||
78 | load_output_dirs: cmd.load_output_dirs, | ||
79 | with_proc_macro: cmd.with_proc_macro, | ||
57 | } | 80 | } |
58 | args::Command::Ssr { rules } => { | 81 | .run(verbosity)?, |
59 | cli::apply_ssr_rules(rules)?; | 82 | flags::RustAnalyzerCmd::AnalysisBench(cmd) => { |
83 | let what = cmd.what(); | ||
84 | BenchCmd { | ||
85 | memory_usage: cmd.memory_usage, | ||
86 | path: cmd.path, | ||
87 | load_output_dirs: cmd.load_output_dirs, | ||
88 | with_proc_macro: cmd.with_proc_macro, | ||
89 | what, | ||
90 | } | ||
91 | .run(verbosity)? | ||
60 | } | 92 | } |
61 | args::Command::StructuredSearch { patterns, debug_snippet } => { | 93 | |
62 | cli::search_for_patterns(patterns, debug_snippet)?; | 94 | flags::RustAnalyzerCmd::Diagnostics(cmd) => { |
95 | cli::diagnostics(&cmd.path, cmd.load_output_dirs, cmd.with_proc_macro)? | ||
63 | } | 96 | } |
64 | args::Command::Version => println!("rust-analyzer {}", env!("REV")), | 97 | flags::RustAnalyzerCmd::Ssr(cmd) => cli::apply_ssr_rules(cmd.rule)?, |
65 | args::Command::Help => {} | 98 | flags::RustAnalyzerCmd::Search(cmd) => cli::search_for_patterns(cmd.pattern, cmd.debug)?, |
66 | } | 99 | } |
67 | Ok(()) | 100 | Ok(()) |
68 | } | 101 | } |
69 | 102 | ||
70 | fn setup_logging(log_file: Option<PathBuf>, no_buffering: bool) -> Result<()> { | 103 | fn setup_logging(log_file: Option<&Path>, no_buffering: bool) -> Result<()> { |
71 | env::set_var("RUST_BACKTRACE", "short"); | 104 | env::set_var("RUST_BACKTRACE", "short"); |
72 | 105 | ||
73 | let log_file = match log_file { | 106 | let log_file = match log_file { |
diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs index ebbbf0596..3bd7e678d 100644 --- a/crates/rust-analyzer/src/cli/analysis_bench.rs +++ b/crates/rust-analyzer/src/cli/analysis_bench.rs | |||
@@ -35,6 +35,7 @@ pub enum BenchWhat { | |||
35 | GotoDef(Position), | 35 | GotoDef(Position), |
36 | } | 36 | } |
37 | 37 | ||
38 | #[derive(Debug, Clone)] | ||
38 | pub struct Position { | 39 | pub struct Position { |
39 | pub path: AbsPathBuf, | 40 | pub path: AbsPathBuf, |
40 | pub line: u32, | 41 | pub line: u32, |