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)
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:
Note: After compiling pfff, the binaries of
# 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
sgrep
and spatch
can be directly copied to other systems without installing or compiling other packages. Resources:
Comments
Post a Comment