Sha256: e5d79006756df905592c8f6cc1bd3f30aad4c1361a4541aa98604b137693115e

Contents?: true

Size: 1.98 KB

Versions: 1

Compression:

Stored size: 1.98 KB

Contents

# encoding: utf-8

module Rubocop
  module Cop
    module FavorModifier
      # TODO extremely ugly solution that needs lots of polish
      def check(sexp)
        # discard if/then/else
        return false if sexp.loc.respond_to?(:else) && sexp.loc.else
        # discard modifier while/until
        return false if [:while, :until].include?(sexp.type) && !sexp.loc.end

        case sexp.loc.keyword.source
        when 'if'     then cond, body, _else = *sexp
        when 'unless' then cond, _else, body = *sexp
        else               cond, body = *sexp
        end

        if length(sexp) > 3
          false
        else
          cond_length = sexp.loc.keyword.size + cond.loc.expression.size + 1
          body_length = body_length(body)

          body_length > 0 && (cond_length + body_length) <= LineLength.max
        end
      end

      def length(sexp)
        sexp.loc.expression.source.split("\n").size
      end

      def body_length(body)
        if body && body.loc.expression
          body.loc.expression.column + body.loc.expression.size
        else
          0
        end
      end
    end

    class IfUnlessModifier < Cop
      include FavorModifier

      def error_message
        'Favor modifier if/unless usage when you have a single-line body. ' +
          'Another good alternative is the usage of control flow &&/||.'
      end

      def on_if(node)
        # discard ternary ops and modifier if/unless nodes
        return unless node.loc.respond_to?(:keyword) &&
          node.loc.respond_to?(:else)

        add_offence(:convention, node.loc.line, error_message) if check(node)

        super
      end
    end

    class WhileUntilModifier < Cop
      include FavorModifier

      MSG =
        'Favor modifier while/until usage when you have a single-line body.'

      def inspect(source, tokens, ast, comments)
        on_node([:while, :until], ast) do |node|
          add_offence(:convention, node.loc.line, MSG) if check(node)
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rubocop-0.8.1 lib/rubocop/cop/favor_modifier.rb