From 59e1207dac8eb9cc56a72ee685bd4f143683d2bb Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Feb 2020 11:56:18 +0100 Subject: Better folder structure --- crates/ra_lsp_server/Cargo.toml | 5 + crates/ra_lsp_server/src/args.rs | 242 ----------------------------------- crates/ra_lsp_server/src/bin/args.rs | 242 +++++++++++++++++++++++++++++++++++ crates/ra_lsp_server/src/bin/main.rs | 96 ++++++++++++++ crates/ra_lsp_server/src/main.rs | 96 -------------- xtask/tests/tidy-tests/docs.rs | 1 - 6 files changed, 343 insertions(+), 339 deletions(-) delete mode 100644 crates/ra_lsp_server/src/args.rs create mode 100644 crates/ra_lsp_server/src/bin/args.rs create mode 100644 crates/ra_lsp_server/src/bin/main.rs delete mode 100644 crates/ra_lsp_server/src/main.rs diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index da523ba8a..151ca3da5 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml @@ -3,10 +3,15 @@ edition = "2018" name = "ra_lsp_server" version = "0.1.0" authors = ["rust-analyzer developers"] +autobins = false [lib] doctest = false +[[bin]] +name = "ra_lsp_server" +path = "./src/bin/main.rs" + [dependencies] anyhow = "1.0" crossbeam-channel = "0.4" diff --git a/crates/ra_lsp_server/src/args.rs b/crates/ra_lsp_server/src/args.rs deleted file mode 100644 index 3890fe13a..000000000 --- a/crates/ra_lsp_server/src/args.rs +++ /dev/null @@ -1,242 +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 anyhow::{bail, Result}; -use pico_args::Arguments; -use ra_lsp_server::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, - with_deps: bool, - path: PathBuf, - }, - Bench { - path: PathBuf, - what: BenchWhat, - }, - RunServer, - Version, -} - -impl Args { - pub(crate) fn parse() -> Result> { - 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: - ra_lsp_server 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: - ra_lsp_server 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: - ra_lsp_server 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: - ra_lsp_server analysis-stats [FLAGS] [OPTIONS] [PATH] - -FLAGS: - -h, --help Prints help information - --memory-usage - -v, --verbose - -q, --quiet - -OPTIONS: - -o - -ARGS: - " - ); - return Ok(Err(HelpPrinted)); - } - - let randomize = matches.contains("--randomize"); - let memory_usage = matches.contains("--memory-usage"); - let only: Option = 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!( - "\ -ra_lsp_server-analysis-bench - -USAGE: - ra_lsp_server analysis-bench [FLAGS] [OPTIONS] [PATH] - -FLAGS: - -h, --help Prints help information - -v, --verbose - -OPTIONS: - --complete Compute completions at this location - --highlight Hightlight this file - -ARGS: - Project to analyse" - ); - return Ok(Err(HelpPrinted)); - } - - let path: PathBuf = matches.opt_value_from_str("--path")?.unwrap_or_default(); - let highlight_path: Option = matches.opt_value_from_str("--highlight")?; - let complete_path: Option = matches.opt_value_from_str("--complete")?; - let goto_def_path: Option = 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: - ra_lsp_server - -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); - } -} diff --git a/crates/ra_lsp_server/src/bin/args.rs b/crates/ra_lsp_server/src/bin/args.rs new file mode 100644 index 000000000..3890fe13a --- /dev/null +++ b/crates/ra_lsp_server/src/bin/args.rs @@ -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 ra_lsp_server::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, + with_deps: bool, + path: PathBuf, + }, + Bench { + path: PathBuf, + what: BenchWhat, + }, + RunServer, + Version, +} + +impl Args { + pub(crate) fn parse() -> Result> { + 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: + ra_lsp_server 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: + ra_lsp_server 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: + ra_lsp_server 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: + ra_lsp_server analysis-stats [FLAGS] [OPTIONS] [PATH] + +FLAGS: + -h, --help Prints help information + --memory-usage + -v, --verbose + -q, --quiet + +OPTIONS: + -o + +ARGS: + " + ); + return Ok(Err(HelpPrinted)); + } + + let randomize = matches.contains("--randomize"); + let memory_usage = matches.contains("--memory-usage"); + let only: Option = 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!( + "\ +ra_lsp_server-analysis-bench + +USAGE: + ra_lsp_server analysis-bench [FLAGS] [OPTIONS] [PATH] + +FLAGS: + -h, --help Prints help information + -v, --verbose + +OPTIONS: + --complete Compute completions at this location + --highlight Hightlight this file + +ARGS: + Project to analyse" + ); + return Ok(Err(HelpPrinted)); + } + + let path: PathBuf = matches.opt_value_from_str("--path")?.unwrap_or_default(); + let highlight_path: Option = matches.opt_value_from_str("--highlight")?; + let complete_path: Option = matches.opt_value_from_str("--complete")?; + let goto_def_path: Option = 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: + ra_lsp_server + +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); + } +} diff --git a/crates/ra_lsp_server/src/bin/main.rs b/crates/ra_lsp_server/src/bin/main.rs new file mode 100644 index 000000000..a549e5ff1 --- /dev/null +++ b/crates/ra_lsp_server/src/bin/main.rs @@ -0,0 +1,96 @@ +//! `ra_lsp_server` binary +mod args; + +use lsp_server::Connection; +use ra_lsp_server::{cli, from_json, show_message, Result, ServerConfig}; +use ra_prof; + +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(ra_lsp_server::server_capabilities()).unwrap(); + + let initialize_params = connection.initialize(server_capabilities)?; + let initialize_params = + from_json::("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::>() + }) + .filter(|workspaces| !workspaces.is_empty()) + .unwrap_or_else(|| vec![root]); + + let server_config = initialize_params + .initialization_options + .and_then(|v| { + from_json::("config", v) + .map_err(|e| { + log::error!("{}", e); + show_message(lsp_types::MessageType::Error, e.to_string(), &connection.sender); + }) + .ok() + }) + .unwrap_or_default(); + + ra_lsp_server::main_loop( + workspace_roots, + initialize_params.capabilities, + server_config, + connection, + )?; + + log::info!("shutting down IO..."); + io_threads.join()?; + log::info!("... IO is down"); + Ok(()) +} diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs deleted file mode 100644 index a549e5ff1..000000000 --- a/crates/ra_lsp_server/src/main.rs +++ /dev/null @@ -1,96 +0,0 @@ -//! `ra_lsp_server` binary -mod args; - -use lsp_server::Connection; -use ra_lsp_server::{cli, from_json, show_message, Result, ServerConfig}; -use ra_prof; - -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(ra_lsp_server::server_capabilities()).unwrap(); - - let initialize_params = connection.initialize(server_capabilities)?; - let initialize_params = - from_json::("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::>() - }) - .filter(|workspaces| !workspaces.is_empty()) - .unwrap_or_else(|| vec![root]); - - let server_config = initialize_params - .initialization_options - .and_then(|v| { - from_json::("config", v) - .map_err(|e| { - log::error!("{}", e); - show_message(lsp_types::MessageType::Error, e.to_string(), &connection.sender); - }) - .ok() - }) - .unwrap_or_default(); - - ra_lsp_server::main_loop( - workspace_roots, - initialize_params.capabilities, - server_config, - connection, - )?; - - log::info!("shutting down IO..."); - io_threads.join()?; - log::info!("... IO is down"); - Ok(()) -} diff --git a/xtask/tests/tidy-tests/docs.rs b/xtask/tests/tidy-tests/docs.rs index b2571df25..62c4f8441 100644 --- a/xtask/tests/tidy-tests/docs.rs +++ b/xtask/tests/tidy-tests/docs.rs @@ -77,7 +77,6 @@ fn no_docs_comments() { "ra_hir", "ra_hir_expand", "ra_ide", - "ra_lsp_server", "ra_mbe", "ra_parser", "ra_prof", -- cgit v1.2.3