99 lines
3.1 KiB
Python
Executable File
99 lines
3.1 KiB
Python
Executable File
#! /usr/bin/env python3
|
|
import sys
|
|
import os
|
|
import clang.cindex
|
|
from mako.template import Template
|
|
|
|
def node_children(node):
|
|
return (c for c in node.get_children() if c.location.file.name == filename)
|
|
|
|
def get_annotations(node):
|
|
return [c.displayname for c in node.get_children() if c.kind == clang.cindex.CursorKind.ANNOTATE_ATTR]
|
|
|
|
class Variable(object):
|
|
def __init__(self, cursor):
|
|
self.name = cursor.spelling
|
|
self.annotations = get_annotations(cursor)
|
|
|
|
class Parameter(object):
|
|
def __init__(self, cursor):
|
|
self.name = cursor.spelling
|
|
self.type = cursor.type.spelling
|
|
|
|
class Constructor(object):
|
|
def __init__(self, cursor):
|
|
|
|
self.parameters = []
|
|
|
|
for c in cursor.get_children():
|
|
if c.kind == clang.cindex.CursorKind.PARM_DECL:
|
|
p = Parameter(c)
|
|
self.parameters.append(p)
|
|
|
|
class Component(object):
|
|
def __init__(self, cursor):
|
|
self.name = cursor.spelling
|
|
self.variables = []
|
|
|
|
self.constructors = []
|
|
|
|
for c in cursor.get_children():
|
|
if (c.kind == clang.cindex.CursorKind.CONSTRUCTOR and c.access_specifier == clang.cindex.AccessSpecifier.PUBLIC):
|
|
con = Constructor(c)
|
|
# if len(con.parameters) > 0:
|
|
self.constructors.append(con)
|
|
|
|
if (c.kind == clang.cindex.CursorKind.FIELD_DECL and c.access_specifier == clang.cindex.AccessSpecifier.PUBLIC):
|
|
v = Variable(c)
|
|
self.variables.append(v)
|
|
|
|
def build_components(cursor, filename):
|
|
result = []
|
|
for c in cursor.get_children():
|
|
if (c.kind == clang.cindex.CursorKind.STRUCT_DECL and c.location.file.name == filename):
|
|
for d in c.get_children():
|
|
if (d.kind == clang.cindex.CursorKind.CXX_BASE_SPECIFIER and d.spelling == "ecs::Component"):
|
|
a_class = Component(c)
|
|
result.append(a_class)
|
|
break
|
|
|
|
elif c.kind == clang.cindex.CursorKind.NAMESPACE:
|
|
child_components = build_components(c, filename)
|
|
result.extend(child_components)
|
|
|
|
return result
|
|
|
|
def main(argv):
|
|
if len(sys.argv) != 3:
|
|
print("Usage: {} [header filename] [output filename]".format(argv[0]))
|
|
sys.exit()
|
|
|
|
filename = argv[1]
|
|
output = argv[2]
|
|
|
|
index = clang.cindex.Index.create()
|
|
tu = index.parse(filename, ['-x', 'c++', '-std=c++20', f'-Iecs/include', f'-Ibuild/_deps/stduuid-src/include', '-I/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include'])
|
|
|
|
components = build_components(tu.cursor, filename)
|
|
|
|
tpl = Template(filename=f'template.mako')
|
|
|
|
include_file = filename.split('/')[-1]
|
|
|
|
if not os.path.exists(os.path.dirname(output)):
|
|
try:
|
|
os.makedirs(os.path.dirname(output))
|
|
except OSError as exc:
|
|
if exc.errno != errno.EEXIST:
|
|
raise
|
|
|
|
output_file = open(output, "w")
|
|
output_file.write(tpl.render(components=components, include_file=include_file))
|
|
output_file.close()
|
|
|
|
for d in tu.diagnostics:
|
|
print(d)
|
|
|
|
if __name__ == "__main__":
|
|
main(sys.argv)
|