use std::io; use biome_console::{markup, ConsoleExt, EnvConsole}; use biome_diagnostics::{ Advices, Diagnostic, Location, LogCategory, PrintDiagnostic, Resource, SourceCode, Visit, }; use biome_rowan::{TextRange, TextSize}; use biome_text_edit::TextEdit; #[derive(Debug, Diagnostic)] #[diagnostic( category = "lint/style/noShoutyConstants", message = "Redundant constant reference", tags(FIXABLE) )] struct LintDiagnostic { #[location(resource)] path: String, #[location(span)] span: TextRange, #[location(source_code)] source_code: String, #[advice] advices: LintAdvices, #[verbose_advice] verbose_advices: LintVerboseAdvices, } #[derive(Debug)] struct LintAdvices { path: String, declaration_span: TextRange, source_code: String, code_action: TextEdit, } impl Advices for LintAdvices { fn record(&self, visitor: &mut dyn Visit) -> io::Result<()> { visitor.record_log( LogCategory::Info, &"You should avoid declaring constants with a string that's the same value as the variable name. It introduces a level of unnecessary indirection when it's only two additional characters to inline." )?; visitor.record_log(LogCategory::Info, &"This constant is declared here")?; visitor.record_frame(Location { resource: Some(Resource::File(&self.path)), span: Some(self.declaration_span), source_code: Some(SourceCode { text: &self.source_code, line_starts: None, }), })?; visitor.record_log(LogCategory::Info, &"Safe Fix")?; visitor.record_diff(&self.code_action) } } #[derive(Debug)] struct LintVerboseAdvices { path: String, } impl Advices for LintVerboseAdvices { fn record(&self, visitor: &mut dyn Visit) -> io::Result<()> { visitor.record_log(LogCategory::Info, &"Apply this fix using `--apply`:")?; visitor.record_command(&format!("biome check --apply {}", self.path)) } } pub fn main() { const SOURCE: &str = "const FOO = \"FOO\"; console.log(FOO);"; const FIXED: &str = "console.log(\"FOO\");"; let diag = LintDiagnostic { path: String::from("style/noShoutyConstants.js"), span: TextRange::at(TextSize::from(31), TextSize::from(3)), source_code: String::from(SOURCE), advices: LintAdvices { path: String::from("style/noShoutyConstants.js"), declaration_span: TextRange::at(TextSize::from(6), TextSize::from(3)), source_code: String::from(SOURCE), code_action: TextEdit::from_unicode_words(SOURCE, FIXED), }, verbose_advices: LintVerboseAdvices { path: String::from("style/noShoutyConstants.js"), }, }; EnvConsole::default().error(markup!({ PrintDiagnostic::verbose(&diag) })); }