Update git submodules
[LibreOffice.git] / compilerplugins / clang / unnecessaryvirtual.py
blob12d8b00af470b1d275466584bab68636aad434ea
1 #!/usr/bin/python3
3 import io
4 import re
6 definitionSet = set()
7 definitionToSourceLocationMap = dict()
8 overridingSet = set()
9 nonEmptySet = set()
12 with io.open("workdir/loplugin.unnecessaryvirtual.log", "r", buffering=1024*1024) as txt:
13 for line in txt:
14 tokens = line.strip().split("\t")
15 if tokens[0] == "definition:":
16 fullMethodName = tokens[1]
17 sourceLocation = tokens[2]
18 definitionSet.add(fullMethodName)
19 definitionToSourceLocationMap[fullMethodName] = sourceLocation
20 elif tokens[0] == "overriding:":
21 fullMethodName = tokens[1]
22 overridingSet.add(fullMethodName)
23 elif tokens[0] == "nonempty:":
24 fullMethodName = tokens[1]
25 nonEmptySet.add(fullMethodName)
26 else:
27 print( "unknown line: " + line)
29 unnecessaryVirtualSet = set()
31 for clazz in (definitionSet - overridingSet):
32 # windows-specific stuff
33 if clazz.startswith("canvas::"): continue
34 if clazz.startswith("psp::PrinterInfoManager"): continue
35 if clazz.startswith("DdeTopic::"): continue
36 if clazz == "basegfx::unotools::UnoPolyPolygon::void-modifying()const": continue
37 if clazz == "SalLayout::_Bool-IsKashidaPosValid(int,)const": continue
38 if clazz == "SalLayout::void-DisableGlyphInjection(_Bool,)": continue
39 # Linux-TDF specific
40 if clazz == "X11SalFrame::void-updateGraphics(_Bool,)": continue
41 # OSX specific
42 if clazz == "SalFrame::void-SetRepresentedURL(const class rtl::OUString &,)": continue
43 if clazz == "SalMenu::_Bool-AddMenuBarButton(const struct SalMenuButtonItem &,)": continue
44 if clazz == "SalMenu::class Rectangle-GetMenuBarButtonRectPixel(sal_uInt16,class SalFrame *,)": continue
45 if clazz == "SalMenu::void-RemoveMenuBarButton(sal_uInt16,)": continue
46 if clazz == "SalLayout::_Bool-DrawTextSpecial(class SalGraphics &,sal_uInt32,)const": continue
47 # GTK < 3
48 if clazz == "GtkSalDisplay::int-CaptureMouse(class SalFrame *,)": continue
49 # some test magic
50 if clazz.startswith("apitest::"): continue
52 loc = definitionToSourceLocationMap[clazz]
54 # ignore external code
55 if loc.startswith("external/"): continue
56 if loc.startswith("workdir/"): continue
57 if loc.startswith("64-linux-gnu/"): continue
58 # there is a bunch of Windows specific code that we don't see
59 if loc.startswith("include/canvas/"): continue
60 # not sure what the problem is here
61 if loc.startswith("include/test/"): continue
63 unnecessaryVirtualSet.add( (clazz,loc) )
66 deadSet = set()
68 for clazz in (definitionSet - nonEmptySet):
70 # ignore destructors
71 if "::~" in clazz: continue
73 loc = definitionToSourceLocationMap[clazz]
75 # ignore external code
76 if loc.startswith("external/"): continue
77 if loc.startswith("workdir/"): continue
78 if loc.startswith("64-linux-gnu/"): continue
80 deadSet.add( (clazz,loc) )
83 # sort the results using a "natural order" so sequences like [item1,item2,item10] sort nicely
84 def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
85 return [int(text) if text.isdigit() else text.lower()
86 for text in re.split(_nsre, s)]
87 # sort by both the source-line and the datatype, so the output file ordering is stable
88 # when we have multiple items on the same source line
89 def v_sort_key(v):
90 return natural_sort_key(v[1]) + [v[0]]
92 # sort results by name and line number
93 tmp1list = sorted(unnecessaryVirtualSet, key=lambda v: v_sort_key(v))
94 tmp2list = sorted(deadSet, key=lambda v: v_sort_key(v))
96 with open("compilerplugins/clang/unnecessaryvirtual.results", "wt") as f:
97 for t in tmp1list:
98 f.write( t[1] + "\n" )
99 f.write( " " + t[0] + "\n" )
100 # add an empty line at the end to make it easier for the removevirtuals plugin to mmap() the output file
101 f.write("\n")
103 with open("compilerplugins/clang/unnecessaryvirtual-dead.results", "wt") as f:
104 for t in tmp2list:
105 f.write( t[1] + "\n" )
106 f.write( " " + t[0] + "\n" )