new loplugin mergeclasses
Idea from Norbert (shm_get) - look for classes that are (a) not instantiated (b) have zero or one subclasses and warn about them - would allow us to remove a bunch of abstract classes that can be merged into one class and simplified Change-Id: I4e43fdd2f549b5cbe25dcb7cee5e9dd3c1df8ba0
This commit is contained in:
73
compilerplugins/clang/mergeclasses.py
Executable file
73
compilerplugins/clang/mergeclasses.py
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
|
||||
instantiatedSet = set()
|
||||
definitionSet = set()
|
||||
parentChildDict = {}
|
||||
definitionToFileDict = {}
|
||||
|
||||
with open("mergeclasses.log") as txt:
|
||||
for line in txt:
|
||||
|
||||
if line.startswith("instantiated:\t"):
|
||||
idx1 = line.find("\t")
|
||||
clazzName = line[idx1+1 : len(line)-1]
|
||||
if (clazzName.startswith("const ")):
|
||||
clazzName = clazzName[6:]
|
||||
if (clazzName.startswith("class ")):
|
||||
clazzName = clazzName[6:]
|
||||
if (clazzName.endswith(" &")):
|
||||
clazzName = clazzName[:len(clazzName)-3]
|
||||
instantiatedSet.add(clazzName)
|
||||
|
||||
elif line.startswith("definition:\t"):
|
||||
idx1 = line.find("\t")
|
||||
idx2 = line.find("\t", idx1+1)
|
||||
clazzName = line[idx1+1 : idx2]
|
||||
fileName = line[idx2+1 : len(line)-1]
|
||||
definitionSet.add(clazzName)
|
||||
definitionToFileDict[clazzName] = fileName
|
||||
|
||||
elif line.startswith("has-subclass:\t"):
|
||||
idx1 = line.find("\t")
|
||||
idx2 = line.find("\t", idx1+1)
|
||||
child = line[idx1+1 : idx2]
|
||||
parent = line[idx2+1 : len(line)-1]
|
||||
if (parent.startswith("class ")):
|
||||
parent = parent[6:]
|
||||
elif (parent.startswith("struct ")):
|
||||
parent = parent[7:]
|
||||
if (child.startswith("class ")):
|
||||
child = child[6:]
|
||||
elif (child.startswith("struct ")):
|
||||
child = child[7:]
|
||||
if (parent not in parentChildDict):
|
||||
parentChildDict[parent] = set()
|
||||
parentChildDict[parent].add(child)
|
||||
|
||||
def extractModuleName(clazz):
|
||||
filename = definitionToFileDict[clazz]
|
||||
if filename.startswith("include/"):
|
||||
filename = filename[8:]
|
||||
idx = filename.find("/")
|
||||
return filename[:idx]
|
||||
|
||||
for clazz in sorted(definitionSet - instantiatedSet):
|
||||
# find uninstantiated classes without any subclasses
|
||||
if (not(clazz in parentChildDict)) or (len(parentChildDict[clazz]) != 1):
|
||||
continue
|
||||
# exclude some common false positives
|
||||
a = ['Dialog', 'Dlg', 'com::sun', 'Base']
|
||||
if any(x in clazz for x in a):
|
||||
continue
|
||||
# ignore base class that contain the word "mutex", they are normally there to
|
||||
# help with the WeakComponentImpl template magic
|
||||
if clazz.find("mutex") != -1 or clazz.find("Mutex") != -1:
|
||||
continue
|
||||
otherclazz = next(iter(parentChildDict[clazz]))
|
||||
# exclude combinations that span modules because we often use those to make cross-module dependencies more manageable.
|
||||
if extractModuleName(clazz) != extractModuleName(otherclazz):
|
||||
continue
|
||||
print "merge", clazz, "with", otherclazz
|
||||
|
Reference in New Issue
Block a user