Class: Simplabs::Excellent::Parsing::SexpContext

Inherits:
Object
  • Object
show all
Defined in:
lib/simplabs/excellent/parsing/sexp_context.rb

Overview

For most nodes the Excellent processor processes, it will create the corresponding context that contains meta information of the processed node. This is the base class for all these contexts.

Example

For a method like the following:

module Shop
  class Basket
    def buy_product(product)
      other_method
    end
  end
end

four context will be generated:

ModuleContext
  name:      'Shop'
  full_name: 'Shop'
  parent:    nil
ClassContext
  name:      'Basket'
  full_name: 'Shop::Basket'
  parent:    ModuleContext
MethodContext
  name:       'buy_product'
  full_name:  'Shop::Basket#buy_product'
  parent:     ClassContext
  parameters: [:product]
CallContext (other_method)
  name:      nil
  full_name: nil
  parent:    MethodContext
  method:    :other_method

Custom Processors

The Excelent processor will also invoke custom processor methods on the contexts if they are defined. To process call nodes in the context for example, you could simply define a process_call method in the context that will be invoked with each call Sexp (S-expression, see en.wikipedia.org/wiki/S_expression) that is processed by the Excellent processor.

def process_call(exp)
  super
  do_something()
end

Custom processor methods must always call super since there might be several processor methods defined in several modules that are in the included in the context and all of these have to be invoked. Also processor methods must not modify the passed Sexp since other processor methods also need the complete Sexp. If you have to modify the Sexp in a processor method, deep clone it:

exp = exp.deep_clone

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(exp, parent = nil) ⇒ SexpContext

Initializes a SexpContext.

Always call super in inherited custom contexts!

Parameters



82
83
84
85
86
87
88
# File 'lib/simplabs/excellent/parsing/sexp_context.rb', line 82

def initialize(exp, parent = nil)
  @exp        = exp
  @parent     = parent
  @file       = exp.file
  @line       = exp.line
  @full_name  = nil
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object

:nodoc:



98
99
100
101
# File 'lib/simplabs/excellent/parsing/sexp_context.rb', line 98

def method_missing(method, *args) #:nodoc:
  return if method.to_s =~ /^process_[a-zA-Z0-9_]+$/
  super
end

Instance Attribute Details

#fileObject (readonly)

The file the code fragment was read from



69
70
71
# File 'lib/simplabs/excellent/parsing/sexp_context.rb', line 69

def file
  @file
end

#lineObject (readonly)

The line the code fragment is located at



72
73
74
# File 'lib/simplabs/excellent/parsing/sexp_context.rb', line 72

def line
  @line
end

#nameObject (readonly)

The name of the code fragment the context is bound to (e.g. ‘User’ for a class)



66
67
68
# File 'lib/simplabs/excellent/parsing/sexp_context.rb', line 66

def name
  @name
end

#parentObject (readonly)

The parent context



63
64
65
# File 'lib/simplabs/excellent/parsing/sexp_context.rb', line 63

def parent
  @parent
end

Instance Method Details

#full_nameObject

Gets the full name of the code fragment the context is bound to. For a method name might be ‘add_product’ while full_name might be ‘Basket#add_product’.



92
93
94
95
96
# File 'lib/simplabs/excellent/parsing/sexp_context.rb', line 92

def full_name
  return @full_name if @full_name
  return @name if @parent.blank?
  "#{@parent.full_name}::#{@name}"
end