mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-26 03:45:04 +00:00
Switch from pico-args to xflags
This commit is contained in:
parent
61c73caa30
commit
3038579c8e
6 changed files with 317 additions and 312 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
@ -1114,12 +1114,6 @@ dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pico-args"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d70072c20945e1ab871c472a285fc772aefd4f5407723c206242f2c6f94595d6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
|
@ -1339,7 +1333,6 @@ dependencies = [
|
||||||
"mimalloc",
|
"mimalloc",
|
||||||
"oorandom",
|
"oorandom",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"pico-args",
|
|
||||||
"proc_macro_srv",
|
"proc_macro_srv",
|
||||||
"profile",
|
"profile",
|
||||||
"project_model",
|
"project_model",
|
||||||
|
@ -1361,6 +1354,7 @@ dependencies = [
|
||||||
"vfs",
|
"vfs",
|
||||||
"vfs-notify",
|
"vfs-notify",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
"xflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1914,18 +1908,18 @@ checksum = "06069a848f95fceae3e5e03c0ddc8cb78452b56654ee0c8e68f938cf790fb9e3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xflags"
|
name = "xflags"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a6292b9528efc06cb25a41b8a0814dd3a9590c0fe2cd95341fe41bbe034fafb"
|
checksum = "ddb4b07c0db813f8e2b5e1b2189ef56fcddb27a6f9ef71314dbf8cc50096a5db"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"xflags-macros",
|
"xflags-macros",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xflags-macros"
|
name = "xflags-macros"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ba2108d40e49a0653f2ee4eda59f51447e0cab5cc2cc197a5abd96525c6bd89e"
|
checksum = "f8e168a99d6ce9d5dd0d0913f1bded279377843952dd8ff83f81b862a1dad0e1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
|
@ -24,7 +24,7 @@ jod-thread = "0.1.0"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
lsp-types = { version = "0.88.0", features = ["proposed"] }
|
lsp-types = { version = "0.88.0", features = ["proposed"] }
|
||||||
parking_lot = "0.11.0"
|
parking_lot = "0.11.0"
|
||||||
pico-args = "0.4.0"
|
xflags = "0.1.2"
|
||||||
oorandom = "11.1.2"
|
oorandom = "11.1.2"
|
||||||
rustc-hash = "1.1.0"
|
rustc-hash = "1.1.0"
|
||||||
serde = { version = "1.0.106", features = ["derive"] }
|
serde = { version = "1.0.106", features = ["derive"] }
|
||||||
|
|
|
@ -1,274 +0,0 @@
|
||||||
//! Command like parsing for rust-analyzer.
|
|
||||||
//!
|
|
||||||
//! If run started args, we run the LSP server loop. With a subcommand, we do a
|
|
||||||
//! one-time batch processing.
|
|
||||||
|
|
||||||
use std::{env, path::PathBuf};
|
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Result};
|
|
||||||
use ide_ssr::{SsrPattern, SsrRule};
|
|
||||||
use pico_args::Arguments;
|
|
||||||
use rust_analyzer::cli::{AnalysisStatsCmd, BenchCmd, BenchWhat, Position, Verbosity};
|
|
||||||
use vfs::AbsPathBuf;
|
|
||||||
|
|
||||||
pub(crate) struct Args {
|
|
||||||
pub(crate) verbosity: Verbosity,
|
|
||||||
pub(crate) log_file: Option<PathBuf>,
|
|
||||||
pub(crate) no_buffering: bool,
|
|
||||||
pub(crate) command: Command,
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) wait_dbg: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) enum Command {
|
|
||||||
Parse { no_dump: bool },
|
|
||||||
Symbols,
|
|
||||||
Highlight { rainbow: bool },
|
|
||||||
AnalysisStats(AnalysisStatsCmd),
|
|
||||||
Bench(BenchCmd),
|
|
||||||
Diagnostics { path: PathBuf, load_output_dirs: bool, with_proc_macro: bool },
|
|
||||||
Ssr { rules: Vec<SsrRule> },
|
|
||||||
StructuredSearch { debug_snippet: Option<String>, patterns: Vec<SsrPattern> },
|
|
||||||
ProcMacro,
|
|
||||||
RunServer,
|
|
||||||
PrintConfigSchema,
|
|
||||||
Version,
|
|
||||||
Help,
|
|
||||||
}
|
|
||||||
|
|
||||||
const HELP: &str = "\
|
|
||||||
rust-analyzer
|
|
||||||
|
|
||||||
USAGE:
|
|
||||||
rust-analyzer [FLAGS] [COMMAND] [COMMAND_OPTIONS]
|
|
||||||
|
|
||||||
FLAGS:
|
|
||||||
--version Print version
|
|
||||||
-h, --help Print this help
|
|
||||||
|
|
||||||
-v, --verbose
|
|
||||||
-vv, --spammy
|
|
||||||
-q, --quiet Set verbosity
|
|
||||||
|
|
||||||
--print-config-schema
|
|
||||||
Dump a LSP config JSON schema
|
|
||||||
--log-file <PATH> Log to the specified file instead of stderr
|
|
||||||
--no-log-buffering
|
|
||||||
Flush log records to the file immediately
|
|
||||||
|
|
||||||
--wait-dbg Wait until a debugger is attached to.
|
|
||||||
The flag is valid for debug builds only
|
|
||||||
|
|
||||||
ENVIRONMENTAL VARIABLES:
|
|
||||||
RA_LOG Set log filter in env_logger format
|
|
||||||
RA_PROFILE Enable hierarchical profiler
|
|
||||||
RA_WAIT_DBG If set acts like a --wait-dbg flag
|
|
||||||
|
|
||||||
COMMANDS:
|
|
||||||
|
|
||||||
not specified Launch LSP server
|
|
||||||
|
|
||||||
parse < main.rs Parse tree
|
|
||||||
--no-dump Suppress printing
|
|
||||||
|
|
||||||
symbols < main.rs Parse input an print the list of symbols
|
|
||||||
|
|
||||||
highlight < main.rs Highlight input as html
|
|
||||||
--rainbow Enable rainbow highlighting of identifiers
|
|
||||||
|
|
||||||
analysis-stats <PATH> Batch typecheck project and print summary statistics
|
|
||||||
<PATH> Directory with Cargo.toml
|
|
||||||
--randomize Randomize order in which crates, modules, and items are processed
|
|
||||||
--parallel Run type inference in parallel
|
|
||||||
--memory-usage Collect memory usage statistics
|
|
||||||
-o, --only <PATH> Only analyze items matching this path
|
|
||||||
--with-deps Also analyze all dependencies
|
|
||||||
--load-output-dirs
|
|
||||||
Load OUT_DIR values by running `cargo check` before analysis
|
|
||||||
--with-proc-macro Use proc-macro-srv for proc-macro expanding
|
|
||||||
|
|
||||||
analysis-bench <PATH> Benchmark specific analysis operation
|
|
||||||
<PATH> Directory with Cargo.toml
|
|
||||||
--highlight <PATH>
|
|
||||||
Compute syntax highlighting for this file
|
|
||||||
--complete <PATH:LINE:COLUMN>
|
|
||||||
Compute completions at this location
|
|
||||||
--goto-def <PATH:LINE:COLUMN>
|
|
||||||
Compute goto definition at this location
|
|
||||||
--memory-usage Collect memory usage statistics
|
|
||||||
--load-output-dirs
|
|
||||||
Load OUT_DIR values by running `cargo check` before analysis
|
|
||||||
--with-proc-macro Use proc-macro-srv for proc-macro expanding
|
|
||||||
|
|
||||||
diagnostics <PATH>
|
|
||||||
<PATH> Directory with Cargo.toml
|
|
||||||
--load-output-dirs
|
|
||||||
Load OUT_DIR values by running `cargo check` before analysis
|
|
||||||
--with-proc-macro Use proc-macro-srv for proc-macro expanding
|
|
||||||
|
|
||||||
ssr [RULE...]
|
|
||||||
<RULE> A structured search replace rule (`$a.foo($b) ==> bar($a, $b)`)
|
|
||||||
|
|
||||||
search [PATTERN..]
|
|
||||||
<PATTERN> A structured search replace pattern (`$a.foo($b)`)
|
|
||||||
--debug <snippet> Prints debug information for any nodes with source exactly
|
|
||||||
equal to <snippet>
|
|
||||||
";
|
|
||||||
|
|
||||||
impl Args {
|
|
||||||
pub(crate) fn parse() -> Result<Args> {
|
|
||||||
let mut matches = Arguments::from_env();
|
|
||||||
|
|
||||||
if matches.contains("--version") {
|
|
||||||
finish_args(matches)?;
|
|
||||||
return Ok(Args {
|
|
||||||
verbosity: Verbosity::Normal,
|
|
||||||
log_file: None,
|
|
||||||
command: Command::Version,
|
|
||||||
no_buffering: false,
|
|
||||||
wait_dbg: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let verbosity = match (
|
|
||||||
matches.contains(["-vv", "--spammy"]),
|
|
||||||
matches.contains(["-v", "--verbose"]),
|
|
||||||
matches.contains(["-q", "--quiet"]),
|
|
||||||
) {
|
|
||||||
(true, _, true) => bail!("Invalid flags: -q conflicts with -vv"),
|
|
||||||
(true, _, false) => Verbosity::Spammy,
|
|
||||||
(false, false, false) => Verbosity::Normal,
|
|
||||||
(false, false, true) => Verbosity::Quiet,
|
|
||||||
(false, true, false) => Verbosity::Verbose,
|
|
||||||
(false, true, true) => bail!("Invalid flags: -q conflicts with -v"),
|
|
||||||
};
|
|
||||||
let log_file = matches.opt_value_from_str("--log-file")?;
|
|
||||||
let no_buffering = matches.contains("--no-log-buffering");
|
|
||||||
let wait_dbg = matches.contains("--wait-dbg");
|
|
||||||
|
|
||||||
if matches.contains(["-h", "--help"]) {
|
|
||||||
eprintln!("{}", HELP);
|
|
||||||
return Ok(Args {
|
|
||||||
verbosity,
|
|
||||||
log_file: None,
|
|
||||||
command: Command::Help,
|
|
||||||
no_buffering,
|
|
||||||
wait_dbg,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if matches.contains("--print-config-schema") {
|
|
||||||
return Ok(Args {
|
|
||||||
verbosity,
|
|
||||||
log_file,
|
|
||||||
command: Command::PrintConfigSchema,
|
|
||||||
no_buffering,
|
|
||||||
wait_dbg,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let subcommand = match matches.subcommand()? {
|
|
||||||
Some(it) => it,
|
|
||||||
None => {
|
|
||||||
finish_args(matches)?;
|
|
||||||
return Ok(Args {
|
|
||||||
verbosity,
|
|
||||||
log_file,
|
|
||||||
command: Command::RunServer,
|
|
||||||
no_buffering,
|
|
||||||
wait_dbg,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let command = match subcommand.as_str() {
|
|
||||||
"parse" => Command::Parse { no_dump: matches.contains("--no-dump") },
|
|
||||||
"symbols" => Command::Symbols,
|
|
||||||
"highlight" => Command::Highlight { rainbow: matches.contains("--rainbow") },
|
|
||||||
"analysis-stats" => Command::AnalysisStats(AnalysisStatsCmd {
|
|
||||||
randomize: matches.contains("--randomize"),
|
|
||||||
parallel: matches.contains("--parallel"),
|
|
||||||
memory_usage: matches.contains("--memory-usage"),
|
|
||||||
only: matches.opt_value_from_str(["-o", "--only"])?,
|
|
||||||
with_deps: matches.contains("--with-deps"),
|
|
||||||
load_output_dirs: matches.contains("--load-output-dirs"),
|
|
||||||
with_proc_macro: matches.contains("--with-proc-macro"),
|
|
||||||
path: matches
|
|
||||||
.opt_free_from_str()?
|
|
||||||
.ok_or_else(|| format_err!("expected positional argument"))?,
|
|
||||||
}),
|
|
||||||
"analysis-bench" => Command::Bench(BenchCmd {
|
|
||||||
what: {
|
|
||||||
let highlight_path: Option<String> =
|
|
||||||
matches.opt_value_from_str("--highlight")?;
|
|
||||||
let complete_path: Option<Position> =
|
|
||||||
matches.opt_value_from_str("--complete")?;
|
|
||||||
let goto_def_path: Option<Position> =
|
|
||||||
matches.opt_value_from_str("--goto-def")?;
|
|
||||||
match (highlight_path, complete_path, goto_def_path) {
|
|
||||||
(Some(path), None, None) => {
|
|
||||||
let path = env::current_dir().unwrap().join(path);
|
|
||||||
BenchWhat::Highlight { path: AbsPathBuf::assert(path) }
|
|
||||||
}
|
|
||||||
(None, Some(position), None) => BenchWhat::Complete(position),
|
|
||||||
(None, None, Some(position)) => BenchWhat::GotoDef(position),
|
|
||||||
_ => panic!(
|
|
||||||
"exactly one of `--highlight`, `--complete` or `--goto-def` must be set"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
memory_usage: matches.contains("--memory-usage"),
|
|
||||||
load_output_dirs: matches.contains("--load-output-dirs"),
|
|
||||||
with_proc_macro: matches.contains("--with-proc-macro"),
|
|
||||||
path: matches
|
|
||||||
.opt_free_from_str()?
|
|
||||||
.ok_or_else(|| format_err!("expected positional argument"))?,
|
|
||||||
}),
|
|
||||||
"diagnostics" => Command::Diagnostics {
|
|
||||||
load_output_dirs: matches.contains("--load-output-dirs"),
|
|
||||||
with_proc_macro: matches.contains("--with-proc-macro"),
|
|
||||||
path: matches
|
|
||||||
.opt_free_from_str()?
|
|
||||||
.ok_or_else(|| format_err!("expected positional argument"))?,
|
|
||||||
},
|
|
||||||
"proc-macro" => Command::ProcMacro,
|
|
||||||
"ssr" => Command::Ssr {
|
|
||||||
rules: {
|
|
||||||
let mut acc = Vec::new();
|
|
||||||
while let Some(rule) = matches.opt_free_from_str()? {
|
|
||||||
acc.push(rule);
|
|
||||||
}
|
|
||||||
acc
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"search" => Command::StructuredSearch {
|
|
||||||
debug_snippet: matches.opt_value_from_str("--debug")?,
|
|
||||||
patterns: {
|
|
||||||
let mut acc = Vec::new();
|
|
||||||
while let Some(rule) = matches.opt_free_from_str()? {
|
|
||||||
acc.push(rule);
|
|
||||||
}
|
|
||||||
acc
|
|
||||||
},
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
eprintln!("{}", HELP);
|
|
||||||
return Ok(Args {
|
|
||||||
verbosity,
|
|
||||||
log_file: None,
|
|
||||||
command: Command::Help,
|
|
||||||
no_buffering,
|
|
||||||
wait_dbg,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
finish_args(matches)?;
|
|
||||||
Ok(Args { verbosity, log_file, command, no_buffering, wait_dbg })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn finish_args(args: Arguments) -> Result<()> {
|
|
||||||
if !args.finish().is_empty() {
|
|
||||||
bail!("Unused arguments.");
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
251
crates/rust-analyzer/src/bin/flags.rs
Normal file
251
crates/rust-analyzer/src/bin/flags.rs
Normal file
|
@ -0,0 +1,251 @@
|
||||||
|
//! Grammar for the command-line arguments.
|
||||||
|
#![allow(unreachable_pub)]
|
||||||
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
|
use ide_ssr::{SsrPattern, SsrRule};
|
||||||
|
use rust_analyzer::cli::{BenchWhat, Position, Verbosity};
|
||||||
|
use vfs::AbsPathBuf;
|
||||||
|
|
||||||
|
xflags::args_parser! {
|
||||||
|
/// LSP server for the Rust programming language.
|
||||||
|
cmd rust-analyzer {
|
||||||
|
/// Verbosity level, can be repeated multiple times.
|
||||||
|
repeated -v, --verbose
|
||||||
|
/// Verbosity level.
|
||||||
|
optional -q, --quiet
|
||||||
|
|
||||||
|
/// Log to the specified file instead of stderr.
|
||||||
|
optional --log-file path: PathBuf
|
||||||
|
/// Flush log records to the file immediately.
|
||||||
|
optional --no-log-buffering
|
||||||
|
|
||||||
|
/// Wait until a debugger is attached to (requires debug build).
|
||||||
|
optional --wait-dbg
|
||||||
|
|
||||||
|
default cmd lsp-server {
|
||||||
|
/// Print version.
|
||||||
|
optional --version
|
||||||
|
/// Print help.
|
||||||
|
optional -h, --help
|
||||||
|
|
||||||
|
/// Dump a LSP config JSON schema.
|
||||||
|
optional --print-config-schema
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse stdin.
|
||||||
|
cmd parse {
|
||||||
|
/// Suppress printing.
|
||||||
|
optional --no-dump
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse stdin and print the list of symbols.
|
||||||
|
cmd symbols {}
|
||||||
|
|
||||||
|
/// Highlight stdin as html.
|
||||||
|
cmd highlight {
|
||||||
|
/// Enable rainbow highlighting of identifiers.
|
||||||
|
optional --rainbow
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Batch typecheck project and print summary statistics
|
||||||
|
cmd analysis-stats
|
||||||
|
/// Directory with Cargo.toml.
|
||||||
|
required path: PathBuf
|
||||||
|
{
|
||||||
|
/// Randomize order in which crates, modules, and items are processed.
|
||||||
|
optional --randomize
|
||||||
|
/// Run type inference in parallel.
|
||||||
|
optional --parallel
|
||||||
|
/// Collect memory usage statistics.
|
||||||
|
optional --memory-usage
|
||||||
|
|
||||||
|
/// Only analyze items matching this path.
|
||||||
|
optional -o, --only path: String
|
||||||
|
/// Also analyze all dependencies.
|
||||||
|
optional --with-deps
|
||||||
|
|
||||||
|
/// Load OUT_DIR values by running `cargo check` before analysis.
|
||||||
|
optional --load-output-dirs
|
||||||
|
/// Use proc-macro-srv for proc-macro expanding.
|
||||||
|
optional --with-proc-macro
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Benchmark specific analysis operation
|
||||||
|
cmd analysis-bench
|
||||||
|
/// Directory with Cargo.toml.
|
||||||
|
required path: PathBuf
|
||||||
|
{
|
||||||
|
/// Collect memory usage statistics.
|
||||||
|
optional --memory-usage
|
||||||
|
|
||||||
|
/// Compute syntax highlighting for this file
|
||||||
|
optional --highlight path: PathBuf
|
||||||
|
/// Compute completions at file:line:column location.
|
||||||
|
optional --complete location: Position
|
||||||
|
/// Compute goto definition at file:line:column location.
|
||||||
|
optional --goto-def location: Position
|
||||||
|
|
||||||
|
/// Load OUT_DIR values by running `cargo check` before analysis.
|
||||||
|
optional --load-output-dirs
|
||||||
|
/// Use proc-macro-srv for proc-macro expanding.
|
||||||
|
optional --with-proc-macro
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd diagnostics
|
||||||
|
/// Directory with Cargo.toml.
|
||||||
|
required path: PathBuf
|
||||||
|
{
|
||||||
|
/// Load OUT_DIR values by running `cargo check` before analysis.
|
||||||
|
optional --load-output-dirs
|
||||||
|
/// Use proc-macro-srv for proc-macro expanding.
|
||||||
|
optional --with-proc-macro
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd ssr
|
||||||
|
/// A structured search replace rule (`$a.foo($b) ==> bar($a, $b)`)
|
||||||
|
repeated rule: SsrRule
|
||||||
|
{}
|
||||||
|
|
||||||
|
cmd search
|
||||||
|
/// A structured search replace pattern (`$a.foo($b)`)
|
||||||
|
repeated pattern: SsrPattern
|
||||||
|
{
|
||||||
|
/// Prints debug information for any nodes with source exactly equal to snippet.
|
||||||
|
optional --debug snippet: String
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd proc-macro {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// generated start
|
||||||
|
// The following code is generated by `xflags` macro.
|
||||||
|
// Run `env XFLAGS_DUMP= cargo build` to regenerate.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RustAnalyzer {
|
||||||
|
pub verbose: u32,
|
||||||
|
pub quiet: bool,
|
||||||
|
pub log_file: Option<PathBuf>,
|
||||||
|
pub no_log_buffering: bool,
|
||||||
|
pub wait_dbg: bool,
|
||||||
|
pub subcommand: RustAnalyzerCmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum RustAnalyzerCmd {
|
||||||
|
LspServer(LspServer),
|
||||||
|
Parse(Parse),
|
||||||
|
Symbols(Symbols),
|
||||||
|
Highlight(Highlight),
|
||||||
|
AnalysisStats(AnalysisStats),
|
||||||
|
AnalysisBench(AnalysisBench),
|
||||||
|
Diagnostics(Diagnostics),
|
||||||
|
Ssr(Ssr),
|
||||||
|
Search(Search),
|
||||||
|
ProcMacro(ProcMacro),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct LspServer {
|
||||||
|
pub version: bool,
|
||||||
|
pub help: bool,
|
||||||
|
pub print_config_schema: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Parse {
|
||||||
|
pub no_dump: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Symbols {}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Highlight {
|
||||||
|
pub rainbow: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AnalysisStats {
|
||||||
|
pub path: PathBuf,
|
||||||
|
|
||||||
|
pub randomize: bool,
|
||||||
|
pub parallel: bool,
|
||||||
|
pub memory_usage: bool,
|
||||||
|
pub only: Option<String>,
|
||||||
|
pub with_deps: bool,
|
||||||
|
pub load_output_dirs: bool,
|
||||||
|
pub with_proc_macro: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AnalysisBench {
|
||||||
|
pub path: PathBuf,
|
||||||
|
|
||||||
|
pub memory_usage: bool,
|
||||||
|
pub highlight: Option<PathBuf>,
|
||||||
|
pub complete: Option<Position>,
|
||||||
|
pub goto_def: Option<Position>,
|
||||||
|
pub load_output_dirs: bool,
|
||||||
|
pub with_proc_macro: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Diagnostics {
|
||||||
|
pub path: PathBuf,
|
||||||
|
|
||||||
|
pub load_output_dirs: bool,
|
||||||
|
pub with_proc_macro: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Ssr {
|
||||||
|
pub rule: Vec<SsrRule>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Search {
|
||||||
|
pub pattern: Vec<SsrPattern>,
|
||||||
|
|
||||||
|
pub debug: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ProcMacro {}
|
||||||
|
|
||||||
|
impl RustAnalyzer {
|
||||||
|
pub const HELP: &'static str = Self::_HELP;
|
||||||
|
|
||||||
|
pub fn from_env() -> xflags::Result<Self> {
|
||||||
|
let mut p = xflags::rt::Parser::new_from_env();
|
||||||
|
Self::_parse(&mut p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// generated end
|
||||||
|
|
||||||
|
impl RustAnalyzer {
|
||||||
|
pub(crate) fn verbosity(&self) -> Verbosity {
|
||||||
|
if self.quiet {
|
||||||
|
return Verbosity::Quiet;
|
||||||
|
}
|
||||||
|
match self.verbose {
|
||||||
|
0 => Verbosity::Normal,
|
||||||
|
1 => Verbosity::Verbose,
|
||||||
|
_ => Verbosity::Spammy,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AnalysisBench {
|
||||||
|
pub(crate) fn what(&self) -> BenchWhat {
|
||||||
|
match (&self.highlight, &self.complete, &self.goto_def) {
|
||||||
|
(Some(path), None, None) => {
|
||||||
|
let path = env::current_dir().unwrap().join(path);
|
||||||
|
BenchWhat::Highlight { path: AbsPathBuf::assert(path) }
|
||||||
|
}
|
||||||
|
(None, Some(position), None) => BenchWhat::Complete(position.clone()),
|
||||||
|
(None, None, Some(position)) => BenchWhat::GotoDef(position.clone()),
|
||||||
|
_ => panic!("exactly one of `--highlight`, `--complete` or `--goto-def` must be set"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,20 @@
|
||||||
//! Driver for rust-analyzer.
|
//! Driver for rust-analyzer.
|
||||||
//!
|
//!
|
||||||
//! Based on cli flags, either spawns an LSP server, or runs a batch analysis
|
//! Based on cli flags, either spawns an LSP server, or runs a batch analysis
|
||||||
mod args;
|
mod flags;
|
||||||
mod logger;
|
mod logger;
|
||||||
|
|
||||||
use std::{convert::TryFrom, env, fs, path::PathBuf, process};
|
use std::{convert::TryFrom, env, fs, path::Path, process};
|
||||||
|
|
||||||
use lsp_server::Connection;
|
use lsp_server::Connection;
|
||||||
use project_model::ProjectManifest;
|
use project_model::ProjectManifest;
|
||||||
use rust_analyzer::{cli, config::Config, from_json, lsp_ext::supports_utf8, Result};
|
use rust_analyzer::{
|
||||||
|
cli::{self, AnalysisStatsCmd, BenchCmd},
|
||||||
|
config::Config,
|
||||||
|
from_json,
|
||||||
|
lsp_ext::supports_utf8,
|
||||||
|
Result,
|
||||||
|
};
|
||||||
use vfs::AbsPathBuf;
|
use vfs::AbsPathBuf;
|
||||||
|
|
||||||
#[cfg(all(feature = "mimalloc"))]
|
#[cfg(all(feature = "mimalloc"))]
|
||||||
|
@ -28,10 +34,10 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_main() -> Result<()> {
|
fn try_main() -> Result<()> {
|
||||||
let args = args::Args::parse()?;
|
let flags = flags::RustAnalyzer::from_env()?;
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
if args.wait_dbg || env::var("RA_WAIT_DBG").is_ok() {
|
if flags.wait_dbg || env::var("RA_WAIT_DBG").is_ok() {
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut d = 4;
|
let mut d = 4;
|
||||||
while d == 4 {
|
while d == 4 {
|
||||||
|
@ -39,35 +45,62 @@ fn try_main() -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_logging(args.log_file, args.no_buffering)?;
|
setup_logging(flags.log_file.as_deref(), flags.no_log_buffering)?;
|
||||||
match args.command {
|
let verbosity = flags.verbosity();
|
||||||
args::Command::RunServer => run_server()?,
|
|
||||||
args::Command::PrintConfigSchema => {
|
|
||||||
println!("{:#}", Config::json_schema());
|
|
||||||
}
|
|
||||||
args::Command::ProcMacro => proc_macro_srv::cli::run()?,
|
|
||||||
|
|
||||||
args::Command::Parse { no_dump } => cli::parse(no_dump)?,
|
match flags.subcommand {
|
||||||
args::Command::Symbols => cli::symbols()?,
|
flags::RustAnalyzerCmd::LspServer(cmd) => {
|
||||||
args::Command::Highlight { rainbow } => cli::highlight(rainbow)?,
|
if cmd.print_config_schema {
|
||||||
args::Command::AnalysisStats(cmd) => cmd.run(args.verbosity)?,
|
println!("{:#}", Config::json_schema());
|
||||||
args::Command::Bench(cmd) => cmd.run(args.verbosity)?,
|
return Ok(());
|
||||||
args::Command::Diagnostics { path, load_output_dirs, with_proc_macro } => {
|
}
|
||||||
cli::diagnostics(path.as_ref(), load_output_dirs, with_proc_macro)?
|
if cmd.version {
|
||||||
|
println!("rust-analyzer {}", env!("REV"));
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
if cmd.help {
|
||||||
|
println!("{}", flags::RustAnalyzer::HELP);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
run_server()?
|
||||||
}
|
}
|
||||||
args::Command::Ssr { rules } => {
|
flags::RustAnalyzerCmd::ProcMacro(_) => proc_macro_srv::cli::run()?,
|
||||||
cli::apply_ssr_rules(rules)?;
|
flags::RustAnalyzerCmd::Parse(cmd) => cli::parse(cmd.no_dump)?,
|
||||||
|
flags::RustAnalyzerCmd::Symbols(_) => cli::symbols()?,
|
||||||
|
flags::RustAnalyzerCmd::Highlight(cmd) => cli::highlight(cmd.rainbow)?,
|
||||||
|
flags::RustAnalyzerCmd::AnalysisStats(cmd) => AnalysisStatsCmd {
|
||||||
|
randomize: cmd.randomize,
|
||||||
|
parallel: cmd.parallel,
|
||||||
|
memory_usage: cmd.memory_usage,
|
||||||
|
only: cmd.only,
|
||||||
|
with_deps: cmd.with_deps,
|
||||||
|
path: cmd.path,
|
||||||
|
load_output_dirs: cmd.load_output_dirs,
|
||||||
|
with_proc_macro: cmd.with_proc_macro,
|
||||||
}
|
}
|
||||||
args::Command::StructuredSearch { patterns, debug_snippet } => {
|
.run(verbosity)?,
|
||||||
cli::search_for_patterns(patterns, debug_snippet)?;
|
flags::RustAnalyzerCmd::AnalysisBench(cmd) => {
|
||||||
|
let what = cmd.what();
|
||||||
|
BenchCmd {
|
||||||
|
memory_usage: cmd.memory_usage,
|
||||||
|
path: cmd.path,
|
||||||
|
load_output_dirs: cmd.load_output_dirs,
|
||||||
|
with_proc_macro: cmd.with_proc_macro,
|
||||||
|
what,
|
||||||
|
}
|
||||||
|
.run(verbosity)?
|
||||||
}
|
}
|
||||||
args::Command::Version => println!("rust-analyzer {}", env!("REV")),
|
|
||||||
args::Command::Help => {}
|
flags::RustAnalyzerCmd::Diagnostics(cmd) => {
|
||||||
|
cli::diagnostics(&cmd.path, cmd.load_output_dirs, cmd.with_proc_macro)?
|
||||||
|
}
|
||||||
|
flags::RustAnalyzerCmd::Ssr(cmd) => cli::apply_ssr_rules(cmd.rule)?,
|
||||||
|
flags::RustAnalyzerCmd::Search(cmd) => cli::search_for_patterns(cmd.pattern, cmd.debug)?,
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_logging(log_file: Option<PathBuf>, no_buffering: bool) -> Result<()> {
|
fn setup_logging(log_file: Option<&Path>, no_buffering: bool) -> Result<()> {
|
||||||
env::set_var("RUST_BACKTRACE", "short");
|
env::set_var("RUST_BACKTRACE", "short");
|
||||||
|
|
||||||
let log_file = match log_file {
|
let log_file = match log_file {
|
||||||
|
|
|
@ -35,6 +35,7 @@ pub enum BenchWhat {
|
||||||
GotoDef(Position),
|
GotoDef(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct Position {
|
pub struct Position {
|
||||||
pub path: AbsPathBuf,
|
pub path: AbsPathBuf,
|
||||||
pub line: u32,
|
pub line: u32,
|
||||||
|
|
Loading…
Reference in a new issue