mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
Add CSV output to analysis-stats
For easy diffing.
This commit is contained in:
parent
f6901c952e
commit
f807ccd6c0
3 changed files with 74 additions and 6 deletions
|
@ -10,7 +10,11 @@ use hir::{
|
|||
db::{AstDatabase, DefDatabase, HirDatabase},
|
||||
AssocItem, Crate, Function, HasSource, HirDisplay, ModuleDef,
|
||||
};
|
||||
use hir_def::{body::BodySourceMap, expr::ExprId, FunctionId};
|
||||
use hir_def::{
|
||||
body::{BodySourceMap, SyntheticSyntax},
|
||||
expr::ExprId,
|
||||
FunctionId,
|
||||
};
|
||||
use hir_ty::{TyExt, TypeWalk};
|
||||
use ide::{Analysis, AnalysisHost, LineCol, RootDatabase};
|
||||
use ide_db::base_db::{
|
||||
|
@ -28,7 +32,7 @@ use syntax::{AstNode, SyntaxNode};
|
|||
use vfs::{AbsPathBuf, Vfs, VfsPath};
|
||||
|
||||
use crate::cli::{
|
||||
flags,
|
||||
flags::{self, OutputFormat},
|
||||
load_cargo::{load_workspace, LoadCargoConfig},
|
||||
print_memory_usage,
|
||||
progress_report::ProgressReport,
|
||||
|
@ -191,7 +195,7 @@ impl flags::AnalysisStats {
|
|||
) {
|
||||
let mut bar = match verbosity {
|
||||
Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(),
|
||||
_ if self.parallel => ProgressReport::hidden(),
|
||||
_ if self.parallel || self.output.is_some() => ProgressReport::hidden(),
|
||||
_ => ProgressReport::new(funcs.len() as u64),
|
||||
};
|
||||
|
||||
|
@ -252,7 +256,7 @@ impl flags::AnalysisStats {
|
|||
for (expr_id, _) in body.exprs.iter() {
|
||||
let ty = &inference_result[expr_id];
|
||||
num_exprs += 1;
|
||||
if ty.is_unknown() {
|
||||
let unknown_or_partial = if ty.is_unknown() {
|
||||
num_exprs_unknown += 1;
|
||||
if verbosity.is_spammy() {
|
||||
if let Some((path, start, end)) =
|
||||
|
@ -270,6 +274,7 @@ impl flags::AnalysisStats {
|
|||
bar.println(format!("{}: Unknown type", name,));
|
||||
}
|
||||
}
|
||||
true
|
||||
} else {
|
||||
let mut is_partially_unknown = false;
|
||||
ty.walk(&mut |ty| {
|
||||
|
@ -280,7 +285,8 @@ impl flags::AnalysisStats {
|
|||
if is_partially_unknown {
|
||||
num_exprs_partially_unknown += 1;
|
||||
}
|
||||
}
|
||||
is_partially_unknown
|
||||
};
|
||||
if self.only.is_some() && verbosity.is_spammy() {
|
||||
// in super-verbose mode for just one function, we print every single expression
|
||||
if let Some((_, start, end)) =
|
||||
|
@ -298,6 +304,13 @@ impl flags::AnalysisStats {
|
|||
bar.println(format!("unknown location: {}", ty.display(db)));
|
||||
}
|
||||
}
|
||||
if unknown_or_partial && self.output == Some(OutputFormat::Csv) {
|
||||
println!(
|
||||
r#"{},type,"{}""#,
|
||||
location_csv(db, &analysis, vfs, &sm, expr_id),
|
||||
ty.display(db)
|
||||
);
|
||||
}
|
||||
if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) {
|
||||
num_type_mismatches += 1;
|
||||
if verbosity.is_verbose() {
|
||||
|
@ -323,6 +336,14 @@ impl flags::AnalysisStats {
|
|||
));
|
||||
}
|
||||
}
|
||||
if self.output == Some(OutputFormat::Csv) {
|
||||
println!(
|
||||
r#"{},mismatch,"{}","{}""#,
|
||||
location_csv(db, &analysis, vfs, &sm, expr_id),
|
||||
mismatch.expected.display(db),
|
||||
mismatch.actual.display(db)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if verbosity.is_spammy() {
|
||||
|
@ -358,6 +379,28 @@ impl flags::AnalysisStats {
|
|||
}
|
||||
}
|
||||
|
||||
fn location_csv(
|
||||
db: &RootDatabase,
|
||||
analysis: &Analysis,
|
||||
vfs: &Vfs,
|
||||
sm: &BodySourceMap,
|
||||
expr_id: ExprId,
|
||||
) -> String {
|
||||
let src = match sm.expr_syntax(expr_id) {
|
||||
Ok(s) => s,
|
||||
Err(SyntheticSyntax) => return "synthetic,,".to_string(),
|
||||
};
|
||||
let root = db.parse_or_expand(src.file_id).unwrap();
|
||||
let node = src.map(|e| e.to_node(&root).syntax().clone());
|
||||
let original_range = node.as_ref().original_file_range(db);
|
||||
let path = vfs.file_path(original_range.file_id);
|
||||
let line_index = analysis.file_line_index(original_range.file_id).unwrap();
|
||||
let text_range = original_range.range;
|
||||
let (start, end) =
|
||||
(line_index.line_col(text_range.start()), line_index.line_col(text_range.end()));
|
||||
format!("{},{}:{},{}:{}", path, start.line + 1, start.col, end.line + 1, end.col)
|
||||
}
|
||||
|
||||
fn expr_syntax_range(
|
||||
db: &RootDatabase,
|
||||
analysis: &Analysis,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Grammar for the command-line arguments.
|
||||
#![allow(unreachable_pub)]
|
||||
use std::path::PathBuf;
|
||||
use std::{path::PathBuf, str::FromStr};
|
||||
|
||||
use ide_ssr::{SsrPattern, SsrRule};
|
||||
|
||||
|
@ -54,6 +54,8 @@ xflags::xflags! {
|
|||
/// Directory with Cargo.toml.
|
||||
required path: PathBuf
|
||||
{
|
||||
optional --output format: OutputFormat
|
||||
|
||||
/// Randomize order in which crates, modules, and items are processed.
|
||||
optional --randomize
|
||||
/// Run type inference in parallel.
|
||||
|
@ -160,6 +162,7 @@ pub struct Highlight {
|
|||
pub struct AnalysisStats {
|
||||
pub path: PathBuf,
|
||||
|
||||
pub output: Option<OutputFormat>,
|
||||
pub randomize: bool,
|
||||
pub parallel: bool,
|
||||
pub memory_usage: bool,
|
||||
|
@ -215,6 +218,11 @@ impl RustAnalyzer {
|
|||
}
|
||||
// generated end
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum OutputFormat {
|
||||
Csv,
|
||||
}
|
||||
|
||||
impl RustAnalyzer {
|
||||
pub fn verbosity(&self) -> Verbosity {
|
||||
if self.quiet {
|
||||
|
@ -227,3 +235,14 @@ impl RustAnalyzer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for OutputFormat {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"csv" => Ok(Self::Csv),
|
||||
_ => Err(format!("unknown output format `{}`", s)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,9 +113,15 @@ pub struct Bb {
|
|||
impl Xtask {
|
||||
pub const HELP: &'static str = Self::HELP_;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn from_env() -> xflags::Result<Self> {
|
||||
Self::from_env_()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn from_vec(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> {
|
||||
Self::from_vec_(args)
|
||||
}
|
||||
}
|
||||
// generated end
|
||||
|
||||
|
|
Loading…
Reference in a new issue