Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / compilerplugins / clang / countusersofdefaultparams.py
blob06c38b9e480738f2f663538c93a8818995c47279
1 #!/usr/bin/python
3 import sys
4 import re
5 import io
7 definitionToSourceLocationMap = dict()
8 callDict = dict()
10 # clang does not always use exactly the same numbers in the type-parameter vars it generates
11 # so I need to substitute them to ensure we can match correctly.
12 normalizeTypeParamsRegex1 = re.compile(r"type-parameter-\d+-\d+")
13 normalizeTypeParamsRegex2 = re.compile(r"typename enable_if<.*")
14 def normalizeTypeParams( line ):
15 line = normalizeTypeParamsRegex1.sub("type-parameter-?-?", line)
16 return normalizeTypeParamsRegex2.sub("type-parameter-?-?", line)
18 with io.open("workdir/loplugin.countusersofdefaultparams.log", "rb", buffering=1024*1024) as txt:
19 for line in txt:
20 tokens = line.strip().split("\t")
21 if tokens[0] == "defn:":
22 access = tokens[1]
23 returnType = tokens[2]
24 nameAndParams = tokens[3]
25 sourceLocation = tokens[4]
26 funcInfo = normalizeTypeParams(returnType) + " " + normalizeTypeParams(nameAndParams)
27 definitionToSourceLocationMap[funcInfo] = sourceLocation
28 if not funcInfo in callDict:
29 callDict[funcInfo] = set()
30 elif tokens[0] == "call:":
31 returnType = tokens[1]
32 nameAndParams = tokens[2]
33 sourceLocationOfCall = tokens[3]
34 funcInfo = normalizeTypeParams(returnType) + " " + normalizeTypeParams(nameAndParams)
35 if not funcInfo in callDict:
36 callDict[funcInfo] = set()
37 callDict[funcInfo].add(sourceLocationOfCall)
39 # Invert the definitionToSourceLocationMap.
40 sourceLocationToDefinitionMap = {}
41 for k, v in definitionToSourceLocationMap.iteritems():
42 sourceLocationToDefinitionMap[v] = sourceLocationToDefinitionMap.get(v, [])
43 sourceLocationToDefinitionMap[v].append(k)
46 tmp1list = list()
47 for k,v in callDict.iteritems():
48 if len(v) >= 1:
49 continue
50 # created by macros
51 if k.endswith("::RegisterInterface(class SfxModule *)"):
52 continue
53 if k.endswith("::RegisterChildWindow(_Bool,class SfxModule *,enum SfxChildWindowFlags)"):
54 continue
55 if k.endswith("::RegisterChildWindowContext(unsigned short,class SfxModule *)"):
56 continue
57 if k.endswith("::RegisterControl(unsigned short,class SfxModule *)"):
58 continue
59 if k.endswith("::RegisterFactory(unsigned short)"):
60 continue
61 # windows-only stuff
62 if "ShutdownIcon::OpenURL" in k:
63 continue
64 # template magic
65 if k.startswith("void VclPtr::VclPtr(const VclPtr<type-parameter-?-?> &,typename UpCast<"):
66 continue
67 if k in definitionToSourceLocationMap:
68 tmp1list.append((k, definitionToSourceLocationMap[k]))
70 # sort the results using a "natural order" so sequences like [item1,item2,item10] sort nicely
71 def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
72 return [int(text) if text.isdigit() else text.lower()
73 for text in re.split(_nsre, s)]
75 # sort results by name and line number
76 tmp1list.sort(key=lambda v: natural_sort_key(v[1]))
78 # print out the results
79 with open("loplugin.countusersofdefaultparams.report", "wt") as f:
80 for t in tmp1list:
81 f.write(t[1] + "\n")
82 f.write(" " + t[0] + "\n")