Class: MethodBasedSexpProcessor
- Inherits:
-
SexpProcessor
- Object
- SexpProcessor
- MethodBasedSexpProcessor
- Defined in:
- lib/sexp_processor.rb
Overview
A simple subclass of SexpProcessor that tracks method and class stacks for you. Use #method_name, #klass_name, or #signature to refer to where you’re at in processing. If you have to subclass process_(class|module|defn|defs) you must call super.
Constant Summary collapse
- @@no_class =
:main
- @@no_method =
:none
Constants inherited from SexpProcessor
Instance Attribute Summary collapse
-
#class_stack ⇒ Object
readonly
A stack of the classes/modules that are being processed.
-
#method_locations ⇒ Object
readonly
A lookup table of all the method locations that have been processed so far.
-
#method_stack ⇒ Object
readonly
A stack of the methods that are being processed.
-
#sclass ⇒ Object
readonly
A stack of the singleton classes that are being processed.
Attributes inherited from SexpProcessor
#auto_shift_type, #context, #debug, #default_method, #env, #expected, #require_empty, #strict, #unsupported, #warn_on_default
Instance Method Summary collapse
-
#in_klass(name) ⇒ Object
Adds name to the class stack, for the duration of the block.
-
#in_method(name, file, line, line_max = nil) ⇒ Object
Adds name to the method stack, for the duration of the block.
-
#in_sklass ⇒ Object
Tracks whether we’re in a singleton class or not.
-
#initialize ⇒ MethodBasedSexpProcessor
constructor
:nodoc:.
-
#klass_name ⇒ Object
Returns the first class in the list, or @@no_class if there are none.
-
#method_name ⇒ Object
Returns the first method in the list, or “#none” if there are none.
-
#process_class(exp) ⇒ Object
Process a class node until empty.
-
#process_defn(exp) ⇒ Object
Process a method node until empty.
-
#process_defs(exp) ⇒ Object
Process a singleton method node until empty.
-
#process_module(exp) ⇒ Object
Process a module node until empty.
-
#process_sclass(exp) ⇒ Object
Process a singleton class node until empty.
-
#process_until_empty(exp) ⇒ Object
Process each element of #exp in turn.
-
#signature ⇒ Object
Returns the method signature for the current method.
-
#with_new_method_stack ⇒ Object
Reset the method stack for the duration of the block.
Methods inherited from SexpProcessor
#assert_empty, #assert_type, #error_handler, expand_dirs_to_files, #in_context, #on_error_in, #process, #process_dummy, processors, #rewrite, rewriters, #scope
Constructor Details
#initialize ⇒ MethodBasedSexpProcessor
:nodoc:
509 510 511 512 513 514 515 516 |
# File 'lib/sexp_processor.rb', line 509 def initialize #:nodoc: super @sclass = [] @class_stack = [] @method_stack = [] @method_locations = {} self.require_empty = false end |
Instance Attribute Details
#class_stack ⇒ Object (readonly)
A stack of the classes/modules that are being processed
489 490 491 |
# File 'lib/sexp_processor.rb', line 489 def class_stack @class_stack end |
#method_locations ⇒ Object (readonly)
A lookup table of all the method locations that have been processed so far.
507 508 509 |
# File 'lib/sexp_processor.rb', line 507 def method_locations @method_locations end |
#method_stack ⇒ Object (readonly)
A stack of the methods that are being processed. You’d think it’d only ever be 1 deep, but you’d be wrong. People do terrible things in/to ruby.
496 497 498 |
# File 'lib/sexp_processor.rb', line 496 def method_stack @method_stack end |
#sclass ⇒ Object (readonly)
A stack of the singleton classes that are being processed.
501 502 503 |
# File 'lib/sexp_processor.rb', line 501 def sclass @sclass end |
Instance Method Details
#in_klass(name) ⇒ Object
Adds name to the class stack, for the duration of the block
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 |
# File 'lib/sexp_processor.rb', line 521 def in_klass name if Sexp === name then name = case name.sexp_type when :colon2 then name = name.flatten name.delete :const name.delete :colon2 name.join("::") when :colon3 then name.last.to_s else raise "unknown type #{name.inspect}" end end @class_stack.unshift name with_new_method_stack do yield end ensure @class_stack.shift end |
#in_method(name, file, line, line_max = nil) ⇒ Object
Adds name to the method stack, for the duration of the block
548 549 550 551 552 553 554 555 556 |
# File 'lib/sexp_processor.rb', line 548 def in_method name, file, line, line_max = nil method_name = Regexp === name ? name.inspect : name.to_s @method_stack.unshift method_name line_max = "-#{line_max}" if line_max @method_locations[signature] = "#{file}:#{line}#{line_max}" yield ensure @method_stack.shift end |
#in_sklass ⇒ Object
Tracks whether we’re in a singleton class or not. Doesn’t track actual receiver.
562 563 564 565 566 567 568 569 570 |
# File 'lib/sexp_processor.rb', line 562 def in_sklass @sclass.push true with_new_method_stack do yield end ensure @sclass.pop end |
#klass_name ⇒ Object
Returns the first class in the list, or @@no_class if there are none.
576 577 578 579 580 581 582 583 584 585 586 |
# File 'lib/sexp_processor.rb', line 576 def klass_name name = @class_stack.first raise "you shouldn't see me" if Sexp === name if @class_stack.any? @class_stack.reverse.join("::").sub(/\([^\)]+\)$/, "") else @@no_class end end |
#method_name ⇒ Object
Returns the first method in the list, or “#none” if there are none.
592 593 594 595 596 |
# File 'lib/sexp_processor.rb', line 592 def method_name m = @method_stack.first || @@no_method m = "##{m}" unless m =~ /::/ m end |
#process_class(exp) ⇒ Object
Process a class node until empty. Tracks all nesting. If you have to subclass and override this method, you can call super with a block.
603 604 605 606 607 608 609 610 611 612 613 |
# File 'lib/sexp_processor.rb', line 603 def process_class exp exp.shift unless auto_shift_type # node type in_klass exp.shift do if block_given? then yield else process_until_empty exp end end s() end |
#process_defn(exp) ⇒ Object
Process a method node until empty. Tracks your location. If you have to subclass and override this method, you can clall super with a block.
620 621 622 623 624 625 626 627 628 629 630 631 632 |
# File 'lib/sexp_processor.rb', line 620 def process_defn exp exp.shift unless auto_shift_type # node type name = @sclass.empty? ? exp.shift : "::#{exp.shift}" in_method name, exp.file, exp.line, exp.line_max do if block_given? then yield else process_until_empty exp end end s() end |
#process_defs(exp) ⇒ Object
Process a singleton method node until empty. Tracks your location. If you have to subclass and override this method, you can clall super with a block.
639 640 641 642 643 644 645 646 647 648 649 650 |
# File 'lib/sexp_processor.rb', line 639 def process_defs exp exp.shift unless auto_shift_type # node type process exp.shift # recv in_method "::#{exp.shift}", exp.file, exp.line, exp.line_max do if block_given? then yield else process_until_empty exp end end s() end |
#process_module(exp) ⇒ Object
Process a module node until empty. Tracks all nesting. If you have to subclass and override this method, you can clall super with a block.
657 658 659 660 661 662 663 664 665 666 667 |
# File 'lib/sexp_processor.rb', line 657 def process_module exp exp.shift unless auto_shift_type # node type in_klass exp.shift do if block_given? then yield else process_until_empty exp end end s() end |
#process_sclass(exp) ⇒ Object
Process a singleton class node until empty. Tracks all nesting. If you have to subclass and override this method, you can clall super with a block.
674 675 676 677 678 679 680 681 682 683 684 |
# File 'lib/sexp_processor.rb', line 674 def process_sclass exp exp.shift unless auto_shift_type # node type in_sklass do if block_given? then yield else process_until_empty exp end end s() end |
#process_until_empty(exp) ⇒ Object
Process each element of #exp in turn.
689 690 691 692 693 694 |
# File 'lib/sexp_processor.rb', line 689 def process_until_empty exp until exp.empty? sexp = exp.shift process sexp if Sexp === sexp end end |
#signature ⇒ Object
Returns the method signature for the current method.
699 700 701 |
# File 'lib/sexp_processor.rb', line 699 def signature "#{klass_name}#{method_name}" end |
#with_new_method_stack ⇒ Object
Reset the method stack for the duration of the block. Used for class scoping.
707 708 709 710 711 712 713 |
# File 'lib/sexp_processor.rb', line 707 def with_new_method_stack old_method_stack, @method_stack = @method_stack, [] yield ensure @method_stack = old_method_stack end |