From: Guillaume Gomez Date: Sat, 31 Oct 2020 14:14:44 +0000 (+0100) Subject: Rename lint to non_autolinks X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=9d114506c68ce717503d0fa1eb335db5c80c195f;p=rust.git Rename lint to non_autolinks --- diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index ad353bb28c9..24bfdad970a 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -69,7 +69,7 @@ use rustc_session::lint::builtin::{ BARE_TRAIT_OBJECTS, BROKEN_INTRA_DOC_LINKS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, INVALID_CODEBLOCK_ATTRIBUTES, INVALID_HTML_TAGS, - MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, URL_IMPROVEMENTS, + MISSING_DOC_CODE_EXAMPLES, NON_AUTOLINKS, PRIVATE_DOC_TESTS, }; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::Span; @@ -313,7 +313,7 @@ macro_rules! register_passes { add_lint_group!( "rustdoc", - URL_IMPROVEMENTS, + NON_AUTOLINKS, BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS, INVALID_CODEBLOCK_ATTRIBUTES, diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index c74680c172f..ff7a145c266 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1891,12 +1891,12 @@ } declare_lint! { - /// The `url_improvements` lint detects when a URL could be written using + /// The `non_autolinks` lint detects when a URL could be written using /// only angle brackets. This is a `rustdoc` only lint, see the /// documentation in the [rustdoc book]. /// - /// [rustdoc book]: ../../../rustdoc/lints.html#url_improvements - pub URL_IMPROVEMENTS, + /// [rustdoc book]: ../../../rustdoc/lints.html#non_autolinks + pub NON_AUTOLINKS, Warn, "detects URLs that could be written using only angle brackets" } @@ -2806,7 +2806,7 @@ MISSING_DOC_CODE_EXAMPLES, INVALID_HTML_TAGS, PRIVATE_DOC_TESTS, - URL_IMPROVEMENTS, + NON_AUTOLINKS, WHERE_CLAUSES_OBJECT_SAFETY, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, MACRO_USE_EXTERN_CRATE, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 8596d52ceae..069e6e7e718 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -287,7 +287,7 @@ unused_imports, unsafe_op_in_unsafe_fn )] -#[cfg_attr(not(bootstrap), allow(url_improvements))] +#[cfg_attr(not(bootstrap), allow(non_autolinks))] // FIXME: This annotation should be moved into rust-lang/stdarch after clashing_extern_declarations is // merged. It currently cannot because bootstrap fails as the lint hasn't been defined yet. #[allow(clashing_extern_declarations)] diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index a89c094bf4c..41292b3d838 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -286,7 +286,7 @@ warning: unclosed HTML tag `h1` warning: 2 warnings emitted ``` -## url_improvements +## non_autolinks This lint is **nightly-only** and **warns by default**. It detects links which could use the "automatic" link syntax. For example: @@ -309,7 +309,7 @@ warning: this URL is not a hyperlink 1 | /// http://example.org | ^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` | - = note: `#[warn(url_improvements)]` on by default + = note: `#[warn(non_autolinks)]` on by default warning: unneeded long form for URL --> foo.rs:2:5 diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 85d73a30e4b..5cb7a32cf0c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -330,7 +330,7 @@ pub fn run_core( let invalid_codeblock_attributes_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES.name; let invalid_html_tags = rustc_lint::builtin::INVALID_HTML_TAGS.name; let renamed_and_removed_lints = rustc_lint::builtin::RENAMED_AND_REMOVED_LINTS.name; - let url_improvements = rustc_lint::builtin::URL_IMPROVEMENTS.name; + let non_autolinks = rustc_lint::builtin::NON_AUTOLINKS.name; let unknown_lints = rustc_lint::builtin::UNKNOWN_LINTS.name; // In addition to those specific lints, we also need to allow those given through @@ -345,7 +345,7 @@ pub fn run_core( invalid_html_tags.to_owned(), renamed_and_removed_lints.to_owned(), unknown_lints.to_owned(), - url_improvements.to_owned(), + non_autolinks.to_owned(), ]; let (lint_opts, lint_caps) = init_lints(lints_to_show, lint_opts, |lint| { diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index fa8bd24efa9..047a73835c8 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -11,8 +11,8 @@ mod stripper; pub use stripper::*; -mod url_improvements; -pub use self::url_improvements::CHECK_URL_IMPROVEMENTS; +mod non_autolinks; +pub use self::non_autolinks::CHECK_NON_AUTOLINKS; mod collapse_docs; pub use self::collapse_docs::COLLAPSE_DOCS; @@ -93,7 +93,7 @@ pub enum Condition { COLLECT_TRAIT_IMPLS, CALCULATE_DOC_COVERAGE, CHECK_INVALID_HTML_TAGS, - CHECK_URL_IMPROVEMENTS, + CHECK_NON_AUTOLINKS, ]; /// The list of passes run by default. @@ -109,7 +109,7 @@ pub enum Condition { ConditionalPass::always(CHECK_CODE_BLOCK_SYNTAX), ConditionalPass::always(CHECK_INVALID_HTML_TAGS), ConditionalPass::always(PROPAGATE_DOC_CFG), - ConditionalPass::always(CHECK_URL_IMPROVEMENTS), + ConditionalPass::always(CHECK_NON_AUTOLINKS), ]; /// The list of default passes run when `--doc-coverage` is passed to rustdoc. diff --git a/src/librustdoc/passes/non_autolinks.rs b/src/librustdoc/passes/non_autolinks.rs new file mode 100644 index 00000000000..4a8fc7fc618 --- /dev/null +++ b/src/librustdoc/passes/non_autolinks.rs @@ -0,0 +1,139 @@ +use super::{span_of_attrs, Pass}; +use crate::clean::*; +use crate::core::DocContext; +use crate::fold::DocFolder; +use crate::html::markdown::opts; +use core::ops::Range; +use pulldown_cmark::{Event, LinkType, Parser, Tag}; +use regex::Regex; +use rustc_errors::Applicability; +use rustc_feature::UnstableFeatures; +use rustc_session::lint; + +pub const CHECK_NON_AUTOLINKS: Pass = Pass { + name: "check-non-autolinks", + run: check_non_autolinks, + description: "detects URLS that could be written using angle brackets", +}; + +const URL_REGEX: &str = concat!( + r"https?://", // url scheme + r"([-a-zA-Z0-9@:%._\+~#=]{2,256}\.)+", // one or more subdomains + r"[a-zA-Z]{2,63}", // root domain + r"\b([-a-zA-Z0-9@:%_\+.~#?&/=]*)" // optional query or url fragments +); + +struct NonAutolinksLinter<'a, 'tcx> { + cx: &'a DocContext<'tcx>, + regex: Regex, +} + +impl<'a, 'tcx> NonAutolinksLinter<'a, 'tcx> { + fn new(cx: &'a DocContext<'tcx>) -> Self { + Self { cx, regex: Regex::new(URL_REGEX).expect("failed to build regex") } + } + + fn find_raw_urls( + &self, + text: &str, + range: Range, + f: &impl Fn(&DocContext<'_>, &str, &str, Range), + ) { + // For now, we only check "full" URLs (meaning, starting with "http://" or "https://"). + for match_ in self.regex.find_iter(&text) { + let url = match_.as_str(); + let url_range = match_.range(); + f( + self.cx, + "this URL is not a hyperlink", + url, + Range { start: range.start + url_range.start, end: range.start + url_range.end }, + ); + } + } +} + +pub fn check_non_autolinks(krate: Crate, cx: &DocContext<'_>) -> Crate { + if !UnstableFeatures::from_environment().is_nightly_build() { + krate + } else { + let mut coll = NonAutolinksLinter::new(cx); + + coll.fold_crate(krate) + } +} + +impl<'a, 'tcx> DocFolder for NonAutolinksLinter<'a, 'tcx> { + fn fold_item(&mut self, item: Item) -> Option { + let hir_id = match self.cx.as_local_hir_id(item.def_id) { + Some(hir_id) => hir_id, + None => { + // If non-local, no need to check anything. + return self.fold_item_recur(item); + } + }; + let dox = item.attrs.collapsed_doc_value().unwrap_or_default(); + if !dox.is_empty() { + let report_diag = |cx: &DocContext<'_>, msg: &str, url: &str, range: Range| { + let sp = super::source_span_for_markdown_range(cx, &dox, &range, &item.attrs) + .or_else(|| span_of_attrs(&item.attrs)) + .unwrap_or(item.source.span()); + cx.tcx.struct_span_lint_hir(lint::builtin::NON_AUTOLINKS, hir_id, sp, |lint| { + lint.build(msg) + .span_suggestion( + sp, + "use an automatic link instead", + format!("<{}>", url), + Applicability::MachineApplicable, + ) + .emit() + }); + }; + + let mut p = Parser::new_ext(&dox, opts()).into_offset_iter(); + + while let Some((event, range)) = p.next() { + match event { + Event::Start(Tag::Link(kind, _, _)) => { + let ignore = matches!(kind, LinkType::Autolink | LinkType::Email); + let mut title = String::new(); + + while let Some((event, range)) = p.next() { + match event { + Event::End(Tag::Link(_, url, _)) => { + // NOTE: links cannot be nested, so we don't need to + // check `kind` + if url.as_ref() == title && !ignore && self.regex.is_match(&url) + { + report_diag( + self.cx, + "unneeded long form for URL", + &url, + range, + ); + } + break; + } + Event::Text(s) if !ignore => title.push_str(&s), + _ => {} + } + } + } + Event::Text(s) => self.find_raw_urls(&s, range, &report_diag), + Event::Start(Tag::CodeBlock(_)) => { + // We don't want to check the text inside the code blocks. + while let Some((event, _)) = p.next() { + match event { + Event::End(Tag::CodeBlock(_)) => break, + _ => {} + } + } + } + _ => {} + } + } + } + + self.fold_item_recur(item) + } +} diff --git a/src/librustdoc/passes/url_improvements.rs b/src/librustdoc/passes/url_improvements.rs deleted file mode 100644 index f09c44b41c9..00000000000 --- a/src/librustdoc/passes/url_improvements.rs +++ /dev/null @@ -1,138 +0,0 @@ -use super::{span_of_attrs, Pass}; -use crate::clean::*; -use crate::core::DocContext; -use crate::fold::DocFolder; -use crate::html::markdown::opts; -use core::ops::Range; -use pulldown_cmark::{Event, LinkType, Parser, Tag}; -use regex::Regex; -use rustc_errors::Applicability; -use rustc_feature::UnstableFeatures; -use rustc_session::lint; - -pub const CHECK_URL_IMPROVEMENTS: Pass = Pass { - name: "check-url-improvements", - run: check_url_improvements, - description: "detects URLS that could be written using angle brackets", -}; - -const URL_REGEX: &str = concat!( - r"https?://", // url scheme - r"([-a-zA-Z0-9@:%._\+~#=]{2,256}\.)+", // one or more subdomains - r"[a-zA-Z]{2,63}", // root domain - r"\b([-a-zA-Z0-9@:%_\+.~#?&/=]*)" // optional query or url fragments -); - -struct UrlImprovementsLinter<'a, 'tcx> { - cx: &'a DocContext<'tcx>, - regex: Regex, -} - -impl<'a, 'tcx> UrlImprovementsLinter<'a, 'tcx> { - fn new(cx: &'a DocContext<'tcx>) -> Self { - UrlImprovementsLinter { cx, regex: Regex::new(URL_REGEX).expect("failed to build regex") } - } - - fn find_raw_urls( - &self, - text: &str, - range: Range, - f: &impl Fn(&DocContext<'_>, &str, &str, Range), - ) { - // For now, we only check "full" URLs (meaning, starting with "http://" or "https://"). - for match_ in self.regex.find_iter(&text) { - let url = match_.as_str(); - let url_range = match_.range(); - f( - self.cx, - "this URL is not a hyperlink", - url, - Range { start: range.start + url_range.start, end: range.start + url_range.end }, - ); - } - } -} - -pub fn check_url_improvements(krate: Crate, cx: &DocContext<'_>) -> Crate { - if !UnstableFeatures::from_environment().is_nightly_build() { - krate - } else { - let mut coll = UrlImprovementsLinter::new(cx); - - coll.fold_crate(krate) - } -} - -impl<'a, 'tcx> DocFolder for UrlImprovementsLinter<'a, 'tcx> { - fn fold_item(&mut self, item: Item) -> Option { - let hir_id = match self.cx.as_local_hir_id(item.def_id) { - Some(hir_id) => hir_id, - None => { - // If non-local, no need to check anything. - return self.fold_item_recur(item); - } - }; - let dox = item.attrs.collapsed_doc_value().unwrap_or_default(); - if !dox.is_empty() { - let report_diag = |cx: &DocContext<'_>, msg: &str, url: &str, range: Range| { - let sp = super::source_span_for_markdown_range(cx, &dox, &range, &item.attrs) - .or_else(|| span_of_attrs(&item.attrs)) - .unwrap_or(item.source.span()); - cx.tcx.struct_span_lint_hir(lint::builtin::URL_IMPROVEMENTS, hir_id, sp, |lint| { - lint.build(msg) - .span_suggestion( - sp, - "use an automatic link instead", - format!("<{}>", url), - Applicability::MachineApplicable, - ) - .emit() - }); - }; - - let mut p = Parser::new_ext(&dox, opts()).into_offset_iter(); - - while let Some((event, range)) = p.next() { - match event { - Event::Start(Tag::Link(kind, _, _)) => { - let ignore = matches!(kind, LinkType::Autolink | LinkType::Email); - let mut title = String::new(); - - while let Some((event, range)) = p.next() { - match event { - Event::End(Tag::Link(_, url, _)) => { - // NOTE: links cannot be nested, so we don't need to - // check `kind` - if url.as_ref() == title && !ignore && self.regex.matches(url) { - report_diag( - self.cx, - "unneeded long form for URL", - &url, - range, - ); - } - break; - } - Event::Text(s) if !ignore => title.push_str(&s), - _ => {} - } - } - } - Event::Text(s) => self.find_raw_urls(&s, range, &report_diag), - Event::Start(Tag::CodeBlock(_)) => { - // We don't want to check the text inside the code blocks. - while let Some((event, _)) = p.next() { - match event { - Event::End(Tag::CodeBlock(_)) => break, - _ => {} - } - } - } - _ => {} - } - } - } - - self.fold_item_recur(item) - } -} diff --git a/src/test/rustdoc-ui/url-improvements.rs b/src/test/rustdoc-ui/url-improvements.rs index b7b1c26cd6d..8531583d38a 100644 --- a/src/test/rustdoc-ui/url-improvements.rs +++ b/src/test/rustdoc-ui/url-improvements.rs @@ -1,11 +1,11 @@ -#![deny(url_improvements)] +#![deny(non_autolinks)] -/// [http://a.com](http://a.com) +/// [http://aa.com](http://aa.com) //~^ ERROR unneeded long form for URL -/// [http://b.com] +/// [http://bb.com] //~^ ERROR unneeded long form for URL /// -/// [http://b.com]: http://b.com +/// [http://bb.com]: http://bb.com /// /// [http://c.com][http://c.com] pub fn a() {} @@ -59,7 +59,7 @@ pub fn c() {} /// [should_not.lint](should_not.lint) pub fn everything_is_fine_here() {} -#[allow(url_improvements)] +#[allow(non_autolinks)] pub mod foo { /// https://somewhere.com/a?hello=12&bye=11#xyz pub fn bar() {} diff --git a/src/test/rustdoc-ui/url-improvements.stderr b/src/test/rustdoc-ui/url-improvements.stderr index e8ed2331dd8..70ad4b06a51 100644 --- a/src/test/rustdoc-ui/url-improvements.stderr +++ b/src/test/rustdoc-ui/url-improvements.stderr @@ -1,20 +1,20 @@ error: unneeded long form for URL --> $DIR/url-improvements.rs:3:5 | -LL | /// [http://a.com](http://a.com) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` +LL | /// [http://aa.com](http://aa.com) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` | note: the lint level is defined here --> $DIR/url-improvements.rs:1:9 | -LL | #![deny(url_improvements)] - | ^^^^^^^^^^^^^^^^ +LL | #![deny(non_autolinks)] + | ^^^^^^^^^^^^^ error: unneeded long form for URL --> $DIR/url-improvements.rs:5:5 | -LL | /// [http://b.com] - | ^^^^^^^^^^^^^^ help: use an automatic link instead: `` +LL | /// [http://bb.com] + | ^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink --> $DIR/url-improvements.rs:13:5