Skip to content

Commit

Permalink
Builtins.sformat is nice
Browse files Browse the repository at this point in the history
  • Loading branch information
mvidner committed Dec 9, 2015
1 parent a29e2ec commit 5d1fe60
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 9 deletions.
24 changes: 24 additions & 0 deletions features/ops_sformat.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Feature: sformat

Builtins.sformat results in a nice value that even if the input is ugly!
Well, it does return nil if the format argument is nil, but
that can be checked, and mostly we will see string literal formats.

Scenario: translates `Ops.add` of a literal and a regular sformat
Given the original code is
"""
Ops.add("nice", Builtins.sformat("%1", nil))
"""
When the cop Yast/Ops autocorrects it
Then the code is converted to
"""
"nice" + Builtins.sformat("%1", nil)
"""

Scenario: doesn't translate `Ops.add` of a literal and a ugly sformat
Given the original code is
"""
Ops.add("nice", Builtins.sformat(ugly, nil))
"""
When the cop Yast/Ops autocorrects it
Then the code is unchanged
8 changes: 0 additions & 8 deletions lib/rubocop/cop/yast/ops.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,4 @@ def autocorrectable?(node)
_ops, _method, a, b = *node
nice(a) && nice(b)
end

def call?(node, namespace, message)
n_receiver, n_message = *node
n_receiver && n_receiver.type == :const &&
n_receiver.children[0].nil? &&
n_receiver.children[1] == namespace &&
n_message == message
end
end
20 changes: 19 additions & 1 deletion lib/rubocop/yast/niceness.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module Niceness

def nice(node)
nice_literal(node) || nice_variable(node) || nice_send(node) ||
nice_begin(node)
nice_sformat(node) || nice_begin(node)
end

def nice_literal(node)
Expand Down Expand Up @@ -54,7 +54,25 @@ def nice_send(node)
args.size == arity && args.all? { |a| nice(a) }
end

# Builtins.sformat is special in that it can produce nil
# but only if the format string is nil which is fortunately
# easy to rule out. Other args may be ugly but we don't care.
def nice_sformat(node)
return false unless node.type == :send
return false unless call?(node, :Builtins, :sformat)
_builtins, _sformat, format_string, *_other_args = *node
nice(format_string)
end

def nice_begin(node)
node.type == :begin && nice(node.children.last)
end

def call?(node, namespace, message)
n_receiver, n_message = *node
n_receiver && n_receiver.type == :const &&
n_receiver.children[0].nil? &&
n_receiver.children[1] == namespace &&
n_message == message
end
end

0 comments on commit 5d1fe60

Please sign in to comment.