461 else: |
463 else: |
462 object.setPublic() |
464 object.setPublic() |
463 |
465 |
464 def __py_scan(self, src): |
466 def __py_scan(self, src): |
465 """ |
467 """ |
466 Private method to scan the source text of a Python module and retrieve the |
468 Private method to scan the source text of a Python module and retrieve the |
467 relevant information. |
469 relevant information. |
468 |
470 |
469 @param src the source text to be scanned (string) |
471 @param src the source text to be scanned (string) |
470 """ |
472 """ |
471 lineno, last_lineno_pos = 1, 0 |
473 lineno, last_lineno_pos = 1, 0 |
472 classstack = [] # stack of (class, indent) pairs |
474 classstack = [] # stack of (class, indent) pairs |
473 conditionalsstack = [] # stack of indents of conditional defines |
475 conditionalsstack = [] # stack of indents of conditional defines |
474 deltastack = [] |
476 deltastack = [] |
475 deltaindent = 0 |
477 deltaindent = 0 |
476 deltaindentcalculated = 0 |
478 deltaindentcalculated = 0 |
477 i = 0 |
479 i = 0 |
478 modulelevel = 1 |
480 modulelevel = 1 |
502 # modify indentation level for conditional defines |
504 # modify indentation level for conditional defines |
503 if conditionalsstack: |
505 if conditionalsstack: |
504 if thisindent > conditionalsstack[-1]: |
506 if thisindent > conditionalsstack[-1]: |
505 if not deltaindentcalculated: |
507 if not deltaindentcalculated: |
506 deltastack.append(thisindent - conditionalsstack[-1]) |
508 deltastack.append(thisindent - conditionalsstack[-1]) |
507 deltaindent = reduce(lambda x,y: x+y, deltastack) |
509 deltaindent = reduce(lambda x, y: x + y, deltastack) |
508 deltaindentcalculated = 1 |
510 deltaindentcalculated = 1 |
509 thisindent -= deltaindent |
511 thisindent -= deltaindent |
510 else: |
512 else: |
511 while conditionalsstack and \ |
513 while conditionalsstack and \ |
512 conditionalsstack[-1] >= thisindent: |
514 conditionalsstack[-1] >= thisindent: |
533 if cur_class is None: |
535 if cur_class is None: |
534 continue |
536 continue |
535 |
537 |
536 if isinstance(cur_class, Class): |
538 if isinstance(cur_class, Class): |
537 # it's a class method |
539 # it's a class method |
538 f = Function(None, meth_name, None, lineno, |
540 f = Function(None, meth_name, None, lineno, |
539 meth_sig, meth_pyqtSig) |
541 meth_sig, meth_pyqtSig) |
540 self.__py_setVisibility(f) |
542 self.__py_setVisibility(f) |
541 cur_class.addMethod(meth_name, f) |
543 cur_class.addMethod(meth_name, f) |
542 break |
544 break |
543 else: |
545 else: |
544 # it's a nested function of a module function |
546 # it's a nested function of a module function |
545 f = Function(self.name, meth_name, self.file, lineno, |
547 f = Function(self.name, meth_name, self.file, lineno, |
546 meth_sig, meth_pyqtSig) |
548 meth_sig, meth_pyqtSig) |
547 self.__py_setVisibility(f) |
549 self.__py_setVisibility(f) |
548 self.addFunction(meth_name, f) |
550 self.addFunction(meth_name, f) |
549 else: |
551 else: |
550 # it's a module function |
552 # it's a module function |
551 f = Function(self.name, meth_name, self.file, lineno, |
553 f = Function(self.name, meth_name, self.file, lineno, |
552 meth_sig, meth_pyqtSig) |
554 meth_sig, meth_pyqtSig) |
553 self.__py_setVisibility(f) |
555 self.__py_setVisibility(f) |
554 self.addFunction(meth_name, f) |
556 self.addFunction(meth_name, f) |
555 cur_obj = f |
557 cur_obj = f |
556 classstack.append((None, thisindent)) # Marker for nested fns |
558 classstack.append((None, thisindent)) # Marker for nested fns |
557 |
559 |
558 elif m.start("Docstring") >= 0: |
560 elif m.start("Docstring") >= 0: |
559 contents = m.group("DocstringContents3") |
561 contents = m.group("DocstringContents3") |
560 if contents is not None: |
562 if contents is not None: |
561 contents = _hashsub(r"\1", contents) |
563 contents = _hashsub(r"\1", contents) |
568 if cur_obj: |
570 if cur_obj: |
569 cur_obj.addDescription(contents) |
571 cur_obj.addDescription(contents) |
570 |
572 |
571 elif m.start("String") >= 0: |
573 elif m.start("String") >= 0: |
572 if modulelevel and \ |
574 if modulelevel and \ |
573 (src[start-len('\r\n'):start] == '\r\n' or \ |
575 (src[start - len('\r\n'):start] == '\r\n' or \ |
574 src[start-len('\n'):start] == '\n' or \ |
576 src[start - len('\n'):start] == '\n' or \ |
575 src[start-len('\r'):start] == '\r'): |
577 src[start - len('\r'):start] == '\r'): |
576 contents = m.group("StringContents3") |
578 contents = m.group("StringContents3") |
577 if contents is not None: |
579 if contents is not None: |
578 contents = _hashsub(r"\1", contents) |
580 contents = _hashsub(r"\1", contents) |
579 else: |
581 else: |
580 if self.file.lower().endswith('.ptl'): |
582 if self.file.lower().endswith('.ptl'): |
655 isSignal = m.group("VariableSignal") != "" |
657 isSignal = m.group("VariableSignal") != "" |
656 lineno = lineno + src.count('\n', last_lineno_pos, start) |
658 lineno = lineno + src.count('\n', last_lineno_pos, start) |
657 last_lineno_pos = start |
659 last_lineno_pos = start |
658 if thisindent == 0: |
660 if thisindent == 0: |
659 # global variable |
661 # global variable |
660 attr = Attribute(self.name, variable_name, self.file, lineno, |
662 attr = Attribute(self.name, variable_name, self.file, lineno, |
661 isSignal = isSignal) |
663 isSignal=isSignal) |
662 self.__py_setVisibility(attr) |
664 self.__py_setVisibility(attr) |
663 self.addGlobal(variable_name, attr) |
665 self.addGlobal(variable_name, attr) |
664 else: |
666 else: |
665 index = -1 |
667 index = -1 |
666 while index >= -len(classstack): |
668 while index >= -len(classstack): |
667 if classstack[index][1] >= thisindent: |
669 if classstack[index][1] >= thisindent: |
668 index -= 1 |
670 index -= 1 |
669 else: |
671 else: |
670 if classstack[index][0] is not None and \ |
672 if classstack[index][0] is not None and \ |
671 isinstance(classstack[index][0], Class): |
673 isinstance(classstack[index][0], Class): |
672 attr = Attribute(self.name, variable_name, self.file, |
674 attr = Attribute(self.name, variable_name, self.file, |
673 lineno, isSignal = isSignal) |
675 lineno, isSignal=isSignal) |
674 self.__py_setVisibility(attr) |
676 self.__py_setVisibility(attr) |
675 classstack[index][0].addGlobal(variable_name, attr) |
677 classstack[index][0].addGlobal(variable_name, attr) |
676 break |
678 break |
677 |
679 |
678 elif m.start("Import") >= 0: |
680 elif m.start("Import") >= 0: |
708 |
710 |
709 modulelevel = 0 |
711 modulelevel = 0 |
710 |
712 |
711 def __rb_scan(self, src): |
713 def __rb_scan(self, src): |
712 """ |
714 """ |
713 Private method to scan the source text of a Python module and retrieve the |
715 Private method to scan the source text of a Python module and retrieve the |
714 relevant information. |
716 relevant information. |
715 |
717 |
716 @param src the source text to be scanned (string) |
718 @param src the source text to be scanned (string) |
717 """ |
719 """ |
718 lineno, last_lineno_pos = 1, 0 |
720 lineno, last_lineno_pos = 1, 0 |
719 classstack = [] # stack of (class, indent) pairs |
721 classstack = [] # stack of (class, indent) pairs |
720 acstack = [] # stack of (access control, indent) pairs |
722 acstack = [] # stack of (access control, indent) pairs |
721 indent = 0 |
723 indent = 0 |
722 i = 0 |
724 i = 0 |
723 cur_obj = self |
725 cur_obj = self |
724 while True: |
726 while True: |
781 else: |
783 else: |
782 # it's a function |
784 # it's a function |
783 f = Function(self.name, meth_name, self.file, lineno, meth_sig) |
785 f = Function(self.name, meth_name, self.file, lineno, meth_sig) |
784 self.addFunction(meth_name, f) |
786 self.addFunction(meth_name, f) |
785 cur_obj = f |
787 cur_obj = f |
786 classstack.append((None, thisindent)) # Marker for nested fns |
788 classstack.append((None, thisindent)) # Marker for nested fns |
787 |
789 |
788 elif m.start("Docstring") >= 0: |
790 elif m.start("Docstring") >= 0: |
789 contents = m.group("DocstringContents") |
791 contents = m.group("DocstringContents") |
790 if contents is not None: |
792 if contents is not None: |
791 contents = _hashsub(r"\1", contents) |
793 contents = _hashsub(r"\1", contents) |
938 if m.group("AttrType") is None: |
940 if m.group("AttrType") is None: |
939 nv = m.group("AttrList").split(",") |
941 nv = m.group("AttrList").split(",") |
940 if not nv: |
942 if not nv: |
941 break |
943 break |
942 name = nv[0].strip()[1:] # get rid of leading ':' |
944 name = nv[0].strip()[1:] # get rid of leading ':' |
943 attr = parent.getAttribute("@"+name) or \ |
945 attr = parent.getAttribute("@" + name) or \ |
944 parent.getAttribute("@@"+name) or \ |
946 parent.getAttribute("@@" + name) or \ |
945 Attribute(self.name, "@"+name, self.file, lineno) |
947 Attribute(self.name, "@" + name, self.file, lineno) |
946 if len(nv) == 1 or nv[1].strip() == "false": |
948 if len(nv) == 1 or nv[1].strip() == "false": |
947 attr.setProtected() |
949 attr.setProtected() |
948 elif nv[1].strip() == "true": |
950 elif nv[1].strip() == "true": |
949 attr.setPublic() |
951 attr.setPublic() |
950 parent.addAttribute(attr.name, attr) |
952 parent.addAttribute(attr.name, attr) |
951 else: |
953 else: |
952 access = m.group("AttrType") |
954 access = m.group("AttrType") |
953 for name in m.group("AttrList").split(","): |
955 for name in m.group("AttrList").split(","): |
954 name = name.strip()[1:] # get rid of leading ':' |
956 name = name.strip()[1:] # get rid of leading ':' |
955 attr = parent.getAttribute("@"+name) or \ |
957 attr = parent.getAttribute("@" + name) or \ |
956 parent.getAttribute("@@"+name) or \ |
958 parent.getAttribute("@@" + name) or \ |
957 Attribute(self.name, "@"+name, self.file, lineno) |
959 Attribute(self.name, "@" + name, self.file, lineno) |
958 if access == "_accessor": |
960 if access == "_accessor": |
959 attr.setPublic() |
961 attr.setPublic() |
960 elif access == "_reader" or access == "_writer": |
962 elif access == "_reader" or access == "_writer": |
961 if attr.isPrivate(): |
963 if attr.isPrivate(): |
962 attr.setProtected() |
964 attr.setProtected() |
992 """ |
994 """ |
993 Public method to build the inheritance hierarchy for all classes of this module. |
995 Public method to build the inheritance hierarchy for all classes of this module. |
994 |
996 |
995 @return A dictionary with inheritance hierarchies. |
997 @return A dictionary with inheritance hierarchies. |
996 """ |
998 """ |
997 hierarchy = {} |
999 hierarchy = {} |
998 for cls in list(list(self.classes.keys())): |
1000 for cls in list(list(self.classes.keys())): |
999 self.assembleHierarchy(cls, self.classes, [cls], hierarchy) |
1001 self.assembleHierarchy(cls, self.classes, [cls], hierarchy) |
1000 for mod in list(list(self.modules.keys())): |
1002 for mod in list(list(self.modules.keys())): |
1001 self.assembleHierarchy(mod, self.modules, [mod], hierarchy) |
1003 self.assembleHierarchy(mod, self.modules, [mod], hierarchy) |
1002 return hierarchy |
1004 return hierarchy |
1180 |
1183 |
1181 @param endLineNo number of the last line (integer) |
1184 @param endLineNo number of the last line (integer) |
1182 """ |
1185 """ |
1183 self.endlineno = endLineNo |
1186 self.endlineno = endLineNo |
1184 |
1187 |
|
1188 |
1185 class RbModule(Class): |
1189 class RbModule(Class): |
1186 ''' |
1190 ''' |
1187 Class to represent a Ruby module. |
1191 Class to represent a Ruby module. |
1188 ''' |
1192 ''' |
1189 def __init__(self, module, name, file, lineno): |
1193 def __init__(self, module, name, file, lineno): |
1205 @param name name of class to be added (string) |
1209 @param name name of class to be added (string) |
1206 @param _class Class object to be added |
1210 @param _class Class object to be added |
1207 """ |
1211 """ |
1208 self.classes[name] = _class |
1212 self.classes[name] = _class |
1209 |
1213 |
|
1214 |
1210 class Function(VisibilityBase): |
1215 class Function(VisibilityBase): |
1211 ''' |
1216 ''' |
1212 Class to represent a Python function or method. |
1217 Class to represent a Python function or method. |
1213 ''' |
1218 ''' |
1214 def __init__(self, module, name, file, lineno, signature = '', pyqtSignature = None): |
1219 def __init__(self, module, name, file, lineno, signature='', pyqtSignature=None): |
1215 """ |
1220 """ |
1216 Constructor |
1221 Constructor |
1217 |
1222 |
1218 @param module name of module containing this function (string) |
1223 @param module name of module containing this function (string) |
1219 @param name name of the function (string) |
1224 @param name name of the function (string) |
1238 |
1243 |
1239 @param description the docstring to be stored (string) |
1244 @param description the docstring to be stored (string) |
1240 """ |
1245 """ |
1241 self.description = description |
1246 self.description = description |
1242 |
1247 |
|
1248 |
1243 class Attribute(VisibilityBase): |
1249 class Attribute(VisibilityBase): |
1244 ''' |
1250 ''' |
1245 Class to represent a Python function or method. |
1251 Class to represent a Python function or method. |
1246 ''' |
1252 ''' |
1247 def __init__(self, module, name, file, lineno, isSignal = False): |
1253 def __init__(self, module, name, file, lineno, isSignal=False): |
1248 """ |
1254 """ |
1249 Constructor |
1255 Constructor |
1250 |
1256 |
1251 @param module name of module containing this function (string) |
1257 @param module name of module containing this function (string) |
1252 @param name name of the function (string) |
1258 @param name name of the function (string) |
1259 self.file = file |
1265 self.file = file |
1260 self.lineno = lineno |
1266 self.lineno = lineno |
1261 self.isSignal = isSignal |
1267 self.isSignal = isSignal |
1262 self.setPublic() |
1268 self.setPublic() |
1263 |
1269 |
1264 def readModule(module, path = [], inpackage = False, basename = "", |
1270 |
1265 extensions = None, caching = True): |
1271 def readModule(module, path=[], inpackage=False, basename="", |
|
1272 extensions=None, caching=True): |
1266 ''' |
1273 ''' |
1267 Function to read a module file and parse it. |
1274 Function to read a module file and parse it. |
1268 |
1275 |
1269 The module is searched in path and sys.path, read and parsed. |
1276 The module is searched in path and sys.path, read and parsed. |
1270 If the module was parsed before, the information is taken |
1277 If the module was parsed before, the information is taken |
1276 package (boolean) |
1283 package (boolean) |
1277 @param basename a path basename. This basename is deleted from |
1284 @param basename a path basename. This basename is deleted from |
1278 the filename of the module file to be read. (string) |
1285 the filename of the module file to be read. (string) |
1279 @param extensions list of extensions, which should be considered valid |
1286 @param extensions list of extensions, which should be considered valid |
1280 source file extensions (list of strings) |
1287 source file extensions (list of strings) |
1281 @param caching flag indicating that the parsed module should be |
1288 @param caching flag indicating that the parsed module should be |
1282 cached (boolean) |
1289 cached (boolean) |
1283 @return reference to a Module object containing the parsed |
1290 @return reference to a Module object containing the parsed |
1284 module information (Module) |
1291 module information (Module) |
1285 ''' |
1292 ''' |
1286 global _modules |
1293 global _modules |
1355 pass |
1362 pass |
1356 if caching: |
1363 if caching: |
1357 _modules[modname] = mod |
1364 _modules[modname] = mod |
1358 return mod |
1365 return mod |
1359 |
1366 |
|
1367 |
1360 def _indent(ws): |
1368 def _indent(ws): |
1361 """ |
1369 """ |
1362 Protected function to determine the indent width of a whitespace string. |
1370 Protected function to determine the indent width of a whitespace string. |
1363 |
1371 |
1364 @param ws The whitespace string to be cheked. (string) |
1372 @param ws The whitespace string to be cheked. (string) |
1365 @return Length of the whitespace string after tab expansion. |
1373 @return Length of the whitespace string after tab expansion. |
1366 """ |
1374 """ |
1367 return len(ws.expandtabs(TABWIDTH)) |
1375 return len(ws.expandtabs(TABWIDTH)) |
|
1376 |
1368 |
1377 |
1369 def find_module(name, path, extensions): |
1378 def find_module(name, path, extensions): |
1370 """ |
1379 """ |
1371 Module function to extend the Python module finding mechanism. |
1380 Module function to extend the Python module finding mechanism. |
1372 |
1381 |
1402 if name.lower().endswith('.py'): |
1411 if name.lower().endswith('.py'): |
1403 name = name[:-3] |
1412 name = name[:-3] |
1404 |
1413 |
1405 return imp.find_module(name, path) |
1414 return imp.find_module(name, path) |
1406 |
1415 |
|
1416 |
1407 def resetParsedModules(): |
1417 def resetParsedModules(): |
1408 """ |
1418 """ |
1409 Module function to reset the list of modules already parsed. |
1419 Module function to reset the list of modules already parsed. |
1410 """ |
1420 """ |
1411 _modules.clear() |
1421 _modules.clear() |
1412 |
1422 |
1413 def resetParsedModule(module, basename = ""): |
1423 |
|
1424 def resetParsedModule(module, basename=""): |
1414 """ |
1425 """ |
1415 Module function to clear one module from the list of parsed modules. |
1426 Module function to clear one module from the list of parsed modules. |
1416 |
1427 |
1417 @param module Name of the module to be parsed (string) |
1428 @param module Name of the module to be parsed (string) |
1418 @param basename a path basename. This basename is deleted from |
1429 @param basename a path basename. This basename is deleted from |