#!/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", "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" )