Rename folder

This commit is contained in:
Aleksey Kladov
2020-02-18 12:37:45 +01:00
parent c855e36696
commit 865759925b
25 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,242 @@
//! 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 anyhow::{bail, Result};
use pico_args::Arguments;
use rust_analyzer::cli::{BenchWhat, Position, Verbosity};
use std::{fmt::Write, path::PathBuf};
pub(crate) struct Args {
pub(crate) verbosity: Verbosity,
pub(crate) command: Command,
}
pub(crate) enum Command {
Parse {
no_dump: bool,
},
Symbols,
Highlight {
rainbow: bool,
},
Stats {
randomize: bool,
memory_usage: bool,
only: Option<String>,
with_deps: bool,
path: PathBuf,
},
Bench {
path: PathBuf,
what: BenchWhat,
},
RunServer,
Version,
}
impl Args {
pub(crate) fn parse() -> Result<Result<Args, HelpPrinted>> {
let mut matches = Arguments::from_env();
if matches.contains("--version") {
matches.finish().or_else(handle_extra_flags)?;
return Ok(Ok(Args { verbosity: Verbosity::Normal, command: Command::Version }));
}
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 subcommand = match matches.subcommand()? {
Some(it) => it,
None => {
matches.finish().or_else(handle_extra_flags)?;
return Ok(Ok(Args { verbosity, command: Command::RunServer }));
}
};
let command = match subcommand.as_str() {
"parse" => {
if matches.contains(["-h", "--help"]) {
eprintln!(
"\
ra-cli-parse
USAGE:
rust-analyzer parse [FLAGS]
FLAGS:
-h, --help Prints help inforamtion
--no-dump"
);
return Ok(Err(HelpPrinted));
}
let no_dump = matches.contains("--no-dump");
matches.finish().or_else(handle_extra_flags)?;
Command::Parse { no_dump }
}
"symbols" => {
if matches.contains(["-h", "--help"]) {
eprintln!(
"\
ra-cli-symbols
USAGE:
rust-analyzer highlight [FLAGS]
FLAGS:
-h, --help Prints help inforamtion"
);
return Ok(Err(HelpPrinted));
}
matches.finish().or_else(handle_extra_flags)?;
Command::Symbols
}
"highlight" => {
if matches.contains(["-h", "--help"]) {
eprintln!(
"\
ra-cli-highlight
USAGE:
rust-analyzer highlight [FLAGS]
FLAGS:
-h, --help Prints help information
-r, --rainbow"
);
return Ok(Err(HelpPrinted));
}
let rainbow = matches.contains(["-r", "--rainbow"]);
matches.finish().or_else(handle_extra_flags)?;
Command::Highlight { rainbow }
}
"analysis-stats" => {
if matches.contains(["-h", "--help"]) {
eprintln!(
"\
ra-cli-analysis-stats
USAGE:
rust-analyzer analysis-stats [FLAGS] [OPTIONS] [PATH]
FLAGS:
-h, --help Prints help information
--memory-usage
-v, --verbose
-q, --quiet
OPTIONS:
-o <ONLY>
ARGS:
<PATH>"
);
return Ok(Err(HelpPrinted));
}
let randomize = matches.contains("--randomize");
let memory_usage = matches.contains("--memory-usage");
let only: Option<String> = matches.opt_value_from_str(["-o", "--only"])?;
let with_deps: bool = matches.contains("--with-deps");
let path = {
let mut trailing = matches.free()?;
if trailing.len() != 1 {
bail!("Invalid flags");
}
trailing.pop().unwrap().into()
};
Command::Stats { randomize, memory_usage, only, with_deps, path }
}
"analysis-bench" => {
if matches.contains(["-h", "--help"]) {
eprintln!(
"\
rust-analyzer-analysis-bench
USAGE:
rust-analyzer analysis-bench [FLAGS] [OPTIONS] [PATH]
FLAGS:
-h, --help Prints help information
-v, --verbose
OPTIONS:
--complete <PATH:LINE:COLUMN> Compute completions at this location
--highlight <PATH> Hightlight this file
ARGS:
<PATH> Project to analyse"
);
return Ok(Err(HelpPrinted));
}
let path: PathBuf = matches.opt_value_from_str("--path")?.unwrap_or_default();
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")?;
let what = match (highlight_path, complete_path, goto_def_path) {
(Some(path), None, None) => BenchWhat::Highlight { path: path.into() },
(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"
),
};
Command::Bench { path, what }
}
_ => {
eprintln!(
"\
ra-cli
USAGE:
rust-analyzer <SUBCOMMAND>
FLAGS:
-h, --help Prints help information
SUBCOMMANDS:
analysis-bench
analysis-stats
highlight
parse
symbols"
);
return Ok(Err(HelpPrinted));
}
};
Ok(Ok(Args { verbosity, command }))
}
}
pub(crate) struct HelpPrinted;
fn handle_extra_flags(e: pico_args::Error) -> Result<()> {
if let pico_args::Error::UnusedArgsLeft(flags) = e {
let mut invalid_flags = String::new();
for flag in flags {
write!(&mut invalid_flags, "{}, ", flag)?;
}
let (invalid_flags, _) = invalid_flags.split_at(invalid_flags.len() - 2);
bail!("Invalid flags: {}", invalid_flags);
} else {
bail!(e);
}
}

View File

@@ -0,0 +1,98 @@
//! Driver for rust-analyzer.
//!
//! Based on cli flags, either spawns an LSP server, or runs a batch analysis
mod args;
use lsp_server::Connection;
use ra_prof;
use rust_analyzer::{cli, from_json, show_message, Result, ServerConfig};
use crate::args::HelpPrinted;
fn main() -> Result<()> {
setup_logging()?;
let args = match args::Args::parse()? {
Ok(it) => it,
Err(HelpPrinted) => return Ok(()),
};
match args.command {
args::Command::Parse { no_dump } => cli::parse(no_dump)?,
args::Command::Symbols => cli::symbols()?,
args::Command::Highlight { rainbow } => cli::highlight(rainbow)?,
args::Command::Stats { randomize, memory_usage, only, with_deps, path } => {
cli::analysis_stats(
args.verbosity,
memory_usage,
path.as_ref(),
only.as_ref().map(String::as_ref),
with_deps,
randomize,
)?
}
args::Command::Bench { path, what } => {
cli::analysis_bench(args.verbosity, path.as_ref(), what)?
}
args::Command::RunServer => run_server()?,
args::Command::Version => println!("rust-analyzer {}", env!("REV")),
}
Ok(())
}
fn setup_logging() -> Result<()> {
std::env::set_var("RUST_BACKTRACE", "short");
env_logger::try_init()?;
ra_prof::init();
Ok(())
}
fn run_server() -> Result<()> {
log::info!("lifecycle: server started");
let (connection, io_threads) = Connection::stdio();
let server_capabilities = serde_json::to_value(rust_analyzer::server_capabilities()).unwrap();
let initialize_params = connection.initialize(server_capabilities)?;
let initialize_params =
from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?;
if let Some(client_info) = initialize_params.client_info {
log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
}
let cwd = std::env::current_dir()?;
let root = initialize_params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd);
let workspace_roots = initialize_params
.workspace_folders
.map(|workspaces| {
workspaces.into_iter().filter_map(|it| it.uri.to_file_path().ok()).collect::<Vec<_>>()
})
.filter(|workspaces| !workspaces.is_empty())
.unwrap_or_else(|| vec![root]);
let server_config = initialize_params
.initialization_options
.and_then(|v| {
from_json::<ServerConfig>("config", v)
.map_err(|e| {
log::error!("{}", e);
show_message(lsp_types::MessageType::Error, e.to_string(), &connection.sender);
})
.ok()
})
.unwrap_or_default();
rust_analyzer::main_loop(
workspace_roots,
initialize_params.capabilities,
server_config,
connection,
)?;
log::info!("shutting down IO...");
io_threads.join()?;
log::info!("... IO is down");
Ok(())
}