# CodeBuff smart formatter By Terence Parr (primary developer), Fangzhou (Morgan) Zhang (help with initial development), Jurgen Vinju (co-author of academic paper, help with empirical results and algorithm discussions). [kaby76](https://github.com/kaby76) has done a [C# port](https://github.com/kaby76/cs-codebuff). ## Abstract Code formatting is not particularly exciting but many researchers would consider it either unsolved or not well-solved. The two well-established solutions are: 1. Build a custom program that formats code for specific a language with ad hoc techniques, typically subject to parameters such as "*always put a space between operators*". 2. Define a set of formal rules that map input patterns to layout instructions such as "*line these expressions up vertically*". Either techniques are painful and finicky. This repository is a step towards what we hope will be a universal code formatter that uses machine learning to look for patterns in a corpus and to format code using those patterns. It requires Java 8. See `pom.xml` for dependencies (e.g., ANTLR 4.x, ...). *Whoa!* It appears to work. Academic paper, [Towards a Universal Code Formatter through Machine Learning](http://arxiv.org/abs/1606.08866) accepted to SLE2016. Sample output is in the paper or next section. Video from [Terence's presentation](https://www.youtube.com/watch?v=Mni2HVGGUdo). ## Sample output All input is completed squeezed of whitespace/newlines so only the output really matters when examining CodeBuff output. You can check out the [output](https://github.com/antlr/codebuff/tree/master/output) dir for leave-one-out formatting of the various [corpora](https://github.com/antlr/codebuff/tree/master/corpus). But, here are some sample formatting results. ### SQL ```sql SELECT * FROM DMartLogging WHERE DATEPART(day, ErrorDateTime) = DATEPART(day, GetDate()) AND DATEPART(month, ErrorDateTime) = DATEPART(month, GetDate()) AND DATEPART(year, ErrorDateTime) = DATEPART(year, GetDate()) ORDER BY ErrorDateTime DESC ``` ```sql SELECT CASE WHEN SSISInstanceID IS NULL THEN 'Total' ELSE SSISInstanceID END SSISInstanceID , SUM(OldStatus4) AS OldStatus4 , SUM(Status0) AS Status0 , SUM(Status1) AS Status1 , SUM(Status2) AS Status2 , SUM(Status3) AS Status3 , SUM(Status4) AS Status4 , SUM(OldStatus4 + Status0 + Status1 + Status2 + Status3 + Status4) AS InstanceTotal FROM ( SELECT CONVERT(VARCHAR, SSISInstanceID) AS SSISInstanceID , COUNT(CASE WHEN Status = 4 AND CONVERT(DATE, LoadReportDBEndDate) < CONVERT(DATE, GETDATE()) THEN Status ELSE NULL END) AS OldStatus4 , COUNT(CASE WHEN Status = 0 THEN Status ELSE NULL END) AS Status0 , COUNT(CASE WHEN Status = 1 THEN Status ELSE NULL END) AS Status1 , COUNT(CASE WHEN Status = 2 THEN Status ELSE NULL END) AS Status2 , COUNT(CASE WHEN Status = 3 THEN Status ELSE NULL END) AS Status3 --, COUNT ( CASE WHEN Status = 4 THEN Status ELSE NULL END ) AS Status4 , COUNT(CASE WHEN Status = 4 AND DATEPART(DAY, LoadReportDBEndDate) = DATEPART(DAY, GETDATE()) THEN Status ELSE NULL END) AS Status4 FROM dbo.ClientConnection GROUP BY SSISInstanceID ) AS StatusMatrix GROUP BY SSISInstanceID ``` ### Java ```java public class Interpreter { ... public static final Set predefinedAnonSubtemplateAttributes = new HashSet() { { add("i"); add("i0"); } }; ... public int exec(STWriter out, InstanceScope scope) { final ST self = scope.st; if ( trace ) System.out.println("exec("+self.getName()+")"); try { setDefaultArguments(out, scope); return _exec(out, scope); } catch (Exception e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); pw.flush(); errMgr.runTimeError(this, scope, ErrorType.INTERNAL_ERROR, "internal error: "+sw.toString()); return 0; } } ... protected int _exec(STWriter out, InstanceScope scope) { final ST self = scope.st; int start = out.index(); // track char we're about to write int prevOpcode = 0; int n = 0; // how many char we write out int nargs; int nameIndex; int addr; String name; Object o, left, right; ST st; Object[] options; byte[] code = self.impl.instrs; // which code block are we executing int ip = 0; while ( ip