Fantomas is a tool that can format F# code, like how Prettier for JavaScript works. The project was in rough shape when I first came across it and wasn’t actively maintained anymore. My F# mentor and I picked it up and started with some minor bugfixes and the port to .NET Core.
I asked Jindřich Ivánek to become co-maintainer due to his numerous contributions to the project. Last year at FableConf in Berlin, I had the opportunity to meet Jindřich in person and things have really gone up since then. We started to collaborate more, made useful tools to debug Fantomas and organize occasional Skype calls.
While the project was gaining some traction, new functionality was added to preserve the line ends after formatting. This change meant that the end of each formatted line was still more or less on the same line as the original source code.
At the time, it seemed like a good idea, however, it did bring along a lot of bugs with it. So, we decided to replace it with something similar. Trying to preserve each line end is simply not always possible. But preserving blank lines and comments is.
At a high-level, Fantomas (2.x), uses the FSharp Compiler Service to create an untyped abstract syntax tree (known as AST). It then traverses this tree and prints out all the nodes to strings. Check out the AST viewer to view some examples. The AST, however, does not contain all the information to do this.
A great example is code comments. These are nowhere to be found in the tree because the compiler doesn’t need them to create an executable format (.exe or .dll).
That is why after traversing the tree, the formatted code is being compared with the original. Token by token, the differences are being found and added to the new code if they are deemed necessary. To continue our code comments example, if it is found in the original and not in the formatted, it must have been added to the formatted code.
Some bugs were just not solvable with the current codebase. It is hard to pinpoint where comments should end up for example. Jindřich mentioned this to Don Syme and they started talking about the “trivia implementation.” Trivia is something that can be found in the source code but is not present in the AST. Comments and newlines being good examples, however, sometimes braces and keyword as well.
The main idea behind the next version of Fantomas is that we scan the source code first, before traversing the AST. In this scan, all the trivia are detected and linked to certain ranges. A range is a location inside the source base determined by four values (start-of-line, start-of-column, end-of-line and end-of-column). After the scan, we take this additional information with us when the tree is being traversed. If a node of the tree is being processed, we also take its trivia information into account. This way, we print the found-code comment at the time of creating the new code.
Once the tree has been fully traversed, we have already printed everything we need and do not require another comparison with the original source.
Akin to C#, F# has the concept of compiler directives. With this, you can include or exclude a piece of code based a configuration-setting the compiler knows about.
#if DEBUG
printfn “Foo”
#else
printfn “Bar”
#endif
In the snippet above the word, “Foo” will be printed if the configuration is DEBUG, in RELEASE the word “Bar” would be printed. The current version of Fantomas will only format one of both code branches and add the other one as is.
The next version of Fantomas will format the code multiple times, based on the combination of found directives and merge all results back together afterwards. This is a new powerful feature that overcomes a previous limitation. In its current form, Fantomas will work for most scenarios and might only misbehave when conditional operators come into play. That last part is highly unlikely, so we will cross that bridge only when we have to.
We have currently released the first beta of Fantomas 3.0 on NuGet. Or you can try it out online.
Please create issues if you encounter any problems whatsoever. Use the “create issue” link down below in the online tool.
With your help, we hope to be able to ship a stable version some time this summer.
A huge supporter of big data research in real-world data sets, the firm focuses on analysis and scientific prediction of global financial markets. They like open-source research and support F# development and the research community around computer science.
Jindřich has been my sounding board for various questions and suggestions. While I got the time to work on the project, he took the time to review and discuss my changes. Many thanks for all your time and effort.
Other people have really helped us well, shout outs to the ones that:
Fantomas would not be what it is today without FableConf last year. Meeting Jindřich in person brought this endeavour to a whole new level. And frankly Fable has nothing to do with Fantomas, FableConf brings together the great F# community and acts as a catalyzer for innovation and collaboration.
Join us at FableConf Antwerp this year! Add your support and buy your ticket today. Trust me its an amazing experience and awe-inspiring event.
Feel free to reach out if you wish to support the further development of Fantomas – in whatever shape or form that may be!
Image by Thomas Konings
Get to know Axxes and our corporate culture!
Join us at FableConf on September the 6th & 7th!
+3232349958