--- a/eric6/Utilities/ClassBrowsers/protoclbr.py Wed Sep 09 18:07:21 2020 +0200 +++ b/eric6/Utilities/ClassBrowsers/protoclbr.py Fri Sep 11 17:28:59 2020 +0200 @@ -243,8 +243,37 @@ @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 + # convert eol markers the Python style src = src.replace("\r\n", "\n").replace("\r", "\n") + srcLines = src.splitlines() dictionary = {} @@ -252,8 +281,6 @@ indent = 0 lineno, last_lineno_pos = 1, 0 - lastGlobalEntry = None - cur_obj = None i = 0 while True: m = _getnext(src, i) @@ -277,9 +304,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 @@ -295,13 +319,9 @@ else: # the file is incorrect, ignore the entry continue - if not classstack: - if lastGlobalEntry: - lastGlobalEntry.setEndLine(lineno - 1) - lastGlobalEntry = f - if cur_obj and isinstance(cur_obj, ServiceMethod): - cur_obj.setEndLine(lineno - 1) - cur_obj = f + if f: + endline = calculateEndline(lineno, srcLines) + f.setEndLine(endline) classstack.append((f, thisindent)) # Marker for nested fns elif m.start("String") >= 0: @@ -319,22 +339,16 @@ message_name = m.group("MessageName") # close all messages/services 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] # remember this message cur_class = Message(module, message_name, file, lineno) + endline = calculateEndline(lineno, srcLines) + cur_class.setEndLine(endline) if not classstack: dictionary[message_name] = cur_class else: msg = classstack[-1][0] msg._addclass(message_name, cur_class) - if not classstack: - if lastGlobalEntry: - lastGlobalEntry.setEndLine(lineno - 1) - lastGlobalEntry = cur_class - cur_obj = cur_class classstack.append((cur_class, thisindent)) elif m.start("Enum") >= 0: @@ -343,25 +357,19 @@ indent += 1 # close all messages/services 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 enum_name = m.group("EnumName") # remember this Enum cur_class = Enum(module, enum_name, file, lineno) + endline = calculateEndline(lineno, srcLines) + cur_class.setEndLine(endline) if not classstack: dictionary[enum_name] = cur_class else: enum = classstack[-1][0] enum._addclass(enum_name, cur_class) - if not classstack: - if lastGlobalEntry: - lastGlobalEntry.setEndLine(lineno - 1) - lastGlobalEntry = cur_class - cur_obj = cur_class classstack.append((cur_class, thisindent)) elif m.start("Service") >= 0: @@ -370,25 +378,19 @@ indent += 1 # close all messages/services 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 service_name = m.group("ServiceName") # remember this Service cur_class = Service(module, service_name, file, lineno) + endline = calculateEndline(lineno, srcLines) + cur_class.setEndLine(endline) if not classstack: dictionary[service_name] = cur_class else: service = classstack[-1][0] service._addclass(service_name, cur_class) - if not classstack: - if lastGlobalEntry: - lastGlobalEntry.setEndLine(lineno - 1) - lastGlobalEntry = cur_class - cur_obj = cur_class classstack.append((cur_class, thisindent)) elif m.start("Begin") >= 0: