eric6/Utilities/ClassBrowsers/idlclbr.py

changeset 7699
d338c533f5f0
parent 7690
a59680062837
child 7706
0c6d32ec64f1
--- 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

eric ide

mercurial