欢迎转载,请支持原创,保留原文链接:blog.ilibrary.me

这是写rails静态代码分析的。怕被误认为是分析rails framework的文章,所以标题取为’ruby静态代码分析’.

初衷是项目中要剔除不用的rails code, 手动一个一个方法去分析挺痛苦的,于是想到用工具去分析。 真正的静态分析实际上很难发现.

废弃!人生苦短,不搞这些高难度的东西了。

  1. S-Expression, symbolic expression,
  2. Sexp Processor, http://docs.seattlerb.org/sexp_processor/
  3. Ruby parser
  4. Rails best practice, 可以输出html格式的报告,还可以自定义规则.
  5. stackprof, A sampling call-stack profiler for Ruby.
  6. Code analyzer
  7. Debride, Analyze code for potentially uncalled / dead methods, now with auto-removal. 这是一个比较好的代码清除上手工具。
    1. Debride 是MethodBasedSexpProcessor的一个子类,MethodBasedSexpProcessor有点类似tree nodes walker.
    2. 可以自定义深度检索.
    3. 或者反复执行debride方法,清除dead code,最终,所有的dead code都会被拔起。
  8. Sexp Processor, Debride有引用,是同一个组织写的。挺蛋疼的一个库,缺乏文档。 可以查看它所有的tests,看该怎么使用. tests写得也巨难懂。还是看debride得代码吧。
  9. Ruby Parser, ruby parser, sexp, debride都是同一个人写的。搞错了,是同一个组织写的, seattlerb.
  10. Rubocop, 星多,这应该是最活跃的一个工具了。RuboCop is a Ruby static code analyzer (a.k.a. linter) and code formatter. Out of the box it will enforce many of the guidelines outlined in the community Ruby Style Guide. Apart from reporting the problems discovered in your code, RuboCop can also automatically fix many of them for you.
  11. RubyMine有一个find usage的功能,可以查看该方法在哪地方被调用了。在Find Usage结果里面还可以查看Call Hierachy. 这个可以用于分析哪些代码可以被废弃了。 11.

  12. 列出所有的常量: Module.constants
       Module.constants.first(4)
       # => [:ARGF, :ARGV, :ArgumentError, :Array]
    
    Module.constants.include?(:SEEK_SET)   # => false
    
    class IO
    Module.constants.include?(:SEEK_SET) # => true
    end
    
  13. 列出所有的模型类:
  14. ApplicationRecord.descendants   ActiveRecord::Base.descendants
  15. ApplicationRecord.descendants.collect(&:name)   ActiveRecord::Base.descendants.collect(&:name)
  16. collect和map是一样的
  17. pry: show-models
  18. 找出类的方法代码所在文件路径:
    YourClass.instance_methods(false).map { |m|
        YourClass.instance_method(m).source_location.first
    }.uniq
    

debride 使用

  1. debride app, 分析app目录下潜在的dead code. 有两个问题
    1. debride只分析一层引用。现实情况是,一般方法调用都很深,需要一直追溯到routes才能确定是否真的有被用到. 2. 2.

SexpProcessor使用

  1. 查找并打印所有的test方法, 在irb里面输入下面的语句。注意,这里有用到运算符重载(sexps / matcher).size
     require "ruby_parser";
     rp = RubyParser.new;
     matcher = Sexp::Matcher.parse "(defn [m /^test_/] ___)"
     paths = Dir["test/**/*.rb"];
     sexps = s(:block, *paths.map { |path| rp.process File.read(path), path });
     (sexps / matcher).size
     (sexps / matcher).map { |(_, name, *_rest)| name }.sort
    
  2. 查找所有方法名为establish_connection的定义, 把上面的/^test_/改为/^establish_connection$/就可以了
  3. 查看所有对establish_connection的调用,
  4. sexp_matcher.rb里面定义了方法def / pattern, def self._, def self.__, 还有很多其它的符号方法。
  5. sexp_processor.rb里面定义了方法def process_defn exp处理(defn [m /^test_/] ___)

pry代码分析