cid#1555694 COPY_INSTEAD_OF_MOVE
[LibreOffice.git] / compilerplugins / clang / unusedvarsglobal.py
blobaf41759b92da0f421092296fc0f9a984ea030611
1 #!/usr/bin/python3
3 import re
4 import io
6 definitionSet = set()
7 readFromSet = set()
8 writeToSet = set()
9 defToTypeMap = dict()
11 def parseFieldInfo( tokens ):
12 return (tokens[1].strip(), tokens[2].strip())
14 with io.open("workdir/loplugin.unusedvarsglobal.log", "r", buffering=16*1024*1024) as txt:
15 for line in txt:
16 try:
17 tokens = line.strip().split("\t")
18 if tokens[0] == "definition:":
19 srcLoc = tokens[3]
20 # ignore external source code
21 if (srcLoc.startswith("external/")):
22 continue
23 # ignore build folder
24 if (srcLoc.startswith("workdir/")):
25 continue
26 varname = tokens[1].strip()
27 vartype = tokens[2].strip()
28 if vartype.startswith("const "):
29 vartype = vartype[6:]
30 if vartype.startswith("class "):
31 vartype = vartype[6:]
32 if vartype.startswith("struct "):
33 vartype = vartype[7:]
34 if vartype.startswith("::"):
35 vartype = vartype[2:]
36 fieldInfo = (srcLoc, varname)
37 definitionSet.add(fieldInfo)
38 defToTypeMap[fieldInfo] = vartype
39 elif tokens[0] == "read:":
40 if len(tokens) == 3:
41 readFromSet.add(parseFieldInfo(tokens))
42 elif tokens[0] == "write:":
43 if len(tokens) == 3:
44 writeToSet.add(parseFieldInfo(tokens))
45 else:
46 print( "unknown line: " + line)
47 except IndexError:
48 print("problem with line " + line.strip())
49 raise
51 definitionSet2 = set()
52 for d in definitionSet:
53 varname = d[1]
54 vartype = defToTypeMap[d]
55 if len(varname) == 0:
56 continue
57 if varname.startswith("autoRegister"): # auto-generated CPPUNIT stuff
58 continue
59 if vartype in ["css::uno::ContextLayer", "SolarMutexGuard", "SolarMutexReleaser", "OpenGLZone"]:
60 continue
61 if vartype in ["PreDefaultWinNoOpenGLZone", "SchedulerGuard", "SkiaZone", "OpenGLVCLContextZone"]:
62 continue
63 if vartype in ["SwXDispatchProviderInterceptor::DispatchMutexLock_Impl", "SfxObjectShellLock", "OpenCLZone"]:
64 continue
65 if vartype in ["OpenCLInitialZone", "pyuno::PyThreadDetach", "SortRefUpdateSetter", "oglcanvas::TransformationPreserver"]:
66 continue
67 if vartype in ["StackHack", "osl::MutexGuard", "accessibility::SolarMethodGuard"]:
68 continue
69 if vartype in ["osl::ClearableMutexGuard", "comphelper::OExternalLockGuard", "osl::Guard< ::osl::Mutex>"]:
70 continue
71 if vartype in ["comphelper::OContextEntryGuard", "Guard<class osl::Mutex>", "basic::LibraryContainerMethodGuard"]:
72 continue
73 if vartype in ["canvas::CanvasBase::MutexType"]:
74 continue
75 definitionSet2.add(d)
77 # Calculate untouched
78 untouchedSet = set()
79 for d in definitionSet2:
80 if d in readFromSet or d in writeToSet:
81 continue
82 varname = d[1]
83 if len(varname) == 0:
84 continue
85 untouchedSet.add(d)
87 writeonlySet = set()
88 for d in definitionSet2:
89 if d in readFromSet or d in untouchedSet:
90 continue
91 varname = d[1]
92 vartype = defToTypeMap[d]
93 if "Alive" in varname:
94 continue
95 if "Keep" in varname:
96 continue
97 if vartype.endswith(" &"):
98 continue
99 writeonlySet.add(d)
101 readonlySet = set()
102 for d in definitionSet2:
103 if d in writeToSet or d in untouchedSet:
104 continue
105 varname = d[1]
106 vartype = defToTypeMap[d]
107 if "Dummy" in varname:
108 continue
109 if "Empty" in varname:
110 continue
111 if varname in ["aOldValue", "aNewValue"]:
112 continue
113 if "Exception" in vartype and vartype.endswith(" &"):
114 continue
115 if "exception" in vartype and vartype.endswith(" &"):
116 continue
117 # TODO for now, focus on the simple stuff
118 if vartype not in ["rtl::OUString", "Bool"]:
119 continue
120 readonlySet.add(d)
122 # sort the results using a "natural order" so sequences like [item1,item2,item10] sort nicely
123 def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
124 return [int(text) if text.isdigit() else text.lower()
125 for text in re.split(_nsre, s)]
126 # sort by both the source-line and the datatype, so the output file ordering is stable
127 # when we have multiple items on the same source line
128 def v_sort_key(v):
129 return natural_sort_key(v[0]) + [v[1]]
131 # sort results by name and line number
132 tmp1list = sorted(untouchedSet, key=lambda v: v_sort_key(v))
133 tmp2list = sorted(writeonlySet, key=lambda v: v_sort_key(v))
134 tmp3list = sorted(readonlySet, key=lambda v: v_sort_key(v))
136 # print out the results
137 with open("compilerplugins/clang/unusedvarsglobal.untouched.results", "wt") as f:
138 for t in tmp1list:
139 f.write( t[0] + "\n" )
140 f.write( " " + defToTypeMap[t] + " " + t[1] + "\n" )
141 with open("compilerplugins/clang/unusedvarsglobal.writeonly.results", "wt") as f:
142 for t in tmp2list:
143 f.write( t[0] + "\n" )
144 f.write( " " + defToTypeMap[t] + " " + t[1] + "\n" )
145 with open("compilerplugins/clang/unusedvarsglobal.readonly.results", "wt") as f:
146 for t in tmp3list:
147 f.write( t[0] + "\n" )
148 f.write( " " + defToTypeMap[t] + " " + t[1] + "\n" )