--- a/Utilities/ModuleParser.py Mon Jul 08 21:47:26 2013 +0200 +++ b/Utilities/ModuleParser.py Mon Jul 08 22:36:10 2013 +0200 @@ -503,6 +503,7 @@ @param src the source text to be scanned (string) """ lineno, last_lineno_pos = 1, 0 + lastGlobalEntry = None classstack = [] # stack of (class, indent) pairs conditionalsstack = [] # stack of indents of conditional defines deltastack = [] @@ -566,11 +567,9 @@ # close all classes indented at least as much while classstack and \ classstack[-1][1] >= thisindent: - if classstack[-1][1] == thisindent and \ - classstack[-1][0] is not None and \ - isinstance(classstack[-1][0], Class): - # we got a class at the same indentation level; - # record the end line of this class + if classstack[-1][0] is not None and \ + isinstance(classstack[-1][0], (Class, Function)): + # record the end line of this class or function classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] if classstack: @@ -601,6 +600,12 @@ meth_sig, meth_pyqtSig, modifierType=modifier) self.__py_setVisibility(f) self.addFunction(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((None, thisindent)) # Marker for nested fns @@ -646,11 +651,9 @@ # close all classes indented at least as much while classstack and \ classstack[-1][1] >= thisindent: - if classstack[-1][1] == thisindent and \ - classstack[-1][0] is not None and \ - isinstance(classstack[-1][0], Class): - # we got a class at the same indentation level; - # record the end line of this class + if classstack[-1][0] is not None and \ + isinstance(classstack[-1][0], (Class, Function)): + # record the end line of this class or function classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] class_name = m.group("ClassName") @@ -686,6 +689,10 @@ cur_obj = cur_class # add nested classes to the module self.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: @@ -714,6 +721,9 @@ isSignal=isSignal) self.__py_setVisibility(attr) self.addGlobal(variable_name, attr) + if lastGlobalEntry: + lastGlobalEntry.setEndLine(lineno - 1) + lastGlobalEntry = None else: index = -1 while index >= -len(classstack): @@ -774,6 +784,7 @@ indent = 0 i = 0 cur_obj = self + lastGlobalEntry = None while True: m = self._getnext(src, i) if not m: @@ -798,6 +809,10 @@ # close all classes/modules indented at least as much while classstack and \ classstack[-1][1] >= thisindent: + if classstack[-1][0] is not None and \ + isinstance(classstack[-1][0], (Class, Function, RbModule)): + # record the end line of this class, function or module + classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] while acstack and \ acstack[-1][1] >= thisindent: @@ -835,6 +850,12 @@ # it's a function f = Function(self.name, meth_name, self.file, lineno, meth_sig) self.addFunction(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((None, thisindent)) # Marker for nested fns @@ -858,12 +879,16 @@ # 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 and \ + isinstance(classstack[-1][0], (Class, Function, RbModule)): + # record the end line of this class, function or module + 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") or m.group("ClassName2") inherit = m.group("ClassSupers") if inherit: @@ -886,23 +911,32 @@ cur_class = classstack[-1][0] else: parent_obj.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' + 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 and \ + isinstance(classstack[-1][0], (Class, Function, RbModule)): + # record the end line of this class, function or module + 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 class cur_class = RbModule(self.name, module_name, @@ -912,12 +946,17 @@ cur_class = self.modules[module_name] else: self.addModule(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' + acstack.append(["public", thisindent]) + # default access control is 'public' elif m.start("AccessControl") >= 0: aclist = m.group("AccessControlList") @@ -978,6 +1017,9 @@ if attrName[0] != "@": attr = Attribute(self.name, attrName, self.file, lineno) self.addGlobal(attrName, attr) + if lastGlobalEntry: + lastGlobalEntry.setEndLine(lineno - 1) + lastGlobalEntry = None elif m.start("Attr") >= 0: lineno = lineno + src.count('\n', last_lineno_pos, start) @@ -1292,6 +1334,7 @@ self.name = name self.file = file self.lineno = lineno + self.endlineno = -1 # marker for "not set" signature = _commentsub('', signature) self.parameters = [e.strip() for e in signature.split(',')] self.description = "" @@ -1306,6 +1349,14 @@ @param description the docstring to be stored (string) """ self.description = description + + def setEndLine(self, endLineNo): + """ + Public method to record the number of the last line of a class. + + @param endLineNo number of the last line (integer) + """ + self.endlineno = endLineNo class Attribute(VisibilityBase):