499 relevant information. |
499 relevant information. |
500 |
500 |
501 @param src the source text to be scanned (string) |
501 @param src the source text to be scanned (string) |
502 """ |
502 """ |
503 lineno, last_lineno_pos = 1, 0 |
503 lineno, last_lineno_pos = 1, 0 |
|
504 lastGlobalEntry = None |
504 classstack = [] # stack of (class, indent) pairs |
505 classstack = [] # stack of (class, indent) pairs |
505 conditionalsstack = [] # stack of indents of conditional defines |
506 conditionalsstack = [] # stack of indents of conditional defines |
506 deltastack = [] |
507 deltastack = [] |
507 deltaindent = 0 |
508 deltaindent = 0 |
508 deltaindentcalculated = 0 |
509 deltaindentcalculated = 0 |
562 del deltastack[-1] |
563 del deltastack[-1] |
563 deltaindentcalculated = 0 |
564 deltaindentcalculated = 0 |
564 # close all classes indented at least as much |
565 # close all classes indented at least as much |
565 while classstack and \ |
566 while classstack and \ |
566 classstack[-1][1] >= thisindent: |
567 classstack[-1][1] >= thisindent: |
567 if classstack[-1][1] == thisindent and \ |
568 if classstack[-1][0] is not None and \ |
568 classstack[-1][0] is not None and \ |
569 isinstance(classstack[-1][0], (Class, Function)): |
569 isinstance(classstack[-1][0], Class): |
570 # record the end line of this class or function |
570 # we got a class at the same indentation level; |
|
571 # record the end line of this class |
|
572 classstack[-1][0].setEndLine(lineno - 1) |
571 classstack[-1][0].setEndLine(lineno - 1) |
573 del classstack[-1] |
572 del classstack[-1] |
574 if classstack: |
573 if classstack: |
575 csi = -1 |
574 csi = -1 |
576 while csi >= -len(classstack): |
575 while csi >= -len(classstack): |
597 # it's a module function |
596 # it's a module function |
598 f = Function(self.name, meth_name, self.file, lineno, |
597 f = Function(self.name, meth_name, self.file, lineno, |
599 meth_sig, meth_pyqtSig, modifierType=modifier) |
598 meth_sig, meth_pyqtSig, modifierType=modifier) |
600 self.__py_setVisibility(f) |
599 self.__py_setVisibility(f) |
601 self.addFunction(meth_name, f) |
600 self.addFunction(meth_name, f) |
|
601 if not classstack: |
|
602 if lastGlobalEntry: |
|
603 lastGlobalEntry.setEndLine(lineno - 1) |
|
604 lastGlobalEntry = f |
|
605 if cur_obj and isinstance(cur_obj, Function): |
|
606 cur_obj.setEndLine(lineno - 1) |
602 cur_obj = f |
607 cur_obj = f |
603 classstack.append((None, thisindent)) # Marker for nested fns |
608 classstack.append((None, thisindent)) # Marker for nested fns |
604 |
609 |
605 # reset the modifier settings |
610 # reset the modifier settings |
606 modifierType = Function.General |
611 modifierType = Function.General |
642 lineno = lineno + src.count('\n', last_lineno_pos, start) |
647 lineno = lineno + src.count('\n', last_lineno_pos, start) |
643 last_lineno_pos = start |
648 last_lineno_pos = start |
644 # close all classes indented at least as much |
649 # close all classes indented at least as much |
645 while classstack and \ |
650 while classstack and \ |
646 classstack[-1][1] >= thisindent: |
651 classstack[-1][1] >= thisindent: |
647 if classstack[-1][1] == thisindent and \ |
652 if classstack[-1][0] is not None and \ |
648 classstack[-1][0] is not None and \ |
653 isinstance(classstack[-1][0], (Class, Function)): |
649 isinstance(classstack[-1][0], Class): |
654 # record the end line of this class or function |
650 # we got a class at the same indentation level; |
|
651 # record the end line of this class |
|
652 classstack[-1][0].setEndLine(lineno - 1) |
655 classstack[-1][0].setEndLine(lineno - 1) |
653 del classstack[-1] |
656 del classstack[-1] |
654 class_name = m.group("ClassName") |
657 class_name = m.group("ClassName") |
655 inherit = m.group("ClassSupers") |
658 inherit = m.group("ClassSupers") |
656 if inherit: |
659 if inherit: |
682 self.file, lineno) |
685 self.file, lineno) |
683 self.__py_setVisibility(cur_class) |
686 self.__py_setVisibility(cur_class) |
684 cur_obj = cur_class |
687 cur_obj = cur_class |
685 # add nested classes to the module |
688 # add nested classes to the module |
686 self.addClass(class_name, cur_class) |
689 self.addClass(class_name, cur_class) |
|
690 if not classstack: |
|
691 if lastGlobalEntry: |
|
692 lastGlobalEntry.setEndLine(lineno - 1) |
|
693 lastGlobalEntry = cur_class |
687 classstack.append((cur_class, thisindent)) |
694 classstack.append((cur_class, thisindent)) |
688 |
695 |
689 elif m.start("Attribute") >= 0: |
696 elif m.start("Attribute") >= 0: |
690 lineno = lineno + src.count('\n', last_lineno_pos, start) |
697 lineno = lineno + src.count('\n', last_lineno_pos, start) |
691 last_lineno_pos = start |
698 last_lineno_pos = start |
710 # global variable |
717 # global variable |
711 attr = Attribute(self.name, variable_name, self.file, lineno, |
718 attr = Attribute(self.name, variable_name, self.file, lineno, |
712 isSignal=isSignal) |
719 isSignal=isSignal) |
713 self.__py_setVisibility(attr) |
720 self.__py_setVisibility(attr) |
714 self.addGlobal(variable_name, attr) |
721 self.addGlobal(variable_name, attr) |
|
722 if lastGlobalEntry: |
|
723 lastGlobalEntry.setEndLine(lineno - 1) |
|
724 lastGlobalEntry = None |
715 else: |
725 else: |
716 index = -1 |
726 index = -1 |
717 while index >= -len(classstack): |
727 while index >= -len(classstack): |
718 if classstack[index][1] >= thisindent: |
728 if classstack[index][1] >= thisindent: |
719 index -= 1 |
729 index -= 1 |
794 elif meth_name.startswith('self::'): |
805 elif meth_name.startswith('self::'): |
795 meth_name = meth_name[6:] |
806 meth_name = meth_name[6:] |
796 # close all classes/modules indented at least as much |
807 # close all classes/modules indented at least as much |
797 while classstack and \ |
808 while classstack and \ |
798 classstack[-1][1] >= thisindent: |
809 classstack[-1][1] >= thisindent: |
|
810 if classstack[-1][0] is not None and \ |
|
811 isinstance(classstack[-1][0], (Class, Function, RbModule)): |
|
812 # record the end line of this class, function or module |
|
813 classstack[-1][0].setEndLine(lineno - 1) |
799 del classstack[-1] |
814 del classstack[-1] |
800 while acstack and \ |
815 while acstack and \ |
801 acstack[-1][1] >= thisindent: |
816 acstack[-1][1] >= thisindent: |
802 del acstack[-1] |
817 del acstack[-1] |
803 if classstack: |
818 if classstack: |
831 f.setPublic() |
846 f.setPublic() |
832 else: |
847 else: |
833 # it's a function |
848 # it's a function |
834 f = Function(self.name, meth_name, self.file, lineno, meth_sig) |
849 f = Function(self.name, meth_name, self.file, lineno, meth_sig) |
835 self.addFunction(meth_name, f) |
850 self.addFunction(meth_name, f) |
|
851 if not classstack: |
|
852 if lastGlobalEntry: |
|
853 lastGlobalEntry.setEndLine(lineno - 1) |
|
854 lastGlobalEntry = f |
|
855 if cur_obj and isinstance(cur_obj, Function): |
|
856 cur_obj.setEndLine(lineno - 1) |
836 cur_obj = f |
857 cur_obj = f |
837 classstack.append((None, thisindent)) # Marker for nested fns |
858 classstack.append((None, thisindent)) # Marker for nested fns |
838 |
859 |
839 elif m.start("Docstring") >= 0: |
860 elif m.start("Docstring") >= 0: |
840 contents = m.group("DocstringContents") |
861 contents = m.group("DocstringContents") |
854 |
875 |
855 elif m.start("Class") >= 0: |
876 elif m.start("Class") >= 0: |
856 # we found a class definition |
877 # we found a class definition |
857 thisindent = indent |
878 thisindent = indent |
858 indent += 1 |
879 indent += 1 |
|
880 lineno = lineno + src.count('\n', last_lineno_pos, start) |
|
881 last_lineno_pos = start |
859 # close all classes/modules indented at least as much |
882 # close all classes/modules indented at least as much |
860 while classstack and \ |
883 while classstack and \ |
861 classstack[-1][1] >= thisindent: |
884 classstack[-1][1] >= thisindent: |
|
885 if classstack[-1][0] is not None and \ |
|
886 isinstance(classstack[-1][0], (Class, Function, RbModule)): |
|
887 # record the end line of this class, function or module |
|
888 classstack[-1][0].setEndLine(lineno - 1) |
862 del classstack[-1] |
889 del classstack[-1] |
863 lineno = lineno + src.count('\n', last_lineno_pos, start) |
|
864 last_lineno_pos = start |
|
865 class_name = m.group("ClassName") or m.group("ClassName2") |
890 class_name = m.group("ClassName") or m.group("ClassName2") |
866 inherit = m.group("ClassSupers") |
891 inherit = m.group("ClassSupers") |
867 if inherit: |
892 if inherit: |
868 # the class inherits from other classes |
893 # the class inherits from other classes |
869 inherit = inherit[1:].strip() |
894 inherit = inherit[1:].strip() |
882 isinstance(classstack[-1][0], Class) and \ |
907 isinstance(classstack[-1][0], Class) and \ |
883 class_name == "self": |
908 class_name == "self": |
884 cur_class = classstack[-1][0] |
909 cur_class = classstack[-1][0] |
885 else: |
910 else: |
886 parent_obj.addClass(class_name, cur_class) |
911 parent_obj.addClass(class_name, cur_class) |
|
912 if not classstack: |
|
913 if lastGlobalEntry: |
|
914 lastGlobalEntry.setEndLine(lineno - 1) |
|
915 lastGlobalEntry = cur_class |
887 cur_obj = cur_class |
916 cur_obj = cur_class |
888 classstack.append((cur_class, thisindent)) |
917 classstack.append((cur_class, thisindent)) |
889 while acstack and \ |
918 while acstack and \ |
890 acstack[-1][1] >= thisindent: |
919 acstack[-1][1] >= thisindent: |
891 del acstack[-1] |
920 del acstack[-1] |
892 acstack.append(["public", thisindent]) # default access control is 'public' |
921 acstack.append(["public", thisindent]) |
|
922 # default access control is 'public' |
893 |
923 |
894 elif m.start("Module") >= 0: |
924 elif m.start("Module") >= 0: |
895 # we found a module definition |
925 # we found a module definition |
896 thisindent = indent |
926 thisindent = indent |
897 indent += 1 |
927 indent += 1 |
|
928 lineno = lineno + src.count('\n', last_lineno_pos, start) |
|
929 last_lineno_pos = start |
898 # close all classes/modules indented at least as much |
930 # close all classes/modules indented at least as much |
899 while classstack and \ |
931 while classstack and \ |
900 classstack[-1][1] >= thisindent: |
932 classstack[-1][1] >= thisindent: |
|
933 if classstack[-1][0] is not None and \ |
|
934 isinstance(classstack[-1][0], (Class, Function, RbModule)): |
|
935 # record the end line of this class, function or module |
|
936 classstack[-1][0].setEndLine(lineno - 1) |
901 del classstack[-1] |
937 del classstack[-1] |
902 lineno = lineno + src.count('\n', last_lineno_pos, start) |
|
903 last_lineno_pos = start |
|
904 module_name = m.group("ModuleName") |
938 module_name = m.group("ModuleName") |
905 # remember this class |
939 # remember this class |
906 cur_class = RbModule(self.name, module_name, |
940 cur_class = RbModule(self.name, module_name, |
907 self.file, lineno) |
941 self.file, lineno) |
908 # add nested Ruby modules to the file |
942 # add nested Ruby modules to the file |
909 if module_name in self.modules: |
943 if module_name in self.modules: |
910 cur_class = self.modules[module_name] |
944 cur_class = self.modules[module_name] |
911 else: |
945 else: |
912 self.addModule(module_name, cur_class) |
946 self.addModule(module_name, cur_class) |
|
947 if not classstack: |
|
948 if lastGlobalEntry: |
|
949 lastGlobalEntry.setEndLine(lineno - 1) |
|
950 lastGlobalEntry = cur_class |
913 cur_obj = cur_class |
951 cur_obj = cur_class |
914 classstack.append((cur_class, thisindent)) |
952 classstack.append((cur_class, thisindent)) |
915 while acstack and \ |
953 while acstack and \ |
916 acstack[-1][1] >= thisindent: |
954 acstack[-1][1] >= thisindent: |
917 del acstack[-1] |
955 del acstack[-1] |
918 acstack.append(["public", thisindent]) # default access control is 'public' |
956 acstack.append(["public", thisindent]) |
|
957 # default access control is 'public' |
919 |
958 |
920 elif m.start("AccessControl") >= 0: |
959 elif m.start("AccessControl") >= 0: |
921 aclist = m.group("AccessControlList") |
960 aclist = m.group("AccessControlList") |
922 if aclist is None: |
961 if aclist is None: |
923 index = -1 |
962 index = -1 |
974 else: |
1013 else: |
975 attrName = m.group("AttributeName") |
1014 attrName = m.group("AttributeName") |
976 if attrName[0] != "@": |
1015 if attrName[0] != "@": |
977 attr = Attribute(self.name, attrName, self.file, lineno) |
1016 attr = Attribute(self.name, attrName, self.file, lineno) |
978 self.addGlobal(attrName, attr) |
1017 self.addGlobal(attrName, attr) |
|
1018 if lastGlobalEntry: |
|
1019 lastGlobalEntry.setEndLine(lineno - 1) |
|
1020 lastGlobalEntry = None |
979 |
1021 |
980 elif m.start("Attr") >= 0: |
1022 elif m.start("Attr") >= 0: |
981 lineno = lineno + src.count('\n', last_lineno_pos, start) |
1023 lineno = lineno + src.count('\n', last_lineno_pos, start) |
982 last_lineno_pos = start |
1024 last_lineno_pos = start |
983 index = -1 |
1025 index = -1 |
1288 """ |
1330 """ |
1289 self.module = module |
1331 self.module = module |
1290 self.name = name |
1332 self.name = name |
1291 self.file = file |
1333 self.file = file |
1292 self.lineno = lineno |
1334 self.lineno = lineno |
|
1335 self.endlineno = -1 # marker for "not set" |
1293 signature = _commentsub('', signature) |
1336 signature = _commentsub('', signature) |
1294 self.parameters = [e.strip() for e in signature.split(',')] |
1337 self.parameters = [e.strip() for e in signature.split(',')] |
1295 self.description = "" |
1338 self.description = "" |
1296 self.pyqtSignature = pyqtSignature |
1339 self.pyqtSignature = pyqtSignature |
1297 self.modifier = modifierType |
1340 self.modifier = modifierType |