Files
rust/crates/rust-analyzer/src/bin/main.rs

158 lines
4.9 KiB
Rust
Raw Normal View History

2020-02-18 12:11:32 +01:00
//! Driver for rust-analyzer.
//!
//! Based on cli flags, either spawns an LSP server, or runs a batch analysis
2020-02-17 19:03:03 +01:00
mod args;
use std::convert::TryFrom;
2019-08-30 20:18:57 +03:00
use lsp_server::Connection;
2020-07-08 18:22:57 +02:00
use ra_project_model::ProjectManifest;
use rust_analyzer::{
cli,
config::{Config, LinkedProject},
from_json, Result,
};
2020-07-08 18:22:57 +02:00
use vfs::AbsPathBuf;
2020-02-17 19:03:03 +01:00
use crate::args::HelpPrinted;
2018-08-10 15:07:43 +03:00
fn main() -> Result<()> {
2019-08-31 14:47:37 +03:00
setup_logging()?;
2020-02-17 19:03:03 +01:00
let args = match args::Args::parse()? {
Ok(it) => it,
Err(HelpPrinted) => return Ok(()),
};
match args.command {
args::Command::RunServer => run_server()?,
args::Command::ProcMacro => ra_proc_macro_srv::cli::run()?,
2020-02-17 19:03:03 +01:00
args::Command::Parse { no_dump } => cli::parse(no_dump)?,
args::Command::Symbols => cli::symbols()?,
args::Command::Highlight { rainbow } => cli::highlight(rainbow)?,
2020-03-16 14:51:44 +01:00
args::Command::Stats {
randomize,
parallel,
2020-03-16 14:51:44 +01:00
memory_usage,
only,
with_deps,
path,
load_output_dirs,
with_proc_macro,
2020-03-16 14:51:44 +01:00
} => cli::analysis_stats(
args.verbosity,
memory_usage,
path.as_ref(),
only.as_ref().map(String::as_ref),
with_deps,
randomize,
parallel,
2020-03-16 14:51:44 +01:00
load_output_dirs,
with_proc_macro,
2020-03-16 14:51:44 +01:00
)?,
2020-07-15 12:14:51 +02:00
args::Command::Bench { memory_usage, path, what, load_output_dirs, with_proc_macro } => {
cli::analysis_bench(
args.verbosity,
path.as_ref(),
what,
2020-07-15 12:14:51 +02:00
memory_usage,
load_output_dirs,
with_proc_macro,
)?
2020-02-17 19:03:03 +01:00
}
args::Command::Diagnostics { path, load_output_dirs, with_proc_macro, all } => {
cli::diagnostics(path.as_ref(), load_output_dirs, with_proc_macro, all)?
}
args::Command::Ssr { rules } => {
cli::apply_ssr_rules(rules)?;
}
2020-06-30 15:55:20 +10:00
args::Command::StructuredSearch { patterns, debug_snippet } => {
cli::search_for_patterns(patterns, debug_snippet)?;
}
2020-02-17 19:03:03 +01:00
args::Command::Version => println!("rust-analyzer {}", env!("REV")),
2019-12-09 15:59:04 +01:00
}
2019-08-31 14:47:37 +03:00
Ok(())
}
fn setup_logging() -> Result<()> {
2019-06-15 12:58:17 +03:00
std::env::set_var("RUST_BACKTRACE", "short");
env_logger::try_init_from_env("RA_LOG")?;
2020-02-16 18:04:08 +01:00
ra_prof::init();
2019-08-31 14:47:37 +03:00
Ok(())
2018-08-10 17:49:45 +03:00
}
2018-11-08 18:43:02 +03:00
2019-08-31 14:47:37 +03:00
fn run_server() -> Result<()> {
log::info!("lifecycle: server started");
2019-08-30 20:18:57 +03:00
let (connection, io_threads) = Connection::stdio();
let (initialize_id, initialize_params) = connection.initialize_start()?;
let initialize_params =
from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?;
let server_capabilities = rust_analyzer::server_capabilities(&initialize_params.capabilities);
let initialize_result = lsp_types::InitializeResult {
capabilities: server_capabilities,
server_info: Some(lsp_types::ServerInfo {
name: String::from("rust-analyzer"),
2020-05-19 18:12:07 -04:00
version: Some(String::from(env!("REV"))),
}),
};
let initialize_result = serde_json::to_value(initialize_result).unwrap();
connection.initialize_finish(initialize_id, initialize_result)?;
2020-01-13 16:20:47 -05:00
if let Some(client_info) = initialize_params.client_info {
log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
}
2020-04-01 18:41:43 +02:00
let config = {
let root_path = match initialize_params
.root_uri
.and_then(|it| it.to_file_path().ok())
.and_then(|it| AbsPathBuf::try_from(it).ok())
{
Some(it) => it,
None => {
let cwd = std::env::current_dir()?;
AbsPathBuf::assert(cwd)
}
};
let mut config = Config::new(root_path);
if let Some(json) = initialize_params.initialization_options {
config.update(json);
2020-04-01 18:41:43 +02:00
}
config.update_caps(&initialize_params.capabilities);
if config.linked_projects.is_empty() {
let workspace_roots = initialize_params
.workspace_folders
.map(|workspaces| {
workspaces
.into_iter()
.filter_map(|it| it.uri.to_file_path().ok())
.filter_map(|it| AbsPathBuf::try_from(it).ok())
.collect::<Vec<_>>()
})
.filter(|workspaces| !workspaces.is_empty())
.unwrap_or_else(|| vec![config.root_path.clone()]);
config.linked_projects = ProjectManifest::discover_all(&workspace_roots)
.into_iter()
.map(LinkedProject::from)
.collect();
}
2020-04-01 18:41:43 +02:00
config
};
rust_analyzer::main_loop(config, connection)?;
2018-12-06 21:03:39 +03:00
log::info!("shutting down IO...");
io_threads.join()?;
2018-12-06 21:03:39 +03:00
log::info!("... IO is down");
2018-09-01 17:40:45 +03:00
Ok(())
2018-08-10 17:49:45 +03:00
}