Skip to content

Commit b51e2a8

Browse files
Merge pull request #2196 from peterschrammel/check-module-includes
Extend linter to check module dependencies
2 parents 0f9c202 + fada0af commit b51e2a8

File tree

61 files changed

+311
-26
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+311
-26
lines changed

jbmc/src/janalyzer/janalyzer_parse_options.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ Author: Daniel Kroening, kroening@kroening.com
1717
#include <memory>
1818

1919
#include <ansi-c/ansi_c_language.h>
20-
#include <cpp/cpp_language.h>
2120
#include <java_bytecode/java_bytecode_language.h>
22-
#include <jsil/jsil_language.h>
2321

2422
#include <goto-programs/goto_convert_functions.h>
2523
#include <goto-programs/goto_inline.h>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
analyses
2+
ansi-c # should go away
3+
cbmc # version.h
4+
java_bytecode
5+
jdiff
6+
goto-analyzer
7+
goto-programs
8+
langapi # should go away
9+
util
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
java_bytecode/library
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
analyses
2+
ansi-c # should go away
3+
goto-programs
4+
java_bytecode
5+
json
6+
langapi # should go away
7+
library
8+
linking
9+
miniz
10+
util

jbmc/src/jbmc/module_dependencies.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
analyses
2+
ansi-c # should go away
3+
cbmc # version.h and bmc.h
4+
goto-instrument
5+
goto-programs
6+
goto-symex
7+
java_bytecode
8+
jbmc
9+
langapi # should go away
10+
linking
11+
pointer-analysis
12+
util
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
analyses
2+
cbmc # version.h
3+
java_bytecode
4+
jdiff
5+
goto-diff
6+
goto-instrument
7+
goto-programs
8+
goto-symex # dubious - rewrite_union
9+
langapi # should go away
10+
pointer-analysis
11+
util
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
miniz
2+
sys # system

scripts/cpplint.py

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4981,7 +4981,7 @@ def _ClassifyInclude(fileinfo, include, is_system):
49814981

49824982

49834983

4984-
def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
4984+
def CheckIncludeLine(filename, clean_lines, linenum, include_state, error, module_deps):
49854985
"""Check rules that are applicable to #include lines.
49864986
49874987
Strings on #include lines are NOT removed from elided line, to make
@@ -5029,6 +5029,18 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
50295029
elif not _THIRD_PARTY_HEADERS_PATTERN.match(include):
50305030
include_state.include_list[-1].append((include, linenum))
50315031

5032+
# Check module dependencies
5033+
module_name = os.path.dirname(filename)
5034+
has_src = module_name.find('src/')
5035+
if has_src >= 0:
5036+
module_name = module_name[has_src+4:]
5037+
deps_name = os.path.dirname(include)
5038+
if deps_name and module_deps:
5039+
may_use = any(deps_name.startswith(module) for module in module_deps)
5040+
if not may_use:
5041+
error(filename, linenum, 'build/include', 4,
5042+
'Module `'+module_name+'` must not use `'+include+'`')
5043+
50325044
# We want to ensure that headers appear in the right order:
50335045
# 1) for foo.cc, foo.h (preferred location)
50345046
# 2) c system files
@@ -5141,7 +5153,7 @@ def _GetTextInside(text, start_pattern):
51415153

51425154

51435155
def CheckLanguage(filename, clean_lines, linenum, file_extension,
5144-
include_state, nesting_state, error):
5156+
include_state, nesting_state, error, module_deps):
51455157
"""Checks rules from the 'C++ language rules' section of cppguide.html.
51465158
51475159
Some of these rules are hard to test (function overloading, using
@@ -5165,7 +5177,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
51655177

51665178
match = _RE_PATTERN_INCLUDE.search(line)
51675179
if match:
5168-
CheckIncludeLine(filename, clean_lines, linenum, include_state, error)
5180+
CheckIncludeLine(filename, clean_lines, linenum, include_state, error, module_deps)
51695181
return
51705182

51715183
# Reset include state across preprocessor directives. This is meant
@@ -6246,7 +6258,7 @@ def CheckForEndl(filename, clean_lines, linenum, error):
62466258
error(filename, linenum, 'runtime/endl', 4, 'Do not use std::endl')
62476259

62486260
def ProcessLine(filename, file_extension, clean_lines, line,
6249-
include_state, function_state, nesting_state, error,
6261+
include_state, function_state, nesting_state, error, module_deps,
62506262
extra_check_functions=[]):
62516263
"""Processes a single line in the file.
62526264
@@ -6276,7 +6288,7 @@ def ProcessLine(filename, file_extension, clean_lines, line,
62766288
CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)
62776289
CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error)
62786290
CheckLanguage(filename, clean_lines, line, file_extension, include_state,
6279-
nesting_state, error)
6291+
nesting_state, error, module_deps)
62806292
CheckForNonConstReference(filename, clean_lines, line, nesting_state, error)
62816293
CheckForNonStandardConstructs(filename, clean_lines, line,
62826294
nesting_state, error)
@@ -6370,6 +6382,27 @@ def ProcessFileData(filename, file_extension, lines, error,
63706382

63716383
ResetNolintSuppressions()
63726384

6385+
# Load module dependencies
6386+
module_deps_file = os.path.join(os.path.dirname(filename), 'module_dependencies.txt')
6387+
module_deps = []
6388+
if os.path.isfile(module_deps_file):
6389+
with open(module_deps_file, 'r') as f:
6390+
module_deps = f.read().splitlines()
6391+
# strip off comments and whitespace
6392+
def strip_off_comments(s):
6393+
comment_index = s.find('#')
6394+
if comment_index >= 0:
6395+
s = s[:comment_index]
6396+
s = s.strip()
6397+
return s
6398+
module_deps = [strip_off_comments(module) for module in module_deps]
6399+
# remove empty lines
6400+
module_deps = [module for module in module_deps if len(module) != 0]
6401+
else:
6402+
error(filename, 0, 'build/include', 4,
6403+
'module_dependencies.txt not found in `' +
6404+
os.path.dirname(filename) + '`')
6405+
63736406
CheckForCopyright(filename, lines, error)
63746407
CheckForFunctionCommentHeaders(filename, lines, error)
63756408
ProcessGlobalSuppresions(lines)
@@ -6381,7 +6414,7 @@ def ProcessFileData(filename, file_extension, lines, error,
63816414

63826415
for line in xrange(clean_lines.NumLines()):
63836416
ProcessLine(filename, file_extension, clean_lines, line,
6384-
include_state, function_state, nesting_state, error,
6417+
include_state, function_state, nesting_state, error, module_deps,
63856418
extra_check_functions)
63866419
FlagCxx11Features(filename, clean_lines, line, error)
63876420
nesting_state.CheckCompletedBlocks(filename, error)

src/analyses/module_dependencies.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
analyses
2+
ansi-c # should go away
3+
goto-programs
4+
langapi # should go away
5+
pointer-analysis
6+
util
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ansi-c
2+
ansi-c/library

0 commit comments

Comments
 (0)