From 21e6892d857f2dd57e5a8345ead6a86711dd250f Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 13 Aug 2018 19:27:41 +0200 Subject: [PATCH 1/7] Support external rustfmt --- src/actions/format.rs | 155 ++++++++++++++++++++++++++++++++++++++++ src/actions/mod.rs | 1 + src/actions/requests.rs | 51 ++++--------- src/config.rs | 5 ++ 4 files changed, 173 insertions(+), 39 deletions(-) create mode 100644 src/actions/format.rs diff --git a/src/actions/format.rs b/src/actions/format.rs new file mode 100644 index 00000000000..97f0a14968a --- /dev/null +++ b/src/actions/format.rs @@ -0,0 +1,155 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Code formatting using Rustfmt - by default using statically-linked one or +//! possibly running Rustfmt binary specified by the user. + +use std::env::temp_dir; +use std::fs::File; +use std::io::Write; +use std::path::{Path, PathBuf}; +use std::process::{Command, Stdio}; + +use rand::{Rng, thread_rng}; +use log::{log, debug}; +use rustfmt_nightly::{Config, Session, Input}; +use serde_json; + +struct External<'a>(&'a Path); +struct Internal; + +/// Formatter responsible for formatting the source code. +pub enum Rustfmt { + /// Path to external `rustfmt` + External(PathBuf), + /// Statically linked `rustfmt` + Internal +} + +impl From> for Rustfmt { + fn from(value: Option) -> Rustfmt { + match value { + Some(path) => Rustfmt::External(PathBuf::from(path)), + None => Rustfmt::Internal + } + } +} + + +pub trait Formatter { + fn format(&self, input: String, cfg: Config) -> Result; +} + +impl Formatter for External<'_> { + fn format(&self, input: String, cfg: Config) -> Result { + let rustfmt_path = self.0; + + let (_file, config_path) = gen_config_file(&cfg)?; + let args = rustfmt_args(&cfg, &config_path); + + let mut rustfmt = Command::new(rustfmt_path) + .args(args) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .map_err(|_| format!("Couldn't spawn `{}`", rustfmt_path.display()))?; + + { + let stdin = rustfmt.stdin.as_mut() + .ok_or_else(|| "Failed to open rustfmt stdin".to_string())?; + stdin.write_all(input.as_bytes()) + .map_err(|_| "Failed to pass input to rustfmt".to_string())?; + } + + rustfmt.wait_with_output() + .map_err(|err| format!("Error running rustfmt: {}", err)) + .and_then(|out| String::from_utf8(out.stdout) + .map_err(|_| "Formatted code is not valid UTF-8".to_string())) + } +} + +impl Formatter for Internal { + fn format(&self, input: String, config: Config) -> Result { + let mut buf = Vec::::new(); + + { + let mut session = Session::new(config, Some(&mut buf)); + + match session.format(Input::Text(input)) { + Ok(report) => { + // Session::format returns Ok even if there are any errors, i.e., parsing errors. + if session.has_operational_errors() || session.has_parsing_errors() { + debug!( + "reformat: format_input failed: has errors, report = {}", + report + ); + + return Err("Reformat failed to complete successfully".into()); + } + } + Err(e) => { + debug!("Reformat failed: {:?}", e); + + return Err("Reformat failed to complete successfully".into()); + } + } + } + + String::from_utf8(buf) + .map_err(|_| "Reformat output is not a valid UTF-8".into()) + } +} + +impl Formatter for Rustfmt { + fn format(&self, input: String, cfg: Config) -> Result { + match self { + Rustfmt::External(ref p) => External(p.as_path()).format(input, cfg), + Rustfmt::Internal => Internal.format(input, cfg), + } + } +} + +fn random_file() -> Result<(File, PathBuf), String> { + const SUFFIX_LEN: usize = 10; + + let suffix: String = thread_rng().gen_ascii_chars().take(SUFFIX_LEN).collect(); + let path = temp_dir().join(suffix); + + Ok(File::create(&path) + .map(|file| (file, path)) + .map_err(|_| "Config file could not be created".to_string())?) +} + +fn gen_config_file(config: &Config) -> Result<(File, PathBuf), String> { + let (mut file, path) = random_file()?; + let toml = config.used_options().to_toml()?; + file.write(toml.as_bytes()) + .map_err(|_| "Could not write config TOML file contents".to_string())?; + + Ok((file, path)) +} + +fn rustfmt_args(config: &Config, config_path: &Path) -> Vec { + let mut args = vec![ + "--unstable-features".into(), + "--skip-children".into(), + "--emit".into(), + "stdout".into(), + ]; + + args.push("--file-lines".into()); + let lines: String = serde_json::to_string(&config.file_lines()).unwrap(); + args.push(lines); + + args.push("--config-path".into()); + args.push(config_path.to_str().map(|x| x.to_string()).unwrap()); + + args +} diff --git a/src/actions/mod.rs b/src/actions/mod.rs index e2e4b0e32cb..2399d3ed6b6 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -66,6 +66,7 @@ pub mod progress; pub mod diagnostics; pub mod run; pub mod hover; +pub mod format; /// Persistent context shared across all requests and notifications. pub enum ActionContext { diff --git a/src/actions/requests.rs b/src/actions/requests.rs index e26ad4f9781..df5e03f09e6 100644 --- a/src/actions/requests.rs +++ b/src/actions/requests.rs @@ -15,13 +15,14 @@ use rls_data as data; use url::Url; use rls_vfs::{FileContents}; use racer; -use rustfmt_nightly::{Session, FileLines, FileName, Input as FmtInput, Range as RustfmtRange}; +use rustfmt_nightly::{FileLines, FileName, Range as RustfmtRange}; use serde_json; use rls_span as span; use itertools::Itertools; use serde_derive::{Serialize, Deserialize}; use log::{debug, log, trace}; +use crate::actions::format::{Rustfmt, Formatter}; use crate::actions::hover; use crate::actions::work_pool; use crate::actions::work_pool::WorkDescription; @@ -719,7 +720,7 @@ fn reformat( let path = parse_file_path!(&doc.uri, "reformat")?; let input = match ctx.vfs.load_file(&path) { - Ok(FileContents::Text(s)) => FmtInput::Text(s), + Ok(FileContents::Text(s)) => s, Ok(_) => { debug!("Reformat failed, found binary file"); return Err(ResponseError::Message( @@ -757,44 +758,14 @@ fn reformat( config.set().file_lines(file_lines); }; - let mut buf = Vec::::new(); + let rustfmt_path = ctx.config.lock().unwrap().rustfmt_path.clone(); + let formatter = Rustfmt::from(rustfmt_path); + let formatted_text = formatter.format(input, config) + .map_err(|msg| ResponseError::Message(ErrorCode::InternalError, msg))?; - { - let mut session = Session::new(config, Some(&mut buf)); - - match session.format(input) { - Ok(report) => { - // Session::format returns Ok even if there are any errors, i.e., parsing errors. - if session.has_operational_errors() || session.has_parsing_errors() { - debug!( - "reformat: format_input failed: has errors, report = {}", - report - ); - - return Err(ResponseError::Message( - ErrorCode::InternalError, - "Reformat failed to complete successfully".into(), - )); - } - } - Err(e) => { - debug!("Reformat failed: {:?}", e); - - return Err(ResponseError::Message( - ErrorCode::InternalError, - "Reformat failed to complete successfully".into(), - )); - } - }; - } + // Note that we don't need to update the VFS, the client echos back the + // change to us when it applies the returned TextEdit. - let text = String::from_utf8(buf).unwrap(); - - // Note that we don't need to update the VFS, the client - // echos back the change to us. - - // If Rustfmt returns range of text that changed, - // we will be able to pass only range of changed text to the client. if !ctx.quiescent.load(Ordering::SeqCst) { return Err(ResponseError::Message( ErrorCode::InternalError, @@ -802,10 +773,12 @@ fn reformat( )) } + // If Rustfmt returns range of text that changed, + // we will be able to pass only range of changed text to the client. Ok([ TextEdit { range: range_whole_file, - new_text: text, + new_text: formatted_text, }, ]) } diff --git a/src/config.rs b/src/config.rs index af7289ccc03..e31b45e4a57 100644 --- a/src/config.rs +++ b/src/config.rs @@ -157,6 +157,9 @@ pub struct Config { /// local variable declaration. When set to false, the content is only availabe when /// holding the `ctrl` key in some editors. pub show_hover_context: bool, + /// Use provided rustfmt binary instead of the statically linked one. + /// (requires unstable features) + pub rustfmt_path: Option, } impl Default for Config { @@ -185,6 +188,7 @@ impl Default for Config { clippy_preference: ClippyPreference::OptIn, full_docs: Inferrable::Inferred(false), show_hover_context: true, + rustfmt_path: None, }; result.normalise(); result @@ -221,6 +225,7 @@ impl Config { self.build_bin = Inferrable::Inferred(None); self.build_lib = Inferrable::Inferred(false); self.cfg_test = false; + self.rustfmt_path = None; } } From 97a8a6e60f7855f3bfc862cebd379f5b3cc8f92d Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 14 Aug 2018 15:38:37 +0200 Subject: [PATCH 2/7] Spawn external rustfmt at project root FIXME: It would be clean to support formatting options passed via Formatter:format() trait method rather than relying on it to 'just' work for now. --- Cargo.lock | 6 +++--- Cargo.toml | 3 +++ src/actions/format.rs | 45 +++++++++++++++++++++++++++-------------- src/actions/requests.rs | 5 +++-- 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1483bec7f2f..852d7654da4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1109,7 +1109,7 @@ dependencies = [ "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-vfs 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-workspace-hack 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfmt-nightly 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustfmt-nightly 0.99.2 (git+https://github.com/Xanewok/rustfmt?branch=file-lines-ser-json)", "serde 1.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1330,7 +1330,7 @@ dependencies = [ [[package]] name = "rustfmt-nightly" version = "0.99.2" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/Xanewok/rustfmt?branch=file-lines-ser-json#4604f46ce8fa5b80b2e47f845c8ed669e8e714ba" dependencies = [ "cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1859,7 +1859,7 @@ dependencies = [ "checksum rustc-workspace-hack 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc71d2faa173b74b232dedc235e3ee1696581bb132fc116fa3626d6151a1a8fb" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rustfix 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "756567f00f7d89c9f89a5c401b8b1caaa122e27240b9eaadd0bb52ee0b680b1b" -"checksum rustfmt-nightly 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)" = "56f5442163d82d1f2fb52dd8572e2ac40c1498a8b71964865d4fe464e93766d4" +"checksum rustfmt-nightly 0.99.2 (git+https://github.com/Xanewok/rustfmt?branch=file-lines-ser-json)" = "" "checksum ryu 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "16aa12da69951804cddf5f74d96abcc414a31b064e610dc81e37c1536082f491" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" "checksum schannel 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1fabf2a7b6483a141426e1afd09ad543520a77ac49bd03c286e7696ccfd77f" diff --git a/Cargo.toml b/Cargo.toml index be82ec29b26..2ce550026ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,9 @@ categories = ["development-tools"] build = "build.rs" +[patch.crates-io] +rustfmt-nightly = { git = "https://github.com/Xanewok/rustfmt", branch = "file-lines-ser-json" } + [dependencies] cargo = { git = "https://github.com/rust-lang/cargo", rev = "6a7672ef5344c1bb570610f2574250fbee932355" } cargo_metadata = "0.6" diff --git a/src/actions/format.rs b/src/actions/format.rs index 97f0a14968a..3e7f6edd899 100644 --- a/src/actions/format.rs +++ b/src/actions/format.rs @@ -22,21 +22,21 @@ use log::{log, debug}; use rustfmt_nightly::{Config, Session, Input}; use serde_json; -struct External<'a>(&'a Path); +struct External<'a>(&'a Path, &'a Path); struct Internal; -/// Formatter responsible for formatting the source code. +/// Specified which `rustfmt` to use. pub enum Rustfmt { - /// Path to external `rustfmt` - External(PathBuf), + /// (Path to external `rustfmt`, cwd where it should be spawned at) + External(PathBuf, PathBuf), /// Statically linked `rustfmt` Internal } -impl From> for Rustfmt { - fn from(value: Option) -> Rustfmt { +impl From> for Rustfmt { + fn from(value: Option<(String, PathBuf)>) -> Rustfmt { match value { - Some(path) => Rustfmt::External(PathBuf::from(path)), + Some((path, cwd)) => Rustfmt::External(PathBuf::from(path), cwd), None => Rustfmt::Internal } } @@ -49,17 +49,18 @@ pub trait Formatter { impl Formatter for External<'_> { fn format(&self, input: String, cfg: Config) -> Result { - let rustfmt_path = self.0; + let External(path, cwd) = self; - let (_file, config_path) = gen_config_file(&cfg)?; + let (_file_handle, config_path) = gen_config_file(&cfg)?; let args = rustfmt_args(&cfg, &config_path); - let mut rustfmt = Command::new(rustfmt_path) + let mut rustfmt = Command::new(path) .args(args) + .current_dir(cwd) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn() - .map_err(|_| format!("Couldn't spawn `{}`", rustfmt_path.display()))?; + .map_err(|_| format!("Couldn't spawn `{}`", path.display()))?; { let stdin = rustfmt.stdin.as_mut() @@ -110,12 +111,15 @@ impl Formatter for Internal { impl Formatter for Rustfmt { fn format(&self, input: String, cfg: Config) -> Result { match self { - Rustfmt::External(ref p) => External(p.as_path()).format(input, cfg), Rustfmt::Internal => Internal.format(input, cfg), + Rustfmt::External(path, cwd) => { + External(path.as_path(), cwd.as_path()).format(input, cfg) + } } } } +#[allow(dead_code)] fn random_file() -> Result<(File, PathBuf), String> { const SUFFIX_LEN: usize = 10; @@ -127,6 +131,7 @@ fn random_file() -> Result<(File, PathBuf), String> { .map_err(|_| "Config file could not be created".to_string())?) } +#[allow(dead_code)] fn gen_config_file(config: &Config) -> Result<(File, PathBuf), String> { let (mut file, path) = random_file()?; let toml = config.used_options().to_toml()?; @@ -136,20 +141,30 @@ fn gen_config_file(config: &Config) -> Result<(File, PathBuf), String> { Ok((file, path)) } +#[allow(unused_variables)] fn rustfmt_args(config: &Config, config_path: &Path) -> Vec { let mut args = vec![ "--unstable-features".into(), "--skip-children".into(), "--emit".into(), "stdout".into(), + "--quiet".into(), ]; args.push("--file-lines".into()); - let lines: String = serde_json::to_string(&config.file_lines()).unwrap(); + let file_lines_json = config.file_lines().to_json_spans(); + let lines: String = serde_json::to_string(&file_lines_json).unwrap(); args.push(lines); - args.push("--config-path".into()); - args.push(config_path.to_str().map(|x| x.to_string()).unwrap()); + // We will spawn Rustfmt at the project directory and so it should pick up + // appropriate config file on its own. + // FIXME: Since in format request handling we modify some of the config and + // pass it via `Formatter::format()`, we should ideally fix `gen_config_file` + // and make it so that `used_options()` will give accurate TOML + // representation for the current format request. + + // args.push("--config-path".into()); + // args.push(config_path.to_str().map(|x| x.to_string()).unwrap()); args } diff --git a/src/actions/requests.rs b/src/actions/requests.rs index df5e03f09e6..75afcccc71e 100644 --- a/src/actions/requests.rs +++ b/src/actions/requests.rs @@ -758,8 +758,9 @@ fn reformat( config.set().file_lines(file_lines); }; - let rustfmt_path = ctx.config.lock().unwrap().rustfmt_path.clone(); - let formatter = Rustfmt::from(rustfmt_path); + let rustfmt = ctx.config.lock().unwrap().rustfmt_path.clone() + .map(|path| (path, ctx.current_project.clone())); + let formatter = Rustfmt::from(rustfmt); let formatted_text = formatter.format(input, config) .map_err(|msg| ResponseError::Message(ErrorCode::InternalError, msg))?; From 98632d83363985302cd296c3e51379bd635e0932 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 14 Aug 2018 17:05:39 +0200 Subject: [PATCH 3/7] Use Formatter interface in hover --- src/actions/format.rs | 1 + src/actions/hover.rs | 131 ++++++++++++++++++---------------------- src/actions/mod.rs | 11 ++++ src/actions/requests.rs | 7 +-- 4 files changed, 74 insertions(+), 76 deletions(-) diff --git a/src/actions/format.rs b/src/actions/format.rs index 3e7f6edd899..d3ca3956762 100644 --- a/src/actions/format.rs +++ b/src/actions/format.rs @@ -26,6 +26,7 @@ struct External<'a>(&'a Path, &'a Path); struct Internal; /// Specified which `rustfmt` to use. +#[derive(Clone)] pub enum Rustfmt { /// (Path to external `rustfmt`, cwd where it should be spawned at) External(PathBuf, PathBuf), diff --git a/src/actions/hover.rs b/src/actions/hover.rs index b7773c9e577..faaad546734 100644 --- a/src/actions/hover.rs +++ b/src/actions/hover.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use crate::actions::format::{Rustfmt, Formatter}; use crate::actions::requests; use crate::actions::InitActionContext; use crate::config::FmtConfig; @@ -18,7 +19,7 @@ use racer; use rls_analysis::{Def, DefKind}; use rls_span::{Column, Row, Span, ZeroIndexed}; use rls_vfs::{self as vfs, Vfs}; -use rustfmt_nightly::{Session as FmtSession, Input as FmtInput, NewlineStyle}; +use rustfmt_nightly::NewlineStyle; use std::path::{Path, PathBuf}; use log::*; @@ -327,6 +328,7 @@ fn tooltip_struct_enum_union_trait( let vfs = ctx.vfs.clone(); let fmt_config = ctx.fmt_config(); + let fmt = ctx.formatter(); // fallback in case source extration fails let the_type = || match def.kind { @@ -339,7 +341,7 @@ fn tooltip_struct_enum_union_trait( let decl = def_decl(def, &vfs, the_type); - let the_type = format_object(&fmt_config, decl); + let the_type = format_object(fmt.clone(), &fmt_config, decl); let docs = def_docs(def, &vfs); let context = None; @@ -380,6 +382,7 @@ fn tooltip_function_method( let vfs = ctx.vfs.clone(); let fmt_config = ctx.fmt_config(); + let fmt = ctx.formatter(); let the_type = || { def.value @@ -391,7 +394,7 @@ fn tooltip_function_method( let decl = def_decl(def, &vfs, the_type); - let the_type = format_method(&fmt_config, decl); + let the_type = format_method(fmt.clone(), &fmt_config, decl); let docs = def_docs(def, &vfs); let context = None; @@ -725,7 +728,7 @@ fn racer_def(ctx: &InitActionContext, span: &Span) -> Option { /// Formats a struct, enum, union, or trait. The original type is returned /// in the event of an error. -fn format_object(fmt_config: &FmtConfig, the_type: String) -> String { +fn format_object(rustfmt: Rustfmt, fmt_config: &FmtConfig, the_type: String) -> String { debug!("format_object: {}", the_type); let mut config = fmt_config.get_rustfmt_config().clone(); config.set().newline_style(NewlineStyle::Unix); @@ -743,21 +746,11 @@ fn format_object(fmt_config: &FmtConfig, the_type: String) -> String { format!("{}{{}}", trimmed) }; - let mut out = Vec::::with_capacity(the_type.len()); - let input = FmtInput::Text(object.clone()); - let mut session = FmtSession::new(config, Some(&mut out)); - let formatted = match session.format(input) { - Ok(_) => { - let utf8 = session.out - .as_ref() - .map(|out| String::from_utf8(out.to_vec())) - .unwrap_or_else(|| Ok(trimmed.to_string())); - match utf8.map(|lines| (lines.rfind('{'), lines)) { - Ok((Some(pos), lines)) => lines[0..pos].into(), - Ok((None, lines)) => lines, - _ => trimmed.into(), - } - } + let formatted = match rustfmt.format(object.clone(), config) { + Ok(lines) => match lines.rfind('{') { + Some(pos) => lines[0..pos].into(), + None => lines, + }, Err(e) => { error!("format_object: error: {:?}, input: {:?}", e, object); trimmed.to_string() @@ -802,44 +795,37 @@ fn format_object(fmt_config: &FmtConfig, the_type: String) -> String { /// Formats a method or function. The original type is returned /// in the event of an error. -fn format_method(fmt_config: &FmtConfig, the_type: String) -> String { +fn format_method(rustfmt: Rustfmt, fmt_config: &FmtConfig, the_type: String) -> String { trace!("format_method: {}", the_type); let the_type = the_type.trim().trim_right_matches(';').to_string(); + let mut config = fmt_config.get_rustfmt_config().clone(); config.set().newline_style(NewlineStyle::Unix); let tab_spaces = config.tab_spaces(); - let method = format!("impl Dummy {{ {} {{ unimplmented!() }} }}", the_type); - let mut out = Vec::::with_capacity(the_type.len()); - let input = FmtInput::Text(method.clone()); - let mut session = FmtSession::new(config, Some(&mut out)); - let result = match session.format(input) { - Ok(_) => { - let lines = session.out - .as_ref() - .map(|out| String::from_utf8(out.to_vec())); - if let Some(Ok(mut lines)) = lines { - if let Some(front_pos) = lines.find('{') { - lines = lines[front_pos..].chars().skip(1).collect(); - } - if let Some(back_pos) = lines.rfind('{') { - lines = lines[0..back_pos].into(); - } - lines - .lines() - .filter(|line| line.trim() != "") - .map(|line| { - let mut spaces = tab_spaces + 1; - let should_trim = |c: char| { - spaces = spaces.saturating_sub(1); - spaces > 0 && c.is_whitespace() - }; - let line = line.trim_left_matches(should_trim); - format!("{}\n", line) - }) - .collect() - } else { - the_type + + let method = format!("impl Dummy {{ {} {{ unimplemented!() }} }}", the_type); + + let result = match rustfmt.format(method.clone(), config) { + Ok(mut lines) => { + if let Some(front_pos) = lines.find('{') { + lines = lines[front_pos..].chars().skip(1).collect(); } + if let Some(back_pos) = lines.rfind('{') { + lines = lines[0..back_pos].into(); + } + lines + .lines() + .filter(|line| line.trim() != "") + .map(|line| { + let mut spaces = tab_spaces + 1; + let should_trim = |c: char| { + spaces = spaces.saturating_sub(1); + spaces > 0 && c.is_whitespace() + }; + let line = line.trim_left_matches(should_trim); + format!("{}\n", line) + }) + .collect() } Err(e) => { error!("format_method: error: {:?}, input: {:?}", e, method); @@ -947,6 +933,7 @@ pub fn tooltip( pub mod test { use super::*; + use crate::actions::format::Rustfmt; use crate::build::BuildPriority; use crate::config; use crate::lsp_data::{ClientCapabilities, InitializationOptions}; @@ -1479,25 +1466,26 @@ pub mod test { #[test] fn test_format_method() { + let fmt = Rustfmt::Internal; let config = &FmtConfig::default(); let input = "fn foo() -> ()"; - let result = format_method(config, input.into()); + let result = format_method(fmt.clone(), config, input.into()); assert_eq!(input, &result, "function explicit void return"); let input = "fn foo()"; let expected = "fn foo()"; - let result = format_method(config, input.into()); + let result = format_method(fmt.clone(), config, input.into()); assert_eq!(expected, &result, "function"); let input = "fn foo() -> Thing"; let expected = "fn foo() -> Thing"; - let result = format_method(config, input.into()); + let result = format_method(fmt.clone(), config, input.into()); assert_eq!(expected, &result, "function with return"); let input = "fn foo(&self);"; let expected = "fn foo(&self)"; - let result = format_method(config, input.into()); + let result = format_method(fmt.clone(), config, input.into()); assert_eq!(expected, &result, "method"); let input = "fn foo(t: T) where T: Copy"; @@ -1508,7 +1496,7 @@ pub mod test { T: Copy, ", ); - let result = format_method(config, input.into()); + let result = format_method(fmt.clone(), config, input.into()); assert_eq!(expected, result, "function with generic parameters"); let input = "fn foo(&self, t: T) where T: Copy"; @@ -1519,7 +1507,7 @@ pub mod test { T: Copy, ", ); - let result = format_method(config, input.into()); + let result = format_method(fmt.clone(), config, input.into()); assert_eq!(expected, result, "method with type parameters"); let input = noindent( @@ -1538,7 +1526,7 @@ pub mod test { T: Copy, ", ); - let result = format_method(config, input); + let result = format_method(fmt.clone(), config, input); assert_eq!( expected, result, "method with type parameters; corrected spacing" @@ -1556,7 +1544,7 @@ pub mod test { ) -> Thing ", ); - let result = format_method(config, input.into()); + let result = format_method(fmt.clone(), config, input.into()); assert_eq!(expected, result, "long function signature"); let input = "fn really_really_really_really_long_name(&self, foo_thing: String, bar_thing: Thing, baz_thing: Vec, foo_other: u32, bar_other: i32) -> Thing"; @@ -1572,7 +1560,7 @@ pub mod test { ) -> Thing ", ); - let result = format_method(config, input.into()); + let result = format_method(fmt.clone(), config, input.into()); assert_eq!(expected, result, "long method signature with generic"); let input = noindent( @@ -1595,7 +1583,7 @@ pub mod test { ) ", ); - let result = format_method(config, input); + let result = format_method(fmt.clone(), config, input); assert_eq!(expected, result, "function with multiline args"); } @@ -1697,57 +1685,58 @@ pub mod test { #[test] fn test_format_object() { + let fmt = Rustfmt::Internal; let config = &FmtConfig::default(); let input = "pub struct Box(Unique);"; - let result = format_object(config, input.into()); + let result = format_object(fmt.clone(), config, input.into()); assert_eq!( "pub struct Box", &result, "tuple struct with all private fields has hidden components" ); let input = "pub struct Thing(pub u32);"; - let result = format_object(config, input.into()); + let result = format_object(fmt.clone(), config, input.into()); assert_eq!( "pub struct Thing(pub u32)", &result, "tuple struct with trailing ';' from racer" ); let input = "pub struct Thing(pub u32)"; - let result = format_object(config, input.into()); + let result = format_object(fmt.clone(), config, input.into()); assert_eq!("pub struct Thing(pub u32)", &result, "pub tuple struct"); let input = "pub struct Thing(pub u32, i32)"; - let result = format_object(config, input.into()); + let result = format_object(fmt.clone(), config, input.into()); assert_eq!( "pub struct Thing(pub u32, _)", &result, "non-pub components of pub tuples should be hidden" ); let input = "struct Thing(u32, i32)"; - let result = format_object(config, input.into()); + let result = format_object(fmt.clone(), config, input.into()); assert_eq!( "struct Thing(u32, i32)", &result, "private tuple struct may show private components" ); let input = "pub struct Thing"; - let result = format_object(config, input.into()); + let result = format_object(fmt.clone(), config, input.into()); assert_eq!("pub struct Thing", &result, "pub struct"); let input = "pub struct Thing {"; - let result = format_object(config, input.into()); + let result = format_object(fmt.clone(), config, input.into()); assert_eq!( "pub struct Thing", &result, "pub struct with trailing '{{' from racer" ); let input = "pub struct Thing { x: i32 }"; - let result = format_object(config, input.into()); + let result = format_object(fmt.clone(), config, input.into()); assert_eq!("pub struct Thing", &result, "pub struct with body"); let input = "pub enum Foobar { Foo, Bar }"; - let result = format_object(config, input.into()); + let result = format_object(fmt.clone(), config, input.into()); assert_eq!("pub enum Foobar", &result, "pub enum with body"); let input = "pub trait Thing where T: Copy + Sized, U: Clone"; @@ -1759,7 +1748,7 @@ pub mod test { U: Clone, ", ); - let result = format_object(config, input.into()); + let result = format_object(fmt.clone(), config, input.into()); assert_eq!(expected, result, "trait with where clause"); } diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 2399d3ed6b6..de398d3d0df 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -22,6 +22,7 @@ use crate::Span; use walkdir::WalkDir; use log::{debug, log, trace, error, info}; +use crate::actions::format::Rustfmt; use crate::actions::post_build::{BuildResults, PostBuildHandler, AnalysisQueue}; use crate::actions::progress::{BuildProgressNotifier, BuildDiagnosticsNotifier}; use crate::build::*; @@ -269,6 +270,16 @@ impl InitActionContext { racer::Session::with_project_model(cache, pm) } + /// Since external Rustfmt can be specified, this returns an enum specifying + /// which one to use and which implements the String-formatting `Formatter` + /// trait. + fn formatter(&self) -> Rustfmt { + let rustfmt = self.config.lock().unwrap().rustfmt_path.clone() + .map(|path| (path, self.current_project.clone())); + + Rustfmt::from(rustfmt) + } + fn fmt_config(&self) -> FmtConfig { FmtConfig::from(&self.current_project) } diff --git a/src/actions/requests.rs b/src/actions/requests.rs index 75afcccc71e..f55b9fd2814 100644 --- a/src/actions/requests.rs +++ b/src/actions/requests.rs @@ -22,7 +22,7 @@ use itertools::Itertools; use serde_derive::{Serialize, Deserialize}; use log::{debug, log, trace}; -use crate::actions::format::{Rustfmt, Formatter}; +use crate::actions::format::Formatter; use crate::actions::hover; use crate::actions::work_pool; use crate::actions::work_pool::WorkDescription; @@ -758,10 +758,7 @@ fn reformat( config.set().file_lines(file_lines); }; - let rustfmt = ctx.config.lock().unwrap().rustfmt_path.clone() - .map(|path| (path, ctx.current_project.clone())); - let formatter = Rustfmt::from(rustfmt); - let formatted_text = formatter.format(input, config) + let formatted_text = ctx.formatter().format(input, config) .map_err(|msg| ResponseError::Message(ErrorCode::InternalError, msg))?; // Note that we don't need to update the VFS, the client echos back the From 92ade8b0c72c6c9188b546aea616c61ed0e519b8 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 14 Aug 2018 17:34:58 +0200 Subject: [PATCH 4/7] Respect config when formatting with external Rustfmt --- src/actions/format.rs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/actions/format.rs b/src/actions/format.rs index d3ca3956762..0010961515f 100644 --- a/src/actions/format.rs +++ b/src/actions/format.rs @@ -120,7 +120,6 @@ impl Formatter for Rustfmt { } } -#[allow(dead_code)] fn random_file() -> Result<(File, PathBuf), String> { const SUFFIX_LEN: usize = 10; @@ -132,17 +131,15 @@ fn random_file() -> Result<(File, PathBuf), String> { .map_err(|_| "Config file could not be created".to_string())?) } -#[allow(dead_code)] fn gen_config_file(config: &Config) -> Result<(File, PathBuf), String> { let (mut file, path) = random_file()?; - let toml = config.used_options().to_toml()?; + let toml = config.all_options().to_toml()?; file.write(toml.as_bytes()) .map_err(|_| "Could not write config TOML file contents".to_string())?; Ok((file, path)) } -#[allow(unused_variables)] fn rustfmt_args(config: &Config, config_path: &Path) -> Vec { let mut args = vec![ "--unstable-features".into(), @@ -157,15 +154,8 @@ fn rustfmt_args(config: &Config, config_path: &Path) -> Vec { let lines: String = serde_json::to_string(&file_lines_json).unwrap(); args.push(lines); - // We will spawn Rustfmt at the project directory and so it should pick up - // appropriate config file on its own. - // FIXME: Since in format request handling we modify some of the config and - // pass it via `Formatter::format()`, we should ideally fix `gen_config_file` - // and make it so that `used_options()` will give accurate TOML - // representation for the current format request. - - // args.push("--config-path".into()); - // args.push(config_path.to_str().map(|x| x.to_string()).unwrap()); + args.push("--config-path".into()); + args.push(config_path.to_str().map(|x| x.to_string()).unwrap()); args } From f5710b0130644cfe709e10cf3c79b107c9f6685a Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Thu, 16 Aug 2018 02:39:33 +0200 Subject: [PATCH 5/7] Use internal Rustfmt for hover tooltips External ones have to create temporary files to pass configs and whatnot and we can technically issue a lot of these hover requests fast - these will be short and the exact formatting does not matter, so we'll just use the internal one instead. --- src/actions/hover.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/actions/hover.rs b/src/actions/hover.rs index faaad546734..54182b95a44 100644 --- a/src/actions/hover.rs +++ b/src/actions/hover.rs @@ -328,7 +328,8 @@ fn tooltip_struct_enum_union_trait( let vfs = ctx.vfs.clone(); let fmt_config = ctx.fmt_config(); - let fmt = ctx.formatter(); + // We hover often so use the in-process one to speed things up + let fmt = Rustfmt::Internal; // fallback in case source extration fails let the_type = || match def.kind { @@ -341,7 +342,7 @@ fn tooltip_struct_enum_union_trait( let decl = def_decl(def, &vfs, the_type); - let the_type = format_object(fmt.clone(), &fmt_config, decl); + let the_type = format_object(fmt, &fmt_config, decl); let docs = def_docs(def, &vfs); let context = None; @@ -382,7 +383,8 @@ fn tooltip_function_method( let vfs = ctx.vfs.clone(); let fmt_config = ctx.fmt_config(); - let fmt = ctx.formatter(); + // We hover often so use the in-process one to speed things up + let fmt = Rustfmt::Internal; let the_type = || { def.value @@ -394,7 +396,7 @@ fn tooltip_function_method( let decl = def_decl(def, &vfs, the_type); - let the_type = format_method(fmt.clone(), &fmt_config, decl); + let the_type = format_method(fmt, &fmt_config, decl); let docs = def_docs(def, &vfs); let context = None; From 3dc459200c7fbdff3d1852dc11adb65f1b4f6906 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Fri, 24 Aug 2018 15:03:48 +0200 Subject: [PATCH 6/7] Replace `Formatter` trait with inherent impl --- src/actions/format.rs | 110 +++++++++++++++++----------------------- src/actions/hover.rs | 2 +- src/actions/mod.rs | 6 +-- src/actions/requests.rs | 1 - 4 files changed, 51 insertions(+), 68 deletions(-) diff --git a/src/actions/format.rs b/src/actions/format.rs index 0010961515f..9c2a0fb0ff4 100644 --- a/src/actions/format.rs +++ b/src/actions/format.rs @@ -22,9 +22,6 @@ use log::{log, debug}; use rustfmt_nightly::{Config, Session, Input}; use serde_json; -struct External<'a>(&'a Path, &'a Path); -struct Internal; - /// Specified which `rustfmt` to use. #[derive(Clone)] pub enum Rustfmt { @@ -43,81 +40,68 @@ impl From> for Rustfmt { } } - -pub trait Formatter { - fn format(&self, input: String, cfg: Config) -> Result; -} - -impl Formatter for External<'_> { - fn format(&self, input: String, cfg: Config) -> Result { - let External(path, cwd) = self; - - let (_file_handle, config_path) = gen_config_file(&cfg)?; - let args = rustfmt_args(&cfg, &config_path); - - let mut rustfmt = Command::new(path) - .args(args) - .current_dir(cwd) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .map_err(|_| format!("Couldn't spawn `{}`", path.display()))?; - - { - let stdin = rustfmt.stdin.as_mut() - .ok_or_else(|| "Failed to open rustfmt stdin".to_string())?; - stdin.write_all(input.as_bytes()) - .map_err(|_| "Failed to pass input to rustfmt".to_string())?; +impl Rustfmt { + pub fn format(&self, input: String, cfg: Config) -> Result { + match self { + Rustfmt::Internal => format_internal(input, cfg), + Rustfmt::External(path, cwd) => format_external(path, cwd, input, cfg), } - - rustfmt.wait_with_output() - .map_err(|err| format!("Error running rustfmt: {}", err)) - .and_then(|out| String::from_utf8(out.stdout) - .map_err(|_| "Formatted code is not valid UTF-8".to_string())) } } -impl Formatter for Internal { - fn format(&self, input: String, config: Config) -> Result { - let mut buf = Vec::::new(); +fn format_external(path: &PathBuf, cwd: &PathBuf, input: String, cfg: Config) -> Result { + let (_file_handle, config_path) = gen_config_file(&cfg)?; + let args = rustfmt_args(&cfg, &config_path); + + let mut rustfmt = Command::new(path) + .args(args) + .current_dir(cwd) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .map_err(|_| format!("Couldn't spawn `{}`", path.display()))?; + + { + let stdin = rustfmt.stdin.as_mut() + .ok_or_else(|| "Failed to open rustfmt stdin".to_string())?; + stdin.write_all(input.as_bytes()) + .map_err(|_| "Failed to pass input to rustfmt".to_string())?; + } + + rustfmt.wait_with_output() + .map_err(|err| format!("Error running rustfmt: {}", err)) + .and_then(|out| String::from_utf8(out.stdout) + .map_err(|_| "Formatted code is not valid UTF-8".to_string())) +} - { - let mut session = Session::new(config, Some(&mut buf)); +fn format_internal(input: String, config:Config) -> Result { + let mut buf = Vec::::new(); - match session.format(Input::Text(input)) { - Ok(report) => { - // Session::format returns Ok even if there are any errors, i.e., parsing errors. - if session.has_operational_errors() || session.has_parsing_errors() { - debug!( - "reformat: format_input failed: has errors, report = {}", - report - ); + { + let mut session = Session::new(config, Some(&mut buf)); - return Err("Reformat failed to complete successfully".into()); - } - } - Err(e) => { - debug!("Reformat failed: {:?}", e); + match session.format(Input::Text(input)) { + Ok(report) => { + // Session::format returns Ok even if there are any errors, i.e., parsing errors. + if session.has_operational_errors() || session.has_parsing_errors() { + debug!( + "reformat: format_input failed: has errors, report = {}", + report + ); return Err("Reformat failed to complete successfully".into()); } } - } - - String::from_utf8(buf) - .map_err(|_| "Reformat output is not a valid UTF-8".into()) - } -} + Err(e) => { + debug!("Reformat failed: {:?}", e); -impl Formatter for Rustfmt { - fn format(&self, input: String, cfg: Config) -> Result { - match self { - Rustfmt::Internal => Internal.format(input, cfg), - Rustfmt::External(path, cwd) => { - External(path.as_path(), cwd.as_path()).format(input, cfg) + return Err("Reformat failed to complete successfully".into()); } } } + + String::from_utf8(buf) + .map_err(|_| "Reformat output is not a valid UTF-8".into()) } fn random_file() -> Result<(File, PathBuf), String> { diff --git a/src/actions/hover.rs b/src/actions/hover.rs index 54182b95a44..8be71968687 100644 --- a/src/actions/hover.rs +++ b/src/actions/hover.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use crate::actions::format::{Rustfmt, Formatter}; +use crate::actions::format::Rustfmt; use crate::actions::requests; use crate::actions::InitActionContext; use crate::config::FmtConfig; diff --git a/src/actions/mod.rs b/src/actions/mod.rs index de398d3d0df..12e2eb65e8a 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -270,9 +270,9 @@ impl InitActionContext { racer::Session::with_project_model(cache, pm) } - /// Since external Rustfmt can be specified, this returns an enum specifying - /// which one to use and which implements the String-formatting `Formatter` - /// trait. + /// Depending on user configuration, we might use either external Rustfmt or + /// the one we're shipping with. + /// Locks config to read `rustfmt_path` key. fn formatter(&self) -> Rustfmt { let rustfmt = self.config.lock().unwrap().rustfmt_path.clone() .map(|path| (path, self.current_project.clone())); diff --git a/src/actions/requests.rs b/src/actions/requests.rs index f55b9fd2814..67d69edb44c 100644 --- a/src/actions/requests.rs +++ b/src/actions/requests.rs @@ -22,7 +22,6 @@ use itertools::Itertools; use serde_derive::{Serialize, Deserialize}; use log::{debug, log, trace}; -use crate::actions::format::Formatter; use crate::actions::hover; use crate::actions::work_pool; use crate::actions::work_pool::WorkDescription; From fe62a7cebb88004f9ae361d94d1f9fb8b5ea454f Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 27 Aug 2018 17:15:00 +0200 Subject: [PATCH 7/7] Use upstream Rustfmt 0.99.4 Also bump Racer to use single version of rustc-ap-* libs (v370) --- Cargo.lock | 99 ++++++++++++++++++++++++++++-------------------------- Cargo.toml | 7 ++-- 2 files changed, 54 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 852d7654da4..102c7550424 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -260,7 +260,7 @@ dependencies = [ "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -912,7 +912,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -979,7 +979,7 @@ dependencies = [ [[package]] name = "racer" -version = "2.1.4" +version = "2.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -990,7 +990,7 @@ dependencies = [ "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1099,7 +1099,7 @@ dependencies = [ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "racer 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "racer 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "rls-analysis 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1109,7 +1109,7 @@ dependencies = [ "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-vfs 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-workspace-hack 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfmt-nightly 0.99.2 (git+https://github.com/Xanewok/rustfmt?branch=file-lines-ser-json)", + "rustfmt-nightly 0.99.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1173,15 +1173,15 @@ dependencies = [ [[package]] name = "rustc-ap-arena" -version = "218.0.0" +version = "237.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-ap-rustc_data_structures 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-rustc_cratesio_shim" -version = "218.0.0" +version = "237.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1190,7 +1190,7 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_data_structures" -version = "218.0.0" +version = "237.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1198,67 +1198,72 @@ dependencies = [ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_cratesio_shim 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-rustc_errors" -version = "218.0.0" +version = "237.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-rustc_target" -version = "218.0.0" +version = "237.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_cratesio_shim 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-serialize" -version = "218.0.0" +version = "237.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "rustc-ap-syntax" -version = "218.0.0" +version = "237.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_errors 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_target 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_errors 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_target 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-syntax_pos" -version = "218.0.0" +version = "237.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-arena 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-arena 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1329,8 +1334,8 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "0.99.2" -source = "git+https://github.com/Xanewok/rustfmt?branch=file-lines-ser-json#4604f46ce8fa5b80b2e47f845c8ed669e8e714ba" +version = "0.99.4" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1342,9 +1347,9 @@ dependencies = [ "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_target 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_target 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.71 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1439,7 +1444,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "smallvec" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1826,7 +1831,7 @@ dependencies = [ "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" "checksum quote 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ed7d650913520df631972f21e104a4fa2f9c82a14afc65d17b388a2e29731e7c" -"checksum racer 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "dcbc5ababaffee8d8f34910f925287c8f716b1ead48561c4278a152d08264f7c" +"checksum racer 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4bc3847329b20ff5ba56c298938c179ae9911af15c9c10553f683b65164533" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" @@ -1843,14 +1848,14 @@ dependencies = [ "checksum rls-rustc 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9dba7390427aefa953608429701e3665192ca810ba8ae09301e001b7c7bed0" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" "checksum rls-vfs 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ecbc8541b4c341d6271eae10f869dd9d36db871afe184f5b6f9bffbd6ed0373f" -"checksum rustc-ap-arena 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e905467184ce31ccdbd33ac33b9ba377f8cc7aefb340a733ab7e5efe34cddda" -"checksum rustc-ap-rustc_cratesio_shim 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a1a45817e78d0c1e2800fb933c526747ef2c5ee4b2dc0946e0c2d901329b88" -"checksum rustc-ap-rustc_data_structures 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4e9e5588883318e0e58bb7ea7cde2a66eaca55b25e32908f0982365988657" -"checksum rustc-ap-rustc_errors 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d233c0d9beda42a52d329a5df865c8f20c64773d2ab7aa6b4ae4248bacf3188" -"checksum rustc-ap-rustc_target 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eec0bc13feecf9e88e39439b24b4b3ca54db8caf12fb7172d0c430451c8b377c" -"checksum rustc-ap-serialize 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffcfb1102cd7cbf5f25c008a00f7253427af9dfac8989ede48c19bd47f556893" -"checksum rustc-ap-syntax 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a2ca0ef078a735c81a0d33589e04148dcf41f80ee7ebe30e72904a631b7c669" -"checksum rustc-ap-syntax_pos 218.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1bbd31d1bbc7210983c3bbbcb9ee35bac443c6c899f979b8114e58bb7101c28" +"checksum rustc-ap-arena 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d24c8b3c1437fad023cb9472381216a1d41d82dbb2d2e6c7858bd6f50317719" +"checksum rustc-ap-rustc_cratesio_shim 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c5b02c76cd1ee4e9c97c8228701796d6b7431e8f100dea2d8af1d6c2c2bad56" +"checksum rustc-ap-rustc_data_structures 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4076388154497fb9a007e3badd78e415402a5594111cd6bc7ce1420dd1b1818b" +"checksum rustc-ap-rustc_errors 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6c11e4789cbc276ceaa87d326c234b1a2d1e0fe6017b88a8a25903200060acb" +"checksum rustc-ap-rustc_target 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "25f711bb152b9d7cdd69410cfe6d99aeb1409c959e0fdf3c8ca4d220e568aa52" +"checksum rustc-ap-serialize 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57638db658d4942d3f30a12566836f9a67a636ed8002c8cae1c9231214e39929" +"checksum rustc-ap-syntax 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6dbcf07abf7a9957dce8d34353d55dfb4cd882153181f24349f4690facb58f0" +"checksum rustc-ap-syntax_pos 237.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0915cb5e166cabe588a129dec2d47357077e96fb1f9b57318fbe217eac4ce508" "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" "checksum rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6d5a683c6ba4ed37959097e88d71c9e8e26659a3cb5be8b389078e7ad45306" @@ -1859,7 +1864,7 @@ dependencies = [ "checksum rustc-workspace-hack 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc71d2faa173b74b232dedc235e3ee1696581bb132fc116fa3626d6151a1a8fb" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rustfix 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "756567f00f7d89c9f89a5c401b8b1caaa122e27240b9eaadd0bb52ee0b680b1b" -"checksum rustfmt-nightly 0.99.2 (git+https://github.com/Xanewok/rustfmt?branch=file-lines-ser-json)" = "" +"checksum rustfmt-nightly 0.99.4 (registry+https://github.com/rust-lang/crates.io-index)" = "df2124994af9da1062649cf5ac3738ae8c1bc292153e991b39a98904e342b7a7" "checksum ryu 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "16aa12da69951804cddf5f74d96abcc414a31b064e610dc81e37c1536082f491" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" "checksum schannel 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1fabf2a7b6483a141426e1afd09ad543520a77ac49bd03c286e7696ccfd77f" @@ -1872,7 +1877,7 @@ dependencies = [ "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142" "checksum serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae" "checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9" -"checksum smallvec 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "211a489e65e94b103926d2054ae515a1cdb5d515ea0ef414fee23b7e043ce748" +"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" "checksum socket2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "962a516af4d3a7c272cb3a1d50a8cc4e5b41802e4ad54cfb7bee8ba61d37d703" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" diff --git a/Cargo.toml b/Cargo.toml index 2ce550026ee..e7ff825c13a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,6 @@ categories = ["development-tools"] build = "build.rs" -[patch.crates-io] -rustfmt-nightly = { git = "https://github.com/Xanewok/rustfmt", branch = "file-lines-ser-json" } - [dependencies] cargo = { git = "https://github.com/rust-lang/cargo", rev = "6a7672ef5344c1bb570610f2574250fbee932355" } cargo_metadata = "0.6" @@ -27,7 +24,7 @@ languageserver-types = "0.45" lazy_static = "1" log = "0.4" num_cpus = "1" -racer = { version = "2.1.4", default-features = false } +racer = { version = "2.1.5", default-features = false } rayon = "1" rls-analysis = "0.16" rls-blacklist = "0.1.2" @@ -35,7 +32,7 @@ rls-data = { version = "0.18", features = ["serialize-serde"] } rls-rustc = "0.5.0" rls-span = { version = "0.4", features = ["serialize-serde"] } rls-vfs = "0.4.6" -rustfmt-nightly = "0.99.2" +rustfmt-nightly = "0.99.4" serde = "1.0" serde_json = "1.0" serde_derive = "1.0"