aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/rubocops/extend
diff options
context:
space:
mode:
authorGautham Goli2017-03-16 23:49:43 +0530
committerGautham Goli2017-03-26 15:26:41 +0530
commita693ca332efcc56e0d7dbb3f43952226225ccf75 (patch)
tree0199f76c6418c8da3cec0a767c9567128562e742 /Library/Homebrew/rubocops/extend
parentfebc1085984e3d7fa23ee4c18d11e087afe20cbe (diff)
downloadbrew-a693ca332efcc56e0d7dbb3f43952226225ccf75.tar.bz2
Wrap rubocop specific code into methods inside FormulaCop
Diffstat (limited to 'Library/Homebrew/rubocops/extend')
-rw-r--r--Library/Homebrew/rubocops/extend/formula_cop.rb126
1 files changed, 124 insertions, 2 deletions
diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb
index cf5d513c9..49108bd48 100644
--- a/Library/Homebrew/rubocops/extend/formula_cop.rb
+++ b/Library/Homebrew/rubocops/extend/formula_cop.rb
@@ -6,16 +6,138 @@ module RuboCop
def on_class(node)
# This method is called by RuboCop and is the main entry point
+ file_path = processed_source.buffer.name
+ return unless file_path_allowed?(file_path)
class_node, parent_class_node, body = *node
- return unless a_formula_class?(parent_class_node)
+ return unless formula_class?(parent_class_node)
+ return unless respond_to?(:audit_formula)
+ @formula_name = class_name(class_node)
audit_formula(node, class_node, parent_class_node, body)
end
+ def regex_match_group(node, pattern)
+ # Checks for regex match of pattern in the node and
+ # Sets the appropriate instance variables to report the match
+ string_repr = string_content(node)
+ match_object = string_repr.match(pattern)
+ return unless match_object
+ node_begin_pos = start_column(node)
+ line_begin_pos = line_start_column(node)
+ @column = node_begin_pos + match_object.begin(0) - line_begin_pos + 1
+ @length = match_object.to_s.length
+ @line_no = line_number(node)
+ @source_buf = source_buffer(node)
+ @offense_source_range = source_range(@source_buf, @line_no, @column, @length)
+ @offensive_node = node
+ match_object
+ end
+
+ def find_node_method_by_name(node, method_name)
+ # Returns method_node matching method_name
+ return if node.nil?
+ node.each_child_node(:send) do |method_node|
+ next unless method_node.method_name == method_name
+ @offensive_node = method_node
+ @offense_source_range = method_node.source_range
+ return method_node
+ end
+ # If not found then, parent node becomes the offensive node
+ @offensive_node = node.parent
+ @offense_source_range = node.parent.source_range
+ nil
+ end
+
+ def find_block(node, block_name)
+ # Returns a block named block_name inside node
+ return if node.nil?
+ node.each_child_node(:block) do |block_node|
+ next if block_node.method_name != block_name
+ @offensive_node = block_node
+ @offense_source_range = block_node.source_range
+ return block_node
+ end
+ # If not found then, parent node becomes the offensive node
+ @offensive_node = node.parent
+ @offense_source_range = node.parent.source_range
+ nil
+ end
+
+ def method_called?(node, method_name)
+ # Check if a method is called inside a block
+ block_body = node.children[2]
+ block_body.each_child_node(:send) do |call_node|
+ next unless call_node.method_name == method_name
+ @offensive_node = call_node
+ @offense_source_range = call_node.source_range
+ return true
+ end
+ false
+ end
+
+ def parameters(method_node)
+ # Returns the array of arguments of the method_node
+ return unless method_node.send_type?
+ method_node.method_args
+ end
+
+ def line_start_column(node)
+ # Returns the begin position of the node's line in source code
+ node.source_range.source_buffer.line_range(node.loc.line).begin_pos
+ end
+
+ def start_column(node)
+ # Returns the begin position of the node in source code
+ node.source_range.begin_pos
+ end
+
+ def line_number(node)
+ # Returns the line number of the node
+ node.loc.line
+ end
+
+ def class_name(node)
+ # Returns the class node's name, nil if not a class node
+ @offensive_node = node
+ @offense_source_range = node.source_range
+ node.const_name
+ end
+
+ def size(node)
+ # Returns the node size in the source code
+ node.source_range.size
+ end
+
+ def block_size(block)
+ # Returns the block length of the block node
+ block_length(block)
+ end
+
+ def source_buffer(node)
+ # Source buffer is required as an argument to report style violations
+ node.source_range.source_buffer
+ end
+
+ def string_content(node)
+ # Returns the string representation if node is of type str
+ node.str_content if node.type == :str
+ end
+
+ def problem(msg)
+ add_offense(@offensive_node, @offense_source_range, msg)
+ end
+
private
- def a_formula_class?(parent_class_node)
+ def formula_class?(parent_class_node)
parent_class_node && parent_class_node.const_name == "Formula"
end
+
+ def file_path_allowed?(file_path)
+ paths_to_exclude = [%r{/Library/Homebrew/compat/},
+ %r{/Library/Homebrew/test/}]
+ return true if file_path.nil? # file_path is nil when source is directly passed to the cop eg., in specs
+ file_path !~ Regexp.union(paths_to_exclude)
+ end
end
end
end