1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
#!/usr/bin/env python2.7
# This file is part of KDevelop
# SPDX-FileCopyrightText: 2011 Victor Varvariuc <victor.varvariuc@gmail.com>
from xml.dom import minidom
def indentCode(code, level):
return '\n'.join(' ' * level + line for line in code.splitlines())
def parseEnum(enumNode, enumName, className = ''):
'''Parse Enum node and return its string representation.'''
enumMembers = []
for node in enumNode.childNodes:
if node.nodeType == node.ELEMENT_NODE:
if node.nodeName == 'EnumMember':
enumMember = node.attributes['name'].value
if enumMember.startswith(className + '.'):
enumMember = enumMember[len(className) + 1:]
if enumMember == 'None':
enumMember = '__kdevpythondocumentation_builtin_None'
enumMembers.append(enumMember)
else:
print('Unknown node in Enum %s.%s: %s' % (className, enumName, node.nodeName))
text = ''
for enumMember in enumMembers:
text += '%s = int() # %s.%s enum\n' % (enumMember, className, enumName)
return text
def parseFunction(functionNode, funcName, className = ''):
'''Parse Function node and return its string representation.'''
params = [] if className == '' else [("None", "self")]
retType = 'None'
namesUsed = []
for node in functionNode.childNodes:
if node.nodeType == node.ELEMENT_NODE:
if node.nodeName == 'Argument':
argType = node.attributes['typename'].value
try:
argName = '*args' if argType == '...' else '_' + node.attributes['name'].value
except KeyError:
retType = argType
else:
if argName not in namesUsed:
params.append((argType, argName))
else:
print("adjusting arg name:", argName)
argName = argName + '_'
params.append((argType, argName))
namesUsed.append(argName)
else:
print('Unknown node in function %s.%s: %s' % (className, funcName, node.nodeName))
descr = 'abstract ' if 'abstract' in functionNode.attributes.keys() else ''
descr += '%s %s.%s(%s)' % (retType, className, funcName,
', '.join('%s %s' % p for p in params))
print("ret type:", retType)
if retType == 'None':
pass # leave it like this
elif retType.startswith('list-of-'):
retType = '[' + retType[8:] + '()]'
elif retType.contains("-or-"):
a, b = retType.split("-or-")
retType = "{0}() if True else {1}()".format(a, b)
elif retType.startsWith("dict-of-"):
key, value = retType[8:].split('-')
retType = '{' + key + "():" + value + "()}"
else:
retType += '()'
# prefix function arguments with '_' to deal with reserved Python keywords
text = 'def %s(%s):\n """%s"""\n return %s' % (funcName, ', '.join(param[1] for param in params), descr, retType)
return text
def parseClass(classNode):
'''Parse Class node.'''
try:
parentClasses = classNode.attributes['inherits'].value.split()
except KeyError:
parentClasses = []
className = classNode.attributes['name'].value
text = 'class %s(%s):\n """"""\n' % (className, ', '.join(parentClasses))
for node in classNode.childNodes:
if node.nodeType == node.ELEMENT_NODE:
name = node.attributes['name'].value
if name.startswith(className + '.'):
name = name[len(className) + 1 :]
if node.nodeName == 'Member':
text += ' %s = None # %s member\n' % (name, node.attributes['typename'].value)
elif node.nodeName == 'Function':
if name not in ('exec', 'print'): # skip this invalid for Python name
text += indentCode(parseFunction(node, name, className), 1) + '\n'
elif node.nodeName == 'Enum':
text += indentCode(parseEnum(node, name, className), 1) + '\n\n'
else:
print('Unknown node in class %s: %s' % (className, node.nodeName))
return text
files = ['QtGuimod.xml', 'QtCoremod.xml']
for filename in files:
dom = minidom.parse(filename)
module = dom.firstChild
assert module.nodeName == 'Module'
moduleName = module.attributes['name'].value
print('Module name:', moduleName)
stats = {}
with open(moduleName + '.py', 'w') as file:
for node in module.childNodes:
if node.nodeType != node.ELEMENT_NODE:
continue # skip non element nodes
nodeName = node.nodeName
stats[nodeName] = stats.setdefault(nodeName, 0) + 1 # stats
if nodeName == 'Class':
file.write(parseClass(node) + '\n\n')
elif nodeName == 'Function':
file.write(parseFunction(node, node.attributes['name'].value) + '\n\n')
elif nodeName == 'Member':
file.write('%s = None # %s member\n\n' % (node.attributes['name'].value, node.attributes['typename'].value))
else:
print('Unknown node:', nodeName)
print('Stats:', stats)
|