|
| 1 | +use clippy_utils::diagnostics::span_lint; |
| 2 | +use itertools::Itertools; |
| 3 | +use rustc_ast::{AttrKind, Attribute}; |
| 4 | +use rustc_lint::{EarlyContext, EarlyLintPass}; |
| 5 | +use rustc_session::{declare_lint_pass, declare_tool_lint}; |
| 6 | + |
| 7 | +declare_clippy_lint! { |
| 8 | + /// ### What it does |
| 9 | + /// Detects the syntax `['foo']` in documentation comments (notice quotes instead of backticks) |
| 10 | + /// outside of code blocks |
| 11 | + /// ### Why is this bad? |
| 12 | + /// It is likely a typo when defining an intra-doc link |
| 13 | + /// |
| 14 | + /// ### Example |
| 15 | + /// ```rust |
| 16 | + /// /// See also: ['foo'] |
| 17 | + /// fn bar() {} |
| 18 | + /// ``` |
| 19 | + /// Use instead: |
| 20 | + /// ```rust |
| 21 | + /// /// See also: [`foo`] |
| 22 | + /// fn bar() {} |
| 23 | + /// ``` |
| 24 | + #[clippy::version = "1.60.0"] |
| 25 | + pub DOC_LINK_WITH_QUOTES, |
| 26 | + pedantic, |
| 27 | + "possible typo for an intra-doc link" |
| 28 | +} |
| 29 | +declare_lint_pass!(DocLinkWithQuotes => [DOC_LINK_WITH_QUOTES]); |
| 30 | + |
| 31 | +impl EarlyLintPass for DocLinkWithQuotes { |
| 32 | + fn check_attribute(&mut self, ctx: &EarlyContext<'_>, attr: &Attribute) { |
| 33 | + if let AttrKind::DocComment(_, symbol) = attr.kind { |
| 34 | + if contains_quote_link(symbol.as_str()) { |
| 35 | + span_lint( |
| 36 | + ctx, |
| 37 | + DOC_LINK_WITH_QUOTES, |
| 38 | + attr.span, |
| 39 | + "possible intra-doc link using quotes instead of backticks", |
| 40 | + ); |
| 41 | + } |
| 42 | + } |
| 43 | + } |
| 44 | +} |
| 45 | + |
| 46 | +fn contains_quote_link(s: &str) -> bool { |
| 47 | + let mut in_backticks = false; |
| 48 | + let mut found_opening = false; |
| 49 | + |
| 50 | + for c in s.chars().tuple_windows::<(char, char)>() { |
| 51 | + match c { |
| 52 | + ('`', _) => in_backticks = !in_backticks, |
| 53 | + ('[', '\'') if !in_backticks => found_opening = true, |
| 54 | + ('\'', ']') if !in_backticks && found_opening => return true, |
| 55 | + _ => {}, |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | + false |
| 60 | +} |
0 commit comments