Warning, file /kdevelop/kdev-python/documentation_src/pyqt/parse_xml.py was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 #!/usr/bin/env python2.7
0002 # This file is part of KDevelop
0003 # SPDX-FileCopyrightText: 2011 Victor Varvariuc <victor.varvariuc@gmail.com>
0004 
0005 from xml.dom import minidom
0006 
0007 
0008 def indentCode(code, level):
0009     return '\n'.join('    ' * level + line for line in code.splitlines())
0010 
0011 
0012 def parseEnum(enumNode, enumName, className = ''):
0013     '''Parse Enum node and return its string representation.'''
0014     enumMembers = []
0015     for node in enumNode.childNodes:
0016         if node.nodeType == node.ELEMENT_NODE:
0017             if node.nodeName == 'EnumMember':
0018                 enumMember = node.attributes['name'].value
0019                 if enumMember.startswith(className + '.'):
0020                     enumMember = enumMember[len(className) + 1:]
0021                 if enumMember == 'None':
0022                     enumMember = '__kdevpythondocumentation_builtin_None'
0023                 enumMembers.append(enumMember)
0024             else:
0025                 print('Unknown node in Enum %s.%s: %s' % (className, enumName, node.nodeName))
0026     text = ''
0027     for enumMember in enumMembers:
0028         text += '%s = int() # %s.%s enum\n' % (enumMember, className, enumName)
0029     return text
0030 
0031 
0032 def parseFunction(functionNode, funcName, className = ''):
0033     '''Parse Function node and return its string representation.'''
0034     params = [] if className == '' else [("None", "self")]
0035     retType = 'None'
0036     namesUsed = []
0037     for node in functionNode.childNodes:
0038         if node.nodeType == node.ELEMENT_NODE:
0039             if node.nodeName == 'Argument':
0040                 argType = node.attributes['typename'].value
0041                 try:
0042                     argName = '*args' if argType == '...' else '_' + node.attributes['name'].value
0043                 except KeyError:
0044                     retType = argType
0045                 else:
0046                     if argName not in namesUsed:
0047                         params.append((argType, argName))
0048                     else:
0049                         print("adjusting arg name:", argName)
0050                         argName = argName + '_'
0051                         params.append((argType, argName))
0052                     namesUsed.append(argName)
0053             else:
0054                 print('Unknown node in function %s.%s: %s' % (className, funcName, node.nodeName))
0055 
0056     descr = 'abstract ' if 'abstract' in functionNode.attributes.keys() else ''
0057     descr += '%s %s.%s(%s)' % (retType, className, funcName,
0058                 ', '.join('%s %s' % p for p in params))
0059 
0060     print("ret type:", retType)
0061     if retType == 'None':
0062         pass # leave it like this
0063     elif retType.startswith('list-of-'):
0064         retType = '[' + retType[8:] + '()]'
0065     elif retType.contains("-or-"):
0066         a, b = retType.split("-or-")
0067         retType = "{0}() if True else {1}()".format(a, b)
0068     elif retType.startsWith("dict-of-"):
0069         key, value = retType[8:].split('-')
0070         retType = '{' + key + "():" + value + "()}"
0071     else:
0072         retType += '()'
0073 
0074     # prefix function arguments with '_' to deal with reserved Python keywords
0075     text = 'def %s(%s):\n    """%s"""\n    return %s' % (funcName, ', '.join(param[1] for param in params), descr, retType)
0076     return text
0077 
0078 
0079 def parseClass(classNode):
0080     '''Parse Class node.'''
0081     try:
0082         parentClasses = classNode.attributes['inherits'].value.split()
0083     except KeyError:
0084         parentClasses = []
0085     className = classNode.attributes['name'].value
0086     text = 'class %s(%s):\n    """"""\n' % (className, ', '.join(parentClasses))
0087     for node in classNode.childNodes:
0088         if node.nodeType == node.ELEMENT_NODE:
0089             name = node.attributes['name'].value
0090             if name.startswith(className + '.'):
0091                 name = name[len(className) + 1 :]
0092             if node.nodeName == 'Member':
0093                 text += '    %s = None # %s member\n' % (name, node.attributes['typename'].value)
0094             elif node.nodeName == 'Function':
0095                 if name not in ('exec', 'print'): # skip this invalid for Python name
0096                     text += indentCode(parseFunction(node, name, className), 1) + '\n'
0097             elif node.nodeName == 'Enum':
0098                 text += indentCode(parseEnum(node, name, className), 1) + '\n\n'
0099             else:
0100                 print('Unknown node in class %s: %s' % (className, node.nodeName))
0101     return text
0102 
0103 
0104 files = ['QtGuimod.xml', 'QtCoremod.xml']
0105 for filename in files:
0106     dom = minidom.parse(filename)
0107 
0108     module = dom.firstChild
0109     assert module.nodeName == 'Module'
0110     moduleName = module.attributes['name'].value
0111     print('Module name:', moduleName)
0112 
0113     stats = {}
0114 
0115     with open(moduleName + '.py', 'w') as file:
0116         for node in module.childNodes:
0117             if node.nodeType != node.ELEMENT_NODE:
0118                 continue # skip non element nodes
0119             nodeName = node.nodeName
0120             stats[nodeName] = stats.setdefault(nodeName, 0) + 1 # stats
0121             if nodeName == 'Class':
0122                 file.write(parseClass(node) + '\n\n')
0123             elif nodeName == 'Function':
0124                 file.write(parseFunction(node, node.attributes['name'].value) + '\n\n')
0125             elif nodeName == 'Member':
0126                 file.write('%s = None # %s member\n\n' % (node.attributes['name'].value, node.attributes['typename'].value))
0127             else:
0128                 print('Unknown node:', nodeName)
0129 
0130     print('Stats:', stats)