创建特定班级的rubocop cop

发布于 2025-01-25 04:47:14 字数 2062 浏览 3 评论 0原文

我们有一个内部使用的库,要求您从定义的方法中返回特定类型。我正在尝试写一个警察,使我们能够检测到这种情况。 Here is the situation I want to detect and flag:

  1. You are inside the Slayer::Command class
  2. You've returned something other than a call to pass or flunk !

It doesn't seem like there's an easy way to check both the call and the parent class, but I know it's doable, because the Rails/HasAndBelongsToMany COP仅触发铁轨模型,而不是轨道控制器。更具体地说,肯定不是一个迭代所有回报的简单方法,因为此错误的数字1是人们忘记了方法的最后一个分支是返回级别。

到目前为止,我需要的是:

require 'rubocop'

module Slayer
  class CommandReturn < RuboCop::Cop::Base
    def_node_search :explicit_returns, 'return'
    def_node_matcher :slayer_command?, "(class (const (const nil :Slayer) :Command) _)"
    def_node_matcher :is_call_to_pass?, "(send nil :pass ?)"
    def_node_matcher :is_call_to_flunk?, "(send nil :flunk! ?)"

    def on_def(node)
      return unless node.method?(:call)
      return unless in_slayer_command?(node)

      explicit_returns(node) do |node|
        validate_return! node.child_nodes.first, node
      end

      return # Temporarily does not look at implicit returns
      implicit_returns(node) do |node|
        validate_return! node
      end
    end

    private

    # Continue traversing `node` until you get to the last expression.
    # If that expression is a call to `.can_see?`, then add an offense.
    def implicit_returns(node)
      raise "Not Implemented Yet"
    end

    def in_slayer_command?(node)
      node.ancestors.any? &:slayer_command?
    end

    def validate_return!(node, return_node = nil)
      return if is_call_to_pass? node
      return if is_call_to_flunk? node

      add_offense(return_node || node, message: "call in Slayer::Command must return the result of `pass` or call `flunk!`")
    end
  end
end

我需要两件事:

  1. 这确实是检查班级父母的最佳方法吗?从Slayer ::命令继承的其他内容继承呢?这里有些东西。
  2. 实现ntimit_returns方法的最佳方法是什么?感觉就像应该烘烤,我只是错过了它。

We have a library that we use internally that requires you to return a specific type from the method you define. I'm trying to write a cop that enables us to detect that case. Here is the situation I want to detect and flag:

  1. You are inside the Slayer::Command class
  2. You've returned something other than a call to pass or flunk!

It doesn't seem like there's an easy way to check both the call and the parent class, but I know it's doable, because the Rails/HasAndBelongsToMany cop only triggers inside Rails models, not Rails controllers. More specifically, there definitely isn't an easy way to iterate all returns, because the number 1 cause of this bug is people forgetting that the last branch of a method is the return balue.

What I have so far is this:

require 'rubocop'

module Slayer
  class CommandReturn < RuboCop::Cop::Base
    def_node_search :explicit_returns, 'return'
    def_node_matcher :slayer_command?, "(class (const (const nil :Slayer) :Command) _)"
    def_node_matcher :is_call_to_pass?, "(send nil :pass ?)"
    def_node_matcher :is_call_to_flunk?, "(send nil :flunk! ?)"

    def on_def(node)
      return unless node.method?(:call)
      return unless in_slayer_command?(node)

      explicit_returns(node) do |node|
        validate_return! node.child_nodes.first, node
      end

      return # Temporarily does not look at implicit returns
      implicit_returns(node) do |node|
        validate_return! node
      end
    end

    private

    # Continue traversing `node` until you get to the last expression.
    # If that expression is a call to `.can_see?`, then add an offense.
    def implicit_returns(node)
      raise "Not Implemented Yet"
    end

    def in_slayer_command?(node)
      node.ancestors.any? &:slayer_command?
    end

    def validate_return!(node, return_node = nil)
      return if is_call_to_pass? node
      return if is_call_to_flunk? node

      add_offense(return_node || node, message: "call in Slayer::Command must return the result of `pass` or call `flunk!`")
    end
  end
end

I need help with two things:

  1. Is this really the best way to check the class' parent? What about inheriting from something else that inherits from Slayer::Command? Something feels off here.
  2. What's the best way to implement the implicit_returns method? That feels like it should be baked in and I'm just missing it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文