1
Fork 0

lint: port hidden unicode codepoints diagnostics

Signed-off-by: David Wood <david.wood@huawei.com>
This commit is contained in:
David Wood 2022-06-27 14:40:55 +01:00
parent a0624eb6c9
commit fd57269e8c
2 changed files with 27 additions and 30 deletions

View file

@ -15,3 +15,16 @@ lint-enum-intrinsics-mem-variant =
lint-expectation = this lint expectation is unfulfilled lint-expectation = this lint expectation is unfulfilled
.note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message .note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
lint-hidden-unicode-codepoints = unicode codepoint changing visible direction of text present in {$label}
.label = this {$label} contains {$count ->
[one] an invisible
*[other] invisible
} unicode text flow control {$count ->
[one] codepoint
*[other] codepoints
}
.note = these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
.suggestion-remove = if their presence wasn't intentional, you can remove them
.suggestion-escape = if you want to keep them but make them visible in your source code, you can escape them
.no-suggestion-note-escape = if you want to keep them but make them visible in your source code, you can escape them: {$escaped}

View file

@ -1,7 +1,7 @@
use crate::{EarlyContext, EarlyLintPass, LintContext}; use crate::{EarlyContext, EarlyLintPass, LintContext};
use ast::util::unicode::{contains_text_flow_control_chars, TEXT_FLOW_CONTROL_CHARS}; use ast::util::unicode::{contains_text_flow_control_chars, TEXT_FLOW_CONTROL_CHARS};
use rustc_ast as ast; use rustc_ast as ast;
use rustc_errors::{Applicability, SuggestionStyle}; use rustc_errors::{fluent, Applicability, SuggestionStyle};
use rustc_span::{BytePos, Span, Symbol}; use rustc_span::{BytePos, Span, Symbol};
declare_lint! { declare_lint! {
@ -61,41 +61,25 @@ impl HiddenUnicodeCodepoints {
.collect(); .collect();
cx.struct_span_lint(TEXT_DIRECTION_CODEPOINT_IN_LITERAL, span, |lint| { cx.struct_span_lint(TEXT_DIRECTION_CODEPOINT_IN_LITERAL, span, |lint| {
let mut err = lint.build(&format!( let mut err = lint.build(fluent::lint::hidden_unicode_codepoints);
"unicode codepoint changing visible direction of text present in {}", err.set_arg("label", label);
label err.set_arg("count", spans.len());
)); err.span_label(span, fluent::lint::label);
let (an, s) = match spans.len() { err.note(fluent::lint::note);
1 => ("an ", ""),
_ => ("", "s"),
};
err.span_label(
span,
&format!(
"this {} contains {}invisible unicode text flow control codepoint{}",
label, an, s,
),
);
if point_at_inner_spans { if point_at_inner_spans {
for (c, span) in &spans { for (c, span) in &spans {
err.span_label(*span, format!("{:?}", c)); err.span_label(*span, format!("{:?}", c));
} }
} }
err.note(
"these kind of unicode codepoints change the way text flows on applications that \
support them, but can cause confusion because they change the order of \
characters on the screen",
);
if point_at_inner_spans && !spans.is_empty() { if point_at_inner_spans && !spans.is_empty() {
err.multipart_suggestion_with_style( err.multipart_suggestion_with_style(
"if their presence wasn't intentional, you can remove them", fluent::lint::suggestion_remove,
spans.iter().map(|(_, span)| (*span, "".to_string())).collect(), spans.iter().map(|(_, span)| (*span, "".to_string())).collect(),
Applicability::MachineApplicable, Applicability::MachineApplicable,
SuggestionStyle::HideCodeAlways, SuggestionStyle::HideCodeAlways,
); );
err.multipart_suggestion( err.multipart_suggestion(
"if you want to keep them but make them visible in your source code, you can \ fluent::lint::suggestion_escape,
escape them",
spans spans
.into_iter() .into_iter()
.map(|(c, span)| { .map(|(c, span)| {
@ -109,16 +93,16 @@ impl HiddenUnicodeCodepoints {
// FIXME: in other suggestions we've reversed the inner spans of doc comments. We // FIXME: in other suggestions we've reversed the inner spans of doc comments. We
// should do the same here to provide the same good suggestions as we do for // should do the same here to provide the same good suggestions as we do for
// literals above. // literals above.
err.note("if their presence wasn't intentional, you can remove them"); err.set_arg(
err.note(&format!( "escaped",
"if you want to keep them but make them visible in your source code, you can \
escape them: {}",
spans spans
.into_iter() .into_iter()
.map(|(c, _)| { format!("{:?}", c) }) .map(|(c, _)| format!("{:?}", c))
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join(", "), .join(", "),
)); );
err.note(fluent::lint::suggestion_remove);
err.note(fluent::lint::no_suggestion_note_escape);
} }
err.emit(); err.emit();
}); });