Skip to content

Commit

Permalink
Update clang-tidy text style check (#34716)
Browse files Browse the repository at this point in the history
* Single space after semicolon

* Fix comment

* Update test

* Disable ellipsis space check in the middle of lines

* Remove spaces after ellipses that start a line

* Remove spaces before punctuations

* Ignore ter_bind and furn_bind strings
  • Loading branch information
Qrox authored and ZhilkinSerg committed Oct 14, 2019
1 parent c97985d commit 1bfd265
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 66 deletions.
161 changes: 100 additions & 61 deletions tools/clang-tidy-plugin/TextStyleCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void TextStyleCheck::registerMatchers( MatchFinder *Finder )
callExpr(
callee(
functionDecl(
hasName( "formatted_set_simple" )
hasAnyName( "formatted_set_simple", "ter_bind", "furn_bind" )
)
)
)
Expand Down Expand Up @@ -108,6 +108,12 @@ void TextStyleCheck::check( const MatchFinder::MatchResult &Result )
size_t fix_end_max = 0;
// remove unnecessary spaces at line end (before '\n')
size_t fix_line_end_max = 0;
// remove unnecessary spaces after a symbol that starts a string
size_t fix_start_max = 0;
// remove unnecessary spaces after a symbol that starts a line (after '\n')
size_t fix_line_start_max = 0;
// remove unnecessary spaces before the symbol
size_t fix_before_max = 0;
} spaces;
struct {
bool yes;
Expand All @@ -121,21 +127,21 @@ void TextStyleCheck::check( const MatchFinder::MatchResult &Result )
// and search for them in this order.
// *INDENT-OFF*
static const std::array<punctuation, 13> punctuations = {{
// symbol,follow, spaces, replace,
// check, len, num spc end yes, string, escaped symbol desc, replc desc
{ U"...", U"", { true, 0, 1, 1, 3, 2, 2, 2 }, { true, "\u2026", R"(\u2026)", "three dots", "ellipsis" } },
{ U"::", U"", { false, }, { false, } },
{ U"\r\n", U"", { false, }, { true, R"(\n)", R"(\n)", "carriage return", "new line" } },
{ U"\u2026", U"", { true, 0, 1, 1, 3, 2, 2, 2 }, { false, } },
{ U".", U"", { true, 0, 3, 1, 3, 2, 0, 2 }, { false, } },
{ U";", U"", { true, 0, 1, 1, 3, 2, 2, 2 }, { false, } },
{ U"!", U"!?", { true, 0, 1, 1, 3, 2, 2, 2 }, { false, } },
{ U"?", U"!?", { true, 0, 1, 1, 3, 2, 2, 2 }, { false, } },
{ U":", U"", { true, 0, 1, 1, 1, 1, 0, 1 }, { false, } },
{ U",", U"", { true, 0, 1, 1, 2, 1, 0, 1 }, { false, } },
{ U"\r", U"", { false, }, { true, R"(\n)", R"(\n)", "carriage return", "new line" } },
{ U"\n", U"", { true, 0, 0, 0, 0, 0, 1, 1 }, { false, } },
{ U"\t", U"", { false, }, { true, " ", " ", "tab", "spaces" } },
// symbol,follow, spaces, replace,
// check, len, num spc, end,start,before yes, string, escaped, symbol desc, replc desc
{ U"...", U"", { true, 0, 1, 0, 0, 0, 2, 2, 2, 2, 1 }, { true, "\u2026", R"(\u2026)", "three dots", "ellipsis" } },
{ U"::", U"", { false, }, { false, } },
{ U"\r\n", U"", { false, }, { true, R"(\n)", R"(\n)", "carriage return", "new line" } },
{ U"\u2026", U"", { true, 0, 1, 1, 3, 2, 2, 2, 2, 2, 1 }, { false, } },
{ U".", U"", { true, 0, 3, 1, 3, 2, 0, 2, 0, 0, 1 }, { false, } },
{ U";", U"", { true, 0, 1, 1, 2, 1, 1, 1, 0, 0, 1 }, { false, } },
{ U"!", U"!?", { true, 0, 1, 1, 3, 2, 2, 2, 0, 0, 1 }, { false, } },
{ U"?", U"!?", { true, 0, 1, 1, 3, 2, 2, 2, 0, 0, 1 }, { false, } },
{ U":", U"", { true, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1 }, { false, } },
{ U",", U"", { true, 0, 1, 1, 2, 1, 0, 1, 0, 0, 1 }, { false, } },
{ U"\r", U"", { false, }, { true, R"(\n)", R"(\n)", "carriage return", "new line" } },
{ U"\n", U"", { true, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1 }, { false, } },
{ U"\t", U"", { false, }, { true, " ", " ", "tab", "spaces" } },
}};
// *INDENT-ON*

Expand Down Expand Up @@ -181,6 +187,22 @@ void TextStyleCheck::check( const MatchFinder::MatchResult &Result )
}
}
if( punc->spaces.check && text_length >= punc->spaces.min_string_length ) {
size_t spacesbefore = 0;
auto itspacebefore = itpunc;
for( ; itspacebefore > beg; --itspacebefore, ++spacesbefore ) {
const uint32_t ch = *( itspacebefore - 1 );
if( ch != U' ' ) {
break;
}
}
if( spacesbefore > 0 && spacesbefore <= punc->spaces.fix_before_max ) {
const CharSourceRange range = CharSourceRange::getCharRange(
location( itspacebefore ), location( itpunc ) );
auto diags = diag( location( itpunc ), "unnecessary spaces before this location." );
if( fixit ) {
diags << FixItHint::CreateRemoval( range );
}
}
size_t wordlen = 0;
for( auto itword = itpunc; itword > beg; --itword, ++wordlen ) {
const uint32_t ch = *( itword - 1 );
Expand All @@ -189,57 +211,74 @@ void TextStyleCheck::check( const MatchFinder::MatchResult &Result )
break;
}
}
if( wordlen >= punc->spaces.min_word_length ) {
auto itspaceend = it;
size_t spacelen = 0;
for( ; itspaceend < end && *itspaceend == U' '; ++itspaceend, ++spacelen ) {
bool after_word = wordlen >= punc->spaces.min_word_length;
auto itspaceend = it;
size_t spacelen = 0;
for( ; itspaceend < end && *itspaceend == U' '; ++itspaceend, ++spacelen ) {
}
if( after_word && itspaceend >= end ) {
// treat spaces at the end of strings in concat expressions (+, += or <<) as deliberate
if( !in_concat_expr && spacelen > 0 && spacelen <= punc->spaces.fix_end_max ) {
const CharSourceRange range = CharSourceRange::getCharRange(
location( it ), location( itspaceend ) );
auto diags = diag( location( it ), "unnecessary spaces at end of string." );
if( fixit ) {
diags << FixItHint::CreateRemoval( range );
}
}
} else if( after_word && *itspaceend == U'\n' ) {
if( spacelen > 0 && spacelen <= punc->spaces.fix_line_end_max ) {
const CharSourceRange range = CharSourceRange::getCharRange(
location( it ), location( itspaceend ) );
auto diags = diag( location( it ), "unnecessary spaces at end of line." );
if( fixit ) {
diags << FixItHint::CreateRemoval( range );
}
}
if( itspaceend >= end ) {
// treat spaces at the end of strings in concat expressions (+, += or <<) as deliberate
if( !in_concat_expr && spacelen > 0 && spacelen <= punc->spaces.fix_end_max ) {
const CharSourceRange range = CharSourceRange::getCharRange(
location( it ), location( itspaceend ) );
auto diags = diag( location( it ), "unnecessary spaces at end of string." );
if( fixit ) {
diags << FixItHint::CreateRemoval( range );
}
} else if( itpunc <= beg ) {
if( spacelen > 0 && spacelen <= punc->spaces.fix_line_start_max ) {
const CharSourceRange range = CharSourceRange::getCharRange(
location( it ), location( itspaceend ) );
auto diags = diag( location( it ), "undesired spaces after a punctuation that starts a string." );
if( fixit ) {
diags << FixItHint::CreateRemoval( range );
}
} else if( *itspaceend == U'\n' ) {
if( spacelen > 0 && spacelen <= punc->spaces.fix_line_end_max ) {
const CharSourceRange range = CharSourceRange::getCharRange(
location( it ), location( itspaceend ) );
auto diags = diag( location( it ), "unnecessary spaces at end of line." );
if( fixit ) {
diags << FixItHint::CreateRemoval( range );
}
}
} else if( itpunc > beg && *( itpunc - 1 ) == U'\n' ) {
if( spacelen > 0 && spacelen <= punc->spaces.fix_start_max ) {
const CharSourceRange range = CharSourceRange::getCharRange(
location( it ), location( itspaceend ) );
auto diags = diag( location( it ), "undesired spaces after a punctuation that starts a line." );
if( fixit ) {
diags << FixItHint::CreateRemoval( range );
}
}
} else if( after_word ) {
if( spacelen >= punc->spaces.fix_spaces_min &&
spacelen < punc->spaces.fix_spaces_to ) {
auto diags = diag( location( it ),
"insufficient spaces at this location. %0 required, but only %1 found." )
<< static_cast<unsigned int>( punc->spaces.fix_spaces_to )
<< static_cast<unsigned int>( spacelen );
if( fixit ) {
diags << FixItHint::CreateInsertion( location( it ),
std::string( punc->spaces.fix_spaces_to - spacelen, ' ' ) );
}
} else {
if( spacelen >= punc->spaces.fix_spaces_min &&
spacelen < punc->spaces.fix_spaces_to ) {
auto diags = diag( location( it ),
"insufficient spaces at this location. %0 required, but only %1 found." )
<< static_cast<unsigned int>( punc->spaces.fix_spaces_to )
<< static_cast<unsigned int>( spacelen );
if( fixit ) {
diags << FixItHint::CreateInsertion( location( it ),
std::string( punc->spaces.fix_spaces_to - spacelen, ' ' ) );
}
} else if( spacelen > punc->spaces.fix_spaces_to &&
spacelen <= punc->spaces.fix_spaces_max ) {
const CharSourceRange range = CharSourceRange::getCharRange(
location( itspaceend - ( spacelen - punc->spaces.fix_spaces_to ) ),
location( itspaceend ) );
auto diags = diag( location( it ),
"excessive spaces at this location. %0 required, but %1 found." )
<< static_cast<unsigned int>( punc->spaces.fix_spaces_to )
<< static_cast<unsigned int>( spacelen );
if( fixit ) {
diags << FixItHint::CreateRemoval( range );
}
} else if( spacelen > punc->spaces.fix_spaces_to &&
spacelen <= punc->spaces.fix_spaces_max ) {
const CharSourceRange range = CharSourceRange::getCharRange(
location( itspaceend - ( spacelen - punc->spaces.fix_spaces_to ) ),
location( itspaceend ) );
auto diags = diag( location( it ),
"excessive spaces at this location. %0 required, but %1 found." )
<< static_cast<unsigned int>( punc->spaces.fix_spaces_to )
<< static_cast<unsigned int>( spacelen );
if( fixit ) {
diags << FixItHint::CreateRemoval( range );
}
}
it = itspaceend;
}
it = itspaceend;
}
}
}
Expand Down
19 changes: 14 additions & 5 deletions tools/clang-tidy-plugin/test/text-style.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,24 @@ static void bar()
// CHECK-MESSAGES: [[@LINE-1]]:17: warning: insufficient spaces at this location. 2 required, but only 1 found.
// CHECK-FIXES: foo( "Three! Two! One!" );
foo( "Three; Two; One;" );
// CHECK-MESSAGES: [[@LINE-1]]:17: warning: insufficient spaces at this location. 2 required, but only 1 found.
// CHECK-FIXES: foo( "Three; Two; One;" );
// CHECK-MESSAGES: [[@LINE-1]]:22: warning: excessive spaces at this location. 1 required, but 2 found.
// CHECK-FIXES: foo( "Three; Two; One;" );
foo( "Three? Two? One?" );
// CHECK-MESSAGES: [[@LINE-1]]:17: warning: insufficient spaces at this location. 2 required, but only 1 found.
// CHECK-FIXES: foo( "Three? Two? One?" );
foo( "Three\u2026 Two\u2026 One\u2026" );
// CHECK-MESSAGES: [[@LINE-1]]:22: warning: insufficient spaces at this location. 2 required, but only 1 found.
// CHECK-FIXES: foo( "Three\u2026 Two\u2026 One\u2026" );
foo( "Three?! Two!? One!!" );
// CHECK-MESSAGES: [[@LINE-1]]:18: warning: insufficient spaces at this location. 2 required, but only 1 found.
// CHECK-FIXES: foo( "Three?! Two!? One!!" );
foo( "\u2026 foo." );
// CHECK-MESSAGES: [[@LINE-1]]:17: warning: undesired spaces after a punctuation that starts a string.
// CHECK-FIXES: foo( "\u2026foo." );
foo( "foo.\n\u2026 bar." );
// CHECK-MESSAGES: [[@LINE-1]]:23: warning: undesired spaces after a punctuation that starts a line.
// CHECK-FIXES: foo( "foo.\n\u2026bar." );
foo( "foo : bar" );
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: unnecessary spaces before this location.
// CHECK-FIXES: foo( "foo: bar" );
foo( "foo \nbar" );
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: unnecessary spaces before this location.
// CHECK-FIXES: foo( "foo\nbar" );
}

0 comments on commit 1bfd265

Please sign in to comment.