250 @param module module name associated with the source text |
250 @param module module name associated with the source text |
251 @type str |
251 @type str |
252 @return dictionary containing the extracted data |
252 @return dictionary containing the extracted data |
253 @rtype dict |
253 @rtype dict |
254 """ |
254 """ |
|
255 def calculateEndline(lineno, lines): |
|
256 """ |
|
257 Function to calculate the end line. |
|
258 |
|
259 @param lineno line number to start at (one based) |
|
260 @type int |
|
261 @param lines list of source lines |
|
262 @type list of str |
|
263 @return end line (one based) |
|
264 @rtype int |
|
265 """ |
|
266 # convert lineno to be zero based |
|
267 lineno -= 1 |
|
268 # 1. search for opening brace '{' |
|
269 while lineno < len(lines) and not "{" in lines[lineno]: |
|
270 lineno += 1 |
|
271 depth = lines[lineno].count("{") - lines[lineno].count("}") |
|
272 # 2. search for ending line, i.e. matching closing brace '}' |
|
273 while depth > 0 and lineno < len(lines) - 1: |
|
274 lineno += 1 |
|
275 depth += lines[lineno].count("{") - lines[lineno].count("}") |
|
276 if depth == 0: |
|
277 # found a matching brace |
|
278 return lineno + 1 |
|
279 else: |
|
280 # nothing found |
|
281 return -1 |
|
282 |
|
283 def calculateMethodEndline(lineno, lines): |
|
284 """ |
|
285 Function to calculate the end line. |
|
286 |
|
287 @param lineno line number to start at (one based) |
|
288 @type int |
|
289 @param lines list of source lines |
|
290 @type list of str |
|
291 @return end line (one based) |
|
292 @rtype int |
|
293 """ |
|
294 # convert lineno to be zero based |
|
295 lineno -= 1 |
|
296 while lineno < len(lines) and not ";" in lines[lineno]: |
|
297 lineno += 1 |
|
298 if ";" in lines[lineno]: |
|
299 # found an end indicator, i.e. ';' |
|
300 return lineno + 1 |
|
301 else: |
|
302 return -1 |
|
303 |
255 # convert eol markers the Python style |
304 # convert eol markers the Python style |
256 src = src.replace("\r\n", "\n").replace("\r", "\n") |
305 src = src.replace("\r\n", "\n").replace("\r", "\n") |
|
306 srcLines = src.splitlines() |
257 |
307 |
258 dictionary = {} |
308 dictionary = {} |
259 dict_counts = {} |
309 dict_counts = {} |
260 |
310 |
261 classstack = [] # stack of (class, indent) pairs |
311 classstack = [] # stack of (class, indent) pairs |
262 indent = 0 |
312 indent = 0 |
263 |
313 |
264 lineno, last_lineno_pos = 1, 0 |
314 lineno, last_lineno_pos = 1, 0 |
265 lastGlobalEntry = None |
|
266 cur_obj = None |
|
267 i = 0 |
315 i = 0 |
268 while True: |
316 while True: |
269 m = _getnext(src, i) |
317 m = _getnext(src, i) |
270 if not m: |
318 if not m: |
271 break |
319 break |
281 meth_sig = _normalize(' ', meth_sig) |
329 meth_sig = _normalize(' ', meth_sig) |
282 lineno = lineno + src.count('\n', last_lineno_pos, start) |
330 lineno = lineno + src.count('\n', last_lineno_pos, start) |
283 last_lineno_pos = start |
331 last_lineno_pos = start |
284 # close all interfaces/modules indented at least as much |
332 # close all interfaces/modules indented at least as much |
285 while classstack and classstack[-1][1] >= thisindent: |
333 while classstack and classstack[-1][1] >= thisindent: |
286 if classstack[-1][0] is not None: |
|
287 # record the end line |
|
288 classstack[-1][0].setEndLine(lineno - 1) |
|
289 del classstack[-1] |
334 del classstack[-1] |
290 if classstack: |
335 if classstack: |
291 # it's an interface/module method |
336 # it's an interface/module method |
292 cur_class = classstack[-1][0] |
337 cur_class = classstack[-1][0] |
293 if ( |
338 if ( |
310 meth_name = "{0}_{1:d}".format( |
355 meth_name = "{0}_{1:d}".format( |
311 meth_name, dict_counts[meth_name]) |
356 meth_name, dict_counts[meth_name]) |
312 else: |
357 else: |
313 dict_counts[meth_name] = 0 |
358 dict_counts[meth_name] = 0 |
314 dictionary[meth_name] = f |
359 dictionary[meth_name] = f |
315 if not classstack: |
360 if f: |
316 if lastGlobalEntry: |
361 endline = calculateMethodEndline(lineno, srcLines) |
317 lastGlobalEntry.setEndLine(lineno - 1) |
362 f.setEndLine(endline) |
318 lastGlobalEntry = f |
|
319 if cur_obj and isinstance(cur_obj, Function): |
|
320 cur_obj.setEndLine(lineno - 1) |
|
321 cur_obj = f |
|
322 classstack.append((f, thisindent)) # Marker for nested fns |
363 classstack.append((f, thisindent)) # Marker for nested fns |
323 |
364 |
324 elif m.start("String") >= 0: |
365 elif m.start("String") >= 0: |
325 pass |
366 pass |
326 |
367 |
331 # we found an interface definition |
372 # we found an interface definition |
332 thisindent = indent |
373 thisindent = indent |
333 indent += 1 |
374 indent += 1 |
334 # close all interfaces/modules indented at least as much |
375 # close all interfaces/modules indented at least as much |
335 while classstack and classstack[-1][1] >= thisindent: |
376 while classstack and classstack[-1][1] >= thisindent: |
336 if classstack[-1][0] is not None: |
|
337 # record the end line |
|
338 classstack[-1][0].setEndLine(lineno - 1) |
|
339 del classstack[-1] |
377 del classstack[-1] |
340 lineno = lineno + src.count('\n', last_lineno_pos, start) |
378 lineno = lineno + src.count('\n', last_lineno_pos, start) |
341 last_lineno_pos = start |
379 last_lineno_pos = start |
342 class_name = m.group("InterfaceName") |
380 class_name = m.group("InterfaceName") |
343 inherit = m.group("InterfaceSupers") |
381 inherit = m.group("InterfaceSupers") |
346 inherit = inherit[1:].strip() |
384 inherit = inherit[1:].strip() |
347 inherit = [_commentsub('', inherit)] |
385 inherit = [_commentsub('', inherit)] |
348 # remember this interface |
386 # remember this interface |
349 cur_class = Interface(module, class_name, inherit, |
387 cur_class = Interface(module, class_name, inherit, |
350 file, lineno) |
388 file, lineno) |
|
389 endline = calculateEndline(lineno, srcLines) |
|
390 cur_class.setEndLine(endline) |
351 if not classstack: |
391 if not classstack: |
352 dictionary[class_name] = cur_class |
392 dictionary[class_name] = cur_class |
353 else: |
393 else: |
354 cls = classstack[-1][0] |
394 cls = classstack[-1][0] |
355 cls._addclass(class_name, cur_class) |
395 cls._addclass(class_name, cur_class) |
356 if not classstack: |
|
357 if lastGlobalEntry: |
|
358 lastGlobalEntry.setEndLine(lineno - 1) |
|
359 lastGlobalEntry = cur_class |
|
360 if cur_obj and isinstance(cur_obj, Function): |
|
361 cur_obj.setEndLine(lineno - 1) |
|
362 cur_obj = cur_class |
|
363 classstack.append((cur_class, thisindent)) |
396 classstack.append((cur_class, thisindent)) |
364 |
397 |
365 elif m.start("Module") >= 0: |
398 elif m.start("Module") >= 0: |
366 # we found a module definition |
399 # we found a module definition |
367 thisindent = indent |
400 thisindent = indent |
368 indent += 1 |
401 indent += 1 |
369 # close all interfaces/modules indented at least as much |
402 # close all interfaces/modules indented at least as much |
370 while classstack and classstack[-1][1] >= thisindent: |
403 while classstack and classstack[-1][1] >= thisindent: |
371 if classstack[-1][0] is not None: |
|
372 # record the end line |
|
373 classstack[-1][0].setEndLine(lineno - 1) |
|
374 del classstack[-1] |
404 del classstack[-1] |
375 lineno = lineno + src.count('\n', last_lineno_pos, start) |
405 lineno = lineno + src.count('\n', last_lineno_pos, start) |
376 last_lineno_pos = start |
406 last_lineno_pos = start |
377 module_name = m.group("ModuleName") |
407 module_name = m.group("ModuleName") |
378 # remember this module |
408 # remember this module |
379 cur_class = Module(module, module_name, file, lineno) |
409 cur_class = Module(module, module_name, file, lineno) |
|
410 endline = calculateEndline(lineno, srcLines) |
|
411 cur_class.setEndLine(endline) |
380 if not classstack: |
412 if not classstack: |
381 dictionary[module_name] = cur_class |
413 dictionary[module_name] = cur_class |
382 if lastGlobalEntry: |
|
383 lastGlobalEntry.setEndLine(lineno - 1) |
|
384 lastGlobalEntry = cur_class |
|
385 if cur_obj and isinstance(cur_obj, Function): |
|
386 cur_obj.setEndLine(lineno - 1) |
|
387 cur_obj = cur_class |
|
388 classstack.append((cur_class, thisindent)) |
414 classstack.append((cur_class, thisindent)) |
389 |
415 |
390 elif m.start("Attribute") >= 0: |
416 elif m.start("Attribute") >= 0: |
391 lineno = lineno + src.count('\n', last_lineno_pos, start) |
417 lineno = lineno + src.count('\n', last_lineno_pos, start) |
392 last_lineno_pos = start |
418 last_lineno_pos = start |