1#!/usr/local/bin/python3.8 2 3import sys 4 5instantiatedSet = set() 6definitionSet = set() 7parentChildDict = {} 8definitionToFileDict = {} 9 10with open("workdir/loplugin.mergeclasses.log") as txt: 11 for line in txt: 12 tokens = line.strip().split("\t") 13 14 if len(tokens) == 1: 15 pass 16 17 elif tokens[0] == "instantiated:": 18 clazzName = tokens[1] 19 if (clazzName.startswith("const ")): 20 clazzName = clazzName[6:] 21 if (clazzName.startswith("class ")): 22 clazzName = clazzName[6:] 23 if (clazzName.startswith("::")): 24 clazzName = clazzName[2:] 25 instantiatedSet.add(clazzName) 26 27 elif tokens[0] == "definition:": 28 clazzName = tokens[1] 29 # the 1.. is so we skip the leading / 30 fileName = tokens[2][1:] 31 definitionSet.add(clazzName) 32 definitionToFileDict[clazzName] = fileName 33 34 elif tokens[0] == "has-subclass:": 35 child = tokens[1] 36 parent = tokens[2] 37 if (parent.startswith("class ")): 38 parent = parent[6:] 39 elif (parent.startswith("struct ")): 40 parent = parent[7:] 41 if (child.startswith("class ")): 42 child = child[6:] 43 elif (child.startswith("struct ")): 44 child = child[7:] 45 if (parent not in parentChildDict): 46 parentChildDict[parent] = set() 47 parentChildDict[parent].add(child) 48 49def extractModuleName(clazz): 50 filename = definitionToFileDict[clazz] 51 if filename.startswith("include/"): 52 filename = filename[8:] 53 idx = filename.find("/") 54 return filename[:idx] 55 56with open("compilerplugins/clang/mergeclasses.results", "wt") as f: 57 # loop over defined, but not instantiated classes 58 for clazz in sorted(definitionSet - instantiatedSet): 59 if clazz == "svl::IUndoManager": print parentChildDict[clazz] 60 # ignore classes without any children, and classes with more than one child 61 if (clazz not in parentChildDict) or (len(parentChildDict[clazz]) != 1): 62 continue 63 # exclude some common false positives 64 a = ['Dialog', 'Dlg', 'com::sun'] 65 if any(x in clazz for x in a): 66 continue 67 # ignore base class that contain the word "mutex", they are normally there to 68 # help with the WeakComponentImpl template magic 69 if ("mutex" in clazz) or ("Mutex" in clazz): 70 continue 71 otherclazz = next(iter(parentChildDict[clazz])) 72 if clazz == "svl::IUndoManager": print extractModuleName(clazz) 73 if otherclazz == "svl::IUndoManager": print extractModuleName(otherclazz) 74 # exclude combinations that span modules because we often use those to make cross-module dependencies more manageable. 75 if extractModuleName(clazz) != extractModuleName(otherclazz): 76 continue 77 f.write( "merge " + clazz + " with " + otherclazz + "\n" ) 78 79