def readmodule_ex(module, path=[]): """ Read a JavaScript file and return a dictionary of functions and variables. @param module name of the JavaScript file (string) @param path path the file should be searched in (list of strings) @return the resulting dictionary """ global _modules dict = {} if module in _modules: # we've seen this file before... return _modules[module] # search the path for the file f = None fullpath = list(path) f, file, (suff, mode, type) = ClassBrowsers.find_module(module, fullpath) if f: f.close() if type not in SUPPORTED_TYPES: # not CORBA IDL source, can't do anything with this module _modules[module] = dict return dict _modules[module] = dict try: src = Utilities.readEncodedFile(file)[0] except (UnicodeError, IOError): # can't do anything with this module _modules[module] = dict return dict visitor = Visitor(src, module, file) dict = visitor.parse() _modules[module] = dict return dict
def readmodule_ex(module, path=[]): """ Read a CORBA IDL file and return a dictionary of classes, functions and modules. @param module name of the CORBA IDL file (string) @param path path the file should be searched in (list of strings) @return the resulting dictionary """ global _modules dict = {} dict_counts = {} if module in _modules: # we've seen this file before... return _modules[module] # search the path for the file f = None fullpath = list(path) f, file, (suff, mode, type) = ClassBrowsers.find_module(module, fullpath) if f: f.close() if type not in SUPPORTED_TYPES: # not CORBA IDL source, can't do anything with this module _modules[module] = dict return dict _modules[module] = dict classstack = [] # stack of (class, indent) pairs indent = 0 try: src = Utilities.readEncodedFile(file)[0] except (UnicodeError, IOError): # can't do anything with this module _modules[module] = dict return dict lineno, last_lineno_pos = 1, 0 lastGlobalEntry = None cur_obj = None i = 0 while True: m = _getnext(src, i) if not m: break start, i = m.span() if m.start("Method") >= 0: # found a method definition or function thisindent = indent meth_name = m.group("MethodName") meth_sig = m.group("MethodSignature") meth_sig = meth_sig and meth_sig.replace('\\\n', '') or '' meth_sig = _commentsub('', meth_sig) meth_sig = _normalize(' ', meth_sig) lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start # close all interfaces/modules indented at least as much while classstack and \ classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] if classstack: # it's an interface/module method cur_class = classstack[-1][0] if isinstance(cur_class, Interface) or \ isinstance(cur_class, Module): # it's a method f = Function(None, meth_name, file, lineno, meth_sig) cur_class._addmethod(meth_name, f) # else it's a nested def else: f = None else: # it's a function f = Function(module, meth_name, file, lineno, meth_sig) if meth_name in dict_counts: dict_counts[meth_name] += 1 meth_name = "{0}_{1:d}".format( meth_name, dict_counts[meth_name]) else: dict_counts[meth_name] = 0 dict[meth_name] = f if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = f if cur_obj and isinstance(cur_obj, Function): cur_obj.setEndLine(lineno - 1) cur_obj = f classstack.append((f, thisindent)) # Marker for nested fns elif m.start("String") >= 0: pass elif m.start("Comment") >= 0: pass elif m.start("Interface") >= 0: # we found an interface definition thisindent = indent indent += 1 # close all interfaces/modules indented at least as much while classstack and \ classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start class_name = m.group("InterfaceName") inherit = m.group("InterfaceSupers") if inherit: # the interface inherits from other interfaces inherit = inherit[1:].strip() inherit = [_commentsub('', inherit)] # remember this interface cur_class = Interface(module, class_name, inherit, file, lineno) if not classstack: dict[class_name] = cur_class else: cls = classstack[-1][0] cls._addclass(class_name, cur_class) if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = cur_class if cur_obj and isinstance(cur_obj, Function): cur_obj.setEndLine(lineno - 1) cur_obj = cur_class classstack.append((cur_class, thisindent)) elif m.start("Module") >= 0: # we found a module definition thisindent = indent indent += 1 # close all interfaces/modules indented at least as much while classstack and \ classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start module_name = m.group("ModuleName") # remember this module cur_class = Module(module, module_name, file, lineno) if not classstack: dict[module_name] = cur_class if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = cur_class if cur_obj and isinstance(cur_obj, Function): cur_obj.setEndLine(lineno - 1) cur_obj = cur_class classstack.append((cur_class, thisindent)) elif m.start("Attribute") >= 0: lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start index = -1 while index >= -len(classstack): if classstack[index][0] is not None and \ not isinstance(classstack[index][0], Function) and \ not classstack[index][1] >= indent: attributes = m.group("AttributeNames").split(',') ro = m.group("AttributeReadonly") for attribute in attributes: attr = Attribute(module, attribute, file, lineno) if ro: attr.setPrivate() classstack[index][0]._addattribute(attr) break else: index -= 1 if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = None elif m.start("Begin") >= 0: # a begin of a block we are not interested in indent += 1 elif m.start("End") >= 0: # an end of a block indent -= 1 else: assert 0, "regexp _getnext found something unexpected" return dict
def readmodule_ex(module, path=[]): """ Read a CORBA IDL file and return a dictionary of classes, functions and modules. @param module name of the CORBA IDL file (string) @param path path the file should be searched in (list of strings) @return the resulting dictionary """ global _modules dict = {} dict_counts = {} if module in _modules: # we've seen this file before... return _modules[module] # search the path for the file f = None fullpath = list(path) f, file, (suff, mode, type) = ClassBrowsers.find_module(module, fullpath) if f: f.close() if type not in SUPPORTED_TYPES: # not CORBA IDL source, can't do anything with this module _modules[module] = dict return dict _modules[module] = dict classstack = [] # stack of (class, indent) pairs indent = 0 try: src = Utilities.readEncodedFile(file)[0] except (UnicodeError, IOError): # can't do anything with this module _modules[module] = dict return dict lineno, last_lineno_pos = 1, 0 lastGlobalEntry = None cur_obj = None i = 0 while True: m = _getnext(src, i) if not m: break start, i = m.span() if m.start("Method") >= 0: # found a method definition or function thisindent = indent meth_name = m.group("MethodName") meth_sig = m.group("MethodSignature") meth_sig = meth_sig and meth_sig.replace('\\\n', '') or '' meth_sig = _commentsub('', meth_sig) meth_sig = _normalize(' ', meth_sig) lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start # close all interfaces/modules indented at least as much while classstack and \ classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] if classstack: # it's an interface/module method cur_class = classstack[-1][0] if isinstance(cur_class, Interface) or \ isinstance(cur_class, Module): # it's a method f = Function(None, meth_name, file, lineno, meth_sig) cur_class._addmethod(meth_name, f) # else it's a nested def else: f = None else: # it's a function f = Function(module, meth_name, file, lineno, meth_sig) if meth_name in dict_counts: dict_counts[meth_name] += 1 meth_name = "{0}_{1:d}".format(meth_name, dict_counts[meth_name]) else: dict_counts[meth_name] = 0 dict[meth_name] = f if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = f if cur_obj and isinstance(cur_obj, Function): cur_obj.setEndLine(lineno - 1) cur_obj = f classstack.append((f, thisindent)) # Marker for nested fns elif m.start("String") >= 0: pass elif m.start("Comment") >= 0: pass elif m.start("Interface") >= 0: # we found an interface definition thisindent = indent indent += 1 # close all interfaces/modules indented at least as much while classstack and \ classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start class_name = m.group("InterfaceName") inherit = m.group("InterfaceSupers") if inherit: # the interface inherits from other interfaces inherit = inherit[1:].strip() inherit = [_commentsub('', inherit)] # remember this interface cur_class = Interface(module, class_name, inherit, file, lineno) if not classstack: dict[class_name] = cur_class else: cls = classstack[-1][0] cls._addclass(class_name, cur_class) if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = cur_class if cur_obj and isinstance(cur_obj, Function): cur_obj.setEndLine(lineno - 1) cur_obj = cur_class classstack.append((cur_class, thisindent)) elif m.start("Module") >= 0: # we found a module definition thisindent = indent indent += 1 # close all interfaces/modules indented at least as much while classstack and \ classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start module_name = m.group("ModuleName") # remember this module cur_class = Module(module, module_name, file, lineno) if not classstack: dict[module_name] = cur_class if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = cur_class if cur_obj and isinstance(cur_obj, Function): cur_obj.setEndLine(lineno - 1) cur_obj = cur_class classstack.append((cur_class, thisindent)) elif m.start("Attribute") >= 0: lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start index = -1 while index >= -len(classstack): if classstack[index][0] is not None and \ not isinstance(classstack[index][0], Function) and \ not classstack[index][1] >= indent: attributes = m.group("AttributeNames").split(',') ro = m.group("AttributeReadonly") for attribute in attributes: attr = Attribute(module, attribute, file, lineno) if ro: attr.setPrivate() classstack[index][0]._addattribute(attr) break else: index -= 1 if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = None elif m.start("Begin") >= 0: # a begin of a block we are not interested in indent += 1 elif m.start("End") >= 0: # an end of a block indent -= 1 else: assert 0, "regexp _getnext found something unexpected" return dict
def readmodule_ex(module, path=[]): """ Read a Ruby file and return a dictionary of classes, functions and modules. @param module name of the Ruby file (string) @param path path the file should be searched in (list of strings) @return the resulting dictionary """ global _modules dict = {} dict_counts = {} if module in _modules: # we've seen this file before... return _modules[module] # search the path for the file f = None fullpath = list(path) f, file, (suff, mode, type) = ClassBrowsers.find_module(module, fullpath) if f: f.close() if type not in SUPPORTED_TYPES: # not Ruby source, can't do anything with this module _modules[module] = dict return dict _modules[module] = dict classstack = [] # stack of (class, indent) pairs acstack = [] # stack of (access control, indent) pairs indent = 0 try: src = Utilities.readEncodedFile(file)[0] except (UnicodeError, IOError): # can't do anything with this module _modules[module] = dict return dict lineno, last_lineno_pos = 1, 0 cur_obj = None lastGlobalEntry = None i = 0 while True: m = _getnext(src, i) if not m: break start, i = m.span() if m.start("Method") >= 0: # found a method definition or function thisindent = indent indent += 1 meth_name = m.group("MethodName") or \ m.group("MethodName2") or \ m.group("MethodName3") meth_sig = m.group("MethodSignature") meth_sig = meth_sig and meth_sig.replace('\\\n', '') or '' meth_sig = _commentsub('', meth_sig) lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start if meth_name.startswith('self.'): meth_name = meth_name[5:] elif meth_name.startswith('self::'): meth_name = meth_name[6:] # close all classes/modules indented at least as much while classstack and \ classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] while acstack and \ acstack[-1][1] >= thisindent: del acstack[-1] if classstack: # it's a class/module method cur_class = classstack[-1][0] if isinstance(cur_class, Class) or \ isinstance(cur_class, Module): # it's a method f = Function(None, meth_name, file, lineno, meth_sig) cur_class._addmethod(meth_name, f) else: f = cur_class # set access control if acstack: accesscontrol = acstack[-1][0] if accesscontrol == "private": f.setPrivate() elif accesscontrol == "protected": f.setProtected() elif accesscontrol == "public": f.setPublic() # else it's a nested def else: # it's a function f = Function(module, meth_name, file, lineno, meth_sig) if meth_name in dict_counts: dict_counts[meth_name] += 1 meth_name = "{0}_{1:d}".format( meth_name, dict_counts[meth_name]) else: dict_counts[meth_name] = 0 dict[meth_name] = f if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = f if cur_obj and isinstance(cur_obj, Function): cur_obj.setEndLine(lineno - 1) cur_obj = f classstack.append((f, thisindent)) # Marker for nested fns elif m.start("String") >= 0: pass elif m.start("Comment") >= 0: pass elif m.start("ClassIgnored") >= 0: pass elif m.start("Class") >= 0: # we found a class definition thisindent = indent indent += 1 lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start # close all classes/modules indented at least as much while classstack and \ classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] class_name = m.group("ClassName") or m.group("ClassName2") inherit = m.group("ClassSupers") if inherit: # the class inherits from other classes inherit = inherit[1:].strip() inherit = [_commentsub('', inherit)] # remember this class cur_class = Class(module, class_name, inherit, file, lineno) if not classstack: if class_name in dict: cur_class = dict[class_name] else: dict[class_name] = cur_class else: cls = classstack[-1][0] if class_name in cls.classes: cur_class = cls.classes[class_name] elif cls.name == class_name or class_name == "self": cur_class = cls else: cls._addclass(class_name, cur_class) if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = cur_class cur_obj = cur_class classstack.append((cur_class, thisindent)) while acstack and \ acstack[-1][1] >= thisindent: del acstack[-1] acstack.append(["public", thisindent]) # default access control is 'public' elif m.start("Module") >= 0: # we found a module definition thisindent = indent indent += 1 lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start # close all classes/modules indented at least as much while classstack and \ classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] module_name = m.group("ModuleName") # remember this class cur_class = Module(module, module_name, file, lineno) if not classstack: if module_name in dict: cur_class = dict[module_name] else: dict[module_name] = cur_class else: cls = classstack[-1][0] if module_name in cls.classes: cur_class = cls.classes[module_name] elif cls.name == module_name: cur_class = cls else: cls._addclass(module_name, cur_class) if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = cur_class cur_obj = cur_class classstack.append((cur_class, thisindent)) while acstack and \ acstack[-1][1] >= thisindent: del acstack[-1] acstack.append(["public", thisindent]) # default access control is 'public' elif m.start("AccessControl") >= 0: aclist = m.group("AccessControlList") if aclist is None: index = -1 while index >= -len(acstack): if acstack[index][1] < indent: actype = m.group("AccessControlType") or \ m.group("AccessControlType2").split('_')[0] acstack[index][0] = actype.lower() break else: index -= 1 else: index = -1 while index >= -len(classstack): if classstack[index][0] is not None and \ not isinstance(classstack[index][0], Function) and \ not classstack[index][1] >= indent: parent = classstack[index][0] actype = m.group("AccessControlType") or \ m.group("AccessControlType2").split('_')[0] actype = actype.lower() for name in aclist.split(","): name = name.strip()[1:] # get rid of leading ':' acmeth = parent._getmethod(name) if acmeth is None: continue if actype == "private": acmeth.setPrivate() elif actype == "protected": acmeth.setProtected() elif actype == "public": acmeth.setPublic() break else: index -= 1 elif m.start("Attribute") >= 0: lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start index = -1 while index >= -len(classstack): if classstack[index][0] is not None and \ not isinstance(classstack[index][0], Function) and \ not classstack[index][1] >= indent: attr = Attribute( module, m.group("AttributeName"), file, lineno) classstack[index][0]._addattribute(attr) break else: index -= 1 if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = None elif m.start("Attr") >= 0: lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start index = -1 while index >= -len(classstack): if classstack[index][0] is not None and \ not isinstance(classstack[index][0], Function) and \ not classstack[index][1] >= indent: parent = classstack[index][0] if m.group("AttrType") is None: nv = m.group("AttrList").split(",") if not nv: break name = nv[0].strip()[1:] # get rid of leading ':' attr = parent._getattribute("@" + name) or \ parent._getattribute("@@" + name) or \ Attribute(module, "@" + name, file, lineno) if len(nv) == 1 or nv[1].strip() == "false": attr.setProtected() elif nv[1].strip() == "true": attr.setPublic() parent._addattribute(attr) else: access = m.group("AttrType") for name in m.group("AttrList").split(","): name = name.strip()[1:] # get rid of leading ':' attr = parent._getattribute("@" + name) or \ parent._getattribute("@@" + name) or \ Attribute(module, "@" + name, file, lineno) if access == "_accessor": attr.setPublic() elif access == "_reader" or access == "_writer": if attr.isPrivate(): attr.setProtected() elif attr.isProtected(): attr.setPublic() parent._addattribute(attr) break else: index -= 1 elif m.start("Begin") >= 0: # a begin of a block we are not interested in indent += 1 elif m.start("End") >= 0: # an end of a block indent -= 1 if indent < 0: # no negative indent allowed if classstack: # it's a class/module method indent = classstack[-1][1] else: indent = 0 elif m.start("BeginEnd") >= 0: pass elif m.start("CodingLine") >= 0: # a coding statement coding = m.group("Coding") lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start if "@@Coding@@" not in dict: dict["@@Coding@@"] = ClbrBaseClasses.Coding( module, file, lineno, coding) else: assert 0, "regexp _getnext found something unexpected" return dict
def readmodule_ex(module, path=[], inpackage=False, isPyFile=False): """ Read a module file and return a dictionary of classes. Search for MODULE in PATH and sys.path, read and parse the module and return a dictionary with one entry for each class found in the module. @param module name of the module file (string) @param path path the module should be searched in (list of strings) @param inpackage flag indicating a module inside a package is scanned @param isPyFile flag indicating a Python file (boolean) @return the resulting dictionary """ global _modules dict = {} dict_counts = {} if module in _modules: # we've seen this module before... return _modules[module] if module in sys.builtin_module_names: # this is a built-in module _modules[module] = dict return dict # search the path for the module f = None if inpackage: try: f, file, (suff, mode, type) = \ ClassBrowsers.find_module(module, path) except ImportError: f = None if f is None: fullpath = list(path) + sys.path f, file, (suff, mode, type) = \ ClassBrowsers.find_module(module, fullpath, isPyFile) if module.endswith(".py") and type == imp.PKG_DIRECTORY: return dict if type == imp.PKG_DIRECTORY: dict['__path__'] = [file] _modules[module] = dict path = [file] + path f, file, (suff, mode, type) = \ ClassBrowsers.find_module('__init__', [file]) if f: f.close() if type not in SUPPORTED_TYPES: # not Python source, can't do anything with this module _modules[module] = dict return dict _modules[module] = dict classstack = [] # stack of (class, indent) pairs conditionalsstack = [] # stack of indents of conditional defines deltastack = [] deltaindent = 0 deltaindentcalculated = 0 try: src = Utilities.readEncodedFile(file)[0] except (UnicodeError, IOError): # can't do anything with this module _modules[module] = dict return dict lineno, last_lineno_pos = 1, 0 lastGlobalEntry = None cur_obj = None i = 0 modifierType = ClbrBaseClasses.Function.General modifierIndent = -1 while True: m = _getnext(src, i) if not m: break start, i = m.span() if m.start("MethodModifier") >= 0: modifierIndent = _indent(m.group("MethodModifierIndent")) modifierType = m.group("MethodModifierType") elif m.start("Method") >= 0: # found a method definition or function thisindent = _indent(m.group("MethodIndent")) meth_name = m.group("MethodName") meth_sig = m.group("MethodSignature") meth_sig = meth_sig.replace('\\\n', '') meth_sig = _commentsub('', meth_sig) meth_ret = m.group("MethodReturnAnnotation") meth_ret = meth_ret.replace('\\\n', '') meth_ret = _commentsub('', meth_ret) lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start if modifierType and modifierIndent == thisindent: if modifierType == "@staticmethod": modifier = ClbrBaseClasses.Function.Static elif modifierType == "@classmethod": modifier = ClbrBaseClasses.Function.Class else: modifier = ClbrBaseClasses.Function.General else: modifier = ClbrBaseClasses.Function.General # modify indentation level for conditional defines if conditionalsstack: if thisindent > conditionalsstack[-1]: if not deltaindentcalculated: deltastack.append(thisindent - conditionalsstack[-1]) deltaindent = reduce(lambda x, y: x + y, deltastack) deltaindentcalculated = 1 thisindent -= deltaindent else: while conditionalsstack and \ conditionalsstack[-1] >= thisindent: del conditionalsstack[-1] if deltastack: del deltastack[-1] deltaindentcalculated = 0 # close all classes indented at least as much while classstack and \ classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] if classstack: # it's a class method cur_class = classstack[-1][0] if cur_class: # it's a method/nested def f = Function(None, meth_name, file, lineno, meth_sig, annotation=meth_ret, modifierType=modifier) cur_class._addmethod(meth_name, f) else: # it's a function f = Function(module, meth_name, file, lineno, meth_sig, annotation=meth_ret, modifierType=modifier) if meth_name in dict_counts: dict_counts[meth_name] += 1 meth_name = "{0}_{1:d}".format(meth_name, dict_counts[meth_name]) else: dict_counts[meth_name] = 0 dict[meth_name] = f if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = f if cur_obj and isinstance(cur_obj, Function): cur_obj.setEndLine(lineno - 1) cur_obj = f classstack.append((f, thisindent)) # Marker for nested fns # reset the modifier settings modifierType = ClbrBaseClasses.Function.General modifierIndent = -1 elif m.start("String") >= 0: pass elif m.start("Class") >= 0: # we found a class definition thisindent = _indent(m.group("ClassIndent")) # close all classes indented at least as much while classstack and \ classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start class_name = m.group("ClassName") inherit = m.group("ClassSupers") if inherit: # the class inherits from other classes inherit = inherit[1:-1].strip() inherit = _commentsub('', inherit) names = [] for n in inherit.split(','): n = n.strip() if n in dict: # we know this super class n = dict[n] else: c = n.split('.') if len(c) > 1: # super class # is of the # form module.class: # look in # module for class m = c[-2] c = c[-1] if m in _modules: d = _modules[m] if c in d: n = d[c] names.append(n) inherit = names # remember this class cur_class = Class(module, class_name, inherit, file, lineno) if not classstack: if class_name in dict_counts: dict_counts[class_name] += 1 class_name = "{0}_{1:d}".format(class_name, dict_counts[class_name]) else: dict_counts[class_name] = 0 dict[class_name] = cur_class else: classstack[-1][0]._addclass(class_name, cur_class) if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = cur_class classstack.append((cur_class, thisindent)) elif m.start("Attribute") >= 0: lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start index = -1 while index >= -len(classstack): if classstack[index][0] is not None and \ not isinstance(classstack[index][0], Function): attr = Attribute(module, m.group("AttributeName"), file, lineno) classstack[index][0]._addattribute(attr) break else: index -= 1 elif m.start("Variable") >= 0: thisindent = _indent(m.group("VariableIndent")) variable_name = m.group("VariableName") lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start if thisindent == 0: # global variable if "@@Globals@@" not in dict: dict["@@Globals@@"] = ClbrBaseClasses.ClbrBase( module, "Globals", file, lineno) dict["@@Globals@@"]._addglobal( Attribute(module, variable_name, file, lineno)) if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = None else: index = -1 while index >= -len(classstack): if classstack[index][1] >= thisindent: index -= 1 else: if isinstance(classstack[index][0], Class): classstack[index][0]._addglobal( Attribute(module, variable_name, file, lineno)) break elif m.start("Publics") >= 0: idents = m.group("Identifiers") lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start pubs = Publics(module, file, lineno, idents) dict['__all__'] = pubs elif m.start("ConditionalDefine") >= 0: # a conditional function/method definition thisindent = _indent(m.group("ConditionalDefineIndent")) while conditionalsstack and \ conditionalsstack[-1] >= thisindent: del conditionalsstack[-1] if deltastack: del deltastack[-1] conditionalsstack.append(thisindent) deltaindentcalculated = 0 elif m.start("CodingLine") >= 0: # a coding statement coding = m.group("Coding") lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start if "@@Coding@@" not in dict: dict["@@Coding@@"] = ClbrBaseClasses.Coding( module, file, lineno, coding) else: assert 0, "regexp _getnext found something unexpected" if '__all__' in dict: # set visibility of all top level elements pubs = dict['__all__'] for key in list(list(dict.keys())): if key == '__all__' or key.startswith("@@"): continue if key in pubs.identifiers: dict[key].setPublic() else: dict[key].setPrivate() del dict['__all__'] return dict
def readmodule_ex(module, path=[], inpackage=False, isPyFile=False): """ Read a module file and return a dictionary of classes. Search for MODULE in PATH and sys.path, read and parse the module and return a dictionary with one entry for each class found in the module. @param module name of the module file (string) @param path path the module should be searched in (list of strings) @param inpackage flag indicating a module inside a package is scanned @param isPyFile flag indicating a Python file (boolean) @return the resulting dictionary """ global _modules dict = {} dict_counts = {} if module in _modules: # we've seen this module before... return _modules[module] if module in sys.builtin_module_names: # this is a built-in module _modules[module] = dict return dict # search the path for the module f = None if inpackage: try: f, file, (suff, mode, type) = \ ClassBrowsers.find_module(module, path) except ImportError: f = None if f is None: fullpath = list(path) + sys.path f, file, (suff, mode, type) = \ ClassBrowsers.find_module(module, fullpath, isPyFile) if module.endswith(".py") and type == imp.PKG_DIRECTORY: return dict if type == imp.PKG_DIRECTORY: dict['__path__'] = [file] _modules[module] = dict path = [file] + path f, file, (suff, mode, type) = \ ClassBrowsers.find_module('__init__', [file]) if f: f.close() if type not in SUPPORTED_TYPES: # not Python source, can't do anything with this module _modules[module] = dict return dict _modules[module] = dict classstack = [] # stack of (class, indent) pairs conditionalsstack = [] # stack of indents of conditional defines deltastack = [] deltaindent = 0 deltaindentcalculated = 0 try: src = Utilities.readEncodedFile(file)[0] except (UnicodeError, IOError): # can't do anything with this module _modules[module] = dict return dict lineno, last_lineno_pos = 1, 0 lastGlobalEntry = None cur_obj = None i = 0 modifierType = ClbrBaseClasses.Function.General modifierIndent = -1 while True: m = _getnext(src, i) if not m: break start, i = m.span() if m.start("MethodModifier") >= 0: modifierIndent = _indent(m.group("MethodModifierIndent")) modifierType = m.group("MethodModifierType") elif m.start("Method") >= 0: # found a method definition or function thisindent = _indent(m.group("MethodIndent")) meth_name = m.group("MethodName") meth_sig = m.group("MethodSignature") meth_sig = meth_sig.replace('\\\n', '') meth_sig = _commentsub('', meth_sig) meth_ret = m.group("MethodReturnAnnotation") meth_ret = meth_ret.replace('\\\n', '') meth_ret = _commentsub('', meth_ret) lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start if modifierType and modifierIndent == thisindent: if modifierType == "@staticmethod": modifier = ClbrBaseClasses.Function.Static elif modifierType == "@classmethod": modifier = ClbrBaseClasses.Function.Class else: modifier = ClbrBaseClasses.Function.General else: modifier = ClbrBaseClasses.Function.General # modify indentation level for conditional defines if conditionalsstack: if thisindent > conditionalsstack[-1]: if not deltaindentcalculated: deltastack.append(thisindent - conditionalsstack[-1]) deltaindent = reduce(lambda x, y: x + y, deltastack) deltaindentcalculated = 1 thisindent -= deltaindent else: while conditionalsstack and \ conditionalsstack[-1] >= thisindent: del conditionalsstack[-1] if deltastack: del deltastack[-1] deltaindentcalculated = 0 # close all classes indented at least as much while classstack and \ classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] if classstack: # it's a class method cur_class = classstack[-1][0] if cur_class: # it's a method/nested def f = Function(None, meth_name, file, lineno, meth_sig, annotation=meth_ret, modifierType=modifier) cur_class._addmethod(meth_name, f) else: # it's a function f = Function(module, meth_name, file, lineno, meth_sig, annotation=meth_ret, modifierType=modifier) if meth_name in dict_counts: dict_counts[meth_name] += 1 meth_name = "{0}_{1:d}".format( meth_name, dict_counts[meth_name]) else: dict_counts[meth_name] = 0 dict[meth_name] = f if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = f if cur_obj and isinstance(cur_obj, Function): cur_obj.setEndLine(lineno - 1) cur_obj = f classstack.append((f, thisindent)) # Marker for nested fns # reset the modifier settings modifierType = ClbrBaseClasses.Function.General modifierIndent = -1 elif m.start("String") >= 0: pass elif m.start("Class") >= 0: # we found a class definition thisindent = _indent(m.group("ClassIndent")) # close all classes indented at least as much while classstack and \ classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start class_name = m.group("ClassName") inherit = m.group("ClassSupers") if inherit: # the class inherits from other classes inherit = inherit[1:-1].strip() inherit = _commentsub('', inherit) names = [] for n in inherit.split(','): n = n.strip() if n in dict: # we know this super class n = dict[n] else: c = n.split('.') if len(c) > 1: # super class # is of the # form module.class: # look in # module for class m = c[-2] c = c[-1] if m in _modules: d = _modules[m] if c in d: n = d[c] names.append(n) inherit = names # remember this class cur_class = Class(module, class_name, inherit, file, lineno) if not classstack: if class_name in dict_counts: dict_counts[class_name] += 1 class_name = "{0}_{1:d}".format( class_name, dict_counts[class_name]) else: dict_counts[class_name] = 0 dict[class_name] = cur_class else: classstack[-1][0]._addclass(class_name, cur_class) if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = cur_class classstack.append((cur_class, thisindent)) elif m.start("Attribute") >= 0: lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start index = -1 while index >= -len(classstack): if classstack[index][0] is not None and \ not isinstance(classstack[index][0], Function): attr = Attribute( module, m.group("AttributeName"), file, lineno) classstack[index][0]._addattribute(attr) break else: index -= 1 elif m.start("Variable") >= 0: thisindent = _indent(m.group("VariableIndent")) variable_name = m.group("VariableName") lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start if thisindent == 0: # global variable if "@@Globals@@" not in dict: dict["@@Globals@@"] = ClbrBaseClasses.ClbrBase( module, "Globals", file, lineno) dict["@@Globals@@"]._addglobal( Attribute(module, variable_name, file, lineno)) if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = None else: index = -1 while index >= -len(classstack): if classstack[index][1] >= thisindent: index -= 1 else: if isinstance(classstack[index][0], Class): classstack[index][0]._addglobal( Attribute(module, variable_name, file, lineno)) break elif m.start("Publics") >= 0: idents = m.group("Identifiers") lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start pubs = Publics(module, file, lineno, idents) dict['__all__'] = pubs elif m.start("Import") >= 0: # import module names = [n.strip() for n in "".join(m.group("ImportList").splitlines()) .replace("\\", "").split(',')] lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start if "@@Import@@" not in dict: dict["@@Import@@"] = Imports(module, file) for name in names: dict["@@Import@@"].addImport(name, [], lineno) elif m.start("ImportFrom") >= 0: # from module import stuff mod = m.group("ImportFromPath") namesLines = (m.group("ImportFromList") .replace("(", "").replace(")", "") .replace("\\", "") .strip().splitlines()) namesLines = [line.split("#")[0].strip() for line in namesLines] names = [n.strip() for n in "".join(namesLines) .split(',')] lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start if "@@Import@@" not in dict: dict["@@Import@@"] = Imports(module, file) dict["@@Import@@"].addImport(mod, names, lineno) elif m.start("ConditionalDefine") >= 0: # a conditional function/method definition thisindent = _indent(m.group("ConditionalDefineIndent")) while conditionalsstack and \ conditionalsstack[-1] >= thisindent: del conditionalsstack[-1] if deltastack: del deltastack[-1] conditionalsstack.append(thisindent) deltaindentcalculated = 0 elif m.start("CodingLine") >= 0: # a coding statement coding = m.group("Coding") lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start if "@@Coding@@" not in dict: dict["@@Coding@@"] = ClbrBaseClasses.Coding( module, file, lineno, coding) else: assert 0, "regexp _getnext found something unexpected" if '__all__' in dict: # set visibility of all top level elements pubs = dict['__all__'] for key in list(list(dict.keys())): if key == '__all__' or key.startswith("@@"): continue if key in pubs.identifiers: dict[key].setPublic() else: dict[key].setPrivate() del dict['__all__'] return dict
def readmodule_ex(module, path=None): """ Read a ProtoBuf protocol file and return a dictionary of messages, enums, services and rpc methods. @param module name of the ProtoBuf protocol file @type str @param path path the file should be searched in @type list of str @return the resulting dictionary @rtype dict """ global _modules dictionary = {} if module in _modules: # we've seen this file before... return _modules[module] # search the path for the file f = None fullpath = [] if path is None else path[:] f, file, (suff, mode, type) = ClassBrowsers.find_module(module, fullpath) if f: f.close() if type not in SUPPORTED_TYPES: # not ProtoBuf protocol source, can't do anything with this module _modules[module] = dictionary return dictionary _modules[module] = dictionary classstack = [] # stack of (class, indent) pairs indent = 0 try: src = Utilities.readEncodedFile(file)[0] except (UnicodeError, IOError): # can't do anything with this module _modules[module] = dictionary return dictionary lineno, last_lineno_pos = 1, 0 lastGlobalEntry = None cur_obj = None i = 0 while True: m = _getnext(src, i) if not m: break start, i = m.span() if m.start("Method") >= 0: # found a method definition or function thisindent = indent meth_name = m.group("MethodName") meth_sig = m.group("MethodSignature") meth_sig = meth_sig and meth_sig.replace('\\\n', '') or '' meth_sig = _commentsub('', meth_sig) meth_sig = _normalize(' ', meth_sig) meth_return = m.group("MethodReturn") meth_return = meth_return and meth_return.replace('\\\n', '') or '' meth_return = _commentsub('', meth_return) meth_return = _normalize(' ', meth_return) lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start # close all interfaces/modules indented at least as much while classstack and classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] if classstack: # it's an interface/module method cur_class = classstack[-1][0] if isinstance(cur_class, Service): # it's a method f = ServiceMethod(meth_name, file, lineno, meth_sig, meth_return) cur_class._addmethod(meth_name, f) # else it's a nested def else: f = None else: # the file is incorrect, ignore the entry continue if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = f if cur_obj and isinstance(cur_obj, ServiceMethod): cur_obj.setEndLine(lineno - 1) cur_obj = f classstack.append((f, thisindent)) # Marker for nested fns elif m.start("String") >= 0: pass elif m.start("Comment") >= 0: pass elif m.start("Message") >= 0: # we found a message definition thisindent = indent indent += 1 # close all messages/services indented at least as much while classstack and classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start message_name = m.group("MessageName") # remember this message cur_class = Message(module, message_name, file, lineno) if not classstack: dictionary[message_name] = cur_class else: msg = classstack[-1][0] msg._addclass(message_name, cur_class) if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = cur_class cur_obj = cur_class classstack.append((cur_class, thisindent)) elif m.start("Enum") >= 0: # we found a message definition thisindent = indent indent += 1 # close all messages/services indented at least as much while classstack and classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start enum_name = m.group("EnumName") # remember this Enum cur_class = Enum(module, enum_name, file, lineno) if not classstack: dictionary[enum_name] = cur_class else: enum = classstack[-1][0] enum._addclass(enum_name, cur_class) if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = cur_class cur_obj = cur_class classstack.append((cur_class, thisindent)) elif m.start("Service") >= 0: # we found a message definition thisindent = indent indent += 1 # close all messages/services indented at least as much while classstack and classstack[-1][1] >= thisindent: if classstack[-1][0] is not None: # record the end line classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] lineno = lineno + src.count('\n', last_lineno_pos, start) last_lineno_pos = start service_name = m.group("ServiceName") # remember this Service cur_class = Service(module, service_name, file, lineno) if not classstack: dictionary[service_name] = cur_class else: service = classstack[-1][0] service._addclass(service_name, cur_class) if not classstack: if lastGlobalEntry: lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = cur_class cur_obj = cur_class classstack.append((cur_class, thisindent)) elif m.start("Begin") >= 0: # a begin of a block we are not interested in indent += 1 elif m.start("End") >= 0: # an end of a block indent -= 1 else: assert 0, "regexp _getnext found something unexpected" return dictionary