Skip to content

Commit 380f6e2

Browse files
authored
Add type linting for HtPP and RzGraph + fix CI (#114)
* Add type linting for HtPP and RzGraph. * Add struct, constructor, and destructor of RzAsm to fix forward declaration error. * Add struct, constructor, and destructor of RzAnalysis to fix forward declaration error. * Fix incorrect type annotation (they are CursorKind not TypeKind in cindex.py).
1 parent b2a1f44 commit 380f6e2

3 files changed

Lines changed: 59 additions & 27 deletions

File tree

src/bindings.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,19 +150,19 @@ def bind_analysis(analysis_h: Header) -> None:
150150
rz_analysis = Class(
151151
analysis_h,
152152
typedef="RzAnalysis",
153-
ignore_fields={"leaddrs"},
154-
rename_fields={},
153+
struct="rz_analysis_t",
155154
)
156155

157156
rz_analysis_function = Class(analysis_h, typedef="RzAnalysisFunction")
158157
rz_analysis_function.add_method("rz_analysis_function_delete", rename="delete_self")
159158
rz_analysis_function.add_prefixed_methods("rz_analysis_function_")
160159

161160
rz_analysis.add_method("rz_analysis_reflines_get", rename="get_reflines")
162-
rz_analysis.add_prefixed_methods("rz_analysis_")
163-
rz_analysis.add_prefixed_funcs("rz_analysis_")
161+
rz_analysis.add_constructor("rz_analysis_new")
162+
rz_analysis.add_destructor("rz_analysis_free")
163+
164+
Class(analysis_h, typedef="RzAnalysisBlock", struct="rz_analysis_bb_t")
164165

165-
Class(analysis_h, typedef="RzAnalysisBlock")
166166
Class(analysis_h, typedef="RzAnalysisEsil")
167167
Class(analysis_h, typedef="RzAnalysisEsilInterState")
168168
Class(analysis_h, typedef="RzAnalysisPlugin")
@@ -180,7 +180,13 @@ def bind_asm(asm_h: Header) -> None:
180180
"""
181181
RzAsm
182182
"""
183-
Class(asm_h, typedef="RzAsm") # TODO: Add functions
183+
184+
rz_asm = Class(asm_h, typedef="RzAsm", struct="rz_asm_t") # TODO: Add functions
185+
rz_asm.add_constructor("rz_asm_new")
186+
rz_asm.add_destructor("rz_asm_free")
187+
rz_asm.add_prefixed_methods("rz_asm_")
188+
rz_asm.add_prefixed_funcs("rz_asm_")
189+
184190
Class(asm_h, typedef="RzAsmPlugin")
185191

186192

src/clang/cindex.pyi

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -110,23 +110,23 @@ class Token:
110110
extent: SourceRange
111111

112112
class CursorKind(Enum):
113-
INCLUSION_DIRECTIVE: TypeKind
114-
MACRO_INSTANTIATION: TypeKind
115-
116-
ENUM_DECL: TypeKind
117-
MACRO_DEFINITION: TypeKind
118-
STRUCT_DECL: TypeKind
119-
TYPEDEF_DECL: TypeKind
120-
FUNCTION_DECL: TypeKind
121-
122-
FIELD_DECL: TypeKind
123-
UNION_DECL: TypeKind
124-
PARM_DECL: TypeKind
125-
ENUM_CONSTANT_DECL: TypeKind
126-
127-
ANNOTATE_ATTR: TypeKind
128-
TYPE_REF: TypeKind
129-
PACKED_ATTR: TypeKind
113+
INCLUSION_DIRECTIVE: CursorKind
114+
MACRO_INSTANTIATION: CursorKind
115+
116+
ENUM_DECL: CursorKind
117+
MACRO_DEFINITION: CursorKind
118+
STRUCT_DECL: CursorKind
119+
TYPEDEF_DECL: CursorKind
120+
FUNCTION_DECL: CursorKind
121+
122+
FIELD_DECL: CursorKind
123+
UNION_DECL: CursorKind
124+
PARM_DECL: CursorKind
125+
ENUM_CONSTANT_DECL: CursorKind
126+
127+
ANNOTATE_ATTR: CursorKind
128+
TYPE_REF: CursorKind
129+
PACKED_ATTR: CursorKind
130130

131131
class Cursor:
132132
kind: CursorKind

src/lint.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from argparse import ArgumentParser
3535
from dataclasses import dataclass
3636
from itertools import zip_longest
37+
from pathlib import Path
3738

3839
from clang.cindex import (
3940
Config,
@@ -82,6 +83,14 @@ def warn(warning: str) -> None:
8283
warnings.add(warning)
8384

8485

86+
def location_get_filename(location: SourceLocation) -> str:
87+
"""
88+
Get filename for a SourceLocation
89+
"""
90+
path = Path(os.path.abspath(location.file.name))
91+
return path.name
92+
93+
8594
def stringify_location(location: SourceLocation) -> str:
8695
"""
8796
Get <relpath:filename:line> for a SourceLocation
@@ -101,7 +110,8 @@ def cursor_get_annotations(cursor: Cursor) -> List[str]:
101110
]
102111

103112

104-
generic_types = {"RzList", "RzListIter", "RzPVector", "RzVector", "RzGraph"}
113+
generic_types = {"RzList", "RzListIter", "RzPVector", "RzVector", "RzGraph", "HtPP"}
114+
skip_files = {"ht_inc.c", "ht_inc.h", "rz_th_ht.h", "thread_hash_table.c"}
105115

106116

107117
def cursor_get_comment(cursor: Cursor, *, packed: bool = False) -> Optional[str]:
@@ -161,7 +171,10 @@ def cursor_get_comment(cursor: Cursor, *, packed: bool = False) -> Optional[str]
161171
# Filter out other tokens
162172
comment = token.spelling
163173
if not comment.startswith("/*") or not comment.endswith("*/"):
164-
if typeref_spelling in generic_types:
174+
if (
175+
typeref_spelling in generic_types
176+
and location_get_filename(cursor.location) not in skip_files
177+
):
165178
warn(
166179
f"Missing type comment at {stringify_location(cursor.location)} "
167180
"(token is not a comment)"
@@ -177,7 +190,7 @@ def cursor_get_comment(cursor: Cursor, *, packed: bool = False) -> Optional[str]
177190
return comment
178191

179192
# Check pointer (or lack of) and space between pointer
180-
if typeref_spelling in {"RzList", "RzListIter", "RzPVector", "RzGraph"}:
193+
if typeref_spelling in {"RzList", "RzListIter", "RzPVector"}:
181194
if comment[-2] != "*":
182195
warn(f"Type comment at {stringify_location(cursor.location)} lacks pointer")
183196
elif comment[-3] != " ":
@@ -189,8 +202,21 @@ def cursor_get_comment(cursor: Cursor, *, packed: bool = False) -> Optional[str]
189202
warn(
190203
f"Type comment at {stringify_location(cursor.location)} should not have pointer"
191204
)
205+
elif typeref_spelling in {"RzGraph", "HtPP"}:
206+
if not re.match(
207+
r"<(struct )?[A-Za-z0-9_]+ \*, (struct )?[A-Za-z0-9_]+ \*>", comment
208+
):
209+
if typeref_spelling == "RzGraph":
210+
warn(
211+
f"Type comment at {stringify_location(cursor.location)} must "
212+
f"follow exactly the pattern '/*<NodeType *, EdgeType *>*/'. Is: '{comment}'"
213+
)
214+
elif typeref_spelling == "HtPP":
215+
warn(
216+
f"Type comment at {stringify_location(cursor.location)} must "
217+
f"follow exactly the pattern '/*<KeyType *, ValueType *>*/'. Is: '{comment}'"
218+
)
192219
elif typeref_spelling in {
193-
"HtPP",
194220
"HtUP",
195221
"HtUU",
196222
"HtPU",

0 commit comments

Comments
 (0)