Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions crates/wright-analyzer/src/analysis.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
use serde::{Deserialize, Serialize};

/// The severity of a finding.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
/// The severity of a finding, ordered from least to most severe.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Severity {
Warning,
Info,
Warning,
Error,
}

impl Severity {
/// Reads a serialized severity label. `notice` is an alias of `info`; a
/// missing or unknown label is a warning.
pub fn from_label(label: Option<&str>) -> Self {
match label {
Some("error") => Self::Error,
Some("info" | "notice") => Self::Info,
_ => Self::Warning,
}
}

pub fn as_str(self) -> &'static str {
match self {
Self::Error => "error",
Expand Down
4 changes: 4 additions & 0 deletions crates/wright-analyzer/src/canonical/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ impl<'a> SemanticService<'a> {
&self.findings
}

pub fn symbol_count(&self) -> usize {
self.index.symbols().count()
}

#[hotpath::measure]
pub fn references_for_all_symbols(&self) -> JsonValue {
JsonValue::Array(self.references_json().clone())
Expand Down
39 changes: 26 additions & 13 deletions crates/wright-analyzer/src/canonical/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ pub enum PositionResolution<'a> {
pub struct SemanticIndex {
symbols: Vec<Symbol>,
references: Vec<Reference>,
/// Positions in `references`, grouped by referenced symbol index.
by_symbol: Vec<Vec<usize>>,
next_value_id: ValueId,
}

Expand Down Expand Up @@ -227,6 +229,7 @@ impl SemanticIndex {
let mut index = Self {
symbols,
references: Vec::new(),
by_symbol: Vec::new(),
next_value_id: 0,
};
index.add_missing_declarations();
Expand All @@ -245,6 +248,17 @@ impl SemanticIndex {
index.walk_action(value, rule, action, program);
}
}
let groups = index
.references
.iter()
.map(|reference| reference.symbol.index() + 1)
.max()
.unwrap_or(0)
.max(index.symbols.len());
index.by_symbol = vec![Vec::new(); groups];
for (position, reference) in index.references.iter().enumerate() {
index.by_symbol[reference.symbol.index()].push(position);
}
index
}

Expand All @@ -255,10 +269,14 @@ impl SemanticIndex {
self.symbols.get(id.index())
}
pub fn references(&self, symbol: SymbolId) -> Vec<&Reference> {
self.references
.iter()
.filter(|reference| reference.symbol == symbol)
.collect()
self.by_symbol
.get(symbol.index())
.map_or_else(Vec::new, |positions| {
positions
.iter()
.map(|&position| &self.references[position])
.collect()
})
}

/// Resolve a 1-based `line`/`col` to the symbol whose identifier
Expand Down Expand Up @@ -290,15 +308,10 @@ impl SemanticIndex {
}
}
pub(super) fn references_for_all_symbols(&self) -> Vec<Vec<&Reference>> {
let mut grouped = (0..self.symbols.len())
.map(|_| Vec::new())
.collect::<Vec<_>>();
for reference in &self.references {
if let Some(references) = grouped.get_mut(reference.symbol.index()) {
references.push(reference);
}
}
grouped
self.symbols
.iter()
.map(|symbol| self.references(symbol.id))
.collect()
}
pub fn usage(&self, symbol: SymbolId) -> UsageSummary {
let mut usage = UsageSummary::default();
Expand Down
1 change: 0 additions & 1 deletion crates/wright-cli/src/lint/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ impl ResultPresentation for LintPackageResult {
fn metadata(&self) -> Option<String> {
Some(metadata(self))
}
fn render_body(&self, _ctx: &RenderContext<'_>) {}
}

fn package_record(row: &LintPackageRow) -> String {
Expand Down
30 changes: 15 additions & 15 deletions crates/wright-cli/src/plain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@ use crate::present::{
diagnostics_on_stdout, display_location_path, edge_caller, finding_files,
finding_severity_rank, findings_severity_counts, fix_status_counts, inline_location,
is_real_source_path, lookup_hint_args, notable_callers, query_items, render_node, rule_address,
rule_name, severity_rank, summary_status, tree_rule,
rule_name, shown_diagnostics, summary_status, tree_rule,
};

pub(crate) fn render<T: serde::Serialize + ResultPresentation + PlainReport>(
envelope: &Envelope<T>,
ctx: &RenderContext<'_>,
) {
if envelope.result.is_artifact_stream() {
if let Some(artifact) = envelope.result.artifact() {
let mut err = Vec::new();
diagnostic_records(envelope, ctx, &mut err);
for line in err {
eprintln!("{line}");
}
envelope.result.render_body(ctx);
print!("{artifact}");
return;
}
let (out, err) = render_lines(envelope, ctx);
Expand Down Expand Up @@ -126,19 +126,15 @@ fn diagnostic_records<T: serde::Serialize>(
ctx: &RenderContext<'_>,
err: &mut Vec<String>,
) {
let mut ordered: Vec<&Diagnostic> = envelope.diagnostics.iter().collect();
ordered.sort_by_key(|diagnostic| severity_rank(diagnostic.severity));
let total = ordered.len();
let bounded = !matches!(envelope.command.as_str(), "compile" | "convert");
let limit = if ctx.presentation.all || !bounded {
usize::MAX
} else {
20
};
for diagnostic in ordered.iter().take(limit) {
let (shown, withheld) = shown_diagnostics(
&envelope.command,
&envelope.diagnostics,
ctx.presentation.all,
);
for diagnostic in shown {
err.push(diagnostic_record(diagnostic));
}
if bounded && !ctx.presentation.all && total > 20 {
if let Some(total) = withheld {
err.push(truncated_record(
&[("diagnostics", 20, total)],
&expand_all(envelope),
Expand All @@ -149,7 +145,11 @@ fn diagnostic_records<T: serde::Serialize>(
.as_ref()
.filter(|selection| selection.total > 0)
{
let mut fields = vec![format!("diagnostics={total}/{}", selection.total)];
let mut fields = vec![format!(
"diagnostics={}/{}",
envelope.diagnostics.len(),
selection.total
)];
if let Some(by_code) = by_code_field(&selection.by_code) {
fields.push(by_code);
}
Expand Down
Loading
Loading