diff options
| author | Gautham Goli | 2017-03-16 23:49:43 +0530 |
|---|---|---|
| committer | Gautham Goli | 2017-03-26 15:26:41 +0530 |
| commit | a693ca332efcc56e0d7dbb3f43952226225ccf75 (patch) | |
| tree | 0199f76c6418c8da3cec0a767c9567128562e742 /Library/Homebrew/rubocops/extend | |
| parent | febc1085984e3d7fa23ee4c18d11e087afe20cbe (diff) | |
| download | brew-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.rb | 126 |
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 |
