diff options
author | Noel Grandin <noel@peralex.com> | 2015-11-20 10:12:32 +0200 |
---|---|---|
committer | Noel Grandin <noel@peralex.com> | 2015-11-20 10:12:58 +0200 |
commit | 1d5c39192e81f950289dbdd7991a0e8a67c0aabc (patch) | |
tree | d4104b843ea7867ae24ad99d441e76ba18a433c0 /compilerplugins/clang/unusedfields.py | |
parent | d4857e30b1defde21895ece6b29c8c9829168a50 (diff) |
new loplugin:unusedfields
run it over the framework module
Change-Id: I1220a4be0936ba30136ce22ffd78633c8a7b9d35
Diffstat (limited to 'compilerplugins/clang/unusedfields.py')
-rwxr-xr-x | compilerplugins/clang/unusedfields.py | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/compilerplugins/clang/unusedfields.py b/compilerplugins/clang/unusedfields.py new file mode 100755 index 000000000000..bade9a8338ea --- /dev/null +++ b/compilerplugins/clang/unusedfields.py @@ -0,0 +1,79 @@ +#!/usr/bin/python + +import sys +import re +import io + +definitionSet = set() +definitionToSourceLocationMap = dict() +callSet = set() +sourceLocationSet = set() +# things we need to exclude for reasons like : +# - it's a weird template thingy that confuses the plugin +exclusionSet = 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. +normalizeTypeParamsRegex = re.compile(r"type-parameter-\d+-\d+") +def normalizeTypeParams( line ): + return normalizeTypeParamsRegex.sub("type-parameter-?-?", line) + +# 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(sys.argv[1], "rb", buffering=1024*1024) as txt: + for line in txt: + if line.startswith("definition:\t"): + idx1 = line.find("\t",12) + idx2 = line.find("\t",idx1+1) + funcInfo = (normalizeTypeParams(line[12:idx1]), normalizeTypeParams(line[idx1+1:idx2])) + definitionSet.add(funcInfo) + definitionToSourceLocationMap[funcInfo] = line[idx2+1:].strip() + elif line.startswith("touch:\t"): + idx1 = line.find("\t",7) + callInfo = (normalizeTypeParams(line[7:idx1]), normalizeTypeParams(line[idx1+1:].strip())) + callSet.add(callInfo) + +# 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 +sourceLocationToDefinitionMap = {} +for k, v in definitionToSourceLocationMap.iteritems(): + sourceLocationToDefinitionMap[v] = sourceLocationToDefinitionMap.get(v, []) + sourceLocationToDefinitionMap[v].append(k) +for k, definitions in sourceLocationToDefinitionMap.iteritems(): + if len(definitions) > 1: + for d in definitions: + definitionSet.remove(d) + +tmp1set = set() +for d in definitionSet: + clazz = d[0] + " " + d[1] + if clazz in exclusionSet: + continue + if d in callSet: + continue + if (definitionToSourceLocationMap[d].startswith("include/")): + continue + + tmp1set.add((clazz, definitionToSourceLocationMap[d])) + +# 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() + for text in re.split(_nsre, s)] + +# sort results by name and line number +tmp1list = sorted(tmp1set, key=lambda v: natural_sort_key(v[1])) + +# print out the results +for t in tmp1list: + print t[1] + print " ", t[0] + + + +# add an empty line at the end to make it easier for the unusedFieldsremove plugin to mmap() the output file +print + + |