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
97
98
99
100
101
102
103
104
105
|
from c_parser import (
parse_files as _parse_files,
)
from c_parser.info import (
KIND,
TypeDeclaration,
resolve_parsed,
)
from c_parser.match import (
filter_by_kind,
group_by_kinds,
)
from . import (
analyze as _analyze,
datafiles as _datafiles,
)
from .info import Analysis
def analyze(filenmes, **kwargs):
results = iter_analysis_results(filenames, **kwargs)
return Analysis.from_results(results)
def iter_analysis_results(filenmes, *,
known=None,
**kwargs
):
decls = iter_decls(filenames, **kwargs)
yield from analyze_decls(decls, known)
def iter_decls(filenames, *,
kinds=None,
parse_files=_parse_files,
**kwargs
):
kinds = KIND.DECLS if kinds is None else (KIND.DECLS & set(kinds))
parse_files = parse_files or _parse_files
parsed = parse_files(filenames, **kwargs)
parsed = filter_by_kind(parsed, kinds)
for item in parsed:
yield resolve_parsed(item)
def analyze_decls(decls, known, *,
analyze_resolved=None,
handle_unresolved=True,
relroot=None,
):
knowntypes, knowntypespecs = _datafiles.get_known(
known,
handle_unresolved=handle_unresolved,
analyze_resolved=analyze_resolved,
relroot=relroot,
)
decls = list(decls)
collated = group_by_kinds(decls)
types = {decl: None for decl in collated['type']}
typespecs = _analyze.get_typespecs(types)
def analyze_decl(decl):
return _analyze.analyze_decl(
decl,
typespecs,
knowntypespecs,
types,
knowntypes,
analyze_resolved=analyze_resolved,
)
_analyze.analyze_type_decls(types, analyze_decl, handle_unresolved)
for decl in decls:
if decl in types:
resolved = types[decl]
else:
resolved = analyze_decl(decl)
if resolved and handle_unresolved:
typedeps, _ = resolved
if not isinstance(typedeps, TypeDeclaration):
if not typedeps or None in typedeps:
raise NotImplementedError((decl, resolved))
yield decl, resolved
#######################################
# checks
def check_all(analysis, checks, *, failfast=False):
for check in checks or ():
for data, failure in check(analysis):
if failure is None:
continue
yield data, failure
if failfast:
yield None, None
break
else:
continue
# We failed fast.
break
|