VultureChecker/VultureCheckerDialog.py

changeset 55
7925ae5c9f17
parent 53
4eb2ec8fff7c
child 60
31b4426c9502
equal deleted inserted replaced
54:2194921f5e22 55:7925ae5c9f17
28 from E5Gui.E5Application import e5App 28 from E5Gui.E5Application import e5App
29 29
30 import Preferences 30 import Preferences
31 import Utilities 31 import Utilities
32 32
33 from .vulture import Item 33
34 class VultureItem(object):
35 """
36 Class to hold the name, type, confidence and location of defined code.
37 """
38 def __init__(self, name, typ, filename, firstLineno, lastLineno,
39 confidence):
40 """
41 Constructor
42
43 @param name item name
44 @type str
45 @param typ item type
46 @type str
47 @param filename name of the file containing item
48 @type str
49 @param firstLineno first line number
50 @type int
51 @param lastLineno last line number
52 @type int
53 @param confidence confidence level
54 @type int
55 """
56 self.name = name
57 self.typ = typ
58 self.filename = filename
59 self.first_lineno = firstLineno
60 self.last_lineno = lastLineno
61 self.confidence = confidence
34 62
35 63
36 class VultureCheckerDialog(QDialog, Ui_VultureCheckerDialog): 64 class VultureCheckerDialog(QDialog, Ui_VultureCheckerDialog):
37 """ 65 """
38 Class implementing a dialog to show the vulture check results. 66 Class implementing a dialog to show the vulture check results.
93 "function": self.tr("Function"), 121 "function": self.tr("Function"),
94 "slot": self.tr("Slot"), 122 "slot": self.tr("Slot"),
95 "attribute": self.tr("Attribute"), 123 "attribute": self.tr("Attribute"),
96 "variable": self.tr("Variable"), 124 "variable": self.tr("Variable"),
97 "class": self.tr("Class"), 125 "class": self.tr("Class"),
126 "import": self.tr("Import"),
98 } 127 }
99 128
100 def __createErrorItem(self, filename, message): 129 def __createErrorItem(self, filename, message):
101 """ 130 """
102 Private slot to create a new error item in the result list. 131 Private slot to create a new error item in the result list.
149 "function": [], 178 "function": [],
150 "slot": [], 179 "slot": [],
151 "attribute": [], 180 "attribute": [],
152 "variable": [], 181 "variable": [],
153 "class": [], 182 "class": [],
183 "import": [],
154 "__patterns__": [ 184 "__patterns__": [
155 "on_*", 185 "on_*",
156 "visit_*", 186 "visit_*",
157 ], 187 ],
158 } 188 }
189 if "import" not in self.__data["WhiteLists"]:
190 self.__data["WhiteLists"]["import"] = []
159 if "SlotsAreUsed" not in self.__data: 191 if "SlotsAreUsed" not in self.__data:
160 self.__data["SlotsAreUsed"] = True 192 self.__data["SlotsAreUsed"] = True
161 193
162 self.excludeFilesEdit.setText(self.__data["ExcludeFiles"]) 194 self.excludeFilesEdit.setText(self.__data["ExcludeFiles"])
163 self.slotsCheckBox.setChecked(self.__data["SlotsAreUsed"]) 195 self.slotsCheckBox.setChecked(self.__data["SlotsAreUsed"])
168 200
169 @param fn file or list of files or directory to show 201 @param fn file or list of files or directory to show
170 the code metrics for 202 the code metrics for
171 @type str or list of str 203 @type str or list of str
172 """ 204 """
205 self.cancelled = False
173 self.__errorItem = None 206 self.__errorItem = None
174 self.resultList.clear() 207 self.resultList.clear()
175 self.cancelled = False
176 QApplication.processEvents() 208 QApplication.processEvents()
177 209
178 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) 210 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
179 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) 211 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True)
180 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) 212 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
216 self.vultureCheck() 248 self.vultureCheck()
217 else: 249 else:
218 self.__batch = True 250 self.__batch = True
219 self.vultureCheckBatch() 251 self.vultureCheckBatch()
220 252
221 def vultureCheck(self, codestring=''): 253 def vultureCheck(self):
222 """ 254 """
223 Public method to start a vulture check for one Python file. 255 Public method to start a vulture check for one Python file.
224 256
225 The results are reported to the __processResult slot. 257 The results are reported to the __processResult slot.
226
227 @keyparam codestring optional sourcestring
228 @type str
229 """ 258 """
230 if not self.files: 259 if not self.files:
231 self.checkProgressLabel.setPath("") 260 self.checkProgressLabel.setPath("")
232 self.checkProgress.setMaximum(1) 261 self.checkProgress.setMaximum(1)
233 self.checkProgress.setValue(1) 262 self.checkProgress.setValue(1)
308 """ 337 """
309 self.__createErrorItem(fn, msg) 338 self.__createErrorItem(fn, msg)
310 339
311 def __processResult(self, fn, result): 340 def __processResult(self, fn, result):
312 """ 341 """
313 Private slot called after perfoming a vulture analysis on one file. 342 Private slot called after performing a vulture analysis on one file.
314 343
315 @param fn filename of the file 344 @param fn filename of the file
316 @type str 345 @type str
317 @param result result dict 346 @param result result dict
318 @type dict 347 @type dict
341 if not self.__batch: 370 if not self.__batch:
342 self.vultureCheck() 371 self.vultureCheck()
343 372
344 def __finish(self): 373 def __finish(self):
345 """ 374 """
346 Private slot called when the action or the user pressed the button. 375 Private slot called when the action finished or the user pressed the
376 cancel button.
347 """ 377 """
348 if not self.__finished: 378 if not self.__finished:
349 self.__finished = True 379 self.__finished = True
350 380
351 if not self.cancelled: 381 if not self.cancelled:
370 else: 400 else:
371 self.resultList.header().setResizeMode(QHeaderView.Interactive) 401 self.resultList.header().setResizeMode(QHeaderView.Interactive)
372 402
373 self.checkProgress.setVisible(False) 403 self.checkProgress.setVisible(False)
374 self.checkProgressLabel.setVisible(False) 404 self.checkProgressLabel.setVisible(False)
405
406 if self.resultList.topLevelItemCount() == 0:
407 itm = QTreeWidgetItem(self.resultList,
408 [self.tr("No unused code found.")])
409 itm.setFirstColumnSpanned(True)
375 410
376 @pyqtSlot(QAbstractButton) 411 @pyqtSlot(QAbstractButton)
377 def on_buttonBox_clicked(self, button): 412 def on_buttonBox_clicked(self, button):
378 """ 413 """
379 Private slot called by a button of the button box clicked. 414 Private slot called by a button of the button box clicked.
447 def __prepareResultLists(self): 482 def __prepareResultLists(self):
448 """ 483 """
449 Private method to prepare the result lists. 484 Private method to prepare the result lists.
450 """ 485 """
451 self.__definedAttrs = [] 486 self.__definedAttrs = []
487 self.__definedClasses = []
452 self.__definedFuncs = [] 488 self.__definedFuncs = []
489 self.__definedImports = []
453 self.__definedSlots = [] 490 self.__definedSlots = []
454 self.__definedProps = [] 491 self.__definedProps = []
455 self.__definedVars = [] 492 self.__definedVars = []
493
456 self.__usedAttrs = [] 494 self.__usedAttrs = []
457 self.__usedVars = [] 495 self.__usedNames = []
458 self.__tupleAssignVars = []
459 self.__namesImportedAsAliases = []
460 496
461 def __storeResult(self, result): 497 def __storeResult(self, result):
462 """ 498 """
463 Private method to store the result of an analysis. 499 Private method to store the result of an analysis.
464 500
465 @param result result dictionary 501 @param result result dictionary
466 @type dict 502 @type dict
467 """ 503 """
468 self.__definedAttrs.extend(self.__filteredList( 504 self.__definedAttrs.extend(self.__filteredList(
469 [self.__dict2Item(d) for d in result["DefinedAttributes"]])) 505 [self.__dict2Item(d) for d in result["DefinedAttributes"]]))
506 self.__definedClasses.extend(self.__filteredList(
507 [self.__dict2Item(d) for d in result["DefinedClasses"]]))
470 self.__definedFuncs.extend(self.__filteredList( 508 self.__definedFuncs.extend(self.__filteredList(
471 [self.__dict2Item(d) for d in result["DefinedFunctions"]])) 509 [self.__dict2Item(d) for d in result["DefinedFunctions"]]))
510 self.__definedImports.extend(self.__filteredList(
511 [self.__dict2Item(d) for d in result["DefinedImports"]]))
472 self.__definedSlots.extend(self.__filteredList( 512 self.__definedSlots.extend(self.__filteredList(
473 [self.__dict2Item(d) for d in result["DefinedSlots"]])) 513 [self.__dict2Item(d) for d in result["DefinedSlots"]]))
474 self.__definedProps.extend(self.__filteredList( 514 self.__definedProps.extend(self.__filteredList(
475 [self.__dict2Item(d) for d in result["DefinedProperties"]])) 515 [self.__dict2Item(d) for d in result["DefinedProperties"]]))
476 self.__definedVars.extend(self.__filteredList( 516 self.__definedVars.extend(self.__filteredList(
477 [self.__dict2Item(d) for d in result["DefinedVariables"]])) 517 [self.__dict2Item(d) for d in result["DefinedVariables"]]))
478 self.__usedAttrs.extend( 518 self.__usedAttrs.extend(result["UsedAttributes"])
479 [self.__dict2Item(d) for d in result["UsedAttributes"]]) 519 self.__usedNames.extend(result["UsedNames"])
480 self.__usedVars.extend(
481 [self.__dict2Item(d) for d in result["UsedVariables"]])
482 self.__tupleAssignVars.extend(
483 [self.__dict2Item(d) for d in result["TupleVariables"]])
484 self.__namesImportedAsAliases.extend(
485 [self.__dict2Item(d) for d in result["Aliases"]])
486 520
487 def __dict2Item(self, d): 521 def __dict2Item(self, d):
488 """ 522 """
489 Private method to convert an item dictionary to a vulture item. 523 Private method to convert an item dictionary to a vulture item.
490 524
491 @param d item dictionary 525 @param d item dictionary
492 @type dict 526 @type dict
493 @return vulture item 527 @return vulture item
494 @rtype vulture.Item 528 @rtype VultureItem
495 """ 529 """
496 return Item(d["name"], d["type"], d["file"], d["line"]) 530 return VultureItem(d["name"], d["type"], d["file"], d["first_line"],
531 d["last_line"], confidence=d["confidence"])
497 532
498 def __filteredList(self, itemList): 533 def __filteredList(self, itemList):
499 """ 534 """
500 Private method to filter a list against the whitelist patterns 535 Private method to filter a list against the whitelist patterns
501 returning items not matching the whitelist. 536 returning items not matching the whitelist.
502 537
503 @param itemList list of items to be filtered 538 @param itemList list of items to be filtered
504 @type list of vulture.Item 539 @type list of VultureItem
505 @return list of filtered items 540 @return list of filtered items
506 @rtype list of vulture.Item 541 @rtype list of VultureItem
507 """ 542 """
508 filteredList = itemList 543 filteredList = itemList
509 for pattern in self.__data["WhiteLists"]["__patterns__"]: 544 for pattern in self.__data["WhiteLists"]["__patterns__"]:
510 regExp = QRegExp(pattern, Qt.CaseSensitive, QRegExp.Wildcard) 545 regExp = QRegExp(pattern, Qt.CaseSensitive, QRegExp.Wildcard)
511 filteredList = [name for name in filteredList 546 filteredList = [item for item in filteredList
512 if not regExp.exactMatch(name)] 547 if not regExp.exactMatch(item.name)]
513 return filteredList 548 return filteredList
514 549
515 def __getUnusedItems(self, defined, used): 550 def __getUnusedItems(self, defined, used):
516 """ 551 """
517 Private method to get a list of unused items. 552 Private method to get a list of unused items.
518 553
519 @param defined list of defined items 554 @param defined list of defined items
520 @type list of vulture.Item 555 @type list of VultureItem
521 @param used list of used items 556 @param used list of used names
522 @type list of vulture.Item 557 @type list of str
523 @return list of unused items 558 @return list of unused items
524 @rtype list of vulture.Item 559 @rtype list of VultureItem
525 """ 560 """
526 return list(set(defined) - set(used)) 561 unusedItems = [item for item in set(defined)
562 if item.name not in used]
563 return unusedItems
527 564
528 def __unusedFunctions(self): 565 def __unusedFunctions(self):
529 """ 566 """
530 Private method to get the list of unused functions. 567 Private method to get the list of unused functions.
531 568
532 @return list of unused functions 569 @return list of unused functions
533 @rtype list of vulture.Item 570 @rtype list of VultureItem
534 """ 571 """
535 return self.__getUnusedItems( 572 return self.__getUnusedItems(
536 self.__definedFuncs, 573 self.__definedFuncs,
537 self.__usedAttrs + self.__usedVars + 574 self.__usedAttrs + self.__usedNames +
538 self.__namesImportedAsAliases + 575 self.__data["WhiteLists"]["function"]
539 self.__data["WhiteLists"]["function"] + 576 )
540 self.__data["WhiteLists"]["class"])
541 577
542 def __unusedSlots(self): 578 def __unusedSlots(self):
543 """ 579 """
544 Private method to get the list of unused PyQt slots. 580 Private method to get the list of unused PyQt/PySide slots.
545 581
546 @return list of unused PyQt slots 582 @return list of unused PyQt/PySide slots
547 @rtype list of vulture.Item 583 @rtype list of VultureItem
548 """ 584 """
549 return self.__getUnusedItems( 585 return self.__getUnusedItems(
550 self.__definedSlots, 586 self.__definedSlots,
551 self.__usedAttrs + self.__usedVars + 587 self.__usedAttrs + self.__usedNames +
552 self.__namesImportedAsAliases + 588 self.__data["WhiteLists"]["slot"]
553 self.__data["WhiteLists"]["slot"]) 589 )
554 590
591 def __unusedClasses(self):
592 """
593 Private method to get the list of unused classes.
594
595 @return list of unused classes
596 @rtype list of VultureItem
597 """
598 return self.__getUnusedItems(
599 self.__definedClasses,
600 self.__usedAttrs + self.__usedNames +
601 self.__data["WhiteLists"]["class"]
602 )
603
604 def __unusedImports(self):
605 """
606 Private method to get a list of unused imports.
607
608 @return list of unused imports
609 @rtype list of VultureItem
610 """
611 return self.__getUnusedItems(
612 self.__definedClasses,
613 self.__usedAttrs + self.__usedNames +
614 self.__data["WhiteLists"]["import"]
615 )
616
555 def __unusedProperties(self): 617 def __unusedProperties(self):
556 """ 618 """
557 Private method to get the list of unused properties. 619 Private method to get the list of unused properties.
558 620
559 @return list of unused properties 621 @return list of unused properties
560 @rtype list of vulture.Item 622 @rtype list of VultureItem
561 """ 623 """
562 return self.__getUnusedItems( 624 return self.__getUnusedItems(
563 self.__definedProps, 625 self.__definedProps,
564 self.__usedAttrs + self.__data["WhiteLists"]["property"]) 626 self.__usedAttrs +
627 self.__data["WhiteLists"]["property"]
628 )
565 629
566 def __unusedVariables(self): 630 def __unusedVariables(self):
567 """ 631 """
568 Private method to get the list of unused variables. 632 Private method to get the list of unused variables.
569 633
570 @return list of unused variables 634 @return list of unused variables
571 @rtype list of vulture.Item 635 @rtype list of VultureItem
572 """ 636 """
573 return self.__getUnusedItems( 637 return self.__getUnusedItems(
574 self.__definedVars, 638 self.__definedVars,
575 self.__usedAttrs + self.__usedVars + self.__tupleAssignVars + 639 self.__usedAttrs + self.__usedNames +
576 self.__namesImportedAsAliases + 640 self.__data["WhiteLists"]["variable"]
577 self.__data["WhiteLists"]["variable"]) 641 )
578 642
579 def __unusedAttributes(self): 643 def __unusedAttributes(self):
580 """ 644 """
581 Private method to get the list of unused attributes. 645 Private method to get the list of unused attributes.
582 646
583 @return list of unused attributes 647 @return list of unused attributes
584 @rtype list of vulture.Item 648 @rtype list of VultureItem
585 """ 649 """
586 return self.__getUnusedItems( 650 return self.__getUnusedItems(
587 self.__definedAttrs, 651 self.__definedAttrs,
588 self.__usedAttrs + self.__usedVars + 652 self.__usedAttrs +
589 self.__data["WhiteLists"]["attribute"]) 653 self.__data["WhiteLists"]["attribute"]
654 )
590 655
591 def __createResultItems(self): 656 def __createResultItems(self):
592 """ 657 """
593 Private method to populate the list with the analysis result. 658 Private method to populate the list with the analysis result.
594 """ # __IGNORE_WARNING__ 659 """ # __IGNORE_WARNING__
596 return item.filename 661 return item.filename
597 662
598 lastFileItem = None 663 lastFileItem = None
599 lastFileName = "" 664 lastFileName = ""
600 items = (self.__unusedFunctions() + 665 items = (self.__unusedFunctions() +
666 self.__unusedClasses() +
667 self.__unusedImports() +
601 self.__unusedProperties() + 668 self.__unusedProperties() +
602 self.__unusedVariables() + 669 self.__unusedVariables() +
603 self.__unusedAttributes()) 670 self.__unusedAttributes())
604 if not self.__slotsAreUsed: 671 if not self.__slotsAreUsed:
605 items += self.__unusedSlots() 672 items += self.__unusedSlots()
615 Private method to create a result item. 682 Private method to create a result item.
616 683
617 @param parent reference to the parent item 684 @param parent reference to the parent item
618 @type QTreeWidgetItem 685 @type QTreeWidgetItem
619 @param item reference to the item 686 @param item reference to the item
620 @type vulture.Item 687 @type VultureItem
621 """ 688 """
622 try: 689 try:
623 translatedType = self.__translatedTypes[item.typ] 690 translatedType = self.__translatedTypes[item.typ]
624 except KeyError: 691 except KeyError:
625 translatedType = item.typ 692 translatedType = item.typ
626 itm = QTreeWidgetItem(parent, [ 693 itm = QTreeWidgetItem(parent, [
627 "{0:6d}".format(item.lineno), str(item), translatedType]) 694 "{0:6d}".format(item.first_lineno), item.name,
695 "{0:3d}%".format(item.confidence), translatedType])
628 itm.setData(0, self.FilePathRole, item.filename) 696 itm.setData(0, self.FilePathRole, item.filename)
629 itm.setData(0, self.TypeRole, item.typ) 697 itm.setData(0, self.TypeRole, item.typ)
630 itm.setTextAlignment(0, Qt.Alignment(Qt.AlignRight)) 698 itm.setTextAlignment(0, Qt.Alignment(Qt.AlignRight)) # line no
699 itm.setTextAlignment(2, Qt.Alignment(Qt.AlignRight)) # confidence
631 700
632 def __createFileItem(self, filename): 701 def __createFileItem(self, filename):
633 """ 702 """
634 Private method to create a file item. 703 Private method to create a file item.
635 704

eric ide

mercurial