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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ hashbrown = { version = "0.15.0", default-features = false, features = [
"equivalent",
"inline-more",
] }
heck = "0.5.0"
ignore = { version = "0.4.22" }
imara-diff = { version = "0.1.5" }
imperative = { version = "1.0.4" }
Expand Down
9 changes: 5 additions & 4 deletions crates/ruff/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use itertools::Itertools;
use log::{debug, error};
use rayon::iter::ParallelIterator;
use rayon::iter::{IntoParallelIterator, ParallelBridge};
use ruff_linter::{codes::Rule, registry::AsRule};
use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize};
use tempfile::NamedTempFile;
Expand Down Expand Up @@ -348,7 +349,7 @@ impl FileCache {
.iter()
.map(|msg| {
Message::Diagnostic(DiagnosticMessage {
name: msg.name.clone(),
name: msg.rule.into(),
body: msg.body.clone(),
suggestion: msg.suggestion.clone(),
range: msg.range,
Expand Down Expand Up @@ -446,7 +447,7 @@ impl LintCacheData {
"message uses a different source file"
);
CacheMessage {
name: msg.name.clone(),
rule: msg.rule(),
body: msg.body.clone(),
suggestion: msg.suggestion.clone(),
range: msg.range,
Expand All @@ -468,8 +469,8 @@ impl LintCacheData {
/// On disk representation of a diagnostic message.
#[derive(Deserialize, Debug, Serialize, PartialEq)]
pub(super) struct CacheMessage {
/// The identifier of the diagnostic, used to align the diagnostic with a rule.
name: String,
/// The rule for the cached diagnostic.
rule: Rule,
/// The message body to display to the user, to explain the diagnostic.
body: String,
/// The message to display to the user, to explain the suggested fix.
Expand Down
4 changes: 2 additions & 2 deletions crates/ruff_diagnostics/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{Fix, Violation};
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Diagnostic {
/// The identifier of the diagnostic, used to align the diagnostic with a rule.
pub name: String,
pub name: &'static str,
/// The message body to display to the user, to explain the diagnostic.
pub body: String,
/// The message to display to the user, to explain the suggested fix.
Expand All @@ -21,7 +21,7 @@ pub struct Diagnostic {
impl Diagnostic {
pub fn new<T: Violation>(kind: T, range: TextRange) -> Self {
Self {
name: T::rule_name().to_string(),
name: T::rule_name(),
body: Violation::message(&kind),
suggestion: Violation::fix_title(&kind),
range,
Expand Down
16 changes: 8 additions & 8 deletions crates/ruff_linter/src/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub enum Message {
/// A diagnostic message corresponding to a rule violation.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct DiagnosticMessage {
pub name: String,
pub name: &'static str,
pub body: String,
pub suggestion: Option<String>,
pub range: TextRange,
Expand Down Expand Up @@ -195,7 +195,7 @@ impl Message {
/// Returns the name used to represent the diagnostic.
pub fn name(&self) -> &str {
match self {
Message::Diagnostic(m) => &m.name,
Message::Diagnostic(m) => m.name,
Message::SyntaxError(_) => "SyntaxError",
}
}
Expand Down Expand Up @@ -429,7 +429,7 @@ def fibonacci(n):

let unused_import_start = TextSize::from(7);
let unused_import = DiagnosticMessage {
name: "UnusedImport".to_string(),
name: "unused-import",
body: "`os` imported but unused".to_string(),
suggestion: Some("Remove unused import: `os`".to_string()),
range: TextRange::new(unused_import_start, TextSize::from(9)),
Expand All @@ -444,7 +444,7 @@ def fibonacci(n):

let unused_variable_start = TextSize::from(94);
let unused_variable = DiagnosticMessage {
name: "UnusedVariable".to_string(),
name: "unused-variable",
body: "Local variable `x` is assigned to but never used".to_string(),
suggestion: Some("Remove assignment to unused variable `x`".to_string()),
range: TextRange::new(unused_variable_start, TextSize::from(95)),
Expand All @@ -461,7 +461,7 @@ def fibonacci(n):

let undefined_name_start = TextSize::from(3);
let undefined_name = DiagnosticMessage {
name: "UndefinedName".to_string(),
name: "undefined-name",
body: "Undefined name `a`".to_string(),
suggestion: None,
range: TextRange::new(undefined_name_start, TextSize::from(4)),
Expand Down Expand Up @@ -495,7 +495,7 @@ def foo():

let unused_import_os_start = TextSize::from(16);
let unused_import_os = DiagnosticMessage {
name: "UnusedImport".to_string(),
name: "unused-import",
body: "`os` imported but unused".to_string(),
suggestion: Some("Remove unused import: `os`".to_string()),
range: TextRange::new(unused_import_os_start, TextSize::from(18)),
Expand All @@ -510,7 +510,7 @@ def foo():

let unused_import_math_start = TextSize::from(35);
let unused_import_math = DiagnosticMessage {
name: "UnusedImport".to_string(),
name: "unused-import",
body: "`math` imported but unused".to_string(),
suggestion: Some("Remove unused import: `math`".to_string()),
range: TextRange::new(unused_import_math_start, TextSize::from(39)),
Expand All @@ -525,7 +525,7 @@ def foo():

let unused_variable_start = TextSize::from(98);
let unused_variable = DiagnosticMessage {
name: "UnusedVariable".to_string(),
name: "unused-variable",
body: "Local variable `x` is assigned to but never used".to_string(),
suggestion: Some("Remove assignment to unused variable `x`".to_string()),
range: TextRange::new(unused_variable_start, TextSize::from(99)),
Expand Down
1 change: 1 addition & 0 deletions crates/ruff_macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ doctest = false
[dependencies]
ruff_python_trivia = { workspace = true }

heck = { workspace = true }
proc-macro2 = { workspace = true }
quote = { workspace = true }
syn = { workspace = true, features = ["derive", "parsing", "extra-traits", "full"] }
Expand Down
15 changes: 3 additions & 12 deletions crates/ruff_macros/src/kebab_case.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
use heck::ToKebabCase;
use proc_macro2::TokenStream;

pub(crate) fn kebab_case(input: &syn::Ident) -> TokenStream {
let screaming_snake_case = input.to_string();
let s = input.to_string();

let mut kebab_case = String::with_capacity(screaming_snake_case.len());

for (i, word) in screaming_snake_case.split('_').enumerate() {
if i > 0 {
kebab_case.push('-');
}

kebab_case.push_str(&word.to_lowercase());
}

let kebab_case_lit = syn::LitStr::new(&kebab_case, input.span());
let kebab_case_lit = syn::LitStr::new(&s.to_kebab_case(), input.span());

quote::quote!(#kebab_case_lit)
}
2 changes: 1 addition & 1 deletion crates/ruff_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub fn derive_combine(input: TokenStream) -> TokenStream {
.into()
}

/// Converts a screaming snake case identifier to a kebab case string.
/// Converts an identifier to a kebab case string.
#[proc_macro]
pub fn kebab_case(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as syn::Ident);
Expand Down
8 changes: 5 additions & 3 deletions crates/ruff_macros/src/map_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ fn register_rules<'a>(input: impl Iterator<Item = &'a Rule>) -> TokenStream {

// Enable conversion from `DiagnosticKind` to `Rule`.
from_impls_for_diagnostic_kind
.extend(quote! {#(#attrs)* stringify!(#name) => Rule::#name,});
.extend(quote! {#(#attrs)* ::ruff_macros::kebab_case!(#name) => Rule::#name,});
}

quote! {
Expand All @@ -443,6 +443,8 @@ fn register_rules<'a>(input: impl Iterator<Item = &'a Rule>) -> TokenStream {
::ruff_macros::CacheKey,
AsRefStr,
::strum_macros::IntoStaticStr,
::serde::Serialize,
::serde::Deserialize,
)]
#[repr(u16)]
#[strum(serialize_all = "kebab-case")]
Expand All @@ -468,7 +470,7 @@ fn register_rules<'a>(input: impl Iterator<Item = &'a Rule>) -> TokenStream {

impl AsRule for ruff_diagnostics::Diagnostic {
fn rule(&self) -> Rule {
match self.name.as_str() {
match self.name {
#from_impls_for_diagnostic_kind
_ => unreachable!("invalid rule name: {}", self.name),
}
Expand All @@ -477,7 +479,7 @@ fn register_rules<'a>(input: impl Iterator<Item = &'a Rule>) -> TokenStream {

impl AsRule for crate::message::DiagnosticMessage {
fn rule(&self) -> Rule {
match self.name.as_str() {
match self.name {
#from_impls_for_diagnostic_kind
_ => unreachable!("invalid rule name: {}", self.name),
}
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_macros/src/violation_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub(crate) fn violation_metadata(input: DeriveInput) -> syn::Result<TokenStream>
#[expect(deprecated)]
impl ruff_diagnostics::ViolationMetadata for #name {
fn rule_name() -> &'static str {
stringify!(#name)
::ruff_macros::kebab_case!(#name)
}

fn explain() -> Option<&'static str> {
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_server/src/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ fn to_lsp_diagnostic(
new_text: noqa_edit.into_content().unwrap_or_default().into_string(),
});
serde_json::to_value(AssociatedDiagnosticData {
title: suggestion.unwrap_or(name),
title: suggestion.unwrap_or_else(|| name.to_string()),
noqa_edit,
edits,
code: rule.noqa_code().to_string(),
Expand Down
Loading