src/eric7/Utilities/ClassBrowsers/rbclbr.py

branch
eric7
changeset 9693
a7e9fd398e5a
parent 9653
e67609152c5e
child 9733
c5c2a74e9382
equal deleted inserted replaced
9692:a0be29ab700a 9693:a7e9fd398e5a
12 It is based on the Python class browser found in this package. 12 It is based on the Python class browser found in this package.
13 """ 13 """
14 14
15 import re 15 import re
16 16
17 from PyQt6.QtCore import QRegularExpression
18
17 from eric7 import Utilities 19 from eric7 import Utilities
18 from eric7.Utilities import ClassBrowsers 20 from eric7.Utilities import ClassBrowsers
19 21
20 from . import ClbrBaseClasses 22 from . import ClbrBaseClasses
21 23
22 SUPPORTED_TYPES = [ClassBrowsers.RB_SOURCE] 24 SUPPORTED_TYPES = [ClassBrowsers.RB_SOURCE]
23 25
24 _getnext = re.compile( 26 _getnext = QRegularExpression(
25 r""" 27 r"""
26 (?P<String> 28 (?P<String>
27 =begin .*? =end 29 =begin .*? =end
28 30
29 | <<-? (?P<HereMarker1> [a-zA-Z0-9_]+? ) [ \t]* .*? (?P=HereMarker1) 31 | <<-? (?P<HereMarker1> [a-zA-Z0-9_]+? ) [ \t]* .*? (?P=HereMarker1)
155 end [ \t]* $ 157 end [ \t]* $
156 | 158 |
157 end \b [^_] 159 end \b [^_]
158 ) 160 )
159 )""", 161 )""",
160 re.VERBOSE | re.DOTALL | re.MULTILINE, 162 QRegularExpression.PatternOption.MultilineOption
161 ).search 163 | QRegularExpression.PatternOption.DotMatchesEverythingOption
164 | QRegularExpression.PatternOption.ExtendedPatternSyntaxOption
165 | QRegularExpression.PatternOption.UseUnicodePropertiesOption,
166 ).match
162 167
163 _commentsub = re.compile(r"""#[^\n]*\n|#[^\n]*$""").sub 168 _commentsub = re.compile(r"""#[^\n]*\n|#[^\n]*$""").sub
164 169
165 170
166 class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase): 171 class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase):
312 cur_obj = None 317 cur_obj = None
313 lastGlobalEntry = None 318 lastGlobalEntry = None
314 i = 0 319 i = 0
315 while True: 320 while True:
316 m = _getnext(src, i) 321 m = _getnext(src, i)
317 if not m: 322 if not m.hasMatch():
318 break 323 break
319 start, i = m.span() 324 start, i = m.capturedStart(), m.capturedEnd()
320 325
321 if m.start("Method") >= 0: 326 if m.hasCaptured("Method"):
322 # found a method definition or function 327 # found a method definition or function
323 thisindent = indent 328 thisindent = indent
324 indent += 1 329 indent += 1
325 meth_name = ( 330 meth_name = (
326 m.group("MethodName") 331 m.captured("MethodName")
327 or m.group("MethodName2") 332 or m.captured("MethodName2")
328 or m.group("MethodName3") 333 or m.captured("MethodName3")
329 ) 334 )
330 meth_sig = m.group("MethodSignature") 335 meth_sig = m.captured("MethodSignature")
331 meth_sig = meth_sig and meth_sig.replace("\\\n", "") or "" 336 meth_sig = meth_sig and meth_sig.replace("\\\n", "") or ""
332 meth_sig = _commentsub("", meth_sig) 337 meth_sig = _commentsub("", meth_sig)
333 lineno += src.count("\n", last_lineno_pos, start) 338 lineno += src.count("\n", last_lineno_pos, start)
334 last_lineno_pos = start 339 last_lineno_pos = start
335 if meth_name.startswith("self."): 340 if meth_name.startswith("self."):
380 cur_obj.setEndLine(lineno - 1) 385 cur_obj.setEndLine(lineno - 1)
381 cur_obj = f 386 cur_obj = f
382 classstack.append((f, thisindent)) # Marker for nested fns 387 classstack.append((f, thisindent)) # Marker for nested fns
383 388
384 elif ( 389 elif (
385 m.start("String") >= 0 390 m.hasCaptured("String")
386 or m.start("Comment") >= 0 391 or m.hasCaptured("Comment")
387 or m.start("ClassIgnored") >= 0 392 or m.hasCaptured("ClassIgnored")
388 or m.start("BeginEnd") >= 0 393 or m.hasCaptured("BeginEnd")
389 ): 394 ):
390 pass 395 pass
391 396
392 elif m.start("Class") >= 0: 397 elif m.hasCaptured("Class"):
393 # we found a class definition 398 # we found a class definition
394 thisindent = indent 399 thisindent = indent
395 indent += 1 400 indent += 1
396 lineno += src.count("\n", last_lineno_pos, start) 401 lineno += src.count("\n", last_lineno_pos, start)
397 last_lineno_pos = start 402 last_lineno_pos = start
399 while classstack and classstack[-1][1] >= thisindent: 404 while classstack and classstack[-1][1] >= thisindent:
400 if classstack[-1][0] is not None: 405 if classstack[-1][0] is not None:
401 # record the end line 406 # record the end line
402 classstack[-1][0].setEndLine(lineno - 1) 407 classstack[-1][0].setEndLine(lineno - 1)
403 del classstack[-1] 408 del classstack[-1]
404 class_name = m.group("ClassName") or m.group("ClassName2") 409 class_name = m.captured("ClassName") or m.captured("ClassName2")
405 inherit = m.group("ClassSupers") 410 inherit = m.captured("ClassSupers")
406 if inherit: 411 if inherit:
407 # the class inherits from other classes 412 # the class inherits from other classes
408 inherit = inherit[1:].strip() 413 inherit = inherit[1:].strip()
409 inherit = [_commentsub("", inherit)] 414 inherit = [_commentsub("", inherit)]
410 # remember this class 415 # remember this class
431 while acstack and acstack[-1][1] >= thisindent: 436 while acstack and acstack[-1][1] >= thisindent:
432 del acstack[-1] 437 del acstack[-1]
433 acstack.append(["public", thisindent]) 438 acstack.append(["public", thisindent])
434 # default access control is 'public' 439 # default access control is 'public'
435 440
436 elif m.start("Module") >= 0: 441 elif m.hasCaptured("Module"):
437 # we found a module definition 442 # we found a module definition
438 thisindent = indent 443 thisindent = indent
439 indent += 1 444 indent += 1
440 lineno += src.count("\n", last_lineno_pos, start) 445 lineno += src.count("\n", last_lineno_pos, start)
441 last_lineno_pos = start 446 last_lineno_pos = start
443 while classstack and classstack[-1][1] >= thisindent: 448 while classstack and classstack[-1][1] >= thisindent:
444 if classstack[-1][0] is not None: 449 if classstack[-1][0] is not None:
445 # record the end line 450 # record the end line
446 classstack[-1][0].setEndLine(lineno - 1) 451 classstack[-1][0].setEndLine(lineno - 1)
447 del classstack[-1] 452 del classstack[-1]
448 module_name = m.group("ModuleName") 453 module_name = m.captured("ModuleName")
449 # remember this class 454 # remember this class
450 cur_class = Module(module, module_name, file, lineno) 455 cur_class = Module(module, module_name, file, lineno)
451 if not classstack: 456 if not classstack:
452 if module_name in dictionary: 457 if module_name in dictionary:
453 cur_class = dictionary[module_name] 458 cur_class = dictionary[module_name]
470 while acstack and acstack[-1][1] >= thisindent: 475 while acstack and acstack[-1][1] >= thisindent:
471 del acstack[-1] 476 del acstack[-1]
472 acstack.append(["public", thisindent]) 477 acstack.append(["public", thisindent])
473 # default access control is 'public' 478 # default access control is 'public'
474 479
475 elif m.start("AccessControl") >= 0: 480 elif m.hasCaptured("AccessControl"):
476 aclist = m.group("AccessControlList") 481 aclist = m.captured("AccessControlList")
477 if aclist is None: 482 if not aclist:
478 index = -1 483 index = -1
479 while index >= -len(acstack): 484 while index >= -len(acstack):
480 if acstack[index][1] < indent: 485 if acstack[index][1] < indent:
481 actype = ( 486 actype = (
482 m.group("AccessControlType") 487 m.captured("AccessControlType")
483 or m.group("AccessControlType2").split("_")[0] 488 or m.captured("AccessControlType2").split("_")[0]
484 ) 489 )
485 acstack[index][0] = actype.lower() 490 acstack[index][0] = actype.lower()
486 break 491 break
487 else: 492 else:
488 index -= 1 493 index -= 1
494 and not isinstance(classstack[index][0], Function) 499 and not isinstance(classstack[index][0], Function)
495 and classstack[index][1] < indent 500 and classstack[index][1] < indent
496 ): 501 ):
497 parent = classstack[index][0] 502 parent = classstack[index][0]
498 actype = ( 503 actype = (
499 m.group("AccessControlType") 504 m.captured("AccessControlType")
500 or m.group("AccessControlType2").split("_")[0] 505 or m.captured("AccessControlType2").split("_")[0]
501 ) 506 )
502 actype = actype.lower() 507 actype = actype.lower()
503 for name in aclist.split(","): 508 for name in aclist.split(","):
504 name = name.strip()[1:] # get rid of leading ':' 509 name = name.strip()[1:] # get rid of leading ':'
505 acmeth = parent._getmethod(name) 510 acmeth = parent._getmethod(name)
513 acmeth.setPublic() 518 acmeth.setPublic()
514 break 519 break
515 else: 520 else:
516 index -= 1 521 index -= 1
517 522
518 elif m.start("Attribute") >= 0: 523 elif m.hasCaptured("Attribute"):
519 lineno += src.count("\n", last_lineno_pos, start) 524 lineno += src.count("\n", last_lineno_pos, start)
520 last_lineno_pos = start 525 last_lineno_pos = start
521 index = -1 526 index = -1
522 while index >= -len(classstack): 527 while index >= -len(classstack):
523 if ( 528 if (
524 classstack[index][0] is not None 529 classstack[index][0] is not None
525 and not isinstance(classstack[index][0], Function) 530 and not isinstance(classstack[index][0], Function)
526 and classstack[index][1] < indent 531 and classstack[index][1] < indent
527 ): 532 ):
528 attr = Attribute(module, m.group("AttributeName"), file, lineno) 533 attr = Attribute(module, m.captured("AttributeName"), file, lineno)
529 classstack[index][0]._addattribute(attr) 534 classstack[index][0]._addattribute(attr)
530 break 535 break
531 else: 536 else:
532 index -= 1 537 index -= 1
533 if lastGlobalEntry: 538 if lastGlobalEntry:
534 lastGlobalEntry.setEndLine(lineno - 1) 539 lastGlobalEntry.setEndLine(lineno - 1)
535 lastGlobalEntry = None 540 lastGlobalEntry = None
536 541
537 elif m.start("Attr") >= 0: 542 elif m.hasCaptured("Attr"):
538 lineno += src.count("\n", last_lineno_pos, start) 543 lineno += src.count("\n", last_lineno_pos, start)
539 last_lineno_pos = start 544 last_lineno_pos = start
540 index = -1 545 index = -1
541 while index >= -len(classstack): 546 while index >= -len(classstack):
542 if ( 547 if (
543 classstack[index][0] is not None 548 classstack[index][0] is not None
544 and not isinstance(classstack[index][0], Function) 549 and not isinstance(classstack[index][0], Function)
545 and classstack[index][1] < indent 550 and classstack[index][1] < indent
546 ): 551 ):
547 parent = classstack[index][0] 552 parent = classstack[index][0]
548 if m.group("AttrType") is None: 553 if not m.captured("AttrType"):
549 nv = m.group("AttrList").split(",") 554 nv = m.captured("AttrList").split(",")
550 if not nv: 555 if not nv:
551 break 556 break
552 name = nv[0].strip()[1:] # get rid of leading ':' 557 name = nv[0].strip()[1:] # get rid of leading ':'
553 attr = ( 558 attr = (
554 parent._getattribute("@" + name) 559 parent._getattribute("@" + name)
559 attr.setProtected() 564 attr.setProtected()
560 elif nv[1].strip() == "true": 565 elif nv[1].strip() == "true":
561 attr.setPublic() 566 attr.setPublic()
562 parent._addattribute(attr) 567 parent._addattribute(attr)
563 else: 568 else:
564 access = m.group("AttrType") 569 access = m.captured("AttrType")
565 for name in m.group("AttrList").split(","): 570 for name in m.captured("AttrList").split(","):
566 name = name.strip()[1:] # get rid of leading ':' 571 name = name.strip()[1:] # get rid of leading ':'
567 attr = ( 572 attr = (
568 parent._getattribute("@" + name) 573 parent._getattribute("@" + name)
569 or parent._getattribute("@@" + name) 574 or parent._getattribute("@@" + name)
570 or Attribute(module, "@" + name, file, lineno) 575 or Attribute(module, "@" + name, file, lineno)
579 parent._addattribute(attr) 584 parent._addattribute(attr)
580 break 585 break
581 else: 586 else:
582 index -= 1 587 index -= 1
583 588
584 elif m.start("Begin") >= 0: 589 elif m.hasCaptured("Begin"):
585 # a begin of a block we are not interested in 590 # a begin of a block we are not interested in
586 indent += 1 591 indent += 1
587 592
588 elif m.start("End") >= 0: 593 elif m.hasCaptured("End"):
589 # an end of a block 594 # an end of a block
590 indent -= 1 595 indent -= 1
591 if indent < 0: 596 if indent < 0:
592 # no negative indent allowed 597 # no negative indent allowed
593 if classstack: 598 if classstack:
594 # it's a class/module method 599 # it's a class/module method
595 indent = classstack[-1][1] 600 indent = classstack[-1][1]
596 else: 601 else:
597 indent = 0 602 indent = 0
598 603
599 elif m.start("CodingLine") >= 0: 604 elif m.hasCaptured("CodingLine"):
600 # a coding statement 605 # a coding statement
601 coding = m.group("Coding") 606 coding = m.captured("Coding")
602 lineno += src.count("\n", last_lineno_pos, start) 607 lineno += src.count("\n", last_lineno_pos, start)
603 last_lineno_pos = start 608 last_lineno_pos = start
604 if "@@Coding@@" not in dictionary: 609 if "@@Coding@@" not in dictionary:
605 dictionary["@@Coding@@"] = ClbrBaseClasses.Coding( 610 dictionary["@@Coding@@"] = ClbrBaseClasses.Coding(
606 module, file, lineno, coding 611 module, file, lineno, coding

eric ide

mercurial