eric6/Utilities/ClassBrowsers/protoclbr.py

changeset 7699
d338c533f5f0
parent 7695
032a0586a349
child 7706
0c6d32ec64f1
--- 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:

eric ide

mercurial