eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py

changeset 7610
df7025fe26a3
parent 7609
d5aff4fd0ef8
child 7611
d546c4e72f52
equal deleted inserted replaced
7609:d5aff4fd0ef8 7610:df7025fe26a3
43 positionRole = Qt.UserRole + 3 43 positionRole = Qt.UserRole + 3
44 messageRole = Qt.UserRole + 4 44 messageRole = Qt.UserRole + 4
45 fixableRole = Qt.UserRole + 5 45 fixableRole = Qt.UserRole + 5
46 codeRole = Qt.UserRole + 6 46 codeRole = Qt.UserRole + 6
47 ignoredRole = Qt.UserRole + 7 47 ignoredRole = Qt.UserRole + 7
48 argsRole = Qt.UserRole + 8
48 49
49 availableFutures = [ 50 availableFutures = [
50 'division', 'absolute_import', 'with_statement', 51 'division', 'absolute_import', 'with_statement',
51 'print_function', 'unicode_literals', 'generator_stop', 52 'print_function', 'unicode_literals', 'generator_stop',
52 'annotations'] 53 'annotations']
197 if not self.resultList.findItems(msg, Qt.MatchExactly): 198 if not self.resultList.findItems(msg, Qt.MatchExactly):
198 itm = QTreeWidgetItem(self.__errorItem, [msg]) 199 itm = QTreeWidgetItem(self.__errorItem, [msg])
199 itm.setForeground(0, Qt.red) 200 itm.setForeground(0, Qt.red)
200 itm.setFirstColumnSpanned(True) 201 itm.setFirstColumnSpanned(True)
201 202
202 def __createResultItem(self, filename, line, pos, message, fixed, 203 def __createFileErrorItem(self, filename, message):
203 autofixing, ignored): 204 """
204 """ 205 Private method to create an error entry for a given file.
205 Private method to create an entry in the result list.
206 206
207 @param filename file name of the file 207 @param filename file name of the file
208 @type str 208 @type str
209 @param line line number of issue 209 @param message error message text
210 @type int or str
211 @param pos character position of issue
212 @type int or str
213 @param message message text
214 @type str 210 @type str
215 @param fixed flag indicating a fixed issue 211 """
216 @type bool 212 result = {
217 @param autofixing flag indicating, that we are fixing issues 213 "file": filename,
218 automatically 214 "line": 1,
219 @type bool 215 "offset": 1,
220 @param ignored flag indicating an ignored issue 216 "code": "",
221 @type bool 217 "args": [],
218 "display": self.tr("Error: {0}").format(message).rstrip(),
219 "fixed": False,
220 "autofixing": False,
221 "ignored": False,
222 }
223 self.__createResultItem(filename, result)
224
225 def __createResultItem(self, filename, result):
226 """
227 Private method to create an entry in the result list.
228
229 @param filename file name of the file
230 @type str
231 @param result dictionary containing check result data
232 @type dict
222 @return reference to the created item 233 @return reference to the created item
223 @rtype QTreeWidgetItem 234 @rtype QTreeWidgetItem
224 """ 235 """
225 from .CodeStyleFixer import FixableCodeStyleIssues 236 from .CodeStyleFixer import FixableCodeStyleIssues
226 237
231 self.__lastFileItem.setFirstColumnSpanned(True) 242 self.__lastFileItem.setFirstColumnSpanned(True)
232 self.__lastFileItem.setExpanded(True) 243 self.__lastFileItem.setExpanded(True)
233 self.__lastFileItem.setData(0, self.filenameRole, filename) 244 self.__lastFileItem.setData(0, self.filenameRole, filename)
234 245
235 fixable = False 246 fixable = False
236 code, message = message.split(None, 1)
237 itm = QTreeWidgetItem( 247 itm = QTreeWidgetItem(
238 self.__lastFileItem, 248 self.__lastFileItem,
239 ["{0:6}".format(line), code, message]) 249 ["{0:6}".format(result["line"]), result["code"],
240 if code.startswith(("W", "-", "C", "M")): 250 result["display"]])
251 if result["code"].startswith(("W", "-", "C", "M")):
241 itm.setIcon(1, UI.PixmapCache.getIcon("warning")) 252 itm.setIcon(1, UI.PixmapCache.getIcon("warning"))
242 elif code.startswith(("A", "N")): 253 elif result["code"].startswith(("A", "N")):
243 itm.setIcon(1, UI.PixmapCache.getIcon("namingError")) 254 itm.setIcon(1, UI.PixmapCache.getIcon("namingError"))
244 elif code.startswith("D"): 255 elif result["code"].startswith("D"):
245 itm.setIcon(1, UI.PixmapCache.getIcon("docstringError")) 256 itm.setIcon(1, UI.PixmapCache.getIcon("docstringError"))
246 else: 257 else:
247 itm.setIcon(1, UI.PixmapCache.getIcon("syntaxError")) 258 itm.setIcon(1, UI.PixmapCache.getIcon("syntaxError"))
248 if fixed: 259 if result["fixed"]:
249 itm.setIcon(0, UI.PixmapCache.getIcon("issueFixed")) 260 itm.setIcon(0, UI.PixmapCache.getIcon("issueFixed"))
250 elif ( 261 elif (
251 code in FixableCodeStyleIssues and not autofixing and 262 result["code"] in FixableCodeStyleIssues and
252 code not in self.__noFixCodesList 263 not result["autofixing"] and
264 result["code"] not in self.__noFixCodesList
253 ): 265 ):
254 itm.setIcon(0, UI.PixmapCache.getIcon("issueFixable")) 266 itm.setIcon(0, UI.PixmapCache.getIcon("issueFixable"))
255 fixable = True 267 fixable = True
256 268
257 itm.setTextAlignment(0, Qt.AlignRight) 269 itm.setTextAlignment(0, Qt.AlignRight)
260 itm.setTextAlignment(0, Qt.AlignVCenter) 272 itm.setTextAlignment(0, Qt.AlignVCenter)
261 itm.setTextAlignment(1, Qt.AlignVCenter) 273 itm.setTextAlignment(1, Qt.AlignVCenter)
262 itm.setTextAlignment(2, Qt.AlignVCenter) 274 itm.setTextAlignment(2, Qt.AlignVCenter)
263 275
264 itm.setData(0, self.filenameRole, filename) 276 itm.setData(0, self.filenameRole, filename)
265 itm.setData(0, self.lineRole, int(line)) 277 itm.setData(0, self.lineRole, int(result["line"]))
266 itm.setData(0, self.positionRole, int(pos)) 278 itm.setData(0, self.positionRole, int(result["offset"]))
267 itm.setData(0, self.messageRole, message) 279 itm.setData(0, self.messageRole, result["display"])
268 itm.setData(0, self.fixableRole, fixable) 280 itm.setData(0, self.fixableRole, fixable)
269 itm.setData(0, self.codeRole, code) 281 itm.setData(0, self.codeRole, result["code"])
270 itm.setData(0, self.ignoredRole, ignored) 282 itm.setData(0, self.ignoredRole, result["ignored"])
271 283 itm.setData(0, self.argsRole, result["args"])
272 if ignored: 284
285 if result["ignored"]:
273 font = itm.font(0) 286 font = itm.font(0)
274 font.setItalic(True) 287 font.setItalic(True)
275 for col in range(itm.columnCount()): 288 for col in range(itm.columnCount()):
276 itm.setFont(col, font) 289 itm.setFont(col, font)
277 290
278 return itm 291 return itm
279 292
280 def __modifyFixedResultItem(self, itm, text, fixed): 293 def __modifyFixedResultItem(self, itm, result):
281 """ 294 """
282 Private method to modify a result list entry to show its 295 Private method to modify a result list entry to show its
283 positive fixed state. 296 positive fixed state.
284 297
285 @param itm reference to the item to modify 298 @param itm reference to the item to modify
286 @type QTreeWidgetItem 299 @type QTreeWidgetItem
287 @param text text to be appended 300 @param result dictionary containing check result data
288 @type str 301 @type dict
289 @param fixed flag indicating a fixed issue 302 """
290 @type bool 303 if result["fixed"]:
291 """ 304 itm.setText(2, result["display"])
292 if fixed:
293 code, message = text.split(None, 1)
294 itm.setText(2, message)
295 itm.setIcon(0, UI.PixmapCache.getIcon("issueFixed")) 305 itm.setIcon(0, UI.PixmapCache.getIcon("issueFixed"))
296 306
297 itm.setData(0, self.messageRole, message) 307 itm.setData(0, self.messageRole, result["display"])
298 else: 308 else:
299 itm.setIcon(0, QIcon()) 309 itm.setIcon(0, QIcon())
300 itm.setData(0, self.fixableRole, False) 310 itm.setData(0, self.fixableRole, False)
301 311
302 def __updateStatistics(self, statistics, fixer, ignoredErrors): 312 def __updateStatistics(self, statistics, fixer, ignoredErrors):
649 source, encoding = Utilities.readEncodedFile( 659 source, encoding = Utilities.readEncodedFile(
650 self.filename) 660 self.filename)
651 source = source.splitlines(True) 661 source = source.splitlines(True)
652 except (UnicodeError, IOError) as msg: 662 except (UnicodeError, IOError) as msg:
653 self.results = CodeStyleCheckerDialog.hasResults 663 self.results = CodeStyleCheckerDialog.hasResults
654 self.__createResultItem( 664 self.__createFileErrorItem(self.filename, str(msg))
655 self.filename, 1, 1,
656 self.tr("Error: {0}").format(str(msg))
657 .rstrip(), False, False, False)
658 self.progress += 1 665 self.progress += 1
659 # Continue with next file 666 # Continue with next file
660 self.check() 667 self.check()
661 return 668 return
662 if encoding.endswith( 669 if encoding.endswith(
700 source, encoding = Utilities.readEncodedFile( 707 source, encoding = Utilities.readEncodedFile(
701 filename) 708 filename)
702 source = source.splitlines(True) 709 source = source.splitlines(True)
703 except (UnicodeError, IOError) as msg: 710 except (UnicodeError, IOError) as msg:
704 self.results = CodeStyleCheckerDialog.hasResults 711 self.results = CodeStyleCheckerDialog.hasResults
705 self.__createResultItem( 712 self.__createFileErrorItem(filename, str(msg))
706 filename, 1, 1,
707 self.tr("Error: {0}").format(str(msg))
708 .rstrip(), False, False, False)
709 continue 713 continue
710 714
711 if encoding.endswith( 715 if encoding.endswith(
712 ('-selected', '-default', '-guessed', '-ignore')): 716 ('-selected', '-default', '-guessed', '-ignore')):
713 encoding = encoding.rsplit('-', 1)[0] 717 encoding = encoding.rsplit('-', 1)[0]
766 @type str 770 @type str
767 @param codeStyleCheckerStats stats of style and name check 771 @param codeStyleCheckerStats stats of style and name check
768 @type dict 772 @type dict
769 @param fixes number of applied fixes 773 @param fixes number of applied fixes
770 @type int 774 @type int
771 @param results tuple for each found violation of style (tuple of 775 @param results dictionary containing check result data
772 lineno, position, text, ignored, fixed, autofixing) 776 @type dict
773 @type tuplt of tuple of (int, int, str, bool, bool, bool)
774 """ 777 """
775 if self.__finished: 778 if self.__finished:
776 return 779 return
777 780
778 # Check if it's the requested file, otherwise ignore signal if not 781 # Check if it's the requested file, otherwise ignore signal if not
785 self.resultList.setSortingEnabled(False) 788 self.resultList.setSortingEnabled(False)
786 789
787 fixed = None 790 fixed = None
788 ignoredErrors = 0 791 ignoredErrors = 0
789 if self.__itms: 792 if self.__itms:
790 for itm, (_lineno, _position, text, _ignored, fixed, 793 for itm, result in zip(self.__itms, results):
791 _autofixing) in zip(self.__itms, results): 794 self.__modifyFixedResultItem(itm, result)
792 self.__modifyFixedResultItem(itm, text, fixed)
793 self.__updateFixerStatistics(fixes) 795 self.__updateFixerStatistics(fixes)
794 else: 796 else:
795 self.__lastFileItem = None 797 self.__lastFileItem = None
796 798
797 for lineno, position, text, ignored, fixed, autofixing in results: 799 for result in results:
798 if ignored: 800 if result["ignored"]:
799 ignoredErrors += 1 801 ignoredErrors += 1
800 if self.showIgnored: 802 if self.showIgnored:
801 text = self.tr("{0} (ignored)").format(text) 803 result["display"] = self.tr(
804 "{0} (ignored)"
805 ).format(result["display"])
802 else: 806 else:
803 continue 807 continue
804 self.results = CodeStyleCheckerDialog.hasResults 808 self.results = CodeStyleCheckerDialog.hasResults
805 self.__createResultItem( 809 self.__createResultItem(fn, result)
806 fn, lineno, position, text, fixed, autofixing, ignored)
807 810
808 self.__updateStatistics( 811 self.__updateStatistics(
809 codeStyleCheckerStats, fixes, ignoredErrors) 812 codeStyleCheckerStats, fixes, ignoredErrors)
810 813
811 if fixed: 814 if fixed:
1321 for itm in fixableItems: 1324 for itm in fixableItems:
1322 filename = itm.data(0, self.filenameRole) 1325 filename = itm.data(0, self.filenameRole)
1323 if filename not in fixesDict: 1326 if filename not in fixesDict:
1324 fixesDict[filename] = [] 1327 fixesDict[filename] = []
1325 fixesDict[filename].append(( 1328 fixesDict[filename].append((
1326 (filename, itm.data(0, self.lineRole), 1329 {
1327 itm.data(0, self.positionRole), 1330 "file": filename,
1328 "{0} {1}".format(itm.data(0, self.codeRole), 1331 "line": itm.data(0, self.lineRole),
1329 itm.data(0, self.messageRole))), 1332 "offset": itm.data(0, self.positionRole),
1333 "code": itm.data(0, self.codeRole),
1334 "display": itm.data(0, self.messageRole),
1335 "args": itm.data(0, self.argsRole),
1336 },
1330 itm 1337 itm
1331 )) 1338 ))
1332 1339
1333 # update the configuration values (3: fixCodes, 4: noFixCodes, 1340 # update the configuration values (3: fixCodes, 4: noFixCodes,
1334 # 5: fixIssues, 6: maxLineLength) 1341 # 5: fixIssues, 6: maxLineLength)

eric ide

mercurial