Class: RubyLint::Analysis::UndefinedMethods
- Defined in:
- lib/ruby-lint/analysis/undefined_methods.rb
Overview
The UndefinedMethods class checks for the use of undefined methods/local variables and adds errors whenever needed. Based on the receiver of a method call the corresponding error message differs to make it easier to understand what is going on.
A simple example:
# => undefined method foobar
'test'. # => undefined method foobar on an instance of String
Constant Summary
Constants inherited from Base
Instance Attribute Summary
Attributes inherited from Base
Attributes inherited from Iterator
#arity_cache, #arity_cache Hash containing the amount of arguments for
Instance Method Summary collapse
-
#class_names_for_object(object) ⇒ String
private
-
#error_for(name, receiver, scope) ⇒ String
private
Determines what error message to use for a method call.
-
#has_definition?(scope, name) ⇒ Boolean
private
-
#method_error(name) ⇒ String
private
-
#name_for_parents(parents) ⇒ String
private
-
#on_send(node) ⇒ Object
-
#receiver_error(name, scope) ⇒ String
private
Returns a String containing the error message to use when calling an undefined method on a receiver.
Methods inherited from Base
#add_message, #after_initialize, analyze?, #current_scope, #error, #info, #previous_scope, register, #set_current_scope, #set_previous_scope, #warning
Methods included from MethodEvaluation
Methods inherited from Iterator
#execute_callback, #initialize, #iterate, #skip_child_nodes!
Constructor Details
This class inherits a constructor from RubyLint::Iterator
Instance Method Details
#class_names_for_object(object) ⇒ String (private)
116 117 118 119 120 121 122 123 124 |
# File 'lib/ruby-lint/analysis/undefined_methods.rb', line 116 def class_names_for_object(object) if object.parents.empty? klass = object.ruby_class ? object.ruby_class : object.name else klass = name_for_parents(object.parents) end return klass end |
#error_for(name, receiver, scope) ⇒ String (private)
Determines what error message to use for a method call.
78 79 80 |
# File 'lib/ruby-lint/analysis/undefined_methods.rb', line 78 def error_for(name, receiver, scope) return receiver ? receiver_error(name, scope) : method_error(name) end |
#has_definition?(scope, name) ⇒ Boolean (private)
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/ruby-lint/analysis/undefined_methods.rb', line 48 def has_definition?(scope, name) type = scope.method_call_type exists = scope.has_definition?(type, name) # Due to the way `parser` wraps block nodes (`(block (send) ...)` # opposed to `(send ... (block))`) we'll try to find the method in the # previous scope if we can't find it in the current block scope. if !exists and scope.block? prev = previous_scope exists = prev.has_definition?(prev.method_call_type, name) end # If method_missing is defined we'll assume the method calls are # handled gracefully and not add any errors for them. if !exists and scope.has_definition?(type, 'method_missing') exists = true end return exists end |
#method_error(name) ⇒ String (private)
86 87 88 |
# File 'lib/ruby-lint/analysis/undefined_methods.rb', line 86 def method_error(name) return "undefined method #{name}" end |
#name_for_parents(parents) ⇒ String (private)
130 131 132 133 134 135 136 |
# File 'lib/ruby-lint/analysis/undefined_methods.rb', line 130 def name_for_parents(parents) return parents[0].name if parents.length == 1 segments = parents[0..-2].map(&:name) return segments.join(', ') + " or #{parents[-1].name}" end |
#on_send(node) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/ruby-lint/analysis/undefined_methods.rb', line 20 def on_send(node) receiver, name, _ = *node receiver = unpack_block(receiver) name = name.to_s scope = current_scope if receiver and vm.associations.key?(receiver) scope = vm.associations[receiver] # TODO: this should be handled in a more generic and especially in a # more nicer way. return if scope.parents.empty? end unless has_definition?(scope, name) = error_for(name, receiver, scope) error(, node) end end |
#receiver_error(name, scope) ⇒ String (private)
Returns a String containing the error message to use when calling an undefined method on a receiver.
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/ruby-lint/analysis/undefined_methods.rb', line 98 def receiver_error(name, scope) klass = class_names_for_object(scope) if scope.instance? error = "undefined method #{name} on an instance of #{klass}" else error = "undefined method #{name} on #{scope.name}" end return error end |