diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2016-11-17 08:39:50 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2016-11-17 08:40:27 +0200 |
commit | 2f7ccd102a6280750ce920e4c4eab66f9a01b9d3 (patch) | |
tree | f1e384c6b76b8fd9846db630ee58cdf6c9085482 /compilerplugins/clang/unusedfields.py | |
parent | 234325b9fc0d54e594de8e5d2e7c717684db1745 (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-x | compilerplugins/clang/unusedfields.py | 97 |
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" ) |