Header menu logo fantomas

Pull request ground rules

We expect some things from code changes. In general, changes should be made as consistent to the current code base as possible. Don't introduce unnecessary new concepts and try and change as little code as possible to achieve your goal.

Always start with the mindset that you are going to introduce a change that might have an impact on how the tool behaves. Capture this change first in a unit test. Set your expectations in the assert part of the test before touching anything. This project is very well suited for Test-driven development and that should be the goal.

Typical unit test template:

let ``my new test`` () =
    formatSourceString false """
let myInput =     42
"""  config
    |> prepend newline
    |> should equal """
let myInput = 42

The vast majority of the tests use the template listed above. Only deviate from this when necessary. Try and find a suitable file in Fantomas.Core.Tests, or introduce a new file.

A new test file should look like:

module Fantomas.Core.Tests.MyNewConceptTests

open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelpers

// add tests here...

Filename: MyNewConceptTests.fs.

When developing a new feature, add new tests to cover all code paths.

If you come across an issue, which can't be reproduced with the latest version of Fantomas but is still open, please submit a regression test. That way, we can ensure the issue stays fixed after closing it.


Target branch

Please always rebase your code on the targeted branch. To keep your fork up to date, run this command:

git remote add upstream https://github.com/fsprojects/fantomas.git

Updating your fork:

git checkout main && git fetch upstream && git rebase upstream/main && git push

Unit test

let ``preserve compile directive between piped functions, 512`` () = ...

You don't need to repeat this number for tests that are deviations from the original report problem.

Verify signature files

Verify if the change you are making should also apply to signature files (*.fsi).

Verify slight variations


Write/update documentation when necessary.
You can find instructions on how to run the documentation locally in the docs/.README.md file.

Pull request title

Format your changes


Run a local build

Finally, make sure to run dotnet fsi build.fsx. Among other things, this will check the format of the code and will tell you, if your changes caused any tests to fail.

Small steps

It is better to create a draft pull request with some initial small changes, and engage conversation, than to spend a lot of effort on a large pull request that was never discussed. Someone might be able to warn you in advance that your change will have wide implications for the rest of Fantomas, or might be able to point you in the right direction. However, this can only happen if you discuss your proposed changes early and often. It's often better to check before contributing that you're setting off on the right path.

Coding conventions

For consistency sake we have a few coding conventions. Please respect those to keep everything as streamlined as possible.

Member declaration

type Foo() =
    member _.Children = []
    // ✔️ OK
    member x.Length = x.Children.Length
    // ❌ Not preferred, we use `x`
    member this.WrongLength = this.Children.Length - 1
type Foo(v: Value) =
    // ✔️ OK
    member val Value = v
        // ❌ Not preferred.
    member _.WrongValue = v

Fixing style guide inconsistencies

Fantomas tries to keep up with the style guides, but as these are living documents, it can occur that something is listed in the style that Fantomas is not respecting. In this case, please create an issue using our online tool. Copy the code snippet from the guide and add a link to the section of the guide that is not being respected. The maintainers will then add the bug (stylistic) to confirm the bug is fixable in Fantomas. In most cases, it may seem obvious that the case can be fixed. However, in the past there have been changes to the style guide that Fantomas could not implement for technical reasons: Fantomas can only implement rules based on information entirely contained within the untyped syntax tree.

Target the next minor or major branch

When fixing a stylistic issue, please ask the maintainers what branch should be targeted. The rule of thumb is that the main branch is used for fixing bug (soundness) and will be used for revision releases. Strive to ensure that end users can always update to the latest patch revision of their current minor or major without fear.

A user should only need to deal with style changes when they have explicitly chosen to upgrade to a new minor or major version. In case no major or minor branch was created yet, please reach out to the maintainers. The maintainers will frequently rebase this branch on top of the main branch and release alpha/beta packages accordingly.

Multiple items
type Foo = new: unit -> Foo member Children: obj list member Length: int member WrongLength: int

new: unit -> Foo
val x: Foo
property Foo.Children: obj list with get
property List.Length: int with get
val this: Foo

Type something to start searching.