--- a/eric6/Utilities/ClassBrowsers/idlclbr.py Wed Sep 09 18:07:21 2020 +0200 +++ b/eric6/Utilities/ClassBrowsers/idlclbr.py Fri Sep 11 17:28:59 2020 +0200 @@ -252,8 +252,58 @@ @return dictionary containing the extracted data @rtype dict """ + def calculateEndline(lineno, lines): + """ + Function to calculate the end line. + + @param lineno line number to start at (one based) + @type int + @param lines list of source lines + @type list of str + @return end line (one based) + @rtype int + """ + # convert lineno to be zero based + lineno -= 1 + # 1. search for opening brace '{' + while lineno < len(lines) and not "{" in lines[lineno]: + lineno += 1 + depth = lines[lineno].count("{") - lines[lineno].count("}") + # 2. search for ending line, i.e. matching closing brace '}' + while depth > 0 and lineno < len(lines) - 1: + lineno += 1 + depth += lines[lineno].count("{") - lines[lineno].count("}") + if depth == 0: + # found a matching brace + return lineno + 1 + else: + # nothing found + return -1 + + def calculateMethodEndline(lineno, lines): + """ + Function to calculate the end line. + + @param lineno line number to start at (one based) + @type int + @param lines list of source lines + @type list of str + @return end line (one based) + @rtype int + """ + # convert lineno to be zero based + lineno -= 1 + while lineno < len(lines) and not ";" in lines[lineno]: + lineno += 1 + if ";" in lines[lineno]: + # found an end indicator, i.e. ';' + return lineno + 1 + else: + return -1 + # convert eol markers the Python style src = src.replace("\r\n", "\n").replace("\r", "\n") + srcLines = src.splitlines() dictionary = {} dict_counts = {} @@ -262,8 +312,6 @@ indent = 0 lineno, last_lineno_pos = 1, 0 - lastGlobalEntry = None - cur_obj = None i = 0 while True: m = _getnext(src, i) @@ -283,9 +331,6 @@ last_lineno_pos = start # close all interfaces/modules indented at least as much while classstack and classstack[-1][1] >= thisindent: - if classstack[-1][0] is not None: - # record the end line - classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] if classstack: # it's an interface/module method @@ -312,13 +357,9 @@ else: dict_counts[meth_name] = 0 dictionary[meth_name] = f - if not classstack: - if lastGlobalEntry: - lastGlobalEntry.setEndLine(lineno - 1) - lastGlobalEntry = f - if cur_obj and isinstance(cur_obj, Function): - cur_obj.setEndLine(lineno - 1) - cur_obj = f + if f: + endline = calculateMethodEndline(lineno, srcLines) + f.setEndLine(endline) classstack.append((f, thisindent)) # Marker for nested fns elif m.start("String") >= 0: @@ -333,9 +374,6 @@ indent += 1 # close all interfaces/modules indented at least as much while classstack and classstack[-1][1] >= thisindent: - if classstack[-1][0] is not None: - # record the end line - classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start @@ -348,18 +386,13 @@ # remember this interface cur_class = Interface(module, class_name, inherit, file, lineno) + endline = calculateEndline(lineno, srcLines) + cur_class.setEndLine(endline) if not classstack: dictionary[class_name] = cur_class else: cls = classstack[-1][0] cls._addclass(class_name, cur_class) - if not classstack: - if lastGlobalEntry: - lastGlobalEntry.setEndLine(lineno - 1) - lastGlobalEntry = cur_class - if cur_obj and isinstance(cur_obj, Function): - cur_obj.setEndLine(lineno - 1) - cur_obj = cur_class classstack.append((cur_class, thisindent)) elif m.start("Module") >= 0: @@ -368,23 +401,16 @@ indent += 1 # close all interfaces/modules indented at least as much while classstack and classstack[-1][1] >= thisindent: - if classstack[-1][0] is not None: - # record the end line - classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start module_name = m.group("ModuleName") # remember this module cur_class = Module(module, module_name, file, lineno) + endline = calculateEndline(lineno, srcLines) + cur_class.setEndLine(endline) if not classstack: dictionary[module_name] = cur_class - if lastGlobalEntry: - lastGlobalEntry.setEndLine(lineno - 1) - lastGlobalEntry = cur_class - if cur_obj and isinstance(cur_obj, Function): - cur_obj.setEndLine(lineno - 1) - cur_obj = cur_class classstack.append((cur_class, thisindent)) elif m.start("Attribute") >= 0: @@ -407,9 +433,6 @@ break else: index -= 1 - if lastGlobalEntry: - lastGlobalEntry.setEndLine(lineno - 1) - lastGlobalEntry = None elif m.start("Begin") >= 0: # a begin of a block we are not interested in