Sha256: 970e24bcd1bbddb10e669a76ff1a060f3966a1dc57ddfe50f88d86b5cc365046

Contents?: true

Size: 1.84 KB

Versions: 14

Compression:

Stored size: 1.84 KB

Contents

module Gitlab
  module Styles
    module Rubocop
      module Cop
        # This cop makes sure that custom error classes, when empty, are declared
        # with Class.new.
        #
        # @example
        #   # bad
        #   class FooError < StandardError
        #   end
        #
        #   # okish
        #   class FooError < StandardError; end
        #
        #   # good
        #   FooError = Class.new(StandardError)
        class CustomErrorClass < RuboCop::Cop::Cop
          MSG = 'Use `Class.new(SuperClass)` to define an empty custom error class.'.freeze

          def on_class(node)
            _klass, parent, body = node.children

            return if body

            parent_klass = class_name_from_node(parent)

            return unless parent_klass&.to_s&.end_with?('Error')

            add_offense(node, location: :expression)
          end

          def autocorrect(node)
            klass, parent, _body = node.children
            replacement = "#{class_name_from_node(klass)} = Class.new(#{class_name_from_node(parent)})"

            lambda do |corrector|
              corrector.replace(node.source_range, replacement)
            end
          end

          private

          # The nested constant `Foo::Bar::Baz` looks like:
          #
          #   s(:const,
          #     s(:const,
          #       s(:const, nil, :Foo), :Bar), :Baz)
          #
          # So recurse through that to get the name as written in the source.
          #
          def class_name_from_node(node, suffix = nil)
            return unless node&.type == :const

            name = node.children[1].to_s
            name = "#{name}::#{suffix}" if suffix

            if node.children[0]
              class_name_from_node(node.children[0], name)
            else
              name
            end
          end
        end
      end
    end
  end
end

Version data entries

14 entries across 14 versions & 1 rubygems

Version Path
gitlab-styles-3.3.0 lib/gitlab/styles/rubocop/cop/custom_error_class.rb
gitlab-styles-3.2.0 lib/gitlab/styles/rubocop/cop/custom_error_class.rb
gitlab-styles-3.1.0 lib/gitlab/styles/rubocop/cop/custom_error_class.rb
gitlab-styles-3.0.0 lib/gitlab/styles/rubocop/cop/custom_error_class.rb
gitlab-styles-2.8.0 lib/gitlab/styles/rubocop/cop/custom_error_class.rb
gitlab-styles-2.7.0 lib/gitlab/styles/rubocop/cop/custom_error_class.rb
gitlab-styles-2.6.2 lib/gitlab/styles/rubocop/cop/custom_error_class.rb
gitlab-styles-2.6.1 lib/gitlab/styles/rubocop/cop/custom_error_class.rb
gitlab-styles-2.6.0 lib/gitlab/styles/rubocop/cop/custom_error_class.rb
gitlab-styles-2.5.2 lib/gitlab/styles/rubocop/cop/custom_error_class.rb
gitlab-styles-2.5.1 lib/gitlab/styles/rubocop/cop/custom_error_class.rb
gitlab-styles-2.5.0 lib/gitlab/styles/rubocop/cop/custom_error_class.rb
gitlab-styles-2.4.1 lib/gitlab/styles/rubocop/cop/custom_error_class.rb
gitlab-styles-2.4.0 lib/gitlab/styles/rubocop/cop/custom_error_class.rb