Kaydet (Commit) 4cc7ebcc authored tarafından Noel Grandin's avatar Noel Grandin

loplugin:unusedmethods new analysis

look for classes containing protected methods where we can convert them
all to private

Change-Id: I4a448341943e0a613cde30501c4012da61dba713
Reviewed-on: https://gerrit.libreoffice.org/44588Reviewed-by: 's avatarNoel Grandin <noel.grandin@collabora.co.uk>
Tested-by: 's avatarNoel Grandin <noel.grandin@collabora.co.uk>
üst 42344398
...@@ -114,11 +114,13 @@ public: ...@@ -114,11 +114,13 @@ public:
bool VisitFunctionDecl( const FunctionDecl* decl ); bool VisitFunctionDecl( const FunctionDecl* decl );
bool VisitDeclRefExpr( const DeclRefExpr* ); bool VisitDeclRefExpr( const DeclRefExpr* );
bool VisitCXXConstructExpr( const CXXConstructExpr* ); bool VisitCXXConstructExpr( const CXXConstructExpr* );
bool TraverseCXXRecordDecl( CXXRecordDecl* );
private: private:
void logCallToRootMethods(const FunctionDecl* functionDecl, std::set<MyFuncInfo>& funcSet); void logCallToRootMethods(const FunctionDecl* functionDecl, std::set<MyFuncInfo>& funcSet);
MyFuncInfo niceName(const FunctionDecl* functionDecl); MyFuncInfo niceName(const FunctionDecl* functionDecl);
std::string toString(SourceLocation loc); std::string toString(SourceLocation loc);
void functionTouchedFromExpr( const FunctionDecl* calleeFunctionDecl, const Expr* expr ); void functionTouchedFromExpr( const FunctionDecl* calleeFunctionDecl, const Expr* expr );
CXXRecordDecl const * currentCxxRecordDecl = nullptr;
}; };
MyFuncInfo UnusedMethods::niceName(const FunctionDecl* functionDecl) MyFuncInfo UnusedMethods::niceName(const FunctionDecl* functionDecl)
...@@ -281,6 +283,10 @@ bool UnusedMethods::VisitCXXConstructExpr( const CXXConstructExpr* constructExpr ...@@ -281,6 +283,10 @@ bool UnusedMethods::VisitCXXConstructExpr( const CXXConstructExpr* constructExpr
logCallToRootMethods(constructorDecl, callSet); logCallToRootMethods(constructorDecl, callSet);
// Now do the checks necessary for the "can be private" analysis
if (constructorDecl->getParent() != currentCxxRecordDecl)
calledFromOutsideSet.insert(niceName(constructorDecl));
return true; return true;
} }
...@@ -341,6 +347,15 @@ bool UnusedMethods::VisitDeclRefExpr( const DeclRefExpr* declRefExpr ) ...@@ -341,6 +347,15 @@ bool UnusedMethods::VisitDeclRefExpr( const DeclRefExpr* declRefExpr )
return true; return true;
} }
bool UnusedMethods::TraverseCXXRecordDecl(CXXRecordDecl* cxxRecordDecl)
{
auto copy = currentCxxRecordDecl;
currentCxxRecordDecl = cxxRecordDecl;
bool ret = RecursiveASTVisitor::TraverseCXXRecordDecl(cxxRecordDecl);
currentCxxRecordDecl = copy;
return ret;
}
loplugin::Plugin::Registration< UnusedMethods > X("unusedmethods", false); loplugin::Plugin::Registration< UnusedMethods > X("unusedmethods", false);
} }
......
...@@ -16,6 +16,7 @@ callSet = set() # set of tuple(return_type, name_and_params) ...@@ -16,6 +16,7 @@ callSet = set() # set of tuple(return_type, name_and_params)
# for the "method can be private" analysis # for the "method can be private" analysis
publicDefinitionSet = set() # set of tuple(return_type, name_and_params) publicDefinitionSet = set() # set of tuple(return_type, name_and_params)
protectedDefinitionSet = set() # set of tuple(return_type, name_and_params)
calledFromOutsideSet = set() # set of tuple(return_type, name_and_params) calledFromOutsideSet = set() # set of tuple(return_type, name_and_params)
virtualSet = set() # set of tuple(return_type, name_and_params) virtualSet = set() # set of tuple(return_type, name_and_params)
...@@ -46,6 +47,8 @@ with io.open("loplugin.unusedmethods.log", "rb", buffering=1024*1024) as txt: ...@@ -46,6 +47,8 @@ with io.open("loplugin.unusedmethods.log", "rb", buffering=1024*1024) as txt:
definitionSet.add(funcInfo) definitionSet.add(funcInfo)
if access == "public": if access == "public":
publicDefinitionSet.add(funcInfo) publicDefinitionSet.add(funcInfo)
elif access == "protected":
protectedDefinitionSet.add(funcInfo)
definitionToSourceLocationMap[funcInfo] = sourceLocation definitionToSourceLocationMap[funcInfo] = sourceLocation
if virtual == "virtual": if virtual == "virtual":
virtualSet.add(funcInfo) virtualSet.add(funcInfo)
...@@ -275,3 +278,33 @@ with open("loplugin.unusedmethods.report-can-be-private", "wt") as f: ...@@ -275,3 +278,33 @@ with open("loplugin.unusedmethods.report-can-be-private", "wt") as f:
f.write(t[1] + "\n") f.write(t[1] + "\n")
f.write(" " + t[0] + "\n") f.write(" " + t[0] + "\n")
# --------------------------------------------------------------------------------------------
# "all protected methods in class can be made private" analysis
# --------------------------------------------------------------------------------------------
potentialClasses = set()
excludedClasses = set()
potentialClassesSourceLocationMap = dict()
matchClassName = re.compile(r"(\w+)::")
for d in protectedDefinitionSet:
m = matchClassName.match(d[1])
if not m: continue
clazz = m.group(1)
if d in calledFromOutsideSet:
excludedClasses.add(clazz)
else:
potentialClasses.add(clazz)
potentialClassesSourceLocationMap[clazz] = definitionToSourceLocationMap[d]
tmp4set = set()
for d in (potentialClasses - excludedClasses):
tmp4set.add((d, potentialClassesSourceLocationMap[d]))
# print output, sorted by name and line number
with open("loplugin.unusedmethods.report-all-protected-can-be-private", "wt") as f:
for t in sort_set_by_natural_key(tmp4set):
f.write(t[1] + "\n")
f.write(" " + t[0] + "\n")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment