compilerplugins/clang/unusedmethods.cxx |   15 ++++++++++++++
 compilerplugins/clang/unusedmethods.py  |   33 ++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)

New commits:
commit 4cc7ebcca3d5fa33556fbc2666d8c63ae30a3424
Author: Noel Grandin <noel.gran...@collabora.co.uk>
Date:   Fri Nov 10 11:33:41 2017 +0200

    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/44588
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    Tested-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/compilerplugins/clang/unusedmethods.cxx 
b/compilerplugins/clang/unusedmethods.cxx
index 3b7b4cb2a5fb..ef681f12c561 100644
--- a/compilerplugins/clang/unusedmethods.cxx
+++ b/compilerplugins/clang/unusedmethods.cxx
@@ -114,11 +114,13 @@ public:
     bool VisitFunctionDecl( const FunctionDecl* decl );
     bool VisitDeclRefExpr( const DeclRefExpr* );
     bool VisitCXXConstructExpr( const CXXConstructExpr* );
+    bool TraverseCXXRecordDecl( CXXRecordDecl* );
 private:
     void logCallToRootMethods(const FunctionDecl* functionDecl, 
std::set<MyFuncInfo>& funcSet);
     MyFuncInfo niceName(const FunctionDecl* functionDecl);
     std::string toString(SourceLocation loc);
     void functionTouchedFromExpr( const FunctionDecl* calleeFunctionDecl, 
const Expr* expr );
+    CXXRecordDecl const * currentCxxRecordDecl = nullptr;
 };
 
 MyFuncInfo UnusedMethods::niceName(const FunctionDecl* functionDecl)
@@ -281,6 +283,10 @@ bool UnusedMethods::VisitCXXConstructExpr( const 
CXXConstructExpr* constructExpr
 
     logCallToRootMethods(constructorDecl, callSet);
 
+    // Now do the checks necessary for the "can be private" analysis
+    if (constructorDecl->getParent() != currentCxxRecordDecl)
+        calledFromOutsideSet.insert(niceName(constructorDecl));
+
     return true;
 }
 
@@ -341,6 +347,15 @@ bool UnusedMethods::VisitDeclRefExpr( const DeclRefExpr* 
declRefExpr )
     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);
 
 }
diff --git a/compilerplugins/clang/unusedmethods.py 
b/compilerplugins/clang/unusedmethods.py
index aaa19abfc8e2..811eca65cae4 100755
--- a/compilerplugins/clang/unusedmethods.py
+++ b/compilerplugins/clang/unusedmethods.py
@@ -16,6 +16,7 @@ callSet = set() # set of tuple(return_type, name_and_params)
 
 # for the "method can be private" analysis
 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)
 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:
             definitionSet.add(funcInfo)
             if access == "public":
                 publicDefinitionSet.add(funcInfo)
+            elif access == "protected":
+                protectedDefinitionSet.add(funcInfo)
             definitionToSourceLocationMap[funcInfo] = sourceLocation
             if virtual == "virtual":
                 virtualSet.add(funcInfo)
@@ -275,3 +278,33 @@ with open("loplugin.unusedmethods.report-can-be-private", 
"wt") as f:
         f.write(t[1] + "\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")
+
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to