summaryrefslogtreecommitdiffstats
path: root/compilerplugins/clang/mergeclasses.py
diff options
context:
space:
mode:
Diffstat (limited to 'compilerplugins/clang/mergeclasses.py')
-rwxr-xr-xcompilerplugins/clang/mergeclasses.py78
1 files changed, 78 insertions, 0 deletions
diff --git a/compilerplugins/clang/mergeclasses.py b/compilerplugins/clang/mergeclasses.py
new file mode 100755
index 000000000..bc6d129ee
--- /dev/null
+++ b/compilerplugins/clang/mergeclasses.py
@@ -0,0 +1,78 @@
+#!/usr/bin/python3
+
+import sys
+
+instantiatedSet = set()
+definitionSet = set()
+parentChildDict = {}
+definitionToFileDict = {}
+
+with open("workdir/loplugin.mergeclasses.log") as txt:
+ for line in txt:
+ tokens = line.strip().split("\t")
+
+ if len(tokens) == 1:
+ pass
+
+ elif tokens[0] == "instantiated:":
+ clazzName = tokens[1]
+ if (clazzName.startswith("const ")):
+ clazzName = clazzName[6:]
+ if (clazzName.startswith("class ")):
+ clazzName = clazzName[6:]
+ if (clazzName.startswith("::")):
+ clazzName = clazzName[2:]
+ instantiatedSet.add(clazzName)
+
+ elif tokens[0] == "definition:":
+ clazzName = tokens[1]
+ # the 1.. is so we skip the leading /
+ fileName = tokens[2][1:]
+ definitionSet.add(clazzName)
+ definitionToFileDict[clazzName] = fileName
+
+ elif tokens[0] == "has-subclass:":
+ child = tokens[1]
+ parent = tokens[2]
+ 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]
+
+with open("compilerplugins/clang/mergeclasses.results", "wt") as f:
+ # loop over defined, but not instantiated classes
+ for clazz in sorted(definitionSet - instantiatedSet):
+ if clazz == "svl::IUndoManager": print(parentChildDict[clazz])
+ # ignore classes without any children, and classes with more than one child
+ if (clazz not in parentChildDict) or (len(parentChildDict[clazz]) != 1):
+ continue
+ # exclude some common false positives
+ a = ['Dialog', 'Dlg', 'com::sun']
+ 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 ("mutex" in clazz) or ("Mutex" in clazz):
+ continue
+ otherclazz = next(iter(parentChildDict[clazz]))
+ if clazz == "svl::IUndoManager": print(extractModuleName(clazz))
+ if otherclazz == "svl::IUndoManager": print(extractModuleName(otherclazz))
+ # exclude combinations that span modules because we often use those to make cross-module dependencies more manageable.
+ if extractModuleName(clazz) != extractModuleName(otherclazz):
+ continue
+ f.write( "merge " + clazz + " with " + otherclazz + "\n" )
+