Module: RuboCop::Cop::Util
- Extended by:
- AST::Sexp
- Includes:
- PathUtil
- Included in:
- Cop, Lint::UnusedBlockArgument
- Defined in:
- lib/rubocop/cop/util.rb
Overview
This module contains a collection of useful utility methods.
Constant Summary collapse
- PROC_NEW_NODE =
s(:send, s(:const, nil, :Proc), :new)
- EQUALS_ASGN_NODES =
[:lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn, :masgn]
- SHORTHAND_ASGN_NODES =
[:op_asgn, :or_asgn, :and_asgn]
- ASGN_NODES =
EQUALS_ASGN_NODES + SHORTHAND_ASGN_NODES
- LITERALS =
[:str, :dstr, :int, :float, :sym, :dsym, :array, :hash, :regexp, :nil, :true, :false]
- BASIC_LITERALS =
LITERALS - [:dstr, :dsym, :array, :hash]
- OPERATOR_METHODS =
http://phrogz.net/programmingruby/language.html#table_18.4 Backtick is added last just to help editors parse this code.
%w( | ^ & <=> == === =~ > >= < <= << >> + - * / % ** ~ +@ -@ [] []= ! != !~ ).map(&:to_sym) + [:'`']
Class Method Summary collapse
- .begins_its_line?(range) ⇒ Boolean
- .block_length(block_node) ⇒ Object
- .command?(name, node) ⇒ Boolean
- .comment_line?(line_source) ⇒ Boolean
- .const_name(node) ⇒ Object
- .directions(side) ⇒ Object
-
.first_part_of_call_chain(node) ⇒ Object
Returns, for example, a bare
if
node if the given node is anif
with calls chained to the end of it. - .lambda?(node) ⇒ Boolean
- .lambda_or_proc?(node) ⇒ Boolean
- .line_range(arg) ⇒ Object
- .move_pos(src, pos, step, condition, regexp) ⇒ Object
-
.numeric_range_size(range) ⇒ Object
Range#size is not available prior to Ruby 2.0.
- .on_node(syms, sexp, excludes = []) {|sexp| ... } ⇒ Object
- .operator?(symbol) ⇒ Boolean
- .parentheses?(node) ⇒ Boolean
- .proc?(node) ⇒ Boolean
- .range_with_surrounding_comma(range, side = :both, buffer = nil) ⇒ Object
- .range_with_surrounding_space(range, side = :both, buffer = nil, with_newline = true) ⇒ Object
- .source_range(source_buffer, line_number, column, length = 1) ⇒ Object
- .strip_quotes(str) ⇒ Object
- .within_node?(inner, outer) ⇒ Boolean
Methods included from PathUtil
hidden?, issue_deprecation_warning, match_path?, relative_path
Class Method Details
.begins_its_line?(range) ⇒ Boolean
193 194 195 196 |
# File 'lib/rubocop/cop/util.rb', line 193 def begins_its_line?(range) source_before_range = range.source_buffer.source[0...range.begin_pos] source_before_range.rpartition("\n").last.strip.empty? end |
.block_length(block_node) ⇒ Object
46 47 48 |
# File 'lib/rubocop/cop/util.rb', line 46 def block_length(block_node) block_node.loc.end.line - block_node.loc.begin.line end |
.command?(name, node) ⇒ Boolean
85 86 87 88 89 90 91 92 |
# File 'lib/rubocop/cop/util.rb', line 85 def command?(name, node) return unless node.type == :send receiver, method_name, _args = *node # commands have no explicit receiver !receiver && method_name == name end |
.comment_line?(line_source) ⇒ Boolean
50 51 52 |
# File 'lib/rubocop/cop/util.rb', line 50 def comment_line?(line_source) line_source =~ /^\s*#/ end |
.const_name(node) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/rubocop/cop/util.rb', line 67 def const_name(node) return nil if node.nil? || node.type != :const const_names = [] const_node = node loop do namespace_node, name = *const_node const_names << name break unless namespace_node break unless namespace_node.is_a?(Parser::AST::Node) break if namespace_node.type == :cbase const_node = namespace_node end const_names.reverse.join('::') end |
.directions(side) ⇒ Object
185 186 187 188 189 190 191 |
# File 'lib/rubocop/cop/util.rb', line 185 def directions(side) if side == :both [true, true] else [side == :left, side == :right] end end |
.first_part_of_call_chain(node) ⇒ Object
Returns, for example, a bare if
node if the given node is an if
with calls chained to the end of it.
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/rubocop/cop/util.rb', line 206 def first_part_of_call_chain(node) while node case node.type when :send receiver, _method_name, _args = *node node = receiver when :block method, _args, _body = *node node = method else break end end node end |
.lambda?(node) ⇒ Boolean
94 95 96 97 98 99 100 |
# File 'lib/rubocop/cop/util.rb', line 94 def lambda?(node) fail 'Not a block node' unless node.type == :block send_node, _block_args, _block_body = *node command?(:lambda, send_node) end |
.lambda_or_proc?(node) ⇒ Boolean
110 111 112 |
# File 'lib/rubocop/cop/util.rb', line 110 def lambda_or_proc?(node) lambda?(node) || proc?(node) end |
.line_range(arg) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/rubocop/cop/util.rb', line 54 def line_range(arg) source_range = case arg when Parser::Source::Range arg when Parser::AST::Node arg.loc.expression else fail ArgumentError, "Invalid argument #{arg}" end source_range.begin.line..source_range.end.line end |
.move_pos(src, pos, step, condition, regexp) ⇒ Object
179 180 181 182 183 |
# File 'lib/rubocop/cop/util.rb', line 179 def move_pos(src, pos, step, condition, regexp) offset = step == -1 ? -1 : 0 pos += step while condition && src[pos + offset] =~ regexp pos end |
.numeric_range_size(range) ⇒ Object
Range#size is not available prior to Ruby 2.0.
223 224 225 226 227 228 |
# File 'lib/rubocop/cop/util.rb', line 223 def numeric_range_size(range) size = range.end - range.begin size += 1 unless range.exclude_end? size = 0 if size < 0 size end |
.on_node(syms, sexp, excludes = []) {|sexp| ... } ⇒ Object
118 119 120 121 122 123 124 125 126 127 |
# File 'lib/rubocop/cop/util.rb', line 118 def on_node(syms, sexp, excludes = []) yield sexp if Array(syms).include?(sexp.type) return if Array(excludes).include?(sexp.type) sexp.children.each do |elem| next unless elem.is_a?(Parser::AST::Node) on_node(syms, elem, excludes) { |s| yield s } end end |
.operator?(symbol) ⇒ Boolean
29 30 31 |
# File 'lib/rubocop/cop/util.rb', line 29 def operator?(symbol) OPERATOR_METHODS.include?(symbol) end |
.parentheses?(node) ⇒ Boolean
114 115 116 |
# File 'lib/rubocop/cop/util.rb', line 114 def parentheses?(node) node.loc.respond_to?(:end) && node.loc.end end |
.proc?(node) ⇒ Boolean
102 103 104 105 106 107 108 |
# File 'lib/rubocop/cop/util.rb', line 102 def proc?(node) fail 'Not a block node' unless node.type == :block send_node, _block_args, _block_body = *node command?(:proc, send_node) || send_node == PROC_NEW_NODE end |
.range_with_surrounding_comma(range, side = :both, buffer = nil) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/rubocop/cop/util.rb', line 149 def range_with_surrounding_comma(range, side = :both, buffer = nil) buffer ||= @processed_source.buffer src = buffer.source go_left, go_right = directions(side) begin_pos = range.begin_pos end_pos = range.end_pos begin_pos = move_pos(src, begin_pos, -1, go_left, /,/) end_pos = move_pos(src, end_pos, 1, go_right, /,/) Parser::Source::Range.new(buffer, begin_pos, end_pos) end |
.range_with_surrounding_space(range, side = :both, buffer = nil, with_newline = true) ⇒ Object
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/rubocop/cop/util.rb', line 163 def range_with_surrounding_space(range, side = :both, buffer = nil, with_newline = true) buffer ||= @processed_source.buffer src = buffer.source go_left, go_right = directions(side) begin_pos = range.begin_pos end_pos = range.end_pos begin_pos = move_pos(src, begin_pos, -1, go_left, /[ \t]/) begin_pos = move_pos(src, begin_pos, -1, go_left && with_newline, /\n/) end_pos = move_pos(src, end_pos, 1, go_right, /[ \t]/) end_pos = move_pos(src, end_pos, 1, go_right && with_newline, /\n/) Parser::Source::Range.new(buffer, begin_pos, end_pos) end |
.source_range(source_buffer, line_number, column, length = 1) ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/rubocop/cop/util.rb', line 129 def source_range(source_buffer, line_number, column, length = 1) if column.is_a?(Range) column_index = column.begin length = numeric_range_size(column) else column_index = column end preceding_line_numbers = (1...line_number) line_begin_pos = preceding_line_numbers.reduce(0) do |pos, line| pos + source_buffer.source_line(line).length + 1 end begin_pos = line_begin_pos + column_index end_pos = begin_pos + length Parser::Source::Range.new(source_buffer, begin_pos, end_pos) end |
.strip_quotes(str) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/rubocop/cop/util.rb', line 33 def strip_quotes(str) if str[0] == '"' || str[0] == "'" str[0] = '' str[-1] = '' else # we're dealing with %q or %Q str[0, 3] = '' str[-1] = '' end str end |
.within_node?(inner, outer) ⇒ Boolean
198 199 200 201 202 |
# File 'lib/rubocop/cop/util.rb', line 198 def within_node?(inner, outer) o = outer.loc.expression i = inner.loc.expression i.begin_pos >= o.begin_pos && i.end_pos <= o.end_pos end |