Sunday, February 22, 2015

Reformatting multiple source files

Recently I had to apply a new code formatter template to a project. Changing 50+ files by hand seemed to be too much monkey work. Writing a custom plug-in seemed to be too much work. Fortunately there is this great scripting framework to accomplish this task quite easily.

Step 1: Detecting affected source files

I have already blogged about EASE and how to install it. So I went directly to the script shell to fetch all java files form a certan project:
loadModule('/System/Resources');

 org.eclipse.ease.modules.platform.ResourcesModule@5f8466b4
files = findFiles("*.java", getProject("org.eclipse.some.dedicated.project"), true)
 [Ljava.lang.Object;@1b61effc
Now we have an array of IFile instances. Easy, isn't it?

Step 2: The formatter script

Ideas how to format source files can be found in the forum. Taking the script and porting it to JS is simple:
function formatUnitSourceCode(file) {
 unit = org.eclipse.jdt.core.JavaCore.create(file);

 unit.becomeWorkingCopy(null);

 formatter = org.eclipse.jdt.core.ToolFactory.createCodeFormatter(null);
 range = unit.getSourceRange();
 formatEdit = formatter
   .format(
     org.eclipse.jdt.core.formatter.CodeFormatter.K_COMPILATION_UNIT
       | org.eclipse.jdt.core.formatter.CodeFormatter.F_INCLUDE_COMMENTS,
     unit.getSource(), 0, unit.getSource().length(), 0, null);
 if (formatEdit.hasChildren()) {
  unit.applyTextEdit(formatEdit, null);
  unit.reconcile(org.eclipse.jdt.core.dom.AST.JLS4, false, null, null);
 }

 unit.commitWorkingCopy(true, null);
}

Step 3: glueing it all together

Load the function into your script shell, fetch the list of files as in step 1 and then process all files in a loop:
for each (file in files) formatUnitSourceCode(file);
That's it. This short script uses your current source formatter settings and applies it to all selected files.

This little helper is available online in the EASE script repository.