522 Private method to scan the source text of a Python module and retrieve |
522 Private method to scan the source text of a Python module and retrieve |
523 the relevant information. |
523 the relevant information. |
524 |
524 |
525 @param src the source text to be scanned (string) |
525 @param src the source text to be scanned (string) |
526 """ |
526 """ |
|
527 def calculateEndline(lineno, lines, indent): |
|
528 """ |
|
529 Function to calculate the end line of a class or method/function. |
|
530 |
|
531 @param lineno line number to start at (one based) |
|
532 @type int |
|
533 @param lines list of source lines |
|
534 @type list of str |
|
535 @param indent indent length the class/method/function definition |
|
536 @type int |
|
537 @return end line of the class/method/function (one based) |
|
538 @rtype int |
|
539 """ |
|
540 # start with zero based line after start line |
|
541 while lineno < len(lines): |
|
542 line = lines[lineno] |
|
543 if line.strip(): |
|
544 # line contains some text |
|
545 lineIndent = _indent(line.replace(line.lstrip(), "")) |
|
546 if lineIndent <= indent: |
|
547 return lineno |
|
548 lineno += 1 |
|
549 |
|
550 # nothing found |
|
551 return -1 |
|
552 |
|
553 srcLines = src.splitlines() |
|
554 |
527 lineno, last_lineno_pos = 1, 0 |
555 lineno, last_lineno_pos = 1, 0 |
528 lastGlobalEntry = None |
|
529 classstack = [] # stack of (class, indent) pairs |
556 classstack = [] # stack of (class, indent) pairs |
530 conditionalsstack = [] # stack of indents of conditional defines |
557 conditionalsstack = [] # stack of indents of conditional defines |
531 deltastack = [] |
558 deltastack = [] |
532 deltaindent = 0 |
559 deltaindent = 0 |
533 deltaindentcalculated = 0 |
560 deltaindentcalculated = 0 |
594 if deltastack: |
621 if deltastack: |
595 del deltastack[-1] |
622 del deltastack[-1] |
596 deltaindentcalculated = 0 |
623 deltaindentcalculated = 0 |
597 # close all classes indented at least as much |
624 # close all classes indented at least as much |
598 while classstack and classstack[-1][1] >= thisindent: |
625 while classstack and classstack[-1][1] >= thisindent: |
599 if ( |
|
600 classstack[-1][0] is not None and |
|
601 isinstance(classstack[-1][0], (Class, Function)) |
|
602 ): |
|
603 # record the end line of this class or function |
|
604 classstack[-1][0].setEndLine(lineno - 1) |
|
605 del classstack[-1] |
626 del classstack[-1] |
606 if classstack: |
627 if classstack: |
607 csi = -1 |
628 csi = -1 |
608 while csi >= -len(classstack): |
629 while csi >= -len(classstack): |
609 # nested defs are added to the class |
630 # nested defs are added to the class |
634 f = Function(self.name, meth_name, self.file, lineno, |
655 f = Function(self.name, meth_name, self.file, lineno, |
635 meth_sig, meth_pyqtSig, modifierType=modifier, |
656 meth_sig, meth_pyqtSig, modifierType=modifier, |
636 annotation=meth_ret) |
657 annotation=meth_ret) |
637 self.__py_setVisibility(f) |
658 self.__py_setVisibility(f) |
638 self.addFunction(meth_name, f) |
659 self.addFunction(meth_name, f) |
639 if not classstack: |
660 endlineno = calculateEndline(lineno, srcLines, thisindent) |
640 if lastGlobalEntry: |
661 f.setEndLine(endlineno) |
641 lastGlobalEntry.setEndLine(lineno - 1) |
|
642 lastGlobalEntry = f |
|
643 if cur_obj and isinstance(cur_obj, Function): |
|
644 cur_obj.setEndLine(lineno - 1) |
|
645 cur_obj = f |
662 cur_obj = f |
646 classstack.append((None, thisindent)) # Marker for nested fns |
663 classstack.append((None, thisindent)) # Marker for nested fns |
647 |
664 |
648 # reset the modifier settings |
665 # reset the modifier settings |
649 modifierType = Function.General |
666 modifierType = Function.General |
691 thisindent = _indent(m.group("ClassIndent")) |
708 thisindent = _indent(m.group("ClassIndent")) |
692 lineno = lineno + src.count('\n', last_lineno_pos, start) |
709 lineno = lineno + src.count('\n', last_lineno_pos, start) |
693 last_lineno_pos = start |
710 last_lineno_pos = start |
694 # close all classes indented at least as much |
711 # close all classes indented at least as much |
695 while classstack and classstack[-1][1] >= thisindent: |
712 while classstack and classstack[-1][1] >= thisindent: |
696 if ( |
|
697 classstack[-1][0] is not None and |
|
698 isinstance(classstack[-1][0], (Class, Function)) |
|
699 ): |
|
700 # record the end line of this class or function |
|
701 classstack[-1][0].setEndLine(lineno - 1) |
|
702 del classstack[-1] |
713 del classstack[-1] |
703 class_name = m.group("ClassName") |
714 class_name = m.group("ClassName") |
704 inherit = m.group("ClassSupers") |
715 inherit = m.group("ClassSupers") |
705 if inherit: |
716 if inherit: |
706 # the class inherits from other classes |
717 # the class inherits from other classes |
728 inherit = names |
739 inherit = names |
729 # remember this class |
740 # remember this class |
730 cur_class = Class(self.name, class_name, inherit, |
741 cur_class = Class(self.name, class_name, inherit, |
731 self.file, lineno) |
742 self.file, lineno) |
732 self.__py_setVisibility(cur_class) |
743 self.__py_setVisibility(cur_class) |
|
744 endlineno = calculateEndline(lineno, srcLines, thisindent) |
|
745 cur_class.setEndLine(endlineno) |
733 cur_obj = cur_class |
746 cur_obj = cur_class |
|
747 self.addClass(class_name, cur_class) |
734 # add nested classes to the module |
748 # add nested classes to the module |
735 self.addClass(class_name, cur_class) |
|
736 if not classstack: |
|
737 if lastGlobalEntry: |
|
738 lastGlobalEntry.setEndLine(lineno - 1) |
|
739 lastGlobalEntry = cur_class |
|
740 classstack.append((cur_class, thisindent)) |
749 classstack.append((cur_class, thisindent)) |
741 |
750 |
742 elif m.start("Attribute") >= 0: |
751 elif m.start("Attribute") >= 0: |
743 lineno = lineno + src.count('\n', last_lineno_pos, start) |
752 lineno = lineno + src.count('\n', last_lineno_pos, start) |
744 last_lineno_pos = start |
753 last_lineno_pos = start |
771 attr = Attribute( |
780 attr = Attribute( |
772 self.name, variable_name, self.file, lineno, |
781 self.name, variable_name, self.file, lineno, |
773 isSignal=isSignal) |
782 isSignal=isSignal) |
774 self.__py_setVisibility(attr) |
783 self.__py_setVisibility(attr) |
775 self.addGlobal(variable_name, attr) |
784 self.addGlobal(variable_name, attr) |
776 if lastGlobalEntry: |
|
777 lastGlobalEntry.setEndLine(lineno - 1) |
|
778 lastGlobalEntry = None |
|
779 else: |
785 else: |
780 index = -1 |
786 index = -1 |
781 while index >= -len(classstack): |
787 while index >= -len(classstack): |
782 if classstack[index][1] >= thisindent: |
788 if classstack[index][1] >= thisindent: |
783 index -= 1 |
789 index -= 1 |