81 ) |
81 ) |
82 |
82 |
83 | (?P<End> |
83 | (?P<End> |
84 [ \t]* } [ \t]* ; |
84 [ \t]* } [ \t]* ; |
85 )""", |
85 )""", |
86 re.VERBOSE | re.DOTALL | re.MULTILINE).search |
86 re.VERBOSE | re.DOTALL | re.MULTILINE, |
|
87 ).search |
87 |
88 |
88 # function to replace comments |
89 # function to replace comments |
89 _commentsub = re.compile(r"""//[^\n]*\n|//[^\n]*$""").sub |
90 _commentsub = re.compile(r"""//[^\n]*\n|//[^\n]*$""").sub |
90 # function to normalize whitespace |
91 # function to normalize whitespace |
91 _normalize = re.compile(r"""[ \t]{2,}""").sub |
92 _normalize = re.compile(r"""[ \t]{2,}""").sub |
92 |
93 |
93 _modules = {} # cache of modules we've seen |
94 _modules = {} # cache of modules we've seen |
94 |
95 |
95 |
96 |
96 class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase): |
97 class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase): |
97 """ |
98 """ |
98 Mixin class implementing the notion of visibility. |
99 Mixin class implementing the notion of visibility. |
99 """ |
100 """ |
|
101 |
100 def __init__(self): |
102 def __init__(self): |
101 """ |
103 """ |
102 Constructor |
104 Constructor |
103 """ |
105 """ |
104 self.setPublic() |
106 self.setPublic() |
106 |
108 |
107 class Module(ClbrBaseClasses.Module, VisibilityMixin): |
109 class Module(ClbrBaseClasses.Module, VisibilityMixin): |
108 """ |
110 """ |
109 Class to represent a CORBA IDL module. |
111 Class to represent a CORBA IDL module. |
110 """ |
112 """ |
|
113 |
111 def __init__(self, module, name, file, lineno): |
114 def __init__(self, module, name, file, lineno): |
112 """ |
115 """ |
113 Constructor |
116 Constructor |
114 |
117 |
115 @param module name of the module containing this module |
118 @param module name of the module containing this module |
116 @type str |
119 @type str |
117 @param name name of this module |
120 @param name name of this module |
118 @type str |
121 @type str |
119 @param file filename containing this module |
122 @param file filename containing this module |
127 |
130 |
128 class Interface(ClbrBaseClasses.Class, VisibilityMixin): |
131 class Interface(ClbrBaseClasses.Class, VisibilityMixin): |
129 """ |
132 """ |
130 Class to represent a CORBA IDL interface. |
133 Class to represent a CORBA IDL interface. |
131 """ |
134 """ |
|
135 |
132 def __init__(self, module, name, superClasses, file, lineno): |
136 def __init__(self, module, name, superClasses, file, lineno): |
133 """ |
137 """ |
134 Constructor |
138 Constructor |
135 |
139 |
136 @param module name of the module containing this interface |
140 @param module name of the module containing this interface |
137 @type str |
141 @type str |
138 @param name name of this interface |
142 @param name name of this interface |
139 @type str |
143 @type str |
140 @param superClasses list of interface names this interface is |
144 @param superClasses list of interface names this interface is |
143 @param file filename containing this interface |
147 @param file filename containing this interface |
144 @type str |
148 @type str |
145 @param lineno line number of the interface definition |
149 @param lineno line number of the interface definition |
146 @type int |
150 @type int |
147 """ |
151 """ |
148 ClbrBaseClasses.Class.__init__(self, module, name, superClasses, file, |
152 ClbrBaseClasses.Class.__init__(self, module, name, superClasses, file, lineno) |
149 lineno) |
|
150 VisibilityMixin.__init__(self) |
153 VisibilityMixin.__init__(self) |
151 |
154 |
152 |
155 |
153 class Function(ClbrBaseClasses.Function, VisibilityMixin): |
156 class Function(ClbrBaseClasses.Function, VisibilityMixin): |
154 """ |
157 """ |
155 Class to represent a CORBA IDL function. |
158 Class to represent a CORBA IDL function. |
156 """ |
159 """ |
157 def __init__(self, module, name, file, lineno, signature='', |
160 |
158 separator=','): |
161 def __init__(self, module, name, file, lineno, signature="", separator=","): |
159 """ |
162 """ |
160 Constructor |
163 Constructor |
161 |
164 |
162 @param module name of the module containing this function |
165 @param module name of the module containing this function |
163 @type str |
166 @type str |
164 @param name name of this function |
167 @param name name of this function |
165 @type str |
168 @type str |
166 @param file filename containing this function |
169 @param file filename containing this function |
170 @param signature parameter list of the function |
173 @param signature parameter list of the function |
171 @type str |
174 @type str |
172 @param separator string separating the parameters |
175 @param separator string separating the parameters |
173 @type str |
176 @type str |
174 """ |
177 """ |
175 ClbrBaseClasses.Function.__init__(self, module, name, file, lineno, |
178 ClbrBaseClasses.Function.__init__( |
176 signature, separator) |
179 self, module, name, file, lineno, signature, separator |
|
180 ) |
177 VisibilityMixin.__init__(self) |
181 VisibilityMixin.__init__(self) |
178 |
182 |
179 |
183 |
180 class Attribute(ClbrBaseClasses.Attribute, VisibilityMixin): |
184 class Attribute(ClbrBaseClasses.Attribute, VisibilityMixin): |
181 """ |
185 """ |
182 Class to represent a CORBA IDL attribute. |
186 Class to represent a CORBA IDL attribute. |
183 """ |
187 """ |
|
188 |
184 def __init__(self, module, name, file, lineno): |
189 def __init__(self, module, name, file, lineno): |
185 """ |
190 """ |
186 Constructor |
191 Constructor |
187 |
192 |
188 @param module name of the module containing this attribute |
193 @param module name of the module containing this attribute |
189 @type str |
194 @type str |
190 @param name name of this attribute |
195 @param name name of this attribute |
191 @type str |
196 @type str |
192 @param file filename containing this attribute |
197 @param file filename containing this attribute |
231 src = Utilities.readEncodedFile(file)[0] |
236 src = Utilities.readEncodedFile(file)[0] |
232 except (UnicodeError, OSError): |
237 except (UnicodeError, OSError): |
233 # can't do anything with this module |
238 # can't do anything with this module |
234 _modules[module] = {} |
239 _modules[module] = {} |
235 return {} |
240 return {} |
236 |
241 |
237 _modules[module] = scan(src, file, module) |
242 _modules[module] = scan(src, file, module) |
238 return _modules[module] |
243 return _modules[module] |
239 |
244 |
240 |
245 |
241 def scan(src, file, module): |
246 def scan(src, file, module): |
242 """ |
247 """ |
243 Public method to scan the given source text. |
248 Public method to scan the given source text. |
244 |
249 |
245 @param src source text to be scanned |
250 @param src source text to be scanned |
246 @type str |
251 @type str |
247 @param file file name associated with the source text |
252 @param file file name associated with the source text |
248 @type str |
253 @type str |
249 @param module module name associated with the source text |
254 @param module module name associated with the source text |
250 @type str |
255 @type str |
251 @return dictionary containing the extracted data |
256 @return dictionary containing the extracted data |
252 @rtype dict |
257 @rtype dict |
253 """ |
258 """ |
|
259 |
254 def calculateEndline(lineno, lines): |
260 def calculateEndline(lineno, lines): |
255 """ |
261 """ |
256 Function to calculate the end line. |
262 Function to calculate the end line. |
257 |
263 |
258 @param lineno line number to start at (one based) |
264 @param lineno line number to start at (one based) |
259 @type int |
265 @type int |
260 @param lines list of source lines |
266 @param lines list of source lines |
261 @type list of str |
267 @type list of str |
262 @return end line (one based) |
268 @return end line (one based) |
297 if ";" in lines[lineno]: |
303 if ";" in lines[lineno]: |
298 # found an end indicator, i.e. ';' |
304 # found an end indicator, i.e. ';' |
299 return lineno + 1 |
305 return lineno + 1 |
300 else: |
306 else: |
301 return -1 |
307 return -1 |
302 |
308 |
303 # convert eol markers the Python style |
309 # convert eol markers the Python style |
304 src = src.replace("\r\n", "\n").replace("\r", "\n") |
310 src = src.replace("\r\n", "\n").replace("\r", "\n") |
305 srcLines = src.splitlines() |
311 srcLines = src.splitlines() |
306 |
312 |
307 dictionary = {} |
313 dictionary = {} |
308 dict_counts = {} |
314 dict_counts = {} |
309 |
315 |
310 classstack = [] # stack of (class, indent) pairs |
316 classstack = [] # stack of (class, indent) pairs |
311 indent = 0 |
317 indent = 0 |
312 |
318 |
313 lineno, last_lineno_pos = 1, 0 |
319 lineno, last_lineno_pos = 1, 0 |
314 i = 0 |
320 i = 0 |
315 while True: |
321 while True: |
316 m = _getnext(src, i) |
322 m = _getnext(src, i) |
317 if not m: |
323 if not m: |
321 if m.start("Method") >= 0: |
327 if m.start("Method") >= 0: |
322 # found a method definition or function |
328 # found a method definition or function |
323 thisindent = indent |
329 thisindent = indent |
324 meth_name = m.group("MethodName") |
330 meth_name = m.group("MethodName") |
325 meth_sig = m.group("MethodSignature") |
331 meth_sig = m.group("MethodSignature") |
326 meth_sig = meth_sig and meth_sig.replace('\\\n', '') or '' |
332 meth_sig = meth_sig and meth_sig.replace("\\\n", "") or "" |
327 meth_sig = _commentsub('', meth_sig) |
333 meth_sig = _commentsub("", meth_sig) |
328 meth_sig = _normalize(' ', meth_sig) |
334 meth_sig = _normalize(" ", meth_sig) |
329 lineno += src.count('\n', last_lineno_pos, start) |
335 lineno += src.count("\n", last_lineno_pos, start) |
330 last_lineno_pos = start |
336 last_lineno_pos = start |
331 # close all interfaces/modules indented at least as much |
337 # close all interfaces/modules indented at least as much |
332 while classstack and classstack[-1][1] >= thisindent: |
338 while classstack and classstack[-1][1] >= thisindent: |
333 del classstack[-1] |
339 del classstack[-1] |
334 if classstack: |
340 if classstack: |
335 # it's an interface/module method |
341 # it's an interface/module method |
336 cur_class = classstack[-1][0] |
342 cur_class = classstack[-1][0] |
337 if isinstance(cur_class, (Interface, Module)): |
343 if isinstance(cur_class, (Interface, Module)): |
338 # it's a method |
344 # it's a method |
339 f = Function(None, meth_name, |
345 f = Function(None, meth_name, file, lineno, meth_sig) |
340 file, lineno, meth_sig) |
|
341 cur_class._addmethod(meth_name, f) |
346 cur_class._addmethod(meth_name, f) |
342 # else it's a nested def |
347 # else it's a nested def |
343 else: |
348 else: |
344 f = None |
349 f = None |
345 else: |
350 else: |
346 # it's a function |
351 # it's a function |
347 f = Function(module, meth_name, |
352 f = Function(module, meth_name, file, lineno, meth_sig) |
348 file, lineno, meth_sig) |
|
349 if meth_name in dict_counts: |
353 if meth_name in dict_counts: |
350 dict_counts[meth_name] += 1 |
354 dict_counts[meth_name] += 1 |
351 meth_name = "{0}_{1:d}".format( |
355 meth_name = "{0}_{1:d}".format(meth_name, dict_counts[meth_name]) |
352 meth_name, dict_counts[meth_name]) |
|
353 else: |
356 else: |
354 dict_counts[meth_name] = 0 |
357 dict_counts[meth_name] = 0 |
355 dictionary[meth_name] = f |
358 dictionary[meth_name] = f |
356 if f: |
359 if f: |
357 endline = calculateMethodEndline(lineno, srcLines) |
360 endline = calculateMethodEndline(lineno, srcLines) |
366 thisindent = indent |
369 thisindent = indent |
367 indent += 1 |
370 indent += 1 |
368 # close all interfaces/modules indented at least as much |
371 # close all interfaces/modules indented at least as much |
369 while classstack and classstack[-1][1] >= thisindent: |
372 while classstack and classstack[-1][1] >= thisindent: |
370 del classstack[-1] |
373 del classstack[-1] |
371 lineno += src.count('\n', last_lineno_pos, start) |
374 lineno += src.count("\n", last_lineno_pos, start) |
372 last_lineno_pos = start |
375 last_lineno_pos = start |
373 class_name = m.group("InterfaceName") |
376 class_name = m.group("InterfaceName") |
374 inherit = m.group("InterfaceSupers") |
377 inherit = m.group("InterfaceSupers") |
375 if inherit: |
378 if inherit: |
376 # the interface inherits from other interfaces |
379 # the interface inherits from other interfaces |
377 inherit = inherit[1:].strip() |
380 inherit = inherit[1:].strip() |
378 inherit = [_commentsub('', inherit)] |
381 inherit = [_commentsub("", inherit)] |
379 # remember this interface |
382 # remember this interface |
380 cur_class = Interface(module, class_name, inherit, |
383 cur_class = Interface(module, class_name, inherit, file, lineno) |
381 file, lineno) |
|
382 endline = calculateEndline(lineno, srcLines) |
384 endline = calculateEndline(lineno, srcLines) |
383 cur_class.setEndLine(endline) |
385 cur_class.setEndLine(endline) |
384 if not classstack: |
386 if not classstack: |
385 dictionary[class_name] = cur_class |
387 dictionary[class_name] = cur_class |
386 else: |
388 else: |
393 thisindent = indent |
395 thisindent = indent |
394 indent += 1 |
396 indent += 1 |
395 # close all interfaces/modules indented at least as much |
397 # close all interfaces/modules indented at least as much |
396 while classstack and classstack[-1][1] >= thisindent: |
398 while classstack and classstack[-1][1] >= thisindent: |
397 del classstack[-1] |
399 del classstack[-1] |
398 lineno += src.count('\n', last_lineno_pos, start) |
400 lineno += src.count("\n", last_lineno_pos, start) |
399 last_lineno_pos = start |
401 last_lineno_pos = start |
400 module_name = m.group("ModuleName") |
402 module_name = m.group("ModuleName") |
401 # remember this module |
403 # remember this module |
402 cur_class = Module(module, module_name, file, lineno) |
404 cur_class = Module(module, module_name, file, lineno) |
403 endline = calculateEndline(lineno, srcLines) |
405 endline = calculateEndline(lineno, srcLines) |
405 if not classstack: |
407 if not classstack: |
406 dictionary[module_name] = cur_class |
408 dictionary[module_name] = cur_class |
407 classstack.append((cur_class, thisindent)) |
409 classstack.append((cur_class, thisindent)) |
408 |
410 |
409 elif m.start("Attribute") >= 0: |
411 elif m.start("Attribute") >= 0: |
410 lineno += src.count('\n', last_lineno_pos, start) |
412 lineno += src.count("\n", last_lineno_pos, start) |
411 last_lineno_pos = start |
413 last_lineno_pos = start |
412 index = -1 |
414 index = -1 |
413 while index >= -len(classstack): |
415 while index >= -len(classstack): |
414 if ( |
416 if ( |
415 classstack[index][0] is not None and |
417 classstack[index][0] is not None |
416 not isinstance(classstack[index][0], Function) and |
418 and not isinstance(classstack[index][0], Function) |
417 classstack[index][1] < indent |
419 and classstack[index][1] < indent |
418 ): |
420 ): |
419 attributes = m.group("AttributeNames").split(',') |
421 attributes = m.group("AttributeNames").split(",") |
420 ro = m.group("AttributeReadonly") |
422 ro = m.group("AttributeReadonly") |
421 for attribute in attributes: |
423 for attribute in attributes: |
422 attr = Attribute(module, attribute, file, lineno) |
424 attr = Attribute(module, attribute, file, lineno) |
423 if ro: |
425 if ro: |
424 attr.setPrivate() |
426 attr.setPrivate() |