--- a/src/eric7/Utilities/ModuleParser.py Thu Jan 12 11:01:36 2023 +0100 +++ b/src/eric7/Utilities/ModuleParser.py Thu Jan 12 11:41:48 2023 +0100 @@ -22,6 +22,8 @@ from functools import reduce +from PyQt6.QtCore import QRegularExpression + from eric7 import Utilities __all__ = [ @@ -64,7 +66,7 @@ return -1 -_py_getnext = re.compile( +_py_getnext = QRegularExpression( r""" (?P<Comment> \# .*? $ # ignore everything in comments @@ -212,10 +214,13 @@ (?: (?: if | elif ) [ \t]+ [^:]* | else [ \t]* ) : (?= \s* (?: async [ \t]+ )? def) )""", - re.VERBOSE | re.DOTALL | re.MULTILINE, -).search + QRegularExpression.PatternOption.MultilineOption + | QRegularExpression.PatternOption.DotMatchesEverythingOption + | QRegularExpression.PatternOption.ExtendedPatternSyntaxOption + | QRegularExpression.PatternOption.UseUnicodePropertiesOption, +).match -_rb_getnext = re.compile( +_rb_getnext = QRegularExpression( r""" (?P<Docstring> =begin [ \t]+ edoc (?P<DocstringContents> .*? ) =end @@ -350,8 +355,11 @@ end \b [^_] ) )""", - re.VERBOSE | re.DOTALL | re.MULTILINE, -).search + QRegularExpression.PatternOption.MultilineOption + | QRegularExpression.PatternOption.DotMatchesEverythingOption + | QRegularExpression.PatternOption.ExtendedPatternSyntaxOption + | QRegularExpression.PatternOption.UseUnicodePropertiesOption, +).match _hashsub = re.compile(r"""^([ \t]*)#[ \t]?""", re.MULTILINE).sub @@ -581,25 +589,25 @@ modifierIndent = -1 while True: m = self._getnext(src, i) - if not m: + if not m.hasMatch(): break - start, i = m.span() + start, i = m.capturedStart(), m.capturedEnd() - if m.start("MethodModifier") >= 0: - modifierIndent = _indent(m.group("MethodModifierIndent")) - modifierType = m.group("MethodModifierType") + if m.hasCaptured("MethodModifier"): + modifierIndent = _indent(m.captured("MethodModifierIndent")) + modifierType = m.captured("MethodModifierType") - elif m.start("Method") >= 0: + elif m.hasCaptured("Method"): # found a method definition or function - thisindent = _indent(m.group("MethodIndent")) - meth_name = m.group("MethodName") - meth_sig = m.group("MethodSignature") + thisindent = _indent(m.captured("MethodIndent")) + meth_name = m.captured("MethodName") + meth_sig = m.captured("MethodSignature") meth_sig = meth_sig.replace("\\\n", "") - meth_ret = m.group("MethodReturnAnnotation") + meth_ret = m.captured("MethodReturnAnnotation") meth_ret = meth_ret.replace("\\\n", "") - if m.group("MethodPyQtSignature") is not None: + if m.captured("MethodPyQtSignature"): meth_pyqtSig = ( - m.group("MethodPyQtSignature") + m.captured("MethodPyQtSignature") .replace("\\\n", "") .split("result")[0] .split("name")[0] @@ -696,49 +704,49 @@ modifierType = Function.General modifierIndent = -1 - elif m.start("Docstring") >= 0: - contents = m.group("DocstringContents3") - if contents is not None: + elif m.hasCaptured("Docstring"): + contents = m.captured("DocstringContents3") + if contents: contents = _hashsub(r"\1", contents) else: if self.file.lower().endswith(".ptl"): contents = "" else: - contents = m.group("DocstringContents1") or m.group( + contents = m.captured("DocstringContents1") or m.captured( "DocstringContents2" ) if cur_obj: cur_obj.addDescription(contents) - elif m.start("String") >= 0: + elif m.hasCaptured("String"): if modulelevel and ( src[start - len("\r\n") : start] == "\r\n" or src[start - len("\n") : start] == "\n" or src[start - len("\r") : start] == "\r" ): - contents = m.group("StringContents3") - if contents is not None: + contents = m.captured("StringContents3") + if contents: contents = _hashsub(r"\1", contents) else: if self.file.lower().endswith(".ptl"): contents = "" else: - contents = m.group("StringContents1") or m.group( + contents = m.captured("StringContents1") or m.captured( "StringContents2" ) if cur_obj: cur_obj.addDescription(contents) - elif m.start("Class") >= 0: + elif m.hasCaptured("Class"): # we found a class definition - thisindent = _indent(m.group("ClassIndent")) + thisindent = _indent(m.captured("ClassIndent")) lineno += src.count("\n", last_lineno_pos, start) last_lineno_pos = start # close all classes indented at least as much while classstack and classstack[-1][1] >= thisindent: del classstack[-1] - class_name = m.group("ClassName") - inherit = m.group("ClassSupers") + class_name = m.captured("ClassName") + inherit = m.captured("ClassSupers") if inherit: # the class inherits from other classes inherit = inherit[1:-1].strip() @@ -787,13 +795,13 @@ # add nested classes to the module classstack.append((cur_class, thisindent)) - elif m.start("Attribute") >= 0: + elif m.hasCaptured("Attribute"): 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: - attrName = m.group("AttributeName") + attrName = m.captured("AttributeName") attr = Attribute(self.name, attrName, self.file, lineno) self.__py_setVisibility(attr) classstack[index][0].addAttribute(attrName, attr) @@ -801,16 +809,16 @@ else: index -= 1 - elif m.start("Main") >= 0: + elif m.hasCaptured("Main"): # 'main' part of the script, reset class stack lineno += src.count("\n", last_lineno_pos, start) last_lineno_pos = start classstack = [] - elif m.start("Variable") >= 0: - thisindent = _indent(m.group("VariableIndent")) - variable_name = m.group("VariableName") - isSignal = m.group("VariableSignal") != "" + elif m.hasCaptured("Variable"): + thisindent = _indent(m.captured("VariableIndent")) + variable_name = m.captured("VariableName") + isSignal = m.captured("VariableSignal") != "" lineno += src.count("\n", last_lineno_pos, start) last_lineno_pos = start if thisindent == 0: @@ -840,11 +848,11 @@ classstack[index][0].addGlobal(variable_name, attr) break - elif m.start("Import") >= 0: + elif m.hasCaptured("Import"): # - import module names = [ n.strip() - for n in "".join(m.group("ImportList").splitlines()) + for n in "".join(m.captured("ImportList").splitlines()) .replace("\\", "") .split(",") ] @@ -852,11 +860,11 @@ [name for name in names if name not in self.imports] ) - elif m.start("ImportFrom") >= 0: + elif m.hasCaptured("ImportFrom"): # - from module import stuff - mod = m.group("ImportFromPath") + mod = m.captured("ImportFromPath") namesLines = ( - m.group("ImportFromList") + m.captured("ImportFromList") .replace("(", "") .replace(")", "") .replace("\\", "") @@ -871,9 +879,9 @@ [name for name in names if name not in self.from_imports[mod]] ) - elif m.start("ConditionalDefine") >= 0: + elif m.hasCaptured("ConditionalDefine"): # a conditional function/method definition - thisindent = _indent(m.group("ConditionalDefineIndent")) + thisindent = _indent(m.captured("ConditionalDefineIndent")) while conditionalsstack and conditionalsstack[-1] >= thisindent: del conditionalsstack[-1] if deltastack: @@ -881,7 +889,7 @@ conditionalsstack.append(thisindent) deltaindentcalculated = 0 - elif m.start("Comment") >= 0 and modulelevel: + elif m.hasCaptured("Comment") and modulelevel: continue modulelevel = False @@ -903,20 +911,20 @@ lastGlobalEntry = None while True: m = self._getnext(src, i) - if not m: + if not m.hasMatch(): break - start, i = m.span() + start, i = m.capturedStart(), m.capturedEnd() - if m.start("Method") >= 0: + if m.hasCaptured("Method"): # found a method definition or function thisindent = indent indent += 1 meth_name = ( - m.group("MethodName") - or m.group("MethodName2") - or m.group("MethodName3") + m.captured("MethodName") + or m.captured("MethodName2") + or m.captured("MethodName3") ) - meth_sig = m.group("MethodSignature") + meth_sig = m.captured("MethodSignature") meth_sig = meth_sig and meth_sig.replace("\\\n", "") or "" lineno += src.count("\n", last_lineno_pos, start) last_lineno_pos = start @@ -974,14 +982,14 @@ cur_obj = f classstack.append((None, thisindent)) # Marker for nested fns - elif m.start("Docstring") >= 0: - contents = m.group("DocstringContents") - if contents is not None: + elif m.hasCaptured("Docstring"): + contents = m.captured("DocstringContents") + if contents: contents = _hashsub(r"\1", contents) if cur_obj: cur_obj.addDescription(contents) - elif m.start("Class") >= 0: + elif m.hasCaptured("Class"): # we found a class definition thisindent = indent indent += 1 @@ -995,8 +1003,8 @@ # record the end line of this class, function or module classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] - class_name = m.group("ClassName") or m.group("ClassName2") - inherit = m.group("ClassSupers") + class_name = m.captured("ClassName") or m.captured("ClassName2") + inherit = m.captured("ClassSupers") if inherit: # the class inherits from other classes inherit = inherit[1:].strip() @@ -1029,7 +1037,7 @@ acstack.append(["public", thisindent]) # default access control is 'public' - elif m.start("Module") >= 0: + elif m.hasCaptured("Module"): # we found a module definition thisindent = indent indent += 1 @@ -1043,7 +1051,7 @@ # record the end line of this class, function or module classstack[-1][0].setEndLine(lineno - 1) del classstack[-1] - module_name = m.group("ModuleName") + module_name = m.captured("ModuleName") # remember this class cur_class = RbModule(self.name, module_name, self.file, lineno) # add nested Ruby modules to the file @@ -1062,15 +1070,15 @@ acstack.append(["public", thisindent]) # default access control is 'public' - elif m.start("AccessControl") >= 0: - aclist = m.group("AccessControlList") - if aclist is None: + elif m.hasCaptured("AccessControl"): + aclist = m.captured("AccessControlList") + if not aclist: index = -1 while index >= -len(acstack): if acstack[index][1] < indent: actype = ( - m.group("AccessControlType") - or m.group("AccessControlType2").split("_")[0] + m.captured("AccessControlType") + or m.captured("AccessControlType2").split("_")[0] ) acstack[index][0] = actype.lower() break @@ -1086,8 +1094,8 @@ ): parent = classstack[index][0] actype = ( - m.group("AccessControlType") - or m.group("AccessControlType2").split("_")[0] + m.captured("AccessControlType") + or m.captured("AccessControlType2").split("_")[0] ) actype = actype.lower() for name in aclist.split(","): @@ -1106,7 +1114,7 @@ else: index -= 1 - elif m.start("Attribute") >= 0: + elif m.hasCaptured("Attribute"): lineno += src.count("\n", last_lineno_pos, start) last_lineno_pos = start index = -1 @@ -1116,7 +1124,7 @@ and not isinstance(classstack[index][0], Function) and classstack[index][1] < indent ): - attrName = m.group("AttributeName") + attrName = m.captured("AttributeName") attr = Attribute(self.name, attrName, self.file, lineno) if attrName.startswith("@@") or attrName[0].isupper(): classstack[index][0].addGlobal(attrName, attr) @@ -1126,7 +1134,7 @@ else: index -= 1 else: - attrName = m.group("AttributeName") + attrName = m.captured("AttributeName") if attrName[0] != "@": attr = Attribute(self.name, attrName, self.file, lineno) self.addGlobal(attrName, attr) @@ -1134,7 +1142,7 @@ lastGlobalEntry.setEndLine(lineno - 1) lastGlobalEntry = None - elif m.start("Attr") >= 0: + elif m.hasCaptured("Attr"): lineno += src.count("\n", last_lineno_pos, start) last_lineno_pos = start index = -1 @@ -1145,8 +1153,8 @@ and classstack[index][1] < indent ): parent = classstack[index][0] - if m.group("AttrType") is None: - nv = m.group("AttrList").split(",") + if not m.captured("AttrType"): + nv = m.captured("AttrList").split(",") if not nv: break # get rid of leading ':' @@ -1162,8 +1170,8 @@ attr.setPublic() parent.addAttribute(attr.name, attr) else: - access = m.group("AttrType") - for name in m.group("AttrList").split(","): + access = m.captured("AttrType") + for name in m.captured("AttrList").split(","): # get rid of leading ':' name = name.strip()[1:] attr = ( @@ -1185,11 +1193,11 @@ else: index -= 1 - elif m.start("Begin") >= 0: + elif m.hasCaptured("Begin"): # a begin of a block we are not interested in indent += 1 - elif m.start("End") >= 0: + elif m.hasCaptured("End"): # an end of a block indent -= 1 if indent < 0: @@ -1201,10 +1209,10 @@ indent = 0 elif ( - m.start("String") >= 0 - or m.start("Comment") >= 0 - or m.start("ClassIgnored") >= 0 - or m.start("BeginEnd") >= 0 + m.hasCaptured("String") + or m.hasCaptured("Comment") + or m.hasCaptured("ClassIgnored") + or m.hasCaptured("BeginEnd") ): pass