diff --git a/CHANGELOG.md b/CHANGELOG.md index c9bdf7bc5b..716cf81c89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## [Unreleased] + +### Changed +* Don't add space between type of array and square brackets. [#2192](https://github.com/fsprojects/fantomas/issues/2192) +* Renamed `fantomas-tool` to `fantomas` and the `Fantomas` namespace to `Fantomas.Core`. [#2174](https://github.com/fsprojects/fantomas/issues/2174) + +## [5.0.0-alpha-002] - 2022-04-04 + +### Changed +* Target net6.0 for fantomas-tool. + +## [5.0.0-alpha-001] - 2022-03-19 + +### Added +* Initial settings for strousrup bracket style. [#2161](https://github.com/fsprojects/fantomas/pull/2161) + ## [4.7.6] - 2022-04-04 ### Fixed diff --git a/README.md b/README.md index ef3a6a58e2..418b077940 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ F# source code formatter, inspired by [scalariform](https://github.com/mdr/scala ## Quick install -* Command line: `dotnet tool install -g fantomas-tool` +* Command line: `dotnet tool install -g fantomas` * JetBrains Rider: preinstalled * VSCode: part of [Ionide](http://ionide.io/) and [fantomas-fmt](https://marketplace.visualstudio.com/items?itemName=paolodellepiane.fantomas-fmt). * [Visual Studio 2019](https://marketplace.visualstudio.com/items?itemName=asti.fantomas-vs) @@ -22,7 +22,7 @@ F# source code formatter, inspired by [scalariform](https://github.com/mdr/scala Use this command to install Fantomas as a .NET 5 SDK global tool: ``` -dotnet tool install -g fantomas-tool +dotnet tool install -g fantomas ``` For detailed guidelines, please read [Fantomas: How to use](docs/Documentation.md#using-the-command-line-tool). @@ -38,7 +38,7 @@ The [resharper-fsharp](https://github.com/JetBrains/resharper-fsharp) uses fanto #### Using the latest version inside Rider For technical reasons Rider cannot always use the latest version of Fantomas found on NuGet. -As a workaround you could install [fantomas-tool](https://www.nuget.org/packages/fantomas-tool) locally with `dotnet tool install fantomas-tool` and configure it as an [External tool](https://www.jetbrains.com/help/rider/Settings_Tools_External_Tools.html). +As a workaround you could install [fantomas](https://www.nuget.org/packages/fantomas) locally with `dotnet tool install fantomas` and configure it as an [External tool](https://www.jetbrains.com/help/rider/Settings_Tools_External_Tools.html). ![Rider external tool window](./docs/rider-external-tool.png) @@ -62,7 +62,7 @@ The F# Formatting extension sets up Fantomas as the default formatter for F# fil ### Visual Studio for Mac -Install [fantomas-tool](https://www.nuget.org/packages/fantomas-tool) locally with `dotnet tool install fantomas-tool` and configure it as an [External tool] +Install [fantomas](https://www.nuget.org/packages/fantomas) locally with `dotnet tool install fantomas` and configure it as an [External tool] ![VS Mac external tool window](./docs/vsmac-external-tool.png) ### Online diff --git a/build.fsx b/build.fsx index c559184fd3..4d91b18d53 100644 --- a/build.fsx +++ b/build.fsx @@ -66,7 +66,7 @@ let fantomasExecutableForExternalTests projectdir = | DotNet.BuildConfiguration.Custom s -> s { ProcessName = "dotnet" - Arguments = [ sprintf "%s/src/Fantomas.CoreGlobalTool/bin/%s/net5.0/fantomas-tool.dll" projectdir configuration ] } + Arguments = [ sprintf "%s/src/Fantomas.CoreGlobalTool/bin/%s/net5.0/fantomas.dll" projectdir configuration ] } let externalProjectsToTest = [ diff --git a/docs/Daemon mode.md b/docs/Daemon mode.md index d9918a8737..e84d4fed58 100644 --- a/docs/Daemon mode.md +++ b/docs/Daemon mode.md @@ -10,13 +10,13 @@ Each version of Fantomas theoretically can have a different outcome as the style ## Solution -To tackle this problem, we introduce two new concepts: `--daemon` mode for the [fantomas-tool](https://www.nuget.org/packages/fantomas-tool) and [Fantomas.Client](https://www.nuget.org/packages/Fantomas.Client). +To tackle this problem, we introduce two new concepts: `--daemon` mode for the [fantomas tool](https://www.nuget.org/packages/fantomas) and [Fantomas.Client](https://www.nuget.org/packages/Fantomas.Client). `--daemon` would launch the commandline application as a sort of [LSP server](https://microsoft.github.io/language-server-protocol/) and `Fantomas.Client` could connect to this and proxy format requests. -Editor tooling would be able to launch your pinned version of `fantomas-tool` as a daemon service and interact with it outside-of-process. +Editor tooling would be able to launch your pinned version of `fantomas` as a daemon service and interact with it outside-of-process. ## End-user impact -End-users don't have to worry about `Fantomas.Client` or the `--daemon` flag. They only need to install a compatible version of `fantomas-tool`. +End-users don't have to worry about `Fantomas.Client` or the `--daemon` flag. They only need to install a compatible version of `fantomas`. Be it locally or globally. The first compatible version is `4.6.0-alpha-004`, all higher version should work as well. Local versions have precedence over the global version. diff --git a/docs/Documentation.md b/docs/Documentation.md index 7a11ada642..f627b628d1 100644 --- a/docs/Documentation.md +++ b/docs/Documentation.md @@ -8,10 +8,10 @@ Create a [.NET tool manifest](https://docs.microsoft.com/en-us/dotnet/core/tools > dotnet new tool-manifest Install the command line tool with: -> dotnet tool install fantomas-tool +> dotnet tool install fantomas or install the tool globally with -> dotnet tool install -g fantomas-tool +> dotnet tool install -g fantomas For the overview how to use the tool, you can type the command @@ -1253,7 +1253,7 @@ let add a b = a + b To exclude files from formatting, create a `.fantomasignore` file in the root of your project. `.fantomasignore` uses gitignore syntax (via [MAB.DotIgnore](https://github.com/markashleybell/MAB.DotIgnore)). -Ignored files will be picked up when the [Fantomas cli tool](https://www.nuget.org/packages/fantomas-tool/) or the FAKE helpers (in [Fantomas.Extras](https://www.nuget.org/packages/Fantomas.Extras/)) are used. +Ignored files will be picked up when the [Fantomas cli tool](https://www.nuget.org/packages/fantomas/) or the FAKE helpers (in [Fantomas.Extras](https://www.nuget.org/packages/Fantomas.Extras/)) are used. Exclusion applies both to formatting and the format checking. ``` @@ -1281,19 +1281,19 @@ git diff --cached --name-only --diff-filter=ACM -z | xargs -0 $HOME/.dotnet/tool git diff --cached --name-only --diff-filter=ACM -z | xargs -0 git add ``` -This script assumes you have installed Fantomas globally as a [dotnet tool](https://www.nuget.org/packages/fantomas-tool/) +This script assumes you have installed Fantomas globally as a [dotnet tool](https://www.nuget.org/packages/fantomas/) **Please use with caution** as [Fantomas is not without bugs](https://github.com/fsprojects/fantomas/issues?q=is%3Aissue+is%3Aopen+label%3A%22bug+%28soundness%29%22). ## FAKE Helpers Fantomas also exposes some less official helper functions in [Fantomas.Extras](https://www.nuget.org/packages/Fantomas.Extras/), these will be deprecated in the next major version. -It is advised to run the `fantomas-tool` instead when using FAKE, see [example](../fake-sample/README.md). +It is advised to run the `fantomas` tool instead when using FAKE, see [example](../fake-sample/README.md). ## Updating to a new Fantomas version By default, Fantomas adheres to the Microsoft [F# code formatting guidelines](https://docs.microsoft.com/en-us/dotnet/fsharp/style-guide/formatting). If these change, Fantomas will follow accordingly. Due to this reason, the output cannot be guaranteed to remain the same when upgrading to a new minor version. -If you are using Git for your source control, it is recommended to ignore commits where `fantomas-tool` was updated using a [.git-blame-ignore-revs file](https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revltrevgt). +If you are using Git for your source control, it is recommended to ignore commits where `fantomas` was updated using a [.git-blame-ignore-revs file](https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revltrevgt). Check out this [blogpost](https://www.moxio.com/blog/43/ignoring-bulk-change-commits-with-git-blame) for more details. diff --git a/docs/ragnarok.md b/docs/ragnarok.md new file mode 100644 index 0000000000..8dc0b151d2 --- /dev/null +++ b/docs/ragnarok.md @@ -0,0 +1,544 @@ +# The Ragnarok Feature + +I'm not sure who this document is for right now. These are some thoughts and some research about a certain feature that people want in Fantomas. +The feature is about how the code is printed back to source and is a variation on what the style guide advices today. + +I will go in great lengths why this is feature does not bring much value to the overall mission of Fantomas. +Why I consider it inconsistent and why the implementation is far from trivial. +Throughout this document there will be a negative tone toward this and for the initial draft I'm ok with this. +Again, there are no plans to publish this as is. +Oh and typos all over the place. + +## Introduction + +The feature has been request multiple times: +- https://github.com/fsprojects/fantomas/issues/1408 +- https://github.com/fsprojects/fantomas/issues/1225 +- https://github.com/fsprojects/fantomas/issues/453 (in comments) + +The gist is that some multiline expressions should start on the same line to save some space: + +```fsharp +let v = { + X = x + Y = y +} +``` + +The style guides deal with this by putting the entire expression on the next line: + +```fsharp +let v = + { X = x + Y = y } + +// or + +let v = + { + X = x + Y = y + } +``` + +## The inconsistency + +When you dissect the initial sample in AST you get something like: + +```fsharp +ImplFile + (ParsedImplFileInput + ("tmp.fsx", true, QualifiedNameOfFile Tmp$fsx, [], [], + [SynModuleOrNamespace + ([Tmp], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,4), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (v, false, None, tmp.fsx (1,4--1,5)), None, + Record + (None, None, + [((LongIdentWithDots ([X], []), true), Some (Ident x), + Some (tmp.fsx (2,10--3,4), None)); + ((LongIdentWithDots ([Y], []), true), Some (Ident y), None)], + tmp.fsx (1,8--4,1)), tmp.fsx (1,4--1,5), + Yes tmp.fsx (1,0--4,1))], tmp.fsx (1,0--4,1))], PreXmlDocEmpty, + [], None, tmp.fsx (1,0--4,1))], (true, true))) +``` + +or simplified: + +`SynBinding(pat = pat; expr = expr)` + +The `pat` represents the `v` and the `expr` everything after the equals sign. +In Fantomas we adhere to a simple rule, we tried an put everything on one line `let v = { X = ...` and if that crossed a certain threshold (based on a setting), we put the expression on the next line indented. + +Now the ask for the ragnarok setting, is to not do this for a handful of [SynExpr](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html). +There are about 65 union cases for `SynExpr` and for maybe 5 cases, people want to deviate from our currently consistent behavior. + +Of course, the thing is that the formatting of these `SynExpr` depends on the context of where the nodes are in. +Example: + +```fsharp +let v = { + X = x + Y = y +} + +// versus + +let vlist = [ + { X = x + Y = y } + // or + { + X = x + Y = y + } +] +``` + +If `SynExpr.Record` is the `expr` in a `SynBinding`, if would not require a newline after the `=` to start. +If it is part of `SynExpr.ArrayOrListComputed`, it would be following the default rules I guess. +Point is that, the combination of two syntax nodes would lead to a different style and that will occur all over the SyntaxTree. + +## The subjectivity + +As a long term Fantomas user, over time you stop caring about how the code looks like. You accept what is does and letting go of your past habits leads to a world of freedom. +People that do not use Fantomas, cannot cope with the fact that the formatted code does differ from their original source. +That is the idea thought, you follow a style guide and your code looks like how the rest of the world does it. + +In any case, as a maintainer, I'm always caught in between giving the people what they want and giving them what they need. +The point I'm trying to make is that there is no right or wrong in the style of code. If you prefer your own handwriting that is fine, but using a typewriter works just as well to bring your story. + +So, asking for a new style without any solid arguments really is a hard sell. People mentioned that this is a popular style and all that jazz but never bring up any numbers. +Nor, do they understand the technical nature of what their preferred style implies. +And lastly, not a single person has engaged the discussion in the MS style guide. This really rubs me the wrong way. +People want something, don't have a solid case, are clueless and don't put in the proper legwork to get somewhere. + +## Scope + +There are many syntax nodes in play for this feature. +Most people only list one example when they ask for this feature, but the realm of the SyntaxTree can be a quite large one. + +### SynExpr + +The `SynExpr` I believe that should be included in this would be: + +- [SynExpr.Record](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#Record) +- [SynExpr.AnonRecd](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#AnonRecd) +- [SynExpr.ComputationExpr](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#ComputationExpr) +- [SynExpr.ArrayOrListComputed](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#ArrayOrListComputed) + +I'm not sure that this list is completed. +Some people might also include [SynExpr.MatchLambda](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#MatchLambda). +And I also wonder about tuples, [SynExpr.Tuple](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#Tuple). + +Maybe multiline strings ([SynConst.String](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synconst.html#String) in [SynExpr.Const](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#Const)) should also be included: + +```fsharp +let json = """ +{ + "foo":"bar" +} +""" +``` + +Note that depending on the information stored in these nodes, they are formatted somewhat differently. + +### SynPat + +The `SynPat` cases might be: +- [SynPat.Record](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synpat.html#Record) +- [SynPat.ArrayOrList](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synpat.html#ArrayOrList) + +### SynType + +The `SynType` cases might be: +- [SynType.AnonRecd](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-syntype.html#AnonRecd) + +### SynBinding + +SynBinding is used for let bindings and members: + +```fsharp +let x a b = async { + return a + b +} + +type Foo() = + member this.Bar = {| + bar with X = x + |} // this is quite interesting how the closing brace is indented. +``` + +Fantomas has different rules depending on the details of the SynBinding. + +```fsharp +let a = { + X = x +} + +// different code path in CodePrinter +let b c = { + X = x +} + +// also a different code path in CodePrinter +let d e : MyRecord = { + X = x +} +``` + +### LetOrUseBang + +Note that not every time the `let` keyword is used, it leads to a `SynBinding`. +[LetBang](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#LetOrUseBang) for example has a different way of storing information. + +```fsharp +async { + let! a = { + X = x + } + () +} +``` + +### YieldOrReturn + +[YieldOrReturn](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#YieldOrReturn) + +```fsharp +myComp { + yield { + X = y + } + return { + Y = y + } +} +``` + +### YieldReturnFrom + +[YieldReturnFrom](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#YieldOrReturnFrom) + +```fsharp +myComp { + yield! { + X = y + } + return! { + Y = y + } +} +``` + +### SynExprAndBang + +[SynExprAndBang](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexprandbang.html) + +```fsharp +async { + let! x = y + and! z = async { + return! meh + } + () +} +``` + +### LongIdentSet + +[LongIdentSet](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#LongIdentSet) + +```fsharp +myMutable <- { + X = x +} +``` + +### DotIndexedSet + +[DotIndexedSet](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#DotIndexedSet) + +```fsharp +myMutable.[x] <- { + X = x +} +``` + +### Set + +[Set](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#Set) + +```fsharp +myMutable[x] <- { + X = x +} +``` + +New F# 6 syntax. + +### DotSet + +[DotSet](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#DotSet) + +```fsharp +myMutable().foo <- { + X = x +} +``` + +### Lambda + +[Lambda](https://fsprojects.github.io/fantomas-tools/#/ast?data=N4KABGBEAmCmBmBLAdrAzpAXFSAacUiaAYmolmPAIYA2as%2BEkAxgPZwWTwCuyYAHmAC0APjBU0AT2TMwwADoAneXwhhFsAC7dFffkpUBfSCENA) + +```fsharp +fun x -> async { + return x +} +``` + +This is an interesting one as there are quite some rules to format lambda in Fantomas. +There is the raw lambda as you see it above but it is often capture in more elaborate patterns: + +```fsharp +myTasks +|> List.map (fun p -> task { + return p +}) +|> Task.WhenAll +``` + +### SynMatchClause + +Used as part of [SynExpr.Match](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#Match) and [SynExpr.MatchBang](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#MatchBang). +[SynMatchClause](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synmatchclause.html). + +```fsharp +match v with +| () -> async { + return FooBar() +} +``` + +Keep in mind that [SynExpr.TryWith](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#TryWith) has this as well: + +```fsharp +try x with +| ex -> async { + () +} +``` + +### App + +Another very interesting case, where do you draw the line with [SynExpr.App](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#App) + +```fsharp +let v = + foo [ + a + b + c + ] +``` + +This is partially already implemented in the Elmish settings. +However, there are again a lot of possibilities there: + +```fsharp +let v = + foo "string" [ + a + b + c + ] +``` + +this is currently not supported. +When do you draw the line and go over to: + +```fsharp +let v = + foo + "string" + [ a + b + c ] +``` + +? + +#### Named arguments + +Another interesting edge case is named arguments inside applications: + +```fsharp +let v = + SomeConstructor(v = [ + A + B + C + ]) +``` + +Note that the AST for `v = [ ... ]` is something like + +```fsharp +App + (NonAtomic, false, + App + (NonAtomic, true, Ident op_Equality, Ident v, + tmp.fsx (2,20--2,23)), + ArrayOrListComputed + (false, + Sequential + (SuppressNeither, true, Ident A, + Sequential + (SuppressNeither, true, Ident B, Ident C, + tmp.fsx (4,8--5,9)), tmp.fsx (3,8--5,9)), + tmp.fsx (2,24--6,5)), tmp.fsx (2,20--6,5)), +tmp.fsx (2,19--2,20), Some tmp.fsx (6,5--6,6), +tmp.fsx (2,19--6,6) +``` + +so this is hard to detect in the first place. + +### SynExprRecordField + +[SynExprRecordField](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexprrecordfield.html) + +```fsharp +let v = { + X = { + Y = y + } +} +``` + +### Fields in AnonRecords + +[recordFields in AnonRecd](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#AnonRecd) + +```fsharp +let v = {| + X = {| + Y = y + |} +|} +``` + +### SynTypeDefnSimpleRepr.Record + +[SynTypeDefnSimpleRepr.Record](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-syntypedefnsimplerepr.html#Record) + +```fsharp +type V = { + X :int + Y: int +} +``` + +Note, access modifiers: + +```fsharp +type V = internal { + X :int + Y: int +} +``` + +Members need the `with` keyword: + +```fsharp +type V = { + X :int + Y: int +} with + member this.XY = X + Y +``` + +The current style does not use the `with` keyword, here is would be a requirement. + +This is also being used in [SynTypeDefnSigRepr.Simple](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-syntypedefnsigrepr.html). + +```fsharp +namespace Meh + +type V = { + X :int + Y: int +} with + member XY : int +``` + +### TypeAbbrev + +[SynType.AnonRecd](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-syntype.html#AnonRecd) in [SynTypeDefnSimpleRepr.TypeAbbrev](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-syntypedefnsimplerepr.html#TypeAbbrev). + +```fsharp +type V = {| + x :int +|} +``` + +### SynArgPats.NamePatPairs + +[SynArgPats.NamePatPairs](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synargpats.html#NamePatPairs) + +```fsharp +match x with +| Foo(x = { + Y = y + }) -> + () +``` + +### SynPat.Record + +[fieldPats in SynPat.Record](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synpat.html#Record) + +```fsharp +match x with +| { Y = { + X = y + }} -> + () + +// no idea if this looks ok but you get the idea, after the `Y =` you have the scenario. +``` + +### Even more nodes + +I'm quite certain that the list above is not complete. + +## Implementation + +The impact will be huge in CodePrinter, there are numerous locations where some clever helper function will need to be called in order not to newline. +I do believe that not placing the newline will not be the only thing that is required to make all these examples work. +Having an entirely new implementation for all the impacted nodes is also not recommended. + +Some re-use might be possible on the record side by turning on [fsharp_multiline_block_brackets_on_same_column](https://github.com/fsprojects/fantomas/blob/master/docs/Documentation.md#fsharp_multiline_block_brackets_on_same_column). +However, by doing this, a new precedent will be introduced. Two settings need to be combined in order for a valid code to be outputted. +This is unseen for the tool. + +And no battle plan survives first contact. Even if everything above is implemented and it produces no warnings whatsoever, the will more definitely be a case that pops up once this is released in the wild. + +## The twist + +Even though this whole thing is a bad idea, like a really bad one, I might be open to it in the future. +There are two things I still wish to achieve in the Fantomas project: +- A better Syntax tree: improvements on the compiler side to simplify Fantomas +- Parallel formatting: formatting certain syntax tree nodes in parallel to speed up things for large files. + +After that, I'm willing to open a bit to what the community wants out of this project. +I might even agreed to the ragnarok feature under very strict conditions. +These obviously would be that the feature is not breaking any existing tests and is not impacting anything else whatsoever. + +I'm also pretty much not going to do this implementation myself unless I'm properly paid for it. +Again, I don't care and this is a bad idea. \ No newline at end of file diff --git a/fake-sample/README.md b/fake-sample/README.md index d36e325c00..92e6faeb11 100644 --- a/fake-sample/README.md +++ b/fake-sample/README.md @@ -10,7 +10,7 @@ This was installed by: > dotnet tool install fake-cli -> dotnet tool install fantomas-tool +> dotnet tool install fantomas 2. Execute script: diff --git a/fantomas.sln b/fantomas.sln index 6bd611d2eb..00a3fb882f 100644 --- a/fantomas.sln +++ b/fantomas.sln @@ -8,7 +8,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{B570C5 paket.dependencies = paket.dependencies EndProjectSection EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Fantomas", "src\Fantomas\Fantomas.fsproj", "{7EA16279-A5F1-4781-A343-4375A04BCE6F}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Fantomas.Core", "src\Fantomas\Fantomas.Core.fsproj", "{7EA16279-A5F1-4781-A343-4375A04BCE6F}" EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Fantomas.Tests", "src\Fantomas.Tests\Fantomas.Tests.fsproj", "{DED76E41-B89F-47BA-84C5-3AB0BECFA767}" EndProject @@ -28,7 +28,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{29F22904-C docs\index.html = docs\index.html EndProjectSection EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fantomas.Client", "src\Fantomas.Client\Fantomas.Client.fsproj", "{AA895F94-CCF2-4FCF-A9BB-E16987B57535}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Fantomas.Client", "src\Fantomas.Client\Fantomas.Client.fsproj", "{AA895F94-CCF2-4FCF-A9BB-E16987B57535}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/Fantomas.Benchmarks/Fantomas.Benchmarks.fsproj b/src/Fantomas.Benchmarks/Fantomas.Benchmarks.fsproj index 2cfc3c240a..a7ef86f391 100644 --- a/src/Fantomas.Benchmarks/Fantomas.Benchmarks.fsproj +++ b/src/Fantomas.Benchmarks/Fantomas.Benchmarks.fsproj @@ -12,7 +12,7 @@ - + diff --git a/src/Fantomas.Benchmarks/Runners.fs b/src/Fantomas.Benchmarks/Runners.fs index 714f209dc3..6f4cddf9a1 100644 --- a/src/Fantomas.Benchmarks/Runners.fs +++ b/src/Fantomas.Benchmarks/Runners.fs @@ -3,7 +3,7 @@ module Fantomas.Benchmarks.Runners open System.IO open BenchmarkDotNet.Attributes open FSharp.Compiler.CodeAnalysis -open Fantomas +open Fantomas.Core open Fantomas.Extras let sharedChecker = lazy (FSharpChecker.Create()) diff --git a/src/Fantomas.CoreGlobalTool.Tests/ConfigTests.fs b/src/Fantomas.CoreGlobalTool.Tests/ConfigTests.fs index cdd169334f..9a4dd40409 100644 --- a/src/Fantomas.CoreGlobalTool.Tests/ConfigTests.fs +++ b/src/Fantomas.CoreGlobalTool.Tests/ConfigTests.fs @@ -1,6 +1,6 @@ module Fantomas.CoreGlobalTool.Tests.ConfigTests -open Fantomas +open Fantomas.Core open NUnit.Framework open FsUnit open Fantomas.CoreGlobalTool.Tests.TestHelpers diff --git a/src/Fantomas.CoreGlobalTool.Tests/DaemonTests.fs b/src/Fantomas.CoreGlobalTool.Tests/DaemonTests.fs index c97ef500ea..6978be7c9b 100644 --- a/src/Fantomas.CoreGlobalTool.Tests/DaemonTests.fs +++ b/src/Fantomas.CoreGlobalTool.Tests/DaemonTests.fs @@ -6,7 +6,7 @@ open Fantomas.CoreGlobalTool.Daemon open NUnit.Framework open FsUnit open Fantomas.CoreGlobalTool.Tests.TestHelpers -open Fantomas +open Fantomas.Core open Fantomas.Client.Contracts open Nerdbank.Streams open StreamJsonRpc diff --git a/src/Fantomas.CoreGlobalTool.Tests/TestHelpers.fs b/src/Fantomas.CoreGlobalTool.Tests/TestHelpers.fs index 206dc6260f..a779dbfe76 100644 --- a/src/Fantomas.CoreGlobalTool.Tests/TestHelpers.fs +++ b/src/Fantomas.CoreGlobalTool.Tests/TestHelpers.fs @@ -118,8 +118,8 @@ let getFantomasToolStartInfo arguments : ProcessStartInfo = "Fantomas.CoreGlobalTool", "bin", configuration, - "netcoreapp3.1", - "fantomas-tool.dll" + "net6.0", + "fantomas.dll" ) let startInfo = ProcessStartInfo("dotnet") diff --git a/src/Fantomas.CoreGlobalTool/Daemon.fs b/src/Fantomas.CoreGlobalTool/Daemon.fs index 12fb098bf9..d7ee3a98ac 100644 --- a/src/Fantomas.CoreGlobalTool/Daemon.fs +++ b/src/Fantomas.CoreGlobalTool/Daemon.fs @@ -12,9 +12,9 @@ open StreamJsonRpc open Thoth.Json.Net open Fantomas.Client.Contracts open Fantomas.Client.LSPFantomasServiceTypes -open Fantomas -open Fantomas.SourceOrigin -open Fantomas.FormatConfig +open Fantomas.Core +open Fantomas.Core.SourceOrigin +open Fantomas.Core.FormatConfig open Fantomas.Extras.EditorConfig open Fantomas.Extras diff --git a/src/Fantomas.CoreGlobalTool/Fantomas.CoreGlobalTool.fsproj b/src/Fantomas.CoreGlobalTool/Fantomas.CoreGlobalTool.fsproj index fd6e19b256..ce96c7ee08 100644 --- a/src/Fantomas.CoreGlobalTool/Fantomas.CoreGlobalTool.fsproj +++ b/src/Fantomas.CoreGlobalTool/Fantomas.CoreGlobalTool.fsproj @@ -1,21 +1,21 @@ Exe - netcoreapp3.1 + net6.0 en Major fantomas True - fantomas-tool + fantomas FS0025 true - + diff --git a/src/Fantomas.CoreGlobalTool/Program.fs b/src/Fantomas.CoreGlobalTool/Program.fs index 8cfe02e20a..7b2cd24485 100644 --- a/src/Fantomas.CoreGlobalTool/Program.fs +++ b/src/Fantomas.CoreGlobalTool/Program.fs @@ -1,8 +1,8 @@ open System open System.IO -open Fantomas +open Fantomas.Core open Fantomas.CoreGlobalTool.Daemon -open Fantomas.FormatConfig +open Fantomas.Core.FormatConfig open Fantomas.Extras open Argu open System.Text diff --git a/src/Fantomas.Extras/EditorConfig.fs b/src/Fantomas.Extras/EditorConfig.fs index f32c1145aa..109243fe25 100644 --- a/src/Fantomas.Extras/EditorConfig.fs +++ b/src/Fantomas.Extras/EditorConfig.fs @@ -2,7 +2,7 @@ module Fantomas.Extras.EditorConfig open System.Collections.Generic open System.ComponentModel -open Fantomas.FormatConfig +open Fantomas.Core.FormatConfig module Reflection = open System diff --git a/src/Fantomas.Extras/FakeHelpers.fs b/src/Fantomas.Extras/FakeHelpers.fs index 618c9473dc..176b790a31 100644 --- a/src/Fantomas.Extras/FakeHelpers.fs +++ b/src/Fantomas.Extras/FakeHelpers.fs @@ -3,8 +3,8 @@ module Fantomas.Extras.FakeHelpers open System open System.IO open FSharp.Compiler.CodeAnalysis -open Fantomas -open Fantomas.FormatConfig +open Fantomas.Core +open Fantomas.Core.FormatConfig open Fantomas.Extras exception CodeFormatException of (string * Option) array with diff --git a/src/Fantomas.Extras/Fantomas.Extras.fsproj b/src/Fantomas.Extras/Fantomas.Extras.fsproj index 2013bdb6b8..4c2521495c 100644 --- a/src/Fantomas.Extras/Fantomas.Extras.fsproj +++ b/src/Fantomas.Extras/Fantomas.Extras.fsproj @@ -14,7 +14,7 @@ - + \ No newline at end of file diff --git a/src/Fantomas.Tests/AppTests.fs b/src/Fantomas.Tests/AppTests.fs index 392f5e608e..b4713087f1 100644 --- a/src/Fantomas.Tests/AppTests.fs +++ b/src/Fantomas.Tests/AppTests.fs @@ -444,7 +444,7 @@ let ``space between function and argument in DotIndexedGet, 1261`` () = formatSourceString false """ -type Queue<'T>(data: list<'T []>, length: int) = +type Queue<'T>(data: list<'T[]>, length: int) = member this.Head = if length > 0 @@ -456,7 +456,7 @@ type Queue<'T>(data: list<'T []>, length: int) = |> should equal """ -type Queue<'T>(data: list<'T []>, length: int) = +type Queue<'T>(data: list<'T[]>, length: int) = member this.Head = if length > 0 then diff --git a/src/Fantomas.Tests/CodeFormatterTests.fs b/src/Fantomas.Tests/CodeFormatterTests.fs index 8ac5e80f2a..09b02db7a3 100644 --- a/src/Fantomas.Tests/CodeFormatterTests.fs +++ b/src/Fantomas.Tests/CodeFormatterTests.fs @@ -2,7 +2,7 @@ module Fantomas.Tests.CodeFormatterTests open NUnit.Framework open Fantomas.Tests.TestHelper -open Fantomas +open Fantomas.Core [] let ``sanitize filename if Program.fs`` () = diff --git a/src/Fantomas.Tests/CommentTests.fs b/src/Fantomas.Tests/CommentTests.fs index a40c2379fe..5a3cefb1e2 100644 --- a/src/Fantomas.Tests/CommentTests.fs +++ b/src/Fantomas.Tests/CommentTests.fs @@ -91,7 +91,7 @@ let ``comments on let bindings with return type, 2043`` () = formatSourceString false """ -let count: int [] // foo +let count: int[] // foo = [2] """ config @@ -99,7 +99,7 @@ let count: int [] // foo |> should equal """ -let count: int [] // foo +let count: int[] // foo = [ 2 ] """ @@ -110,7 +110,7 @@ let ``comments after SynType_Array in record type, 2043`` () = false """ type Model = - { Flags: bool [] // foo + { Flags: bool[] // foo Name: string // bar Street: string } """ @@ -120,7 +120,7 @@ type Model = equal """ type Model = - { Flags: bool [] // foo + { Flags: bool[] // foo Name: string // bar Street: string } """ diff --git a/src/Fantomas.Tests/ContextTests.fs b/src/Fantomas.Tests/ContextTests.fs index 4e314e73d0..9eb0588770 100644 --- a/src/Fantomas.Tests/ContextTests.fs +++ b/src/Fantomas.Tests/ContextTests.fs @@ -2,10 +2,10 @@ module Fantomas.Tests.ContextTests open NUnit.Framework open FsUnit -open Fantomas.Context +open Fantomas.Core.Context open Fantomas.Tests.TestHelper -open Fantomas.FormatConfig -open Fantomas +open Fantomas.Core.FormatConfig +open Fantomas.Core [] let ``sepSpace should not add an additional space if the line ends with a space`` () = diff --git a/src/Fantomas.Tests/ControlStructureTests.fs b/src/Fantomas.Tests/ControlStructureTests.fs index 3ce54dae41..47db887643 100644 --- a/src/Fantomas.Tests/ControlStructureTests.fs +++ b/src/Fantomas.Tests/ControlStructureTests.fs @@ -699,7 +699,7 @@ let ``keep new line before for loop, 1317`` () = false """ /// Fold over the array passing the index and element at that index to a folding function - let foldi (folder: 'State -> int -> 'T -> 'State) (state: 'State) (array: 'T []) = + let foldi (folder: 'State -> int -> 'T -> 'State) (state: 'State) (array: 'T[]) = checkNonNull "array" array if array.Length = 0 then @@ -722,7 +722,7 @@ let ``keep new line before for loop, 1317`` () = equal """ /// Fold over the array passing the index and element at that index to a folding function -let foldi (folder: 'State -> int -> 'T -> 'State) (state: 'State) (array: 'T []) = +let foldi (folder: 'State -> int -> 'T -> 'State) (state: 'State) (array: 'T[]) = checkNonNull "array" array if array.Length = 0 then diff --git a/src/Fantomas.Tests/DotGetTests.fs b/src/Fantomas.Tests/DotGetTests.fs index 5f7cd4d40e..d1e8b33a46 100644 --- a/src/Fantomas.Tests/DotGetTests.fs +++ b/src/Fantomas.Tests/DotGetTests.fs @@ -122,7 +122,7 @@ module Services = type StreamResolver(storage: Storage.Instance) = member __.Resolve ( - codec: FsCodec.IEventCodec<'event, byte [], _>, + codec: FsCodec.IEventCodec<'event, byte[], _>, fold: ('state -> 'event seq -> 'state), initial: 'state, snapshot: (('event -> bool) * ('state -> 'event)) @@ -150,7 +150,7 @@ module Services = type StreamResolver(storage: Storage.Instance) = member __.Resolve ( - codec: FsCodec.IEventCodec<'event, byte [], _>, + codec: FsCodec.IEventCodec<'event, byte[], _>, fold: ('state -> 'event seq -> 'state), initial: 'state, snapshot: (('event -> bool) * ('state -> 'event)) diff --git a/src/Fantomas.Tests/ElmishTests.fs b/src/Fantomas.Tests/ElmishTests.fs index e88f40b744..1c9a4ec663 100644 --- a/src/Fantomas.Tests/ElmishTests.fs +++ b/src/Fantomas.Tests/ElmishTests.fs @@ -1291,7 +1291,7 @@ let Dashboard () = ] """ { config with - RecordMultilineFormatter = Fantomas.FormatConfig.MultilineFormatterType.NumberOfItems + RecordMultilineFormatter = Fantomas.Core.FormatConfig.MultilineFormatterType.NumberOfItems MaxArrayOrListWidth = 20 MaxElmishWidth = 10 SingleArgumentWebMode = true diff --git a/src/Fantomas.Tests/FSharpScriptTests.fs b/src/Fantomas.Tests/FSharpScriptTests.fs index d45a586b97..ac3ebea635 100644 --- a/src/Fantomas.Tests/FSharpScriptTests.fs +++ b/src/Fantomas.Tests/FSharpScriptTests.fs @@ -3,7 +3,7 @@ module Fantomas.Tests.FSharpScriptTests open System.IO open NUnit.Framework open FsUnit -open Fantomas +open Fantomas.Core open Fantomas.Extras open Fantomas.Tests.TestHelper open Fantomas.Tests.FormatConfigEditorConfigurationFileTests diff --git a/src/Fantomas.Tests/Fantomas.Tests.fsproj b/src/Fantomas.Tests/Fantomas.Tests.fsproj index ad4a7e5c6f..81c80358f2 100644 --- a/src/Fantomas.Tests/Fantomas.Tests.fsproj +++ b/src/Fantomas.Tests/Fantomas.Tests.fsproj @@ -93,10 +93,29 @@ + + + + + + + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/src/Fantomas.Tests/FormatAstTests.fs b/src/Fantomas.Tests/FormatAstTests.fs index cf35f82ad9..081555cc32 100644 --- a/src/Fantomas.Tests/FormatAstTests.fs +++ b/src/Fantomas.Tests/FormatAstTests.fs @@ -1,6 +1,6 @@ module Fantomas.Tests.FormatAstTests -open Fantomas +open Fantomas.Core open NUnit.Framework open FsUnit open Fantomas.Tests.TestHelper diff --git a/src/Fantomas.Tests/FormatConfigEditorConfigurationFileTests.fs b/src/Fantomas.Tests/FormatConfigEditorConfigurationFileTests.fs index 9d2d1a029b..dcc8ac646e 100644 --- a/src/Fantomas.Tests/FormatConfigEditorConfigurationFileTests.fs +++ b/src/Fantomas.Tests/FormatConfigEditorConfigurationFileTests.fs @@ -1,8 +1,8 @@ module Fantomas.Tests.FormatConfigEditorConfigurationFileTests open System -open Fantomas -open Fantomas.FormatConfig +open Fantomas.Core +open Fantomas.Core.FormatConfig open Fantomas.Extras open Fantomas.Tests.TestHelper open NUnit.Framework diff --git a/src/Fantomas.Tests/InterfaceTests.fs b/src/Fantomas.Tests/InterfaceTests.fs index 82e7fb66ac..ce57d13019 100644 --- a/src/Fantomas.Tests/InterfaceTests.fs +++ b/src/Fantomas.Tests/InterfaceTests.fs @@ -256,12 +256,12 @@ let ``long abstract member definition, 435`` () = false """ type Test = - abstract RunJobs: folder:string * ?jobs:string * ?ctm:string * ?createDuplicate:bool * ?hold:bool * ?ignoreCriteria:bool * ?independentFlow:bool * ?orderDate:string * ?orderIntoFolder:string * ?variables:Dictionary [] * ?waitForOrderDate:bool + abstract RunJobs: folder:string * ?jobs:string * ?ctm:string * ?createDuplicate:bool * ?hold:bool * ?ignoreCriteria:bool * ?independentFlow:bool * ?orderDate:string * ?orderIntoFolder:string * ?variables:Dictionary[] * ?waitForOrderDate:bool -> string override this.RunJobs(folder: string, ?jobs: string, ?ctm: string, ?createDuplicate: bool, ?hold: bool, ?ignoreCriteria: bool, ?independentFlow: bool, ?orderDate: string, ?orderIntoFolder: string, - ?variables: Dictionary [], ?waitForOrderDate: bool) = + ?variables: Dictionary[], ?waitForOrderDate: bool) = "" """ config @@ -280,7 +280,7 @@ type Test = ?independentFlow: bool * ?orderDate: string * ?orderIntoFolder: string * - ?variables: Dictionary [] * + ?variables: Dictionary[] * ?waitForOrderDate: bool -> string @@ -295,7 +295,7 @@ type Test = ?independentFlow: bool, ?orderDate: string, ?orderIntoFolder: string, - ?variables: Dictionary [], + ?variables: Dictionary[], ?waitForOrderDate: bool ) = "" diff --git a/src/Fantomas.Tests/KeepIndentInBranchTests.fs b/src/Fantomas.Tests/KeepIndentInBranchTests.fs index 4d4ed2322b..2364c13cdf 100644 --- a/src/Fantomas.Tests/KeepIndentInBranchTests.fs +++ b/src/Fantomas.Tests/KeepIndentInBranchTests.fs @@ -3,7 +3,7 @@ open NUnit.Framework open FsUnit open Fantomas.Tests.TestHelper -open Fantomas.FormatConfig +open Fantomas.Core.FormatConfig let config = { config with KeepIndentInBranch = true } diff --git a/src/Fantomas.Tests/ListTests.fs b/src/Fantomas.Tests/ListTests.fs index 5b0216f487..e4d0b6cc4a 100644 --- a/src/Fantomas.Tests/ListTests.fs +++ b/src/Fantomas.Tests/ListTests.fs @@ -199,9 +199,9 @@ let getColumn c (A:_[,]) = flatten A.[*,c..c] |> Seq.toArray""" |> should equal """ -let cast<'a> (A: obj [,]) : 'a [,] = A |> Array2D.map unbox -let flatten (A: 'a [,]) = A |> Seq.cast<'a> -let getColumn c (A: _ [,]) = flatten A.[*, c..c] |> Seq.toArray +let cast<'a> (A: obj[,]) : 'a[,] = A |> Array2D.map unbox +let flatten (A: 'a[,]) = A |> Seq.cast<'a> +let getColumn c (A: _[,]) = flatten A.[*, c..c] |> Seq.toArray """ [] @@ -2134,7 +2134,7 @@ let ``yield inside list that is part of multi line function application, 1191`` formatSourceString false """ -let private fn (xs: int []) = +let private fn (xs: int[]) = fn2 "" [ let r = Seq.head xs @@ -2149,7 +2149,7 @@ let private fn (xs: int []) = |> should equal """ -let private fn (xs: int []) = +let private fn (xs: int[]) = fn2 "" [ let r = Seq.head xs @@ -2282,3 +2282,37 @@ let fns = // I think the space at the start of the lines above matter ] """ + +[] +let ``don't add space between array type and square brackets, 2192`` () = + let before = + """ +let x: int[] = [ 1, 2, 3 ] +let x: double[][] = [ [ 1.0, 2.0, 3.0 ] ] +let foo (x: double[]) (y: object[][]) : string[,] = x :> int[] +let foo<'T> (x: 'T[]) = x +""" + + formatSourceString false before config + |> prepend newline + |> should equal before + +let ``remove space between array type and square brackets, 2192`` () = + formatSourceString + false + """ +let x: int [] = [ 1, 2, 3 ] +let x: double [] [] = [ [ 1.0, 2.0, 3.0 ] ] +let foo (x: double []) (y: object [] []) : string [,] = x :> int [] +let foo<'T> (x: 'T []) = x +""" + config + |> prepend newline + |> should + equal + """ +let x: int[] = [ 1, 2, 3 ] +let x: double[][] = [ [ 1.0, 2.0, 3.0 ] ] +let foo (x: double[]) (y: object[][]) : string[,] = x :> int[] +let foo<'T> (x: 'T[]) = x +""" diff --git a/src/Fantomas.Tests/ModuleTests.fs b/src/Fantomas.Tests/ModuleTests.fs index d247924440..7e89f0a1cb 100644 --- a/src/Fantomas.Tests/ModuleTests.fs +++ b/src/Fantomas.Tests/ModuleTests.fs @@ -1,6 +1,6 @@ module Fantomas.Tests.ModuleTests -open Fantomas +open Fantomas.Core open NUnit.Framework open FsUnit open Fantomas.Tests.TestHelper diff --git a/src/Fantomas.Tests/MultilineBlockBracketsOnSameColumnRecordTests.fs b/src/Fantomas.Tests/MultilineBlockBracketsOnSameColumnRecordTests.fs index 462236d577..875f36c737 100644 --- a/src/Fantomas.Tests/MultilineBlockBracketsOnSameColumnRecordTests.fs +++ b/src/Fantomas.Tests/MultilineBlockBracketsOnSameColumnRecordTests.fs @@ -3,7 +3,7 @@ module Fantomas.Tests.MultilineBlockBracketsOnSameColumnRecordTests open NUnit.Framework open FsUnit open Fantomas.Tests.TestHelper -open Fantomas.FormatConfig +open Fantomas.Core.FormatConfig let config = { config with diff --git a/src/Fantomas.Tests/NewlineBetweenTypeDefinitionAndMembersTests.fs b/src/Fantomas.Tests/NewlineBetweenTypeDefinitionAndMembersTests.fs index 8e04d5c3ff..9e324d9512 100644 --- a/src/Fantomas.Tests/NewlineBetweenTypeDefinitionAndMembersTests.fs +++ b/src/Fantomas.Tests/NewlineBetweenTypeDefinitionAndMembersTests.fs @@ -62,7 +62,7 @@ let ``no extra newline after record type with no members`` () = To : float Name: string } """ - config + { config with MaxRecordWidth = 39 } |> prepend newline |> should equal diff --git a/src/Fantomas.Tests/NumberOfItemsListOrArrayTests.fs b/src/Fantomas.Tests/NumberOfItemsListOrArrayTests.fs index b1e78cdbe9..5ea24168f6 100644 --- a/src/Fantomas.Tests/NumberOfItemsListOrArrayTests.fs +++ b/src/Fantomas.Tests/NumberOfItemsListOrArrayTests.fs @@ -3,7 +3,7 @@ module Fantomas.Tests.NumberOfItemsListOrArrayTests open NUnit.Framework open FsUnit open Fantomas.Tests.TestHelper -open Fantomas.FormatConfig +open Fantomas.Core.FormatConfig [] let ``number of items sized lists are formatted properly`` () = diff --git a/src/Fantomas.Tests/NumberOfItemsRecordTests.fs b/src/Fantomas.Tests/NumberOfItemsRecordTests.fs index 891e753864..80dcc53822 100644 --- a/src/Fantomas.Tests/NumberOfItemsRecordTests.fs +++ b/src/Fantomas.Tests/NumberOfItemsRecordTests.fs @@ -3,7 +3,7 @@ module Fantomas.Tests.NumberOfItemsRecordTests open NUnit.Framework open FsUnit open Fantomas.Tests.TestHelper -open Fantomas.FormatConfig +open Fantomas.Core.FormatConfig let config = { config with RecordMultilineFormatter = NumberOfItems } diff --git a/src/Fantomas.Tests/OpenTypeTests.fs b/src/Fantomas.Tests/OpenTypeTests.fs index 6f1e74b426..221b9e505b 100644 --- a/src/Fantomas.Tests/OpenTypeTests.fs +++ b/src/Fantomas.Tests/OpenTypeTests.fs @@ -1,6 +1,5 @@ module Fantomas.Tests.OpenTypeTests -open Fantomas open NUnit.Framework open FsUnit open Fantomas.Tests.TestHelper diff --git a/src/Fantomas.Tests/PatternMatchingTests.fs b/src/Fantomas.Tests/PatternMatchingTests.fs index 059a7a852a..e2a83bd493 100644 --- a/src/Fantomas.Tests/PatternMatchingTests.fs +++ b/src/Fantomas.Tests/PatternMatchingTests.fs @@ -406,14 +406,14 @@ let ``should put brackets around array type tests`` () = false """ match item.Item with -| :? (Instruction []) -> ()""" +| :? (Instruction[]) -> ()""" config |> prepend newline |> should equal """ match item.Item with -| :? (Instruction []) -> () +| :? (Instruction[]) -> () """ [] diff --git a/src/Fantomas.Tests/QueueTests.fs b/src/Fantomas.Tests/QueueTests.fs index f60d392c3d..8ca490d7e5 100644 --- a/src/Fantomas.Tests/QueueTests.fs +++ b/src/Fantomas.Tests/QueueTests.fs @@ -1,6 +1,6 @@ module Fantomas.Tests.QueueTests -open Fantomas +open Fantomas.Core open NUnit.Framework open FsUnit open FsCheck diff --git a/src/Fantomas.Tests/Ragnarok/DotIndexedSetExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/DotIndexedSetExpressionTests.fs new file mode 100644 index 0000000000..8a119b484b --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/DotIndexedSetExpressionTests.fs @@ -0,0 +1,506 @@ +module Fantomas.Tests.Ragnarok.DotIndexedSetExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``dotIndexedSet with record instance `` () = + formatSourceString + false + """ +myMutable.[x] <- + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +myMutable.[x] <- { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +""" + +[] +let ``dotIndexedSet with update record`` () = + formatSourceString + false + """ +myMutable.[x] <- + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +myMutable.[x] <- + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``dotIndexedSet with anonymous record instance`` () = + formatSourceString + false + """ +myMutable.[x] <- + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +myMutable.[x] <- {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``dotIndexedSet with anonymous record instance struct`` () = + formatSourceString + false + """ +myMutable.[x] <- + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +myMutable.[x] <- struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``dotIndexedSet with computation expression`` () = + formatSourceString + false + """ +myMutable.[x] <- + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +myMutable.[x] <- task { + // some computation here + () +} +""" + +[] +let ``dotIndexedSet with list`` () = + formatSourceString + false + """ +myMutable.[x] <- + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +myMutable.[x] <- [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +""" + +[] +let ``dotIndexedSet with array`` () = + formatSourceString + false + """ +myMutable.[x] <- + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +myMutable.[x] <- [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +""" + +[] +let ``application unit dotIndexedSet with record instance `` () = + formatSourceString + false + """ +app().[x] <- + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +app().[x] <- { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +""" + +[] +let ``application unit dotIndexedSet with update record`` () = + formatSourceString + false + """ +app().[x] <- + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +app().[x] <- + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``application unit dotIndexedSet with anonymous record instance`` () = + formatSourceString + false + """ +app().[x] <- + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +app().[x] <- {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``application unit dotIndexedSet with anonymous record instance struct`` () = + formatSourceString + false + """ +app().[x] <- + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +app().[x] <- struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``application unit dotIndexedSet with computation expression`` () = + formatSourceString + false + """ +app().[x] <- + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +app().[x] <- task { + // some computation here + () +} +""" + +[] +let ``application unit dotIndexedSet with list`` () = + formatSourceString + false + """ +app().[x] <- + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +app().[x] <- [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +""" + +[] +let ``application unit dotIndexedSet with array`` () = + formatSourceString + false + """ +app().[x] <- + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +app().[x] <- [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +""" + +// See https://github.com/fsprojects/fantomas/issues/1999 + +[] +let ``application parenthesis expr dotIndexedSet with record instance `` () = + formatSourceString + false + """ +app(meh).[x] <- + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +app( + meh +).[x] <- { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +""" + +[] +let ``application parenthesis expr dotIndexedSet with update record`` () = + formatSourceString + false + """ +app(meh).[x] <- + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +app( + meh +).[x] <- + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``application parenthesis expr dotIndexedSet with anonymous record instance`` () = + formatSourceString + false + """ +app(meh).[x] <- + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +app( + meh +).[x] <- {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``application parenthesis expr dotIndexedSet with anonymous record instance struct`` () = + formatSourceString + false + """ +app(meh).[x] <- + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +app( + meh +).[x] <- struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``application parenthesis expr dotIndexedSet with computation expression`` () = + formatSourceString + false + """ +app(meh).[x] <- + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +app( + meh +).[x] <- task { + // some computation here + () +} +""" + +[] +let ``application parenthesis expr dotIndexedSet with list`` () = + formatSourceString + false + """ +app(meh).[x] <- + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +app( + meh +).[x] <- [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +""" + +[] +let ``application parenthesis expr dotIndexedSet with array`` () = + formatSourceString + false + """ +app(meh).[x] <- + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +app( + meh +).[x] <- [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +""" diff --git a/src/Fantomas.Tests/Ragnarok/DotSetExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/DotSetExpressionTests.fs new file mode 100644 index 0000000000..d2d03783d0 --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/DotSetExpressionTests.fs @@ -0,0 +1,170 @@ +module Fantomas.Tests.Ragnarok.DotSetExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``dotSet with record instance `` () = + formatSourceString + false + """ +App().foo <- + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +App().foo <- { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +""" + +[] +let ``dotSet with update record`` () = + formatSourceString + false + """ +App().foo <- + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +App().foo <- + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``dotSet with anonymous record instance`` () = + formatSourceString + false + """ +App().foo <- + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +App().foo <- {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``dotSet with anonymous record instance struct`` () = + formatSourceString + false + """ +App().foo <- + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +App().foo <- struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``dotSet with computation expression`` () = + formatSourceString + false + """ +App().foo <- + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +App().foo <- task { + // some computation here + () +} +""" + +[] +let ``dotSet with list`` () = + formatSourceString + false + """ +App().foo <- + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +App().foo <- [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +""" + +[] +let ``dotSet with array`` () = + formatSourceString + false + """ +App().foo <- + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +App().foo <- [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +""" diff --git a/src/Fantomas.Tests/Ragnarok/KeepIndentInBranchExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/KeepIndentInBranchExpressionTests.fs new file mode 100644 index 0000000000..418bfe17c6 --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/KeepIndentInBranchExpressionTests.fs @@ -0,0 +1,188 @@ +module Fantomas.Tests.Ragnarok.KeepIndentInBranchExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + KeepIndentInBranch = true + Ragnarok = true } + +// There currently is no conflict with this setting, but I'm guessing the case was never brought up. +// I would conclude that will never clash. + +[] +let ``synMatchClause in match expression with record instance `` () = + formatSourceString + false + """ +match x with +| _ -> + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +""" + +[] +let ``synMatchClause in match expression with update record`` () = + formatSourceString + false + """ +match x with +| _ -> + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``synMatchClause in match expression with anonymous record instance`` () = + formatSourceString + false + """ +match x with +| _ -> + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``synMatchClause in match expression with anonymous record instance struct`` () = + formatSourceString + false + """ +match x with +| _ -> + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``synMatchClause in match expression with computation expression`` () = + formatSourceString + false + """ +match x with +| _ -> + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> task { + // some computation here + () +} +""" + +[] +let ``synMatchClause in match expression with list`` () = + formatSourceString + false + """ +match x with +| _ -> + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +""" + +[] +let ``synMatchClause in match expression with array`` () = + formatSourceString + false + """ +match x with +| _ -> + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +""" diff --git a/src/Fantomas.Tests/Ragnarok/LambdaExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/LambdaExpressionTests.fs new file mode 100644 index 0000000000..73b3ee97b4 --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/LambdaExpressionTests.fs @@ -0,0 +1,856 @@ +module Fantomas.Tests.Ragnarok.LambdaExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``lambda with record instance `` () = + formatSourceString + false + """ +fun x -> + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +fun x -> { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +""" + +[] +let ``lambda with update record`` () = + formatSourceString + false + """ +fun x -> + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +fun x -> + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``lambda with anonymous record instance`` () = + formatSourceString + false + """ +fun x -> + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +fun x -> {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``lambda with anonymous record instance struct`` () = + formatSourceString + false + """ +fun x -> + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +fun x -> struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``lambda with computation expression`` () = + formatSourceString + false + """ +fun x -> + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +fun x -> task { + // some computation here + () +} +""" + +[] +let ``lambda with list`` () = + formatSourceString + false + """ +fun x -> + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +fun x -> [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +""" + +[] +let ``lambda with array`` () = + formatSourceString + false + """ +fun x -> + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +fun x -> [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +""" + +[] +let ``paren lambda with record instance `` () = + formatSourceString + false + """ +(fun x -> + { A = longTypeName + B = someOtherVariable + C = ziggyBarX }) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +}) +""" + +[] +let ``paren lambda with update record`` () = + formatSourceString + false + """ +(fun x -> + { astContext with IsInsideMatchClausePattern = true }) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> + { astContext with + IsInsideMatchClausePattern = true + }) +""" + +[] +let ``paren lambda with anonymous record instance`` () = + formatSourceString + false + """ +(fun x -> + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|}) +""" + +[] +let ``paren lambda with anonymous record instance struct`` () = + formatSourceString + false + """ +(fun x -> + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|}) +""" + +[] +let ``paren lambda with computation expression`` () = + formatSourceString + false + """ +(fun x -> + task { + // some computation here + () + }) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> task { + // some computation here + () +}) +""" + +[] +let ``paren lambda with list`` () = + formatSourceString + false + """ +(fun x -> + [ itemOne + itemTwo + itemThree + itemFour + itemFive ]) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> [ + itemOne + itemTwo + itemThree + itemFour + itemFive +]) +""" + +[] +let ``paren lambda with array`` () = + formatSourceString + false + """ +(fun x -> + [| itemOne + itemTwo + itemThree + itemFour + itemFive |]) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|]) +""" + +[] +let ``app paren lambda with record instance `` () = + formatSourceString + false + """ +List.map (fun x -> + { A = longTypeName + B = someOtherVariable + C = ziggyBarX }) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +}) +""" + +[] +let ``app paren lambda with update record`` () = + formatSourceString + false + """ +List.map (fun x -> + { astContext with IsInsideMatchClausePattern = true }) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> + { astContext with + IsInsideMatchClausePattern = true + }) +""" + +[] +let ``app paren lambda with anonymous record instance`` () = + formatSourceString + false + """ +List.map (fun x -> + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|}) +""" + +[] +let ``app paren lambda with anonymous record instance struct`` () = + formatSourceString + false + """ +List.map (fun x -> + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|}) +""" + +[] +let ``app paren lambda with computation expression`` () = + formatSourceString + false + """ +List.map (fun x -> + task { + // some computation here + () + }) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> task { + // some computation here + () +}) +""" + +[] +let ``app paren lambda with list`` () = + formatSourceString + false + """ +List.map (fun x -> + [ itemOne + itemTwo + itemThree + itemFour + itemFive ]) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> [ + itemOne + itemTwo + itemThree + itemFour + itemFive +]) +""" + +[] +let ``app paren lambda with array`` () = + formatSourceString + false + """ +List.map (fun x -> + [| itemOne + itemTwo + itemThree + itemFour + itemFive |]) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|]) +""" + +[] +let ``app paren lambda with record instance and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + { A = longTypeName + B = someOtherVariable + C = ziggyBarX }) b c +""" + config + |> prepend newline + |> should + equal + """ +List.map + (fun x -> { + A = longTypeName + B = someOtherVariable + C = ziggyBarX + }) + b + c +""" + +[] +let ``app paren lambda with update record and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + { astContext with IsInsideMatchClausePattern = true }) b c +""" + { config with MaxLineLength = 60 } + |> prepend newline + |> should + equal + """ +List.map + (fun x -> + { astContext with + IsInsideMatchClausePattern = true + }) + b + c +""" + +[] +let ``app paren lambda with anonymous record instance and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}) b c +""" + config + |> prepend newline + |> should + equal + """ +List.map + (fun x -> {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |}) + b + c +""" + +[] +let ``app paren lambda with anonymous record instance struct and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}) b c +""" + config + |> prepend newline + |> should + equal + """ +List.map + (fun x -> struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |}) + b + c +""" + +[] +let ``app paren lambda with computation expression and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + task { + // some computation here + () + }) b c +""" + config + |> prepend newline + |> should + equal + """ +List.map + (fun x -> task { + // some computation here + () + }) + b + c +""" + +[] +let ``app paren lambda with list and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + [ itemOne + itemTwo + itemThree + itemFour + itemFive ]) b c +""" + config + |> prepend newline + |> should + equal + """ +List.map + (fun x -> [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ]) + b + c +""" + +[] +let ``app paren lambda with array and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + [| itemOne + itemTwo + itemThree + itemFour + itemFive |]) b c +""" + config + |> prepend newline + |> should + equal + """ +List.map + (fun x -> [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |]) + b + c +""" + +[] +let ``dotGetApp with lambda with record instance`` () = + formatSourceString + false + """ +Bar.Foo(fun x -> { A = longTypeName + B = someOtherVariable + C = ziggyBarX + D = evenMoreZigBarry }).Bar() +""" + config + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> { + A = longTypeName + B = someOtherVariable + C = ziggyBarX + D = evenMoreZigBarry + }) + .Bar() +""" + +[] +let ``dotGetApp with lambda with update record`` () = + formatSourceString + false + """ +Bar.Foo(fun x -> { other with + A = longTypeName + B = someOtherVariable + C = ziggyBarX + D = evenMoreZigBarry }).Bar() +""" + { config with MaxLineLength = 60 } + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> + { other with + A = longTypeName + B = someOtherVariable + C = ziggyBarX + D = evenMoreZigBarry + }) + .Bar() +""" + +[] +let ``dotGetApp with lambda with anonymous record instance`` () = + formatSourceString + false + """ +Bar.Foo(fun x -> + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}).Bar() +""" + config + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |}) + .Bar() +""" + +[] +let ``dotGetApp with lambda with anonymous record instance struct`` () = + formatSourceString + false + """ +Bar + .Foo(fun x -> + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}).Bar() +""" + config + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |}) + .Bar() +""" + +[] +let ``dotGetApp with lambda with computation expression`` () = + formatSourceString + false + """ +Bar + .Foo(fun x -> + task { + // some computation here + () + }).Bar() +""" + config + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> task { + // some computation here + () + }) + .Bar() +""" + +[] +let ``dotGetApp with lambda with list`` () = + formatSourceString + false + """ +Bar + .Foo(fun x -> + [ itemOne + itemTwo + itemThree + itemFour + itemFive ]).Bar() +""" + config + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ]) + .Bar() +""" + +[] +let ``dotGetApp with lambda with array`` () = + formatSourceString + false + """ +Bar + .Foo(fun x -> + [| itemOne + itemTwo + itemThree + itemFour + itemFive |]).Bar() +""" + config + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |]) + .Bar() +""" diff --git a/src/Fantomas.Tests/Ragnarok/LetOrUseBangExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/LetOrUseBangExpressionTests.fs new file mode 100644 index 0000000000..dfea4679d6 --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/LetOrUseBangExpressionTests.fs @@ -0,0 +1,226 @@ +module Fantomas.Tests.Ragnarok.LetOrUseBangExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``letOrUseBang with record instance`` () = + formatSourceString + false + """ +opt { + let! foo = + { X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree } + + () +} +""" + config + |> prepend newline + |> should + equal + """ +opt { + let! foo = { + X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree + } + + () +} +""" + +[] +let ``letOrUseBang with update record`` () = + formatSourceString + false + """ +opt { + let! foo = + { bar with X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree } + + () +} +""" + config + |> prepend newline + |> should + equal + """ +opt { + let! foo = + { bar with + X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree + } + + () +} +""" + +[] +let ``letOrUseBang with anonymous record instance`` () = + formatSourceString + false + """ +opt { + let! foo = + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} + + () +} +""" + config + |> prepend newline + |> should + equal + """ +opt { + let! foo = {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + + () +} +""" + +[] +let ``letOrUseBang with anonymous record instance struct`` () = + formatSourceString + false + """ +opt { + let! foo = + struct {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} + + () +} +""" + config + |> prepend newline + |> should + equal + """ +opt { + let! foo = struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + + () +} +""" + +[] +let ``letOrUseBang with computation expression`` () = + formatSourceString + false + """ +task { + let! meh = + task { + // comment + return 42 + } + () +} +""" + config + |> prepend newline + |> should + equal + """ +task { + let! meh = task { + // comment + return 42 + } + + () +} +""" + +[] +let ``letOrUseBang with list`` () = + formatSourceString + false + """ +collect { + let! items = + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] + return items +} +""" + config + |> prepend newline + |> should + equal + """ +collect { + let! items = [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] + + return items +} +""" + +[] +let ``letOrUseBang with array`` () = + formatSourceString + false + """ +collect { + let! items = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] + return items +} +""" + config + |> prepend newline + |> should + equal + """ +collect { + let! items = [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] + + return items +} +""" diff --git a/src/Fantomas.Tests/Ragnarok/LongIdentSetExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/LongIdentSetExpressionTests.fs new file mode 100644 index 0000000000..4d403f96f5 --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/LongIdentSetExpressionTests.fs @@ -0,0 +1,170 @@ +module Fantomas.Tests.Ragnarok.LongIdentSetExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``longIdentSet with record instance `` () = + formatSourceString + false + """ +myMutable <- + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +myMutable <- { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +""" + +[] +let ``longIdentSet with update record`` () = + formatSourceString + false + """ +myMutable <- + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +myMutable <- + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``longIdentSet with anonymous record instance`` () = + formatSourceString + false + """ +myMutable <- + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +myMutable <- {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``longIdentSet with anonymous record instance struct`` () = + formatSourceString + false + """ +myMutable <- + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +myMutable <- struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``longIdentSet with computation expression`` () = + formatSourceString + false + """ +myMutable <- + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +myMutable <- task { + // some computation here + () +} +""" + +[] +let ``longIdentSet with list`` () = + formatSourceString + false + """ +myMutable <- + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +myMutable <- [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +""" + +[] +let ``longIdentSet with array`` () = + formatSourceString + false + """ +myMutable <- + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +myMutable <- [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +""" diff --git a/src/Fantomas.Tests/Ragnarok/MultiLineLambdaClosingNewlineExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/MultiLineLambdaClosingNewlineExpressionTests.fs new file mode 100644 index 0000000000..85dfe5983a --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/MultiLineLambdaClosingNewlineExpressionTests.fs @@ -0,0 +1,728 @@ +module Fantomas.Tests.Ragnarok.MultiLineLambdaClosingNewlineExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + MultiLineLambdaClosingNewline = true + Ragnarok = true } + +// TODO: figure out what should happen when you mix MultiLineLambdaClosingNewline and Ragnarok +// From a technical point of view, this is correct behavior but having `})` at the end seems sensible as well. + +[] +let ``paren lambda with record instance`` () = + formatSourceString + false + """ +(fun x -> + { A = longTypeName + B = someOtherVariable + C = ziggyBarX }) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +) +""" + +[] +let ``paren lambda with update record`` () = + formatSourceString + false + """ +(fun x -> + { astContext with IsInsideMatchClausePattern = true }) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> + { astContext with + IsInsideMatchClausePattern = true + } +) +""" + +[] +let ``paren lambda with anonymous record instance`` () = + formatSourceString + false + """ +(fun x -> + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +) +""" + +[] +let ``paren lambda with anonymous record instance struct`` () = + formatSourceString + false + """ +(fun x -> + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +) +""" + +[] +let ``paren lambda with computation expression`` () = + formatSourceString + false + """ +(fun x -> + task { + // some computation here + () + }) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> task { + // some computation here + () +} +) +""" + +[] +let ``paren lambda with list`` () = + formatSourceString + false + """ +(fun x -> + [ itemOne + itemTwo + itemThree + itemFour + itemFive ]) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +) +""" + +[] +let ``paren lambda with array`` () = + formatSourceString + false + """ +(fun x -> + [| itemOne + itemTwo + itemThree + itemFour + itemFive |]) +""" + config + |> prepend newline + |> should + equal + """ +(fun x -> [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +) +""" + +[] +let ``app paren lambda with record instance `` () = + formatSourceString + false + """ +List.map (fun x -> + { A = longTypeName + B = someOtherVariable + C = ziggyBarX }) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +) +""" + +[] +let ``app paren lambda with update record`` () = + formatSourceString + false + """ +List.map (fun x -> + { astContext with IsInsideMatchClausePattern = true }) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> + { astContext with + IsInsideMatchClausePattern = true + } +) +""" + +[] +let ``app paren lambda with anonymous record instance`` () = + formatSourceString + false + """ +List.map (fun x -> + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +) +""" + +[] +let ``app paren lambda with anonymous record instance struct`` () = + formatSourceString + false + """ +List.map (fun x -> + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +) +""" + +[] +let ``app paren lambda with computation expression`` () = + formatSourceString + false + """ +List.map (fun x -> + task { + // some computation here + () + }) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> task { + // some computation here + () +} +) +""" + +[] +let ``app paren lambda with list`` () = + formatSourceString + false + """ +List.map (fun x -> + [ itemOne + itemTwo + itemThree + itemFour + itemFive ]) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +) +""" + +[] +let ``app paren lambda with array`` () = + formatSourceString + false + """ +List.map (fun x -> + [| itemOne + itemTwo + itemThree + itemFour + itemFive |]) +""" + config + |> prepend newline + |> should + equal + """ +List.map (fun x -> [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +) +""" + +[] +let ``app paren lambda with record instance and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + { A = longTypeName + B = someOtherVariable + C = ziggyBarX }) b c +""" + config + |> prepend newline + |> should + equal + """ +List.map + (fun x -> { + A = longTypeName + B = someOtherVariable + C = ziggyBarX + } + ) + b + c +""" + +[] +let ``app paren lambda with update record and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + { astContext with IsInsideMatchClausePattern = true }) b c +""" + { config with MaxLineLength = 60 } + |> prepend newline + |> should + equal + """ +List.map + (fun x -> + { astContext with + IsInsideMatchClausePattern = true + } + ) + b + c +""" + +[] +let ``app paren lambda with anonymous record instance and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}) b c +""" + config + |> prepend newline + |> should + equal + """ +List.map + (fun x -> {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + ) + b + c +""" + +[] +let ``app paren lambda with anonymous record instance struct and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}) b c +""" + config + |> prepend newline + |> should + equal + """ +List.map + (fun x -> struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + ) + b + c +""" + +[] +let ``app paren lambda with computation expression and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + task { + // some computation here + () + }) b c +""" + config + |> prepend newline + |> should + equal + """ +List.map + (fun x -> task { + // some computation here + () + } + ) + b + c +""" + +[] +let ``app paren lambda with list and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + [ itemOne + itemTwo + itemThree + itemFour + itemFive ]) b c +""" + config + |> prepend newline + |> should + equal + """ +List.map + (fun x -> [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] + ) + b + c +""" + +[] +let ``app paren lambda with array and other args`` () = + formatSourceString + false + """ +List.map (fun x -> + [| itemOne + itemTwo + itemThree + itemFour + itemFive |]) b c +""" + config + |> prepend newline + |> should + equal + """ +List.map + (fun x -> [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] + ) + b + c +""" + +[] +let ``dotGetApp with lambda with record instance`` () = + formatSourceString + false + """ +Bar.Foo(fun x -> { A = longTypeName + B = someOtherVariable + C = ziggyBarX + D = evenMoreZigBarry }).Bar() +""" + config + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> { + A = longTypeName + B = someOtherVariable + C = ziggyBarX + D = evenMoreZigBarry + } + ) + .Bar() +""" + +[] +let ``dotGetApp with lambda with update record`` () = + formatSourceString + false + """ +Bar.Foo(fun x -> { other with + A = longTypeName + B = someOtherVariable + C = ziggyBarX + D = evenMoreZigBarry }).Bar() +""" + { config with MaxLineLength = 60 } + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> + { other with + A = longTypeName + B = someOtherVariable + C = ziggyBarX + D = evenMoreZigBarry + } + ) + .Bar() +""" + +[] +let ``dotGetApp with lambda with anonymous record instance`` () = + formatSourceString + false + """ +Bar.Foo(fun x -> + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}).Bar() +""" + config + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + ) + .Bar() +""" + +[] +let ``dotGetApp with lambda with anonymous record instance struct`` () = + formatSourceString + false + """ +Bar + .Foo(fun x -> + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |}).Bar() +""" + config + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + ) + .Bar() +""" + +[] +let ``dotGetApp with lambda with computation expression`` () = + formatSourceString + false + """ +Bar + .Foo(fun x -> + task { + // some computation here + () + }).Bar() +""" + config + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> task { + // some computation here + () + } + ) + .Bar() +""" + +[] +let ``dotGetApp with lambda with list`` () = + formatSourceString + false + """ +Bar + .Foo(fun x -> + [ itemOne + itemTwo + itemThree + itemFour + itemFive ]).Bar() +""" + config + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] + ) + .Bar() +""" + +[] +let ``dotGetApp with lambda with array`` () = + formatSourceString + false + """ +Bar + .Foo(fun x -> + [| itemOne + itemTwo + itemThree + itemFour + itemFive |]).Bar() +""" + config + |> prepend newline + |> should + equal + """ +Bar + .Foo(fun x -> [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] + ) + .Bar() +""" diff --git a/src/Fantomas.Tests/Ragnarok/NamedArgumentExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/NamedArgumentExpressionTests.fs new file mode 100644 index 0000000000..7d61fc2fa9 --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/NamedArgumentExpressionTests.fs @@ -0,0 +1,518 @@ +module Fantomas.Tests.Ragnarok.NamedArgumentExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``synExprApp with named argument with record instance`` () = + formatSourceString + false + """ +let v = + SomeConstructor( + v = + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + SomeConstructor( + v = { + A = longTypeName + B = someOtherVariable + C = ziggyBarX + } + ) +""" + +[] +let ``synExprApp with named argument with update record`` () = + formatSourceString + false + """ +let v = + SomeConstructor( + v = + { astContext with IsInsideMatchClausePattern = true + A = longTypeName + B = someOtherVariable + C = ziggyBarX } + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + SomeConstructor( + v = + { astContext with + IsInsideMatchClausePattern = true + A = longTypeName + B = someOtherVariable + C = ziggyBarX + } + ) +""" + +[] +let ``synExprApp with named argument with anonymous record instance`` () = + formatSourceString + false + """ +let v = + SomeConstructor( + v = + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + SomeConstructor( + v = {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + ) +""" + +[] +let ``synExprApp with named argument with anonymous record instance struct`` () = + formatSourceString + false + """ +let v = + SomeConstructor( + v = + struct {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + SomeConstructor( + v = struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + ) +""" + +[] +let ``synExprApp with named argument with computation expression`` () = + formatSourceString + false + """ +let v = + SomeConstructor( + v = + task { + // some computation here + () + } + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + SomeConstructor( + v = task { + // some computation here + () + } + ) +""" + +[] +let ``synExprApp with named argument with list`` () = + formatSourceString + false + """ +let v = + SomeConstructor( + v = + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + SomeConstructor( + v = [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] + ) +""" + +[] +let ``synExprApp with named argument with array`` () = + formatSourceString + false + """ +let v = + SomeConstructor( + v = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + SomeConstructor( + v = [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] + ) +""" + +[] +let ``synExprApp with multiple named arguments`` () = + formatSourceString + false + """ +let v = + SomeConstructor( + x = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |], + y = + [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + SomeConstructor( + x = [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |], + y = [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] + ) +""" + +[] +let ``synExprNew with named argument with record instance`` () = + formatSourceString + false + """ +let v = + new FooBar( + v = + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + new FooBar( + v = { + A = longTypeName + B = someOtherVariable + C = ziggyBarX + } + ) +""" + +[] +let ``synExprNew with named argument with update record`` () = + formatSourceString + false + """ +let v = + new FooBar( + v = + { astContext with IsInsideMatchClausePattern = true + A = longTypeName + B = someOtherVariable + C = ziggyBarX } + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + new FooBar( + v = + { astContext with + IsInsideMatchClausePattern = true + A = longTypeName + B = someOtherVariable + C = ziggyBarX + } + ) +""" + +[] +let ``synExprNew with named argument with anonymous record instance`` () = + formatSourceString + false + """ +let v = + new FooBar( + v = + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + new FooBar( + v = {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + ) +""" + +[] +let ``synExprNew with named argument with anonymous record instance struct`` () = + formatSourceString + false + """ +let v = + new FooBar( + v = + struct {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + new FooBar( + v = struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + ) +""" + +[] +let ``synExprNew with named argument with computation expression`` () = + formatSourceString + false + """ +let v = + new FooBar( + v = + task { + // some computation here + () + } + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + new FooBar( + v = task { + // some computation here + () + } + ) +""" + +[] +let ``synExprNew with named argument with list`` () = + formatSourceString + false + """ +let v = + new FooBar( + v = + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + new FooBar( + v = [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] + ) +""" + +[] +let ``synExprNew with named argument with array`` () = + formatSourceString + false + """ +let v = + new FooBar( + v = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + new FooBar( + v = [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] + ) +""" + +[] +let ``synExprNew with multiple named arguments`` () = + formatSourceString + false + """ +let v = + new FooBar( + x = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |], + y = + [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] + ) +""" + config + |> prepend newline + |> should + equal + """ +let v = + new FooBar( + x = [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |], + y = [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] + ) +""" diff --git a/src/Fantomas.Tests/Ragnarok/SetExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/SetExpressionTests.fs new file mode 100644 index 0000000000..39fe7c888f --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/SetExpressionTests.fs @@ -0,0 +1,170 @@ +module Fantomas.Tests.Ragnarok.SetExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``set with record instance `` () = + formatSourceString + false + """ +myMutable[x] <- + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +myMutable[x] <- { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +""" + +[] +let ``set with update record`` () = + formatSourceString + false + """ +myMutable[x] <- + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +myMutable[x] <- + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``set with anonymous record instance`` () = + formatSourceString + false + """ +myMutable[x] <- + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +myMutable[x] <- {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``set with anonymous record instance struct`` () = + formatSourceString + false + """ +myMutable[x] <- + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +myMutable[x] <- struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``set with computation expression`` () = + formatSourceString + false + """ +myMutable[x] <- + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +myMutable[x] <- task { + // some computation here + () +} +""" + +[] +let ``set with list`` () = + formatSourceString + false + """ +myMutable[x] <- + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +myMutable[x] <- [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +""" + +[] +let ``set with array`` () = + formatSourceString + false + """ +myMutable[x] <- + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +myMutable[x] <- [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +""" diff --git a/src/Fantomas.Tests/Ragnarok/SynBindingFunctionExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/SynBindingFunctionExpressionTests.fs new file mode 100644 index 0000000000..a64a94476e --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/SynBindingFunctionExpressionTests.fs @@ -0,0 +1,320 @@ +module Fantomas.Tests.Ragnarok.SynBindingFunctionExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``synbinding function with record instance `` () = + formatSourceString + false + """ +let x y = + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +let x y = { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +""" + +[] +let ``synbinding function with update record`` () = + formatSourceString + false + """ +let x y = + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +let x y = + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``synbinding function with anonymous record instance `` () = + formatSourceString + false + """ +let x y = + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +let x y = {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``synbinding function with computation expression`` () = + formatSourceString + false + """ +let x y = + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +let x y = task { + // some computation here + () +} +""" + +[] +let ``synbinding function with list`` () = + formatSourceString + false + """ +let x y = + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +let x y = [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +""" + +[] +let ``synbinding function with array`` () = + formatSourceString + false + """ +let x y = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +let x y = [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +""" + +[] +let ``type member function with record instance`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x = + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x = { + A = longTypeName + B = someOtherVariable + C = ziggyBarX + } +""" + +[] +let ``type member function with update record`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x = { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x = + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``type member function with anonymous record instance`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x = + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x = {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} +""" + +[] +let ``type member function with anonymous record instance struct`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x = + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x = struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} +""" + +[] +let ``type member function with computation expression`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x = + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x = task { + // some computation here + () + } +""" + +[] +let ``type member function with list`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x = + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x = [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] +""" + +[] +let ``type member function with array`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x = [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] +""" diff --git a/src/Fantomas.Tests/Ragnarok/SynBindingFunctionLongPatternExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/SynBindingFunctionLongPatternExpressionTests.fs new file mode 100644 index 0000000000..0fd8034c34 --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/SynBindingFunctionLongPatternExpressionTests.fs @@ -0,0 +1,518 @@ +module Fantomas.Tests.Ragnarok.SynBindingFunctionLongPatternExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MaxLineLength = 80 + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +// TODO: conclude on what should happen here +// This one feels very weird to have `= {` because the pattern is already multiline +[] +let ``synbinding function with record`` () = + formatSourceString + false + """ +let private addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +let private addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + { + A = longTypeName + B = someOtherVariable + C = ziggyBarX + } +""" + +[] +let ``synbinding function with update record`` () = + formatSourceString + false + """ +let private addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +let private addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + { astContext with + IsInsideMatchClausePattern = true + } +""" + + +[] +let ``synbinding function with anonymous record`` () = + formatSourceString + false + """ +let private addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +let private addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} +""" + +[] +let ``synbinding function with computation expression`` () = + formatSourceString + false + """ +let private addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +let private addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + task { + // some computation here + () + } +""" + +[] +let ``synbinding function with list`` () = + formatSourceString + false + """ +let private addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +let private addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] +""" + +[] +let ``synbinding function with array`` () = + formatSourceString + false + """ +let private addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +let private addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] +""" + + +[] +let ``type member function with record instance`` () = + formatSourceString + false + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + { + A = longTypeName + B = someOtherVariable + C = ziggyBarX + } +""" + +[] +let ``type member function with update record`` () = + formatSourceString + false + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``type member function with anonymous record instance`` () = + formatSourceString + false + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} +""" + +[] +let ``type member function with anonymous record instance struct`` () = + formatSourceString + false + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} +""" + +[] +let ``type member function with computation expression`` () = + formatSourceString + false + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + task { + // some computation here + () + } +""" + +[] +let ``type member function with list`` () = + formatSourceString + false + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] +""" + +[] +let ``type member function with array`` () = + formatSourceString + false + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.addTaskToScheduler + (scheduler: IScheduler) + taskName + taskCron + prio + (task: unit -> unit) + groupName + = + [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] +""" diff --git a/src/Fantomas.Tests/Ragnarok/SynBindingFunctionWithReturnTypeExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/SynBindingFunctionWithReturnTypeExpressionTests.fs new file mode 100644 index 0000000000..fc32ac78db --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/SynBindingFunctionWithReturnTypeExpressionTests.fs @@ -0,0 +1,320 @@ +module Fantomas.Tests.Ragnarok.SynBindingFunctionWithReturnTypeExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``synbinding function with record instance `` () = + formatSourceString + false + """ +let x y : MyRecord = + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +let x y : MyRecord = { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +""" + +[] +let ``synbinding function with update record`` () = + formatSourceString + false + """ +let x y : MyRecord = + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +let x y : MyRecord = + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``synbinding function with anonymous record instance `` () = + formatSourceString + false + """ +let x y : {| A:int; B:int; C:int |} = + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +let x y : {| A: int; B: int; C: int |} = {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``synbinding function with computation expression`` () = + formatSourceString + false + """ +let x y: Task = + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +let x y : Task = task { + // some computation here + () +} +""" + +[] +let ``synbinding function with list`` () = + formatSourceString + false + """ +let x y : int list = + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +let x y : int list = [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +""" + +[] +let ``synbinding function with array`` () = + formatSourceString + false + """ +let x y : int array = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +let x y : int array = [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +""" + +[] +let ``type member function with record instance`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x : MyRecord = + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x : MyRecord = { + A = longTypeName + B = someOtherVariable + C = ziggyBarX + } +""" + +[] +let ``type member function with update record`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x : MyRecord = { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x : MyRecord = + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``type member function with anonymous record instance`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x : {| A:int; B:int; C:int |} = + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x : {| A: int; B: int; C: int |} = {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} +""" + +[] +let ``type member function with anonymous record instance struct`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x : {| A:int; B:int; C:int |} = + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x : {| A: int; B: int; C: int |} = struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} +""" + +[] +let ``type member function with computation expression`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x : Task = + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x : Task = task { + // some computation here + () + } +""" + +[] +let ``type member function with list`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x : int list = + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x : int list = [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] +""" + +[] +let ``type member function with array`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar x : int array = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar x : int array = [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] +""" diff --git a/src/Fantomas.Tests/Ragnarok/SynBindingValueExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/SynBindingValueExpressionTests.fs new file mode 100644 index 0000000000..ab455d6e2e --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/SynBindingValueExpressionTests.fs @@ -0,0 +1,370 @@ +module Fantomas.Tests.Ragnarok.SynBindingValueExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``synbinding value with record instance `` () = + formatSourceString + false + """ +let x = + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +let x = { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +""" + +[] +let ``synbinding value with update record`` () = + formatSourceString + false + """ +let astCtx = + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +let astCtx = + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``synbinding value with anonymous record instance`` () = + formatSourceString + false + """ +let x = + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +let x = {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``synbinding value with anonymous record instance struct`` () = + formatSourceString + false + """ +let x = + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +let x = struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``synbinding value with computation expression`` () = + formatSourceString + false + """ +let t = + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +let t = task { + // some computation here + () +} +""" + +[] +let ``synbinding value with list`` () = + formatSourceString + false + """ +let t = + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +let t = [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +""" + +[] +let ``synbinding value with array`` () = + formatSourceString + false + """ +let t = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +let t = [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +""" + +[] +let ``nested synbinding value with record`` () = + formatSourceString + false + """ +let outer = + let inner = + { + X = someGreatXValue + Y = someRatherSmallYValue + } + () +""" + config + |> prepend newline + |> should + equal + """ +let outer = + let inner = { + X = someGreatXValue + Y = someRatherSmallYValue + } + + () +""" + +[] +let ``type member value with record instance`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar = + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar = { + A = longTypeName + B = someOtherVariable + C = ziggyBarX + } +""" + +[] +let ``type member value with update record`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar = { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar = + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``type member value with anonymous record instance`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar = + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar = {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} +""" + +[] +let ``type member value with anonymous record instance struct`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar = + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar = struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} +""" + +[] +let ``type member value with computation expression`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar = + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar = task { + // some computation here + () + } +""" + +[] +let ``type member value with list`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar = + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar = [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] +""" + +[] +let ``type member value with array`` () = + formatSourceString + false + """ +type Foo() = + member this.Bar = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +type Foo() = + member this.Bar = [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] +""" diff --git a/src/Fantomas.Tests/Ragnarok/SynExprAndBangExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/SynExprAndBangExpressionTests.fs new file mode 100644 index 0000000000..e57ecc9ca8 --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/SynExprAndBangExpressionTests.fs @@ -0,0 +1,248 @@ +module Fantomas.Tests.Ragnarok.SynExprAndBangExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``andBang with record instance`` () = + formatSourceString + false + """ +opt { + let! abc = def () + and! foo = + { X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree } + + () +} +""" + config + |> prepend newline + |> should + equal + """ +opt { + let! abc = def () + + and! foo = { + X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree + } + + () +} +""" + +[] +let ``andBang with update record`` () = + formatSourceString + false + """ +opt { + let! abc = def () + and! foo = + { bar with X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree } + + () +} +""" + config + |> prepend newline + |> should + equal + """ +opt { + let! abc = def () + + and! foo = + { bar with + X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree + } + + () +} +""" + +[] +let ``andBang with anonymous record instance`` () = + formatSourceString + false + """ +opt { + let! abc = def () + and! foo = + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} + + () +} +""" + config + |> prepend newline + |> should + equal + """ +opt { + let! abc = def () + + and! foo = {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + + () +} +""" + +[] +let ``andBang with anonymous record instance struct`` () = + formatSourceString + false + """ +opt { + let! abc = def () + and! foo = + struct {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} + + () +} +""" + config + |> prepend newline + |> should + equal + """ +opt { + let! abc = def () + + and! foo = struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + + () +} +""" + +[] +let ``andBang with computation expression`` () = + formatSourceString + false + """ +task { + let! abc = def () + and! meh = + task { + // comment + return 42 + } + () +} +""" + config + |> prepend newline + |> should + equal + """ +task { + let! abc = def () + + and! meh = task { + // comment + return 42 + } + + () +} +""" + +[] +let ``andBang with list`` () = + formatSourceString + false + """ +collect { + let! abc = def () + and! items = + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] + return items +} +""" + config + |> prepend newline + |> should + equal + """ +collect { + let! abc = def () + + and! items = [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] + + return items +} +""" + +[] +let ``andBang with array`` () = + formatSourceString + false + """ +collect { + let! abc = def () + + and! items = + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] + return items +} +""" + config + |> prepend newline + |> should + equal + """ +collect { + let! abc = def () + + and! items = [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] + + return items +} +""" diff --git a/src/Fantomas.Tests/Ragnarok/SynMatchClauseExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/SynMatchClauseExpressionTests.fs new file mode 100644 index 0000000000..c77b39c7f1 --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/SynMatchClauseExpressionTests.fs @@ -0,0 +1,454 @@ +module Fantomas.Tests.Ragnarok.SynMatchClauseExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``synMatchClause in match expression with record instance `` () = + formatSourceString + false + """ +match x with +| _ -> + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +""" + +[] +let ``synMatchClause in match expression with update record`` () = + formatSourceString + false + """ +match x with +| _ -> + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``synMatchClause in match expression with anonymous record instance`` () = + formatSourceString + false + """ +match x with +| _ -> + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``synMatchClause in match expression with anonymous record instance struct`` () = + formatSourceString + false + """ +match x with +| _ -> + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``synMatchClause in match expression with computation expression`` () = + formatSourceString + false + """ +match x with +| _ -> + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> task { + // some computation here + () +} +""" + +[] +let ``synMatchClause in match expression with list`` () = + formatSourceString + false + """ +match x with +| _ -> + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +""" + +[] +let ``synMatchClause in match expression with array`` () = + formatSourceString + false + """ +match x with +| _ -> + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ -> [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +""" + +// TODO: Here, I again feel this is fitting not to have ragnarok. +// Similar to long patterns in synbinding functions. + +[] +let ``synMatchClause in match expression with long when expression with record instance `` () = + formatSourceString + false + """ +match x with +| _ when (try + somethingDangerous () + true + with | ex -> false) + -> + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +match x with +| _ when + (try + somethingDangerous () + true + with + | ex -> false) + -> + { + A = longTypeName + B = someOtherVariable + C = ziggyBarX + } +""" + + +[] +let ``synMatchClause in try/with expression with record instance `` () = + formatSourceString + false + """ +try + foo() +with ex -> + { A = longTypeName + B = someOtherVariable + C = ziggyBarX } +""" + config + |> prepend newline + |> should + equal + """ +try + foo () +with +| ex -> { + A = longTypeName + B = someOtherVariable + C = ziggyBarX +} +""" + +[] +let ``synMatchClause in try/with expression with update record`` () = + formatSourceString + false + """ +try + foo() +with ex -> + { astContext with IsInsideMatchClausePattern = true } +""" + config + |> prepend newline + |> should + equal + """ +try + foo () +with +| ex -> + { astContext with + IsInsideMatchClausePattern = true + } +""" + +[] +let ``synMatchClause in try/with expression with anonymous record instance`` () = + formatSourceString + false + """ +try + foo() +with ex -> + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +try + foo () +with +| ex -> {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``synMatchClause in try/with expression with anonymous record instance struct`` () = + formatSourceString + false + """ +try + foo() +with ex -> + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +""" + config + |> prepend newline + |> should + equal + """ +try + foo () +with +| ex -> struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX +|} +""" + +[] +let ``synMatchClause in try/with expression with computation expression`` () = + formatSourceString + false + """ +try + foo() +with +| ex -> + task { + // some computation here + () + } +""" + config + |> prepend newline + |> should + equal + """ +try + foo () +with +| ex -> task { + // some computation here + () +} +""" + +[] +let ``synMatchClause in try/with expression with list`` () = + formatSourceString + false + """ +try + foo () +with +| ex -> + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +""" + config + |> prepend newline + |> should + equal + """ +try + foo () +with +| ex -> [ + itemOne + itemTwo + itemThree + itemFour + itemFive +] +""" + +[] +let ``synMatchClause in try/with expression with array`` () = + formatSourceString + false + """ +try + foo () +with +| ex -> + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +""" + config + |> prepend newline + |> should + equal + """ +try + foo () +with +| ex -> [| + itemOne + itemTwo + itemThree + itemFour + itemFive +|] +""" + +[] +let ``multiple clauses with lists`` () = + formatSourceString + false + """ +match x with +| SynMemberDefn.ImplicitCtor (_, attrs, ctorArgs, _, _xmlDoc, range) -> + [ yield mkNode SynMemberDefn_ImplicitCtor range + yield! (visitSynAttributeLists attrs) + yield! visitSynSimplePats ctorArgs ] +| SynMemberDefn.ImplicitInherit (inheritType, inheritArgs, _, range) -> + [ yield mkNode SynMemberDefn_ImplicitInherit range + yield! visitSynType inheritType + yield! visitSynExpr inheritArgs ] +""" + config + |> prepend newline + |> should + equal + """ +match x with +| SynMemberDefn.ImplicitCtor (_, attrs, ctorArgs, _, _xmlDoc, range) -> [ + yield mkNode SynMemberDefn_ImplicitCtor range + yield! (visitSynAttributeLists attrs) + yield! visitSynSimplePats ctorArgs + ] +| SynMemberDefn.ImplicitInherit (inheritType, inheritArgs, _, range) -> [ + yield mkNode SynMemberDefn_ImplicitInherit range + yield! visitSynType inheritType + yield! visitSynExpr inheritArgs + ] +""" diff --git a/src/Fantomas.Tests/Ragnarok/SynTypeDefnSigReprSimpleTests.fs b/src/Fantomas.Tests/Ragnarok/SynTypeDefnSigReprSimpleTests.fs new file mode 100644 index 0000000000..4bca70defd --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/SynTypeDefnSigReprSimpleTests.fs @@ -0,0 +1,96 @@ +module Fantomas.Tests.Ragnarok.SynTypeDefnSigReprSimpleTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``record type definition`` () = + formatSourceString + true + """ +namespace Foo + +type V = + { X: SomeFieldType + Y: OhSomethingElse + Z: ALongTypeName } +""" + config + |> prepend newline + |> should + equal + """ +namespace Foo + +type V = { + X: SomeFieldType + Y: OhSomethingElse + Z: ALongTypeName +} +""" + +[] +[] +let ``record type definition with comment after equals`` () = + formatSourceString + true + """ +namespace Foo + +type V = // comment + { X: SomeFieldType + Y: OhSomethingElse + Z: ALongTypeName } +""" + config + |> prepend newline + |> should + equal + """ +namespace Foo + +type V = // comment + { + X: SomeFieldType + Y: OhSomethingElse + Z: ALongTypeName + } +""" + +// TODO: I feel like ragnarok should not work when there are members involved +// Having members would require the `with` keyword which is not recommended by the style guide: https://docs.microsoft.com/en-us/dotnet/fsharp/style-guide/formatting#formatting-record-declarations + +[] +let ``record type definition with members`` () = + formatSourceString + true + """ +namespace Foo + +type V = + { X: SomeFieldType + Y: OhSomethingElse + Z: ALongTypeName } + member Coordinate : SomeFieldType * OhSomethingElse * ALongTypeName +""" + config + |> prepend newline + |> should + equal + """ +namespace Foo + +type V = + { + X: SomeFieldType + Y: OhSomethingElse + Z: ALongTypeName + } + member Coordinate: SomeFieldType * OhSomethingElse * ALongTypeName +""" diff --git a/src/Fantomas.Tests/Ragnarok/SynTypeDefnSimpleReprRecordTests.fs b/src/Fantomas.Tests/Ragnarok/SynTypeDefnSimpleReprRecordTests.fs new file mode 100644 index 0000000000..f491ad8254 --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/SynTypeDefnSimpleReprRecordTests.fs @@ -0,0 +1,84 @@ +module Fantomas.Tests.Ragnarok.SynTypeDefnSimpleReprRecordTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``record type definition`` () = + formatSourceString + false + """ +type V = + { X: SomeFieldType + Y: OhSomethingElse + Z: ALongTypeName } +""" + config + |> prepend newline + |> should + equal + """ +type V = { + X: SomeFieldType + Y: OhSomethingElse + Z: ALongTypeName +} +""" + +[] +[] +let ``record type definition with comment after equals`` () = + formatSourceString + false + """ +type V = // comment + { X: SomeFieldType + Y: OhSomethingElse + Z: ALongTypeName } +""" + config + |> prepend newline + |> should + equal + """ +type V = // comment + { + X: SomeFieldType + Y: OhSomethingElse + Z: ALongTypeName + } +""" + +// TODO: I feel like ragnarok should not work when there are members involved +// Having members would require the `with` keyword which is not recommended by the style guide: https://docs.microsoft.com/en-us/dotnet/fsharp/style-guide/formatting#formatting-record-declarations + +[] +let ``record type definition with members`` () = + formatSourceString + false + """ +type V = + { X: SomeFieldType + Y: OhSomethingElse + Z: ALongTypeName } + member this.Coordinate = (this.X, this.Y, this.Z) +""" + config + |> prepend newline + |> should + equal + """ +type V = + { + X: SomeFieldType + Y: OhSomethingElse + Z: ALongTypeName + } + member this.Coordinate = (this.X, this.Y, this.Z) +""" diff --git a/src/Fantomas.Tests/Ragnarok/YieldOrReturnBangExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/YieldOrReturnBangExpressionTests.fs new file mode 100644 index 0000000000..e0e3427fd9 --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/YieldOrReturnBangExpressionTests.fs @@ -0,0 +1,281 @@ +module Fantomas.Tests.Ragnarok.YieldOrReturnBangExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``yieldOrReturnBang with record instance`` () = + formatSourceString + false + """ +myComp { + yield! + { X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree } + return! + { X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree } +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield! { + X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree + } + + return! { + X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree + } +} +""" + +[] +let ``yieldOrReturnBang with update record`` () = + formatSourceString + false + """ +myComp { + yield! + { bar with X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree } + return! + { bar with X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree } +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield! + { bar with + X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree + } + + return! + { bar with + X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree + } +} +""" + +[] +let ``yieldOrReturnBang with anonymous record instance`` () = + formatSourceString + false + """ +myComp { + yield! + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} + return! + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield! {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + + return! {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} +} +""" + +[] +let ``yieldOrReturnBang with anonymous record instance struct`` () = + formatSourceString + false + """ +myComp { + yield! + struct {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} + return! + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield! struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + + return! struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} +} +""" + +[] +let ``yieldOrReturnBang with computation expression`` () = + formatSourceString + false + """ +myComp { + yield! + seq { + // meh + return 0 .. 2 + } + return! + seq { + // meh + return 0 .. 2 + } +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield! seq { + // meh + return 0..2 + } + + return! seq { + // meh + return 0..2 + } +} +""" + +[] +let ``yieldOrReturnBang with list`` () = + formatSourceString + false + """ +myComp { + yield! + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] + return! + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield! [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] + + return! [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] +} +""" + +[] +let ``yieldOrReturnBang with array`` () = + formatSourceString + false + """ +myComp { + yield! + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] + return! + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield! [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] + + return! [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] +} +""" diff --git a/src/Fantomas.Tests/Ragnarok/YieldOrReturnExpressionTests.fs b/src/Fantomas.Tests/Ragnarok/YieldOrReturnExpressionTests.fs new file mode 100644 index 0000000000..7818f6827c --- /dev/null +++ b/src/Fantomas.Tests/Ragnarok/YieldOrReturnExpressionTests.fs @@ -0,0 +1,281 @@ +module Fantomas.Tests.Ragnarok.YieldOrReturnExpressionTests + +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelper + +let config = + { config with + MultilineBlockBracketsOnSameColumn = true + Ragnarok = true } + +[] +let ``yieldOrReturn with record instance`` () = + formatSourceString + false + """ +myComp { + yield + { X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree } + return + { X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree } +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield { + X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree + } + + return { + X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree + } +} +""" + +[] +let ``yieldOrReturn with update record`` () = + formatSourceString + false + """ +myComp { + yield + { bar with X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree } + return + { bar with X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree } +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield + { bar with + X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree + } + + return + { bar with + X = xFieldValueOne + Y = yFieldValueTwo + Z = zFieldValueThree + } +} +""" + +[] +let ``yieldOrReturn with anonymous record instance`` () = + formatSourceString + false + """ +myComp { + yield + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} + return + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + + return {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} +} +""" + +[] +let ``yieldOrReturn with anonymous record instance struct`` () = + formatSourceString + false + """ +myComp { + yield + struct {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} + return + struct + {| A = longTypeName + B = someOtherVariable + C = ziggyBarX |} +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} + + return struct {| + A = longTypeName + B = someOtherVariable + C = ziggyBarX + |} +} +""" + +[] +let ``yieldOrReturn with computation expression`` () = + formatSourceString + false + """ +myComp { + yield + seq { + // meh + return 0 .. 2 + } + return + seq { + // meh + return 0 .. 2 + } +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield seq { + // meh + return 0..2 + } + + return seq { + // meh + return 0..2 + } +} +""" + +[] +let ``yieldOrReturn with list`` () = + formatSourceString + false + """ +myComp { + yield + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] + return + [ itemOne + itemTwo + itemThree + itemFour + itemFive ] +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] + + return [ + itemOne + itemTwo + itemThree + itemFour + itemFive + ] +} +""" + +[] +let ``yieldOrReturn with array`` () = + formatSourceString + false + """ +myComp { + yield + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] + return + [| itemOne + itemTwo + itemThree + itemFour + itemFive |] +} +""" + config + |> prepend newline + |> should + equal + """ +myComp { + yield [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] + + return [| + itemOne + itemTwo + itemThree + itemFour + itemFive + |] +} +""" diff --git a/src/Fantomas.Tests/TestHelpers.fs b/src/Fantomas.Tests/TestHelpers.fs index 52a2e21bb5..ffe18980ef 100644 --- a/src/Fantomas.Tests/TestHelpers.fs +++ b/src/Fantomas.Tests/TestHelpers.fs @@ -9,8 +9,8 @@ open FSharp.Compiler.Text open FSharp.Compiler.CodeAnalysis open FSharp.Compiler.Syntax open FSharp.Compiler.Xml -open Fantomas.FormatConfig -open Fantomas +open Fantomas.Core.FormatConfig +open Fantomas.Core open Fantomas.Extras [] diff --git a/src/Fantomas.Tests/TokenParserBoolExprTests.fs b/src/Fantomas.Tests/TokenParserBoolExprTests.fs index 20255dace5..c3b9cee7e3 100644 --- a/src/Fantomas.Tests/TokenParserBoolExprTests.fs +++ b/src/Fantomas.Tests/TokenParserBoolExprTests.fs @@ -1,10 +1,10 @@ module Fantomas.Tests.TokenParserBoolExprTests -open Fantomas +open Fantomas.Core open NUnit.Framework open FsUnit -open Fantomas.TokenParser -open Fantomas.TokenParserBoolExpr +open Fantomas.Core.TokenParser +open Fantomas.Core.TokenParserBoolExpr open Fantomas.Tests.TestHelper open FsCheck diff --git a/src/Fantomas.Tests/TokenParserTests.fs b/src/Fantomas.Tests/TokenParserTests.fs index 9440ccf66c..cf3aa46fab 100644 --- a/src/Fantomas.Tests/TokenParserTests.fs +++ b/src/Fantomas.Tests/TokenParserTests.fs @@ -1,10 +1,10 @@ module Fantomas.Tests.TokenParserTests -open Fantomas +open Fantomas.Core open NUnit.Framework open FsUnit -open Fantomas.TokenParser -open Fantomas.TriviaTypes +open Fantomas.Core.TokenParser +open Fantomas.Core.TriviaTypes open Fantomas.Tests.TestHelper let private isNewline item = diff --git a/src/Fantomas.Tests/TriviaTests.fs b/src/Fantomas.Tests/TriviaTests.fs index 988b5e7029..adc09f41a3 100644 --- a/src/Fantomas.Tests/TriviaTests.fs +++ b/src/Fantomas.Tests/TriviaTests.fs @@ -1,9 +1,9 @@ module Fantomas.Tests.TriviaTests open NUnit.Framework -open Fantomas +open Fantomas.Core open Fantomas.Tests.TestHelper -open Fantomas.TriviaTypes +open Fantomas.Core.TriviaTypes let private collectTrivia = Trivia.collectTrivia (fun (sl, sc) (el, ec) -> diff --git a/src/Fantomas.Tests/TypeDeclarationTests.fs b/src/Fantomas.Tests/TypeDeclarationTests.fs index f1afb978a1..164afca46e 100644 --- a/src/Fantomas.Tests/TypeDeclarationTests.fs +++ b/src/Fantomas.Tests/TypeDeclarationTests.fs @@ -171,7 +171,7 @@ let ``params arguments`` () = false """ type X() = - member this.F([] args: Object []) = + member this.F([] args: Object[]) = for arg in args do printfn "%A" arg""" config @@ -180,7 +180,7 @@ type X() = equal """ type X() = - member this.F([] args: Object []) = + member this.F([] args: Object[]) = for arg in args do printfn "%A" arg """ @@ -1055,14 +1055,14 @@ let ``should preserve attributes on member parameters`` () = false """ type ILogger = - abstract DebugFormat : format:String * []args:Object [] -> unit""" + abstract DebugFormat : format:String * []args:Object[] -> unit""" config |> prepend newline |> should equal """ type ILogger = - abstract DebugFormat: format: String * [] args: Object [] -> unit + abstract DebugFormat: format: String * [] args: Object[] -> unit """ [] @@ -3062,7 +3062,7 @@ type MethInfo = #if NO_EXTENSIONTYPING member ProvidedStaticParameterInfo: obj option #else - member ProvidedStaticParameterInfo: (Tainted * Tainted []) option + member ProvidedStaticParameterInfo: (Tainted * Tainted[]) option #endif """ config @@ -3081,6 +3081,6 @@ type MethInfo = #if NO_EXTENSIONTYPING member ProvidedStaticParameterInfo: obj option #else - member ProvidedStaticParameterInfo: (Tainted * Tainted []) option + member ProvidedStaticParameterInfo: (Tainted * Tainted[]) option #endif """ diff --git a/src/Fantomas.Tests/TypeProviderTests.fs b/src/Fantomas.Tests/TypeProviderTests.fs index cc7c40df34..733eb1a734 100644 --- a/src/Fantomas.Tests/TypeProviderTests.fs +++ b/src/Fantomas.Tests/TypeProviderTests.fs @@ -49,7 +49,7 @@ type Graphml = XmlProvider] let ``should throw FormatException on unparsed input`` () = - Assert.Throws (fun () -> + Assert.Throws (fun () -> formatSourceString false """ @@ -71,7 +71,7 @@ let ``should handle lines with more than 512 characters`` () = equal """ (new CsvFile( - new Func(fun (parent: obj) (row: string []) -> + new Func(fun (parent: obj) (row: string[]) -> CommonRuntime.GetNonOptionalValue( "Name", CommonRuntime.ConvertString(TextConversions.AsOption(row.[0])), @@ -87,7 +87,7 @@ let ``should handle lines with more than 512 characters`` () = CommonRuntime.ConvertDecimal("", TextConversions.AsOption(row.[2])), TextConversions.AsOption(row.[2]) )), - new Func(fun (row: string * decimal * decimal) -> + new Func(fun (row: string * decimal * decimal) -> [| CommonRuntime.ConvertStringBack(CommonRuntime.GetOptionalValue((let x, _, _ = row in x))) CommonRuntime.ConvertDecimalBack("", CommonRuntime.GetOptionalValue((let _, x, _ = row in x))) CommonRuntime.ConvertDecimalBack("", CommonRuntime.GetOptionalValue((let _, _, x = row in x))) |]), diff --git a/src/Fantomas.Tests/UtilsTests.fs b/src/Fantomas.Tests/UtilsTests.fs index 431a596f4e..f2978c9e60 100644 --- a/src/Fantomas.Tests/UtilsTests.fs +++ b/src/Fantomas.Tests/UtilsTests.fs @@ -2,7 +2,7 @@ module Fantomas.Tests.UtilsTests open System open NUnit.Framework -open Fantomas +open Fantomas.Core open Fantomas.Tests.TestHelper open FsCheck diff --git a/src/Fantomas/AstTransformer.fs b/src/Fantomas/AstTransformer.fs index 710b4715c7..4384eb0059 100644 --- a/src/Fantomas/AstTransformer.fs +++ b/src/Fantomas/AstTransformer.fs @@ -1,10 +1,10 @@ -module Fantomas.AstTransformer +module Fantomas.Core.AstTransformer open FSharp.Compiler.Text open FSharp.Compiler.Syntax -open Fantomas.TriviaTypes -open Fantomas.RangePatterns -open Fantomas +open Fantomas.Core.TriviaTypes +open Fantomas.Core.RangePatterns +open Fantomas.Core type Id = { Ident: string; Range: Range } diff --git a/src/Fantomas/CodeFormatter.fs b/src/Fantomas/CodeFormatter.fs index 6be64bdc5e..290544d5c5 100644 --- a/src/Fantomas/CodeFormatter.fs +++ b/src/Fantomas/CodeFormatter.fs @@ -1,4 +1,4 @@ -namespace Fantomas +namespace Fantomas.Core [] type CodeFormatter = diff --git a/src/Fantomas/CodeFormatter.fsi b/src/Fantomas/CodeFormatter.fsi index f9c406842c..a612627ded 100644 --- a/src/Fantomas/CodeFormatter.fsi +++ b/src/Fantomas/CodeFormatter.fsi @@ -1,7 +1,7 @@ -namespace Fantomas +namespace Fantomas.Core -open Fantomas.FormatConfig -open Fantomas.SourceOrigin +open Fantomas.Core.FormatConfig +open Fantomas.Core.SourceOrigin open FSharp.Compiler.Text open FSharp.Compiler.CodeAnalysis open FSharp.Compiler.Syntax diff --git a/src/Fantomas/CodeFormatterImpl.fs b/src/Fantomas/CodeFormatterImpl.fs index 28d8f0ae9f..286731f9b8 100644 --- a/src/Fantomas/CodeFormatterImpl.fs +++ b/src/Fantomas/CodeFormatterImpl.fs @@ -1,5 +1,5 @@ [] -module Fantomas.CodeFormatterImpl +module Fantomas.Core.CodeFormatterImpl open System open System.Diagnostics @@ -11,11 +11,11 @@ open FSharp.Compiler.Text open FSharp.Compiler.Text.Position open FSharp.Compiler.Text.Range open FSharp.Compiler.Tokenization -open Fantomas -open Fantomas.FormatConfig -open Fantomas.SourceOrigin -open Fantomas.SourceParser -open Fantomas.CodePrinter +open Fantomas.Core +open Fantomas.Core.FormatConfig +open Fantomas.Core.SourceOrigin +open Fantomas.Core.SourceParser +open Fantomas.Core.CodePrinter // Share an F# checker instance across formatting calls let sharedChecker = lazy (FSharpChecker.Create()) diff --git a/src/Fantomas/CodePrinter.fs b/src/Fantomas/CodePrinter.fs index 308db3d8c9..1182a03a5a 100644 --- a/src/Fantomas/CodePrinter.fs +++ b/src/Fantomas/CodePrinter.fs @@ -1,17 +1,17 @@ -module internal Fantomas.CodePrinter +module internal Fantomas.Core.CodePrinter open System open System.Text.RegularExpressions open FSharp.Compiler.Text open FSharp.Compiler.Syntax open FSharp.Compiler.Xml -open Fantomas -open Fantomas.FormatConfig -open Fantomas.SourceParser -open Fantomas.SourceTransformer -open Fantomas.Context -open Fantomas.TriviaTypes -open Fantomas.TriviaContext +open Fantomas.Core +open Fantomas.Core.FormatConfig +open Fantomas.Core.SourceParser +open Fantomas.Core.SourceTransformer +open Fantomas.Core.Context +open Fantomas.Core.TriviaTypes +open Fantomas.Core.TriviaContext /// This type consists of contextual information which is important for formatting /// Please avoid using this record as it can be the cause of unexpected behavior when used incorrectly @@ -1029,10 +1029,7 @@ and genNamedArgumentExpr (astContext: ASTContext) operatorExpr e1 e2 appRange = genExpr astContext e1 +> sepSpace +> genInfixOperator "=" operatorExpr - +> indent - +> sepNln - +> genExpr astContext e2 - +> unindent + +> autoIndentAndNlnExpressUnlessRagnarok (fun e -> sepSpace +> genExpr astContext e) e2 expressionFitsOnRestOfLine short long |> genTriviaFor SynExpr_App appRange @@ -1246,6 +1243,16 @@ and genExpr astContext synExpr ctx = +> ifElse isInfixExpr genInfixExpr genNonInfixExpr | SingleExpr (kind, e) -> + let mapping = + (match kind with + | YieldFrom _ + | Yield _ + | Return _ + | ReturnFrom _ + | Do _ + | DoBang _ -> autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok (genExpr astContext) e + | _ -> autoIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e)) + match kind with | InferredDowncast downcastKeyword -> genTriviaFor SynExpr_InferredDowncast_Downcast downcastKeyword !- "downcast " @@ -1262,7 +1269,8 @@ and genExpr astContext synExpr ctx = | Do doKeyword -> genTriviaFor SynExpr_Do_Do doKeyword !- "do " | DoBang doBangKeyword -> genTriviaFor SynExpr_DoBang_DoBang doBangKeyword !- "do! " | Fixed fixedKeyword -> genTriviaFor SynExpr_Fixed_Fixed fixedKeyword !- "fixed " - +> autoIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e) + +> mapping + | ConstExpr (c, r) -> genConst c r | NullExpr -> !- "null" // Not sure about the role of e1 @@ -1507,13 +1515,13 @@ and genExpr astContext synExpr ctx = +> genPat astContext pat +> genEq SynExpr_LetOrUseBang_Equals equalsRange +> sepSpace - +> autoIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext expr) + +> autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok (genExpr astContext) expr | AndBangStatement (pat, equalsRange, expr, range) -> !- "and! " +> genPat astContext pat +> genEq SynExprAndBang_Equals (Some equalsRange) +> sepSpace - +> autoIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext expr) + +> autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok (genExpr astContext) expr |> genTriviaFor SynExprAndBang_ range | OtherStatement expr -> genExpr astContext expr @@ -1545,9 +1553,9 @@ and genExpr astContext synExpr ctx = | JoinIn (e1, e2) -> genExpr astContext e1 -- " in " +> genExpr astContext e2 - | Paren (lpr, Lambda (pats, arrowRange, expr, lambdaRange), rpr, _pr) -> + | Paren (lpr, Lambda (pats, arrowRange, expr, lambdaRange), rpr, pr) -> fun (ctx: Context) -> - let body = genExprKeepIndentInBranch astContext expr + let body = genExprKeepIndentInBranch astContext let expr = let triviaOfLambda f (ctx: Context) = @@ -1563,18 +1571,22 @@ and genExpr astContext synExpr ctx = +> (fun ctx -> if not ctx.Config.MultiLineLambdaClosingNewline then genLambdaArrowWithTrivia - (body - +> triviaOfLambda printContentAfter - +> sepNlnWhenWriteBeforeNewlineNotEmpty id - +> sepCloseTFor rpr) + (fun e -> + body e + +> triviaOfLambda printContentAfter + +> sepNlnWhenWriteBeforeNewlineNotEmpty id + +> sepCloseTFor rpr) + expr arrowRange ctx else leadingExpressionIsMultiline (genLambdaArrowWithTrivia - (body - +> triviaOfLambda printContentAfter - +> sepNlnWhenWriteBeforeNewlineNotEmpty id) + (fun e -> + body e + +> triviaOfLambda printContentAfter + +> sepNlnWhenWriteBeforeNewlineNotEmpty id) + expr arrowRange) (fun isMultiline -> onlyIf isMultiline sepNln +> sepCloseTFor rpr) ctx) @@ -1591,7 +1603,7 @@ and genExpr astContext synExpr ctx = sepArrow |> genTriviaFor SynExpr_Lambda_Arrow arrowRange) arrowRange - +> autoIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext expr) + +> autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok (genExpr astContext) expr ) | MatchLambda (keywordRange, cs) -> (!- "function " @@ -2070,7 +2082,8 @@ and genExpr astContext synExpr ctx = +> (!- "fun " +> col sepSpace pats (genPat astContext) +> genLambdaArrowWithTrivia - (genExprKeepIndentInBranch astContext bodyExpr) + (genExprKeepIndentInBranch astContext) + bodyExpr arrowRange |> genTriviaFor SynExpr_Lambda range) +> sepNln @@ -2147,7 +2160,7 @@ and genExpr astContext synExpr ctx = +> (sepOpenTFor lpr +> (!- "fun " +> col sepSpace pats (genPat astContext) - +> genLambdaArrowWithTrivia (genExprKeepIndentInBranch astContext body) arrowRange + +> genLambdaArrowWithTrivia (genExprKeepIndentInBranch astContext) body arrowRange |> genTriviaFor SynExpr_Lambda lambdaRange) +> sepNlnWhenWriteBeforeNewlineNotEmpty sepNone +> sepCloseTFor rpr @@ -2162,7 +2175,7 @@ and genExpr astContext synExpr ctx = +> (sepOpenTFor lpr +> (!- "fun " +> col sepSpace pats (genPat astContext) - +> genLambdaArrowWithTrivia (genExprKeepIndentInBranch astContext body) arrowRange + +> genLambdaArrowWithTrivia (genExprKeepIndentInBranch astContext) body arrowRange |> genTriviaFor SynExpr_Lambda lambdaRange) +> sepCloseTFor rpr |> genTriviaFor SynExpr_Paren pr) @@ -2249,7 +2262,11 @@ and genExpr astContext synExpr ctx = +> genTriviaFor SynExpr_TryWith_With withKeyword (!- "with") +> indentOnWith +> sepNln - +> col sepNln cs (genClause astContext true) + +> (fun ctx -> + let hasMultipleClausesWhereOneHasRagnarok = + hasMultipleClausesWhereOneHasRagnarok ctx.Config.Ragnarok cs + + col sepNln cs (genClause astContext true hasMultipleClausesWhereOneHasRagnarok) ctx) +> unindentOnWith ) @@ -2430,7 +2447,7 @@ and genExpr astContext synExpr ctx = +> opt id lastRange (leaveNodeFor Ident_) | LongIdentSet (s, e, _) -> !-(sprintf "%s <- " s) - +> autoIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e) + +> autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok (genExpr astContext) e | DotIndexedGet (App (e, [ ConstExpr (SynConst.Unit, _) as ux ]), indexArgs) -> genExpr astContext e +> genExpr astContext ux @@ -2472,7 +2489,7 @@ and genExpr astContext synExpr ctx = (appExpr +> idx +> genExpr astContext valueExpr) (appExpr +> idx - +> autoIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext valueExpr)) + +> autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok (genExpr astContext) valueExpr) | DotIndexedSet (AppSingleParenArg (a, px), indexArgs, valueExpr) -> let short = genExpr astContext a +> genExpr astContext px @@ -2491,14 +2508,14 @@ and genExpr astContext synExpr ctx = (short +> idx +> genExpr astContext valueExpr) (long +> idx - +> autoIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext valueExpr)) + +> autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok (genExpr astContext) valueExpr) | DotIndexedSet (objectExpr, indexArgs, valueExpr) -> addParenIfAutoNln objectExpr (genExpr astContext) -- ".[" +> genExpr astContext indexArgs -- "] <- " - +> autoIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext valueExpr) + +> autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok (genExpr astContext) valueExpr | NamedIndexedPropertySet (ident, e1, e2) -> !-ident +> genExpr astContext e1 -- " <- " +> autoIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e2) @@ -2524,12 +2541,12 @@ and genExpr astContext synExpr ctx = | DotSet (e1, s, e2) -> addParenIfAutoNln e1 (genExpr astContext) -- sprintf ".%s <- " s - +> genExpr astContext e2 + +> autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok (genExpr astContext) e2 | SynExpr.Set (e1, e2, _) -> addParenIfAutoNln e1 (genExpr astContext) -- sprintf " <- " - +> genExpr astContext e2 + +> autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok (genExpr astContext) e2 | ParsingError r -> raise @@ -2901,7 +2918,7 @@ and genMultilineFunctionApplicationArguments astContext argExpr = (sepOpenTFor lpr +> (!- "fun " +> col sepSpace pats (genPat astContext) - +> genLambdaArrowWithTrivia (genExprKeepIndentInBranch astContext body) arrowRange + +> genLambdaArrowWithTrivia (genExprKeepIndentInBranch astContext) body arrowRange |> genTriviaFor SynExpr_Lambda range) +> sepNln +> sepCloseTFor rpr) @@ -3055,7 +3072,6 @@ and genMultilineRecordInstanceAlignBrackets +> unindent +> ifElseCtx lastWriteEventIsNewline sepNone sepNln +> genTriviaFor SynExpr_Record_ClosingBrace closingBrace sepCloseSFixed) - |> atCurrentColumnIndent and genMultilineAnonRecord (isStruct: bool) fields copyInfo (astContext: ASTContext) = let recordExpr = @@ -3131,7 +3147,7 @@ and genMultilineAnonRecordAlignBrackets (isStruct: bool) fields copyInfo astCont +> sepCloseAnonRecdFixed ifElse isStruct !- "struct " sepNone - +> atCurrentColumnIndent genAnonRecord + +> genAnonRecord and genObjExpr t eio withKeyword bd members ims range (astContext: ASTContext) = // Check the role of the second part of eio @@ -3273,7 +3289,7 @@ and genApp astContext e es ctx = leadingExpressionIsMultiline (sepOpenTFor lpr -- "fun " +> pats - +> genLambdaArrowWithTrivia (genExprKeepIndentInBranch astContext bodyExpr) arrowRange) + +> genLambdaArrowWithTrivia (genExprKeepIndentInBranch astContext) bodyExpr arrowRange) (fun isMultiline -> onlyIf isMultiline sepNln +> sepCloseTFor rpr) |> genTriviaFor SynExpr_Paren pr @@ -3319,7 +3335,7 @@ and genLambdaMultiLineClosingNewline leadingExpressionIsMultiline (sepOpenTFor lpr -- "fun " +> col sepSpace pats (genPat astContext) - +> genLambdaArrowWithTrivia (genExprKeepIndentInBranch astContext bodyExpr) arrowRange + +> genLambdaArrowWithTrivia (genExprKeepIndentInBranch astContext) bodyExpr arrowRange |> genTriviaFor SynExpr_Lambda lambdaRange) (fun isMultiline -> onlyIf isMultiline sepNln +> sepCloseTFor rpr) |> genTriviaFor SynExpr_Paren pr @@ -3643,9 +3659,7 @@ and genTypeDefn closingBrace) (genMultilineSimpleRecordTypeDefn astContext openingBrace withKeyword ms ao' fs closingBrace) - let bodyExpr ctx = - let size = getRecordSize ctx fs - + let bodyExpr size ctx = if (List.isEmpty ms) then (isSmallExpression size smallExpression multilineExpression +> leaveNodeFor SynTypeDefnSimpleRepr_Record tdr.Range // this will only print something when there is trivia after } in the short expression @@ -3655,11 +3669,22 @@ and genTypeDefn else multilineExpression ctx + let genTypeDefinition (ctx: Context) = + let size = getRecordSize ctx fs + + let short = + enterNodeFor SynTypeDefnSimpleRepr_Record tdr.Range + +> bodyExpr size + +> leaveNodeFor SynTypeDefnSimpleRepr_Record tdr.Range + + if ctx.Config.Ragnarok && ms.IsEmpty then + (sepSpace +> short) ctx + else + isSmallExpression size short (indent +> sepNln +> short +> unindent) ctx + typeName +> genEq SynTypeDefn_Equals equalsRange - +> indent - +> genTriviaFor SynTypeDefnSimpleRepr_Record tdr.Range bodyExpr - +> unindent + +> genTypeDefinition | Simple TDSRNone -> typeName | Simple (TDSRTypeAbbrev t) -> @@ -3821,8 +3846,7 @@ and genMultilineSimpleRecordTypeDefn astContext openingBrace withKeyword ms ao' and genMultilineSimpleRecordTypeDefnAlignBrackets astContext openingBrace withKeyword ms ao' fs closingBrace = // the typeName is already printed - sepNlnUnlessLastEventIsNewline - +> opt (indent +> sepNln) ao' genAccess + opt (indent +> sepNln) ao' genAccess +> enterNodeFor SynTypeDefnSimpleRepr_Record_OpeningBrace openingBrace +> sepOpenSFixed +> indent @@ -3936,9 +3960,7 @@ and genSigTypeDefn (genSigSimpleRecordAlignBrackets astContext openingBrace withKeyword ms ao' fs closingBrace) (genSigSimpleRecord astContext openingBrace withKeyword ms ao' fs closingBrace) - let bodyExpr ctx = - let size = getRecordSize ctx fs - + let bodyExpr size ctx = if (List.isEmpty ms) then (isSmallExpression size smallExpression multilineExpression +> leaveNodeFor SynTypeDefnSimpleRepr_Record tdr.Range // this will only print something when there is trivia after } in the short expression @@ -3948,11 +3970,20 @@ and genSigTypeDefn else multilineExpression ctx - typeName - +> genEq SynTypeDefnSig_Equals equalsRange - +> indent - +> genTriviaFor SynTypeDefnSimpleRepr_Record tdr.Range bodyExpr - +> unindent + let genTypeDefinition (ctx: Context) = + let size = getRecordSize ctx fs + + let short = + enterNodeFor SynTypeDefnSimpleRepr_Record tdr.Range + +> bodyExpr size + +> leaveNodeFor SynTypeDefnSimpleRepr_Record tdr.Range + + if ctx.Config.Ragnarok && ms.IsEmpty then + (sepSpace +> short) ctx + else + isSmallExpression size short (indent +> sepNln +> short +> unindent) ctx + + typeName +> sepEq +> genTypeDefinition | SigSimple TDSRNone -> let genMembers = @@ -4039,10 +4070,7 @@ and genSigTypeDefn |> genTriviaFor SynTypeDefnSig_ fullRange and genSigSimpleRecord astContext openingBrace withKeyword ms ao' fs closingBrace = - // the typeName is already printed - sepNlnUnlessLastEventIsNewline - +> opt (indent +> sepNln) ao' genAccess - +> enterNodeFor SynTypeDefnSimpleRepr_Record_OpeningBrace openingBrace + opt (indent +> sepNln) ao' genAccess +> sepOpenS +> atCurrentColumn ( leaveNodeFor SynTypeDefnSimpleRepr_Record_OpeningBrace openingBrace @@ -4055,10 +4083,7 @@ and genSigSimpleRecord astContext openingBrace withKeyword ms ao' fs closingBrac +> colPre sepNln sepNln ms (genMemberSig astContext) and genSigSimpleRecordAlignBrackets astContext openingBrace withKeyword ms ao' fs closingBrace = - // the typeName is already printed - sepNlnUnlessLastEventIsNewline - +> opt (indent +> sepNln) ao' genAccess - +> enterNodeFor SynTypeDefnSimpleRepr_Record_OpeningBrace openingBrace + opt (indent +> sepNln) ao' genAccess +> sepOpenSFixed +> indent +> sepNln @@ -4269,7 +4294,7 @@ and genType astContext outerBracket t = +> addSpaceIfSynTypeStaticConstantHasAtSignBeforeString t2 +> loop t2 | TArray (t, n, r) -> - loop t -- " [" +> rep (n - 1) (!- ",") -- "]" + loop t -- "[" +> rep (n - 1) (!- ",") -- "]" |> genTriviaFor SynType_Array r | TAnon -> sepWild | TVar (tp, r) -> @@ -4564,7 +4589,12 @@ and genInterfaceImpl astContext (InterfaceImpl (t, withKeywordRange, bs, members +> genMemberDefnList astContext members +> unindent -and genClause astContext hasBar (Clause (p, eo, arrowRange, e) as ce) = +and genClause + (astContext: ASTContext) + (hasBar: bool) + (hasMultipleClausesWhereOneHasRagnarok: bool) + (Clause (p, eo, arrowRange, e) as ce) + = let astCtx = { astContext with IsInsideMatchClausePattern = true } let patAndBody = @@ -4606,14 +4636,34 @@ and genClause astContext hasBar (Clause (p, eo, arrowRange, e) as ce) = sepArrow |> genTriviaFor SynMatchClause_Arrow arrowRange) arrowRange - +> autoIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e)) + +> autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok (genExpr astContext) e) ctx) - (onlyIf hasBar sepBar +> patAndBody + (onlyIf hasBar sepBar + +> (fun ctx -> + if hasMultipleClausesWhereOneHasRagnarok then + // avoid edge case + (* + match x with + | y -> [ + 1 + 2 + 3 + ] + | z -> [ + 4 + 5 + 6 + ] + *) + // ] and | cannot align, otherwise you get a parser error + atCurrentColumn patAndBody ctx + else + patAndBody ctx) |> genTriviaFor SynMatchClause_ ce.Range) -and genClauses astContext cs = - col sepNln cs (genClause astContext true) +and genClauses astContext cs (ctx: Context) = + col sepNln cs (genClause astContext true (hasMultipleClausesWhereOneHasRagnarok ctx.Config.Ragnarok cs)) ctx /// Each multiline member definition has a pre and post new line. and genMemberDefnList astContext nodes = @@ -5156,7 +5206,12 @@ and genSynBindingFunction if isMultiline then (indent +> sepNln +> body +> unindent) else - sepSpaceIfShortExpressionOrAddIndentAndNewline ctx.Config.MaxFunctionBindingWidth body + let short = sepSpace +> body + + let long = + autoIndentAndNlnExpressUnlessRagnarok (fun e -> sepSpace +> genExprKeepIndentInBranch astContext e) e + + isShortExpression ctx.Config.MaxFunctionBindingWidth short long (genPreXmlDoc px +> genAttrIsFirstChild @@ -5261,7 +5316,12 @@ and genSynBindingFunctionWithReturnType if isMultiline then (indent +> sepNln +> body +> unindent) else - sepSpaceIfShortExpressionOrAddIndentAndNewline ctx.Config.MaxFunctionBindingWidth body + let short = sepSpace +> body + + let long = + autoIndentAndNlnExpressUnlessRagnarok (fun e -> sepSpace +> genExprKeepIndentInBranch astContext e) e + + isShortExpression ctx.Config.MaxFunctionBindingWidth short long (genPreXmlDoc px +> genAttrIsFirstChild @@ -5380,10 +5440,7 @@ and genSynBindingValue let long = prefix - +> indent - +> sepNln - +> genExprKeepIndentInBranch astContext e - +> unindent + +> autoIndentAndNlnExpressUnlessRagnarok (genExprKeepIndentInBranch astContext) e isShortExpression ctx.Config.MaxValueBindingWidth short long ctx) @@ -5467,11 +5524,19 @@ and genKeepIndentMatch withRange ) +> sepNln - +> coli sepNln clauses (fun idx -> - if idx < lastClauseIndex then - genClause astContext true - else - genLastClauseKeepIdent astContext) + +> (fun ctx -> + let hasMultipleClausesWhereOneHasRagnarok = + hasMultipleClausesWhereOneHasRagnarok ctx.Config.Ragnarok clauses + + coli + sepNln + clauses + (fun idx -> + if idx < lastClauseIndex then + genClause astContext true hasMultipleClausesWhereOneHasRagnarok + else + genLastClauseKeepIdent astContext) + ctx) |> genTriviaFor triviaType range and genLastClauseKeepIdent (astContext: ASTContext) (Clause (pat, whenExpr, arrowRange, expr)) = @@ -5716,7 +5781,11 @@ and genTriviaForOption (mainNodeName: FsAstType) (range: range option) f ctx = | None -> ctx | Some range -> genTriviaFor mainNodeName range f ctx -and genLambdaArrowWithTrivia (bodyExpr: Context -> Context) (arrowRange: Range option) = +and genLambdaArrowWithTrivia + (bodyExpr: SynExpr -> Context -> Context) + (body: SynExpr) + (arrowRange: Range option) + : Context -> Context = optSingle (fun arrowRange -> sepArrow @@ -5724,9 +5793,9 @@ and genLambdaArrowWithTrivia (bodyExpr: Context -> Context) (arrowRange: Range o arrowRange +> (fun ctx -> if String.isNotNullOrEmpty ctx.WriterModel.WriteBeforeNewline then - (indent +> sepNln +> bodyExpr +> unindent) ctx + (indent +> sepNln +> (bodyExpr body) +> unindent) ctx else - (autoIndentAndNlnIfExpressionExceedsPageWidth bodyExpr) ctx) + autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok bodyExpr body ctx) and infixOperatorFromTrivia range fallback (ctx: Context) = // by specs, section 3.4 https://fsharp.org/specs/language-spec/4.1/FSharpSpec-4.1-latest.pdf#page=24&zoom=auto,-137,312 diff --git a/src/Fantomas/Context.fs b/src/Fantomas/Context.fs index e1dabfd81e..d57baccd64 100644 --- a/src/Fantomas/Context.fs +++ b/src/Fantomas/Context.fs @@ -1,13 +1,13 @@ -module Fantomas.Context +module Fantomas.Core.Context open System open FSharp.Compiler.Text open FSharp.Compiler.Text.Range open FSharp.Compiler.Text.Position open FSharp.Compiler.Syntax -open Fantomas -open Fantomas.FormatConfig -open Fantomas.TriviaTypes +open Fantomas.Core +open Fantomas.Core.FormatConfig +open Fantomas.Core.TriviaTypes type WriterEvent = | Write of string @@ -644,6 +644,10 @@ let internal getRecordSize ctx fields = let internal ifElse b (f1: Context -> Context) f2 (ctx: Context) = if b then f1 ctx else f2 ctx let internal ifElseCtx cond (f1: Context -> Context) f2 (ctx: Context) = if cond ctx then f1 ctx else f2 ctx +let internal ifRagnarokElse = ifElseCtx (fun ctx -> ctx.Config.Ragnarok) + +let internal ifRagnarok (f1: Context -> Context) = + ifElseCtx (fun ctx -> ctx.Config.Ragnarok) f1 id /// apply f only when cond is true let internal onlyIf cond f ctx = if cond then f ctx else ctx @@ -693,6 +697,12 @@ let internal sepNlnUnlessLastEventIsNewline (ctx: Context) = else sepNln ctx +let internal sepNlnUnlessLastEventIsNewlineOrRagnarok (ctx: Context) = + if lastWriteEventIsNewline ctx || ctx.Config.Ragnarok then + ctx + else + sepNln ctx + let internal sepStar = !- " * " let internal sepStarFixed = !- "* " let internal sepEq = !- " =" @@ -1324,6 +1334,20 @@ let internal addExtraNewlineIfLeadingWasMultiline leading sepNlnConsideringTrivi +> onlyIf ml sepNlnConsideringTriviaContentBefore +> continuation) +let internal autoIndentAndNlnExpressUnlessRagnarok (f: SynExpr -> Context -> Context) (e: SynExpr) (ctx: Context) = + match e with + | SourceParser.RagnarokExpr e when ctx.Config.Ragnarok -> f e ctx + | _ -> (indent +> sepNln +> f e +> unindent) ctx + +let internal autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok + (f: SynExpr -> Context -> Context) + (e: SynExpr) + (ctx: Context) + = + match e with + | SourceParser.RagnarokExpr e when ctx.Config.Ragnarok -> f e ctx + | _ -> autoIndentAndNlnIfExpressionExceedsPageWidth (f e) ctx + type internal ColMultilineItem = | ColMultilineItem of // current expression diff --git a/src/Fantomas/Fantomas.fsproj b/src/Fantomas/Fantomas.Core.fsproj similarity index 100% rename from src/Fantomas/Fantomas.fsproj rename to src/Fantomas/Fantomas.Core.fsproj diff --git a/src/Fantomas/FormatConfig.fs b/src/Fantomas/FormatConfig.fs index b34d600534..4af8ae3652 100644 --- a/src/Fantomas/FormatConfig.fs +++ b/src/Fantomas/FormatConfig.fs @@ -1,4 +1,4 @@ -module Fantomas.FormatConfig +module Fantomas.Core.FormatConfig open System open System.ComponentModel @@ -218,6 +218,10 @@ type FormatConfig = [] BarBeforeDiscriminatedUnionDeclaration: bool + [] + [] + Ragnarok: bool + [] [] [] @@ -263,4 +267,5 @@ type FormatConfig = KeepIndentInBranch = false BlankLinesAroundNestedMultilineExpressions = true BarBeforeDiscriminatedUnionDeclaration = false + Ragnarok = false StrictMode = false } diff --git a/src/Fantomas/Queue.fs b/src/Fantomas/Queue.fs index 3e9696795a..08ef36dd7b 100644 --- a/src/Fantomas/Queue.fs +++ b/src/Fantomas/Queue.fs @@ -1,4 +1,4 @@ -namespace Fantomas +namespace Fantomas.Core /// append only collection optimized for quick append of block of data and query operations /// data - list of blocks in reverse order diff --git a/src/Fantomas/RangeHelpers.fs b/src/Fantomas/RangeHelpers.fs index fde7c783fe..944d3f03a0 100644 --- a/src/Fantomas/RangeHelpers.fs +++ b/src/Fantomas/RangeHelpers.fs @@ -1,4 +1,4 @@ -namespace Fantomas +namespace Fantomas.Core open FSharp.Compiler.Text diff --git a/src/Fantomas/SourceOrigin.fs b/src/Fantomas/SourceOrigin.fs index 68bf420d23..972ef9cd97 100644 --- a/src/Fantomas/SourceOrigin.fs +++ b/src/Fantomas/SourceOrigin.fs @@ -1,4 +1,4 @@ -module Fantomas.SourceOrigin +module Fantomas.Core.SourceOrigin open FSharp.Compiler.Text diff --git a/src/Fantomas/SourceParser.fs b/src/Fantomas/SourceParser.fs index d0e0e1488d..b807462264 100644 --- a/src/Fantomas/SourceParser.fs +++ b/src/Fantomas/SourceParser.fs @@ -1,13 +1,13 @@ -module internal Fantomas.SourceParser +module internal Fantomas.Core.SourceParser open System open FSharp.Compiler.Syntax open FSharp.Compiler.Syntax.PrettyNaming open FSharp.Compiler.Text open FSharp.Compiler.Xml -open Fantomas -open Fantomas.TriviaTypes -open Fantomas.RangePatterns +open Fantomas.Core +open Fantomas.Core.TriviaTypes +open Fantomas.Core.RangePatterns /// Don't put space before and after these operators let internal noSpaceInfixOps = set [ "?" ] @@ -1848,3 +1848,24 @@ let (|KeepIndentIfThenElse|_|) (e: SynExpr) = else None | _ -> None + +let (|RagnarokExpr|_|) (e: SynExpr) = + match e with + // { foo with Bar = bar } + | SynExpr.Record(copyInfo = Some _) -> None + | SynExpr.Record _ + | SynExpr.AnonRecd _ + // task { ... } + | SynExpr.App (ExprAtomicFlag.NonAtomic, false, SynExpr.Ident _, SynExpr.ComputationExpr _, _) + | ArrayOrList _ -> Some e + | _ -> None + +let hasMultipleClausesWhereOneHasRagnarok (ragnarokEnabled) (cs: SynMatchClause list) : bool = + ragnarokEnabled + && List.moreThanOne cs + && List.exists + (fun (SynMatchClause (resultExpr = e)) -> + match e with + | RagnarokExpr _ -> true + | _ -> false) + cs diff --git a/src/Fantomas/SourceTransformer.fs b/src/Fantomas/SourceTransformer.fs index f42c38d0f0..9b5b077685 100644 --- a/src/Fantomas/SourceTransformer.fs +++ b/src/Fantomas/SourceTransformer.fs @@ -1,10 +1,10 @@ -module internal Fantomas.SourceTransformer +module internal Fantomas.Core.SourceTransformer open FSharp.Compiler.Syntax open FSharp.Compiler.Text -open Fantomas.Context -open Fantomas.SourceParser -open Fantomas.TriviaTypes +open Fantomas.Core.Context +open Fantomas.Core.SourceParser +open Fantomas.Core.TriviaTypes [] module List = diff --git a/src/Fantomas/TokenParser.fs b/src/Fantomas/TokenParser.fs index da1dad8614..fac745de9b 100644 --- a/src/Fantomas/TokenParser.fs +++ b/src/Fantomas/TokenParser.fs @@ -1,12 +1,12 @@ -module internal Fantomas.TokenParser +module internal Fantomas.Core.TokenParser open System open System.Text open FSharp.Compiler.Syntax open FSharp.Compiler.Tokenization -open Fantomas -open Fantomas.TokenParserBoolExpr -open Fantomas.TriviaTypes +open Fantomas.Core +open Fantomas.Core.TokenParserBoolExpr +open Fantomas.Core.TriviaTypes let private whiteSpaceTag = 4 let private lineCommentTag = 8 diff --git a/src/Fantomas/TokenParserBoolExpr.fs b/src/Fantomas/TokenParserBoolExpr.fs index 52611bb4df..07c4b4bc7e 100644 --- a/src/Fantomas/TokenParserBoolExpr.fs +++ b/src/Fantomas/TokenParserBoolExpr.fs @@ -1,4 +1,4 @@ -module Fantomas.TokenParserBoolExpr +module Fantomas.Core.TokenParserBoolExpr #nowarn "40" diff --git a/src/Fantomas/Trivia.fs b/src/Fantomas/Trivia.fs index 6f5c82070c..f7e63cc60b 100644 --- a/src/Fantomas/Trivia.fs +++ b/src/Fantomas/Trivia.fs @@ -1,12 +1,12 @@ -module internal Fantomas.Trivia +module internal Fantomas.Core.Trivia open FSharp.Compiler.Text open FSharp.Compiler.Syntax open FSharp.Compiler.Tokenization -open Fantomas -open Fantomas.SourceParser -open Fantomas.AstTransformer -open Fantomas.TriviaTypes +open Fantomas.Core +open Fantomas.Core.SourceParser +open Fantomas.Core.AstTransformer +open Fantomas.Core.TriviaTypes let inline isMainNodeFor nodeType (node: TriviaNodeAssigner) = nodeType = node.Type diff --git a/src/Fantomas/TriviaContext.fs b/src/Fantomas/TriviaContext.fs index e700f19b2f..f5f16af320 100644 --- a/src/Fantomas/TriviaContext.fs +++ b/src/Fantomas/TriviaContext.fs @@ -1,8 +1,8 @@ -module internal Fantomas.TriviaContext +module internal Fantomas.Core.TriviaContext -open Fantomas -open Fantomas.Context -open Fantomas.TriviaTypes +open Fantomas.Core +open Fantomas.Core.Context +open Fantomas.Core.TriviaTypes let getIndentBetweenTicksFromSynPat patRange fallback ctx = TriviaHelpers.getNodesForTypes [ SynPat_LongIdent; SynPat_Named ] ctx.TriviaMainNodes diff --git a/src/Fantomas/TriviaHelpers.fs b/src/Fantomas/TriviaHelpers.fs index 7baadfd296..3c08c68586 100644 --- a/src/Fantomas/TriviaHelpers.fs +++ b/src/Fantomas/TriviaHelpers.fs @@ -1,7 +1,7 @@ -namespace Fantomas +namespace Fantomas.Core open FSharp.Compiler.Text -open Fantomas.TriviaTypes +open Fantomas.Core.TriviaTypes [] module internal TriviaHelpers = diff --git a/src/Fantomas/TriviaTypes.fs b/src/Fantomas/TriviaTypes.fs index 14c99510ec..fd0a866d40 100644 --- a/src/Fantomas/TriviaTypes.fs +++ b/src/Fantomas/TriviaTypes.fs @@ -1,4 +1,4 @@ -module Fantomas.TriviaTypes +module Fantomas.Core.TriviaTypes open FSharp.Compiler.Text open FSharp.Compiler.Tokenization diff --git a/src/Fantomas/Utils.fs b/src/Fantomas/Utils.fs index c8402ad411..65de659722 100644 --- a/src/Fantomas/Utils.fs +++ b/src/Fantomas/Utils.fs @@ -1,4 +1,4 @@ -namespace Fantomas +namespace Fantomas.Core open System open System.Text.RegularExpressions diff --git a/src/Fantomas/Version.fs b/src/Fantomas/Version.fs index f7edb695c2..e618ed0a51 100644 --- a/src/Fantomas/Version.fs +++ b/src/Fantomas/Version.fs @@ -1,4 +1,4 @@ -module internal Fantomas.Version +module internal Fantomas.Core.Version open System.Reflection