eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py

changeset 7042
2be5b245e1b8
parent 7040
f89952e5fc11
child 7045
c2bf08f87a1d
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py	Thu Jun 27 19:05:28 2019 +0200
+++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py	Thu Jun 27 19:21:23 2019 +0200
@@ -13,6 +13,7 @@
 import itertools
 from string import Formatter
 from collections import defaultdict
+import tokenize
 
 
 def composeCallPath(node):
@@ -37,36 +38,62 @@
     Class implementing a checker for miscellaneous checks.
     """
     Codes = [
+        ## Coding line
         "M101", "M102",
+        
+        ## Copyright
         "M111", "M112",
+        
+        ## Shadowed Builtins
         "M131", "M132",
         
+        ## Comprehensions
         "M191", "M192", "M193", "M194",
         "M195", "M196", "M197", "M198",
         
+        ## Dictionaries with sorted keys
         "M201",
         
+        ## Bugbear
         "M501", "M502", "M503", "M504", "M505", "M506", "M507", "M508",
         "M509",
         "M511", "M512", "M513",
         "M521", "M522", "M523", "M524",
         
+        ## Format Strings
         "M601",
         "M611", "M612", "M613",
         "M621", "M622", "M623", "M624", "M625",
         "M631", "M632",
+        
+        ## Logging
         "M651", "M652", "M653", "M654", "M655",
         
+        ## Future statements
         "M701", "M702",
+        
+        ## Gettext
         "M711",
         
+        ## print
         "M801",
+        
+        ## one element tuple
         "M811",
+        
+        ## Mutable Defaults
         "M821", "M822",
+        
+        ## return statements
         "M831", "M832", "M833", "M834",
         
+        ## line continuation
+        "M841",
+        
+        ## commented code
         "M891",
         
+        ## syntax error
         "M901",
     ]
     
@@ -144,10 +171,11 @@
             (self.__checkFuture, ("M701", "M702")),
             (self.__checkGettext, ("M711",)),
             (self.__checkPrintStatements, ("M801",)),
-            (self.__checkTuple, ("M811", )),
+            (self.__checkTuple, ("M811",)),
             (self.__checkMutableDefault, ("M821", "M822")),
             (self.__checkReturn, ("M831", "M832", "M833", "M834")),
-            (self.__checkCommentedCode, ("M891")),
+            (self.__checkLineContinuation, ("M841",)),
+            (self.__checkCommentedCode, ("M891",)),
         ]
         
         self.__defaultArgs = {
@@ -341,6 +369,30 @@
                 source, aggressive=aggressive):
             self.__error(markedLine - 1, 0, "M891")
     
+    def __checkLineContinuation(self):
+        """
+        Private method to check öine continuation using '\'.
+        """
+        # generate source lines without comments
+        linesIterator = iter(self.__source)
+        tokens = tokenize.generate_tokens(lambda: next(linesIterator))
+        comments = [token for token in tokens if token[0] == tokenize.COMMENT]
+        stripped = self.__source[:]
+        for comment in comments:
+            lineno = comment[3][0]
+            start = comment[2][1]
+            stop = comment[3][1]
+            content = stripped[lineno - 1]
+            withoutComment = content[:start] + content[stop:]
+            stripped[lineno - 1] = withoutComment.rstrip()
+        
+        # perform check with 'cleaned' source
+        for lineIndex, line in enumerate(stripped):
+            strippedLine = line.strip()
+            if (strippedLine.endswith('\\') and
+                    not strippedLine.startswith(('assert', 'with'))):
+                self.__error(lineIndex, len(line), "M841")
+    
     def __checkPrintStatements(self):
         """
         Private method to check for print statements.

eric ide

mercurial