Black Bytes
Share this post!

Static Analysis in Ruby

If you want to know something about your source code, like the name and line number of all your methods, what do you do?

Your first idea might be to write a regexp for it, but what if I told you there is a better way?

ruby static analysis

Static analysis is a technique you can use when you need to extract information from the source code itself. This is done by converting source code into tokens (parsing).

Let’s get right into it!

Using the Parser Gem

Ruby has a parser available on the standard library, the name is Ripper. The output is hard to work with so I prefer using the fantastic parser gem. Rubocop uses this gem to do its magic.

This gem also includes a binary you can use to parse some code directly and see the resulting parse tree.

Here is an example:

The output looks like this:

This can be useful if you are trying to understand how Ruby parses some code. But if you want to create your own analysis tools you will have to read the source file, parse it and then traverse the generated tree.

Example:

The parser will return an AST (Abstract Syntax Tree) of your code. Don’t get too intimidated by the name, it’s simpler than it sounds 🙂

Traversing the AST

Now that you have parsed your code using the parser gem you need to traverse the resulting AST.

To do that you need to create a class and inherit from AST::Processor:

Then you have to instantiate this class and call the .process method:

You need to define some on_ methods. These methods correspond to the node names in the AST.

To discover what methods you need to define you can add the handler_missing method to your Processor class. You also need the on_begin method.

Here is where we are:

You have your AST and a basic processor, when you run this code you will see the node types for your AST.

Now:

You need to to implement all the on_ methods that you want to use. For example, if I want all the instance method names along with their line numbers I can do this:

When you run your program now it should print all the method names found.

Conclusion

Building a Ruby static analysis tool is not as difficult as it may look. If you want a more complete example take a look at my class_indexer gem. Now it’s your turn to make your own tools!

Please share this post if you enjoyed it! 🙂