Skip to content
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

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

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
Prev Previous commit
Next Next commit
Merge c_parser.info into c_analyzer_common.info.
  • Loading branch information
ericsnowcurrently committed Sep 27, 2019
commit bf3bd21dbc8fbc139ceb369f26195a56f156c0d2
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
from ..util import PseudoStr, StrProxy, Object
from .. import tool_imports_for_tests
with tool_imports_for_tests():
from c_analyzer_common.info import ID
from c_analyzer_common.info import (
UNKNOWN,
ID,
normalize_vartype, Variable
)


class IDTests(unittest.TestCase):
Expand Down Expand Up @@ -192,3 +196,237 @@ def test_validate_bad_field(self):
id = id._replace(**{field: value})

id.validate() # This does not fail.


class NormalizeVartypeTests(unittest.TestCase):

def test_basic(self):
tests = [
(None, None),
('', ''),
('int', 'int'),
(PseudoStr('int'), 'int'),
(StrProxy('int'), 'int'),
]
for vartype, expected in tests:
with self.subTest(vartype):
normalized = normalize_vartype(vartype)

self.assertEqual(normalized, expected)


class VariableTests(unittest.TestCase):

VALID_ARGS = (
('x/y/z/spam.c', 'func', 'eggs'),
'static',
'int',
)
VALID_KWARGS = dict(zip(Variable._fields, VALID_ARGS))
VALID_EXPECTED = VALID_ARGS

def test_init_typical_global(self):
for storage in ('static', 'extern', 'implicit'):
with self.subTest(storage):
static = Variable(
id=ID(
filename='x/y/z/spam.c',
funcname=None,
name='eggs',
),
storage=storage,
vartype='int',
)

self.assertEqual(static, (
('x/y/z/spam.c', None, 'eggs'),
storage,
'int',
))

def test_init_typical_local(self):
for storage in ('static', 'local'):
with self.subTest(storage):
static = Variable(
id=ID(
filename='x/y/z/spam.c',
funcname='func',
name='eggs',
),
storage=storage,
vartype='int',
)

self.assertEqual(static, (
('x/y/z/spam.c', 'func', 'eggs'),
storage,
'int',
))

def test_init_all_missing(self):
for value in ('', None):
with self.subTest(repr(value)):
static = Variable(
id=value,
storage=value,
vartype=value,
)

self.assertEqual(static, (
None,
None,
None,
))

def test_init_all_coerced(self):
id = ID('x/y/z/spam.c', 'func', 'spam')
tests = [
('str subclass',
dict(
id=(
PseudoStr('x/y/z/spam.c'),
PseudoStr('func'),
PseudoStr('spam'),
),
storage=PseudoStr('static'),
vartype=PseudoStr('int'),
),
(id,
'static',
'int',
)),
('non-str 1',
dict(
id=id,
storage=Object(),
vartype=Object(),
),
(id,
'<object>',
'<object>',
)),
('non-str 2',
dict(
id=id,
storage=StrProxy('static'),
vartype=StrProxy('variable'),
),
(id,
'static',
'variable',
)),
('non-str',
dict(
id=id,
storage=('a', 'b', 'c'),
vartype=('x', 'y', 'z'),
),
(id,
"('a', 'b', 'c')",
"('x', 'y', 'z')",
)),
]
for summary, kwargs, expected in tests:
with self.subTest(summary):
static = Variable(**kwargs)

for field in Variable._fields:
value = getattr(static, field)
if field == 'id':
self.assertIs(type(value), ID)
else:
self.assertIs(type(value), str)
self.assertEqual(tuple(static), expected)

def test_iterable(self):
static = Variable(**self.VALID_KWARGS)

id, storage, vartype = static

values = (id, storage, vartype)
for value, expected in zip(values, self.VALID_EXPECTED):
self.assertEqual(value, expected)

def test_fields(self):
static = Variable(('a', 'b', 'z'), 'x', 'y')

self.assertEqual(static.id, ('a', 'b', 'z'))
self.assertEqual(static.storage, 'x')
self.assertEqual(static.vartype, 'y')

def test___getattr__(self):
static = Variable(('a', 'b', 'z'), 'x', 'y')

self.assertEqual(static.filename, 'a')
self.assertEqual(static.funcname, 'b')
self.assertEqual(static.name, 'z')

def test_validate_typical(self):
validstorage = ('static', 'extern', 'implicit', 'local')
self.assertEqual(set(validstorage), set(Variable.STORAGE))

for storage in validstorage:
with self.subTest(storage):
static = Variable(
id=ID(
filename='x/y/z/spam.c',
funcname='func',
name='eggs',
),
storage=storage,
vartype='int',
)

static.validate() # This does not fail.

def test_validate_missing_field(self):
for field in Variable._fields:
with self.subTest(field):
static = Variable(**self.VALID_KWARGS)
static = static._replace(**{field: None})

with self.assertRaises(TypeError):
static.validate()
for field in ('storage', 'vartype'):
with self.subTest(field):
static = Variable(**self.VALID_KWARGS)
static = static._replace(**{field: UNKNOWN})

with self.assertRaises(TypeError):
static.validate()

def test_validate_bad_field(self):
badch = tuple(c for c in string.punctuation + string.digits)
notnames = (
'1a',
'a.b',
'a-b',
'&a',
'a++',
) + badch
tests = [
('id', ()), # Any non-empty str is okay.
('storage', ('external', 'global') + notnames),
('vartype', ()), # Any non-empty str is okay.
]
seen = set()
for field, invalid in tests:
for value in invalid:
seen.add(value)
with self.subTest(f'{field}={value!r}'):
static = Variable(**self.VALID_KWARGS)
static = static._replace(**{field: value})

with self.assertRaises(ValueError):
static.validate()

for field, invalid in tests:
if field == 'id':
continue
valid = seen - set(invalid)
for value in valid:
with self.subTest(f'{field}={value!r}'):
static = Variable(**self.VALID_KWARGS)
static = static._replace(**{field: value})

static.validate() # This does not fail.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

from .. import tool_imports_for_tests
with tool_imports_for_tests():
from c_parser.info import Variable
from c_analyzer_common.info import ID
from c_analyzer_common.info import ID, Variable
from c_analyzer_common.known import from_file


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from .. import tool_imports_for_tests
with tool_imports_for_tests():
from c_parser import info
from c_analyzer_common import info
from c_analyzer_common.show import basic


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@

from .. import tool_imports_for_tests
with tool_imports_for_tests():
from c_analyzer_common import SOURCE_DIRS
from c_analyzer_common import SOURCE_DIRS, info
from c_analyzer_common.known import DATA_FILE as KNOWN_FILE
from c_parser import info
import c_globals as cg
from c_globals.supported import IGNORED_FILE
from c_globals.__main__ import cmd_check, cmd_show, parse_args, main
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from .. import tool_imports_for_tests
with tool_imports_for_tests():
from c_parser import info
from c_analyzer_common import info
from c_globals.find import globals_from_binary, globals


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

from .. import tool_imports_for_tests
with tool_imports_for_tests():
from c_analyzer_common.info import ID
from c_parser import info
from c_analyzer_common.info import ID, Variable
from c_globals.supported import is_supported, ignored_from_file


Expand All @@ -14,8 +13,8 @@ class IsSupportedTests(unittest.TestCase):
@unittest.expectedFailure
def test_supported(self):
statics = [
info.StaticVar('src1/spam.c', None, 'var1', 'const char *'),
info.StaticVar('src1/spam.c', None, 'var1', 'int'),
Variable('src1/spam.c', None, 'var1', 'const char *'),
Variable('src1/spam.c', None, 'var1', 'int'),
]
for static in statics:
with self.subTest(static):
Expand All @@ -26,8 +25,8 @@ def test_supported(self):
@unittest.expectedFailure
def test_not_supported(self):
statics = [
info.StaticVar('src1/spam.c', None, 'var1', 'PyObject *'),
info.StaticVar('src1/spam.c', None, 'var1', 'PyObject[10]'),
Variable('src1/spam.c', None, 'var1', 'PyObject *'),
Variable('src1/spam.c', None, 'var1', 'PyObject[10]'),
]
for static in statics:
with self.subTest(static):
Expand Down
Loading