8000 bpo-36876: Re-organize the c-analyzer tool code. by ericsnowcurrently · Pull Request #16841 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-36876: Re-organize the c-analyzer tool code. #16841

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Oct 19, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8ce7d62
Move show.py to c_analyzer_common.
ericsnowcurrently Sep 27, 2019
c40c247
Small cleanups around _check_results().
ericsnowcurrently Sep 27, 2019
bf3bd21
Merge c_parser.info into c_analyzer_common.info.
ericsnowcurrently Sep 27, 2019
52113ae
c_symbols.binary -> c_symbols.find.
ericsnowcurrently Sep 27, 2019
dc8333f
Add ID.match().
ericsnowcurrently Sep 30, 2019
9b47596
Add known.look_up_variable().
ericsnowcurrently Sep 30, 2019
67eea78
Add c_parser.find module.
ericsnowcurrently Sep 30, 2019
b61b704
Add c_symbols.find module.
ericsnowcurrently Sep 30, 2019
a041e4a
Avoid variable resolution in _nm.iter_symbols().
ericsnowcurrently Sep 30, 2019
b9b0499
Add c_analyzer_common.find module.
ericsnowcurrently Sep 30, 2019
15b60db
Use the new modules in __main__.
ericsnowcurrently Sep 30, 2019
2f9958f
Drop the old code.
ericsnowcurrently Sep 30, 2019
b05272c
Specify "preprocessed" option as an arg.
ericsnowcurrently Sep 30, 2019
80d299c
Add a TODO.
ericsnowcurrently Sep 30, 2019
15c1226
Use declarations.iter_all() instead of iter_variables().
ericsnowcurrently Sep 30, 2019
e08bad5
Make sure "resolve()" is used properly.
ericsnowcurrently Oct 1, 2019
fa6f1b5
Move extract_storage() to c_parser.declarations.
ericsnowcurrently Oct 4, 2019
6531014
Move the generic code under a top-level c_analyzer package.
ericsnowcurrently Oct 4, 2019
15f010b
Move some code to a new c_analyzer.variables package.
ericsnowcurrently Oct 4, 2019
c399dc0
c_global -> cpython.
ericsnowcurrently Oct 4, 2019
025e8c3
Do not use Variable in symbols or parser packages.
ericsnowcurrently Oct 15, 2019
f60551e
Drop "INCLUDES" from SOURCE_DIRS.
ericsnowcurrently Oct 18, 2019
4beba49
Process files more cleanly.
ericsnowcurrently Oct 18, 2019
9e5c09b
Fix a typo.
ericsnowcurrently Oct 18, 2019
6e14276
Call check_filename() properly.
ericsnowcurrently Oct 18, 2019
0ce0cd1
Fix one last import.
ericsnowcurrently Oct 18, 2019
264d698
Fix whitespace.
ericsnowcurrently Oct 18, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8000
Prev Previous commit
Next Next commit
Add c_analyzer_common.find module.
  • Loading branch information
ericsnowcurrently committed Sep 30, 2019
commit b9b049985bb0dd670334f2a75e31ec6102b9c864
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import unittest

from .. import tool_imports_for_tests
with tool_imports_for_tests():
from c_analyzer_common import info
from c_analyzer_common.find import vars_from_binary


class _Base(unittest.TestCase):

maxDiff = None

@property
def calls(self):
try:
return self._calls
except AttributeError:
self._calls = []
return self._calls


class VarsFromBinaryTests(_Base):

_return_iter_vars = ()
_return_get_symbol_resolver = None

def setUp(self):
super().setUp()

self.kwargs = dict(
_iter_vars=self._iter_vars,
_get_symbol_resolver=self._get_symbol_resolver,
)

def _iter_vars(self, binfile, resolve):
self.calls.append(('_iter_vars', (binfile, resolve)))
return [(v, v) for v in self._return_iter_vars]

def _get_symbol_resolver(self, known, dirnames=None, perfilecache=None):
self.calls.append(('_get_symbol_resolver', (known, dirnames, perfilecache)))
return self._return_get_symbol_resolver

def test_typical(self):
resolver = self._return_get_symbol_resolver = object()
variables = self._return_iter_vars = [
info.Variable.from_parts('dir1/spam.c', None, 'var1', 'int'),
info.Variable.from_parts('dir1/spam.c', None, 'var2', 'static int'),
info.Variable.from_parts('dir1/spam.c', None, 'var3', 'char *'),
info.Variable.from_parts('dir1/spam.c', 'func2', 'var4', 'const char *'),
info.Variable.from_parts('dir1/eggs.c', None, 'var1', 'static int'),
info.Variable.from_parts('dir1/eggs.c', 'func1', 'var2', 'static char *'),
]
known = object()
dirnames = object()

found = list(vars_from_binary('python',
known=known,
dirnames=dirnames,
**self.kwargs))

self.assertEqual(found, [
info.Variable.from_parts('dir1/spam.c', None, 'var1', 'int'),
info.Variable.from_parts('dir1/spam.c', None, 'var2', 'static int'),
info.Variable.from_parts('dir1/spam.c', None, 'var3', 'char *'),
info.Variable.from_parts('dir1/spam.c', 'func2', 'var4', 'const char *'),
info.Variable.from_parts('dir1/eggs.c', None, 'var1', 'static int'),
info.Variable.from_parts('dir1/eggs.c', 'func1', 'var2', 'static char *'),
])
self.assertEqual(self.calls, [
('_get_symbol_resolver', (known, dirnames, {})),
('_iter_vars', ('python', resolver)),
])

# self._return_iter_symbols = [
# s_info.Symbol(('dir1/spam.c', None, 'var1'), 'variable', False),
# s_info.Symbol(('dir1/spam.c', None, 'var2'), 'variable', False),
# s_info.Symbol(('dir1/spam.c', None, 'func1'), 'function', False),
# s_info.Symbol(('dir1/spam.c', None, 'func2'), 'function', True),
# s_info.Symbol(('dir1/spam.c', None, 'var3'), 'variable', False),
# s_info.Symbol(('dir1/spam.c', 'func2', 'var4'), 'variable', False),
# s_info.Symbol(('dir1/ham.c', None, 'var1'), 'variable', True),
# s_info.Symbol(('dir1/eggs.c', None, 'var1'), 'variable', False),
# s_info.Symbol(('dir1/eggs.c', None, 'xyz'), 'other', False),
# s_info.Symbol(('dir1/eggs.c', '???', 'var2'), 'variable', False),
# s_info.Symbol(('???', None, 'var_x'), 'variable', False),
# s_info.Symbol(('???', '???', 'var_y'), 'variable', False),
# s_info.Symbol((None, None, '???'), 'other', False),
# ]
# known = object()
#
# vars_from_binary('python', knownvars=known, **this.kwargs)
# found = list(globals_from_symbols(['dir1'], self.iter_symbols))
#
# self.assertEqual(found, [
# info.Variable.from_parts('dir1/spam.c', None, 'var1', '???'),
# info.Variable.from_parts('dir1/spam.c', None, 'var2', '???'),
# info.Variable.from_parts('dir1/spam.c', None, 'var3', '???'),
# info.Variable.from_parts('dir1/spam.c', 'func2', 'var4', '???'),
# info.Variable.from_parts('dir1/eggs.c', None, 'var1', '???'),
# ])
# self.assertEqual(self.calls, [
# ('iter_symbols', (['dir1'],)),
# ])
#
# def test_no_symbols(self):
# self._return_iter_symbols = []
#
# found = list(globals_from_symbols(['dir1'], self.iter_symbols))
#
# self.assertEqual(found, [])
# self.assertEqual(self.calls, [
# ('iter_symbols', (['dir1'],)),
# ])

# XXX need functional test
62 changes: 62 additions & 0 deletions Tools/c-analyzer/c_analyzer_common/find.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from c_analyzer_common import SOURCE_DIRS, PYTHON
from c_analyzer_common.info import UNKNOWN, Variable
from c_symbols import (
info as s_info,
find as s_find,
)


# XXX needs tests:
# * vars_from_source
# * vars_from_preprocessed


def _remove_cached(cache, var):
if not cache:
return
try:
cached = cache[var.filename]
cached.remove(var)
except (KeyError, IndexError):
pass


def vars_from_binary(binfile=PYTHON, *,
known=None,
dirnames=SOURCE_DIRS,
_iter_vars=s_find.variables,
_get_symbol_resolver=s_find.get_resolver,
):
"""Yield a Variable for each found Symbol.

Details are filled in from the given "known" variables and types.
"""
cache = {}
resolve = _get_symbol_resolver(known, dirnames,
perfilecache=cache,
)
for var, symbol in _iter_vars(binfile, resolve=resolve):
if var is None:
var = Variable(symbol.id, UNKNOWN, UNKNOWN)
yield var
_remove_cached(cache, var)


def vars_from_source(filenames, *,
known=None,
):
"""Yield a Variable for each declaration in the raw source code.

Details are filled in from the given "known" variables and types.
"""
raise NotImplementedError


def vars_from_preprocessed(filenames, *,
known=None,
):
"""Yield a Variable for each found declaration.

Details are filled in from the given "known" variables and types.
"""
raise NotImplementedError
0