52b08068c9
Change-Id: Ifd5fdee23e5adba2b5a667f74c38ba6fb28f54b4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165446 Tested-by: Ilmari Lauhakangas <ilmari.lauhakangas@libreoffice.org> Tested-by: Jenkins Reviewed-by: Ilmari Lauhakangas <ilmari.lauhakangas@libreoffice.org>
150 lines
5.2 KiB
Python
Executable file
150 lines
5.2 KiB
Python
Executable file
#!/usr/bin/python3
|
|
|
|
import re
|
|
import io
|
|
|
|
definitionSet = set()
|
|
readFromSet = set()
|
|
writeToSet = set()
|
|
defToTypeMap = dict()
|
|
|
|
def parseFieldInfo( tokens ):
|
|
return (tokens[1].strip(), tokens[2].strip())
|
|
|
|
with io.open("workdir/loplugin.unusedvarsglobal.log", "r", buffering=16*1024*1024) as txt:
|
|
for line in txt:
|
|
try:
|
|
tokens = line.strip().split("\t")
|
|
if tokens[0] == "definition:":
|
|
srcLoc = tokens[3]
|
|
# ignore external source code
|
|
if (srcLoc.startswith("external/")):
|
|
continue
|
|
# ignore build folder
|
|
if (srcLoc.startswith("workdir/")):
|
|
continue
|
|
varname = tokens[1].strip()
|
|
vartype = tokens[2].strip()
|
|
if vartype.startswith("const "):
|
|
vartype = vartype[6:]
|
|
if vartype.startswith("class "):
|
|
vartype = vartype[6:]
|
|
if vartype.startswith("struct "):
|
|
vartype = vartype[7:]
|
|
if vartype.startswith("::"):
|
|
vartype = vartype[2:]
|
|
fieldInfo = (srcLoc, varname)
|
|
definitionSet.add(fieldInfo)
|
|
defToTypeMap[fieldInfo] = vartype
|
|
elif tokens[0] == "read:":
|
|
if len(tokens) == 3:
|
|
readFromSet.add(parseFieldInfo(tokens))
|
|
elif tokens[0] == "write:":
|
|
if len(tokens) == 3:
|
|
writeToSet.add(parseFieldInfo(tokens))
|
|
else:
|
|
print( "unknown line: " + line)
|
|
except IndexError:
|
|
print("problem with line " + line.strip())
|
|
raise
|
|
|
|
definitionSet2 = set()
|
|
for d in definitionSet:
|
|
varname = d[1]
|
|
vartype = defToTypeMap[d]
|
|
if len(varname) == 0:
|
|
continue
|
|
if varname.startswith("autoRegister"): # auto-generated CPPUNIT stuff
|
|
continue
|
|
if vartype in ["css::uno::ContextLayer", "SolarMutexGuard", "SolarMutexReleaser", "OpenGLZone"]:
|
|
continue
|
|
if vartype in ["PreDefaultWinNoOpenGLZone", "SchedulerGuard", "SkiaZone", "OpenGLVCLContextZone"]:
|
|
continue
|
|
if vartype in ["SwXDispatchProviderInterceptor::DispatchMutexLock_Impl", "SfxObjectShellLock", "OpenCLZone"]:
|
|
continue
|
|
if vartype in ["OpenCLInitialZone", "pyuno::PyThreadDetach", "SortRefUpdateSetter", "oglcanvas::TransformationPreserver"]:
|
|
continue
|
|
if vartype in ["StackHack", "osl::MutexGuard", "accessibility::SolarMethodGuard"]:
|
|
continue
|
|
if vartype in ["osl::ClearableMutexGuard", "comphelper::OExternalLockGuard", "osl::Guard< ::osl::Mutex>"]:
|
|
continue
|
|
if vartype in ["comphelper::OContextEntryGuard", "Guard<class osl::Mutex>", "basic::LibraryContainerMethodGuard"]:
|
|
continue
|
|
if vartype in ["canvas::CanvasBase::MutexType"]:
|
|
continue
|
|
definitionSet2.add(d)
|
|
|
|
# Calculate untouched
|
|
untouchedSet = set()
|
|
for d in definitionSet2:
|
|
if d in readFromSet or d in writeToSet:
|
|
continue
|
|
varname = d[1]
|
|
if len(varname) == 0:
|
|
continue
|
|
untouchedSet.add(d)
|
|
|
|
writeonlySet = set()
|
|
for d in definitionSet2:
|
|
if d in readFromSet or d in untouchedSet:
|
|
continue
|
|
varname = d[1]
|
|
vartype = defToTypeMap[d]
|
|
if "Alive" in varname:
|
|
continue
|
|
if "Keep" in varname:
|
|
continue
|
|
if vartype.endswith(" &"):
|
|
continue
|
|
writeonlySet.add(d)
|
|
|
|
readonlySet = set()
|
|
for d in definitionSet2:
|
|
if d in writeToSet or d in untouchedSet:
|
|
continue
|
|
varname = d[1]
|
|
vartype = defToTypeMap[d]
|
|
if "Dummy" in varname:
|
|
continue
|
|
if "Empty" in varname:
|
|
continue
|
|
if varname in ["aOldValue", "aNewValue"]:
|
|
continue
|
|
if "Exception" in vartype and vartype.endswith(" &"):
|
|
continue
|
|
if "exception" in vartype and vartype.endswith(" &"):
|
|
continue
|
|
# TODO for now, focus on the simple stuff
|
|
if vartype not in ["rtl::OUString", "Bool"]:
|
|
continue
|
|
readonlySet.add(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 by both the source-line and the datatype, so the output file ordering is stable
|
|
# when we have multiple items on the same source line
|
|
def v_sort_key(v):
|
|
return natural_sort_key(v[0]) + [v[1]]
|
|
|
|
# sort results by name and line number
|
|
tmp1list = sorted(untouchedSet, key=lambda v: v_sort_key(v))
|
|
tmp2list = sorted(writeonlySet, key=lambda v: v_sort_key(v))
|
|
tmp3list = sorted(readonlySet, key=lambda v: v_sort_key(v))
|
|
|
|
# print out the results
|
|
with open("compilerplugins/clang/unusedvarsglobal.untouched.results", "wt") as f:
|
|
for t in tmp1list:
|
|
f.write( t[0] + "\n" )
|
|
f.write( " " + defToTypeMap[t] + " " + t[1] + "\n" )
|
|
with open("compilerplugins/clang/unusedvarsglobal.writeonly.results", "wt") as f:
|
|
for t in tmp2list:
|
|
f.write( t[0] + "\n" )
|
|
f.write( " " + defToTypeMap[t] + " " + t[1] + "\n" )
|
|
with open("compilerplugins/clang/unusedvarsglobal.readonly.results", "wt") as f:
|
|
for t in tmp3list:
|
|
f.write( t[0] + "\n" )
|
|
f.write( " " + defToTypeMap[t] + " " + t[1] + "\n" )
|
|
|
|
|