aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-03-02 12:01:48 +0000
committerAleksey Kladov <[email protected]>2021-03-02 12:08:20 +0000
commit3038579c8ed446b296ff8afbe51ffcfa9c1869a2 (patch)
tree0944b063e9ea128a111027d83bc0411004af9fe4
parent61c73caa307a4972e8cc42a607d6974388d44d59 (diff)
Switch from pico-args to xflags
-rw-r--r--Cargo.lock16
-rw-r--r--crates/rust-analyzer/Cargo.toml2
-rw-r--r--crates/rust-analyzer/src/bin/args.rs274
-rw-r--r--crates/rust-analyzer/src/bin/flags.rs251
-rw-r--r--crates/rust-analyzer/src/bin/main.rs85
-rw-r--r--crates/rust-analyzer/src/cli/analysis_bench.rs1
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]]
1118name = "pico-args"
1119version = "0.4.0"
1120source = "registry+https://github.com/rust-lang/crates.io-index"
1121checksum = "d70072c20945e1ab871c472a285fc772aefd4f5407723c206242f2c6f94595d6"
1122
1123[[package]]
1124name = "pin-project-lite" 1118name = "pin-project-lite"
1125version = "0.2.4" 1119version = "0.2.4"
1126source = "registry+https://github.com/rust-lang/crates.io-index" 1120source = "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]]
1916name = "xflags" 1910name = "xflags"
1917version = "0.1.2" 1911version = "0.1.3"
1918source = "registry+https://github.com/rust-lang/crates.io-index" 1912source = "registry+https://github.com/rust-lang/crates.io-index"
1919checksum = "1a6292b9528efc06cb25a41b8a0814dd3a9590c0fe2cd95341fe41bbe034fafb" 1913checksum = "ddb4b07c0db813f8e2b5e1b2189ef56fcddb27a6f9ef71314dbf8cc50096a5db"
1920dependencies = [ 1914dependencies = [
1921 "xflags-macros", 1915 "xflags-macros",
1922] 1916]
1923 1917
1924[[package]] 1918[[package]]
1925name = "xflags-macros" 1919name = "xflags-macros"
1926version = "0.1.2" 1920version = "0.1.3"
1927source = "registry+https://github.com/rust-lang/crates.io-index" 1921source = "registry+https://github.com/rust-lang/crates.io-index"
1928checksum = "ba2108d40e49a0653f2ee4eda59f51447e0cab5cc2cc197a5abd96525c6bd89e" 1922checksum = "f8e168a99d6ce9d5dd0d0913f1bded279377843952dd8ff83f81b862a1dad0e1"
1929dependencies = [ 1923dependencies = [
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"
24log = "0.4.8" 24log = "0.4.8"
25lsp-types = { version = "0.88.0", features = ["proposed"] } 25lsp-types = { version = "0.88.0", features = ["proposed"] }
26parking_lot = "0.11.0" 26parking_lot = "0.11.0"
27pico-args = "0.4.0" 27xflags = "0.1.2"
28oorandom = "11.1.2" 28oorandom = "11.1.2"
29rustc-hash = "1.1.0" 29rustc-hash = "1.1.0"
30serde = { version = "1.0.106", features = ["derive"] } 30serde = { 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
6use std::{env, path::PathBuf};
7
8use anyhow::{bail, format_err, Result};
9use ide_ssr::{SsrPattern, SsrRule};
10use pico_args::Arguments;
11use rust_analyzer::cli::{AnalysisStatsCmd, BenchCmd, BenchWhat, Position, Verbosity};
12use vfs::AbsPathBuf;
13
14pub(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
23pub(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
39const HELP: &str = "\
40rust-analyzer
41
42USAGE:
43 rust-analyzer [FLAGS] [COMMAND] [COMMAND_OPTIONS]
44
45FLAGS:
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
62ENVIRONMENTAL 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
67COMMANDS:
68
69not specified Launch LSP server
70
71parse < main.rs Parse tree
72 --no-dump Suppress printing
73
74symbols < main.rs Parse input an print the list of symbols
75
76highlight < main.rs Highlight input as html
77 --rainbow Enable rainbow highlighting of identifiers
78
79analysis-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
90analysis-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
103diagnostics <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
109ssr [RULE...]
110 <RULE> A structured search replace rule (`$a.foo($b) ==> bar($a, $b)`)
111
112search [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
118impl 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
269fn 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)]
3use std::{env, path::PathBuf};
4
5use ide_ssr::{SsrPattern, SsrRule};
6use rust_analyzer::cli::{BenchWhat, Position, Verbosity};
7use vfs::AbsPathBuf;
8
9xflags::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)]
125pub 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)]
135pub 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)]
149pub struct LspServer {
150 pub version: bool,
151 pub help: bool,
152 pub print_config_schema: bool,
153}
154
155#[derive(Debug)]
156pub struct Parse {
157 pub no_dump: bool,
158}
159
160#[derive(Debug)]
161pub struct Symbols {}
162
163#[derive(Debug)]
164pub struct Highlight {
165 pub rainbow: bool,
166}
167
168#[derive(Debug)]
169pub 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)]
182pub 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)]
194pub struct Diagnostics {
195 pub path: PathBuf,
196
197 pub load_output_dirs: bool,
198 pub with_proc_macro: bool,
199}
200
201#[derive(Debug)]
202pub struct Ssr {
203 pub rule: Vec<SsrRule>,
204}
205
206#[derive(Debug)]
207pub struct Search {
208 pub pattern: Vec<SsrPattern>,
209
210 pub debug: Option<String>,
211}
212
213#[derive(Debug)]
214pub struct ProcMacro {}
215
216impl 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
226impl 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
239impl 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
4mod args; 4mod flags;
5mod logger; 5mod logger;
6 6
7use std::{convert::TryFrom, env, fs, path::PathBuf, process}; 7use std::{convert::TryFrom, env, fs, path::Path, process};
8 8
9use lsp_server::Connection; 9use lsp_server::Connection;
10use project_model::ProjectManifest; 10use project_model::ProjectManifest;
11use rust_analyzer::{cli, config::Config, from_json, lsp_ext::supports_utf8, Result}; 11use rust_analyzer::{
12 cli::{self, AnalysisStatsCmd, BenchCmd},
13 config::Config,
14 from_json,
15 lsp_ext::supports_utf8,
16 Result,
17};
12use vfs::AbsPathBuf; 18use vfs::AbsPathBuf;
13 19
14#[cfg(all(feature = "mimalloc"))] 20#[cfg(all(feature = "mimalloc"))]
@@ -28,10 +34,10 @@ fn main() {
28} 34}
29 35
30fn try_main() -> Result<()> { 36fn 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
70fn setup_logging(log_file: Option<PathBuf>, no_buffering: bool) -> Result<()> { 103fn 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)]
38pub struct Position { 39pub struct Position {
39 pub path: AbsPathBuf, 40 pub path: AbsPathBuf,
40 pub line: u32, 41 pub line: u32,