Next generation refactoring with syntactical grep and patch from pfff

Refactoring of PHP methods is often difficult:
  • syntax errors or non-existing methods are only detected during runtime
  • wrong method calls or uninitialized variables are only detected during runtime
  • wrong order of parameters often remains undetected
  • not enough unit tests to validate the changes
  • not many resources for refactoring (time + money)
We can solve most of these issues by using a few tools for syntactic analysis.

You might have already worked with grep to search your code:


# find a function in all PHP files (and sub-directories)
grep -rin "SomeFunc(" *.php

This also finds "doSomeFunc(" as well as strings or documentation containing "SomeFunc(".
If you want to find all occurrences of SomeFunc() with exactly 2 parameters or at least 1 parameter, things get complicated.

Happily, Facebook has released a few tools to run static analysis and source-to-source transformations on PHP code. The package is named pfff and is available on GitHub.

Syntactic grep

Using sgrep from pfff, we can do syntactic searches in the code:


# find all occurrences of SomeFunc() with exactly 2 parameters
sgrep -e "SomeFunc(X,Y)" *.php

# find all occurrences of SomeFunc() with at least 1 parameter
sgrep -e "SomeFunc(X,...)" *.php

# ... is a wildcard for any number of parameters
# X, Y are wildcards for a parameter, X != Y

Syntactic patch

Using spatch, we can use syntactic searches to refactor our code:


# change parameters order from ABC to CAB
spatch -e 's/SomeFunc(A,B,C)/SomeFunc(C, A, B)/' *.php

# drop second parameter
spatch -e 's/SomeFunc(A,B,C)/SomeFunc(A, C)/' *.php

# rename SomeFunc to SomeOtherFunc
spatch -e 's/SomeFunc(...)/SomeOtherFunc(...)/' *.php

Install pfff

There are currently no binary packages, so you need to compile pfff manually on your machine. Here is a small guide to get it done with Ubuntu 12.10:


# ocaml 4.0 is currently only in Debian experimental
echo deb http://ftp.de.debian.org/debian experimental main \
>/etc/apt/sources.list.d/debian_exp.list
apt-get install git build-essential debian-archive-keyring
apt-get update
apt-get install libpcre3-dev libgtk2.0-dev binutils-gold gawk
apt-get install -t experimental ocaml camlp4 ocaml-base ocaml-nox \
ocaml-base-nox ocaml-interp ocaml-compiler-libs
cd /
git clone --depth=1 git://github.com/facebook/pfff.git
cd pfff
./configure
make depend && make && make opt
make install
Note: After compiling pfff, the binaries of sgrep and spatch can be directly copied to other systems without installing or compiling other packages.

Resources:

Comments

Popular posts from this blog

How to construct a B+ tree with example

How to show only month and year fields in android Date-picker?

Visitor Counter Script Using PHP