mirror of
https://github.com/google/styleguide.git
synced 2024-03-22 13:11:43 +08:00
Update cpplint.py to r456
456 - Tweak lint to sometimes allow { on line following array initialization. 455 - Recognize more types. 454 - Try a bit harder to detect templated types. 453 - Changed error message wording on build/storage_class to be less ambiguous. 452 - Recognize more types to silence false positives for brace warnings. 451 - <skipped> 450 - <skipped> 449 - Ignore whitespace/tab for Linux Kernel files. 448 - Remove some more false positive lint warnings for int64{n}. 447 - Just one warning message for line length is enough, don't need two. 446 - Allow braced conversions to int16, uint64, etc. per the style guide. 445 - Fixed handling of backslash escapes for checking whether a "//" is quoted. 444 - Reduced dependency on hardcoded .cc extension. 443 - Disable single-arg constructor checks by default, since ClangTidy has the same check. We could just delete the check entirely, but it's slightly useful in places that can't run ClangTidy. 442 - Fix matching of macro names in CheckTrailingSemicolon to include digits. 441 - Deleted checks: - All checks for RValue references. - Spacing check around boolean &&, because those look like RValue references. A huge amount of code and effort were dedicated to tell RValue references apart from boolean expressions, and to differentiate allowed versus banned RValue references. But we still get regular false positives from this one check. Rather than making the check more complex than what it already is, it seemed safer to just delete it altogether for now, and have a different process for catching RValue references. 440 - Add rule to cpplint to throw error on empty if statement bodies without else clauses. If statement bodies with comments are not considered empty. 439 - Allow spaces before closing brace of namespace block so that namespaces inside of macro definitions (where the entire macro definition is indented) are not treated as errors. 438 - cpplint: fix a false positive on `new const int(x)`. 437 - Only check for function length when current line is inside a function. 436 - cpplint: Catch static `std::string` instances as well as those written as `string`. Previously users would sometimes work around the lint warning by changing their code to even worse code by adding the "std::" prefix. 435 - cpplint: Be a little smarter about warning on indentation. 434 - cpplint: Remove false positives on some functions returning string const&. 433 - cpplint: improve diagnostics of global/static string objects. 432 - Allow non-const reference parameters for iostream based types. 431 - Better handling of raw strings inside comments. 430 - <noop> 429 - <skipped> 428 - <skipped> 427 - Add support to CHECK_NOTNULL when checking if a member variable is initialized with itself. 426 - Allow suppressing specific warnings in C headers. 425 - Allow spaces before parens for inline assembly. 424 - Remove lint checks for {EXPECT,ASSERT}_.*_M. 423 - Allow comment lines of more than 80 characters if they contain a single "word" (without any spaces). 422 - cpplint: Warn on inclusion of C++14 headers. 421 - cpplint: recognize <shared_mutex> as a standard library header. 420 - Add <scoped_allocator> to cpplint's list of C++ standard headers. 419 - Add cpplint check for tr1/ headers. We removed the nanny guards for these 418 - <skipped> 417 - Update the styleguide and cpplint to allow unnamed parameters 416 - Remove the rule explicitly banning non-default move operations. 415 - Remove the check for explicit multi arg constructors 414 - Include clarity of lambda default captures in "pros" section, mention of capturing `this` and lambdas which escape the current scope in "cons". Soften the ban on default captures to a preference, with admonition against using them for capturing `this` or when they will escape the current scope. This is a fairly straightforward change with a brief inclusion of 2 problematic cases for implicit capture. As this is the style guide, I'm not sure how much more detail is appropriate. 413 - Fixed a bug by making regex in CleanseRawStrings match multiple raw strings on a single line in left-to-right order. 412 - Fixed false positive for classes derived using decltype() 411 - <skipped> 410 - Recognize '1LL<<20' as numeric and don't flag it for spacing.
This commit is contained in:
parent
175866f6c4
commit
01e47236c8
962
cpplint/cpplint.py
vendored
962
cpplint/cpplint.py
vendored
File diff suppressed because it is too large
Load Diff
|
@ -290,6 +290,14 @@ class CpplintTest(CpplintTestBase):
|
|||
results = self.GetNamespaceResults(lines)
|
||||
self.assertEquals(results, '')
|
||||
|
||||
def testWhitespaceBeforeNamespace(self):
|
||||
lines = [' namespace Test {',
|
||||
' void foo() { }',
|
||||
' } // namespace Test']
|
||||
|
||||
results = self.GetNamespaceResults(lines)
|
||||
self.assertEquals(results, '')
|
||||
|
||||
def testFalsePositivesNoError(self):
|
||||
lines = ['namespace Test {',
|
||||
'struct OuterClass {',
|
||||
|
@ -362,13 +370,23 @@ class CpplintTest(CpplintTestBase):
|
|||
'// Hello',
|
||||
'')
|
||||
self.TestLint(
|
||||
'// ' + 'x' * 80,
|
||||
'// x' + ' x' * 40,
|
||||
'Lines should be <= 80 characters long'
|
||||
' [whitespace/line_length] [2]')
|
||||
self.TestLint(
|
||||
'// ' + 'x' * 100,
|
||||
'Lines should very rarely be longer than 100 characters'
|
||||
' [whitespace/line_length] [4]')
|
||||
'// x' + ' x' * 50,
|
||||
'Lines should be <= 80 characters long'
|
||||
' [whitespace/line_length] [2]')
|
||||
self.TestLint(
|
||||
'// //some/path/to/f' + ('i' * 100) + 'le',
|
||||
'')
|
||||
self.TestLint(
|
||||
'// //some/path/to/f' + ('i' * 100) + 'le',
|
||||
'')
|
||||
self.TestLint(
|
||||
'// //some/path/to/f' + ('i' * 50) + 'le and some comments',
|
||||
'Lines should be <= 80 characters long'
|
||||
' [whitespace/line_length] [2]')
|
||||
self.TestLint(
|
||||
'// http://g' + ('o' * 100) + 'gle.com/',
|
||||
'')
|
||||
|
@ -445,6 +463,64 @@ class CpplintTest(CpplintTestBase):
|
|||
''],
|
||||
error_collector)
|
||||
self.assertEquals('', error_collector.Results())
|
||||
# LINT_C_FILE silences cast warnings for entire file.
|
||||
error_collector = ErrorCollector(self.assert_)
|
||||
cpplint.ProcessFileData('test.h', 'h',
|
||||
['// Copyright 2014 Your Company.',
|
||||
'// NOLINT(build/header_guard)',
|
||||
'int64 a = (uint64) 65;',
|
||||
'// LINT_C_FILE',
|
||||
''],
|
||||
error_collector)
|
||||
self.assertEquals('', error_collector.Results())
|
||||
# Vim modes silence cast warnings for entire file.
|
||||
for modeline in ['vi:filetype=c',
|
||||
'vi:sw=8 filetype=c',
|
||||
'vi:sw=8 filetype=c ts=8',
|
||||
'vi: filetype=c',
|
||||
'vi: sw=8 filetype=c',
|
||||
'vi: sw=8 filetype=c ts=8',
|
||||
'vim:filetype=c',
|
||||
'vim:sw=8 filetype=c',
|
||||
'vim:sw=8 filetype=c ts=8',
|
||||
'vim: filetype=c',
|
||||
'vim: sw=8 filetype=c',
|
||||
'vim: sw=8 filetype=c ts=8',
|
||||
'vim: set filetype=c:',
|
||||
'vim: set sw=8 filetype=c:',
|
||||
'vim: set sw=8 filetype=c ts=8:',
|
||||
'vim: set filetype=c :',
|
||||
'vim: set sw=8 filetype=c :',
|
||||
'vim: set sw=8 filetype=c ts=8 :',
|
||||
'vim: se filetype=c:',
|
||||
'vim: se sw=8 filetype=c:',
|
||||
'vim: se sw=8 filetype=c ts=8:',
|
||||
'vim: se filetype=c :',
|
||||
'vim: se sw=8 filetype=c :',
|
||||
'vim: se sw=8 filetype=c ts=8 :']:
|
||||
error_collector = ErrorCollector(self.assert_)
|
||||
cpplint.ProcessFileData('test.h', 'h',
|
||||
['// Copyright 2014 Your Company.',
|
||||
'// NOLINT(build/header_guard)',
|
||||
'int64 a = (uint64) 65;',
|
||||
'/* Prevent warnings about the modeline',
|
||||
modeline,
|
||||
'*/',
|
||||
''],
|
||||
error_collector)
|
||||
self.assertEquals('', error_collector.Results())
|
||||
# LINT_KERNEL_FILE silences whitespace/tab warnings for entire file.
|
||||
error_collector = ErrorCollector(self.assert_)
|
||||
cpplint.ProcessFileData('test.h', 'h',
|
||||
['// Copyright 2014 Your Company.',
|
||||
'// NOLINT(build/header_guard)',
|
||||
'struct test {',
|
||||
'\tint member;',
|
||||
'};',
|
||||
'// LINT_KERNEL_FILE',
|
||||
''],
|
||||
error_collector)
|
||||
self.assertEquals('', error_collector.Results())
|
||||
|
||||
# Test Variable Declarations.
|
||||
def testVariableDeclarations(self):
|
||||
|
@ -509,14 +585,55 @@ class CpplintTest(CpplintTestBase):
|
|||
self.TestLint('[](int/*unused*/) -> bool {', '')
|
||||
self.TestLint('[](int /*unused*/) -> bool {', '')
|
||||
self.TestLint('auto f = [](MyStruct* /*unused*/)->int {', '')
|
||||
self.TestLint(
|
||||
'[](int) -> bool {',
|
||||
'All parameters should be named in a function'
|
||||
' [readability/function] [3]')
|
||||
self.TestLint(
|
||||
'auto f = [](MyStruct*)->int {',
|
||||
'All parameters should be named in a function'
|
||||
' [readability/function] [3]')
|
||||
self.TestLint('[](int) -> bool {', '')
|
||||
self.TestLint('auto f = [](MyStruct*)->int {', '')
|
||||
|
||||
# Cast with brace initializers
|
||||
self.TestLint('int64_t{4096} * 1000 * 1000', '')
|
||||
self.TestLint('size_t{4096} * 1000 * 1000', '')
|
||||
self.TestLint('uint_fast16_t{4096} * 1000 * 1000', '')
|
||||
|
||||
# Brace initializer with templated type
|
||||
self.TestMultiLineLint(
|
||||
"""
|
||||
template <typename Type1,
|
||||
typename Type2>
|
||||
void Function(int arg1,
|
||||
int arg2) {
|
||||
variable &= ~Type1{0} - 1;
|
||||
}""",
|
||||
'')
|
||||
self.TestMultiLineLint(
|
||||
"""
|
||||
template <typename Type>
|
||||
class Class {
|
||||
void Function() {
|
||||
variable &= ~Type{0} - 1;
|
||||
}
|
||||
};""",
|
||||
'')
|
||||
self.TestMultiLineLint(
|
||||
"""
|
||||
template <typename Type>
|
||||
class Class {
|
||||
void Function() {
|
||||
variable &= ~Type{0} - 1;
|
||||
}
|
||||
};""",
|
||||
'')
|
||||
self.TestMultiLineLint(
|
||||
"""
|
||||
namespace {
|
||||
template <typename Type>
|
||||
class Class {
|
||||
void Function() {
|
||||
if (block) {
|
||||
variable &= ~Type{0} - 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
}""",
|
||||
'')
|
||||
|
||||
# Test taking address of casts (runtime/casting)
|
||||
def testRuntimeCasting(self):
|
||||
|
@ -559,6 +676,10 @@ class CpplintTest(CpplintTestBase):
|
|||
'Foo::Foo(Bar r, Bel l) : r_(r_), l_(l_) { }',
|
||||
'You seem to be initializing a member variable with itself.'
|
||||
' [runtime/init] [4]')
|
||||
self.TestLint(
|
||||
'Foo::Foo(Bar r, Bel l) : r_(CHECK_NOTNULL(r_)) { }',
|
||||
'You seem to be initializing a member variable with itself.'
|
||||
' [runtime/init] [4]')
|
||||
self.TestLint(
|
||||
'Foo::Foo(Bar r, Bel l) : r_(r), l_(l) { }',
|
||||
'')
|
||||
|
@ -568,14 +689,12 @@ class CpplintTest(CpplintTestBase):
|
|||
|
||||
# Test for unnamed arguments in a method.
|
||||
def testCheckForUnnamedParams(self):
|
||||
message = ('All parameters should be named in a function'
|
||||
' [readability/function] [3]')
|
||||
self.TestLint('virtual void Func(int*) const;', message)
|
||||
self.TestLint('virtual void Func(int*);', message)
|
||||
self.TestLint('void Method(char*) {', message)
|
||||
self.TestLint('void Method(char*);', message)
|
||||
self.TestLint('static void operator delete[](void*) throw();', message)
|
||||
self.TestLint('int Method(int);', message)
|
||||
self.TestLint('virtual void Func(int*) const;', '')
|
||||
self.TestLint('virtual void Func(int*);', '')
|
||||
self.TestLint('void Method(char*) {', '')
|
||||
self.TestLint('void Method(char*);', '')
|
||||
self.TestLint('static void operator delete[](void*) throw();', '')
|
||||
self.TestLint('int Method(int);', '')
|
||||
|
||||
self.TestLint('virtual void Func(int* p);', '')
|
||||
self.TestLint('void operator delete(void* x) throw();', '')
|
||||
|
@ -627,6 +746,7 @@ class CpplintTest(CpplintTestBase):
|
|||
self.TestLint('operator bool();', '') # Conversion operator
|
||||
self.TestLint('new int64(123);', '') # "new" operator on basic type
|
||||
self.TestLint('new int64(123);', '') # "new" operator on basic type
|
||||
self.TestLint('new const int(42);', '') # "new" on const-qualified type
|
||||
self.TestLint('using a = bool(int arg);', '') # C++11 alias-declaration
|
||||
self.TestLint('x = bit_cast<double(*)[3]>(y);', '') # array of array
|
||||
self.TestLint('void F(const char(&src)[N]);', '') # array of references
|
||||
|
@ -838,7 +958,7 @@ class CpplintTest(CpplintTestBase):
|
|||
"""#include "base/foobar.h"
|
||||
bool foobar = swap(0,1);
|
||||
""",
|
||||
'Add #include <algorithm> for swap [build/include_what_you_use] [4]')
|
||||
'Add #include <utility> for swap [build/include_what_you_use] [4]')
|
||||
self.TestIncludeWhatYouUse(
|
||||
"""#include "base/foobar.h"
|
||||
bool foobar = transform(a.begin(), a.end(), b.start(), Foo);
|
||||
|
@ -1199,16 +1319,13 @@ class CpplintTest(CpplintTestBase):
|
|||
};""",
|
||||
'Zero-parameter constructors should not be marked explicit.'
|
||||
' [runtime/explicit] [5]')
|
||||
# Warn explicit multi-argument constructors at lowest severity
|
||||
# No warning for multi-parameter constructors
|
||||
self.TestMultiLineLint(
|
||||
"""
|
||||
class Foo {
|
||||
explicit Foo(int f, int g);
|
||||
};""",
|
||||
'Constructors that require multiple arguments '
|
||||
'should not be marked explicit. [runtime/explicit] [0]')
|
||||
# but explicit multi-argument constructors with only one non-default
|
||||
# argument are OK
|
||||
'')
|
||||
self.TestMultiLineLint(
|
||||
"""
|
||||
class Foo {
|
||||
|
@ -1863,18 +1980,6 @@ class CpplintTest(CpplintTestBase):
|
|||
'EXPECT_TRUE(+42 >= x);',
|
||||
'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
|
||||
' [readability/check] [2]')
|
||||
self.TestLint(
|
||||
'EXPECT_TRUE_M(-42 > x);',
|
||||
'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)'
|
||||
' [readability/check] [2]')
|
||||
self.TestLint(
|
||||
'EXPECT_TRUE_M(42U <= x);',
|
||||
'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)'
|
||||
' [readability/check] [2]')
|
||||
self.TestLint(
|
||||
'EXPECT_TRUE_M(42L < x);',
|
||||
'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)'
|
||||
' [readability/check] [2]')
|
||||
|
||||
self.TestLint(
|
||||
'EXPECT_FALSE(x == 42);',
|
||||
|
@ -1896,10 +2001,6 @@ class CpplintTest(CpplintTestBase):
|
|||
'ASSERT_FALSE(x <= 42);',
|
||||
'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
|
||||
' [readability/check] [2]')
|
||||
self.TestLint(
|
||||
'ASSERT_FALSE_M(x < 42);',
|
||||
'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)'
|
||||
' [readability/check] [2]')
|
||||
|
||||
self.TestLint('CHECK(x<42);',
|
||||
['Missing spaces around <'
|
||||
|
@ -2033,6 +2134,10 @@ class CpplintTest(CpplintTestBase):
|
|||
self.TestLint('stream& operator>>(stream& s, Foo& f);', '')
|
||||
self.TestLint('stream& operator<<(stream& s, Foo& f);', '')
|
||||
self.TestLint('void swap(Bar& a, Bar& b);', '')
|
||||
self.TestLint('ostream& LogFunc(ostream& s);', '')
|
||||
self.TestLint('ostringstream& LogFunc(ostringstream& s);', '')
|
||||
self.TestLint('istream& LogFunc(istream& s);', '')
|
||||
self.TestLint('istringstream& LogFunc(istringstream& s);', '')
|
||||
# Returning a non-const reference from a function is OK.
|
||||
self.TestLint('int& g();', '')
|
||||
# Passing a const reference to a struct (using the struct keyword) is OK.
|
||||
|
@ -2282,6 +2387,9 @@ class CpplintTest(CpplintTestBase):
|
|||
self.TestLint('((a+b))', '')
|
||||
self.TestLint('foo (foo)', 'Extra space before ( in function call'
|
||||
' [whitespace/parens] [4]')
|
||||
# asm volatile () may have a space, as it isn't a function call.
|
||||
self.TestLint('asm volatile ("")', '')
|
||||
self.TestLint('__asm__ __volatile__ ("")', '')
|
||||
self.TestLint('} catch (const Foo& ex) {', '')
|
||||
self.TestLint('case (42):', '')
|
||||
self.TestLint('typedef foo (*foo)(foo)', '')
|
||||
|
@ -2319,9 +2427,20 @@ class CpplintTest(CpplintTestBase):
|
|||
self.TestLint('for {', '')
|
||||
self.TestLint('EXPECT_DEBUG_DEATH({', '')
|
||||
self.TestLint('std::is_convertible<A, B>{}', '')
|
||||
self.TestLint('blah{32}', 'Missing space before {'
|
||||
' [whitespace/braces] [5]')
|
||||
self.TestLint('int8_t{3}', '')
|
||||
self.TestLint('int16_t{3}', '')
|
||||
self.TestLint('int32_t{3}', '')
|
||||
self.TestLint('uint64_t{12345}', '')
|
||||
self.TestLint('constexpr int64_t kBatchGapMicros ='
|
||||
' int64_t{7} * 24 * 3600 * 1000000; // 1 wk.', '')
|
||||
self.TestLint('MoveOnly(int i1, int i2) : ip1{new int{i1}}, '
|
||||
'ip2{new int{i2}} {}',
|
||||
'')
|
||||
|
||||
def testSemiColonAfterBraces(self):
|
||||
self.TestLint('if (cond) {};',
|
||||
self.TestLint('if (cond) { func(); };',
|
||||
'You don\'t need a ; after a } [readability/braces] [4]')
|
||||
self.TestLint('void Func() {};',
|
||||
'You don\'t need a ; after a } [readability/braces] [4]')
|
||||
|
@ -2337,8 +2456,11 @@ class CpplintTest(CpplintTestBase):
|
|||
|
||||
self.TestLint('class X : public Y {};', '')
|
||||
self.TestLint('class X : public MACRO() {};', '')
|
||||
self.TestLint('class X : public decltype(expr) {};', '')
|
||||
self.TestLint('DEFINE_FACADE(PCQueue::Watcher, PCQueue) {};', '')
|
||||
self.TestLint('VCLASS(XfaTest, XfaContextTest) {};', '')
|
||||
self.TestLint('class STUBBY_CLASS(H, E) {};', '')
|
||||
self.TestLint('class STUBBY2_CLASS(H, E) {};', '')
|
||||
self.TestLint('TEST(TestCase, TestName) {};',
|
||||
'You don\'t need a ; after a } [readability/braces] [4]')
|
||||
self.TestLint('TEST_F(TestCase, TestName) {};',
|
||||
|
@ -2365,19 +2487,6 @@ class CpplintTest(CpplintTestBase):
|
|||
'};\n',
|
||||
'')
|
||||
|
||||
for lambda_with_default_capture in ('void f() { [=]{}; }',
|
||||
'void f() { [=](int i) {}; }',
|
||||
'void f() { [=, &x]{}; }',
|
||||
'void f() { [&]{}; }',
|
||||
'void f() { [ & ]{}; }',
|
||||
'void f() { [&, y]{}; }'):
|
||||
self.TestLint(lambda_with_default_capture,
|
||||
'Default lambda captures are an unapproved C++ feature. '
|
||||
'[build/c++11] [4]')
|
||||
|
||||
# "[&...]" isn't necessarily a default capture, though "[=...]" always is.
|
||||
self.TestLint('void f() { [&variable]{}; }', '')
|
||||
|
||||
# Avoid false positives with operator[]
|
||||
self.TestLint('table_to_children[&*table].push_back(dependent);', '')
|
||||
|
||||
|
@ -2412,13 +2521,28 @@ class CpplintTest(CpplintTestBase):
|
|||
' }\n'
|
||||
'};\n', '')
|
||||
self.TestMultiLineLint('if (true) {\n'
|
||||
' if (false){}\n'
|
||||
' if (false){ func(); }\n'
|
||||
'}\n',
|
||||
'Missing space before { [whitespace/braces] [5]')
|
||||
self.TestMultiLineLint('MyClass::MyClass()\n'
|
||||
' : initializer_{\n'
|
||||
' Func()} {\n'
|
||||
'}\n', '')
|
||||
self.TestLint('const pair<string, string> kCL' +
|
||||
('o' * 41) + 'gStr[] = {\n',
|
||||
'Lines should be <= 80 characters long'
|
||||
' [whitespace/line_length] [2]')
|
||||
self.TestMultiLineLint('const pair<string, string> kCL' +
|
||||
('o' * 40) + 'ngStr[] =\n'
|
||||
' {\n'
|
||||
' {"gooooo", "oooogle"},\n'
|
||||
'};\n', '')
|
||||
self.TestMultiLineLint('const pair<string, string> kCL' +
|
||||
('o' * 39) + 'ngStr[] =\n'
|
||||
' {\n'
|
||||
' {"gooooo", "oooogle"},\n'
|
||||
'};\n', '{ should almost always be at the end of '
|
||||
'the previous line [whitespace/braces] [4]')
|
||||
|
||||
def testSpacingAroundElse(self):
|
||||
self.TestLint('}else {', 'Missing space before else'
|
||||
|
@ -2455,6 +2579,7 @@ class CpplintTest(CpplintTestBase):
|
|||
'Missing spaces around << [whitespace/operators] [3]')
|
||||
self.TestLint('a<<b',
|
||||
'Missing spaces around << [whitespace/operators] [3]')
|
||||
self.TestLint('10LL<<20', '')
|
||||
self.TestLint('10ULL<<20', '')
|
||||
self.TestLint('a>>b',
|
||||
'Missing spaces around >> [whitespace/operators] [3]')
|
||||
|
@ -2481,141 +2606,6 @@ class CpplintTest(CpplintTestBase):
|
|||
self.TestLint('using Vector3<T>::operator==;', '')
|
||||
self.TestLint('using Vector3<T>::operator!=;', '')
|
||||
|
||||
def testRvalueReference(self):
|
||||
space_error = 'Missing spaces around && [whitespace/operators] [3]'
|
||||
rvalue_error = ('RValue references are an unapproved C++ feature.'
|
||||
' [build/c++11] [3]')
|
||||
|
||||
# Places where lack of space are allowed
|
||||
self.TestLint('DEFINE_BINARY_OPERATOR(&&)', '')
|
||||
self.TestLint('bool operator&&(A b) {}', '')
|
||||
self.TestLint('bool operator&&(A b) {', '')
|
||||
self.TestLint('bool operator&&(A b);', '')
|
||||
|
||||
# Assignment expressions
|
||||
self.TestLint('a = b && c;', '')
|
||||
self.TestLint('a = b&& c;', space_error)
|
||||
self.TestLint('a = b &&c;', space_error)
|
||||
self.TestLint('a = (b&& c);', space_error)
|
||||
self.TestLint('a = (b &&c);', space_error)
|
||||
self.TestLint('a&& b = c;', rvalue_error)
|
||||
self.TestLint('a<b>&& c = d;', rvalue_error)
|
||||
self.TestLint('auto&& a = b;', rvalue_error)
|
||||
self.TestLint('const a&& b = c;', rvalue_error)
|
||||
self.TestLint('struct a&& b = c;', rvalue_error)
|
||||
self.TestLint('decltype(a)&& b = c;', rvalue_error)
|
||||
|
||||
# Cast expressions
|
||||
self.TestLint('a = const_cast<b&&>(c);', rvalue_error)
|
||||
self.TestLint('a = const_cast<const b&&>(c);', rvalue_error)
|
||||
self.TestLint('a = static_cast<b&&>(c);', rvalue_error)
|
||||
self.TestLint('a = static_cast<const b&&>(c);', rvalue_error)
|
||||
self.TestLint('a = dynamic_cast<b&&>(c);', rvalue_error)
|
||||
self.TestLint('a = dynamic_cast<const b&&>(c);', rvalue_error)
|
||||
self.TestLint('a = reinterpret_cast<b&&>(c);', rvalue_error)
|
||||
self.TestLint('a = reinterpret_cast<const b&&>(c);', rvalue_error)
|
||||
self.TestLint('a = cast < b&& c;', space_error)
|
||||
|
||||
# Function parameters
|
||||
for indent in ['', ' ']:
|
||||
for head in ['void Func', 'vector<int> Func', 'vector<int>\nFunc',
|
||||
'inline void Func',
|
||||
'Constructor', 'Constructor::Constructor',
|
||||
'operator=', 'operator =', 'operator = ']:
|
||||
for body in [' {}', ' {', ';']:
|
||||
self.TestMultiLineLint(indent + head + '(A&& b)' + body, rvalue_error)
|
||||
self.TestMultiLineLint(indent + head + '(A &&b)' + body, rvalue_error)
|
||||
self.TestMultiLineLint(indent + head + '(A&&... b)' + body,
|
||||
rvalue_error)
|
||||
self.TestMultiLineLint(indent + head + '(A<B>&& c)' + body,
|
||||
rvalue_error)
|
||||
self.TestMultiLineLint(indent + head + '(A<B> &&c)' + body,
|
||||
rvalue_error)
|
||||
|
||||
# Function templates
|
||||
self.TestLint('std::conditional<A, B&, C&&>::type', rvalue_error)
|
||||
self.TestLint('std::conditional<A, B&&, C&>::type', rvalue_error)
|
||||
|
||||
# Template functions
|
||||
self.TestLint('template <typename T> R&& F()', rvalue_error)
|
||||
self.TestLint('template <typename T> R&& F() {', rvalue_error)
|
||||
self.TestMultiLineLint('template <typename T>\nR&& F()', rvalue_error)
|
||||
self.TestMultiLineLint('template <typename T>\nR&& F() {', rvalue_error)
|
||||
self.TestLint('template <typename T> void F(T a, R&& b)', rvalue_error)
|
||||
self.TestLint('template <typename T> void F(T a, R &&b)', rvalue_error)
|
||||
self.TestLint('template <typename T> void F(T a, R&& b) {', rvalue_error)
|
||||
|
||||
# For loops
|
||||
self.TestLint('for (a&& b;;)', rvalue_error)
|
||||
self.TestLint('for (a&& b;;) {', rvalue_error)
|
||||
self.TestLint('for (; a&& b;)', space_error)
|
||||
self.TestLint('for (; a&& b;) {', space_error)
|
||||
|
||||
# Constructors
|
||||
self.TestLint('A(a&& b)', rvalue_error)
|
||||
self.TestLint('explicit A(a&& b)', rvalue_error)
|
||||
self.TestLint('A(a b) : c(d&& e)', space_error)
|
||||
self.TestLint('A(a b) : c(), d(e&& f)', space_error)
|
||||
|
||||
def testAllowedRvalueReference(self):
|
||||
# Verify that RValue reference warnings for a line range can be silenced
|
||||
error_collector = ErrorCollector(self.assert_)
|
||||
cpplint.ProcessFileData('foo.cc', 'cc',
|
||||
['// Copyright 2014 Your Company.',
|
||||
'GOOGLE_ALLOW_RVALUE_REFERENCES_PUSH',
|
||||
'void F(A&& b);',
|
||||
'GOOGLE_ALLOW_RVALUE_REFERENCES_POP',
|
||||
''],
|
||||
error_collector)
|
||||
self.assertEquals(error_collector.Results(), '')
|
||||
|
||||
# RValue references for constructors and operator=
|
||||
error_collector = ErrorCollector(self.assert_)
|
||||
cpplint.ProcessFileData(
|
||||
'foo.cc', 'cc',
|
||||
['// Copyright 2014 Your Company.',
|
||||
'class X {',
|
||||
' X(X&& param) = delete; // NOLINT(runtime/explicit)',
|
||||
' X(X &¶m) = default; // NOLINT(runtime/explicit)',
|
||||
' inline X(X&& param) = default; // NOLINT(runtime/explicit)',
|
||||
'',
|
||||
' X& operator=(X&& param) = delete;',
|
||||
' X& operator=(X&& param) = default;',
|
||||
'};',
|
||||
'A::A(A&&) = default;',
|
||||
'Outer::Inner::Inner(Inner&&) = default;',
|
||||
''],
|
||||
error_collector)
|
||||
self.assertEquals(error_collector.Results(), '')
|
||||
|
||||
# Assume templated function parameters are forwarded, and are allowed
|
||||
error_collector = ErrorCollector(self.assert_)
|
||||
cpplint.ProcessFileData(
|
||||
'foo.cc', 'cc',
|
||||
['// Copyright 2014 Your Company.',
|
||||
'template <typename Allowed1>',
|
||||
'void Function1(Allowed1&& a);',
|
||||
'',
|
||||
'template <typename Allowed2, typename Allowed3>',
|
||||
'void Function2(Allowed2&& a, Allowed3 &&b) {',
|
||||
'}',
|
||||
'',
|
||||
'template <class Allowed4>',
|
||||
'void Function3(Ignored1 *a, Allowed4&& b) {',
|
||||
'}',
|
||||
'',
|
||||
'template <typename... Allowed5>',
|
||||
'void Function4(Allowed5&&... a) {',
|
||||
'}',
|
||||
'',
|
||||
'template <class... Allowed6>',
|
||||
'void Function5(',
|
||||
' Allowed6 &&...a) {',
|
||||
'}',
|
||||
''],
|
||||
error_collector)
|
||||
self.assertEquals(error_collector.Results(), '')
|
||||
|
||||
def testSpacingBeforeLastSemicolon(self):
|
||||
self.TestLint('call_function() ;',
|
||||
'Extra space before last semicolon. If this should be an '
|
||||
|
@ -2649,6 +2639,11 @@ class CpplintTest(CpplintTestBase):
|
|||
self.TestLint('for (;;)', '')
|
||||
self.TestLint('for (;;) continue;', '')
|
||||
self.TestLint('for (;;) func();', '')
|
||||
self.TestLint('if (test) {}',
|
||||
'If statement had no body and no else clause'
|
||||
' [whitespace/empty_if_body] [4]')
|
||||
self.TestLint('if (test) func();', '')
|
||||
self.TestLint('if (test) {} else {}', '')
|
||||
self.TestMultiLineLint("""while (true &&
|
||||
false);""",
|
||||
'Empty loop bodies should use {} or continue'
|
||||
|
@ -2665,6 +2660,39 @@ class CpplintTest(CpplintTestBase):
|
|||
while (false);""",
|
||||
'Empty loop bodies should use {} or continue'
|
||||
' [whitespace/empty_loop_body] [5]')
|
||||
self.TestMultiLineLint("""if (test) {
|
||||
}""",
|
||||
'If statement had no body and no else clause'
|
||||
' [whitespace/empty_if_body] [4]')
|
||||
self.TestMultiLineLint("""if (test,
|
||||
func({})) {
|
||||
}""",
|
||||
'If statement had no body and no else clause'
|
||||
' [whitespace/empty_if_body] [4]')
|
||||
self.TestMultiLineLint("""if (test)
|
||||
func();""", '')
|
||||
self.TestLint('if (test) { hello; }', '')
|
||||
self.TestLint('if (test({})) { hello; }', '')
|
||||
self.TestMultiLineLint("""if (test) {
|
||||
func();
|
||||
}""", '')
|
||||
self.TestMultiLineLint("""if (test) {
|
||||
// multiline
|
||||
// comment
|
||||
}""", '')
|
||||
self.TestMultiLineLint("""if (test) { // comment
|
||||
}""", '')
|
||||
self.TestMultiLineLint("""if (test) {
|
||||
} else {
|
||||
}""", '')
|
||||
self.TestMultiLineLint("""if (func(p1,
|
||||
p2,
|
||||
p3)) {
|
||||
func();
|
||||
}""", '')
|
||||
self.TestMultiLineLint("""if (func({}, p1)) {
|
||||
func();
|
||||
}""", '')
|
||||
|
||||
def testSpacingForRangeBasedFor(self):
|
||||
# Basic correctly formatted case:
|
||||
|
@ -2693,19 +2721,49 @@ class CpplintTest(CpplintTestBase):
|
|||
|
||||
# Static or global STL strings.
|
||||
def testStaticOrGlobalSTLStrings(self):
|
||||
# A template for the error message for a const global/static string.
|
||||
error_msg = ('For a static/global string constant, use a C style '
|
||||
'string instead: "%s[]". [runtime/string] [4]')
|
||||
|
||||
# The error message for a non-const global/static string variable.
|
||||
nonconst_error_msg = ('Static/global string variables are not permitted.'
|
||||
' [runtime/string] [4]')
|
||||
|
||||
self.TestLint('string foo;',
|
||||
error_msg % 'char foo')
|
||||
nonconst_error_msg)
|
||||
self.TestLint('string kFoo = "hello"; // English',
|
||||
error_msg % 'char kFoo')
|
||||
nonconst_error_msg)
|
||||
self.TestLint('static string foo;',
|
||||
error_msg % 'static char foo')
|
||||
nonconst_error_msg)
|
||||
self.TestLint('static const string foo;',
|
||||
error_msg % 'static const char foo')
|
||||
self.TestLint('static const std::string foo;',
|
||||
error_msg % 'static const char foo')
|
||||
self.TestLint('string Foo::bar;',
|
||||
error_msg % 'char Foo::bar')
|
||||
nonconst_error_msg)
|
||||
|
||||
self.TestLint('std::string foo;',
|
||||
nonconst_error_msg)
|
||||
self.TestLint('std::string kFoo = "hello"; // English',
|
||||
nonconst_error_msg)
|
||||
self.TestLint('static std::string foo;',
|
||||
nonconst_error_msg)
|
||||
self.TestLint('static const std::string foo;',
|
||||
error_msg % 'static const char foo')
|
||||
self.TestLint('std::string Foo::bar;',
|
||||
nonconst_error_msg)
|
||||
|
||||
self.TestLint('::std::string foo;',
|
||||
nonconst_error_msg)
|
||||
self.TestLint('::std::string kFoo = "hello"; // English',
|
||||
nonconst_error_msg)
|
||||
self.TestLint('static ::std::string foo;',
|
||||
nonconst_error_msg)
|
||||
self.TestLint('static const ::std::string foo;',
|
||||
error_msg % 'static const char foo')
|
||||
self.TestLint('::std::string Foo::bar;',
|
||||
nonconst_error_msg)
|
||||
|
||||
self.TestLint('string* pointer', '')
|
||||
self.TestLint('string *pointer', '')
|
||||
self.TestLint('string* pointer = Func();', '')
|
||||
|
@ -2725,12 +2783,14 @@ class CpplintTest(CpplintTestBase):
|
|||
self.TestLint('string Foo::bar() {}', '')
|
||||
self.TestLint('string Foo::operator*() {}', '')
|
||||
# Rare case.
|
||||
self.TestLint('string foo("foobar");', error_msg % 'char foo')
|
||||
self.TestLint('string foo("foobar");', nonconst_error_msg)
|
||||
# Should not catch local or member variables.
|
||||
self.TestLint(' string foo', '')
|
||||
# Should not catch functions.
|
||||
self.TestLint('string EmptyString() { return ""; }', '')
|
||||
self.TestLint('string EmptyString () { return ""; }', '')
|
||||
self.TestLint('string const& FileInfo::Pathname() const;', '')
|
||||
self.TestLint('string const &FileInfo::Pathname() const;', '')
|
||||
self.TestLint('string VeryLongNameFunctionSometimesEndsWith(\n'
|
||||
' VeryLongNameType very_long_name_variable) {}', '')
|
||||
self.TestLint('template<>\n'
|
||||
|
@ -2761,21 +2821,24 @@ class CpplintTest(CpplintTestBase):
|
|||
'NestedClass::MemberFunction3();',
|
||||
'string TemplateClass<T>::',
|
||||
'NestedClass::MemberFunction4();',
|
||||
'string Class',
|
||||
'const string Class',
|
||||
'::static_member_variable1;',
|
||||
'string Class::',
|
||||
'const string Class::',
|
||||
'static_member_variable2;',
|
||||
'string Class',
|
||||
'const string Class',
|
||||
'::static_member_variable3 = "initial value";',
|
||||
'string Class::',
|
||||
'const string Class::',
|
||||
'static_member_variable4 = "initial value";',
|
||||
'string Class::',
|
||||
'static_member_variable5;',
|
||||
''],
|
||||
error_collector)
|
||||
self.assertEquals(error_collector.Results(),
|
||||
[error_msg % 'char Class::static_member_variable1',
|
||||
error_msg % 'char Class::static_member_variable2',
|
||||
error_msg % 'char Class::static_member_variable3',
|
||||
error_msg % 'char Class::static_member_variable4'])
|
||||
[error_msg % 'const char Class::static_member_variable1',
|
||||
error_msg % 'const char Class::static_member_variable2',
|
||||
error_msg % 'const char Class::static_member_variable3',
|
||||
error_msg % 'const char Class::static_member_variable4',
|
||||
nonconst_error_msg])
|
||||
|
||||
def testNoSpacesInFunctionCalls(self):
|
||||
self.TestLint('TellStory(1, 3);',
|
||||
|
@ -2825,6 +2888,9 @@ class CpplintTest(CpplintTestBase):
|
|||
self.TestLint('// TODO(ljenkins): Fix this', '')
|
||||
self.TestLint('#if 1 // TEST_URLTODOCID_WHICH_HAS_THAT_WORD_IN_IT_H_', '')
|
||||
self.TestLint('// See also similar TODO above', '')
|
||||
self.TestLint(r'EXPECT_EQ("\\", '
|
||||
r'NormalizePath("/./../foo///bar/..//x/../..", ""));',
|
||||
'')
|
||||
|
||||
def testTwoSpacesBetweenCodeAndComments(self):
|
||||
self.TestLint('} // namespace foo',
|
||||
|
@ -3360,10 +3426,9 @@ class CpplintTest(CpplintTestBase):
|
|||
'')
|
||||
self.TestMultiLineLint(
|
||||
TrimExtraIndent('''
|
||||
static const char kNotRawString[] = "("
|
||||
")";'''),
|
||||
'Weird number of spaces at line-start. '
|
||||
'Are you using a 2-space indent? [whitespace/indent] [3]')
|
||||
KV<Query,
|
||||
Tuple<TaxonomyId, PetacatCategoryId, double>>'''),
|
||||
'')
|
||||
self.TestMultiLineLint(
|
||||
' static const char kSingleLineRawString[] = R"(...)";',
|
||||
'Weird number of spaces at line-start. '
|
||||
|
@ -3723,18 +3788,18 @@ class CpplintTest(CpplintTestBase):
|
|||
try:
|
||||
cpplint._line_length = 80
|
||||
self.TestLint(
|
||||
'// %s' % ('H' * 77),
|
||||
'// H %s' % ('H' * 75),
|
||||
'')
|
||||
self.TestLint(
|
||||
'// %s' % ('H' * 78),
|
||||
'// H %s' % ('H' * 76),
|
||||
'Lines should be <= 80 characters long'
|
||||
' [whitespace/line_length] [2]')
|
||||
cpplint._line_length = 120
|
||||
self.TestLint(
|
||||
'// %s' % ('H' * 117),
|
||||
'// H %s' % ('H' * 115),
|
||||
'')
|
||||
self.TestLint(
|
||||
'// %s' % ('H' * 118),
|
||||
'// H %s' % ('H' * 116),
|
||||
'Lines should be <= 120 characters long'
|
||||
' [whitespace/line_length] [2]')
|
||||
finally:
|
||||
|
@ -3873,7 +3938,8 @@ class CpplintTest(CpplintTestBase):
|
|||
cpplint.ProcessFileData(file_path, 'h', [], error_collector)
|
||||
for error in error_collector.ResultList():
|
||||
matched = re.search(
|
||||
'No #ifndef header guard found, suggested CPP variable is: ([A-Z_]+)',
|
||||
'No #ifndef header guard found, suggested CPP variable is: '
|
||||
'([A-Z0-9_]+)',
|
||||
error)
|
||||
if matched is not None:
|
||||
return matched.group(1)
|
||||
|
@ -4176,8 +4242,8 @@ class CpplintTest(CpplintTestBase):
|
|||
storage_classes = ['extern', 'register', 'static', 'typedef']
|
||||
|
||||
build_storage_class_error_message = (
|
||||
'Storage class (static, extern, typedef, etc) should be first.'
|
||||
' [build/storage_class] [5]')
|
||||
'Storage-class specifier (static, extern, typedef, etc) should be '
|
||||
'at the beginning of the declaration. [build/storage_class] [5]')
|
||||
|
||||
# Some explicit cases. Legal in C++, deprecated in C99.
|
||||
self.TestLint('const int static foo = 5;',
|
||||
|
@ -4309,6 +4375,9 @@ class Cxx11Test(CpplintTestBase):
|
|||
self.assertEquals(expected_error, collector.Results())
|
||||
|
||||
def testBlockedHeaders(self):
|
||||
self.TestCxx11Feature('#include <tr1/regex>',
|
||||
'C++ TR1 headers such as <tr1/regex> are '
|
||||
'unapproved. [build/c++tr1] [5]')
|
||||
self.TestCxx11Feature('#include <mutex>',
|
||||
'<mutex> is an unapproved C++11 header.'
|
||||
' [build/c++11] [5]')
|
||||
|
@ -4353,6 +4422,25 @@ class Cxx11Test(CpplintTestBase):
|
|||
' [build/explicit_make_pair] [4]')
|
||||
self.TestLint('my_make_pair<int, int>', '')
|
||||
|
||||
class Cxx14Test(CpplintTestBase):
|
||||
|
||||
def TestCxx14Feature(self, code, expected_error):
|
||||
lines = code.split('\n')
|
||||
collector = ErrorCollector(self.assert_)
|
||||
cpplint.RemoveMultiLineComments('foo.h', lines, collector)
|
||||
clean_lines = cpplint.CleansedLines(lines)
|
||||
cpplint.FlagCxx14Features('foo.cc', clean_lines, 0, collector)
|
||||
self.assertEquals(expected_error, collector.Results())
|
||||
|
||||
def testBlockedHeaders(self):
|
||||
self.TestCxx14Feature('#include <scoped_allocator>',
|
||||
'<scoped_allocator> is an unapproved C++14 header.'
|
||||
' [build/c++14] [5]')
|
||||
self.TestCxx14Feature('#include <shared_mutex>',
|
||||
'<shared_mutex> is an unapproved C++14 header.'
|
||||
' [build/c++14] [5]')
|
||||
|
||||
|
||||
class CleansedLinesTest(unittest.TestCase):
|
||||
|
||||
def testInit(self):
|
||||
|
@ -4970,6 +5058,20 @@ class CheckForFunctionLengthsTest(CpplintTestBase):
|
|||
'Lint failed to find start of function body.'
|
||||
' [readability/fn_size] [5]')
|
||||
|
||||
def testFunctionLengthCheckWithNamespace(self):
|
||||
old_verbosity = cpplint._SetVerboseLevel(1)
|
||||
self.TestFunctionLengthsCheck(
|
||||
('namespace {\n'
|
||||
'void CodeCoverageCL35256059() {\n' +
|
||||
(' X++;\n' * 3000) +
|
||||
'}\n'
|
||||
'} // namespace\n'),
|
||||
('Small and focused functions are preferred: '
|
||||
'CodeCoverageCL35256059() has 3000 non-comment lines '
|
||||
'(error triggered by exceeding 20 lines).'
|
||||
' [readability/fn_size] [5]'))
|
||||
cpplint._SetVerboseLevel(old_verbosity)
|
||||
|
||||
|
||||
def TrimExtraIndent(text_block):
|
||||
"""Trim a uniform amount of whitespace off of each line in a string.
|
||||
|
|
Loading…
Reference in New Issue
Block a user