src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleFixer.py

branch
eric7
changeset 11147
dee6e106b4d3
parent 11090
f5f5f5803935
child 11148
15e30f0c76a8
equal deleted inserted replaced
11146:59e04f7003e9 11147:dee6e106b4d3
20 # under Python3. So ignore it. 20 # under Python3. So ignore it.
21 with contextlib.suppress(ImportError): 21 with contextlib.suppress(ImportError):
22 import pycodestyle 22 import pycodestyle
23 23
24 FixableCodeStyleIssues = [ # noqa: U200 24 FixableCodeStyleIssues = [ # noqa: U200
25 "D111", 25 "D-111",
26 "D112", 26 "D-112",
27 "D121", 27 "D-121",
28 "D131", 28 "D-131",
29 "D141", 29 "D-141",
30 "D142", 30 "D-142",
31 "D143", 31 "D-143",
32 "D144", 32 "D-144",
33 "D145", 33 "D-145",
34 "D221", 34 "D-221",
35 "D222", 35 "D-222",
36 "D231", 36 "D-231",
37 "D242", 37 "D-242",
38 "D243", 38 "D-243",
39 "D244", 39 "D-244",
40 "D245", 40 "D-245",
41 "D246", 41 "D-246",
42 "D247", 42 "D-247",
43 "E101", 43 "E-101",
44 "E111", 44 "E-111",
45 "E121", 45 "E-121",
46 "E122", 46 "E-122",
47 "E123", 47 "E-123",
48 "E124", 48 "E-124",
49 "E125", 49 "E-125",
50 "E126", 50 "E-126",
51 "E127", 51 "E-127",
52 "E128", 52 "E-128",
53 "E133", 53 "E-133",
54 "E201", 54 "E-201",
55 "E202", 55 "E-202",
56 "E203", 56 "E-203",
57 "E211", 57 "E-211",
58 "E221", 58 "E-221",
59 "E222", 59 "E-222",
60 "E223", 60 "E-223",
61 "E224", 61 "E-224",
62 "E225", 62 "E-225",
63 "E226", 63 "E-226",
64 "E227", 64 "E-227",
65 "E228", 65 "E-228",
66 "E231", 66 "E-231",
67 "E241", 67 "E-241",
68 "E242", 68 "E-242",
69 "E251", 69 "E-251",
70 "E261", 70 "E-261",
71 "E262", 71 "E-262",
72 "E271", 72 "E-271",
73 "E272", 73 "E-272",
74 "E273", 74 "E-273",
75 "E274", 75 "E-274",
76 "E301", 76 "E-301",
77 "E302", 77 "E-302",
78 "E303", 78 "E-303",
79 "E304", 79 "E-304",
80 "E305", 80 "E-305",
81 "E306", 81 "E-306",
82 "E307", 82 "E-307",
83 "E308", 83 "E-308",
84 "E401", 84 "E-401",
85 "E501", 85 "E-501",
86 "E502", 86 "E-502",
87 "E701", 87 "E-701",
88 "E702", 88 "E-702",
89 "E703", 89 "E-703",
90 "E711", 90 "E-711",
91 "E712", 91 "E-712",
92 "N804", 92 "N-804",
93 "N805", 93 "N-805",
94 "N806", 94 "N-806",
95 "W191", 95 "W-191",
96 "W291", 96 "W-291",
97 "W292", 97 "W-292",
98 "W293", 98 "W-293",
99 "W391", 99 "W-391",
100 "W603", 100 "W-603",
101 ] 101 ]
102 102
103 103
104 class CodeStyleFixer: 104 class CodeStyleFixer:
105 """ 105 """
172 ) 172 )
173 self.__createBackup = False 173 self.__createBackup = False
174 self.__eol = eol 174 self.__eol = eol
175 175
176 self.__fixes = { 176 self.__fixes = {
177 "D111": self.__fixD111, 177 "D-111": self.__fixD111,
178 "D112": self.__fixD112, 178 "D-112": self.__fixD112,
179 "D121": self.__fixD121, 179 "D-121": self.__fixD121,
180 "D131": self.__fixD131, 180 "D-131": self.__fixD131,
181 "D141": self.__fixD141, 181 "D-141": self.__fixD141,
182 "D142": self.__fixD142, 182 "D-142": self.__fixD142,
183 "D143": self.__fixD143, 183 "D-143": self.__fixD143,
184 "D144": self.__fixD144, 184 "D-144": self.__fixD144,
185 "D145": self.__fixD145, 185 "D-145": self.__fixD145,
186 "D221": self.__fixD221, 186 "D-221": self.__fixD221,
187 "D222": self.__fixD221, 187 "D-222": self.__fixD221,
188 "D231": self.__fixD131, 188 "D-231": self.__fixD131,
189 "D242": self.__fixD242, 189 "D-242": self.__fixD242,
190 "D243": self.__fixD243, 190 "D-243": self.__fixD243,
191 "D244": self.__fixD242, 191 "D-244": self.__fixD242,
192 "D245": self.__fixD243, 192 "D-245": self.__fixD243,
193 "D246": self.__fixD144, 193 "D-246": self.__fixD144,
194 "D247": self.__fixD247, 194 "D-247": self.__fixD247,
195 "E101": self.__fixE101, 195 "E-101": self.__fixE101,
196 "E111": self.__fixE101, 196 "E-111": self.__fixE101,
197 "E121": self.__fixE121, 197 "E-121": self.__fixE121,
198 "E122": self.__fixE122, 198 "E-122": self.__fixE122,
199 "E123": self.__fixE123, 199 "E-123": self.__fixE123,
200 "E124": self.__fixE121, 200 "E-124": self.__fixE121,
201 "E125": self.__fixE125, 201 "E-125": self.__fixE125,
202 "E126": self.__fixE126, 202 "E-126": self.__fixE126,
203 "E127": self.__fixE127, 203 "E-127": self.__fixE127,
204 "E128": self.__fixE127, 204 "E-128": self.__fixE127,
205 "E133": self.__fixE126, 205 "E-133": self.__fixE126,
206 "E201": self.__fixE201, 206 "E-201": self.__fixE201,
207 "E202": self.__fixE201, 207 "E-202": self.__fixE201,
208 "E203": self.__fixE201, 208 "E-203": self.__fixE201,
209 "E211": self.__fixE201, 209 "E-211": self.__fixE201,
210 "E221": self.__fixE221, 210 "E-221": self.__fixE221,
211 "E222": self.__fixE221, 211 "E-222": self.__fixE221,
212 "E223": self.__fixE221, 212 "E-223": self.__fixE221,
213 "E224": self.__fixE221, 213 "E-224": self.__fixE221,
214 "E225": self.__fixE225, 214 "E-225": self.__fixE225,
215 "E226": self.__fixE225, 215 "E-226": self.__fixE225,
216 "E227": self.__fixE225, 216 "E-227": self.__fixE225,
217 "E228": self.__fixE225, 217 "E-228": self.__fixE225,
218 "E231": self.__fixE231, 218 "E-231": self.__fixE231,
219 "E241": self.__fixE221, 219 "E-241": self.__fixE221,
220 "E242": self.__fixE221, 220 "E-242": self.__fixE221,
221 "E251": self.__fixE251, 221 "E-251": self.__fixE251,
222 "E261": self.__fixE261, 222 "E-261": self.__fixE261,
223 "E262": self.__fixE261, 223 "E-262": self.__fixE261,
224 "E271": self.__fixE221, 224 "E-271": self.__fixE221,
225 "E272": self.__fixE221, 225 "E-272": self.__fixE221,
226 "E273": self.__fixE221, 226 "E-273": self.__fixE221,
227 "E274": self.__fixE221, 227 "E-274": self.__fixE221,
228 "E301": self.__fixBlankLinesBefore, 228 "E-301": self.__fixBlankLinesBefore,
229 "E302": self.__fixBlankLinesBefore, 229 "E-302": self.__fixBlankLinesBefore,
230 "E303": self.__fixBlankLinesBefore, 230 "E-303": self.__fixBlankLinesBefore,
231 "E304": self.__fixE304, 231 "E-304": self.__fixE304,
232 "E305": self.__fixBlankLinesBefore, 232 "E-305": self.__fixBlankLinesBefore,
233 "E306": self.__fixBlankLinesBefore, 233 "E-306": self.__fixBlankLinesBefore,
234 "E307": self.__fixBlankLinesBefore, 234 "E-307": self.__fixBlankLinesBefore,
235 "E308": self.__fixBlankLinesBefore, 235 "E-308": self.__fixBlankLinesBefore,
236 "E401": self.__fixE401, 236 "E-401": self.__fixE401,
237 "E501": self.__fixE501, 237 "E-501": self.__fixE501,
238 "E502": self.__fixE502, 238 "E-502": self.__fixE502,
239 "E701": self.__fixE701, 239 "E-701": self.__fixE701,
240 "E702": self.__fixE702, 240 "E-702": self.__fixE702,
241 "E703": self.__fixE702, 241 "E-703": self.__fixE702,
242 "E711": self.__fixE711, 242 "E-711": self.__fixE711,
243 "E712": self.__fixE711, 243 "E-712": self.__fixE711,
244 "N804": self.__fixN804, 244 "N-804": self.__fixN804,
245 "N805": self.__fixN804, 245 "N-805": self.__fixN804,
246 "N806": self.__fixN806, 246 "N-806": self.__fixN806,
247 "W191": self.__fixE101, 247 "W-191": self.__fixE101,
248 "W291": self.__fixW291, 248 "W-291": self.__fixW291,
249 "W292": self.__fixW292, 249 "W-292": self.__fixW292,
250 "W293": self.__fixW291, 250 "W-293": self.__fixW291,
251 "W391": self.__fixW391, 251 "W-391": self.__fixW391,
252 "W603": self.__fixW603, 252 "W-603": self.__fixW603,
253 } 253 }
254 self.__modified = False 254 self.__modified = False
255 self.__stackLogical = [] 255 self.__stackLogical = []
256 # These need to be fixed before the file is saved but after all 256 # These need to be fixed before the file is saved but after all
257 # other inline fixes. These work with logical lines. 257 # other inline fixes. These work with logical lines.
297 297
298 with open(self.__filename, "wb") as fp: 298 with open(self.__filename, "wb") as fp:
299 fp.write(txt) 299 fp.write(txt)
300 except (OSError, UnicodeError) as err: 300 except (OSError, UnicodeError) as err:
301 # Could not save the file! Skipping it. Reason: {0} 301 # Could not save the file! Skipping it. Reason: {0}
302 return ("FIXWRITE_ERROR", [str(err)]) 302 return ("FIX-WRITE_ERROR", [str(err)])
303 303
304 return None 304 return None
305 305
306 def __codeMatch(self, code): 306 def __codeMatch(self, code):
307 """ 307 """
631 self.__source[line] = left + '"""' + right 631 self.__source[line] = left + '"""' + right
632 break 632 break
633 line += 1 633 line += 1
634 634
635 # Triple single quotes converted to triple double quotes. 635 # Triple single quotes converted to triple double quotes.
636 return (1, "FIXD111", [], 0) 636 return (1, "FIX-D111", [], 0)
637 637
638 def __fixD112(self, code, line, _pos): 638 def __fixD112(self, code, line, _pos):
639 """ 639 """
640 Private method to fix docstring 'r' in leading quotes. 640 Private method to fix docstring 'r' in leading quotes.
641 641
651 a message code for the fix, a list of arguments for the 651 a message code for the fix, a list of arguments for the
652 message and an ID for a deferred fix 652 message and an ID for a deferred fix
653 @rtype tuple of (int, str, list or int, int) 653 @rtype tuple of (int, str, list or int, int)
654 """ 654 """
655 line -= 1 655 line -= 1
656 if code == "D112": 656 if code == "D-112":
657 insertChar = "r" 657 insertChar = "r"
658 else: 658 else:
659 return (0, "", 0) 659 return (0, "", 0)
660 660
661 newText = ( 661 newText = (
663 + insertChar 663 + insertChar
664 + self.__source[line].lstrip() 664 + self.__source[line].lstrip()
665 ) 665 )
666 self.__source[line] = newText 666 self.__source[line] = newText
667 # Introductory quotes corrected to be {0}""" 667 # Introductory quotes corrected to be {0}"""
668 return (1, "FIXD112", [insertChar], 0) 668 return (1, "FIX-D112", [insertChar], 0)
669 669
670 def __fixD121(self, code, line, pos, apply=False): 670 def __fixD121(self, code, line, pos, apply=False):
671 """ 671 """
672 Private method to fix a single line docstring on multiple lines. 672 Private method to fix a single line docstring on multiple lines.
673 673
700 self.__source[line + 2] = "" 700 self.__source[line + 2] = ""
701 701
702 self.__source[line] = docstring 702 self.__source[line] = docstring
703 self.__source[line + 1] = "" 703 self.__source[line + 1] = ""
704 # Single line docstring put on one line. 704 # Single line docstring put on one line.
705 return (1, "FIXD121", [], 0) 705 return (1, "FIX-D121", [], 0)
706 else: 706 else:
707 fixId = self.__getID() 707 fixId = self.__getID()
708 self.__stack.append((fixId, code, line, pos)) 708 self.__stack.append((fixId, code, line, pos))
709 return (-1, "", [], fixId) 709 return (-1, "", [], fixId)
710 710
750 newText = self.__source[line].rstrip() + "." + self.__eol 750 newText = self.__source[line].rstrip() + "." + self.__eol
751 751
752 if newText: 752 if newText:
753 self.__source[line] = newText 753 self.__source[line] = newText
754 # Period added to summary line. 754 # Period added to summary line.
755 return (1, "FIXD131", [], 0) 755 return (1, "FIX-D131", [], 0)
756 else: 756 else:
757 return (0, "", [], 0) 757 return (0, "", [], 0)
758 758
759 def __fixD141(self, code, line, pos, apply=False): 759 def __fixD141(self, code, line, pos, apply=False):
760 """ 760 """
778 """ 778 """
779 if apply: 779 if apply:
780 line -= 1 780 line -= 1
781 self.__source[line - 1] = "" 781 self.__source[line - 1] = ""
782 # Blank line before function/method docstring removed. 782 # Blank line before function/method docstring removed.
783 return (1, "FIXD141", [], 0) 783 return (1, "FIX-D141", [], 0)
784 else: 784 else:
785 fixId = self.__getID() 785 fixId = self.__getID()
786 self.__stack.append((fixId, code, line, pos)) 786 self.__stack.append((fixId, code, line, pos))
787 return (-1, "", [], fixId) 787 return (-1, "", [], fixId)
788 788
808 """ 808 """
809 if apply: 809 if apply:
810 line -= 1 810 line -= 1
811 self.__source[line] = self.__eol + self.__source[line] 811 self.__source[line] = self.__eol + self.__source[line]
812 # Blank line inserted before class docstring. 812 # Blank line inserted before class docstring.
813 return (1, "FIXD142", [], 0) 813 return (1, "FIX-D142", [], 0)
814 else: 814 else:
815 fixId = self.__getID() 815 fixId = self.__getID()
816 self.__stack.append((fixId, code, line, pos)) 816 self.__stack.append((fixId, code, line, pos))
817 return (-1, "", [], fixId) 817 return (-1, "", [], fixId)
818 818
838 """ 838 """
839 if apply: 839 if apply:
840 line -= 1 840 line -= 1
841 self.__source[line] += self.__eol 841 self.__source[line] += self.__eol
842 # Blank line inserted after class docstring. 842 # Blank line inserted after class docstring.
843 return (1, "FIXD143", [], 0) 843 return (1, "FIX-D143", [], 0)
844 else: 844 else:
845 fixId = self.__getID() 845 fixId = self.__getID()
846 self.__stack.append((fixId, code, line, pos)) 846 self.__stack.append((fixId, code, line, pos))
847 return (-1, "", [], fixId) 847 return (-1, "", [], fixId)
848 848
872 # only correct summary lines can be fixed here 872 # only correct summary lines can be fixed here
873 return (0, "", 0) 873 return (0, "", 0)
874 874
875 self.__source[line] += self.__eol 875 self.__source[line] += self.__eol
876 # Blank line inserted after docstring summary. 876 # Blank line inserted after docstring summary.
877 return (1, "FIXD144", [], 0) 877 return (1, "FIX-D144", [], 0)
878 else: 878 else:
879 fixId = self.__getID() 879 fixId = self.__getID()
880 self.__stack.append((fixId, code, line, pos)) 880 self.__stack.append((fixId, code, line, pos))
881 return (-1, "", [], fixId) 881 return (-1, "", [], fixId)
882 882
902 """ 902 """
903 if apply: 903 if apply:
904 line -= 1 904 line -= 1
905 self.__source[line] = self.__eol + self.__source[line] 905 self.__source[line] = self.__eol + self.__source[line]
906 # Blank line inserted after last paragraph of docstring. 906 # Blank line inserted after last paragraph of docstring.
907 return (1, "FIXD145", [], 0) 907 return (1, "FIX-D145", [], 0)
908 else: 908 else:
909 fixId = self.__getID() 909 fixId = self.__getID()
910 self.__stack.append((fixId, code, line, pos)) 910 self.__stack.append((fixId, code, line, pos))
911 return (-1, "", [], fixId) 911 return (-1, "", [], fixId)
912 912
932 """ 932 """
933 if apply: 933 if apply:
934 line -= 1 934 line -= 1
935 indent = self.__getIndent(self.__source[line]) 935 indent = self.__getIndent(self.__source[line])
936 source = self.__source[line].strip() 936 source = self.__source[line].strip()
937 if code == "D221": 937 if code == "D-221":
938 # leading 938 # leading
939 if source.startswith(("r", "u")): 939 if source.startswith(("r", "u")):
940 first, second = source[:4], source[4:].strip() 940 first, second = source[:4], source[4:].strip()
941 else: 941 else:
942 first, second = source[:3], source[3:].strip() 942 first, second = source[:3], source[3:].strip()
943 else: 943 else:
944 # trailing 944 # trailing
945 first, second = source[:-3].strip(), source[-3:] 945 first, second = source[:-3].strip(), source[-3:]
946 newText = indent + first + self.__eol + indent + second + self.__eol 946 newText = indent + first + self.__eol + indent + second + self.__eol
947 self.__source[line] = newText 947 self.__source[line] = newText
948 if code == "D221": 948 if code == "D-221":
949 # Leading quotes put on separate line. 949 # Leading quotes put on separate line.
950 msg = "FIXD221" 950 msg = "FIX-D221"
951 else: 951 else:
952 # Trailing quotes put on separate line. 952 # Trailing quotes put on separate line.
953 msg = "FIXD222" 953 msg = "FIX-D222"
954 return (1, msg, [], 0) 954 return (1, msg, [], 0)
955 else: 955 else:
956 fixId = self.__getID() 956 fixId = self.__getID()
957 self.__stack.append((fixId, code, line, pos)) 957 self.__stack.append((fixId, code, line, pos))
958 return (-1, "", [], fixId) 958 return (-1, "", [], fixId)
978 @rtype tuple of (int, str, list or int, int) 978 @rtype tuple of (int, str, list or int, int)
979 """ 979 """
980 if apply: 980 if apply:
981 line -= 1 981 line -= 1
982 self.__source[line - 1] = "" 982 self.__source[line - 1] = ""
983 if code == "D242": 983 if code == "D-242":
984 # Blank line before class docstring removed. 984 # Blank line before class docstring removed.
985 msg = "FIXD242" 985 msg = "FIX-D242"
986 else: 986 else:
987 # Blank line before function/method docstring removed. 987 # Blank line before function/method docstring removed.
988 msg = "FIXD244" 988 msg = "FIX-D244"
989 return (1, msg, [], 0) 989 return (1, msg, [], 0)
990 else: 990 else:
991 fixId = self.__getID() 991 fixId = self.__getID()
992 self.__stack.append((fixId, code, line, pos)) 992 self.__stack.append((fixId, code, line, pos))
993 return (-1, "", [], fixId) 993 return (-1, "", [], fixId)
1013 @rtype tuple of (int, str, list or int, int) 1013 @rtype tuple of (int, str, list or int, int)
1014 """ 1014 """
1015 if apply: 1015 if apply:
1016 line -= 1 1016 line -= 1
1017 self.__source[line + 1] = "" 1017 self.__source[line + 1] = ""
1018 if code == "D243": 1018 if code == "D-243":
1019 # Blank line after class docstring removed. 1019 # Blank line after class docstring removed.
1020 msg = "FIXD243" 1020 msg = "FIX-D243"
1021 else: 1021 else:
1022 # Blank line after function/method docstring removed. 1022 # Blank line after function/method docstring removed.
1023 msg = "FIXD245" 1023 msg = "FIX-D245"
1024 return (1, msg, [], 0) 1024 return (1, msg, [], 0)
1025 else: 1025 else:
1026 fixId = self.__getID() 1026 fixId = self.__getID()
1027 self.__stack.append((fixId, code, line, pos)) 1027 self.__stack.append((fixId, code, line, pos))
1028 return (-1, "", [], fixId) 1028 return (-1, "", [], fixId)
1049 """ 1049 """
1050 if apply: 1050 if apply:
1051 line -= 1 1051 line -= 1
1052 self.__source[line - 1] = "" 1052 self.__source[line - 1] = ""
1053 # Blank line after last paragraph removed. 1053 # Blank line after last paragraph removed.
1054 return (1, "FIXD247", [], 0) 1054 return (1, "FIX-D247", [], 0)
1055 else: 1055 else:
1056 fixId = self.__getID() 1056 fixId = self.__getID()
1057 self.__stack.append((fixId, code, line, pos)) 1057 self.__stack.append((fixId, code, line, pos))
1058 return (-1, "", [], fixId) 1058 return (-1, "", [], fixId)
1059 1059
1078 self.__reindenter = Reindenter(self.__source) 1078 self.__reindenter = Reindenter(self.__source)
1079 self.__reindenter.run() 1079 self.__reindenter.run()
1080 fixedLine = self.__reindenter.fixedLine(line - 1) 1080 fixedLine = self.__reindenter.fixedLine(line - 1)
1081 if fixedLine is not None and fixedLine != self.__source[line - 1]: 1081 if fixedLine is not None and fixedLine != self.__source[line - 1]:
1082 self.__source[line - 1] = fixedLine 1082 self.__source[line - 1] = fixedLine
1083 if code in ["E101", "W191"]: 1083 if code in ["E-101", "W-191"]:
1084 # Tab converted to 4 spaces. 1084 # Tab converted to 4 spaces.
1085 msg = "FIXE101" 1085 msg = "FIX-E101"
1086 else: 1086 else:
1087 # Indentation adjusted to be a multiple of four. 1087 # Indentation adjusted to be a multiple of four.
1088 msg = "FIXE111" 1088 msg = "FIX-E111"
1089 return (1, msg, [], 0) 1089 return (1, msg, [], 0)
1090 else: 1090 else:
1091 return (0, "", [], 0) 1091 return (0, "", [], 0)
1092 1092
1093 def __fixE121(self, code, line, pos, apply=False): 1093 def __fixE121(self, code, line, pos, apply=False):
1114 logical = self.__getLogical(line, pos) 1114 logical = self.__getLogical(line, pos)
1115 if logical: 1115 if logical:
1116 # Fix by adjusting initial indent level. 1116 # Fix by adjusting initial indent level.
1117 changed = self.__fixReindent(line, pos, logical) 1117 changed = self.__fixReindent(line, pos, logical)
1118 if changed: 1118 if changed:
1119 if code == "E121": 1119 if code == "E-121":
1120 # Indentation of continuation line corrected. 1120 # Indentation of continuation line corrected.
1121 msg = "FIXE121" 1121 msg = "FIX-E121"
1122 elif code == "E124": 1122 elif code == "E-124":
1123 # Indentation of closing bracket corrected. 1123 # Indentation of closing bracket corrected.
1124 msg = "FIXE124" 1124 msg = "FIX-E124"
1125 return (1, msg, [], 0) 1125 return (1, msg, [], 0)
1126 return (0, "", [], 0) 1126 return (0, "", [], 0)
1127 else: 1127 else:
1128 fixId = self.__getID() 1128 fixId = self.__getID()
1129 self.__stackLogical.append((fixId, code, line, pos)) 1129 self.__stackLogical.append((fixId, code, line, pos))
1160 indentation = self.__getIndent(text) 1160 indentation = self.__getIndent(text)
1161 self.__source[line] = ( 1161 self.__source[line] = (
1162 indentation + self.__indentWord + text.lstrip() 1162 indentation + self.__indentWord + text.lstrip()
1163 ) 1163 )
1164 # Missing indentation of continuation line corrected. 1164 # Missing indentation of continuation line corrected.
1165 return (1, "FIXE122", [], 0) 1165 return (1, "FIX-E122", [], 0)
1166 return (0, "", [], 0) 1166 return (0, "", [], 0)
1167 else: 1167 else:
1168 fixId = self.__getID() 1168 fixId = self.__getID()
1169 self.__stackLogical.append((fixId, code, line, pos)) 1169 self.__stackLogical.append((fixId, code, line, pos))
1170 return (-1, "", [], fixId) 1170 return (-1, "", [], fixId)
1202 else: 1202 else:
1203 self.__source[row] = newText 1203 self.__source[row] = newText
1204 changed = True 1204 changed = True
1205 if changed: 1205 if changed:
1206 # Closing bracket aligned to opening bracket. 1206 # Closing bracket aligned to opening bracket.
1207 return (1, "FIXE123", [], 0) 1207 return (1, "FIX-E123", [], 0)
1208 return (0, "", [], 0) 1208 return (0, "", [], 0)
1209 else: 1209 else:
1210 fixId = self.__getID() 1210 fixId = self.__getID()
1211 self.__stackLogical.append((fixId, code, line, pos)) 1211 self.__stackLogical.append((fixId, code, line, pos))
1212 return (-1, "", [], fixId) 1212 return (-1, "", [], fixId)
1241 text = self.__source[row] 1241 text = self.__source[row]
1242 self.__source[row] = ( 1242 self.__source[row] = (
1243 self.__getIndent(text) + self.__indentWord + text.lstrip() 1243 self.__getIndent(text) + self.__indentWord + text.lstrip()
1244 ) 1244 )
1245 # Indentation level changed. 1245 # Indentation level changed.
1246 return (1, "FIXE125", [], 0) 1246 return (1, "FIX-E125", [], 0)
1247 return (0, "", [], 0) 1247 return (0, "", [], 0)
1248 else: 1248 else:
1249 fixId = self.__getID() 1249 fixId = self.__getID()
1250 self.__stackLogical.append((fixId, code, line, pos)) 1250 self.__stackLogical.append((fixId, code, line, pos))
1251 return (-1, "", [], fixId) 1251 return (-1, "", [], fixId)
1288 else: 1288 else:
1289 self.__source[row] = newText 1289 self.__source[row] = newText
1290 changed = True 1290 changed = True
1291 if changed: 1291 if changed:
1292 # Indentation level of hanging indentation changed. 1292 # Indentation level of hanging indentation changed.
1293 return (1, "FIXE126", [], 0) 1293 return (1, "FIX-E126", [], 0)
1294 return (0, "", [], 0) 1294 return (0, "", [], 0)
1295 else: 1295 else:
1296 fixId = self.__getID() 1296 fixId = self.__getID()
1297 self.__stackLogical.append((fixId, code, line, pos)) 1297 self.__stackLogical.append((fixId, code, line, pos))
1298 return (-1, "", [], fixId) 1298 return (-1, "", [], fixId)
1350 else: 1350 else:
1351 self.__source[row] = newText 1351 self.__source[row] = newText
1352 changed = True 1352 changed = True
1353 if changed: 1353 if changed:
1354 # Visual indentation corrected. 1354 # Visual indentation corrected.
1355 return (1, "FIXE127", [], 0) 1355 return (1, "FIX-E127", [], 0)
1356 return (0, "", [], 0) 1356 return (0, "", [], 0)
1357 else: 1357 else:
1358 fixId = self.__getID() 1358 fixId = self.__getID()
1359 self.__stackLogical.append((fixId, code, line, pos)) 1359 self.__stackLogical.append((fixId, code, line, pos))
1360 return (-1, "", [], fixId) 1360 return (-1, "", [], fixId)
1386 if newText == text: 1386 if newText == text:
1387 return (0, "", [], 0) 1387 return (0, "", [], 0)
1388 1388
1389 self.__source[line] = newText 1389 self.__source[line] = newText
1390 # Extraneous whitespace removed. 1390 # Extraneous whitespace removed.
1391 return (1, "FIXE201", [], 0) 1391 return (1, "FIX-E201", [], 0)
1392 1392
1393 def __fixE221(self, _code, line, pos): 1393 def __fixE221(self, _code, line, pos):
1394 """ 1394 """
1395 Private method to fix extraneous whitespace around operator or 1395 Private method to fix extraneous whitespace around operator or
1396 keyword. 1396 keyword.
1417 newText = self.__fixWhitespace(text, pos, " ") 1417 newText = self.__fixWhitespace(text, pos, " ")
1418 if newText == text: 1418 if newText == text:
1419 return (0, "", [], 0) 1419 return (0, "", [], 0)
1420 1420
1421 self.__source[line] = newText 1421 self.__source[line] = newText
1422 return (1, "FIXE221", [], 0) 1422 return (1, "FIX-E221", [], 0)
1423 1423
1424 def __fixE225(self, _code, line, pos): 1424 def __fixE225(self, _code, line, pos):
1425 """ 1425 """
1426 Private method to fix extraneous whitespaces around operator. 1426 Private method to fix extraneous whitespaces around operator.
1427 1427
1462 if newText == text: 1462 if newText == text:
1463 return (0, "", [], 0) 1463 return (0, "", [], 0)
1464 1464
1465 self.__source[line] = newText 1465 self.__source[line] = newText
1466 # Missing whitespaces added. 1466 # Missing whitespaces added.
1467 return (1, "FIXE225", [], 0) 1467 return (1, "FIX-E225", [], 0)
1468 1468
1469 def __fixE231(self, _code, line, pos): 1469 def __fixE231(self, _code, line, pos):
1470 """ 1470 """
1471 Private method to fix missing whitespace after ',;:'. 1471 Private method to fix missing whitespace after ',;:'.
1472 1472
1487 pos += 1 1487 pos += 1
1488 self.__source[line] = ( 1488 self.__source[line] = (
1489 self.__source[line][:pos] + " " + self.__source[line][pos:] 1489 self.__source[line][:pos] + " " + self.__source[line][pos:]
1490 ) 1490 )
1491 # Missing whitespace added. 1491 # Missing whitespace added.
1492 return (1, "FIXE231", [], 0) 1492 return (1, "FIX-E231", [], 0)
1493 1493
1494 def __fixE251(self, _code, line, pos): 1494 def __fixE251(self, _code, line, pos):
1495 """ 1495 """
1496 Private method to fix extraneous whitespace around keyword and 1496 Private method to fix extraneous whitespace around keyword and
1497 default parameter equals. 1497 default parameter equals.
1525 self.__source[line] = newText.rstrip("\n\r \t\\") 1525 self.__source[line] = newText.rstrip("\n\r \t\\")
1526 self.__source[line + 1] = self.__source[line + 1].lstrip() 1526 self.__source[line + 1] = self.__source[line + 1].lstrip()
1527 else: 1527 else:
1528 self.__source[line] = newText 1528 self.__source[line] = newText
1529 # Extraneous whitespace removed. 1529 # Extraneous whitespace removed.
1530 return (1, "FIXE251", [], 0) 1530 return (1, "FIX-E251", [], 0)
1531 1531
1532 def __fixE261(self, _code, line, pos): 1532 def __fixE261(self, _code, line, pos):
1533 """ 1533 """
1534 Private method to fix whitespace before or after inline comment. 1534 Private method to fix whitespace before or after inline comment.
1535 1535
1551 left = text[:pos].rstrip(" \t#") 1551 left = text[:pos].rstrip(" \t#")
1552 right = text[pos:].lstrip(" \t#") 1552 right = text[pos:].lstrip(" \t#")
1553 newText = left + (" # " + right if right.strip() else right) 1553 newText = left + (" # " + right if right.strip() else right)
1554 self.__source[line] = newText 1554 self.__source[line] = newText
1555 # Whitespace around comment sign corrected. 1555 # Whitespace around comment sign corrected.
1556 return (1, "FIXE261", [], 0) 1556 return (1, "FIX-E261", [], 0)
1557 1557
1558 def __fixBlankLinesBefore(self, code, line, pos, apply=False): 1558 def __fixBlankLinesBefore(self, code, line, pos, apply=False):
1559 """ 1559 """
1560 Private method to fix the need for blank lines before class, function 1560 Private method to fix the need for blank lines before class, function
1561 and method definitions. 1561 and method definitions.
1574 a message code for the fix, a list of arguments for the 1574 a message code for the fix, a list of arguments for the
1575 message and an ID for a deferred fix 1575 message and an ID for a deferred fix
1576 @rtype tuple of (int, str, list or int, int) 1576 @rtype tuple of (int, str, list or int, int)
1577 """ 1577 """
1578 if apply: 1578 if apply:
1579 if code in ["E301", "E306", "E307"]: 1579 if code in ["E-301", "E-306", "E-307"]:
1580 blankLinesBefore = self.__blankLines["method"] 1580 blankLinesBefore = self.__blankLines["method"]
1581 elif code == "E308": 1581 elif code == "E-308":
1582 blankLinesBefore = 1 1582 blankLinesBefore = 1
1583 else: 1583 else:
1584 blankLinesBefore = self.__blankLines["toplevel"] 1584 blankLinesBefore = self.__blankLines["toplevel"]
1585 1585
1586 # count blank lines 1586 # count blank lines
1599 # insert blank lines (one or two) 1599 # insert blank lines (one or two)
1600 while delta < 0: 1600 while delta < 0:
1601 self.__source.insert(line, self.__eol) 1601 self.__source.insert(line, self.__eol)
1602 delta += 1 1602 delta += 1
1603 # %n blank line(s) inserted. 1603 # %n blank line(s) inserted.
1604 return (1, "FIXE302+", blankLinesBefore - blanks, 0) 1604 return (1, "FIX-E302+", blankLinesBefore - blanks, 0)
1605 elif delta > 0: 1605 elif delta > 0:
1606 # delete superfluous blank lines 1606 # delete superfluous blank lines
1607 while delta > 0: 1607 while delta > 0:
1608 del self.__source[line - 1] 1608 del self.__source[line - 1]
1609 line -= 1 1609 line -= 1
1610 delta -= 1 1610 delta -= 1
1611 # %n superfluous line(s) removed. 1611 # %n superfluous line(s) removed.
1612 return (1, "FIXE302-", blanks - blankLinesBefore, 0) 1612 return (1, "FIX-E302-", blanks - blankLinesBefore, 0)
1613 else: 1613 else:
1614 return (0, "", [], 0) 1614 return (0, "", [], 0)
1615 else: 1615 else:
1616 fixId = self.__getID() 1616 fixId = self.__getID()
1617 self.__stack.append((fixId, code, line, pos)) 1617 self.__stack.append((fixId, code, line, pos))
1644 del self.__source[index] 1644 del self.__source[index]
1645 index -= 1 1645 index -= 1
1646 else: 1646 else:
1647 break 1647 break
1648 # Superfluous blank lines after function decorator removed. 1648 # Superfluous blank lines after function decorator removed.
1649 return (1, "FIXE304", [], 0) 1649 return (1, "FIX-E304", [], 0)
1650 else: 1650 else:
1651 fixId = self.__getID() 1651 fixId = self.__getID()
1652 self.__stack.append((fixId, code, line, pos)) 1652 self.__stack.append((fixId, code, line, pos))
1653 return (-1, "", [], fixId) 1653 return (-1, "", [], fixId)
1654 1654
1690 + "import " 1690 + "import "
1691 + text[pos:].lstrip("\t ,") 1691 + text[pos:].lstrip("\t ,")
1692 ) 1692 )
1693 self.__source[line] = newText 1693 self.__source[line] = newText
1694 # Imports were put on separate lines. 1694 # Imports were put on separate lines.
1695 return (1, "FIXE401", [], 0) 1695 return (1, "FIX-E401", [], 0)
1696 else: 1696 else:
1697 fixId = self.__getID() 1697 fixId = self.__getID()
1698 self.__stack.append((fixId, code, line, pos)) 1698 self.__stack.append((fixId, code, line, pos))
1699 return (-1, "", [], fixId) 1699 return (-1, "", [], fixId)
1700 1700
1746 if newNextText and newNextText != nextText: 1746 if newNextText and newNextText != nextText:
1747 if newNextText == " ": 1747 if newNextText == " ":
1748 newNextText = "" 1748 newNextText = ""
1749 self.__source[line + 1] = newNextText 1749 self.__source[line + 1] = newNextText
1750 # Long lines have been shortened. 1750 # Long lines have been shortened.
1751 return (1, "FIXE501", [], 0) 1751 return (1, "FIX-E501", [], 0)
1752 else: 1752 else:
1753 return (0, "", [], 0) 1753 return (0, "", [], 0)
1754 else: 1754 else:
1755 fixId = self.__getID() 1755 fixId = self.__getID()
1756 self.__stack.append((fixId, code, line, pos)) 1756 self.__stack.append((fixId, code, line, pos))
1775 """ 1775 """
1776 self.__source[line - 1] = ( 1776 self.__source[line - 1] = (
1777 self.__source[line - 1].rstrip("\n\r \t\\") + self.__eol 1777 self.__source[line - 1].rstrip("\n\r \t\\") + self.__eol
1778 ) 1778 )
1779 # Redundant backslash in brackets removed. 1779 # Redundant backslash in brackets removed.
1780 return (1, "FIXE502", [], 0) 1780 return (1, "FIX-E502", [], 0)
1781 1781
1782 def __fixE701(self, code, line, pos, apply=False): 1782 def __fixE701(self, code, line, pos, apply=False):
1783 """ 1783 """
1784 Private method to fix colon-separated compound statements. 1784 Private method to fix colon-separated compound statements.
1785 1785
1811 + text[pos:].lstrip("\n\r \t\\") 1811 + text[pos:].lstrip("\n\r \t\\")
1812 + self.__eol 1812 + self.__eol
1813 ) 1813 )
1814 self.__source[line] = newText 1814 self.__source[line] = newText
1815 # Compound statement corrected. 1815 # Compound statement corrected.
1816 return (1, "FIXE701", [], 0) 1816 return (1, "FIX-E701", [], 0)
1817 else: 1817 else:
1818 fixId = self.__getID() 1818 fixId = self.__getID()
1819 self.__stack.append((fixId, code, line, pos)) 1819 self.__stack.append((fixId, code, line, pos))
1820 return (-1, "", [], fixId) 1820 return (-1, "", [], fixId)
1821 1821
1851 else: 1851 else:
1852 first = text[:pos].rstrip("\n\r \t;") + self.__eol 1852 first = text[:pos].rstrip("\n\r \t;") + self.__eol
1853 second = text[pos:].lstrip("\n\r \t;") 1853 second = text[pos:].lstrip("\n\r \t;")
1854 self.__source[line] = first + self.__getIndent(text) + second 1854 self.__source[line] = first + self.__getIndent(text) + second
1855 # Compound statement corrected. 1855 # Compound statement corrected.
1856 return (1, "FIXE702", [], 0) 1856 return (1, "FIX-E702", [], 0)
1857 else: 1857 else:
1858 fixId = self.__getID() 1858 fixId = self.__getID()
1859 self.__stack.append((fixId, code, line, pos)) 1859 self.__stack.append((fixId, code, line, pos))
1860 return (-1, "", [], fixId) 1860 return (-1, "", [], fixId)
1861 1861
1897 else: 1897 else:
1898 return (0, "", [], 0) 1898 return (0, "", [], 0)
1899 1899
1900 self.__source[line] = " ".join([left, center, right]) 1900 self.__source[line] = " ".join([left, center, right])
1901 # Comparison to None/True/False corrected. 1901 # Comparison to None/True/False corrected.
1902 return (1, "FIXE711", [], 0) 1902 return (1, "FIX-E711", [], 0)
1903 1903
1904 def __fixN804(self, code, line, pos, apply=False): 1904 def __fixN804(self, code, line, pos, apply=False):
1905 """ 1905 """
1906 Private method to fix a wrong first argument of normal and 1906 Private method to fix a wrong first argument of normal and
1907 class methods. 1907 class methods.
1922 @rtype tuple of (int, str, list or int, int) 1922 @rtype tuple of (int, str, list or int, int)
1923 """ 1923 """
1924 if apply: 1924 if apply:
1925 line -= 1 1925 line -= 1
1926 text = self.__source[line] 1926 text = self.__source[line]
1927 if code == "N804": 1927 if code == "N-804":
1928 arg = "cls" 1928 arg = "cls"
1929 else: 1929 else:
1930 arg = "self" 1930 arg = "self"
1931 1931
1932 if text.rstrip().endswith("("): 1932 if text.rstrip().endswith("("):
1947 else: 1947 else:
1948 center = arg + ", " 1948 center = arg + ", "
1949 newText = left + center + right 1949 newText = left + center + right
1950 self.__source[line] = newText 1950 self.__source[line] = newText
1951 # '{0}' argument added. 1951 # '{0}' argument added.
1952 return (1, "FIXN804", [arg], 0) 1952 return (1, "FIX-N804", [arg], 0)
1953 else: 1953 else:
1954 fixId = self.__getID() 1954 fixId = self.__getID()
1955 self.__stack.append((fixId, code, line, pos)) 1955 self.__stack.append((fixId, code, line, pos))
1956 return (-1, "", [], fixId) 1956 return (-1, "", [], fixId)
1957 1957
2011 self.__source[line] = "" 2011 self.__source[line] = ""
2012 else: 2012 else:
2013 self.__source[line] = indent + right 2013 self.__source[line] = indent + right
2014 2014
2015 # '{0}' argument removed. 2015 # '{0}' argument removed.
2016 return (1, "FIXN806", [arg], 0) 2016 return (1, "FIX-N806", [arg], 0)
2017 else: 2017 else:
2018 fixId = self.__getID() 2018 fixId = self.__getID()
2019 self.__stack.append((fixId, code, line, pos)) 2019 self.__stack.append((fixId, code, line, pos))
2020 return (-1, "", [], fixId) 2020 return (-1, "", [], fixId)
2021 2021
2038 """ 2038 """
2039 self.__source[line - 1] = re.sub( 2039 self.__source[line - 1] = re.sub(
2040 r"[\t ]+(\r?)$", r"\1", self.__source[line - 1] 2040 r"[\t ]+(\r?)$", r"\1", self.__source[line - 1]
2041 ) 2041 )
2042 # Whitespace stripped from end of line. 2042 # Whitespace stripped from end of line.
2043 return (1, "FIXW291", [], 0) 2043 return (1, "FIX-W291", [], 0)
2044 2044
2045 def __fixW292(self, _code, line, _pos): 2045 def __fixW292(self, _code, line, _pos):
2046 """ 2046 """
2047 Private method to fix a missing newline at the end of file. 2047 Private method to fix a missing newline at the end of file.
2048 2048
2059 message and an ID for a deferred fix 2059 message and an ID for a deferred fix
2060 @rtype tuple of (int, str, list or int, int) 2060 @rtype tuple of (int, str, list or int, int)
2061 """ 2061 """
2062 self.__source[line - 1] += self.__eol 2062 self.__source[line - 1] += self.__eol
2063 # newline added to end of file. 2063 # newline added to end of file.
2064 return (1, "FIXW292", [], 0) 2064 return (1, "FIX-W292", [], 0)
2065 2065
2066 def __fixW391(self, _code, line, _pos): 2066 def __fixW391(self, _code, line, _pos):
2067 """ 2067 """
2068 Private method to fix trailing blank lines. 2068 Private method to fix trailing blank lines.
2069 2069
2086 del self.__source[index] 2086 del self.__source[index]
2087 index -= 1 2087 index -= 1
2088 else: 2088 else:
2089 break 2089 break
2090 # Superfluous trailing blank lines removed from end of file. 2090 # Superfluous trailing blank lines removed from end of file.
2091 return (1, "FIXW391", [], 0) 2091 return (1, "FIX-W391", [], 0)
2092 2092
2093 def __fixW603(self, _code, line, _pos): 2093 def __fixW603(self, _code, line, _pos):
2094 """ 2094 """
2095 Private method to fix the not equal notation. 2095 Private method to fix the not equal notation.
2096 2096
2107 message and an ID for a deferred fix 2107 message and an ID for a deferred fix
2108 @rtype tuple of (int, str, list or int, int) 2108 @rtype tuple of (int, str, list or int, int)
2109 """ 2109 """
2110 self.__source[line - 1] = self.__source[line - 1].replace("<>", "!=") 2110 self.__source[line - 1] = self.__source[line - 1].replace("<>", "!=")
2111 # '<>' replaced by '!='. 2111 # '<>' replaced by '!='.
2112 return (1, "FIXW603", [], 0) 2112 return (1, "FIX-W603", [], 0)
2113 2113
2114 2114
2115 class Reindenter: 2115 class Reindenter:
2116 """ 2116 """
2117 Class to reindent badly-indented code to uniformly use four-space 2117 Class to reindent badly-indented code to uniformly use four-space

eric ide

mercurial