class Reek::Context::CodeContext
Superclass for all types of source code context. Each instance represents a code element of some kind, and each provides behaviour relevant to that code element. CodeContexts form a tree in the same way the code does, with each context holding a reference to a unique outer context.
@quality :reek:TooManyMethods { max_methods: 19 } @quality :reek:TooManyInstanceVariables { max_instance_variables: 8 }
Attributes
Public Class Methods
Source
# File lib/reek/context/code_context.rb, line 29 def initialize(exp) @exp = exp @children = [] @statement_counter = StatementCounter.new @refs = AST::ObjectRefs.new end
Initializes a new CodeContext
.
@param exp [Reek::AST::Node] The code described by this context
Public Instance Methods
Source
# File lib/reek/context/code_context.rb, line 108 def append_child_context(child) children << child self end
Register a context as a child context of this context. This is generally used by a child context to register itself with its parent.
@param child [CodeContext] the child context to register
Source
# File lib/reek/context/code_context.rb, line 160 def apply_current_visibility(_current_visibility) # Nothing to do by default end
Source
# File lib/reek/context/code_context.rb, line 143 def config_for(detector_class) parent_config_for(detector_class).merge( configuration_via_code_commment[detector_class.smell_type] || {}) end
Source
# File lib/reek/context/code_context.rb, line 53 def each(&block) return enum_for(:each) unless block yield self children.each do |child| child.each(&block) end end
Iterate over ‘self` and child contexts. The main difference (among others) to `local_nodes` is that we are traversing `CodeContexts` here, not AST
nodes (see `Reek::AST::Node`).
@yield block that is executed for every node. @return [Enumerator]
Source
# File lib/reek/context/code_context.rb, line 139 def full_name exp.full_name(parent ? parent.full_name : '') end
Source
# File lib/reek/context/code_context.rb, line 156 def instance_method? false end
Source
# File lib/reek/context/code_context.rb, line 41 def local_nodes(type, ignored = [], &) ignored |= [:class, :module] exp.each_node(type, ignored, &) end
Iterate over each AST
node (see ‘Reek::AST::Node`) of a given type for the current expression.
@param type [Symbol] the type of the nodes we are looking for, e.g. :defs. @yield block that is executed for every node.
Source
# File lib/reek/context/code_context.rb, line 131 def matches?(candidates) my_fq_name = full_name candidates.any? do |candidate| candidate = Regexp.quote(candidate) if candidate.is_a?(String) /#{candidate}/ =~ my_fq_name end end
Source
# File lib/reek/context/code_context.rb, line 148 def number_of_statements statement_counter.value end
Source
# File lib/reek/context/code_context.rb, line 115 def record_call_to(exp) receiver = exp.receiver type = receiver ? receiver.type : :self line = exp.line case type when :lvar, :lvasgn refs.record_reference(name: receiver.name, line: line) unless exp.object_creation_call? when :self refs.record_reference(name: :self, line: line) end end
@quality :reek:TooManyStatements { max_statements: 6 } @quality :reek:FeatureEnvy
Source
# File lib/reek/context/code_context.rb, line 127 def record_use_of_self refs.record_reference(name: :self) end
Source
# File lib/reek/context/code_context.rb, line 100 def register_with_parent(parent) @parent = parent.append_child_context(self) if parent end
Link the present context to its parent.
@param parent [Reek::AST::Node] The parent context of the code described by this context
For example, given the following code:
class Omg def foo(x) puts x end end
The {ContextBuilder} object first instantiates a {RootContext}, which has no parent.
Next, it instantiates a {ModuleContext}, with exp
looking like this:
(class (const nil :Omg) nil (def :foo (args (arg :x)) (send nil :puts (lvar :x))))
It will then call register_with_parent
on the {ModuleContext}, passing in the parent {RootContext}.
Finally, {ContextBuilder} will instantiate a {MethodContext}. This time, exp
is:
(def :foo (args (arg :x)) (send nil :puts (lvar :x)))
Then it will call register_with_parent
on the {MethodContext}, passing in the parent {ModuleContext}.
Source
# File lib/reek/context/code_context.rb, line 152 def singleton_method? false end
Private Instance Methods
Source
# File lib/reek/context/code_context.rb, line 168 def configuration_via_code_commment @configuration_via_code_commment ||= CodeComment.new(comment: full_comment, line: exp.line, source: exp.source).config end
Source
# File lib/reek/context/code_context.rb, line 174 def full_comment exp.full_comment || '' end
Source
# File lib/reek/context/code_context.rb, line 178 def parent_config_for(detector_class) parent ? parent.config_for(detector_class) : {} end