Emit only necessary compilation options in save-analysis
This is `command`, `directory` and `output` file.
This commit is contained in:
parent
cddd00a1e6
commit
d45f87701c
@ -2373,6 +2373,7 @@ dependencies = [
|
|||||||
"rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc 0.0.0",
|
"rustc 0.0.0",
|
||||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc_codegen_utils 0.0.0",
|
||||||
"rustc_data_structures 0.0.0",
|
"rustc_data_structures 0.0.0",
|
||||||
"rustc_target 0.0.0",
|
"rustc_target 0.0.0",
|
||||||
"rustc_typeck 0.0.0",
|
"rustc_typeck 0.0.0",
|
||||||
|
@ -12,6 +12,7 @@ crate-type = ["dylib"]
|
|||||||
log = "0.4"
|
log = "0.4"
|
||||||
rustc = { path = "../librustc" }
|
rustc = { path = "../librustc" }
|
||||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||||
|
rustc_codegen_utils = { path = "../librustc_codegen_utils" }
|
||||||
rustc_target = { path = "../librustc_target" }
|
rustc_target = { path = "../librustc_target" }
|
||||||
rustc_typeck = { path = "../librustc_typeck" }
|
rustc_typeck = { path = "../librustc_typeck" }
|
||||||
syntax = { path = "../libsyntax" }
|
syntax = { path = "../libsyntax" }
|
||||||
|
@ -28,8 +28,9 @@ use rustc::hir::def_id::DefId;
|
|||||||
use rustc::ty::{self, TyCtxt};
|
use rustc::ty::{self, TyCtxt};
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
use syntax::ast::{self, Attribute, NodeId, PatKind, CRATE_NODE_ID};
|
use syntax::ast::{self, Attribute, NodeId, PatKind, CRATE_NODE_ID};
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
@ -172,11 +173,20 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
|||||||
self.dumper.crate_prelude(data);
|
self.dumper.crate_prelude(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dump_compilation_options(&mut self) {
|
pub fn dump_compilation_options(&mut self, crate_name: &str) {
|
||||||
// Apply possible `remap-path-prefix` remapping to the raw invocation
|
// Apply possible `remap-path-prefix` remapping to the raw command
|
||||||
let invocation = {
|
let command = {
|
||||||
|
let mapping = self.tcx.sess.source_map().path_mapping();
|
||||||
|
let remap_arg = |x: &str| -> String {
|
||||||
|
match fs::canonicalize(x) {
|
||||||
|
Ok(path) => mapping.map_prefix(path).0.to_str().unwrap().to_owned(),
|
||||||
|
Err(_) => x.to_owned(), // Probably not a path, ignore
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let remap_arg_indices = {
|
let remap_arg_indices = {
|
||||||
let mut indices = FxHashSet();
|
let mut indices = FxHashSet();
|
||||||
|
// rustc args are guaranteed to be valid UTF-8 (checked early)
|
||||||
for (i, e) in env::args().enumerate() {
|
for (i, e) in env::args().enumerate() {
|
||||||
if e.starts_with("--remap-path-prefix=") {
|
if e.starts_with("--remap-path-prefix=") {
|
||||||
indices.insert(i);
|
indices.insert(i);
|
||||||
@ -188,19 +198,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
|||||||
indices
|
indices
|
||||||
};
|
};
|
||||||
|
|
||||||
let args_without_remap_args = env::args()
|
let args = env::args()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(i, _)| !remap_arg_indices.contains(i))
|
.filter(|(i, _)| !remap_arg_indices.contains(i))
|
||||||
.map(|(_, e)| e);
|
.map(|(_, elem)| {
|
||||||
|
|
||||||
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, '=');
|
let mut arg = elem.splitn(2, '=');
|
||||||
match (arg.next(), arg.next()) {
|
match (arg.next(), arg.next()) {
|
||||||
// Apart from `--remap...`, in `a=b` args usually only
|
// Apart from `--remap...`, in `a=b` args usually only
|
||||||
@ -214,14 +215,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
|||||||
args.as_slice().join(" ")
|
args.as_slice().join(" ")
|
||||||
};
|
};
|
||||||
|
|
||||||
let opts = &self.tcx.sess.opts;
|
|
||||||
|
|
||||||
let data = CompilationOptions {
|
let data = CompilationOptions {
|
||||||
invocation,
|
directory: self.tcx.sess.working_dir.0.clone(),
|
||||||
crate_name: opts.crate_name.clone(),
|
command,
|
||||||
test: opts.test,
|
output: self.save_ctxt.compilation_output(crate_name),
|
||||||
sysroot: opts.maybe_sysroot.clone(),
|
|
||||||
target_triple: opts.target_triple.to_string(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.dumper.compilation_opts(data);
|
self.dumper.compilation_opts(data);
|
||||||
|
@ -23,6 +23,7 @@ extern crate rustc;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate rustc_data_structures;
|
extern crate rustc_data_structures;
|
||||||
|
extern crate rustc_codegen_utils;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
extern crate rustc_target;
|
extern crate rustc_target;
|
||||||
extern crate rustc_typeck;
|
extern crate rustc_typeck;
|
||||||
@ -45,9 +46,10 @@ use rustc::hir::def::Def as HirDef;
|
|||||||
use rustc::hir::Node;
|
use rustc::hir::Node;
|
||||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc::middle::cstore::ExternCrate;
|
use rustc::middle::cstore::ExternCrate;
|
||||||
use rustc::session::config::CrateType;
|
use rustc::session::config::{CrateType, OutputType};
|
||||||
use rustc::ty::{self, TyCtxt};
|
use rustc::ty::{self, TyCtxt};
|
||||||
use rustc_typeck::hir_ty_to_ty;
|
use rustc_typeck::hir_ty_to_ty;
|
||||||
|
use rustc_codegen_utils::link::{filename_for_metadata, out_filename};
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
@ -111,6 +113,24 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns path to the compilation output (e.g. libfoo-12345678.rmeta)
|
||||||
|
pub fn compilation_output(&self, crate_name: &str) -> PathBuf {
|
||||||
|
let sess = &self.tcx.sess;
|
||||||
|
// Save-analysis is emitted per whole session, not per each crate type
|
||||||
|
let crate_type = sess.crate_types.borrow()[0];
|
||||||
|
let outputs = &*self.tcx.output_filenames(LOCAL_CRATE);
|
||||||
|
|
||||||
|
if outputs.outputs.contains_key(&OutputType::Metadata) {
|
||||||
|
filename_for_metadata(sess, crate_name, outputs)
|
||||||
|
} else if outputs.outputs.should_codegen() {
|
||||||
|
out_filename(sess, crate_type, outputs, crate_name)
|
||||||
|
} else {
|
||||||
|
// Otherwise it's only a DepInfo, in which case we return early and
|
||||||
|
// not even reach the analysis stage.
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// List external crates used by the current crate.
|
// List external crates used by the current crate.
|
||||||
pub fn get_external_crates(&self) -> Vec<ExternalCrateData> {
|
pub fn get_external_crates(&self) -> Vec<ExternalCrateData> {
|
||||||
let mut result = Vec::with_capacity(self.tcx.crates().len());
|
let mut result = Vec::with_capacity(self.tcx.crates().len());
|
||||||
@ -139,15 +159,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||||||
disambiguator: self.tcx.crate_disambiguator(n).to_fingerprint().as_value(),
|
disambiguator: self.tcx.crate_disambiguator(n).to_fingerprint().as_value(),
|
||||||
},
|
},
|
||||||
source: CrateSource {
|
source: CrateSource {
|
||||||
dylib: src.dylib.as_ref().map(|(ref path, _)|
|
dylib: src.dylib.as_ref().map(|(path, _)| map_prefix(path)),
|
||||||
map_prefix(path).display().to_string()
|
rlib: src.rlib.as_ref().map(|(path, _)| map_prefix(path)),
|
||||||
),
|
rmeta: src.rmeta.as_ref().map(|(path, _)| map_prefix(path)),
|
||||||
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()
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1103,7 +1117,7 @@ impl<'a> SaveHandler for DumpHandler<'a> {
|
|||||||
let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
|
let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
|
||||||
|
|
||||||
visitor.dump_crate_info(cratename, krate);
|
visitor.dump_crate_info(cratename, krate);
|
||||||
visitor.dump_compilation_options();
|
visitor.dump_compilation_options(cratename);
|
||||||
visit::walk_crate(&mut visitor, krate);
|
visit::walk_crate(&mut visitor, krate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1129,7 +1143,7 @@ impl<'b> SaveHandler for CallbackHandler<'b> {
|
|||||||
let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
|
let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
|
||||||
|
|
||||||
visitor.dump_crate_info(cratename, krate);
|
visitor.dump_crate_info(cratename, krate);
|
||||||
visitor.dump_compilation_options();
|
visitor.dump_compilation_options(cratename);
|
||||||
visit::walk_crate(&mut visitor, krate);
|
visit::walk_crate(&mut visitor, krate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user