mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 13:48:50 +00:00
Merge #3199
3199: Use anyhow r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
64755b5e1f
6 changed files with 232 additions and 182 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -945,6 +945,7 @@ dependencies = [
|
|||
name = "ra_cli"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"crossbeam-channel",
|
||||
"env_logger",
|
||||
"itertools",
|
||||
|
|
|
@ -13,6 +13,7 @@ log = "0.4.5"
|
|||
pico-args = "0.3.0"
|
||||
rand = { version = "0.7.0", features = ["small_rng"] }
|
||||
rustc-hash = "1.0"
|
||||
anyhow = "1.0"
|
||||
|
||||
hir = { path = "../ra_hir", package = "ra_hir" }
|
||||
hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
|
||||
|
|
|
@ -1,47 +1,17 @@
|
|||
//! FIXME: write short doc here
|
||||
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
str::FromStr,
|
||||
sync::Arc,
|
||||
time::Instant,
|
||||
};
|
||||
use std::{path::Path, sync::Arc, time::Instant};
|
||||
|
||||
use anyhow::format_err;
|
||||
use ra_db::{
|
||||
salsa::{Database, Durability},
|
||||
FileId, SourceDatabaseExt,
|
||||
};
|
||||
use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FilePosition, LineCol};
|
||||
|
||||
use crate::{load_cargo::load_cargo, Result};
|
||||
use crate::{load_cargo::load_cargo, BenchWhat, Result, Verbosity};
|
||||
|
||||
pub(crate) struct Position {
|
||||
path: PathBuf,
|
||||
line: u32,
|
||||
column: u32,
|
||||
}
|
||||
|
||||
impl FromStr for Position {
|
||||
type Err = Box<dyn std::error::Error + Send + Sync>;
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
let (path_line, column) = rsplit_at_char(s, ':')?;
|
||||
let (path, line) = rsplit_at_char(path_line, ':')?;
|
||||
Ok(Position { path: path.into(), line: line.parse()?, column: column.parse()? })
|
||||
}
|
||||
}
|
||||
|
||||
fn rsplit_at_char(s: &str, c: char) -> Result<(&str, &str)> {
|
||||
let idx = s.rfind(':').ok_or_else(|| format!("no `{}` in {}", c, s))?;
|
||||
Ok((&s[..idx], &s[idx + 1..]))
|
||||
}
|
||||
|
||||
pub(crate) enum Op {
|
||||
Highlight { path: PathBuf },
|
||||
Complete(Position),
|
||||
GotoDef(Position),
|
||||
}
|
||||
|
||||
pub(crate) fn run(verbose: bool, path: &Path, op: Op) -> Result<()> {
|
||||
pub(crate) fn run(verbosity: Verbosity, path: &Path, what: BenchWhat) -> Result<()> {
|
||||
ra_prof::init();
|
||||
|
||||
let start = Instant::now();
|
||||
|
@ -51,9 +21,9 @@ pub(crate) fn run(verbose: bool, path: &Path, op: Op) -> Result<()> {
|
|||
eprintln!("{:?}\n", start.elapsed());
|
||||
|
||||
let file_id = {
|
||||
let path = match &op {
|
||||
Op::Highlight { path } => path,
|
||||
Op::Complete(pos) | Op::GotoDef(pos) => &pos.path,
|
||||
let path = match &what {
|
||||
BenchWhat::Highlight { path } => path,
|
||||
BenchWhat::Complete(pos) | BenchWhat::GotoDef(pos) => &pos.path,
|
||||
};
|
||||
let path = std::env::current_dir()?.join(path).canonicalize()?;
|
||||
roots
|
||||
|
@ -70,22 +40,22 @@ pub(crate) fn run(verbose: bool, path: &Path, op: Op) -> Result<()> {
|
|||
}
|
||||
None
|
||||
})
|
||||
.ok_or_else(|| format!("Can't find {:?}", path))?
|
||||
.ok_or_else(|| format_err!("Can't find {}", path.display()))?
|
||||
};
|
||||
|
||||
match &op {
|
||||
Op::Highlight { .. } => {
|
||||
match &what {
|
||||
BenchWhat::Highlight { .. } => {
|
||||
let res = do_work(&mut host, file_id, |analysis| {
|
||||
analysis.diagnostics(file_id).unwrap();
|
||||
analysis.highlight_as_html(file_id, false).unwrap()
|
||||
});
|
||||
if verbose {
|
||||
if verbosity.is_verbose() {
|
||||
println!("\n{}", res);
|
||||
}
|
||||
}
|
||||
Op::Complete(pos) | Op::GotoDef(pos) => {
|
||||
let is_completion = match op {
|
||||
Op::Complete(..) => true,
|
||||
BenchWhat::Complete(pos) | BenchWhat::GotoDef(pos) => {
|
||||
let is_completion = match what {
|
||||
BenchWhat::Complete(..) => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
@ -98,13 +68,13 @@ pub(crate) fn run(verbose: bool, path: &Path, op: Op) -> Result<()> {
|
|||
if is_completion {
|
||||
let res =
|
||||
do_work(&mut host, file_id, |analysis| analysis.completions(file_postion));
|
||||
if verbose {
|
||||
if verbosity.is_verbose() {
|
||||
println!("\n{:#?}", res);
|
||||
}
|
||||
} else {
|
||||
let res =
|
||||
do_work(&mut host, file_id, |analysis| analysis.goto_definition(file_postion));
|
||||
if verbose {
|
||||
if verbosity.is_verbose() {
|
||||
println!("\n{:#?}", res);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
//! FIXME: write short doc here
|
||||
|
||||
use std::{collections::HashSet, error::Error, path::Path};
|
||||
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::{collections::HashSet, path::Path};
|
||||
|
||||
use crossbeam_channel::{unbounded, Receiver};
|
||||
use ra_db::{CrateGraph, FileId, SourceRootId};
|
||||
|
@ -10,8 +8,9 @@ use ra_ide::{AnalysisChange, AnalysisHost, FeatureFlags};
|
|||
use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace};
|
||||
use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch};
|
||||
use ra_vfs_glob::RustPackageFilterBuilder;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
|
||||
use anyhow::Result;
|
||||
|
||||
fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId {
|
||||
FileId(f.0)
|
||||
|
|
|
@ -5,14 +5,82 @@ mod analysis_stats;
|
|||
mod analysis_bench;
|
||||
mod progress_report;
|
||||
|
||||
use std::{error::Error, fmt::Write, io::Read};
|
||||
use std::{fmt::Write, io::Read, path::PathBuf, str::FromStr};
|
||||
|
||||
use pico_args::Arguments;
|
||||
use ra_ide::{file_structure, Analysis};
|
||||
use ra_prof::profile;
|
||||
use ra_syntax::{AstNode, SourceFile};
|
||||
|
||||
type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
|
||||
use anyhow::{bail, format_err, Result};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
env_logger::try_init()?;
|
||||
|
||||
let command = match Command::from_env_args()? {
|
||||
Ok(it) => it,
|
||||
Err(HelpPrinted) => return Ok(()),
|
||||
};
|
||||
match command {
|
||||
Command::Parse { no_dump } => {
|
||||
let _p = profile("parsing");
|
||||
let file = file()?;
|
||||
if !no_dump {
|
||||
println!("{:#?}", file.syntax());
|
||||
}
|
||||
std::mem::forget(file);
|
||||
}
|
||||
Command::Symbols => {
|
||||
let file = file()?;
|
||||
for s in file_structure(&file) {
|
||||
println!("{:?}", s);
|
||||
}
|
||||
}
|
||||
Command::Highlight { rainbow } => {
|
||||
let (analysis, file_id) = Analysis::from_single_file(read_stdin()?);
|
||||
let html = analysis.highlight_as_html(file_id, rainbow).unwrap();
|
||||
println!("{}", html);
|
||||
}
|
||||
Command::Stats { verbosity, randomize, memory_usage, only, with_deps, path } => {
|
||||
analysis_stats::run(
|
||||
verbosity,
|
||||
memory_usage,
|
||||
path.as_ref(),
|
||||
only.as_ref().map(String::as_ref),
|
||||
with_deps,
|
||||
randomize,
|
||||
)?;
|
||||
}
|
||||
Command::Bench { verbosity, path, what } => {
|
||||
analysis_bench::run(verbosity, path.as_ref(), what)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
enum Command {
|
||||
Parse {
|
||||
no_dump: bool,
|
||||
},
|
||||
Symbols,
|
||||
Highlight {
|
||||
rainbow: bool,
|
||||
},
|
||||
Stats {
|
||||
verbosity: Verbosity,
|
||||
randomize: bool,
|
||||
memory_usage: bool,
|
||||
only: Option<String>,
|
||||
with_deps: bool,
|
||||
path: PathBuf,
|
||||
},
|
||||
Bench {
|
||||
verbosity: Verbosity,
|
||||
path: PathBuf,
|
||||
what: BenchWhat,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Verbosity {
|
||||
|
@ -37,17 +105,57 @@ impl Verbosity {
|
|||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
env_logger::try_init()?;
|
||||
enum BenchWhat {
|
||||
Highlight { path: PathBuf },
|
||||
Complete(Position),
|
||||
GotoDef(Position),
|
||||
}
|
||||
|
||||
let mut matches = Arguments::from_env();
|
||||
let subcommand = matches.subcommand()?.unwrap_or_default();
|
||||
pub(crate) struct Position {
|
||||
path: PathBuf,
|
||||
line: u32,
|
||||
column: u32,
|
||||
}
|
||||
|
||||
match subcommand.as_str() {
|
||||
"parse" => {
|
||||
if matches.contains(["-h", "--help"]) {
|
||||
eprintln!(
|
||||
"\
|
||||
impl FromStr for Position {
|
||||
type Err = anyhow::Error;
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
let (path_line, column) = rsplit_at_char(s, ':')?;
|
||||
let (path, line) = rsplit_at_char(path_line, ':')?;
|
||||
Ok(Position { path: path.into(), line: line.parse()?, column: column.parse()? })
|
||||
}
|
||||
}
|
||||
|
||||
fn rsplit_at_char(s: &str, c: char) -> Result<(&str, &str)> {
|
||||
let idx = s.rfind(c).ok_or_else(|| format_err!("no `{}` in {}", c, s))?;
|
||||
Ok((&s[..idx], &s[idx + 1..]))
|
||||
}
|
||||
|
||||
struct HelpPrinted;
|
||||
|
||||
impl Command {
|
||||
fn from_env_args() -> Result<Result<Command, HelpPrinted>> {
|
||||
let mut matches = Arguments::from_env();
|
||||
let subcommand = matches.subcommand()?.unwrap_or_default();
|
||||
|
||||
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 command = match subcommand.as_str() {
|
||||
"parse" => {
|
||||
if matches.contains(["-h", "--help"]) {
|
||||
eprintln!(
|
||||
"\
|
||||
ra-cli-parse
|
||||
|
||||
USAGE:
|
||||
|
@ -56,24 +164,18 @@ USAGE:
|
|||
FLAGS:
|
||||
-h, --help Prints help inforamtion
|
||||
--no-dump"
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
);
|
||||
return Ok(Err(HelpPrinted));
|
||||
}
|
||||
|
||||
let no_dump = matches.contains("--no-dump");
|
||||
matches.finish().or_else(handle_extra_flags)?;
|
||||
|
||||
let _p = profile("parsing");
|
||||
let file = file()?;
|
||||
if !no_dump {
|
||||
println!("{:#?}", file.syntax());
|
||||
let no_dump = matches.contains("--no-dump");
|
||||
matches.finish().or_else(handle_extra_flags)?;
|
||||
Command::Parse { no_dump }
|
||||
}
|
||||
std::mem::forget(file);
|
||||
}
|
||||
"symbols" => {
|
||||
if matches.contains(["-h", "--help"]) {
|
||||
eprintln!(
|
||||
"\
|
||||
"symbols" => {
|
||||
if matches.contains(["-h", "--help"]) {
|
||||
eprintln!(
|
||||
"\
|
||||
ra-cli-symbols
|
||||
|
||||
USAGE:
|
||||
|
@ -81,21 +183,18 @@ USAGE:
|
|||
|
||||
FLAGS:
|
||||
-h, --help Prints help inforamtion"
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
);
|
||||
return Ok(Err(HelpPrinted));
|
||||
}
|
||||
|
||||
matches.finish().or_else(handle_extra_flags)?;
|
||||
matches.finish().or_else(handle_extra_flags)?;
|
||||
|
||||
let file = file()?;
|
||||
for s in file_structure(&file) {
|
||||
println!("{:?}", s);
|
||||
Command::Symbols
|
||||
}
|
||||
}
|
||||
"highlight" => {
|
||||
if matches.contains(["-h", "--help"]) {
|
||||
eprintln!(
|
||||
"\
|
||||
"highlight" => {
|
||||
if matches.contains(["-h", "--help"]) {
|
||||
eprintln!(
|
||||
"\
|
||||
ra-cli-highlight
|
||||
|
||||
USAGE:
|
||||
|
@ -104,21 +203,18 @@ USAGE:
|
|||
FLAGS:
|
||||
-h, --help Prints help information
|
||||
-r, --rainbow"
|
||||
);
|
||||
return Ok(());
|
||||
);
|
||||
return Ok(Err(HelpPrinted));
|
||||
}
|
||||
|
||||
let rainbow = matches.contains(["-r", "--rainbow"]);
|
||||
matches.finish().or_else(handle_extra_flags)?;
|
||||
Command::Highlight { rainbow }
|
||||
}
|
||||
|
||||
let rainbow_opt = matches.contains(["-r", "--rainbow"]);
|
||||
matches.finish().or_else(handle_extra_flags)?;
|
||||
|
||||
let (analysis, file_id) = Analysis::from_single_file(read_stdin()?);
|
||||
let html = analysis.highlight_as_html(file_id, rainbow_opt).unwrap();
|
||||
println!("{}", html);
|
||||
}
|
||||
"analysis-stats" => {
|
||||
if matches.contains(["-h", "--help"]) {
|
||||
eprintln!(
|
||||
"\
|
||||
"analysis-stats" => {
|
||||
if matches.contains(["-h", "--help"]) {
|
||||
eprintln!(
|
||||
"\
|
||||
ra-cli-analysis-stats
|
||||
|
||||
USAGE:
|
||||
|
@ -135,47 +231,28 @@ OPTIONS:
|
|||
|
||||
ARGS:
|
||||
<PATH>"
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let verbosity = match (
|
||||
matches.contains(["-vv", "--spammy"]),
|
||||
matches.contains(["-v", "--verbose"]),
|
||||
matches.contains(["-q", "--quiet"]),
|
||||
) {
|
||||
(true, _, true) => Err("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) => Err("Invalid flags: -q conflicts with -v")?,
|
||||
};
|
||||
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 {
|
||||
Err("Invalid flags")?;
|
||||
);
|
||||
return Ok(Err(HelpPrinted));
|
||||
}
|
||||
trailing.pop().unwrap()
|
||||
};
|
||||
|
||||
analysis_stats::run(
|
||||
verbosity,
|
||||
memory_usage,
|
||||
path.as_ref(),
|
||||
only.as_ref().map(String::as_ref),
|
||||
with_deps,
|
||||
randomize,
|
||||
)?;
|
||||
}
|
||||
"analysis-bench" => {
|
||||
if matches.contains(["-h", "--help"]) {
|
||||
eprintln!(
|
||||
"\
|
||||
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 { verbosity, randomize, memory_usage, only, with_deps, path }
|
||||
}
|
||||
"analysis-bench" => {
|
||||
if matches.contains(["-h", "--help"]) {
|
||||
eprintln!(
|
||||
"\
|
||||
ra_cli-analysis-bench
|
||||
|
||||
USAGE:
|
||||
|
@ -191,29 +268,27 @@ OPTIONS:
|
|||
|
||||
ARGS:
|
||||
<PATH> Project to analyse"
|
||||
);
|
||||
return Ok(());
|
||||
);
|
||||
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 { verbosity, path, what }
|
||||
}
|
||||
|
||||
let verbose = matches.contains(["-v", "--verbose"]);
|
||||
let path: String = matches.opt_value_from_str("--path")?.unwrap_or_default();
|
||||
let highlight_path: Option<String> = matches.opt_value_from_str("--highlight")?;
|
||||
let complete_path: Option<String> = matches.opt_value_from_str("--complete")?;
|
||||
let goto_def_path: Option<String> = matches.opt_value_from_str("--goto-def")?;
|
||||
let op = match (highlight_path, complete_path, goto_def_path) {
|
||||
(Some(path), None, None) => analysis_bench::Op::Highlight { path: path.into() },
|
||||
(None, Some(position), None) => analysis_bench::Op::Complete(position.parse()?),
|
||||
(None, None, Some(position)) => analysis_bench::Op::GotoDef(position.parse()?),
|
||||
_ => panic!(
|
||||
"exactly one of `--highlight`, `--complete` or `--goto-def` must be set"
|
||||
),
|
||||
};
|
||||
matches.finish().or_else(handle_extra_flags)?;
|
||||
|
||||
analysis_bench::run(verbose, path.as_ref(), op)?;
|
||||
}
|
||||
_ => eprintln!(
|
||||
"\
|
||||
_ => {
|
||||
eprintln!(
|
||||
"\
|
||||
ra-cli
|
||||
|
||||
USAGE:
|
||||
|
@ -228,9 +303,12 @@ SUBCOMMANDS:
|
|||
highlight
|
||||
parse
|
||||
symbols"
|
||||
),
|
||||
);
|
||||
return Ok(Err(HelpPrinted));
|
||||
}
|
||||
};
|
||||
Ok(Ok(command))
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_extra_flags(e: pico_args::Error) -> Result<()> {
|
||||
|
@ -240,9 +318,9 @@ fn handle_extra_flags(e: pico_args::Error) -> Result<()> {
|
|||
write!(&mut invalid_flags, "{}, ", flag)?;
|
||||
}
|
||||
let (invalid_flags, _) = invalid_flags.split_at(invalid_flags.len() - 2);
|
||||
Err(format!("Invalid flags: {}", invalid_flags).into())
|
||||
bail!("Invalid flags: {}", invalid_flags);
|
||||
} else {
|
||||
Err(e.to_string().into())
|
||||
bail!(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,27 +8,28 @@ authors = ["rust-analyzer developers"]
|
|||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
threadpool = "1.7.1"
|
||||
relative-path = "1.0.0"
|
||||
serde_json = "1.0.34"
|
||||
serde = { version = "1.0.83", features = ["derive"] }
|
||||
crossbeam-channel = "0.4"
|
||||
either = "1.5"
|
||||
env_logger = { version = "0.7.1", default-features = false }
|
||||
jod-thread = "0.1.0"
|
||||
log = "0.4.3"
|
||||
lsp-types = { version = "0.70.0", features = ["proposed"] }
|
||||
rustc-hash = "1.0"
|
||||
parking_lot = "0.10.0"
|
||||
jod-thread = "0.1.0"
|
||||
ra_vfs = "0.5.0"
|
||||
relative-path = "1.0.0"
|
||||
rustc-hash = "1.0"
|
||||
serde = { version = "1.0.83", features = ["derive"] }
|
||||
serde_json = "1.0.34"
|
||||
threadpool = "1.7.1"
|
||||
|
||||
lsp-server = "0.3.0"
|
||||
ra_cargo_watch = { path = "../ra_cargo_watch" }
|
||||
ra_ide = { path = "../ra_ide" }
|
||||
ra_prof = { path = "../ra_prof" }
|
||||
ra_project_model = { path = "../ra_project_model" }
|
||||
ra_syntax = { path = "../ra_syntax" }
|
||||
ra_text_edit = { path = "../ra_text_edit" }
|
||||
ra_ide = { path = "../ra_ide" }
|
||||
lsp-server = "0.3.0"
|
||||
ra_project_model = { path = "../ra_project_model" }
|
||||
ra_prof = { path = "../ra_prof" }
|
||||
ra_vfs = "0.5.0"
|
||||
ra_vfs_glob = { path = "../ra_vfs_glob" }
|
||||
env_logger = { version = "0.7.1", default-features = false }
|
||||
ra_cargo_watch = { path = "../ra_cargo_watch" }
|
||||
either = "1.5"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = "0.3"
|
||||
|
|
Loading…
Reference in a new issue