Improve automatic_links globally
This commit is contained in:
parent
f467b8d77c
commit
7f839b2ece
|
@ -1891,14 +1891,14 @@ declare_lint! {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// The `automatic_links` lint detects when a URL/email address could be
|
/// The `automatic_links` lint detects when a URL could be written using
|
||||||
/// written using only angle brackets. This is a `rustdoc` only lint, see
|
/// only angle brackets. This is a `rustdoc` only lint, see the
|
||||||
/// the documentation in the [rustdoc book].
|
/// documentation in the [rustdoc book].
|
||||||
///
|
///
|
||||||
/// [rustdoc book]: ../../../rustdoc/lints.html#automatic_links
|
/// [rustdoc book]: ../../../rustdoc/lints.html#automatic_links
|
||||||
pub AUTOMATIC_LINKS,
|
pub AUTOMATIC_LINKS,
|
||||||
Allow,
|
Warn,
|
||||||
"detects URLs/email adresses that could be written using only angle brackets"
|
"detects URLs that could be written using only angle brackets"
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
|
|
|
@ -288,12 +288,10 @@ warning: 2 warnings emitted
|
||||||
|
|
||||||
## automatic_links
|
## automatic_links
|
||||||
|
|
||||||
This link is **allowed by default** and is **nightly-only**. It detects links
|
This lint is **nightly-only** and **warns by default**. It detects links which
|
||||||
which could use the "automatic" link syntax. For example:
|
could use the "automatic" link syntax. For example:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
#![warn(automatic_links)]
|
|
||||||
|
|
||||||
/// http://hello.rs
|
/// http://hello.rs
|
||||||
/// [http://a.com](http://a.com)
|
/// [http://a.com](http://a.com)
|
||||||
/// [http://b.com]
|
/// [http://b.com]
|
||||||
|
@ -305,17 +303,12 @@ pub fn foo() {}
|
||||||
Which will give:
|
Which will give:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
warning: won't be a link as is
|
warning: this URL is not a hyperlink
|
||||||
--> foo.rs:3:5
|
--> foo.rs:3:5
|
||||||
|
|
|
|
||||||
3 | /// http://hello.rs
|
3 | /// http://hello.rs
|
||||||
| ^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://hello.rs>`
|
| ^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://hello.rs>`
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> foo.rs:1:9
|
|
||||||
|
|
|
||||||
1 | #![warn(automatic_links)]
|
|
||||||
| ^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unneeded long form for URL
|
warning: unneeded long form for URL
|
||||||
--> foo.rs:4:5
|
--> foo.rs:4:5
|
||||||
|
|
|
@ -13,11 +13,15 @@ use rustc_session::lint;
|
||||||
pub const CHECK_AUTOMATIC_LINKS: Pass = Pass {
|
pub const CHECK_AUTOMATIC_LINKS: Pass = Pass {
|
||||||
name: "check-automatic-links",
|
name: "check-automatic-links",
|
||||||
run: check_automatic_links,
|
run: check_automatic_links,
|
||||||
description: "detects URLS/email addresses that could be written using angle brackets",
|
description: "detects URLS that could be written using angle brackets",
|
||||||
};
|
};
|
||||||
|
|
||||||
const URL_REGEX: &str =
|
const URL_REGEX: &str = concat!(
|
||||||
r"https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)";
|
r"https?://", // url scheme
|
||||||
|
r"([-a-zA-Z0-9@:%._\+~#=]{2,256}\.)+", // one or more subdomains
|
||||||
|
r"[a-zA-Z]{2,4}", // root domain
|
||||||
|
r"\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)" // optional query or url fragments
|
||||||
|
);
|
||||||
|
|
||||||
struct AutomaticLinksLinter<'a, 'tcx> {
|
struct AutomaticLinksLinter<'a, 'tcx> {
|
||||||
cx: &'a DocContext<'tcx>,
|
cx: &'a DocContext<'tcx>,
|
||||||
|
@ -35,22 +39,16 @@ impl<'a, 'tcx> AutomaticLinksLinter<'a, 'tcx> {
|
||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
f: &impl Fn(&DocContext<'_>, &str, &str, Range<usize>),
|
f: &impl Fn(&DocContext<'_>, &str, &str, Range<usize>),
|
||||||
) {
|
) {
|
||||||
for (pos, c) in text.char_indices() {
|
// For now, we only check "full" URLs (meaning, starting with "http://" or "https://").
|
||||||
// For now, we only check "full" URLs.
|
for match_ in self.regex.find_iter(&text) {
|
||||||
if c == 'h' {
|
let url = match_.as_str();
|
||||||
let text = &text[pos..];
|
let url_range = match_.range();
|
||||||
if text.starts_with("http://") || text.starts_with("https://") {
|
f(
|
||||||
if let Some(m) = self.regex.find(text) {
|
self.cx,
|
||||||
let url = &text[..m.end()];
|
"this URL is not a hyperlink",
|
||||||
f(
|
url,
|
||||||
self.cx,
|
Range { start: range.start + url_range.start, end: range.start + url_range.end },
|
||||||
"won't be a link as is",
|
);
|
||||||
url,
|
|
||||||
Range { start: range.start + pos, end: range.start + pos + m.end() },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,6 +104,7 @@ impl<'a, 'tcx> DocFolder for AutomaticLinksLinter<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
Event::End(Tag::Link(_, url, _)) => {
|
Event::End(Tag::Link(_, url, _)) => {
|
||||||
in_link = false;
|
in_link = false;
|
||||||
|
// NOTE: links cannot be nested, so we don't need to check `kind`
|
||||||
if url.as_ref() == title && !ignore {
|
if url.as_ref() == title && !ignore {
|
||||||
report_diag(self.cx, "unneeded long form for URL", &url, range);
|
report_diag(self.cx, "unneeded long form for URL", &url, range);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,40 @@
|
||||||
/// [http://c.com][http://c.com]
|
/// [http://c.com][http://c.com]
|
||||||
pub fn a() {}
|
pub fn a() {}
|
||||||
|
|
||||||
|
/// https://somewhere.com
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// https://somewhere.com/a
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// https://www.somewhere.com
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// https://www.somewhere.com/a
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// https://subdomain.example.com
|
||||||
|
//~^ ERROR not a hyperlink
|
||||||
|
/// https://somewhere.com?
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// https://somewhere.com/a?
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
/// https://somewhere.com?hello=12
|
/// https://somewhere.com?hello=12
|
||||||
//~^ ERROR won't be a link as is
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// https://somewhere.com/a?hello=12
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// https://example.com?hello=12#xyz
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// https://example.com/a?hello=12#xyz
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// https://example.com#xyz
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// https://example.com/a#xyz
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// https://somewhere.com?hello=12&bye=11
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// https://somewhere.com/a?hello=12&bye=11
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// https://somewhere.com?hello=12&bye=11#xyz
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
|
/// hey! https://somewhere.com/a?hello=12&bye=11#xyz
|
||||||
|
//~^ ERROR this URL is not a hyperlink
|
||||||
pub fn c() {}
|
pub fn c() {}
|
||||||
|
|
||||||
/// <https://somewhere.com>
|
/// <https://somewhere.com>
|
||||||
|
@ -20,3 +52,9 @@ pub fn c() {}
|
||||||
///
|
///
|
||||||
/// [b]: http://b.com
|
/// [b]: http://b.com
|
||||||
pub fn everything_is_fine_here() {}
|
pub fn everything_is_fine_here() {}
|
||||||
|
|
||||||
|
#[allow(automatic_links)]
|
||||||
|
pub mod foo {
|
||||||
|
/// https://somewhere.com/a?hello=12&bye=11#xyz
|
||||||
|
pub fn bar() {}
|
||||||
|
}
|
||||||
|
|
|
@ -16,11 +16,107 @@ error: unneeded long form for URL
|
||||||
LL | /// [http://b.com]
|
LL | /// [http://b.com]
|
||||||
| ^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://b.com>`
|
| ^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://b.com>`
|
||||||
|
|
||||||
error: won't be a link as is
|
error: this URL is not a hyperlink
|
||||||
--> $DIR/automatic-links.rs:13:5
|
--> $DIR/automatic-links.rs:13:5
|
||||||
|
|
|
|
||||||
|
LL | /// https://somewhere.com
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:15:5
|
||||||
|
|
|
||||||
|
LL | /// https://somewhere.com/a
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:17:5
|
||||||
|
|
|
||||||
|
LL | /// https://www.somewhere.com
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://www.somewhere.com>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:19:5
|
||||||
|
|
|
||||||
|
LL | /// https://www.somewhere.com/a
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://www.somewhere.com/a>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:21:5
|
||||||
|
|
|
||||||
|
LL | /// https://subdomain.example.com
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://subdomain.example.com>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:23:5
|
||||||
|
|
|
||||||
|
LL | /// https://somewhere.com?
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:25:5
|
||||||
|
|
|
||||||
|
LL | /// https://somewhere.com/a?
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:27:5
|
||||||
|
|
|
||||||
LL | /// https://somewhere.com?hello=12
|
LL | /// https://somewhere.com?hello=12
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?hello=12>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?hello=12>`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:29:5
|
||||||
|
|
|
||||||
|
LL | /// https://somewhere.com/a?hello=12
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?hello=12>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:31:5
|
||||||
|
|
|
||||||
|
LL | /// https://example.com?hello=12#xyz
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com?hello=12#xyz>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:33:5
|
||||||
|
|
|
||||||
|
LL | /// https://example.com/a?hello=12#xyz
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com/a?hello=12#xyz>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:35:5
|
||||||
|
|
|
||||||
|
LL | /// https://example.com#xyz
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com#xyz>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:37:5
|
||||||
|
|
|
||||||
|
LL | /// https://example.com/a#xyz
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com/a#xyz>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:39:5
|
||||||
|
|
|
||||||
|
LL | /// https://somewhere.com?hello=12&bye=11
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?hello=12&bye=11>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:41:5
|
||||||
|
|
|
||||||
|
LL | /// https://somewhere.com/a?hello=12&bye=11
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?hello=12&bye=11>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:43:5
|
||||||
|
|
|
||||||
|
LL | /// https://somewhere.com?hello=12&bye=11#xyz
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?hello=12&bye=11#xyz>`
|
||||||
|
|
||||||
|
error: this URL is not a hyperlink
|
||||||
|
--> $DIR/automatic-links.rs:45:10
|
||||||
|
|
|
||||||
|
LL | /// hey! https://somewhere.com/a?hello=12&bye=11#xyz
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?hello=12&bye=11#xyz>`
|
||||||
|
|
||||||
|
error: aborting due to 19 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue