-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
derive-msg-formats 4/5: Implement #[derive_message_formats]
The idea is nice and simple we replace: fn placeholder() -> Self; with fn message_formats() -> &'static [&'static str]; So e.g. if a Violation implementation defines: fn message(&self) -> String { format!("Local variable `{name}` is assigned to but never used") } it would also have to define: fn message_formats() -> &'static [&'static str] { &["Local variable `{name}` is assigned to but never used"] } Since we however obviously do not want to duplicate all of our format strings we simply introduce a new procedural macro attribute #[derive_message_formats] that can be added to the message method declaration in order to automatically derive the message_formats implementation. This commit implements the macro. The following and final commit updates violations.rs to use the macro. (The changes have been separated because the next commit is autogenerated via a Python script.)
- Loading branch information
1 parent
72ffa07
commit 707da7c
Showing
10 changed files
with
87 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use proc_macro2::TokenStream; | ||
use quote::{quote, quote_spanned, ToTokens}; | ||
use syn::spanned::Spanned; | ||
use syn::{Block, Expr, ItemFn, Stmt}; | ||
|
||
pub fn derive_message_formats(func: &ItemFn) -> proc_macro2::TokenStream { | ||
let mut strings = quote!(); | ||
|
||
if let Err(err) = parse_block(&func.block, &mut strings) { | ||
return err; | ||
} | ||
|
||
quote! { | ||
#func | ||
fn message_formats() -> &'static [&'static str] { | ||
&[#strings] | ||
} | ||
} | ||
} | ||
|
||
fn parse_block(block: &Block, strings: &mut TokenStream) -> Result<(), TokenStream> { | ||
let Some(Stmt::Expr(last)) = block.stmts.last() else {panic!("expected last statement in block to be an expression")}; | ||
parse_expr(last, strings)?; | ||
Ok(()) | ||
} | ||
|
||
fn parse_expr(expr: &Expr, strings: &mut TokenStream) -> Result<(), TokenStream> { | ||
match expr { | ||
Expr::Macro(mac) if mac.mac.path.is_ident("format") => { | ||
let Some(first_token) = mac.mac.tokens.to_token_stream().into_iter().next() else { | ||
return Err(quote_spanned!(expr.span() => compile_error!("expected format! to have an argument"))) | ||
}; | ||
strings.extend(quote! {#first_token,}); | ||
Ok(()) | ||
} | ||
Expr::Block(block) => parse_block(&block.block, strings), | ||
Expr::If(expr) => { | ||
parse_block(&expr.then_branch, strings)?; | ||
if let Some((_, then)) = &expr.else_branch { | ||
parse_expr(then, strings)?; | ||
} | ||
Ok(()) | ||
} | ||
Expr::Match(block) => { | ||
for arm in &block.arms { | ||
parse_expr(&arm.body, strings)?; | ||
} | ||
Ok(()) | ||
} | ||
_ => Err(quote_spanned!( | ||
expr.span() => | ||
compile_error!("expected last expression to be a format! macro or a match block") | ||
)), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
#![allow(clippy::useless_format)] | ||
pub mod eradicate; | ||
pub mod flake8_2020; | ||
pub mod flake8_annotations; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters