Skip to content

Commit 26af971

Browse files
granular build/namespaces categories
Enhance the using directives check by adding more granularity to the warnings. The warnings are split into multiple categories 1. block/namespace scope 2. source/header file 3. literal/nonliteral namespace Possible filter combinations would look like the following 1. Google: None 2. CppCoreGuidelines 1. -build/namespaces/header/block 2. -build/namespaces/source 3. Like CppCoreGuidlines, but disallow non-literal namespaces in source files at namespace scope 1. -build/namespaces/header/block 2. -build/namespaces/source/block 3. -build/namespaces/source/namespace/literal Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent b6ada00 commit 26af971

File tree

6 files changed

+124
-38
lines changed

6 files changed

+124
-38
lines changed

cpplint.py

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,14 @@
308308
"build/include_order",
309309
"build/include_what_you_use",
310310
"build/namespaces_headers",
311-
"build/namespaces_literals",
312-
"build/namespaces",
311+
"build/namespaces/header/block/literals",
312+
"build/namespaces/header/block/nonliterals",
313+
"build/namespaces/header/namespace/literals",
314+
"build/namespaces/header/namespace/nonliterals",
315+
"build/namespaces/source/block/literals",
316+
"build/namespaces/source/block/nonliterals",
317+
"build/namespaces/source/namespace/literals",
318+
"build/namespaces/source/namespace/nonliterals",
313319
"build/printf_format",
314320
"build/storage_class",
315321
"legal/copyright",
@@ -935,6 +941,16 @@
935941
"Missing space after ,": r"s/,\([^ ]\)/, \1/g",
936942
}
937943

944+
# Used for backwards compatibility and ease of use
945+
_FILTER_SHORTCUTS = {
946+
"build/namespaces_literals": [
947+
"build/namespaces/header/block/literals",
948+
"build/namespaces/header/namespace/literals",
949+
"build/namespaces/source/block/literals",
950+
"build/namespaces/source/namespace/literals",
951+
]
952+
}
953+
938954
# The root directory used for deriving header guard CPP variable.
939955
# This is set by --root flag.
940956
_root = None
@@ -1457,7 +1473,12 @@ def AddFilters(self, filters):
14571473
for filt in filters.split(","):
14581474
clean_filt = filt.strip()
14591475
if clean_filt:
1460-
self.filters.append(clean_filt)
1476+
if len(clean_filt) > 1 and clean_filt[1:] in _FILTER_SHORTCUTS:
1477+
starting_char = clean_filt[0]
1478+
new_filters = [starting_char + x for x in _FILTER_SHORTCUTS[clean_filt[1:]]]
1479+
self.filters.extend(new_filters)
1480+
else:
1481+
self.filters.append(clean_filt)
14611482
for filt in self.filters:
14621483
if not filt.startswith(("+", "-")):
14631484
msg = f"Every filter in --filters must start with + or - ({filt} does not)"
@@ -3287,6 +3308,14 @@ def InAsmBlock(self):
32873308
"""
32883309
return self.stack and self.stack[-1].inline_asm != _NO_ASM
32893310

3311+
def InBlockScope(self):
3312+
"""Check if we are currently one level inside a block scope.
3313+
3314+
Returns:
3315+
True if top of the stack is a block scope, False otherwise.
3316+
"""
3317+
return len(self.stack) > 0 and not isinstance(self.stack[-1], _NamespaceInfo)
3318+
32903319
def InTemplateArgumentList(self, clean_lines, linenum, pos):
32913320
"""Check if current position is inside template argument list.
32923321
@@ -6021,22 +6050,26 @@ def CheckLanguage(
60216050
)
60226051

60236052
if re.search(r"\busing namespace\b", line):
6024-
if re.search(r"\bliterals\b", line):
6025-
error(
6026-
filename,
6027-
linenum,
6028-
"build/namespaces_literals",
6029-
5,
6030-
"Do not use namespace using-directives. Use using-declarations instead.",
6031-
)
6032-
else:
6033-
error(
6034-
filename,
6035-
linenum,
6036-
"build/namespaces",
6037-
5,
6038-
"Do not use namespace using-directives. Use using-declarations instead.",
6039-
)
6053+
is_literals = re.search(r"\bliterals\b", line) is not None
6054+
is_header = not _IsSourceExtension(file_extension)
6055+
file_type = "header" if is_header else "source"
6056+
6057+
# Check for the block scope for multiline blocks.
6058+
# Check if the line starts with the using directive as a heuristic in case it's all one line
6059+
is_block_scope = nesting_state.InBlockScope() or not line.startswith("using namespace")
6060+
6061+
scope_type = "block" if is_block_scope else "namespace"
6062+
literal_type = "literals" if is_literals else "nonliterals"
6063+
6064+
specific_category = f"build/namespaces/{file_type}/{scope_type}/{literal_type}"
6065+
6066+
error(
6067+
filename,
6068+
linenum,
6069+
specific_category,
6070+
5,
6071+
"Do not use namespace using-directives. Use using-declarations instead.",
6072+
)
60406073

60416074
# Detect variable-length arrays.
60426075
match = re.match(r"\s*(.+::)?(\w+) [a-z]\w*\[(.+)];", line)

cpplint_unittest.py

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3640,7 +3640,7 @@ def DoTest(self, lines):
36403640
assert (
36413641
error_collector.Results().count(
36423642
"Do not use namespace using-directives. Use using-declarations instead. "
3643-
"[build/namespaces] [5]"
3643+
"[build/namespaces/source/namespace/nonliterals] [5]"
36443644
)
36453645
== 1
36463646
)
@@ -3649,20 +3649,6 @@ def DoTest(self, lines):
36493649
DoTest(self, ["", "", "", "using namespace foo;"])
36503650
DoTest(self, ["// hello", "using namespace foo;"])
36513651

3652-
def testUsingLiteralsNamespaces(self):
3653-
self.TestLint(
3654-
"using namespace std::literals;",
3655-
"Do not use namespace"
3656-
" using-directives. Use using-declarations instead."
3657-
" [build/namespaces_literals] [5]",
3658-
)
3659-
self.TestLint(
3660-
"using namespace std::literals::chrono_literals;",
3661-
"Do"
3662-
" not use namespace using-directives. Use using-declarations instead."
3663-
" [build/namespaces_literals] [5]",
3664-
)
3665-
36663652
def testNewlineAtEOF(self):
36673653
def DoTest(self, data, is_missing_eof):
36683654
error_collector = ErrorCollector(self.assertTrue)
@@ -4203,6 +4189,73 @@ def testEndOfNamespaceComments(self):
42034189
== 0
42044190
)
42054191

4192+
def testUsingNamespacesGranular(self):
4193+
"""Test granular using namespace checks for different contexts."""
4194+
4195+
self.TestLanguageRulesCheck(
4196+
"foo.h",
4197+
"using namespace std;",
4198+
"Do not use namespace using-directives. "
4199+
"Use using-declarations instead."
4200+
" [build/namespaces/header/namespace/nonliterals] [5]",
4201+
)
4202+
4203+
self.TestLanguageRulesCheck(
4204+
"foo.h",
4205+
"using namespace std::chrono::literals;",
4206+
"Do not use namespace using-directives. "
4207+
"Use using-declarations instead."
4208+
" [build/namespaces/header/namespace/literals] [5]",
4209+
)
4210+
4211+
self.TestLanguageRulesCheck(
4212+
"foo.cc",
4213+
"using namespace std;",
4214+
"Do not use namespace using-directives. "
4215+
"Use using-declarations instead."
4216+
" [build/namespaces/source/namespace/nonliterals] [5]",
4217+
)
4218+
4219+
self.TestLanguageRulesCheck(
4220+
"foo.cc",
4221+
"using namespace std::chrono::literals;",
4222+
"Do not use namespace using-directives. "
4223+
"Use using-declarations instead."
4224+
" [build/namespaces/source/namespace/literals] [5]",
4225+
)
4226+
4227+
self.TestLanguageRulesCheck(
4228+
"foo.h",
4229+
"{ using namespace std; }",
4230+
"Do not use namespace using-directives. "
4231+
"Use using-declarations instead."
4232+
" [build/namespaces/header/block/nonliterals] [5]",
4233+
)
4234+
4235+
self.TestLanguageRulesCheck(
4236+
"foo.h",
4237+
"{ using namespace std::chrono::literals; }",
4238+
"Do not use namespace using-directives. "
4239+
"Use using-declarations instead."
4240+
" [build/namespaces/header/block/literals] [5]",
4241+
)
4242+
4243+
self.TestLanguageRulesCheck(
4244+
"foo.cc",
4245+
"{ using namespace std; }",
4246+
"Do not use namespace using-directives. "
4247+
"Use using-declarations instead."
4248+
" [build/namespaces/source/block/nonliterals] [5]",
4249+
)
4250+
4251+
self.TestLanguageRulesCheck(
4252+
"foo.cc",
4253+
"{ using namespace std::chrono::literals; }",
4254+
"Do not use namespace using-directives. "
4255+
"Use using-declarations instead."
4256+
" [build/namespaces/source/block/literals] [5]",
4257+
)
4258+
42064259
def testComma(self):
42074260
self.TestLint("a = f(1,2);", "Missing space after , [whitespace/comma] [3]")
42084261
self.TestLint(

samples/silly-sample/filters.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ src/sillycode.cpp:1: Include the directory when naming header files [build/inc
1313
src/sillycode.cpp:2: <ratio> is an unapproved C++11 header. [build/c++11] [5]
1414
src/sillycode.cpp:3: Found C system header after other header. Should be: sillycode.h, c system, c++ system, other. [build/include_order] [4]
1515
src/sillycode.cpp:4: Found C system header after other header. Should be: sillycode.h, c system, c++ system, other. [build/include_order] [4]
16-
src/sillycode.cpp:5: Do not use namespace using-directives. Use using-declarations instead. [build/namespaces] [5]
16+
src/sillycode.cpp:5: Do not use namespace using-directives. Use using-declarations instead. [build/namespaces/source/namespace/nonliterals] [5]
1717
src/sillycode.cpp:40: If/else bodies with multiple statements require braces [readability/braces] [4]
1818
src/sillycode.cpp:66: Single-parameter constructors should be marked explicit. [runtime/explicit] [4]
1919
src/sillycode.cpp:76: Single-parameter constructors should be marked explicit. [runtime/explicit] [4]

samples/silly-sample/includeorder_cfirst.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ src/sillycode.cpp:2: Should have a space between // and comment [whitespace/co
1111
src/sillycode.cpp:2: <ratio> is an unapproved C++11 header. [build/c++11] [5]
1212
src/sillycode.cpp:3: Found other system header after other header. Should be: sillycode.h, c system, c++ system, other. [build/include_order] [4]
1313
src/sillycode.cpp:4: Found other system header after other header. Should be: sillycode.h, c system, c++ system, other. [build/include_order] [4]
14-
src/sillycode.cpp:5: Do not use namespace using-directives. Use using-declarations instead. [build/namespaces] [5]
14+
src/sillycode.cpp:5: Do not use namespace using-directives. Use using-declarations instead. [build/namespaces/source/namespace/nonliterals] [5]
1515
src/sillycode.cpp:8: public: should be indented +1 space inside class Date [whitespace/indent] [3]
1616
src/sillycode.cpp:15: { should almost always be at the end of the previous line [whitespace/braces] [4]
1717
src/sillycode.cpp:39: { should almost always be at the end of the previous line [whitespace/braces] [4]

samples/silly-sample/sed.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ sed -i '249s/\([^ ]\){/\1 {/' src/sillycode.cpp # Missing space before { [white
1515
# src/sillycode.cpp:2: "<ratio> is an unapproved C++11 header." [build/c++11] [5]
1616
# src/sillycode.cpp:3: "Found C system header after other header. Should be: sillycode.h, c system, c++ system, other." [build/include_order] [4]
1717
# src/sillycode.cpp:4: "Found C system header after other header. Should be: sillycode.h, c system, c++ system, other." [build/include_order] [4]
18-
# src/sillycode.cpp:5: "Do not use namespace using-directives. Use using-declarations instead." [build/namespaces] [5]
18+
# src/sillycode.cpp:5: "Do not use namespace using-directives. Use using-declarations instead." [build/namespaces/source/namespace/nonliterals] [5]
1919
# src/sillycode.cpp:8: "public: should be indented +1 space inside class Date" [whitespace/indent] [3]
2020
# src/sillycode.cpp:15: "{ should almost always be at the end of the previous line" [whitespace/braces] [4]
2121
# src/sillycode.cpp:39: "{ should almost always be at the end of the previous line" [whitespace/braces] [4]

samples/silly-sample/simple.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ src/sillycode.cpp:2: Should have a space between // and comment [whitespace/co
1212
src/sillycode.cpp:2: <ratio> is an unapproved C++11 header. [build/c++11] [5]
1313
src/sillycode.cpp:3: Found C system header after other header. Should be: sillycode.h, c system, c++ system, other. [build/include_order] [4]
1414
src/sillycode.cpp:4: Found C system header after other header. Should be: sillycode.h, c system, c++ system, other. [build/include_order] [4]
15-
src/sillycode.cpp:5: Do not use namespace using-directives. Use using-declarations instead. [build/namespaces] [5]
15+
src/sillycode.cpp:5: Do not use namespace using-directives. Use using-declarations instead. [build/namespaces/source/namespace/nonliterals] [5]
1616
src/sillycode.cpp:8: public: should be indented +1 space inside class Date [whitespace/indent] [3]
1717
src/sillycode.cpp:15: { should almost always be at the end of the previous line [whitespace/braces] [4]
1818
src/sillycode.cpp:39: { should almost always be at the end of the previous line [whitespace/braces] [4]

0 commit comments

Comments
 (0)