155 |
155 |
156 class Class(ClbrBaseClasses.Class, VisibilityMixin): |
156 class Class(ClbrBaseClasses.Class, VisibilityMixin): |
157 """ |
157 """ |
158 Class to represent a Python class. |
158 Class to represent a Python class. |
159 """ |
159 """ |
160 def __init__(self, module, name, super, file, lineno): |
160 def __init__(self, module, name, superClasses, file, lineno): |
161 """ |
161 """ |
162 Constructor |
162 Constructor |
163 |
163 |
164 @param module name of the module containing this class |
164 @param module name of the module containing this class |
165 @param name name of this class |
165 @param name name of this class |
166 @param super list of class names this class is inherited from |
166 @param superClasses list of class names this class is inherited from |
167 @param file filename containing this class |
167 @param file filename containing this class |
168 @param lineno linenumber of the class definition |
168 @param lineno linenumber of the class definition |
169 """ |
169 """ |
170 ClbrBaseClasses.Class.__init__(self, module, name, super, file, lineno) |
170 ClbrBaseClasses.Class.__init__(self, module, name, superClasses, file, |
|
171 lineno) |
171 VisibilityMixin.__init__(self) |
172 VisibilityMixin.__init__(self) |
172 |
173 |
173 |
174 |
174 class Function(ClbrBaseClasses.Function, VisibilityMixin): |
175 class Function(ClbrBaseClasses.Function, VisibilityMixin): |
175 """ |
176 """ |
338 @param isPyFile flag indicating a Python file (boolean) |
339 @param isPyFile flag indicating a Python file (boolean) |
339 @return the resulting dictionary |
340 @return the resulting dictionary |
340 """ |
341 """ |
341 global _modules |
342 global _modules |
342 |
343 |
343 dict = {} |
344 dictionary = {} |
344 dict_counts = {} |
345 dict_counts = {} |
345 |
346 |
346 if module in _modules: |
347 if module in _modules: |
347 # we've seen this module before... |
348 # we've seen this module before... |
348 return _modules[module] |
349 return _modules[module] |
349 if module in sys.builtin_module_names: |
350 if module in sys.builtin_module_names: |
350 # this is a built-in module |
351 # this is a built-in module |
351 _modules[module] = dict |
352 _modules[module] = dictionary |
352 return dict |
353 return dictionary |
353 |
354 |
354 # search the path for the module |
355 # search the path for the module |
355 f = None |
356 f = None |
356 if inpackage: |
357 if inpackage: |
357 try: |
358 try: |
362 if f is None: |
363 if f is None: |
363 fullpath = list(path) + sys.path |
364 fullpath = list(path) + sys.path |
364 f, file, (suff, mode, type) = \ |
365 f, file, (suff, mode, type) = \ |
365 ClassBrowsers.find_module(module, fullpath, isPyFile) |
366 ClassBrowsers.find_module(module, fullpath, isPyFile) |
366 if module.endswith(".py") and type == imp.PKG_DIRECTORY: |
367 if module.endswith(".py") and type == imp.PKG_DIRECTORY: |
367 return dict |
368 return dictionary |
368 if type == imp.PKG_DIRECTORY: |
369 if type == imp.PKG_DIRECTORY: |
369 dict['__path__'] = [file] |
370 dictionary['__path__'] = [file] |
370 _modules[module] = dict |
371 _modules[module] = dictionary |
371 path = [file] + path |
372 path = [file] + path |
372 f, file, (suff, mode, type) = \ |
373 f, file, (suff, mode, type) = \ |
373 ClassBrowsers.find_module('__init__', [file]) |
374 ClassBrowsers.find_module('__init__', [file]) |
374 if f: |
375 if f: |
375 f.close() |
376 f.close() |
376 if type not in SUPPORTED_TYPES: |
377 if type not in SUPPORTED_TYPES: |
377 # not Python source, can't do anything with this module |
378 # not Python source, can't do anything with this module |
378 _modules[module] = dict |
379 _modules[module] = dictionary |
379 return dict |
380 return dictionary |
380 |
381 |
381 _modules[module] = dict |
382 _modules[module] = dictionary |
382 classstack = [] # stack of (class, indent) pairs |
383 classstack = [] # stack of (class, indent) pairs |
383 conditionalsstack = [] # stack of indents of conditional defines |
384 conditionalsstack = [] # stack of indents of conditional defines |
384 deltastack = [] |
385 deltastack = [] |
385 deltaindent = 0 |
386 deltaindent = 0 |
386 deltaindentcalculated = 0 |
387 deltaindentcalculated = 0 |
387 try: |
388 try: |
388 src = Utilities.readEncodedFile(file)[0] |
389 src = Utilities.readEncodedFile(file)[0] |
389 except (UnicodeError, IOError): |
390 except (UnicodeError, IOError): |
390 # can't do anything with this module |
391 # can't do anything with this module |
391 _modules[module] = dict |
392 _modules[module] = dictionary |
392 return dict |
393 return dictionary |
393 |
394 |
394 lineno, last_lineno_pos = 1, 0 |
395 lineno, last_lineno_pos = 1, 0 |
395 lastGlobalEntry = None |
396 lastGlobalEntry = None |
396 cur_obj = None |
397 cur_obj = None |
397 i = 0 |
398 i = 0 |
468 dict_counts[meth_name] += 1 |
469 dict_counts[meth_name] += 1 |
469 meth_name = "{0}_{1:d}".format( |
470 meth_name = "{0}_{1:d}".format( |
470 meth_name, dict_counts[meth_name]) |
471 meth_name, dict_counts[meth_name]) |
471 else: |
472 else: |
472 dict_counts[meth_name] = 0 |
473 dict_counts[meth_name] = 0 |
473 dict[meth_name] = f |
474 dictionary[meth_name] = f |
474 if not classstack: |
475 if not classstack: |
475 if lastGlobalEntry: |
476 if lastGlobalEntry: |
476 lastGlobalEntry.setEndLine(lineno - 1) |
477 lastGlobalEntry.setEndLine(lineno - 1) |
477 lastGlobalEntry = f |
478 lastGlobalEntry = f |
478 if cur_obj and isinstance(cur_obj, Function): |
479 if cur_obj and isinstance(cur_obj, Function): |
535 dict_counts[class_name] += 1 |
536 dict_counts[class_name] += 1 |
536 class_name = "{0}_{1:d}".format( |
537 class_name = "{0}_{1:d}".format( |
537 class_name, dict_counts[class_name]) |
538 class_name, dict_counts[class_name]) |
538 else: |
539 else: |
539 dict_counts[class_name] = 0 |
540 dict_counts[class_name] = 0 |
540 dict[class_name] = cur_class |
541 dictionary[class_name] = cur_class |
541 else: |
542 else: |
542 classstack[-1][0]._addclass(class_name, cur_class) |
543 classstack[-1][0]._addclass(class_name, cur_class) |
543 if not classstack: |
544 if not classstack: |
544 if lastGlobalEntry: |
545 if lastGlobalEntry: |
545 lastGlobalEntry.setEndLine(lineno - 1) |
546 lastGlobalEntry.setEndLine(lineno - 1) |
565 variable_name = m.group("VariableName") |
566 variable_name = m.group("VariableName") |
566 lineno = lineno + src.count('\n', last_lineno_pos, start) |
567 lineno = lineno + src.count('\n', last_lineno_pos, start) |
567 last_lineno_pos = start |
568 last_lineno_pos = start |
568 if thisindent == 0: |
569 if thisindent == 0: |
569 # global variable |
570 # global variable |
570 if "@@Globals@@" not in dict: |
571 if "@@Globals@@" not in dictionary: |
571 dict["@@Globals@@"] = ClbrBaseClasses.ClbrBase( |
572 dictionary["@@Globals@@"] = ClbrBaseClasses.ClbrBase( |
572 module, "Globals", file, lineno) |
573 module, "Globals", file, lineno) |
573 dict["@@Globals@@"]._addglobal( |
574 dictionary["@@Globals@@"]._addglobal( |
574 Attribute(module, variable_name, file, lineno)) |
575 Attribute(module, variable_name, file, lineno)) |
575 if lastGlobalEntry: |
576 if lastGlobalEntry: |
576 lastGlobalEntry.setEndLine(lineno - 1) |
577 lastGlobalEntry.setEndLine(lineno - 1) |
577 lastGlobalEntry = None |
578 lastGlobalEntry = None |
578 else: |
579 else: |
589 elif m.start("Publics") >= 0: |
590 elif m.start("Publics") >= 0: |
590 idents = m.group("Identifiers") |
591 idents = m.group("Identifiers") |
591 lineno = lineno + src.count('\n', last_lineno_pos, start) |
592 lineno = lineno + src.count('\n', last_lineno_pos, start) |
592 last_lineno_pos = start |
593 last_lineno_pos = start |
593 pubs = Publics(module, file, lineno, idents) |
594 pubs = Publics(module, file, lineno, idents) |
594 dict['__all__'] = pubs |
595 dictionary['__all__'] = pubs |
595 |
596 |
596 elif m.start("Import") >= 0: |
597 elif m.start("Import") >= 0: |
597 # import module |
598 # import module |
598 names = [n.strip() for n in |
599 names = [n.strip() for n in |
599 "".join(m.group("ImportList").splitlines()) |
600 "".join(m.group("ImportList").splitlines()) |
600 .replace("\\", "").split(',')] |
601 .replace("\\", "").split(',')] |
601 lineno = lineno + src.count('\n', last_lineno_pos, start) |
602 lineno = lineno + src.count('\n', last_lineno_pos, start) |
602 last_lineno_pos = start |
603 last_lineno_pos = start |
603 if "@@Import@@" not in dict: |
604 if "@@Import@@" not in dictionary: |
604 dict["@@Import@@"] = Imports(module, file) |
605 dictionary["@@Import@@"] = Imports(module, file) |
605 for name in names: |
606 for name in names: |
606 dict["@@Import@@"].addImport(name, [], lineno) |
607 dictionary["@@Import@@"].addImport(name, [], lineno) |
607 |
608 |
608 elif m.start("ImportFrom") >= 0: |
609 elif m.start("ImportFrom") >= 0: |
609 # from module import stuff |
610 # from module import stuff |
610 mod = m.group("ImportFromPath") |
611 mod = m.group("ImportFromPath") |
611 namesLines = (m.group("ImportFromList") |
612 namesLines = (m.group("ImportFromList") |
617 names = [n.strip() for n in |
618 names = [n.strip() for n in |
618 "".join(namesLines) |
619 "".join(namesLines) |
619 .split(',')] |
620 .split(',')] |
620 lineno = lineno + src.count('\n', last_lineno_pos, start) |
621 lineno = lineno + src.count('\n', last_lineno_pos, start) |
621 last_lineno_pos = start |
622 last_lineno_pos = start |
622 if "@@Import@@" not in dict: |
623 if "@@Import@@" not in dictionary: |
623 dict["@@Import@@"] = Imports(module, file) |
624 dictionary["@@Import@@"] = Imports(module, file) |
624 dict["@@Import@@"].addImport(mod, names, lineno) |
625 dictionary["@@Import@@"].addImport(mod, names, lineno) |
625 |
626 |
626 elif m.start("ConditionalDefine") >= 0: |
627 elif m.start("ConditionalDefine") >= 0: |
627 # a conditional function/method definition |
628 # a conditional function/method definition |
628 thisindent = _indent(m.group("ConditionalDefineIndent")) |
629 thisindent = _indent(m.group("ConditionalDefineIndent")) |
629 while conditionalsstack and \ |
630 while conditionalsstack and \ |
637 elif m.start("CodingLine") >= 0: |
638 elif m.start("CodingLine") >= 0: |
638 # a coding statement |
639 # a coding statement |
639 coding = m.group("Coding") |
640 coding = m.group("Coding") |
640 lineno = lineno + src.count('\n', last_lineno_pos, start) |
641 lineno = lineno + src.count('\n', last_lineno_pos, start) |
641 last_lineno_pos = start |
642 last_lineno_pos = start |
642 if "@@Coding@@" not in dict: |
643 if "@@Coding@@" not in dictionary: |
643 dict["@@Coding@@"] = ClbrBaseClasses.Coding( |
644 dictionary["@@Coding@@"] = ClbrBaseClasses.Coding( |
644 module, file, lineno, coding) |
645 module, file, lineno, coding) |
645 |
646 |
646 else: |
647 else: |
647 assert 0, "regexp _getnext found something unexpected" |
648 assert 0, "regexp _getnext found something unexpected" |
648 |
649 |
649 if '__all__' in dict: |
650 if '__all__' in dictionary: |
650 # set visibility of all top level elements |
651 # set visibility of all top level elements |
651 pubs = dict['__all__'] |
652 pubs = dictionary['__all__'] |
652 for key in list(list(dict.keys())): |
653 for key in dictionary.keys(): |
653 if key == '__all__' or key.startswith("@@"): |
654 if key == '__all__' or key.startswith("@@"): |
654 continue |
655 continue |
655 if key in pubs.identifiers: |
656 if key in pubs.identifiers: |
656 dict[key].setPublic() |
657 dictionary[key].setPublic() |
657 else: |
658 else: |
658 dict[key].setPrivate() |
659 dictionary[key].setPrivate() |
659 del dict['__all__'] |
660 del dictionary['__all__'] |
660 |
661 |
661 return dict |
662 return dictionary |
662 |
663 |
663 |
664 |
664 def _indent(ws): |
665 def _indent(ws): |
665 """ |
666 """ |
666 Module function to return the indentation depth. |
667 Module function to return the indentation depth. |