Skip to content

Commit 24ac439

Browse files
committed
Make IR file-scoped and add source_path metadata
Refactor the bindgen IR to be file-scoped: IRModule now holds a files: Dict[path, IRFile] map (IRFile groups types/enums/functions/classes/constants/aliases). Add source_path metadata to IR nodes (fields, structs, enums, aliases, functions, methods, classes, constants) and collect entities into per-file buckets in the normalizer. Normalize now detects cursor file paths, handles lvalue/rvalue references and elaborated/unexposed types, records class fields/bases, constructors/destructors, and filters out operators. Serializer now emits the files map, codegen context exposes files, file_paths and flattened lists, and example README/template and header discovery sorting were updated accordingly.
1 parent 60175d4 commit 24ac439

File tree

7 files changed

+323
-72
lines changed

7 files changed

+323
-72
lines changed

tools/bindgen/README.md

Lines changed: 63 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -102,44 +102,68 @@ C++ Headers
102102

103103
### 模块(IRModule)
104104

105-
- headers
106-
- types
107-
- functions
108-
- classes
109-
- constants
110-
- aliases
105+
- IR 输出为 `path -> IRFile` 的 map(不再包含 `headers` 节点)
106+
- `IRFile` 结构包含:
107+
- types
108+
- enums
109+
- functions
110+
- classes
111+
- constants
112+
- aliases
113+
- `source_path`:结构体/枚举/函数/别名/常量/类/方法/字段所在头文件路径(如 `src/foundation/color.h`
111114

112115
### IR JSON 示例(最小)
113116

114117
```json
115118
{
116-
"headers": ["include/nativeapi.h"],
117-
"types": [
118-
{
119-
"kind": "struct",
120-
"name": "Point",
121-
"fields": [
122-
{"name": "x", "type": {"kind": "float32"}},
123-
{"name": "y", "type": {"kind": "float32"}}
124-
]
125-
}
126-
],
127-
"functions": [
128-
{
129-
"name": "na_distance",
130-
"return_type": {"kind": "float32"},
131-
"params": [
132-
{"name": "a", "type": {"kind": "pointer", "to": {"kind": "struct", "name": "Point"}}, "nullable": false},
133-
{"name": "b", "type": {"kind": "pointer", "to": {"kind": "struct", "name": "Point"}}, "nullable": false}
134-
]
135-
}
136-
],
137-
"constants": [
138-
{"name": "NA_OK", "type": {"kind": "int32"}, "value": 0}
139-
],
140-
"aliases": [
141-
{"name": "NAHandle", "target": {"kind": "uintptr"}}
142-
]
119+
"src/foundation/geometry.h": {
120+
"types": [
121+
{
122+
"kind": "struct",
123+
"name": "Point",
124+
"source_path": "src/foundation/geometry.h",
125+
"fields": [
126+
{"name": "x", "type": {"kind": "float32"}, "source_path": "src/foundation/geometry.h"},
127+
{"name": "y", "type": {"kind": "float32"}, "source_path": "src/foundation/geometry.h"}
128+
]
129+
}
130+
],
131+
"functions": [
132+
{
133+
"name": "na_distance",
134+
"source_path": "src/foundation/geometry.h",
135+
"return_type": {"kind": "float32"},
136+
"params": [
137+
{"name": "a", "type": {"kind": "pointer", "to": {"kind": "struct", "name": "Point"}}, "nullable": false},
138+
{"name": "b", "type": {"kind": "pointer", "to": {"kind": "struct", "name": "Point"}}, "nullable": false}
139+
]
140+
}
141+
],
142+
"enums": [],
143+
"classes": [],
144+
"constants": [],
145+
"aliases": []
146+
},
147+
"src/foundation/error.h": {
148+
"types": [],
149+
"enums": [],
150+
"functions": [],
151+
"classes": [],
152+
"constants": [
153+
{"name": "NA_OK", "type": {"kind": "int32"}, "value": 0, "source_path": "src/foundation/error.h"}
154+
],
155+
"aliases": []
156+
},
157+
"src/foundation/types.h": {
158+
"types": [],
159+
"enums": [],
160+
"functions": [],
161+
"classes": [],
162+
"constants": [],
163+
"aliases": [
164+
{"name": "NAHandle", "target": {"kind": "uintptr"}, "source_path": "src/foundation/types.h"}
165+
]
166+
}
143167
}
144168
```
145169

@@ -207,11 +231,13 @@ render_to_files(templates, context, out_dir)
207231

208232
**模板上下文约定(建议)**
209233

210-
- `module`: 当前模块信息(headers, namespaces)
211-
- `types`: 结构体/枚举/别名列表(已排序)
212-
- `functions`: 函数列表(已过滤)
234+
- `module`: 当前模块信息(含 `files`
235+
- `files`: path -> IRFile 的 map
236+
- `file_paths`: 排序后的文件路径列表
237+
- `types`: 结构体/枚举/别名列表(已扁平化并排序)
238+
- `functions`: 函数列表(已过滤并扁平化)
213239
- `classes`: C++ 类/struct 列表(public methods)
214-
- `constants`: 常量列表
240+
- `constants`: 常量列表(扁平化)
215241
- `mapping`: 语言映射配置(types/conventions/naming)
216242

217243
**优点**

tools/bindgen/codegen/context.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,31 @@
66

77

88
def build_context(module: IRModule, mapping: Dict) -> Dict:
9+
files = module.files
10+
sorted_paths = sorted(files.keys())
11+
types = []
12+
enums = []
13+
functions = []
14+
classes = []
15+
constants = []
16+
aliases = []
17+
for path in sorted_paths:
18+
bucket = files[path]
19+
types.extend(bucket.types)
20+
enums.extend(bucket.enums)
21+
functions.extend(bucket.functions)
22+
classes.extend(bucket.classes)
23+
constants.extend(bucket.constants)
24+
aliases.extend(bucket.aliases)
925
return {
1026
"module": module,
11-
"types": module.types,
12-
"enums": module.enums,
13-
"functions": module.functions,
14-
"classes": module.classes,
15-
"constants": module.constants,
16-
"aliases": module.aliases,
27+
"files": files,
28+
"file_paths": sorted_paths,
29+
"types": types,
30+
"enums": enums,
31+
"functions": functions,
32+
"classes": classes,
33+
"constants": constants,
34+
"aliases": aliases,
1735
"mapping": mapping,
1836
}

tools/bindgen/example/bindgen/template/example.txt.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Generated by bindgen example template.
22
language={{ mapping.language | default("example") }}
3-
headers={{ module.headers|length }}
3+
files={{ file_paths|length }}
44
structs={{ types|length }}
55
enums={{ enums|length }}
66
functions={{ functions|length }}

tools/bindgen/ir/model.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22

33
from dataclasses import dataclass, field
4-
from typing import List, Optional
4+
from typing import Dict, List, Optional
55

66

77
@dataclass
@@ -19,13 +19,15 @@ class IRType:
1919
class IRField:
2020
name: str
2121
type: IRType
22+
source_path: Optional[str] = None
2223

2324

2425
@dataclass
2526
class IRStruct:
2627
name: str
2728
fields: List[IRField]
2829
qualified_name: Optional[str] = None
30+
source_path: Optional[str] = None
2931

3032

3133
@dataclass
@@ -40,12 +42,14 @@ class IREnum:
4042
values: List[IREnumValue]
4143
scoped: bool = False
4244
qualified_name: Optional[str] = None
45+
source_path: Optional[str] = None
4346

4447

4548
@dataclass
4649
class IRAlias:
4750
name: str
4851
target: IRType
52+
source_path: Optional[str] = None
4953

5054

5155
@dataclass
@@ -64,39 +68,50 @@ class IRFunction:
6468
callconv: Optional[str] = None
6569
variadic: bool = False
6670
qualified_name: Optional[str] = None
71+
source_path: Optional[str] = None
6772

6873

6974
@dataclass
7075
class IRMethod:
7176
name: str
7277
return_type: IRType
7378
params: List[IRParam]
79+
kind: str = "method"
7480
static: bool = False
7581
const: bool = False
7682
access: Optional[str] = None
7783
variadic: bool = False
84+
source_path: Optional[str] = None
7885

7986

8087
@dataclass
8188
class IRClass:
8289
name: str
90+
fields: List[IRField] = field(default_factory=list)
8391
methods: List[IRMethod] = field(default_factory=list)
92+
bases: List[str] = field(default_factory=list)
8493
qualified_name: Optional[str] = None
94+
source_path: Optional[str] = None
8595

8696

8797
@dataclass
8898
class IRConstant:
8999
name: str
90100
type: IRType
91101
value: int | float | str
102+
source_path: Optional[str] = None
92103

93104

94105
@dataclass
95-
class IRModule:
96-
headers: List[str]
106+
class IRFile:
97107
types: List[IRStruct] = field(default_factory=list)
98108
enums: List[IREnum] = field(default_factory=list)
99109
functions: List[IRFunction] = field(default_factory=list)
100110
classes: List[IRClass] = field(default_factory=list)
101111
constants: List[IRConstant] = field(default_factory=list)
102112
aliases: List[IRAlias] = field(default_factory=list)
113+
114+
115+
@dataclass
116+
class IRModule:
117+
files: Dict[str, IRFile] = field(default_factory=dict)

tools/bindgen/ir/serializer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99

1010
def dump_ir_json(module: IRModule, path: Path) -> None:
11-
payload = asdict(module)
11+
payload = asdict(module)["files"]
1212
path.parent.mkdir(parents=True, exist_ok=True)
1313
path.write_text(
1414
json.dumps(payload, indent=2, ensure_ascii=False) + "\n", encoding="utf-8"

0 commit comments

Comments
 (0)