[DEV] better integration of template

This commit is contained in:
Edouard DUPIN 2016-03-24 21:58:34 +01:00
parent b040a7b84d
commit 8ace149e4f
2 changed files with 226 additions and 152 deletions

View File

@ -178,6 +178,7 @@ lex.lex()
## @return The new table. ex: ['class', 'Bar::Foo']
##
def create_compleate_class_name(table):
debug.warning("table = " + str(table))
if "::" not in "".join(table):
out = table
else:
@ -211,27 +212,28 @@ def create_compleate_class_name(table):
out[-1] += name
else:
out.append(name)
debug.warning(" ==> out = " + str(out))
return out
class parse_file():
def gen_debug_space(self):
ret = "[" + str(len(self.braceDepthType)+1) + "]"
for iii in range(0,len(self.braceDepthType)):
ret = "[" + str(len(self.brace_depth_type)+1) + "]"
for iii in range(0,len(self.brace_depth_type)):
ret += " "
return ret
def fusion(self, baseNode):
baseNode.fusion(self.mainNode)
baseNode.fusion(self.main_node)
return baseNode
def __init__(self, fileName):
self.mainNode = Node.MainNode("main-node", "tmp")
self.m_elementParseStack = []
self.main_node = Node.MainNode("main-node", "tmp")
self.element_parse_stack = []
debug.debug("Parse file : '" + fileName + "'")
self.headerFileName = fileName
self.header_file_name = fileName
self.anon_union_counter = [-1, 0]
# load all the file data :
@ -262,174 +264,177 @@ class parse_file():
###### debug.info(headerFileStr)
self.stack = [] # token stack to find the namespace and the element name ...
self.previous = None
self.nameStack = [] #
self.braceDepth = 0
self.braceDepthType = []
self.lastComment = []
self.subModuleCountBrace = 0;
self.name_stack = [] #
self.brace_depth = 0
self.brace_depth_type = []
self.last_comment = []
self.sub_module_count_brace = 0;
lex.lex()
lex.input(headerFileStr)
self.curLine = 0
self.curChar = 0
self.cur_line = 0
self.cur_char = 0
while True:
tok = lex.token()
if not tok:
break
debug.verbose("TOK: " + str(tok))
self.stack.append( tok.value )
self.curLine = tok.lineno
self.curChar = tok.lexpos
self.cur_line = tok.lineno
self.cur_char = tok.lexpos
# special case to remove internal function define in header:
if self.previous_is('function') == True:
if tok.type == 'OPEN_BRACE':
self.subModuleCountBrace += 1
self.sub_module_count_brace += 1
debug.verbose("openBrace " + str(self.sub_module_count_brace))
elif tok.type == 'CLOSE_BRACE':
self.subModuleCountBrace -= 1
if self.subModuleCountBrace <= 0:
self.sub_module_count_brace -= 1
debug.verbose("closeBrace " + str(self.sub_module_count_brace) + " line:" + str(self.cur_line))
if self.sub_module_count_brace <= 0:
self.brace_type_pop()
self.lastComment = []
self.last_comment = []
continue
# normal case:
if tok.type == 'PRECOMP':
debug.debug("PRECOMP: " + str(tok))
self.stack = []
self.nameStack = []
self.lastComment = []
self.name_stack = []
self.last_comment = []
# Do nothing for macro ==> many time not needed ...
continue
if tok.type == 'COMMENT_SINGLELINE_DOC_PREVIOUS':
if self.previous_is('enum') == True:
if self.nameStack[-1] == ",":
self.nameStack[-1] = "//!< " + tok.value
self.nameStack.append(",")
if self.name_stack[-1] == ",":
self.name_stack[-1] = "//!< " + tok.value
self.name_stack.append(",")
else:
self.nameStack.append("//!< " + tok.value)
self.name_stack.append("//!< " + tok.value)
elif self.previous != None \
and self.previous.get_node_type() == 'variable':
self.previous.add_doc([tok.value])
else:
#self.lastComment.append(tok.value)
#self.last_comment.append(tok.value)
pass
if tok.type == 'COMMENT_MULTILINE_DOC':
self.lastComment.append(tok.value)
self.last_comment.append(tok.value)
if tok.type == 'COMMENT_SINGLELINE_DOC':
self.lastComment.append(tok.value)
self.last_comment.append(tok.value)
if tok.type == 'OPEN_BRACE':
# When we open a brace, this is the time to parse the stack ...
# Clean the stack : (remove \t\r\n , and concatenate the 'xx', ':', ':', 'yy' in 'xx::yy',
self.nameStack = create_compleate_class_name(self.nameStack)
if len(self.nameStack) <= 0:
self.name_stack = create_compleate_class_name(self.name_stack)
if len(self.name_stack) <= 0:
#open brace with no name ...
self.brace_type_push('empty', [])
elif is_a_function(self.nameStack):
elif is_a_function(self.name_stack):
# need to parse sub function internal description...
self.subModuleCountBrace = 1
self.brace_type_push('function', self.nameStack)
elif 'namespace' in self.nameStack:
self.brace_type_push('namespace', self.nameStack)
elif 'class' in self.nameStack:
self.brace_type_push('class', self.nameStack)
elif 'enum' in self.nameStack:
self.brace_type_push('enum', self.nameStack)
elif 'struct' in self.nameStack:
self.brace_type_push('struct', self.nameStack)
elif 'typedef' in self.nameStack:
self.brace_type_push('typedef', self.nameStack)
elif 'union' in self.nameStack:
self.brace_type_push('union', self.nameStack)
self.sub_module_count_brace = 1
self.brace_type_push('function', self.name_stack)
debug.verbose("openBrace *** " + str(self.name_stack))
elif 'namespace' in self.name_stack:
self.brace_type_push('namespace', self.name_stack)
elif 'class' in self.name_stack:
self.brace_type_push('class', self.name_stack)
elif 'enum' in self.name_stack:
self.brace_type_push('enum', self.name_stack)
elif 'struct' in self.name_stack:
self.brace_type_push('struct', self.name_stack)
elif 'typedef' in self.name_stack:
self.brace_type_push('typedef', self.name_stack)
elif 'union' in self.name_stack:
self.brace_type_push('union', self.name_stack)
else:
self.brace_type_push('unknow', self.nameStack)
self.brace_type_push('unknow', self.name_stack)
self.stack = []
self.nameStack = []
self.lastComment = []
self.name_stack = []
self.last_comment = []
elif tok.type == 'CLOSE_BRACE':
if len(self.nameStack) != 0:
if len(self.name_stack) != 0:
if self.previous_is('enum') == True:
self.brace_type_append('enum list', self.nameStack);
self.brace_type_append('enum list', self.name_stack);
else:
debug.warning(self.gen_debug_space() + "end brace DROP : " + str(self.nameStack));
debug.warning(self.gen_debug_space() + "end brace DROP : " + str(self.name_stack));
self.stack = []
self.nameStack = []
self.lastComment = []
self.name_stack = []
self.last_comment = []
self.brace_type_pop()
self.nameStack = create_compleate_class_name(self.nameStack)
self.name_stack = create_compleate_class_name(self.name_stack)
if tok.type == 'OPEN_PAREN':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'CLOSE_PAREN':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'OPEN_SQUARE_BRACKET':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'CLOSE_SQUARE_BRACKET':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'EQUALS':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'COMMA':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'BACKSLASH':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'PIPE':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'PERCENT':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'CARET':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'EXCLAMATION':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'SQUOTE':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'NUMBER':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'MINUS':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'PLUS':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'STRING_LITERAL':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'NAME' \
or tok.type == 'AMPERSTAND' \
or tok.type == 'ASTERISK' \
or tok.type == 'CHAR_LITERAL':
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'COLON':
if self.nameStack[0] in Node.accessList:
debug.debug(self.gen_debug_space() + "change visibility : " + self.nameStack[0]);
self.brace_type_change_access(self.nameStack[0])
self.nameStack = []
if self.name_stack[0] in Node.accessList:
debug.debug(self.gen_debug_space() + "change visibility : " + self.name_stack[0]);
self.brace_type_change_access(self.name_stack[0])
self.name_stack = []
self.stack = []
else :
self.nameStack.append(tok.value)
self.name_stack.append(tok.value)
elif tok.type == 'SEMI_COLON':
if len(self.nameStack) != 0:
self.nameStack = create_compleate_class_name(self.nameStack)
if is_a_function(self.nameStack):
self.brace_type_append('function', self.nameStack);
elif 'namespace' in self.nameStack:
debug.debug(self.gen_debug_space() + "find a namespace DECLARATION : " + str(self.nameStack));
elif 'class' in self.nameStack:
debug.debug(self.gen_debug_space() + "find a class DECLARATION : " + str(self.nameStack));
elif 'enum' in self.nameStack:
debug.debug(self.gen_debug_space() + "find a enum DECLARATION : " + str(self.nameStack));
elif 'struct' in self.nameStack:
debug.debug(self.gen_debug_space() + "find a struct DECLARATION : " + str(self.nameStack));
elif 'typedef' in self.nameStack:
debug.info(self.gen_debug_space() + "find a typedef DECLARATION : " + str(self.nameStack));
elif 'union' in self.nameStack:
debug.debug(self.gen_debug_space() + "find a union DECLARATION : " + str(self.nameStack));
if len(self.name_stack) != 0:
self.name_stack = create_compleate_class_name(self.name_stack)
if is_a_function(self.name_stack):
self.brace_type_append('function', self.name_stack);
elif 'namespace' in self.name_stack:
debug.debug(self.gen_debug_space() + "find a namespace DECLARATION : " + str(self.name_stack));
elif 'class' in self.name_stack:
debug.debug(self.gen_debug_space() + "find a class DECLARATION : " + str(self.name_stack));
elif 'enum' in self.name_stack:
debug.debug(self.gen_debug_space() + "find a enum DECLARATION : " + str(self.name_stack));
elif 'struct' in self.name_stack:
debug.debug(self.gen_debug_space() + "find a struct DECLARATION : " + str(self.name_stack));
elif 'typedef' in self.name_stack:
debug.info(self.gen_debug_space() + "find a typedef DECLARATION : " + str(self.name_stack));
elif 'union' in self.name_stack:
debug.debug(self.gen_debug_space() + "find a union DECLARATION : " + str(self.name_stack));
else:
if self.previous_is('enum') == True:
self.brace_type_append('enum list', self.nameStack);
self.brace_type_append('enum list', self.name_stack);
else:
# TODO : Check if it is true in all case :
self.brace_type_append('variable', self.nameStack);
#debug.warning(self.gen_debug_space() + "variable : " + str(self.nameStack));
self.brace_type_append('variable', self.name_stack);
#debug.warning(self.gen_debug_space() + "variable : " + str(self.name_stack));
self.stack = []
self.nameStack = []
self.lastComment = []
self.name_stack = []
self.last_comment = []
#self.debug_display();
def debug_display(self):
debug.info("Debug display :")
self.mainNode.debug_display(1)
self.main_node.debug_display(1)
def create_element(self, type, stack):
ret = None
@ -438,27 +443,27 @@ class parse_file():
or type == 'enum list':
pass
elif type == 'namespace':
ret = Namespace.Namespace(stack, self.headerFileName, self.curLine, self.lastComment)
ret = Namespace.Namespace(stack, self.header_file_name, self.cur_line, self.last_comment)
elif type == 'class':
ret = Class.Class(stack, self.headerFileName, self.curLine, self.lastComment)
ret = Class.Class(stack, self.header_file_name, self.cur_line, self.last_comment)
elif type == 'struct':
ret = Struct.Struct(stack, self.headerFileName, self.curLine, self.lastComment)
ret = Struct.Struct(stack, self.header_file_name, self.cur_line, self.last_comment)
elif type == 'typedef':
#ret = Namespace.Namespace(stack, self.headerFileName, self.curLine)
#ret = Namespace.Namespace(stack, self.header_file_name, self.cur_line)
# TODO ...
pass
elif type == 'union':
ret = Union.Union(stack, self.headerFileName, self.curLine, self.lastComment)
ret = Union.Union(stack, self.header_file_name, self.cur_line, self.last_comment)
elif type == 'function':
#debug.info(str(self.lastComment))
#debug.info(str(self.last_comment))
if self.get_last_type() == 'class':
ret = Methode.Methode(stack, self.headerFileName, self.curLine, self.lastComment, self.braceDepthType[len(self.braceDepthType)-1]['node'].get_name())
ret = Methode.Methode(stack, self.header_file_name, self.cur_line, self.last_comment, self.brace_depth_type[len(self.brace_depth_type)-1]['node'].get_name())
else:
ret = Methode.Methode(stack, self.headerFileName, self.curLine, self.lastComment)
ret = Methode.Methode(stack, self.header_file_name, self.cur_line, self.last_comment)
elif type == 'enum':
ret = Enum.Enum(stack, self.headerFileName, self.curLine, self.lastComment)
ret = Enum.Enum(stack, self.header_file_name, self.cur_line, self.last_comment)
elif type == 'variable':
ret = Variable.Variable(stack, self.headerFileName, self.curLine, self.lastComment)
ret = Variable.Variable(stack, self.header_file_name, self.cur_line, self.last_comment)
self.previous = ret
else:
debug.error("unknow type ...")
@ -471,22 +476,22 @@ class parse_file():
'stack' : stack,
'node' : myClassElement
}
self.braceDepthType.append(element)
self.brace_depth_type.append(element)
#debug.info ("append : " + str(element))
def brace_type_append_current(self, element, id = -50):
if id == -50:
id = len(self.braceDepthType)-1
id = len(self.brace_depth_type)-1
if id >= 0:
while self.braceDepthType[id]['node'] == None:
while self.brace_depth_type[id]['node'] == None:
# special case for empty brace, just add it to the upper
id -=1
if id < 0:
break;
if id < 0:
self.mainNode.append(element)
self.main_node.append(element)
else:
self.braceDepthType[id]['node'].append(element)
self.brace_depth_type[id]['node'].append(element)
def brace_type_append(self, type, stack):
debug.debug(self.gen_debug_space() + " append a <<" + type + ">> : " + str(stack));
@ -498,31 +503,31 @@ class parse_file():
# enum sub list:
if lastType == 'enum' \
and type == 'enum list':
id = len(self.braceDepthType)-1
self.braceDepthType[id]['node'].enum_append(stack)
id = len(self.brace_depth_type)-1
self.brace_depth_type[id]['node'].enum_append(stack)
return
debug.info("TODO : Parse the special type")
def brace_type_pop(self):
id = len(self.braceDepthType)-1
id = len(self.brace_depth_type)-1
if id < 0:
debug.warning("Try to pop the stack with No more element ...")
return
if self.braceDepthType[id]['node'] == None:
if self.brace_depth_type[id]['node'] == None:
# nothing to add at the upper ...
pass
else:
# add it on the previous
self.brace_type_append_current(self.braceDepthType[id]['node'], id-1)
self.braceDepthType.pop()
self.brace_type_append_current(self.brace_depth_type[id]['node'], id-1)
self.brace_depth_type.pop()
def brace_type_change_access(self, newOne):
if newOne not in Node.accessList:
debug.error("unknow access type : " + newOne)
return
id = len(self.braceDepthType)-1
id = len(self.brace_depth_type)-1
if id >= 0:
while self.braceDepthType[id]['node'] == None:
while self.brace_depth_type[id]['node'] == None:
# special case for empty brace, just add it to the upper
id -=1
if id < 0:
@ -530,10 +535,10 @@ class parse_file():
if id < 0:
debug.warning("can not change the main access on the library")
else:
if self.braceDepthType[id]['node'].get_access() == None:
debug.error("Can not set access in other as : 'class' or 'struct' :" + str(self.braceDepthType[id]))
if self.brace_depth_type[id]['node'].get_access() == None:
debug.error("Can not set access in other as : 'class' or 'struct' :" + str(self.brace_depth_type[id]))
return
self.braceDepthType[id]['node'].set_access(newOne)
self.brace_depth_type[id]['node'].set_access(newOne)
def previous_is(self, type):
if self.get_last_type() == type:
@ -541,8 +546,8 @@ class parse_file():
return False
def get_last_type(self):
if len(self.braceDepthType) > 0:
return self.braceDepthType[len(self.braceDepthType)-1]['type']
if len(self.brace_depth_type) > 0:
return self.brace_depth_type[len(self.brace_depth_type)-1]['type']
return None
def is_a_function(stack) :

View File

@ -22,6 +22,7 @@ global_class_link = {
"std::list" : "http://www.cplusplus.com/reference/list/list/",
"std::pair" : "http://www.cplusplus.com/reference/utility/pair/",
"std::tuple" : "http://www.cplusplus.com/reference/tuple/tuple/",
"std::ostream" : "http://www.cplusplus.com/reference/ostream/ostream/",
"std::shared_ptr": "http://www.cplusplus.com/reference/memory/shared_ptr/",
"std::weak_ptr" : "http://www.cplusplus.com/reference/memory/weak_ptr/",
"std::enable_shared_from_this" : "http://www.cplusplus.com/reference/memory/enable_shared_from_this/"
@ -30,14 +31,16 @@ global_class_link = {
class Type():
def __init__(self, stack=[]):
self.nameBefore = ""
self.name_before = ""
self.name = ""
self.nameAfter = ""
self.name_after = ""
self.const = False # the const xxxxx
self.reference = False
self.constVar = False # the char* const VarName
self.const_var = False # the char* const VarName
self.enum = False
self.struct = False
self.mutable = False
self.template_parameter = None
if len(stack) == 0:
# None type
@ -47,7 +50,7 @@ class Type():
return;
# check end const
if stack[len(stack)-1] == 'const':
self.constVar = True
self.const_var = True
stack = stack[:len(stack)-1]
# check if element is a reference ...
if stack[len(stack)-1] == '&':
@ -64,39 +67,86 @@ class Type():
if stack[0] == 'struct':
self.struct = True
stack = stack[1:]
if stack[0] == 'mutable':
self.mutable = True
stack = stack[1:]
self.nameBefore = ""
debug.info("get type : " + str(stack))
self.name_before = ""
self.name = ""
self.nameAfter = ""
self.name_after = ""
template_level = 0
template_new_elem = False
for element in stack:
if self.nameAfter != "":
self.nameAfter += element
if template_level == 0:
if self.name_after != "":
self.name_after += element
continue
if element[0] in ['*', '&']:
if self.name == "":
self.name_before += element
continue
else:
self.name_after += element
continue
else:
if element[0] in [',']:
#Template separator ...
template_new_elem = True
continue
if element[0] in ['<']:
debug.info(" Start template")
if self.template_parameter == None:
self.template_parameter = []
if element[1:] != "":
self.template_parameter.append(element[1:])
template_level += 1
continue
if element[0] in ['*', '&', '<']:
if self.name == "":
self.nameBefore += element
continue
else:
self.nameAfter += element
continue
self.name += element
#debug.info("get type : " + str(stack) + " ==> " +self.name)
if element[0] in ['>']:
template_level -= 1
debug.info(" Stop template")
continue
if template_level != 0:
if element != "":
if template_new_elem == True:
self.template_parameter.append(element)
else:
self.template_parameter[-1] += " " + element
else:
self.name += element
if self.template_parameter == None:
debug.info(" ==> '" + self.name + "'")
else:
debug.info(" ==> '" + self.name + "' : " + str(self.template_parameter))
debug.info(" self.name_before='" + str(self.name_before) + "'")
debug.info(" self.name_after='" + self.name_after + "'")
def to_str(self) :
ret = ""
if self.const == True:
ret += "const "
if self.mutable == True:
ret += "mutable "
if self.enum == True:
ret += "enum "
if self.struct == True:
ret += "struct "
ret += self.nameBefore
ret += self.name_before
ret += self.name
ret += self.nameAfter
if self.template_parameter != None:
ret += "<"
first_elem = True
for elem in self.template_parameter:
if first_elem == True:
first_elem = False
else:
ret += ", "
ret += elem
ret += ">"
ret += self.name_after
if self.reference == True:
ret += " &"
if self.constVar == True:
if self.const_var == True:
ret += " const"
return ret
@ -108,16 +158,19 @@ class Type():
if self.const == True:
ret += "const "
retDecorated += module.display_color("const") + " "
if self.mutable == True:
ret += "mutable "
retDecorated += module.display_color("mutable") + " "
if self.enum == True:
ret += "enum "
retDecorated += module.display_color("enum") + " "
if self.struct == True:
ret += "struct "
retDecorated += module.display_color("struct") + " "
ret += self.nameBefore
ret += self.name_before
ret += self.name
ret += self.nameAfter
retDecorated += self.nameBefore
ret += self.name_after
retDecorated += self.name_before
element = module.get_element_with_name(self.name)
if element == None:
@ -134,11 +187,27 @@ class Type():
retDecorated += '<a class="code-type" href="' + link + '">'
retDecorated += self.name
retDecorated += '</a>'
retDecorated += re.sub(">","&gt;", re.sub("<","&lt;", self.nameAfter))
if self.template_parameter != None:
retDecorated += "&lt;"
ret += "<"
first_elem = True
for elem in self.template_parameter:
if first_elem == True:
first_elem = False
else:
ret += ", "
retDecorated += ", "
ret += elem
retDecorated += elem
ret += ">"
retDecorated += "&gt;"
retDecorated += self.name_after
if self.reference == True:
ret += " &"
retDecorated += " &"
if self.constVar == True:
if self.const_var == True:
ret += " const"
retDecorated += " " + module.display_color("const")
return [ret, retDecorated]