Added automatic binding generator script with basic template, updated/extended parser and added generated error and file listing
Former-commit-id: cb25fb2ce7
This commit is contained in:
+50
-39
@@ -3,10 +3,16 @@ import os
|
||||
from threading import Thread
|
||||
|
||||
import clang.cindex
|
||||
import ccsyspath
|
||||
import itertools
|
||||
from mako.template import Template
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def get_annotations(node):
|
||||
return [c.displayname for c in node.get_children()
|
||||
if c.kind == clang.cindex.CursorKind.ANNOTATE_ATTR]
|
||||
@@ -17,33 +23,33 @@ class Function(object):
|
||||
self.name = cursor.spelling
|
||||
self.annotations = get_annotations(cursor)
|
||||
self.access = cursor.access_specifier
|
||||
# template_pars = [c.extent for c in cursor.get_children() if c.kind == clang.cindex.CursorKind.TEMPLATE_TYPE_PARAMETER]
|
||||
# parameter_dec = [c for c in cursor.get_children() if c.kind == clang.cindex.CursorKind.PARM_DECL]
|
||||
# print(parameter_dec, template_pars)
|
||||
# print(cursor.get_num_template_arguments(), cursor.get_template_argument_type(0), cursor.get_template_argument_value(0), template_pars, parameter_dec)
|
||||
self.parameters = []
|
||||
self.parnames = []
|
||||
# template_pars = [c.extent for c in cursor.get_children() if c.kind == clang.cindex.CursorKind.TEMPLATE_TYPE_PARAMETER]
|
||||
parameter_dec = [c for c in cursor.get_children() if c.kind == clang.cindex.CursorKind.PARM_DECL]
|
||||
|
||||
parameters = []
|
||||
for p in parameter_dec:
|
||||
children = []
|
||||
for c in p.get_children():
|
||||
# print(c.spelling)
|
||||
children.append(c.spelling)
|
||||
parameters.append((p.spelling, p.type.spelling, children))
|
||||
|
||||
self.parameters = parameters
|
||||
self.documentation = cursor.raw_comment
|
||||
|
||||
|
||||
class Enum(object):
|
||||
def __init__(self, cursor):
|
||||
self.name = cursor.spelling
|
||||
self.annotations = get_annotations(cursor)
|
||||
self.access = cursor.access_specifier
|
||||
# template_pars = [c.extent for c in cursor.get_children() if c.kind == clang.cindex.CursorKind.TEMPLATE_TYPE_PARAMETER]
|
||||
# parameter_dec = [c for c in cursor.get_children() if c.kind == clang.cindex.CursorKind.PARM_DECL]
|
||||
# print(parameter_dec, template_pars)
|
||||
# print(cursor.get_num_template_arguments(), cursor.get_template_argument_type(0), cursor.get_template_argument_value(0), template_pars, parameter_dec)
|
||||
self.parameters = []
|
||||
self.parnames = []
|
||||
self.constants = [c.spelling for c in cursor.get_children() if c.kind ==
|
||||
clang.cindex.CursorKind.ENUM_CONSTANT_DECL]
|
||||
self.documentation = cursor.raw_comment
|
||||
|
||||
# class Class(object):
|
||||
# def __init__(self, cursor):
|
||||
# self.name = cursor.spelling
|
||||
class Class(object):
|
||||
def __init__(self, cursor):
|
||||
self.name = cursor.spelling
|
||||
# self.functions = []
|
||||
# self.annotations = get_annotations(cursor)
|
||||
self.annotations = get_annotations(cursor)
|
||||
|
||||
# for c in cursor.get_children():
|
||||
# if (c.kind == clang.cindex.CursorKind.CXX_METHOD and
|
||||
@@ -51,19 +57,16 @@ class Enum(object):
|
||||
# f = Function(c)
|
||||
# self.functions.append(f)
|
||||
|
||||
def find_namespace_node(c):
|
||||
if (c.kind == clang.cindex.CursorKind.NAMESPACE and c.spelling == "igl"):
|
||||
return c
|
||||
else:
|
||||
for child_node in c.get_children():
|
||||
return find_namespace_node(child_node)
|
||||
|
||||
|
||||
def traverse(c, path, objects):
|
||||
if c.location.file and not c.location.file.name.endswith(path):
|
||||
return
|
||||
|
||||
# print(c.kind, c.spelling)
|
||||
if c.spelling == "PARULA_COLOR_MAP": # Fix to prevent python stack overflow from infinite recursion
|
||||
return
|
||||
|
||||
# print(c.kind, c.spelling)
|
||||
|
||||
|
||||
if c.kind == clang.cindex.CursorKind.TRANSLATION_UNIT or c.kind == clang.cindex.CursorKind.UNEXPOSED_DECL:
|
||||
@@ -76,7 +79,7 @@ def traverse(c, path, objects):
|
||||
pass
|
||||
|
||||
elif c.kind == clang.cindex.CursorKind.FUNCTION_TEMPLATE:
|
||||
# print("Function Template", c.spelling, c.raw_comment)
|
||||
# print("Function Template", c.spelling, c.raw_comment)
|
||||
objects["functions"].append(Function(c))
|
||||
return
|
||||
|
||||
@@ -90,6 +93,18 @@ def traverse(c, path, objects):
|
||||
objects["enums"].append(Enum(c))
|
||||
return
|
||||
|
||||
elif c.kind == clang.cindex.CursorKind.CLASS_DECL:
|
||||
objects["classes"].append(Class(c))
|
||||
return
|
||||
|
||||
elif c.kind == clang.cindex.CursorKind.CLASS_TEMPLATE:
|
||||
objects["classes"].append(Class(c))
|
||||
return
|
||||
|
||||
elif c.kind == clang.cindex.CursorKind.STRUCT_DECL:
|
||||
objects["structs"].append(Class(c))
|
||||
return
|
||||
|
||||
else:
|
||||
# print("Unknown", c.kind, c.spelling)
|
||||
pass
|
||||
@@ -100,20 +115,16 @@ def traverse(c, path, objects):
|
||||
|
||||
def parse(path):
|
||||
index = clang.cindex.Index.create()
|
||||
tu = index.parse(path, ['-x', 'c++', '-std=c++11', '-fparse-all-comments', '-DIGL_STATIC_LIBRARY'])
|
||||
# Clang can't parse files with missing definitions, add static library definition
|
||||
objects = {"functions": [], "enums": [], "namespaces": [], "classes": []}
|
||||
# Clang can't parse files with missing definitions, add static library definition or not?
|
||||
args = ['-x', 'c++', '-std=c++11', '-fparse-all-comments', '-DIGL_STATIC_LIBRARY']
|
||||
args.append('-I/usr/include/eigen3/') # TODO Properly add all needed includes
|
||||
syspath = ccsyspath.system_include_paths('clang++-3.7') # Add the system libraries
|
||||
incargs = [(b'-I' + inc).decode("utf-8") for inc in syspath]
|
||||
args.extend(incargs)
|
||||
|
||||
tu = index.parse(path, args)
|
||||
objects = {"functions": [], "enums": [], "namespaces": [], "classes": [], "structs": []}
|
||||
traverse(tu.cursor, path, objects)
|
||||
|
||||
# tpl = Template(filename='bind.mako')
|
||||
# rendered = tpl.render(functions=functions)
|
||||
|
||||
# OUTPUT_DIR = 'generated'
|
||||
|
||||
# if not os.path.isdir(OUTPUT_DIR): os.mkdir(OUTPUT_DIR)
|
||||
|
||||
# with open("generated/{}.bind.cc".format(sys.argv[1]), "w") as f:
|
||||
# f.write(rendered)
|
||||
return objects
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user