Utilities/ModuleParser.py

changeset 2768
eab35f6e709f
parent 2396
89475661e400
child 2791
a9577f248f04
child 2922
16905f0f48be
equal deleted inserted replaced
2766:c413e9eeaf95 2768:eab35f6e709f
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
770 classstack = [] # stack of (class, indent) pairs 780 classstack = [] # stack of (class, indent) pairs
771 acstack = [] # stack of (access control, indent) pairs 781 acstack = [] # stack of (access control, indent) pairs
772 indent = 0 782 indent = 0
773 i = 0 783 i = 0
774 cur_obj = self 784 cur_obj = self
785 lastGlobalEntry = None
775 while True: 786 while True:
776 m = self._getnext(src, i) 787 m = self._getnext(src, i)
777 if not m: 788 if not m:
778 break 789 break
779 start, i = m.span() 790 start, i = m.span()
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
1302 Public method to store the functions docstring. 1345 Public method to store the functions docstring.
1303 1346
1304 @param description the docstring to be stored (string) 1347 @param description the docstring to be stored (string)
1305 """ 1348 """
1306 self.description = description 1349 self.description = description
1350
1351 def setEndLine(self, endLineNo):
1352 """
1353 Public method to record the number of the last line of a class.
1354
1355 @param endLineNo number of the last line (integer)
1356 """
1357 self.endlineno = endLineNo
1307 1358
1308 1359
1309 class Attribute(VisibilityBase): 1360 class Attribute(VisibilityBase):
1310 ''' 1361 '''
1311 Class to represent a Python function or method. 1362 Class to represent a Python function or method.

eric ide

mercurial