summaryrefslogtreecommitdiff
path: root/compilerplugins/clang/unusedfields.py
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2016-11-17 08:39:50 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2016-11-17 08:40:27 +0200
commit2f7ccd102a6280750ce920e4c4eab66f9a01b9d3 (patch)
treef1e384c6b76b8fd9846db630ee58cdf6c9085482 /compilerplugins/clang/unusedfields.py
parent234325b9fc0d54e594de8e5d2e7c717684db1745 (diff)
extend unusedfields loplugin to find fields that can be private
and apply the results in xmlscript Change-Id: Ib126f6e1576639abfd171e99d9561be9715ece2f
Diffstat (limited to 'compilerplugins/clang/unusedfields.py')
-rwxr-xr-xcompilerplugins/clang/unusedfields.py97
1 files changed, 46 insertions, 51 deletions
diff --git a/compilerplugins/clang/unusedfields.py b/compilerplugins/clang/unusedfields.py
index 785b7a9a1881..7bf910f62d80 100755
--- a/compilerplugins/clang/unusedfields.py
+++ b/compilerplugins/clang/unusedfields.py
@@ -5,11 +5,13 @@ import re
import io
definitionSet = set()
+protectedAndPublicDefinitionSet = set() # set of tuple(type, name)
definitionToSourceLocationMap = dict()
definitionToTypeMap = dict()
callSet = set()
readFromSet = set()
sourceLocationSet = set()
+touchedFromOutsideSet = set()
# clang does not always use exactly the same numbers in the type-parameter vars it generates
# so I need to substitute them to ensure we can match correctly.
@@ -17,30 +19,43 @@ normalizeTypeParamsRegex = re.compile(r"type-parameter-\d+-\d+")
def normalizeTypeParams( line ):
return normalizeTypeParamsRegex.sub("type-parameter-?-?", line)
+def parseFieldInfo( tokens ):
+ if len(tokens) == 3:
+ return (normalizeTypeParams(tokens[1]), tokens[2])
+ else:
+ return (normalizeTypeParams(tokens[1]), "")
+
# The parsing here is designed to avoid grabbing stuff which is mixed in from gbuild.
# I have not yet found a way of suppressing the gbuild output.
with io.open("loplugin.unusedfields.log", "rb", buffering=1024*1024) as txt:
for line in txt:
tokens = line.strip().split("\t")
if tokens[0] == "definition:":
- fieldInfo = (normalizeTypeParams(tokens[1]), tokens[2])
+ access = tokens[1]
+ fieldInfo = (normalizeTypeParams(tokens[2]), tokens[3])
+ srcLoc = tokens[5]
+ # ignore external source code
+ if (srcLoc.startswith("external/")):
+ continue
+ # ignore build folder
+ if (srcLoc.startswith("workdir/")):
+ continue
definitionSet.add(fieldInfo)
- definitionToTypeMap[fieldInfo] = tokens[3]
- definitionToSourceLocationMap[fieldInfo] = tokens[4]
+ definitionToTypeMap[fieldInfo] = tokens[4]
+ if access == "protected" or access == "public":
+ protectedAndPublicDefinitionSet.add(fieldInfo)
+ definitionToSourceLocationMap[fieldInfo] = tokens[5]
elif tokens[0] == "touch:":
- if len(tokens) == 3:
- callInfo = (normalizeTypeParams(tokens[1]), tokens[2])
- callSet.add(callInfo)
- else:
- callInfo = (normalizeTypeParams(tokens[1]), "")
- callSet.add(callInfo)
+ callSet.add(parseFieldInfo(tokens))
+ elif tokens[0] == "read:":
+ readFromSet.add(parseFieldInfo(tokens))
elif tokens[0] == "read:":
- if len(tokens) == 3:
- readInfo = (normalizeTypeParams(tokens[1]), tokens[2])
- readFromSet.add(readInfo)
- else:
- readInfo = (normalizeTypeParams(tokens[1]), "")
- readFromSet.add(readInfo)
+ readFromSet.add(parseFieldInfo(tokens))
+ elif tokens[0] == "outside:":
+ touchedFromOutsideSet.add(parseFieldInfo(tokens))
+ else:
+ print( "unknown line: " + line)
+
# Invert the definitionToSourceLocationMap
# If we see more than one method at the same sourceLocation, it's being autogenerated as part of a template
# and we should just ignore
@@ -58,24 +73,6 @@ for d in definitionSet:
if d in callSet:
continue
srcLoc = definitionToSourceLocationMap[d];
- # ignore external source code
- if (srcLoc.startswith("external/")):
- continue
- # ignore build folder
- if (srcLoc.startswith("workdir/")):
- continue
- # ignore our stable/URE/UNO api
- if (srcLoc.startswith("include/com/")
- or srcLoc.startswith("include/cppu/")
- or srcLoc.startswith("include/cppuhelper/")
- or srcLoc.startswith("include/osl/")
- or srcLoc.startswith("include/rtl/")
- or srcLoc.startswith("include/sal/")
- or srcLoc.startswith("include/salhelper/")
- or srcLoc.startswith("include/systools/")
- or srcLoc.startswith("include/typelib/")
- or srcLoc.startswith("include/uno/")):
- continue
# this is all representations of on-disk data structures
if (srcLoc.startswith("sc/source/filter/inc/scflt.hxx")
or srcLoc.startswith("sw/source/filter/ww8/")
@@ -108,24 +105,6 @@ for d in definitionSet:
if d in readFromSet:
continue
srcLoc = definitionToSourceLocationMap[d];
- # ignore external source code
- if (srcLoc.startswith("external/")):
- continue
- # ignore build folder
- if (srcLoc.startswith("workdir/")):
- continue
- # ignore our stable/URE/UNO api
- if (srcLoc.startswith("include/com/")
- or srcLoc.startswith("include/cppu/")
- or srcLoc.startswith("include/cppuhelper/")
- or srcLoc.startswith("include/osl/")
- or srcLoc.startswith("include/rtl/")
- or srcLoc.startswith("include/sal/")
- or srcLoc.startswith("include/salhelper/")
- or srcLoc.startswith("include/systools/")
- or srcLoc.startswith("include/typelib/")
- or srcLoc.startswith("include/uno/")):
- continue
# this is all representations of on-disk data structures
if (srcLoc.startswith("sc/source/filter/inc/scflt.hxx")
or srcLoc.startswith("sw/source/filter/ww8/")
@@ -140,6 +119,17 @@ for d in definitionSet:
writeonlySet.add((clazz + " " + definitionToTypeMap[d], srcLoc))
+
+canBePrivateSet = set()
+for d in protectedAndPublicDefinitionSet:
+ clazz = d[0] + " " + d[1]
+ if d in touchedFromOutsideSet:
+ continue
+ srcLoc = definitionToSourceLocationMap[d];
+
+ canBePrivateSet.add((clazz + " " + definitionToTypeMap[d], srcLoc))
+
+
# sort the results using a "natural order" so sequences like [item1,item2,item10] sort nicely
def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
return [int(text) if text.isdigit() else text.lower()
@@ -148,6 +138,7 @@ def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
# sort results by name and line number
tmp1list = sorted(untouchedSet, key=lambda v: natural_sort_key(v[1]))
tmp2list = sorted(writeonlySet, key=lambda v: natural_sort_key(v[1]))
+tmp3list = sorted(canBePrivateSet, key=lambda v: natural_sort_key(v[1]))
# print out the results
with open("loplugin.unusedfields.report-untouched", "wt") as f:
@@ -158,5 +149,9 @@ with open("loplugin.unusedfields.report-writeonly", "wt") as f:
for t in tmp2list:
f.write( t[1] + "\n" )
f.write( " " + t[0] + "\n" )
+with open("loplugin.unusedfields.report-can-be-private", "wt") as f:
+ for t in tmp3list:
+ f.write( t[1] + "\n" )
+ f.write( " " + t[0] + "\n" )