Keep function arguments in order
[pywsdlgen.git] / pywsdlgen / parser_intro.py
blob6f563655e8cde95921e32d37df0cbfe8910d1226
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 # Author: Enrico Tröger
5 # License: LGPL
9 import imp
10 import inspect
11 import re
12 import sys
13 from parser import Parser
16 class ParserIntrospection(Parser):
17 """
18 Parser based on introspection code
19 """
21 #----------------------------------------------------------------------
22 def __init__(self, **kw):
23 super(ParserIntrospection, self).__init__(**kw)
25 self.re_doc_string = re.compile('^[ \t]*@(param|return)[ \t]+(.*)[ \t]+(.*).*')
26 self.re_clean_args = re.compile('(\(|\)|[ \t])')
28 #----------------------------------------------------------------------
29 def _add_tag(self, tagname, args):
30 """
31 Verify the found tag name and if it is valid, add it to the list
33 @param tagname (str)
34 @param args (list)
35 """
36 # add two lists, one for the arguments and the other one for the argument types
37 # a dcitionary would be much better but then we will loose the argument order
38 # TODO use a lift of tuples
39 arg_types = []
40 args.remove('self')
41 # TODO find a more elegant way to create an empty list of X elements
42 args_len = len(args)
43 for x in xrange(0, args_len + 1):
44 arg_types.append('')
45 args.append('return')
46 self.tags[tagname] = [ args, arg_types ]
48 #----------------------------------------------------------------------
49 def _parse_doc_string(self, method_name, input):
50 """
51 Parse the given doc string for arguments and argument types
53 @param method_name (str)
54 @param input (str)
55 """
56 if input:
57 lines = input.splitlines()
58 for line in lines:
59 m = self.re_doc_string.match(line)
60 if m:
61 f1, f2, f3 = m.groups()
62 if f2 and f2[0] == '(':
63 arg_name = f3
64 arg_type = f2
65 else:
66 arg_name = f2
67 arg_type = f3
69 arg_type = self.re_clean_args.sub('', arg_type)
70 if f1 == 'return':
71 arg_name = 'return'
73 if arg_type:
74 try:
75 idx = self.tags[method_name][0].index(arg_name)
76 self.tags[method_name][1][idx] = arg_type
77 except ValueError:
78 pass
80 #----------------------------------------------------------------------
81 def process_file(self, filename):
82 """
83 Read the file specified by filename and look for class and function definitions
85 @param filename (str)
86 """
87 module = imp.load_source('pywsdlgen', filename)
88 symbols = inspect.getmembers(module, callable)
89 for name, obj in symbols:
90 if inspect.isclass(obj):
91 self.class_name = obj.__name__
92 methods = inspect.getmembers(obj, inspect.ismethod)
93 for m_name, m_obj in methods:
94 # skip non-public tags and non-methods
95 if m_name.startswith('_') or not inspect.ismethod(m_obj):
96 continue
98 try:
99 args = inspect.getargspec(m_obj).args
100 except:
101 args = ''
102 self._add_tag(m_name, args)
103 self._parse_doc_string(m_name, m_obj.__doc__)