src/eric7/Utilities/ClassBrowsers/pyclbr.py

branch
eric7
changeset 9693
a7e9fd398e5a
parent 9653
e67609152c5e
child 9733
c5c2a74e9382
equal deleted inserted replaced
9692:a0be29ab700a 9693:a7e9fd398e5a
14 import sys 14 import sys
15 15
16 from dataclasses import dataclass 16 from dataclasses import dataclass
17 from functools import reduce 17 from functools import reduce
18 18
19 from PyQt6.QtCore import QRegularExpression
20
19 from eric7 import Utilities 21 from eric7 import Utilities
20 from eric7.Utilities import ClassBrowsers 22 from eric7.Utilities import ClassBrowsers
21 23
22 from . import ClbrBaseClasses 24 from . import ClbrBaseClasses
23 25
24 TABWIDTH = 4 26 TABWIDTH = 4
25 27
26 SUPPORTED_TYPES = [ClassBrowsers.PY_SOURCE, ClassBrowsers.PTL_SOURCE] 28 SUPPORTED_TYPES = [ClassBrowsers.PY_SOURCE, ClassBrowsers.PTL_SOURCE]
27 29
28 _getnext = re.compile( 30 _getnext = QRegularExpression(
29 r""" 31 r"""
30 (?P<CodingLine> 32 (?P<CodingLine>
31 ^ \# \s* [*_-]* \s* coding[:=] \s* (?P<Coding> [-\w_.]+ ) \s* [*_-]* $ 33 ^ \# \s* [*_-]* \s* coding[:=] \s* (?P<Coding> [-\w_.]+ ) \s* [*_-]* $
32 ) 34 )
33 35
133 (?P<ImportFromList> 135 (?P<ImportFromList>
134 (?: \( \s* .*? \s* \) ) 136 (?: \( \s* .*? \s* \) )
135 | 137 |
136 (?: [^#;\\\n]* (?: \\\n )* )* ) 138 (?: [^#;\\\n]* (?: \\\n )* )* )
137 )""", 139 )""",
138 re.VERBOSE | re.DOTALL | re.MULTILINE, 140 QRegularExpression.PatternOption.MultilineOption
139 ).search 141 | QRegularExpression.PatternOption.DotMatchesEverythingOption
142 | QRegularExpression.PatternOption.ExtendedPatternSyntaxOption
143 | QRegularExpression.PatternOption.UseUnicodePropertiesOption,
144 ).match
140 145
141 _commentsub = re.compile(r"""#[^\n]*\n|#[^\n]*$""").sub 146 _commentsub = re.compile(r"""#[^\n]*\n|#[^\n]*$""").sub
142 147
143 148
144 class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase): 149 class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase):
443 i = 0 448 i = 0
444 modifierType = ClbrBaseClasses.Function.General 449 modifierType = ClbrBaseClasses.Function.General
445 modifierIndent = -1 450 modifierIndent = -1
446 while True: 451 while True:
447 m = _getnext(src, i) 452 m = _getnext(src, i)
448 if not m: 453 if not m.hasMatch():
449 break 454 break
450 start, i = m.span() 455 start, i = m.capturedStart(), m.capturedEnd()
451 456
452 if m.start("MethodModifier") >= 0: 457 if m.hasCaptured("MethodModifier"):
453 modifierIndent = _indent(m.group("MethodModifierIndent")) 458 modifierIndent = _indent(m.captured("MethodModifierIndent"))
454 modifierType = m.group("MethodModifierType") 459 modifierType = m.captured("MethodModifierType")
455 460
456 elif m.start("Method") >= 0: 461 elif m.hasCaptured("Method"):
457 # found a method definition or function 462 # found a method definition or function
458 thisindent = _indent(m.group("MethodIndent")) 463 thisindent = _indent(m.captured("MethodIndent"))
459 meth_name = m.group("MethodName") 464 meth_name = m.captured("MethodName")
460 meth_sig = m.group("MethodSignature") 465 meth_sig = m.captured("MethodSignature")
461 meth_sig = meth_sig.replace("\\\n", "") 466 meth_sig = meth_sig.replace("\\\n", "")
462 meth_sig = _commentsub("", meth_sig) 467 meth_sig = _commentsub("", meth_sig)
463 meth_ret = m.group("MethodReturnAnnotation") 468 meth_ret = m.captured("MethodReturnAnnotation")
464 meth_ret = meth_ret.replace("\\\n", "") 469 meth_ret = meth_ret.replace("\\\n", "")
465 meth_ret = _commentsub("", meth_ret) 470 meth_ret = _commentsub("", meth_ret)
466 lineno += src.count("\n", last_lineno_pos, start) 471 lineno += src.count("\n", last_lineno_pos, start)
467 last_lineno_pos = start 472 last_lineno_pos = start
468 if modifierType and modifierIndent == thisindent: 473 if modifierType and modifierIndent == thisindent:
532 537
533 # reset the modifier settings 538 # reset the modifier settings
534 modifierType = ClbrBaseClasses.Function.General 539 modifierType = ClbrBaseClasses.Function.General
535 modifierIndent = -1 540 modifierIndent = -1
536 541
537 elif m.start("String") >= 0: 542 elif m.hasCaptured("String"):
538 pass 543 pass
539 544
540 elif m.start("Class") >= 0: 545 elif m.hasCaptured("Class"):
541 # we found a class definition 546 # we found a class definition
542 thisindent = _indent(m.group("ClassIndent")) 547 thisindent = _indent(m.captured("ClassIndent"))
543 # close all classes indented at least as much 548 # close all classes indented at least as much
544 while classstack and classstack[-1][1] >= thisindent: 549 while classstack and classstack[-1][1] >= thisindent:
545 del classstack[-1] 550 del classstack[-1]
546 lineno += src.count("\n", last_lineno_pos, start) 551 lineno += src.count("\n", last_lineno_pos, start)
547 last_lineno_pos = start 552 last_lineno_pos = start
548 class_name = m.group("ClassName") 553 class_name = m.captured("ClassName")
549 inherit = m.group("ClassSupers") 554 inherit = m.captured("ClassSupers")
550 if inherit: 555 if inherit:
551 # the class inherits from other classes 556 # the class inherits from other classes
552 inherit = inherit[1:-1].strip() 557 inherit = inherit[1:-1].strip()
553 inherit = _commentsub("", inherit) 558 inherit = _commentsub("", inherit)
554 names = [] 559 names = []
599 dictionary[class_name] = cur_class 604 dictionary[class_name] = cur_class
600 else: 605 else:
601 classstack[-1][0]._addclass(class_name, cur_class) 606 classstack[-1][0]._addclass(class_name, cur_class)
602 classstack.append((cur_class, thisindent)) 607 classstack.append((cur_class, thisindent))
603 608
604 elif m.start("Attribute") >= 0: 609 elif m.hasCaptured("Attribute"):
605 lineno += src.count("\n", last_lineno_pos, start) 610 lineno += src.count("\n", last_lineno_pos, start)
606 last_lineno_pos = start 611 last_lineno_pos = start
607 index = -1 612 index = -1
608 while index >= -len(classstack): 613 while index >= -len(classstack):
609 if classstack[index][0] is not None and not isinstance( 614 if classstack[index][0] is not None and not isinstance(
610 classstack[index][0], Function 615 classstack[index][0], Function
611 ): 616 ):
612 attr = Attribute(module, m.group("AttributeName"), file, lineno) 617 attr = Attribute(module, m.captured("AttributeName"), file, lineno)
613 classstack[index][0]._addattribute(attr) 618 classstack[index][0]._addattribute(attr)
614 break 619 break
615 else: 620 else:
616 index -= 1 621 index -= 1
617 622
618 elif m.start("Main") >= 0: 623 elif m.hasCaptured("Main"):
619 # 'main' part of the script, reset class stack 624 # 'main' part of the script, reset class stack
620 lineno += src.count("\n", last_lineno_pos, start) 625 lineno += src.count("\n", last_lineno_pos, start)
621 last_lineno_pos = start 626 last_lineno_pos = start
622 classstack = [] 627 classstack = []
623 628
624 elif m.start("Variable") >= 0: 629 elif m.hasCaptured("Variable"):
625 thisindent = _indent(m.group("VariableIndent")) 630 thisindent = _indent(m.captured("VariableIndent"))
626 variable_name = m.group("VariableName") 631 variable_name = m.captured("VariableName")
627 lineno += src.count("\n", last_lineno_pos, start) 632 lineno += src.count("\n", last_lineno_pos, start)
628 last_lineno_pos = start 633 last_lineno_pos = start
629 if thisindent == 0 or not classstack: 634 if thisindent == 0 or not classstack:
630 # global variable, reset class stack first 635 # global variable, reset class stack first
631 classstack = [] 636 classstack = []
647 classstack[index][0]._addglobal( 652 classstack[index][0]._addglobal(
648 Attribute(module, variable_name, file, lineno) 653 Attribute(module, variable_name, file, lineno)
649 ) 654 )
650 break 655 break
651 656
652 elif m.start("Publics") >= 0: 657 elif m.hasCaptured("Publics"):
653 idents = m.group("Identifiers") 658 idents = m.captured("Identifiers")
654 lineno += src.count("\n", last_lineno_pos, start) 659 lineno += src.count("\n", last_lineno_pos, start)
655 last_lineno_pos = start 660 last_lineno_pos = start
656 pubs = Publics( 661 pubs = Publics(
657 module=module, 662 module=module,
658 file=file, 663 file=file,
662 for e in idents.split(",") 667 for e in idents.split(",")
663 ], 668 ],
664 ) 669 )
665 dictionary["__all__"] = pubs 670 dictionary["__all__"] = pubs
666 671
667 elif m.start("Import") >= 0: 672 elif m.hasCaptured("Import"):
668 # - import module 673 # - import module
669 names = [ 674 names = [
670 n.strip() 675 n.strip()
671 for n in "".join(m.group("ImportList").splitlines()) 676 for n in "".join(m.captured("ImportList").splitlines())
672 .replace("\\", "") 677 .replace("\\", "")
673 .split(",") 678 .split(",")
674 ] 679 ]
675 lineno += src.count("\n", last_lineno_pos, start) 680 lineno += src.count("\n", last_lineno_pos, start)
676 last_lineno_pos = start 681 last_lineno_pos = start
677 if "@@Import@@" not in dictionary: 682 if "@@Import@@" not in dictionary:
678 dictionary["@@Import@@"] = Imports(module, file) 683 dictionary["@@Import@@"] = Imports(module, file)
679 for name in names: 684 for name in names:
680 dictionary["@@Import@@"].addImport(name, [], lineno) 685 dictionary["@@Import@@"].addImport(name, [], lineno)
681 686
682 elif m.start("ImportFrom") >= 0: 687 elif m.hasCaptured("ImportFrom"):
683 # - from module import stuff 688 # - from module import stuff
684 mod = m.group("ImportFromPath") 689 mod = m.captured("ImportFromPath")
685 namesLines = ( 690 namesLines = (
686 m.group("ImportFromList") 691 m.captured("ImportFromList")
687 .replace("(", "") 692 .replace("(", "")
688 .replace(")", "") 693 .replace(")", "")
689 .replace("\\", "") 694 .replace("\\", "")
690 .strip() 695 .strip()
691 .splitlines() 696 .splitlines()
696 last_lineno_pos = start 701 last_lineno_pos = start
697 if "@@Import@@" not in dictionary: 702 if "@@Import@@" not in dictionary:
698 dictionary["@@Import@@"] = Imports(module, file) 703 dictionary["@@Import@@"] = Imports(module, file)
699 dictionary["@@Import@@"].addImport(mod, names, lineno) 704 dictionary["@@Import@@"].addImport(mod, names, lineno)
700 705
701 elif m.start("ConditionalDefine") >= 0: 706 elif m.hasCaptured("ConditionalDefine"):
702 # a conditional function/method definition 707 # a conditional function/method definition
703 thisindent = _indent(m.group("ConditionalDefineIndent")) 708 thisindent = _indent(m.captured("ConditionalDefineIndent"))
704 while conditionalsstack and conditionalsstack[-1] >= thisindent: 709 while conditionalsstack and conditionalsstack[-1] >= thisindent:
705 del conditionalsstack[-1] 710 del conditionalsstack[-1]
706 if deltastack: 711 if deltastack:
707 del deltastack[-1] 712 del deltastack[-1]
708 conditionalsstack.append(thisindent) 713 conditionalsstack.append(thisindent)
709 deltaindentcalculated = False 714 deltaindentcalculated = False
710 715
711 elif m.start("CodingLine") >= 0: 716 elif m.hasCaptured("CodingLine"):
712 # a coding statement 717 # a coding statement
713 coding = m.group("Coding") 718 coding = m.captured("Coding")
714 lineno += src.count("\n", last_lineno_pos, start) 719 lineno += src.count("\n", last_lineno_pos, start)
715 last_lineno_pos = start 720 last_lineno_pos = start
716 if "@@Coding@@" not in dictionary: 721 if "@@Coding@@" not in dictionary:
717 dictionary["@@Coding@@"] = ClbrBaseClasses.Coding( 722 dictionary["@@Coding@@"] = ClbrBaseClasses.Coding(
718 module, file, lineno, coding 723 module, file, lineno, coding

eric ide

mercurial