Emit used rustc invocation in the save-analysis file
This commit is contained in:
parent
8876906867
commit
c01e4ce74e
@ -57,6 +57,7 @@ cargo = { path = "tools/cargo" }
|
||||
# that we're shipping as well (to ensure that the rustfmt in RLS and the
|
||||
# `rustfmt` executable are the same exact version).
|
||||
rustfmt-nightly = { path = "tools/rustfmt" }
|
||||
rls-data = { git = "https://github.com/Xanewok/rls-data", branch = "compilation-options" }
|
||||
|
||||
# See comments in `tools/rustc-workspace-hack/README.md` for what's going on
|
||||
# here
|
||||
|
@ -28,7 +28,8 @@ use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::env;
|
||||
|
||||
use syntax::ast::{self, Attribute, NodeId, PatKind, CRATE_NODE_ID};
|
||||
use syntax::parse::token;
|
||||
@ -49,8 +50,10 @@ use json_dumper::{Access, DumpOutput, JsonDumper};
|
||||
use span_utils::SpanUtils;
|
||||
use sig;
|
||||
|
||||
use rls_data::{CratePreludeData, Def, DefKind, GlobalCrateId, Import, ImportKind, Ref, RefKind,
|
||||
Relation, RelationKind, SpanData};
|
||||
use rls_data::{
|
||||
CompilationOptions, CratePreludeData, Def, DefKind, GlobalCrateId, Import, ImportKind, Ref,
|
||||
RefKind, Relation, RelationKind, SpanData,
|
||||
};
|
||||
|
||||
macro_rules! down_cast_data {
|
||||
($id:ident, $kind:ident, $sp:expr) => {
|
||||
@ -169,6 +172,61 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||
self.dumper.crate_prelude(data);
|
||||
}
|
||||
|
||||
pub fn dump_compilation_options(&mut self) {
|
||||
// Apply possible `remap-path-prefix` remapping to the raw invocation
|
||||
let invocation = {
|
||||
let remap_arg_indices = {
|
||||
let mut indices = FxHashSet();
|
||||
for (i, e) in env::args().enumerate() {
|
||||
if e.starts_with("--remap-path-prefix=") {
|
||||
indices.insert(i);
|
||||
} else if e == "--remap-path-prefix" {
|
||||
indices.insert(i);
|
||||
indices.insert(i + 1);
|
||||
}
|
||||
}
|
||||
indices
|
||||
};
|
||||
|
||||
let args_without_remap_args = env::args()
|
||||
.enumerate()
|
||||
.filter(|(i, _)| !remap_arg_indices.contains(i))
|
||||
.map(|(_, e)| e);
|
||||
|
||||
let mapping = self.tcx.sess.source_map().path_mapping();
|
||||
let remap_arg = |x: &str| -> String {
|
||||
mapping.map_prefix(PathBuf::from(x)).0.to_str().unwrap().to_owned()
|
||||
};
|
||||
|
||||
// Naively attempt to remap every argument
|
||||
let args = args_without_remap_args
|
||||
.map(|elem| {
|
||||
let mut arg = elem.splitn(2, '=');
|
||||
match (arg.next(), arg.next()) {
|
||||
// Apart from `--remap...`, in `a=b` args usually only
|
||||
// `b` is a path (e.g. `--extern some_crate=/path/to..`)
|
||||
(Some(a), Some(b)) => format!("{}={}", a, remap_arg(b)),
|
||||
(Some(a), _) => remap_arg(a),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
args.as_slice().join(" ")
|
||||
};
|
||||
|
||||
let opts = &self.tcx.sess.opts;
|
||||
|
||||
let data = CompilationOptions {
|
||||
invocation,
|
||||
crate_name: opts.crate_name.clone(),
|
||||
test: opts.test,
|
||||
sysroot: opts.maybe_sysroot.clone(),
|
||||
target_triple: opts.target_triple.to_string(),
|
||||
};
|
||||
|
||||
self.dumper.compilation_opts(data);
|
||||
}
|
||||
|
||||
// Return all non-empty prefixes of a path.
|
||||
// For each prefix, we return the span for the last segment in the prefix and
|
||||
// a str representation of the entire prefix.
|
||||
|
@ -12,9 +12,11 @@ use std::io::Write;
|
||||
|
||||
use rustc_serialize::json::as_json;
|
||||
|
||||
use rls_data::{self, Analysis, CratePreludeData, Def, DefKind, Import, MacroRef, Ref, RefKind,
|
||||
Relation, Impl};
|
||||
use rls_data::config::Config;
|
||||
use rls_data::{
|
||||
self, Analysis, CompilationOptions, CratePreludeData, Def, DefKind, Impl, Import, MacroRef,
|
||||
Ref, RefKind, Relation,
|
||||
};
|
||||
use rls_span::{Column, Row};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -89,6 +91,10 @@ impl<'b, O: DumpOutput + 'b> JsonDumper<O> {
|
||||
self.result.prelude = Some(data)
|
||||
}
|
||||
|
||||
pub fn compilation_opts(&mut self, data: CompilationOptions) {
|
||||
self.result.compilation = Some(data);
|
||||
}
|
||||
|
||||
pub fn macro_use(&mut self, data: MacroRef) {
|
||||
if self.config.pub_only || self.config.reachable_only {
|
||||
return;
|
||||
|
@ -70,10 +70,11 @@ use json_dumper::JsonDumper;
|
||||
use dump_visitor::DumpVisitor;
|
||||
use span_utils::SpanUtils;
|
||||
|
||||
use rls_data::{Def, DefKind, ExternalCrateData, GlobalCrateId, MacroRef, Ref, RefKind, Relation,
|
||||
RelationKind, SpanData, Impl, ImplKind};
|
||||
use rls_data::config::Config;
|
||||
|
||||
use rls_data::{
|
||||
CrateSource, Def, DefKind, ExternalCrateData, GlobalCrateId, Impl, ImplKind, MacroRef, Ref,
|
||||
RefKind, Relation, RelationKind, SpanData,
|
||||
};
|
||||
|
||||
pub struct SaveContext<'l, 'tcx: 'l> {
|
||||
tcx: TyCtxt<'l, 'tcx, 'tcx>,
|
||||
@ -122,16 +123,32 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let src = self.tcx.used_crate_source(n);
|
||||
let lo_loc = self.span_utils.sess.source_map().lookup_char_pos(span.lo());
|
||||
let map_prefix = |path: &PathBuf| -> PathBuf {
|
||||
self.tcx.sess.source_map().path_mapping().map_prefix(path.to_owned()).0
|
||||
};
|
||||
|
||||
result.push(ExternalCrateData {
|
||||
// FIXME: change file_name field to PathBuf in rls-data
|
||||
// https://github.com/nrc/rls-data/issues/7
|
||||
file_name: self.span_utils.make_path_string(&lo_loc.file.name),
|
||||
file_name: self.span_utils.make_filename_string(&lo_loc.file),
|
||||
num: n.as_u32(),
|
||||
id: GlobalCrateId {
|
||||
name: self.tcx.crate_name(n).to_string(),
|
||||
disambiguator: self.tcx.crate_disambiguator(n).to_fingerprint().as_value(),
|
||||
},
|
||||
source: CrateSource {
|
||||
dylib: src.dylib.as_ref().map(|(ref path, _)|
|
||||
map_prefix(path).display().to_string()
|
||||
),
|
||||
rlib: src.rlib.as_ref().map(|(ref path, _)|
|
||||
map_prefix(path).display().to_string()
|
||||
),
|
||||
rmeta: src.rmeta.as_ref().map(|(ref path, _)|
|
||||
map_prefix(path).display().to_string()
|
||||
),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -1086,6 +1103,7 @@ impl<'a> SaveHandler for DumpHandler<'a> {
|
||||
let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
|
||||
|
||||
visitor.dump_crate_info(cratename, krate);
|
||||
visitor.dump_compilation_options();
|
||||
visit::walk_crate(&mut visitor, krate);
|
||||
}
|
||||
}
|
||||
@ -1111,6 +1129,7 @@ impl<'b> SaveHandler for CallbackHandler<'b> {
|
||||
let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
|
||||
|
||||
visitor.dump_crate_info(cratename, krate);
|
||||
visitor.dump_compilation_options();
|
||||
visit::walk_crate(&mut visitor, krate);
|
||||
}
|
||||
}
|
||||
|
@ -35,14 +35,17 @@ impl<'a> SpanUtils<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_path_string(&self, path: &FileName) -> String {
|
||||
match *path {
|
||||
FileName::Real(ref path) if !path.is_absolute() =>
|
||||
pub fn make_filename_string(&self, file: &SourceFile) -> String {
|
||||
match &file.name {
|
||||
FileName::Real(path) if !path.is_absolute() && !file.name_was_remapped => {
|
||||
self.sess.working_dir.0
|
||||
.join(&path)
|
||||
.display()
|
||||
.to_string(),
|
||||
_ => path.to_string(),
|
||||
.to_string()
|
||||
},
|
||||
// If the file name is already remapped, we assume the user
|
||||
// configured it the way they wanted to, so use that directly
|
||||
filename => filename.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user