pyclbr: improved determination of the last line of a class, method or function.

Wed, 09 Sep 2020 18:07:21 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 09 Sep 2020 18:07:21 +0200
changeset 7698
12cb12380a6a
parent 7697
c981a807aab1
child 7699
d338c533f5f0

pyclbr: improved determination of the last line of a class, method or function.

eric6/APIs/Python3/eric6.api file | annotate | diff | comparison | revisions
eric6/Documentation/Help/source.qch file | annotate | diff | comparison | revisions
eric6/Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
eric6/Documentation/Source/eric6.Utilities.ClassBrowsers.pyclbr.html file | annotate | diff | comparison | revisions
eric6/Utilities/ClassBrowsers/pyclbr.py file | annotate | diff | comparison | revisions
--- a/eric6/APIs/Python3/eric6.api	Wed Sep 09 18:05:58 2020 +0200
+++ b/eric6/APIs/Python3/eric6.api	Wed Sep 09 18:07:21 2020 +0200
@@ -9225,6 +9225,7 @@
 eric6.Utilities.ClassBrowsers.pyclbr._getnext?8
 eric6.Utilities.ClassBrowsers.pyclbr._indent?5(ws)
 eric6.Utilities.ClassBrowsers.pyclbr._modules?8
+eric6.Utilities.ClassBrowsers.pyclbr.calculateEndline?4(lineno, lines, indent)
 eric6.Utilities.ClassBrowsers.pyclbr.readmodule_ex?4(module, path=None, inpackage=False, isPyFile=False)
 eric6.Utilities.ClassBrowsers.pyclbr.scan?4(src, file, module)
 eric6.Utilities.ClassBrowsers.rbclbr.Attribute?1(module, name, file, lineno)
Binary file eric6/Documentation/Help/source.qch has changed
--- a/eric6/Documentation/Help/source.qhp	Wed Sep 09 18:05:58 2020 +0200
+++ b/eric6/Documentation/Help/source.qhp	Wed Sep 09 18:07:21 2020 +0200
@@ -16978,6 +16978,7 @@
       <keyword name="blank_lines" id="blank_lines" ref="eric6.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#blank_lines" />
       <keyword name="break_after_binary_operator" id="break_after_binary_operator" ref="eric6.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#break_after_binary_operator" />
       <keyword name="break_before_binary_operator" id="break_before_binary_operator" ref="eric6.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#break_before_binary_operator" />
+      <keyword name="calculateEndline" id="calculateEndline" ref="eric6.Utilities.ClassBrowsers.pyclbr.html#calculateEndline" />
       <keyword name="certificateValidation (Module)" id="certificateValidation (Module)" ref="eric6.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.certificateValidation.html" />
       <keyword name="changeRememberedMaster" id="changeRememberedMaster" ref="eric6.Utilities.crypto.__init__.html#changeRememberedMaster" />
       <keyword name="checkAssertUsed" id="checkAssertUsed" ref="eric6.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.assert.html#checkAssertUsed" />
--- a/eric6/Documentation/Source/eric6.Utilities.ClassBrowsers.pyclbr.html	Wed Sep 09 18:05:58 2020 +0200
+++ b/eric6/Documentation/Source/eric6.Utilities.ClassBrowsers.pyclbr.html	Wed Sep 09 18:07:21 2020 +0200
@@ -76,6 +76,10 @@
 <td>Module function to return the indentation depth.</td>
 </tr>
 <tr>
+<td><a href="#calculateEndline">calculateEndline</a></td>
+<td>Function to calculate the end line of a class or method/function.</td>
+</tr>
+<tr>
 <td><a href="#readmodule_ex">readmodule_ex</a></td>
 <td>Read a module file and return a dictionary of classes.</td>
 </tr>
@@ -622,6 +626,43 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
+<a NAME="calculateEndline" ID="calculateEndline"></a>
+<h2>calculateEndline</h2>
+<b>calculateEndline</b>(<i>lineno, lines, indent</i>)
+
+<p>
+        Function to calculate the end line of a class or method/function.
+</p>
+<dl>
+
+<dt><i>lineno</i> (int)</dt>
+<dd>
+line number to start at
+</dd>
+<dt><i>lines</i> (list of str)</dt>
+<dd>
+list of source lines
+</dd>
+<dt><i>indent</i> (int)</dt>
+<dd>
+indent length the class/method/function definition
+</dd>
+</dl>
+<dl>
+<dt>Returns:</dt>
+<dd>
+end line of the class/method/function
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+int
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
 <a NAME="readmodule_ex" ID="readmodule_ex"></a>
 <h2>readmodule_ex</h2>
 <b>readmodule_ex</b>(<i>module, path=None, inpackage=False, isPyFile=False</i>)
--- a/eric6/Utilities/ClassBrowsers/pyclbr.py	Wed Sep 09 18:05:58 2020 +0200
+++ b/eric6/Utilities/ClassBrowsers/pyclbr.py	Wed Sep 09 18:07:21 2020 +0200
@@ -400,8 +400,35 @@
     @return dictionary containing the extracted data
     @rtype dict
     """
+    def calculateEndline(lineno, lines, indent):
+        """
+        Function to calculate the end line of a class or method/function.
+        
+        @param lineno line number to start at
+        @type int
+        @param lines list of source lines
+        @type list of str
+        @param indent indent length the class/method/function definition
+        @type int
+        @return end line of the class/method/function
+        @rtype int
+        """
+        # start with zero based line after start line
+        while lineno < len(lines):
+            line = lines[lineno]
+            if line.strip():
+                # line contains some text
+                lineIndent = _indent(line.replace(line.lstrip(), ""))
+                if lineIndent <= indent:
+                    return lineno
+            lineno += 1
+        
+        # nothing found
+        return -1
+    
     # convert eol markers the Python style
     src = src.replace("\r\n", "\n").replace("\r", "\n")
+    srcLines = src.splitlines()
     
     dictionary = {}
     dict_counts = {}
@@ -413,7 +440,6 @@
     deltaindentcalculated = 0
     
     lineno, last_lineno_pos = 1, 0
-    lastGlobalEntry = None
     cur_obj = None
     i = 0
     modifierType = ClbrBaseClasses.Function.General
@@ -493,10 +519,8 @@
                 else:
                     dict_counts[meth_name] = 0
                 dictionary[meth_name] = f
-            if not classstack:
-                if lastGlobalEntry:
-                    lastGlobalEntry.setEndLine(lineno - 1)
-                lastGlobalEntry = f
+            endlineno = calculateEndline(lineno, srcLines, thisindent)
+            f.setEndLine(endlineno)
             if cur_obj and isinstance(cur_obj, Function):
                 cur_obj.setEndLine(lineno - 1)
             cur_obj = f
@@ -551,6 +575,8 @@
             # remember this class
             cur_class = Class(module, class_name, inherit,
                               file, lineno)
+            endlineno = calculateEndline(lineno, srcLines, thisindent)
+            cur_class.setEndLine(endlineno)
             if not classstack:
                 if class_name in dict_counts:
                     dict_counts[class_name] += 1
@@ -561,10 +587,6 @@
                 dictionary[class_name] = cur_class
             else:
                 classstack[-1][0]._addclass(class_name, cur_class)
-            if not classstack:
-                if lastGlobalEntry:
-                    lastGlobalEntry.setEndLine(lineno - 1)
-                lastGlobalEntry = cur_class
             classstack.append((cur_class, thisindent))
 
         elif m.start("Attribute") >= 0:
@@ -603,9 +625,6 @@
                         module, "Globals", file, lineno)
                 dictionary["@@Globals@@"]._addglobal(
                     Attribute(module, variable_name, file, lineno))
-                if lastGlobalEntry:
-                    lastGlobalEntry.setEndLine(lineno - 1)
-                lastGlobalEntry = None
             else:
                 index = -1
                 while index >= -len(classstack):

eric ide

mercurial