diff -r 2194921f5e22 -r 7925ae5c9f17 VultureChecker/VultureCheckerDialog.py --- a/VultureChecker/VultureCheckerDialog.py Sat Mar 31 13:04:21 2018 +0200 +++ b/VultureChecker/VultureCheckerDialog.py Sun Nov 25 12:44:16 2018 +0100 @@ -30,7 +30,35 @@ import Preferences import Utilities -from .vulture import Item + +class VultureItem(object): + """ + Class to hold the name, type, confidence and location of defined code. + """ + def __init__(self, name, typ, filename, firstLineno, lastLineno, + confidence): + """ + Constructor + + @param name item name + @type str + @param typ item type + @type str + @param filename name of the file containing item + @type str + @param firstLineno first line number + @type int + @param lastLineno last line number + @type int + @param confidence confidence level + @type int + """ + self.name = name + self.typ = typ + self.filename = filename + self.first_lineno = firstLineno + self.last_lineno = lastLineno + self.confidence = confidence class VultureCheckerDialog(QDialog, Ui_VultureCheckerDialog): @@ -95,6 +123,7 @@ "attribute": self.tr("Attribute"), "variable": self.tr("Variable"), "class": self.tr("Class"), + "import": self.tr("Import"), } def __createErrorItem(self, filename, message): @@ -151,11 +180,14 @@ "attribute": [], "variable": [], "class": [], + "import": [], "__patterns__": [ "on_*", "visit_*", ], } + if "import" not in self.__data["WhiteLists"]: + self.__data["WhiteLists"]["import"] = [] if "SlotsAreUsed" not in self.__data: self.__data["SlotsAreUsed"] = True @@ -170,9 +202,9 @@ the code metrics for @type str or list of str """ + self.cancelled = False self.__errorItem = None self.resultList.clear() - self.cancelled = False QApplication.processEvents() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) @@ -218,14 +250,11 @@ self.__batch = True self.vultureCheckBatch() - def vultureCheck(self, codestring=''): + def vultureCheck(self): """ Public method to start a vulture check for one Python file. The results are reported to the __processResult slot. - - @keyparam codestring optional sourcestring - @type str """ if not self.files: self.checkProgressLabel.setPath("") @@ -310,7 +339,7 @@ def __processResult(self, fn, result): """ - Private slot called after perfoming a vulture analysis on one file. + Private slot called after performing a vulture analysis on one file. @param fn filename of the file @type str @@ -343,7 +372,8 @@ def __finish(self): """ - Private slot called when the action or the user pressed the button. + Private slot called when the action finished or the user pressed the + cancel button. """ if not self.__finished: self.__finished = True @@ -372,6 +402,11 @@ self.checkProgress.setVisible(False) self.checkProgressLabel.setVisible(False) + + if self.resultList.topLevelItemCount() == 0: + itm = QTreeWidgetItem(self.resultList, + [self.tr("No unused code found.")]) + itm.setFirstColumnSpanned(True) @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): @@ -449,14 +484,15 @@ Private method to prepare the result lists. """ self.__definedAttrs = [] + self.__definedClasses = [] self.__definedFuncs = [] + self.__definedImports = [] self.__definedSlots = [] self.__definedProps = [] self.__definedVars = [] + self.__usedAttrs = [] - self.__usedVars = [] - self.__tupleAssignVars = [] - self.__namesImportedAsAliases = [] + self.__usedNames = [] def __storeResult(self, result): """ @@ -467,22 +503,20 @@ """ self.__definedAttrs.extend(self.__filteredList( [self.__dict2Item(d) for d in result["DefinedAttributes"]])) + self.__definedClasses.extend(self.__filteredList( + [self.__dict2Item(d) for d in result["DefinedClasses"]])) self.__definedFuncs.extend(self.__filteredList( [self.__dict2Item(d) for d in result["DefinedFunctions"]])) + self.__definedImports.extend(self.__filteredList( + [self.__dict2Item(d) for d in result["DefinedImports"]])) self.__definedSlots.extend(self.__filteredList( [self.__dict2Item(d) for d in result["DefinedSlots"]])) self.__definedProps.extend(self.__filteredList( [self.__dict2Item(d) for d in result["DefinedProperties"]])) self.__definedVars.extend(self.__filteredList( [self.__dict2Item(d) for d in result["DefinedVariables"]])) - self.__usedAttrs.extend( - [self.__dict2Item(d) for d in result["UsedAttributes"]]) - self.__usedVars.extend( - [self.__dict2Item(d) for d in result["UsedVariables"]]) - self.__tupleAssignVars.extend( - [self.__dict2Item(d) for d in result["TupleVariables"]]) - self.__namesImportedAsAliases.extend( - [self.__dict2Item(d) for d in result["Aliases"]]) + self.__usedAttrs.extend(result["UsedAttributes"]) + self.__usedNames.extend(result["UsedNames"]) def __dict2Item(self, d): """ @@ -491,9 +525,10 @@ @param d item dictionary @type dict @return vulture item - @rtype vulture.Item + @rtype VultureItem """ - return Item(d["name"], d["type"], d["file"], d["line"]) + return VultureItem(d["name"], d["type"], d["file"], d["first_line"], + d["last_line"], confidence=d["confidence"]) def __filteredList(self, itemList): """ @@ -501,15 +536,15 @@ returning items not matching the whitelist. @param itemList list of items to be filtered - @type list of vulture.Item + @type list of VultureItem @return list of filtered items - @rtype list of vulture.Item + @rtype list of VultureItem """ filteredList = itemList for pattern in self.__data["WhiteLists"]["__patterns__"]: regExp = QRegExp(pattern, Qt.CaseSensitive, QRegExp.Wildcard) - filteredList = [name for name in filteredList - if not regExp.exactMatch(name)] + filteredList = [item for item in filteredList + if not regExp.exactMatch(item.name)] return filteredList def __getUnusedItems(self, defined, used): @@ -517,76 +552,106 @@ Private method to get a list of unused items. @param defined list of defined items - @type list of vulture.Item - @param used list of used items - @type list of vulture.Item + @type list of VultureItem + @param used list of used names + @type list of str @return list of unused items - @rtype list of vulture.Item + @rtype list of VultureItem """ - return list(set(defined) - set(used)) + unusedItems = [item for item in set(defined) + if item.name not in used] + return unusedItems def __unusedFunctions(self): """ Private method to get the list of unused functions. @return list of unused functions - @rtype list of vulture.Item + @rtype list of VultureItem """ return self.__getUnusedItems( self.__definedFuncs, - self.__usedAttrs + self.__usedVars + - self.__namesImportedAsAliases + - self.__data["WhiteLists"]["function"] + - self.__data["WhiteLists"]["class"]) + self.__usedAttrs + self.__usedNames + + self.__data["WhiteLists"]["function"] + ) def __unusedSlots(self): """ - Private method to get the list of unused PyQt slots. + Private method to get the list of unused PyQt/PySide slots. - @return list of unused PyQt slots - @rtype list of vulture.Item + @return list of unused PyQt/PySide slots + @rtype list of VultureItem """ return self.__getUnusedItems( self.__definedSlots, - self.__usedAttrs + self.__usedVars + - self.__namesImportedAsAliases + - self.__data["WhiteLists"]["slot"]) + self.__usedAttrs + self.__usedNames + + self.__data["WhiteLists"]["slot"] + ) + def __unusedClasses(self): + """ + Private method to get the list of unused classes. + + @return list of unused classes + @rtype list of VultureItem + """ + return self.__getUnusedItems( + self.__definedClasses, + self.__usedAttrs + self.__usedNames + + self.__data["WhiteLists"]["class"] + ) + + def __unusedImports(self): + """ + Private method to get a list of unused imports. + + @return list of unused imports + @rtype list of VultureItem + """ + return self.__getUnusedItems( + self.__definedClasses, + self.__usedAttrs + self.__usedNames + + self.__data["WhiteLists"]["import"] + ) + def __unusedProperties(self): """ Private method to get the list of unused properties. @return list of unused properties - @rtype list of vulture.Item + @rtype list of VultureItem """ return self.__getUnusedItems( self.__definedProps, - self.__usedAttrs + self.__data["WhiteLists"]["property"]) + self.__usedAttrs + + self.__data["WhiteLists"]["property"] + ) def __unusedVariables(self): """ Private method to get the list of unused variables. @return list of unused variables - @rtype list of vulture.Item + @rtype list of VultureItem """ return self.__getUnusedItems( self.__definedVars, - self.__usedAttrs + self.__usedVars + self.__tupleAssignVars + - self.__namesImportedAsAliases + - self.__data["WhiteLists"]["variable"]) + self.__usedAttrs + self.__usedNames + + self.__data["WhiteLists"]["variable"] + ) def __unusedAttributes(self): """ Private method to get the list of unused attributes. @return list of unused attributes - @rtype list of vulture.Item + @rtype list of VultureItem """ return self.__getUnusedItems( self.__definedAttrs, - self.__usedAttrs + self.__usedVars + - self.__data["WhiteLists"]["attribute"]) + self.__usedAttrs + + self.__data["WhiteLists"]["attribute"] + ) def __createResultItems(self): """ @@ -598,6 +663,8 @@ lastFileItem = None lastFileName = "" items = (self.__unusedFunctions() + + self.__unusedClasses() + + self.__unusedImports() + self.__unusedProperties() + self.__unusedVariables() + self.__unusedAttributes()) @@ -617,17 +684,19 @@ @param parent reference to the parent item @type QTreeWidgetItem @param item reference to the item - @type vulture.Item + @type VultureItem """ try: translatedType = self.__translatedTypes[item.typ] except KeyError: translatedType = item.typ itm = QTreeWidgetItem(parent, [ - "{0:6d}".format(item.lineno), str(item), translatedType]) + "{0:6d}".format(item.first_lineno), item.name, + "{0:3d}%".format(item.confidence), translatedType]) itm.setData(0, self.FilePathRole, item.filename) itm.setData(0, self.TypeRole, item.typ) - itm.setTextAlignment(0, Qt.Alignment(Qt.AlignRight)) + itm.setTextAlignment(0, Qt.Alignment(Qt.AlignRight)) # line no + itm.setTextAlignment(2, Qt.Alignment(Qt.AlignRight)) # confidence def __createFileItem(self, filename): """