-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathtransitive_includes.patch
96 lines (86 loc) · 4.12 KB
/
transitive_includes.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
diff --git a/cpplint.py b/cpplint.py
index 7a8b8ab..b52a4e5 100755
--- cpplint.py
+++ cpplint.py
@@ -6192,24 +6192,12 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
if not line or line[0] == '#':
continue
- _re_patterns = []
- _re_patterns.extend(_re_pattern_types_or_objs)
- _re_patterns.extend(_re_pattern_functions)
- for pattern, item, header in _re_patterns:
- matched = pattern.search(line)
- if matched:
- # Don't warn about strings in non-STL namespaces:
- # (We check only the first match per line; good enough.)
- prefix = line[:matched.start()]
- if prefix.endswith('std::') or not prefix.endswith('::'):
- required[header] = (linenum, item)
-
for pattern, template, header in _re_pattern_headers_maybe_templates:
if pattern.search(line):
required[header] = (linenum, template)
# The following function is just a speed up, no semantics are changed.
- if '<' not in line: # Reduces the cpu time usage by skipping lines.
+ if not '<' in line: # Reduces the cpu time usage by skipping lines.
continue
for pattern, template, header in _re_pattern_templates:
@@ -6221,25 +6209,57 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
if prefix.endswith('std::') or not prefix.endswith('::'):
required[header] = (linenum, template)
+ # The policy is that if you #include something in foo.h you don't need to
+ # include it again in foo.cc. Here, we will look at possible includes.
# Let's flatten the include_state include_list and copy it into a dictionary.
include_dict = dict([item for sublist in include_state.include_list
for item in sublist])
+ # Did we find the header for this file (if any) and successfully load it?
+ header_found = False
+
+ # Use the absolute path so that matching works properly.
+ abs_filename = FileInfo(filename).FullName()
+
+ # For Emacs's flymake.
+ # If cpplint is invoked from Emacs's flymake, a temporary file is generated
+ # by flymake and that file name might end with '_flymake.cc'. In that case,
+ # restore original file name here so that the corresponding header file can be
+ # found.
+ # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h'
+ # instead of 'foo_flymake.h'
+ abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename)
+
+ # include_dict is modified during iteration, so we iterate over a copy of
+ # the keys.
+ header_keys = list(include_dict.keys())
+ for header in header_keys:
+ (same_module, common_path) = FilesBelongToSameModule(abs_filename, header)
+ fullpath = common_path + header
+ if same_module:
+ header_found = True
+
+ # If we can't find the header file for a .cc, assume it's because we don't
+ # know where to look. In that case we'll give up as we're not sure they
+ # didn't include it in the .h file.
+ # TODO(unknown): Do a better job of finding .h files so we are confident that
+ # not having the .h file means there isn't one.
+ if filename.endswith('.cc') and not header_found:
+ return
+
# All the lines have been processed, report the errors found.
- for header in sorted(required, key=required.__getitem__):
- template = required[header][1]
- header_stripped = header.strip('<>"')
- if (header_stripped not in include_dict
- and not (header_stripped[0] == 'c'
- and (header_stripped[1:] + '.h') in include_dict)):
- error(filename, required[header][0],
+ for required_header_unstripped in required:
+ template = required[required_header_unstripped][1]
+ if required_header_unstripped.strip('<>"') not in include_dict:
+ error(filename, required[required_header_unstripped][0],
'build/include_what_you_use', 4,
- 'Add #include ' + header + ' for ' + template)
+ 'Add #include ' + required_header_unstripped + ' for ' + template)
_RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<')
+
def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error):
"""Check that make_pair's template arguments are deduced.