diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index a843352c4b..a192a52a65 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -9,13 +9,13 @@
]
},
"fantomas": {
- "version": "5.2.0",
+ "version": "5.2.1",
"commands": [
"fantomas"
]
},
"fsdocs-tool": {
- "version": "17.0.0",
+ "version": "17.2.2",
"commands": [
"fsdocs"
]
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 992d0d28a3..cfa632ae86 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -8,7 +8,7 @@ env:
jobs:
build:
-
+ continue-on-error: true
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 659f5d86b6..6b78b2047e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,62 @@
# Changelog
+## [6.0.0-alpha-007] - 2023-03-27
+
+### Changed
+
+* `CodeFormatter.FormatASTAsync` returns a string. [#2799](https://github.com/fsprojects/fantomas/pull/2799)
+* Cursor with defines. [#2774](https://github.com/fsprojects/fantomas/pull/2774)
+
+### Removed
+
+* Strict mode. [#2798](https://github.com/fsprojects/fantomas/pull/2798)
+
+## [6.0.0-alpha-006] - 2023-03-17
+
+### Fixed
+* Record member declarations can break with Stroustrup enabled. [#2787](https://github.com/fsprojects/fantomas/issues/2787)
+
+### Changed
+* Add `fsharp_experimental_elmish` setting. [#2795](https://github.com/fsprojects/fantomas/pull/2795)
+
+## [6.0.0-alpha-005] - 2023-02-24
+
+### Changed
+* Fix handling of AppExpr with a single stroustrup record. [#2747](https://github.com/fsprojects/fantomas/pull/2747)
+* Inconsistent styling when using Stroustrup with or without member attach to record creation. [#2652](https://github.com/fsprojects/fantomas/issues/2652)
+
+## [6.0.0-alpha-004] - 2023-02-22
+
+### Changed
+* Always process folder recursive. [#2768](https://github.com/fsprojects/fantomas/issues/2768)
+* Revisit --profile flag. [#2751](https://github.com/fsprojects/fantomas/issues/2751)
+
+### Fixed
+* Don't hook up SerilogTraceListener in FantomasDaemon. [#2777](https://github.com/fsprojects/fantomas/pull/2777)
+
+## [6.0.0-alpha-003] - 2023-02-04
+
+### Changed
+* Splitting ExperimentalStroustrupStyle to separate settings. [#2276](https://github.com/fsprojects/fantomas/issues/2276)
+* Remove F# option from public API. [#2759](https://github.com/fsprojects/fantomas/pull/2759)
+* Naive parallel formatting implementation. [#2717](https://github.com/fsprojects/fantomas/pull/2717)
+* Add separate CodeFormatter.FormatDocumentAsync overloads with cursor and config. [#2763](https://github.com/fsprojects/fantomas/pull/2763)
+
+## [6.0.0-alpha-002] - 2023-02-01
+
+### Changed
+* Update output for copy-and-update expression for Stroustrup. [#2748](https://github.com/fsprojects/fantomas/pull/2748)
+* Drop Experimental prefix from ExperimentalStroustrup. [#2755](https://github.com/fsprojects/fantomas/pull/2755)
+* Expose initial Oak API. [#2758](https://github.com/fsprojects/fantomas/pull/2758)
+
+## [6.0.0-alpha-001] - 2023-01-24
+
+### Changed
+* Add `--verbosity` flag. [#2693](https://github.com/fsprojects/fantomas/pull/2693)
+* Sunset MultilineBlockBracketsOnSameColumn & ExperimentalStroustrupStyle. [#2710](https://github.com/fsprojects/fantomas/issues/2710)
+* Move FormatConfig into Fantomas.Core namespace. [#2736](https://github.com/fsprojects/fantomas/pull/2736)
+* Initial cursor API. [#2739](https://github.com/fsprojects/fantomas/pull/2739)
+
## [5.2.4] - 2023-03-17
### Fixed
diff --git a/build.fsx b/build.fsx
index 31113411f9..4726a68d60 100644
--- a/build.fsx
+++ b/build.fsx
@@ -1,4 +1,4 @@
-#r "nuget: Fun.Build, 0.1.8"
+#r "nuget: Fun.Build, 0.3.1"
#r "nuget: CliWrap, 3.5.0"
#r "nuget: FSharp.Data, 5.0.2"
@@ -57,14 +57,14 @@ pipeline "Build" {
run (
cleanFolders
[| "bin"
- "src/Fantomas.FCS/bin"
- "src/Fantomas.FCS/obj"
- "src/Fantomas.Core/bin"
- "src/Fantomas.Core/obj"
- "src/Fantomas/bin"
- "src/Fantomas/obj"
- "src/Fantomas.Client/bin"
- "src/Fantomas.Client/obj" |]
+ "src/Fantomas.FCS/bin/Release"
+ "src/Fantomas.FCS/obj/Release"
+ "src/Fantomas.Core/bin/Release"
+ "src/Fantomas.Core/obj/Release"
+ "src/Fantomas/bin/Release"
+ "src/Fantomas/obj/Release"
+ "src/Fantomas.Client/bin/Release"
+ "src/Fantomas.Client/obj/Release" |]
)
}
stage "CheckFormat" { run "dotnet fantomas src docs build.fsx --recurse --check" }
diff --git a/docs/content/webcomponents.js b/docs/content/webcomponents.js
index b6dd7774c5..21f18b9c93 100644
--- a/docs/content/webcomponents.js
+++ b/docs/content/webcomponents.js
@@ -1,7 +1,7 @@
import {html} from 'https://cdn.skypack.dev/lit';
import {component} from 'https://cdn.skypack.dev/haunted';
-function FantomasSettingIcon({type}) {
+function FantomasSettingIconCore(type) {
let settingType
switch (type) {
case 'green':
@@ -20,9 +20,7 @@ function FantomasSettingIcon({type}) {
break;
case 'red':
settingType = {
- icon: "bi-x-circle-fill",
- color: "red-recommendation",
- tooltip: "You shouldn't use this setting."
+ icon: "bi-x-circle-fill", color: "red-recommendation", tooltip: "You shouldn't use this setting."
}
break;
case 'gr':
@@ -35,7 +33,7 @@ function FantomasSettingIcon({type}) {
data-bs-title="${tooltip}"
src="${root}/images/gresearch.svg" alt="G-Research logo"/>`;
default:
- throw `The "type" can only be "green", "orange", "red" or "gr". Found "${type}"`;
+ throw "The \"type\" can only be \"green\", \"orange\", \"red\" or \"gr\"";
}
return html`
- ${green && FantomasSettingIcon({type: "green"})}
- ${orange && FantomasSettingIcon({type: "orange"})}
- ${red && FantomasSettingIcon({type: "red"})}
- ${gr && FantomasSettingIcon({type: "gr"})}
+ ${green && FantomasSettingIconCore('green')}
+ ${orange && FantomasSettingIconCore('orange')}
+ ${red && FantomasSettingIconCore('red')}
+ ${gr && FantomasSettingIconCore('gr')}
`
}
+function FantomasSettingIcon({green, orange, red, gr}) {
+ return html`
+ ${green && FantomasSettingIconCore('green')}
+ ${orange && FantomasSettingIconCore('orange')}
+ ${red && FantomasSettingIconCore('red')}
+ ${gr && FantomasSettingIconCore('gr')}
+ `
+}
+
customElements.define('fantomas-setting-icon', component(FantomasSettingIcon, {
- useShadowDOM: false, observedAttributes: ['type']
+ useShadowDOM: false, observedAttributes: ['green', 'orange', 'red', 'gr']
}));
+
customElements.define('fantomas-setting', component(FantomasSetting, {
useShadowDOM: false, observedAttributes: ['name', 'green', 'orange', 'red', 'gr']
}));
diff --git a/docs/docs/contributors/Solution Structure.md b/docs/docs/contributors/Solution Structure.md
index 5ffee7da8f..eec2ccd51d 100644
--- a/docs/docs/contributors/Solution Structure.md
+++ b/docs/docs/contributors/Solution Structure.md
@@ -15,7 +15,7 @@ graph TD
B --> D[Fantomas.Benchmarks]
B --> E[Fantomas.Core.Tests]
C --> F[Fantomas.Tests]
- G[Fantomas.Client]
+ G[Fantomas.Client] --> H[Fantomas.Client.Tests]
## Fantomas.FCS
@@ -57,4 +57,8 @@ A suite of unit tests that target the core formatting functionalities of `Fantom
A suite of end-to-end tests that run the actual `fantomas` command line application.
+## Fantomas.Client.Tests
+
+A suite of end-to-end tests that will verify the `Fantomas.Client` code against released versions of `fantomas`.
+
diff --git a/docs/docs/end-users/Configuration.fsx b/docs/docs/end-users/Configuration.fsx
index a4af68e244..7b90fe74fc 100644
--- a/docs/docs/end-users/Configuration.fsx
+++ b/docs/docs/end-users/Configuration.fsx
@@ -15,6 +15,12 @@ Your IDE should respect your settings, however the implementation of that is edi
UI might be available depending on the IDE.
*)
+#r "../../../src/Fantomas/bin/Release/net6.0/Fantomas.FCS.dll"
+#r "../../../src/Fantomas/bin/Release/net6.0/Fantomas.Core.dll"
+
+printf $"version: {Fantomas.Core.CodeFormatter.GetVersion()}"
+(*** include-output ***)
+
(**
## Usage
Inside .editorconfig you can specify the file extension and code location to be use per config:
@@ -28,7 +34,7 @@ fsharp_bar_before_discriminated_union_declaration = true
#\ Apply specific settings for a targeted subfolder
[src/Elmish/View.fs]
-fsharp_multiline_bracket_style = experimental_stroustrup
+fsharp_multiline_bracket_style = stroustrup
```
*)
@@ -39,23 +45,23 @@ You can quickly try your settings via the
*)
-#r "nuget: Fantomas.Core, 5.*"
-
-open Fantomas.Core.FormatConfig
open Fantomas.Core
let formatCode input configIndent =
- CodeFormatter.FormatDocumentAsync(false, input, configIndent)
+ async {
+ let! result = CodeFormatter.FormatDocumentAsync(false, input, configIndent)
+ printf $"%s{result.Code}"
+ }
|> Async.RunSynchronously
(**
## Settings recommendations
Fantomas ships with a series of settings that you can use freely depending on your case.
However, there are settings that we do not recommend and generally should not be used.
-
Safe to change: Settings that aren't attached to any guidelines. Depending on your team or your own preferences, feel free to change these as it's been agreed on the codebase, however, you can always use it's defaults.
-Use with caution: Settings where it is not recommended to change the default value. They might lead to incomplete results.
-Do not use: Settings that don't follow any guidelines.
-G-Research: G-Research styling guide. If you use one of these, for consistency reasons you should use all of them.
+Safe to change: Settings that aren't attached to any guidelines. Depending on your team or your own preferences, feel free to change these as it's been agreed on the codebase, however, you can always use it's defaults.
+Use with caution: Settings where it is not recommended to change the default value. They might lead to incomplete results.
+Do not use: Settings that don't follow any guidelines.
+G-Research: G-Research styling guide. If you use one of these, for consistency reasons you should use all of them.
*)
(**
@@ -87,7 +93,7 @@ formatCode
"""
{ FormatConfig.Default with
IndentSize = 2 }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -105,7 +111,7 @@ formatCode
"""
{ FormatConfig.Default with
MaxLineLength = 60 }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -130,7 +136,7 @@ formatCode
"""
{ FormatConfig.Default with
InsertFinalNewline = false }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -148,7 +154,7 @@ formatCode
"""
{ FormatConfig.Default with
SpaceBeforeParameter = false }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -169,7 +175,7 @@ match x with
"""
{ FormatConfig.Default with
SpaceBeforeLowercaseInvocation = false }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -190,7 +196,7 @@ match x with
"""
{ FormatConfig.Default with
SpaceBeforeUppercaseInvocation = true }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -209,7 +215,7 @@ formatCode
{ FormatConfig.Default with
SpaceBeforeClassConstructor = true }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -229,7 +235,7 @@ formatCode
"""
{ FormatConfig.Default with
SpaceBeforeMember = true }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -247,7 +253,7 @@ formatCode
"""
{ FormatConfig.Default with
SpaceBeforeColon = true }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -264,7 +270,7 @@ formatCode
"""
{ FormatConfig.Default with
SpaceAfterComma = false }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -282,7 +288,7 @@ formatCode
"""
{ FormatConfig.Default with
SpaceBeforeSemicolon = true }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -300,7 +306,7 @@ formatCode
"""
{ FormatConfig.Default with
SpaceAfterSemicolon = false }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -317,7 +323,7 @@ formatCode
"""
{ FormatConfig.Default with
SpaceAroundDelimiter = false }
-(*** include-it ***)
+(*** include-output ***)
(**
## Maximum width constraints
@@ -341,7 +347,7 @@ formatCode
"""
{ FormatConfig.Default with
MaxIfThenShortWidth = 15 }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -358,7 +364,7 @@ formatCode
"""
{ FormatConfig.Default with
MaxIfThenElseShortWidth = 10 }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -374,7 +380,7 @@ formatCode
"""
{ FormatConfig.Default with
MaxInfixOperatorExpression = 20 }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -393,7 +399,7 @@ formatCode
"""
{ FormatConfig.Default with
MaxRecordWidth = 20 }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -425,7 +431,7 @@ formatCode
{ FormatConfig.Default with
MaxRecordNumberOfItems = 2
RecordMultilineFormatter = MultilineFormatterType.NumberOfItems }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -453,7 +459,7 @@ formatCode
"""
{ FormatConfig.Default with
RecordMultilineFormatter = MultilineFormatterType.NumberOfItems }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -471,7 +477,7 @@ formatCode
"""
{ FormatConfig.Default with
MaxArrayOrListWidth = 20 }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -491,7 +497,7 @@ formatCode
{ FormatConfig.Default with
MaxArrayOrListNumberOfItems = 2
ArrayOrListMultilineFormatter = MultilineFormatterType.NumberOfItems }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -511,7 +517,7 @@ formatCode
"""
{ FormatConfig.Default with
ArrayOrListMultilineFormatter = MultilineFormatterType.NumberOfItems }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -530,7 +536,7 @@ formatCode
"""
{ FormatConfig.Default with
MaxValueBindingWidth = 10 }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -549,7 +555,7 @@ formatCode
"""
{ FormatConfig.Default with
MaxFunctionBindingWidth = 10 }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -569,63 +575,91 @@ formatCode
"""
{ FormatConfig.Default with
MaxDotGetExpressionWidth = 100 }
-(*** include-it ***)
+(*** include-output ***)
(**
-
-
-How to format bracketted expressions (e.g. records, arrays, lists, etc.) that span multiple lines.
+
-_This setting replaces the deprecated settings `fsharp_multiline_block_brackets_on_same_column` and `fsharp_experimental_stroustrup_style`._
+`Cramped` The default way in F# to format brackets.
+`Aligned` Alternative way of formatting records, arrays and lists. This will align the braces at the same column level.
+`Stroustrup` Allow for easier reordering of members and keeping the code succinct.
-Possible values:
-
-* `cramped`
-* `aligned`
-* `experimental_stroustrup`
-
-Default = `cramped`.
+Default = Cramped.
*)
-(**
-**Cramped** - The default way in F# to format brackets.
-*)
formatCode
"""
- let band = { Vocals = "John"; Bass = "Paul"; Guitar = "George"; Drums = "Ringo" }
- let songs = [ "Come Together"; "Hey Jude"; "Yesterday"; "Yellow Submarine"; "Here Comes the Sun" ]
+ let myRecord =
+ { Level = 1
+ Progress = "foo"
+ Bar = "bar"
+ Street = "Bakerstreet"
+ Number = 42 }
+
+ type Range =
+ { From: float
+ To: float
+ FileName: string }
+
+ let a =
+ [| (1, 2, 3)
+ (4, 5, 6)
+ (7, 8, 9)
+ (10, 11, 12)
+ (13, 14, 15)
+ (16, 17,18)
+ (19, 20, 21) |]
"""
{ FormatConfig.Default with
- MultilineBracketStyle = Cramped }
-(*** include-it ***)
-
-(**
-**Aligned** - Alternative way of formatting brackets. This will align the braces at the same column level.
-*)
+ MultilineBracketStyle = Aligned }
+(*** include-output ***)
formatCode
"""
- let band = { Vocals = "John"; Bass = "Paul"; Guitar = "George"; Drums = "Ringo" }
- let songs = [ "Come Together"; "Hey Jude"; "Yesterday"; "Yellow Submarine"; "Here Comes the Sun" ]
+ let myRecord =
+ { Level = 1
+ Progress = "foo"
+ Bar = "bar"
+ Street = "Bakerstreet"
+ Number = 42 }
+
+ type Range =
+ { From: float
+ To: float
+ FileName: string }
+
+ let a =
+ [| (1, 2, 3)
+ (4, 5, 6)
+ (7, 8, 9)
+ (10, 11, 12)
+ (13, 14, 15)
+ (16, 17,18)
+ (19, 20, 21) |]
"""
{ FormatConfig.Default with
- MultilineBracketStyle = Aligned }
-(*** include-it ***)
+ MultilineBracketStyle = Stroustrup }
+(*** include-output ***)
(**
-**ExperimentalStroustrup** - Experimental setting. Places the opening brace on the same line as the binding, and the closing brace on its own line.
+
+
+Insert a newline before a computation expression that spans multiple lines
-_Please contribute to [fsprojects/fantomas#1408](https://github.com/fsprojects/fantomas/issues/1408) and engage in [fsharp/fslang-design#706](https://github.com/fsharp/fslang-design/issues/706)._
+Default = true
*)
formatCode
"""
- let band = { Vocals = "John"; Bass = "Paul"; Guitar = "George"; Drums = "Ringo" }
- let songs = [ "Come Together"; "Hey Jude"; "Yesterday"; "Yellow Submarine"; "Here Comes the Sun" ]
+ let something =
+ task {
+ let! thing = otherThing ()
+ return 5
+ }
"""
{ FormatConfig.Default with
- MultilineBracketStyle = ExperimentalStroustrup }
-(*** include-it ***)
+ NewlineBeforeMultilineComputationExpression = false }
+(*** include-output ***)
(**
## G-Research style
@@ -649,7 +683,7 @@ type Range =
"""
{ FormatConfig.Default with
NewlineBetweenTypeDefinitionAndMembers = true }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -671,7 +705,7 @@ let run
"""
{ FormatConfig.Default with
AlignFunctionSignatureToIndentation = true }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -704,7 +738,7 @@ type D() =
"""
{ FormatConfig.Default with
AlternativeLongMemberDefinitions = true }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -732,7 +766,7 @@ let printListWithOffset a list1 =
"""
{ FormatConfig.Default with
MultiLineLambdaClosingNewline = true }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -762,7 +796,7 @@ let main argv =
"""
{ FormatConfig.Default with
ExperimentalKeepIndentInBranch = true }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -780,7 +814,7 @@ formatCode
{ FormatConfig.Default with
BarBeforeDiscriminatedUnionDeclaration = true }
-(*** include-it ***)
+(*** include-output ***)
(**
## Other
@@ -814,7 +848,7 @@ formatCode
"""
{ FormatConfig.Default with
BlankLinesAroundNestedMultilineExpressions = false }
-(*** include-it ***)
+(*** include-output ***)
(**
@@ -832,34 +866,48 @@ formatCode
"""
{ FormatConfig.Default with
KeepMaxNumberOfBlankLines = 1 }
-(*** include-it ***)
+(*** include-output ***)
(**
-
+
-If being set, pretty printing is only done via ASTs. Compiler directives, inline comments and block comments will be ignored.
-There are numerous situations when the information in the AST alone cannot restore the original code.
+Applies the Stroustrup style to the final (two) array or list argument(s) in a function application.
+Note that this behaviour is also active when `fsharp_multiline_bracket_style = stroustrup`.
-**Please do not use this setting for formatting hand written code!**
-
-Valid use-case of this settings is code generation in projects like [FsAst](https://github.com/ionide/FsAst) and [Myriad](https://github.com/MoiraeSoftware/myriad).
-
-Default = false.
+Default = false
*)
formatCode
"""
- // some great comment
- let add a b =
- #if INTERACTIVE
- 42
- #else
- a + b
- #endif
+let dualList =
+ div
+ []
+ [
+ h1 [] [ str "Some title" ]
+ ul
+ []
+ [
+ for p in model.Points do
+ li [] [ str $"%i{p.X}, %i{p.Y}" ]
+ ]
+ hr []
+ ]
+
+let singleList =
+ Html.div
+ [
+ Html.h1 [ str "Some title" ]
+ Html.ul
+ [
+ for p in model.Points do
+ Html.li [ str $"%i{p.X}, %i{p.Y}" ]
+ ]
+ ]
"""
{ FormatConfig.Default with
- StrictMode = true }
-(*** include-it ***)
+ ExperimentalElmish = true }
+(*** include-output ***)
+
(**
diff --git a/docs/docs/end-users/FAQ.md b/docs/docs/end-users/FAQ.md
index 782c02f4ee..a6dae9c506 100644
--- a/docs/docs/end-users/FAQ.md
+++ b/docs/docs/end-users/FAQ.md
@@ -44,4 +44,4 @@ without the compiler nagging you about the missing space between the callee (`Pr
Since F# 6.0, Fantomas interprets the list as an index expression and formats it accordingly.
In such a case, just add a space between the callee and the list and you should be good to go.
-
+
diff --git a/docs/docs/end-users/GeneratingCode.fsx b/docs/docs/end-users/GeneratingCode.fsx
index 1bd7e4a92e..4cec53a859 100644
--- a/docs/docs/end-users/GeneratingCode.fsx
+++ b/docs/docs/end-users/GeneratingCode.fsx
@@ -32,83 +32,63 @@ In simple scenarios this can work out, but in the long run it doesn't scale well
To illustrate the API, lets generate a simple value binding: `let a = 0`.
*)
-#r "nuget: Fantomas.Core, 5.*" // Note that this will also load Fantomas.FCS, which contains the syntax tree types.
+#r "../../../src/Fantomas/bin/Release/net6.0/Fantomas.FCS.dll"
+#r "../../../src/Fantomas/bin/Release/net6.0/Fantomas.Core.dll" // In production use #r "nuget: Fantomas.Core, 6.0-alpha-*"
open FSharp.Compiler.Text
-open FSharp.Compiler.Xml
-open FSharp.Compiler.Syntax
-open FSharp.Compiler.SyntaxTrivia
+open Fantomas.Core.SyntaxOak
let implementationSyntaxTree =
- ParsedInput.ImplFile(
- ParsedImplFileInput(
- "filename.fsx",
- true,
- QualifiedNameOfFile(Ident("", Range.Zero)),
- [],
- [],
- [ SynModuleOrNamespace(
- [],
- false,
- SynModuleOrNamespaceKind.AnonModule,
- [ SynModuleDecl.Let(
- false,
- [ SynBinding(
- None,
- SynBindingKind.Normal,
- false,
- false,
- [],
- PreXmlDoc.Empty,
- SynValData(None, SynValInfo([], SynArgInfo([], false, None)), None),
- SynPat.Named(SynIdent(Ident("a", Range.Zero), None), false, None, Range.Zero),
- None,
- SynExpr.Const(SynConst.Int32(0), Range.Zero),
- Range.Zero,
- DebugPointAtBinding.Yes Range.Zero,
- { EqualsRange = Some Range.Zero
- InlineKeyword = None
- LeadingKeyword = SynLeadingKeyword.Let Range.Zero }
- ) ],
- Range.Zero
- ) ],
- PreXmlDoc.Empty,
- [],
- None,
- Range.Zero,
- { LeadingKeyword = SynModuleOrNamespaceLeadingKeyword.None }
- ) ],
- (false, false),
- { ConditionalDirectives = []
- CodeComments = [] },
- Set.empty
- )
+ Oak(
+ [],
+ [ ModuleOrNamespaceNode(
+ None,
+ [ BindingNode(
+ None,
+ None,
+ MultipleTextsNode([ SingleTextNode("let", Range.Zero) ], Range.Zero),
+ false,
+ None,
+ None,
+ Choice1Of2(IdentListNode([ IdentifierOrDot.Ident(SingleTextNode("a", Range.Zero)) ], Range.Zero)),
+ None,
+ [],
+ None,
+ SingleTextNode("=", Range.Zero),
+ Expr.Constant(Constant.FromText(SingleTextNode("0", Range.Zero))),
+ Range.Zero
+ )
+ |> ModuleDecl.TopLevelBinding ],
+ Range.Zero
+ ) ],
+ Range.Zero
)
open Fantomas.Core
-CodeFormatter.FormatASTAsync(implementationSyntaxTree) |> Async.RunSynchronously
-(*** include-it ***)
+CodeFormatter.FormatOakAsync(implementationSyntaxTree)
+|> Async.RunSynchronously
+|> printfn "%s"
+(*** include-output ***)
(**
Constructing the entire syntax tree can be a bit overwhelming at first. There is a lot of information to provide and a lot to unpack if you have never seen any of this before.
Let's deconstruct a couple of things:
-- Every file has one or more [SynModuleOrNamespace](../../reference/fsharp-compiler-syntax-synmoduleornamespace.html). In this case the module was anonymous and thus invisible.
-- Every `SynModuleOrNamespace` has top level [SynModuleDecl](../../https://fsprojects.github.io/fantomas/reference/fsharp-compiler-syntax-synmoduledecl.html).
-- [SynModuleDecl.Let](../../https://fsprojects.github.io/fantomas/reference/fsharp-compiler-syntax-synmoduledecl.html#Let) takes one or more [SynBinding](../../reference/fsharp-compiler-syntax-synbinding.html).
+- Every file has one or more [ModuleOrNamespaceNode](../../reference/fantomas-core-syntaxoak-moduleornamespacenode.html). In this case the module was anonymous and thus invisible.
+- Every `ModuleOrNamespaceNode` has top level [ModuleDecl](../../reference/fantomas-core-syntaxoak-moduledecl.html).
+- [ModuleDecl.TopLevelBinding](../../https://fsprojects.github.io/fantomas/reference/fantomas-core-syntaxoak-moduledecl.html#TopLevelBinding) takes a [BindingNode ](../../reference/fantomas-core-syntaxoak-bindingnode.html).
- You would have multiple bindings in case of a recursive function.
-- The `headPat` of binding contains the name and the parameters.
-- The `expr` ([SynExpr](../../reference/fsharp-compiler-syntax-synexpr.html)) represents the F# syntax expression.
+- The `functionName ` of binding contains the name or is a pattern.
+- The `expr` ([Expr](../../reference/fantomas-core-syntaxoak-expr.html)) represents the F# syntax expression.
- Because there is no actual source code, all ranges will be `Range.Zero`.
-The more you interact with AST, the easier you pick up which node represents what.
+The more you interact with AST/Oak, the easier you pick up which node represents what.
### Fantomas.FCS
-When looking at the example, we notice that we've opened a couple of `FSharp.Compiler.*` namespaces.
+When looking at the example, we notice that we've opened `FSharp.Compiler.Text`.
Don't be fooled by this, `Fantomas.Core` and `Fantomas.FCS` **do not reference [FSharp.Compiler.Service](https://www.nuget.org/packages/FSharp.Compiler.Service)**!
Instead, `Fantomas.FCS` is a custom version of the F# compiler (built from source) that only exposes the F# parser and the syntax tree.
@@ -121,14 +101,17 @@ Example usage:
*)
-#r "nuget: Fantomas.FCS"
-
-open FSharp.Compiler.Text
open Fantomas.FCS
Parse.parseFile false (SourceText.ofString "let a = 1") []
(*** include-it ***)
+(**
+You can format untyped AST created from `Fantomas.FCS` using the `CodeFormatter` API.
+However, we recommend to use the new `Oak` model (as in the example) instead.
+The `Oak` model is easier to reason with as it structures certain concepts differently than the untyped AST.
+*)
+
(**
## Tips and tricks
@@ -137,77 +120,39 @@ Parse.parseFile false (SourceText.ofString "let a = 1") []
The syntax tree can have an overwhelming type hierarchy.
We wholeheartedly recommend to use our **[online tool](https://fsprojects.github.io/fantomas-tools/#/ast)** when working with AST.
-![F# AST Viewer](../../images/ast-viewer.png)
+![F# AST Viewer](../../images/oak-viewer.png)
-This shows you what AST nodes the parser created for a given input text.
+This shows you what Oak nodes the parser created for a given input text.
From there on you can use our search bar to find the corresponding documentation:
![Search bar](../../images/searchbar-ast.png)
### Match the AST the parser would produce
-Fantomas will very selectively use information from the AST.
-Please make sure you construct the same AST as the parser would.
+Fantomas will very selectively use information from the AST to construct the Oak.
+Please make sure you construct the same Oak as Fantomas would.
*)
// You typically make some helper functions along the way
-let mkCodeFromExpression (e: SynExpr) : string =
- ParsedInput.ImplFile(
- ParsedImplFileInput(
- "filename.fsx",
- true,
- QualifiedNameOfFile(Ident("", Range.Zero)),
- [],
- [],
- [ SynModuleOrNamespace(
- [],
- false,
- SynModuleOrNamespaceKind.AnonModule,
- [ SynModuleDecl.Expr(e, Range.Zero) ],
- PreXmlDoc.Empty,
- [],
- None,
- Range.Zero,
- { LeadingKeyword = SynModuleOrNamespaceLeadingKeyword.None }
- ) ],
- (false, false),
- { ConditionalDirectives = []
- CodeComments = [] },
- Set.empty
- )
- )
- |> CodeFormatter.FormatASTAsync
- |> Async.RunSynchronously
+let text v = SingleTextNode(v, Range.Zero)
-let numberExpr = SynExpr.Const(SynConst.Int32(7), Range.Zero)
-let wrappedNumber = SynExpr.Paren(numberExpr, Range.Zero, None, Range.Zero)
-
-try
- mkCodeFromExpression wrappedNumber
-with _ex ->
- // Fantomas.Core will make assumptions about certain constructs.
- // Just because you can instantiate the AST, does not mean it will be lead to valid code.
- "Code could not be transformed internally"
-(*** include-it ***)
+let mkCodeFromExpression (e: Expr) =
+ Oak([], [ ModuleOrNamespaceNode(None, [ ModuleDecl.DeclExpr e ], Range.Zero) ], Range.Zero)
+ |> CodeFormatter.FormatOakAsync
+ |> Async.RunSynchronously
+ |> printfn "%s"
-(**
-Notice that last but one argument `None`, it represents the range of the closing `)`.
-The F# parser would include `Some range` when it parses code, so you need to provide a `Some range` value as well.
-Even though the range is empty. Fantomas is designed to work with AST created by the parser.
-Creating a `SynExpr.Paren` node is not enough to get both parentheses!
-The `CodeFormatter.FormatASTAsync` API is really a side-effect and not a first class citizen.
-It will work when you play ball with the exact shape of the parser.
-*)
+let numberExpr = Expr.Constant(Constant.FromText(text "7"))
-let betterWrappedNumber =
- SynExpr.Paren(numberExpr, Range.Zero, Some Range.Zero, Range.Zero)
+let wrappedNumber =
+ Expr.Paren(ExprParenNode(text "(", numberExpr, text ")", Range.Zero))
-mkCodeFromExpression betterWrappedNumber
-(*** include-it ***)
+mkCodeFromExpression wrappedNumber
+(*** include-output ***)
(**
As a rule of thumb: **create what the parser creates, use the online tool!**
-Just because you can create AST nodes, does not mean Fantomas will do the right thing.
+Just because you can create Oak nodes, does not mean Fantomas will do the right thing.
### Look at the Fantomas code base
@@ -216,107 +161,55 @@ For example creating [SynExpr.Lambda](../../reference/fsharp-compiler-syntax-syn
When you want to construct `fun a b -> a + b`, the AST the online tool produces looks like:
```fsharp
-Lambda
- (false, false,
- SimplePats
- ([Id (a, None, false, false, false, tmp.fsx (1,4--1,5))],
- tmp.fsx (1,4--1,5)),
- Lambda
- (false, true,
- SimplePats
- ([Id (b, None, false, false, false, tmp.fsx (1,6--1,7))],
- tmp.fsx (1,6--1,7)),
- App
- (NonAtomic, false,
- App
- (NonAtomic, true,
- LongIdent
- (false,
- SynLongIdent
- ([op_Addition], [], [Some (OriginalNotation "+")]),
- None, tmp.fsx (1,13--1,14)), Ident a,
- tmp.fsx (1,11--1,14)), Ident b, tmp.fsx (1,11--1,16)),
- None, tmp.fsx (1,0--1,16),
- { ArrowRange = Some tmp.fsx (1,8--1,10) }),
- Some
- ([Named (SynIdent (a, None), false, None, tmp.fsx (1,4--1,5));
- Named (SynIdent (b, None), false, None, tmp.fsx (1,6--1,7))],
- App
- (NonAtomic, false,
- App
- (NonAtomic, true,
- LongIdent
- (false,
- SynLongIdent
- ([op_Addition], [], [Some (OriginalNotation "+")]),
- None, tmp.fsx (1,13--1,14)), Ident a,
- tmp.fsx (1,11--1,14)), Ident b, tmp.fsx (1,11--1,16))),
- tmp.fsx (1,0--1,16), { ArrowRange = Some tmp.fsx (1,8--1,10) })
+Oak (1,0-1,16)
+ ModuleOrNamespaceNode (1,0-1,16)
+ ExprLambdaNode (1,0-1,16)
+ "fun" (1,0-1,3)
+ PatNamedNode (1,4-1,5)
+ "a" (1,4-1,5)
+ PatNamedNode (1,6-1,7)
+ "b" (1,6-1,7)
+ "->" (1,8-1,10)
+ ExprInfixAppNode (1,11-1,16)
+ "a" (1,11-1,12)
+ "+" (1,13-1,14)
+ "b" (1,15-1,16)
```
-but the Fantomas `CodePrinter` does not use all this data.
-We can easily create a `Lambda` without the nested body structure, as Fantomas will use the `parsedData` information.
*)
-// this dummy expr will never be used!
-let dummyExpr = SynExpr.Const(SynConst.Unit, Range.Zero)
let lambdaExpr =
- let args =
- [ SynPat.Named(SynIdent(Ident("a", Range.Zero), None), false, None, Range.Zero)
- SynPat.Named(SynIdent(Ident("b", Range.Zero), None), false, None, Range.Zero) ]
-
- let expr =
- SynExpr.App(
- ExprAtomicFlag.NonAtomic,
- false,
- SynExpr.App(
- ExprAtomicFlag.NonAtomic,
- true,
- SynExpr.LongIdent(
- false,
- SynLongIdent(
- [ Ident("_actually_not_used_", Range.Zero) ],
- [],
- [ Some(IdentTrivia.OriginalNotation("+")) ]
- ),
- None,
- Range.Zero
-
- ),
- SynExpr.Ident(Ident("a", Range.Zero)),
- Range.Zero
- ),
- SynExpr.Ident(Ident("b", Range.Zero)),
- Range.Zero
- )
-
- SynExpr.Lambda(
- false,
- false,
- SynSimplePats.SimplePats([], Range.Zero), // not used
- dummyExpr, // not used
- Some(args, expr), // The good stuff is in here!
- Range.Zero,
- { ArrowRange = Some Range.Zero }
+ let body: Expr =
+ ExprInfixAppNode(Expr.Ident(text "a"), text "+", Expr.Ident(text "b"), Range.Zero)
+ |> Expr.InfixApp
+
+ ExprLambdaNode(
+ text "fun",
+ [ Pattern.Named(PatNamedNode(None, text "a", Range.Zero))
+ Pattern.Named(PatNamedNode(None, text "b", Range.Zero)) ],
+ text "->",
+ body,
+ Range.Zero
)
+ |> Expr.Lambda
mkCodeFromExpression lambdaExpr
-(*** include-it ***)
+(*** include-output ***)
-(**
-Notice how minimal the AST is, versus to what the parser produced. A subset of the data was enough.
-How to know which nodes to include? Take a look at `CodePrinter.fs` and `SourceParser.fs`!
+(**
+How to know which nodes to include? Take a look at `CodePrinter.fs`!
### Create your own set of helper functions
Throughout all these examples, we have duplicated a lot of code. You can typically easily refactor this into some helper functions.
The Fantomas maintainers are not affiliated with any projects that expose AST construction helpers.
-Relying on these projects, is at your own risk. The constructed AST might not be suitable for what Fantomas expects.
### Updates
-Since code generation is considered to be a nice to have functionality, there is no compatibility between any `Fantomas.FCS`.
-We do not apply any semantic versioning to `Fantomas.FCS`. Breaking changes can be expected at any given point.
+Since code generation is considered to be a nice to have functionality, there is no compatibility between any `Fantomas.Core` version when it comes to the `SyntaxOak` module.
+We do not apply any semantic versioning to `Fantomas.FCS` or `Fantomas.Core.SyntaxOak`. Breaking changes can be expected at any given point.
+Our recommendation is that you include a set of regression tests to meet your own expectations when upgrading.
+As none of our versions are compatible it is advised to take a very strict dependency on `Fantomas.Core`. Using constraints like `(>= 6.0.0)` will inevitably lead to unexpected problems.
-
+
*)
diff --git a/docs/docs/end-users/Rider.md b/docs/docs/end-users/Rider.md
index 3d77eba68b..bf97231beb 100644
--- a/docs/docs/end-users/Rider.md
+++ b/docs/docs/end-users/Rider.md
@@ -46,7 +46,7 @@ fsharp_array_or_list_multiline_formatter=character_width
fsharp_max_value_binding_width=80
fsharp_max_function_binding_width=40
fsharp_max_dot_get_expression_width=80
-fsharp_multiline_block_brackets_on_same_column=false
+fsharp_multiline_bracket_style = cramped
fsharp_newline_between_type_definition_and_members=true
fsharp_align_function_signature_to_indentation=false
fsharp_alternative_long_member_definitions=false
@@ -54,7 +54,6 @@ fsharp_multi_line_lambda_closing_newline=false
fsharp_experimental_keep_indent_in_branch=false
fsharp_blank_lines_around_nested_multiline_expressions=true
fsharp_bar_before_discriminated_union_declaration=false
-fsharp_experimental_stroustrup_style=false
fsharp_keep_max_number_of_blank_lines=100
fsharp_strict_mode=false
```
diff --git a/docs/docs/end-users/UpgradeGuide.md b/docs/docs/end-users/UpgradeGuide.md
new file mode 100644
index 0000000000..8847d0ca07
--- /dev/null
+++ b/docs/docs/end-users/UpgradeGuide.md
@@ -0,0 +1,80 @@
+---
+category: End-users
+categoryindex: 1
+index: 12
+---
+# Upgrade guide
+
+We wish to capture all changes required to upgrade to a new version. Please note that the focus of this document is about how to upgrade.
+New features are not covered in detail here, for those please refer to our [changelog](https://github.com/fsprojects/fantomas/blob/main/CHANGELOG.md).
+If you find something to be missing from this guide, please consider opening a PR to mend the gap instead of opening an issue.
+
+
+
+## v5.0
+
+### .editorconfig
+
+- `fsharp_max_elmish_width` was removed.
+- `fsharp_single_argument_web_mode` was removed.
+- `fsharp_disable_elmish_syntax` was removed.
+- `fsharp_semicolon_at_end_of_line` was removed.
+- `fsharp_keep_if_then_in_same_line` was removed.
+- `fsharp_indent_on_try_with` was removed.
+- If you were using Elmish inspired code (or `fsharp_single_argument_web_mode`) use
+
+```
+fsharp_multiline_block_brackets_on_same_column = true
+fsharp_experimental_stroustrup_style = true
+```
+- `fsharp_keep_indent_in_branch ` was renamed to `fsharp_experimental_keep_indent_in_branch`
+
+### console application
+
+- The dotnet tool is now targeting `net6.0`.
+- `--stdin` was removed.
+- `--stdout` was removed.
+- `--fsi` was removed.
+- `--force` now writes a formatted file to disk, regardless of its validity.
+
+### Miscellaneous
+
+- NuGet package `Fantomas` was renamed to `Fantomas.Core`.
+- NuGet package `fantomas-tool` was renamed to `fantomas`.
+- `Fantomas.Core` uses [Fantomas.FCS](https://www.nuget.org/packages/Fantomas.FCS) instead of [FSharp.Compiler.Service](https://www.nuget.org/packages/FSharp.Compiler.Service)
+- NuGet package `Fantomas.Extras` is deprecated.
+
+## v5.1
+
+### .editorconfig
+
+- The space in patterns is no longer controlled by `fsharp_space_before_parameter`,
+ `fsharp_space_before_lowercase_invocation` and `fsharp_space_before_uppercase_invocation` are now used.
+
+## v5.2
+
+### .editorconfig
+
+- `fsharp_multiline_block_brackets_on_same_column` and `fsharp_experimental_stroustrup_style` are now merged into one setting `fsharp_multiline_bracket_style`.
+ The accepted values for `fsharp_multiline_bracket_style` are `cramped`, `aligned` and `experimental_stroustrup`.
+ Note that `fsharp_multiline_block_brackets_on_same_column` and `fsharp_experimental_stroustrup_style` will continue to work until the next major version.
+
+## v6.0 (latest alpha)
+
+### .editorconfig
+
+- `fsharp_multiline_block_brackets_on_same_column` and `fsharp_experimental_stroustrup_style` are replaced with `fsharp_multiline_bracket_style`
+- `experimental_stroustrup` for `fsharp_multiline_bracket_style` is now `stroustrup`
+- `fsharp_newline_before_multiline_computation_expression` was extracted from `fsharp_multiline_bracket_style = stroustrup` and now controls how computation expression behave.
+- `fsharp_strict_mode` was removed and can no longer be used.
+
+### console application
+- `-v` is now short for `--verbosity` instead of `--version`
+- The console output was revamped.
+- `--recurse` was removed. Please use [.fantomasignore](./IgnoreFiles.html) file if you wish to ignore certain files.
+
+### Miscellaneous
+- The public API of CodeFormatter no longer uses `FSharpOption<'T>`, instead overloads are now used.
+- `StrictMode` was removed from `FormatConfig`, not passing the source text in the public API will have the same effect.
+
+
diff --git a/docs/images/ast-viewer.png b/docs/images/ast-viewer.png
deleted file mode 100644
index 07b6ef7e3e..0000000000
Binary files a/docs/images/ast-viewer.png and /dev/null differ
diff --git a/docs/images/oak-viewer.png b/docs/images/oak-viewer.png
new file mode 100644
index 0000000000..2eefd84000
Binary files /dev/null and b/docs/images/oak-viewer.png differ
diff --git a/docs/images/searchbar-ast.png b/docs/images/searchbar-ast.png
index d44c129ac6..6b18ecbb82 100644
Binary files a/docs/images/searchbar-ast.png and b/docs/images/searchbar-ast.png differ
diff --git a/fantomas.sln b/fantomas.sln
index ba8edd6db9..455820b02b 100644
--- a/fantomas.sln
+++ b/fantomas.sln
@@ -17,6 +17,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{29F22904-C
ProjectSection(SolutionItems) = preProject
docs\index.html = docs\index.html
docs\.README.md = docs\.README.md
+ docs\docs\end-users\Configuration.fsx = docs\docs\end-users\Configuration.fsx
EndProjectSection
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fantomas.Client", "src\Fantomas.Client\Fantomas.Client.fsproj", "{AA895F94-CCF2-4FCF-A9BB-E16987B57535}"
@@ -40,6 +41,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md
EndProjectSection
EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fantomas.Client.Tests", "src\Fantomas.Client.Tests\Fantomas.Client.Tests.fsproj", "{68814E36-3957-4D1C-BCDB-84C3C8478BEC}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -134,6 +137,18 @@ Global
{B39D50EE-0307-4C08-81F5-97418A946F63}.Release|x64.Build.0 = Release|Any CPU
{B39D50EE-0307-4C08-81F5-97418A946F63}.Release|x86.ActiveCfg = Release|Any CPU
{B39D50EE-0307-4C08-81F5-97418A946F63}.Release|x86.Build.0 = Release|Any CPU
+ {68814E36-3957-4D1C-BCDB-84C3C8478BEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {68814E36-3957-4D1C-BCDB-84C3C8478BEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {68814E36-3957-4D1C-BCDB-84C3C8478BEC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {68814E36-3957-4D1C-BCDB-84C3C8478BEC}.Debug|x64.Build.0 = Debug|Any CPU
+ {68814E36-3957-4D1C-BCDB-84C3C8478BEC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {68814E36-3957-4D1C-BCDB-84C3C8478BEC}.Debug|x86.Build.0 = Debug|Any CPU
+ {68814E36-3957-4D1C-BCDB-84C3C8478BEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {68814E36-3957-4D1C-BCDB-84C3C8478BEC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {68814E36-3957-4D1C-BCDB-84C3C8478BEC}.Release|x64.ActiveCfg = Release|Any CPU
+ {68814E36-3957-4D1C-BCDB-84C3C8478BEC}.Release|x64.Build.0 = Release|Any CPU
+ {68814E36-3957-4D1C-BCDB-84C3C8478BEC}.Release|x86.ActiveCfg = Release|Any CPU
+ {68814E36-3957-4D1C-BCDB-84C3C8478BEC}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/Fantomas.Benchmarks/Runners.fs b/src/Fantomas.Benchmarks/Runners.fs
index f121ac5802..482fe4fe97 100644
--- a/src/Fantomas.Benchmarks/Runners.fs
+++ b/src/Fantomas.Benchmarks/Runners.fs
@@ -4,7 +4,7 @@ open System.IO
open BenchmarkDotNet.Attributes
open Fantomas.Core
-let config = FormatConfig.FormatConfig.Default
+let config = FormatConfig.Default
[]
[]
diff --git a/src/Fantomas.Client.Tests/EndToEndTests.fs b/src/Fantomas.Client.Tests/EndToEndTests.fs
new file mode 100644
index 0000000000..bd9dd604ae
--- /dev/null
+++ b/src/Fantomas.Client.Tests/EndToEndTests.fs
@@ -0,0 +1,107 @@
+module Fantomas.Client.Tests
+
+open System
+open System.IO
+open System.Threading.Tasks
+open CliWrap
+open CliWrap.Buffered
+open Fantomas.Client.Contracts
+open Fantomas.Client.LSPFantomasService
+open Fantomas.Client.LSPFantomasServiceTypes
+open NUnit.Framework
+
+[]
+type EndToEndTests() =
+ let folder: DirectoryInfo =
+ DirectoryInfo(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")))
+
+ let service: FantomasService = new LSPFantomasService()
+
+ let unformattedCode = "let a = 8"
+
+ let withVersion version (callback: string -> Task) =
+ if Path.Exists(Path.Combine(folder.FullName, version)) then
+ backgroundTask {
+ let file = Path.Combine(folder.FullName, version, "File.fs")
+ do! callback file
+ }
+ else
+ backgroundTask {
+ let subDirectory = folder.CreateSubdirectory(version)
+
+ let dotnet (command: string) =
+ Cli
+ .Wrap("dotnet")
+ .WithWorkingDirectory(subDirectory.FullName)
+ .WithArguments(command)
+ .ExecuteBufferedAsync()
+ .Task
+ :> Task
+
+ // This sdk version must match the version used in this repository.
+ // It will be the version which the CI/CD pipeline has access to.
+ do! dotnet "new globaljson --sdk-version 7.0.100 --roll-forward latestPatch"
+ do! dotnet "new tool-manifest"
+
+ do!
+ dotnet
+ $"tool install fantomas -v d --version {version} --add-source https://api.nuget.org/v3/index.json"
+
+ let fsharpFile = Path.Combine(subDirectory.FullName, "File.fs")
+ File.Create(fsharpFile).Dispose()
+ do! callback fsharpFile
+ }
+
+ []
+ member _.Setup() = folder.Create()
+
+ []
+ member _.TearDown() =
+ backgroundTask {
+ service.Dispose()
+ // Give it a little time before all processes are truly killed.
+ do! Task.Delay(200)
+ folder.Delete(true)
+ }
+
+ []
+ []
+ []
+ []
+ member _.Version(version: string) =
+ withVersion version (fun fsharpFile ->
+ backgroundTask {
+ let! version = service.VersionAsync(fsharpFile)
+ Assert.AreEqual(int FantomasResponseCode.Version, version.Code)
+ })
+
+ []
+ []
+ []
+ []
+ member _.FormatDocument(version: string) =
+ withVersion version (fun fsharpFile ->
+ backgroundTask {
+ let request: FormatDocumentRequest =
+ { SourceCode = unformattedCode
+ FilePath = fsharpFile
+ Config = None
+ Cursor = None }
+
+ let! formatResponse = service.FormatDocumentAsync(request)
+ Assert.AreEqual(int FantomasResponseCode.Formatted, formatResponse.Code)
+ })
+
+ []
+ member _.``FormatDocument with Cursor``(version: string) =
+ withVersion version (fun fsharpFile ->
+ backgroundTask {
+ let request: FormatDocumentRequest =
+ { SourceCode = unformattedCode
+ FilePath = fsharpFile
+ Config = None
+ Cursor = Some(FormatCursorPosition(1, 12)) }
+
+ let! formatResponse = service.FormatDocumentAsync(request)
+ Assert.AreEqual(int FantomasResponseCode.Formatted, formatResponse.Code)
+ })
diff --git a/src/Fantomas.Client.Tests/Fantomas.Client.Tests.fsproj b/src/Fantomas.Client.Tests/Fantomas.Client.Tests.fsproj
new file mode 100644
index 0000000000..c6b2d92df6
--- /dev/null
+++ b/src/Fantomas.Client.Tests/Fantomas.Client.Tests.fsproj
@@ -0,0 +1,27 @@
+
+
+
+ FS0988
+ net7.0
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Fantomas.Client.Tests/packages.lock.json b/src/Fantomas.Client.Tests/packages.lock.json
new file mode 100644
index 0000000000..7c5c66f44b
--- /dev/null
+++ b/src/Fantomas.Client.Tests/packages.lock.json
@@ -0,0 +1,819 @@
+{
+ "version": 1,
+ "dependencies": {
+ "net7.0": {
+ "CliWrap": {
+ "type": "Direct",
+ "requested": "[3.6.0, )",
+ "resolved": "3.6.0",
+ "contentHash": "AY6LvRZOEYuAiuaWPLnIDddJUnpiPpiSvfoPwweEXI1orRNnsAwf6sOv9Tt0J4GFrlwejFF/INuR57iEKIh7bw=="
+ },
+ "FSharp.Core": {
+ "type": "Direct",
+ "requested": "[6.0.1, )",
+ "resolved": "6.0.1",
+ "contentHash": "VrFAiW8dEEekk+0aqlbvMNZzDvYXmgWZwAt68AUBqaWK8RnoEVUNglj66bZzhs4/U63q0EfXlhcEKnH1sTYLjw=="
+ },
+ "Microsoft.NET.Test.Sdk": {
+ "type": "Direct",
+ "requested": "[17.3.2, )",
+ "resolved": "17.3.2",
+ "contentHash": "apR0ha1T8FujBwq1P8i/DOZjbI5XhcP/i8As4NnVztVSpZG8GtWRPCstcmgkUkBpvEfcrrDPlJWbuZY+Hl1hSg==",
+ "dependencies": {
+ "Microsoft.CodeCoverage": "17.3.2",
+ "Microsoft.TestPlatform.TestHost": "17.3.2"
+ }
+ },
+ "NUnit": {
+ "type": "Direct",
+ "requested": "[3.13.3, )",
+ "resolved": "3.13.3",
+ "contentHash": "KNPDpls6EfHwC3+nnA67fh5wpxeLb3VLFAfLxrug6JMYDLHH6InaQIWR7Sc3y75d/9IKzMksH/gi08W7XWbmnQ==",
+ "dependencies": {
+ "NETStandard.Library": "2.0.0"
+ }
+ },
+ "NUnit3TestAdapter": {
+ "type": "Direct",
+ "requested": "[4.2.1, )",
+ "resolved": "4.2.1",
+ "contentHash": "kgH8VKsrcZZgNGQXRpVCrM7TnNz9li3b/snH+YmnXUNqsaWa1Xw9EQWHpbzq4Li2FbTjTE/E5N5HdLNXzZ8BpQ=="
+ },
+ "NunitXml.TestLogger": {
+ "type": "Direct",
+ "requested": "[3.0.127, )",
+ "resolved": "3.0.127",
+ "contentHash": "v8cEbYVSZGwCD6290yKeRCsRpOwYcgnng1YRrQKGgP79mHuxj1b1lpb6kA02QoLUM5/Qv9aDSLmS0U05m6HlJg=="
+ },
+ "MessagePack": {
+ "type": "Transitive",
+ "resolved": "2.2.85",
+ "contentHash": "3SqAgwNV5LOf+ZapHmjQMUc7WDy/1ur9CfFNjgnfMZKCB5CxkVVbyHa06fObjGTEHZI7mcDathYjkI+ncr92ZQ==",
+ "dependencies": {
+ "MessagePack.Annotations": "2.2.85",
+ "Microsoft.Bcl.AsyncInterfaces": "1.0.0",
+ "System.Collections.Immutable": "1.5.0",
+ "System.Memory": "4.5.3",
+ "System.Reflection.Emit": "4.6.0",
+ "System.Reflection.Emit.Lightweight": "4.6.0",
+ "System.Runtime.CompilerServices.Unsafe": "4.5.2",
+ "System.Threading.Tasks.Extensions": "4.5.3"
+ }
+ },
+ "MessagePack.Annotations": {
+ "type": "Transitive",
+ "resolved": "2.2.85",
+ "contentHash": "YptRsDCQK35K5FhmZ0LojW4t8I6DpetLfK5KG8PVY2f6h7/gdyr8f4++xdSEK/xS6XX7/GPvEpqszKVPksCsiQ=="
+ },
+ "Microsoft.Bcl.AsyncInterfaces": {
+ "type": "Transitive",
+ "resolved": "5.0.0",
+ "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ=="
+ },
+ "Microsoft.CodeCoverage": {
+ "type": "Transitive",
+ "resolved": "17.3.2",
+ "contentHash": "+CeYNY9hYNRgv1wAID5koeDVob1ZOrOYfRRTLxU9Zm5ZMDMkMZ8wzXgakxVv+jtk8tPdE8Ze9vVE+czMKapv/Q=="
+ },
+ "Microsoft.NETCore.Platforms": {
+ "type": "Transitive",
+ "resolved": "5.0.0",
+ "contentHash": "VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ=="
+ },
+ "Microsoft.NETCore.Targets": {
+ "type": "Transitive",
+ "resolved": "1.1.0",
+ "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg=="
+ },
+ "Microsoft.TestPlatform.ObjectModel": {
+ "type": "Transitive",
+ "resolved": "17.3.2",
+ "contentHash": "DJEIfSA2GDC+2m42vKGNR2hm+Uhta4SpCsLZVVvYIiYMjxtk7GzNnv82qvE4SCW3kIYllMg2D0rr8juuj/f7AA==",
+ "dependencies": {
+ "NuGet.Frameworks": "5.11.0",
+ "System.Reflection.Metadata": "1.6.0"
+ }
+ },
+ "Microsoft.TestPlatform.TestHost": {
+ "type": "Transitive",
+ "resolved": "17.3.2",
+ "contentHash": "113J19v31pIx+PzmdEw67cWTZWh/YApnprbclFeat6szNbnpKOKG7Ap4PX5LT6E5Da+xONyilxvx2HZPpEaXPQ==",
+ "dependencies": {
+ "Microsoft.TestPlatform.ObjectModel": "17.3.2",
+ "Newtonsoft.Json": "9.0.1"
+ }
+ },
+ "Microsoft.VisualStudio.Threading": {
+ "type": "Transitive",
+ "resolved": "16.9.60",
+ "contentHash": "9igpltD4NDMb1QeLiuAShr4inAG/MEm/GL0VE3tCUXQmwrfrbrmwrhAn5fXy2uiZ1g2s2qSUkyEvx7sp2h7M8Q==",
+ "dependencies": {
+ "Microsoft.Bcl.AsyncInterfaces": "5.0.0",
+ "Microsoft.VisualStudio.Threading.Analyzers": "16.9.60",
+ "Microsoft.VisualStudio.Validation": "16.8.33",
+ "Microsoft.Win32.Registry": "5.0.0",
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ }
+ },
+ "Microsoft.VisualStudio.Threading.Analyzers": {
+ "type": "Transitive",
+ "resolved": "16.9.60",
+ "contentHash": "kbl+ra5Ao93lDar3A2vUSdfWiHMYBBsLM3Z6i/t6fH2iPHGyMTqvt3z20XCZ+L+1gcc8lpbhmkFS4rh+zwfsTg=="
+ },
+ "Microsoft.VisualStudio.Validation": {
+ "type": "Transitive",
+ "resolved": "16.8.33",
+ "contentHash": "onzrXL8gsjht1knmmViGLTU3l1LIKoVLDL+gLN9Pdd+gclED9jLgxx/5X3mJHqETHMi7Va//hNCekiJ11LezSg=="
+ },
+ "Microsoft.Win32.Primitives": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "9ZQKCWxH7Ijp9BfahvL2Zyf1cJIk8XYLF6Yjzr2yi0b2cOut/HQ31qf1ThHAgCc3WiZMdnWcfJCgN82/0UunxA==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "Microsoft.Win32.Registry": {
+ "type": "Transitive",
+ "resolved": "5.0.0",
+ "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==",
+ "dependencies": {
+ "System.Security.AccessControl": "5.0.0",
+ "System.Security.Principal.Windows": "5.0.0"
+ }
+ },
+ "Nerdbank.Streams": {
+ "type": "Transitive",
+ "resolved": "2.6.81",
+ "contentHash": "htBHFE359qyyFwrvAGvFxrbBAoldZdl0XjtQdDWTJ8t5sWWs7QVXID5y1ZGJE61UgpV5CqWsj/NT0LOAn5GdZw==",
+ "dependencies": {
+ "Microsoft.Bcl.AsyncInterfaces": "1.1.1",
+ "Microsoft.VisualStudio.Threading": "16.7.56",
+ "Microsoft.VisualStudio.Validation": "15.5.31",
+ "System.IO.Pipelines": "4.7.2",
+ "System.Net.WebSockets": "4.3.0",
+ "System.Runtime.CompilerServices.Unsafe": "4.7.1"
+ }
+ },
+ "NETStandard.Library": {
+ "type": "Transitive",
+ "resolved": "2.0.0",
+ "contentHash": "7jnbRU+L08FXKMxqUflxEXtVymWvNOrS8yHgu9s6EM8Anr6T/wIX4nZ08j/u3Asz+tCufp3YVwFSEvFTPYmBPA==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0"
+ }
+ },
+ "Newtonsoft.Json": {
+ "type": "Transitive",
+ "resolved": "12.0.2",
+ "contentHash": "rTK0s2EKlfHsQsH6Yx2smvcTCeyoDNgCW7FEYyV01drPlh2T243PR2DiDXqtC5N4GDm4Ma/lkxfW5a/4793vbA=="
+ },
+ "NuGet.Frameworks": {
+ "type": "Transitive",
+ "resolved": "5.11.0",
+ "contentHash": "eaiXkUjC4NPcquGWzAGMXjuxvLwc6XGKMptSyOGQeT0X70BUZObuybJFZLA0OfTdueLd3US23NBPTBb6iF3V1Q=="
+ },
+ "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
+ "type": "Transitive",
+ "resolved": "4.3.2",
+ "contentHash": "7VSGO0URRKoMEAq0Sc9cRz8mb6zbyx/BZDEWhgPdzzpmFhkam3fJ1DAGWFXBI4nGlma+uPKpfuMQP5LXRnOH5g=="
+ },
+ "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
+ "type": "Transitive",
+ "resolved": "4.3.2",
+ "contentHash": "0oAaTAm6e2oVH+/Zttt0cuhGaePQYKII1dY8iaqP7CvOpVKgLybKRFvQjXR2LtxXOXTVPNv14j0ot8uV+HrUmw=="
+ },
+ "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
+ "type": "Transitive",
+ "resolved": "4.3.2",
+ "contentHash": "G24ibsCNi5Kbz0oXWynBoRgtGvsw5ZSVEWjv13/KiCAM8C6wz9zzcCniMeQFIkJ2tasjo2kXlvlBZhplL51kGg=="
+ },
+ "runtime.native.System": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "c/qWt2LieNZIj1jGnVNsE2Kl23Ya2aSTBuXMD6V7k9KWr6l16Tqdwq+hJScEpWER9753NWC8h96PaVNY5Ld7Jw==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0"
+ }
+ },
+ "runtime.native.System.Net.Http": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "ZVuZJqnnegJhd2k/PtAbbIcZ3aZeITq3sj06oKfMBSfphW3HDmk/t4ObvbOk/JA/swGR0LNqMksAh/f7gpTROg==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0"
+ }
+ },
+ "runtime.native.System.Security.Cryptography.Apple": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "DloMk88juo0OuOWr56QG7MNchmafTLYWvABy36izkrLI5VledI0rq28KGs1i9wbpeT9NPQrx/wTf8U2vazqQ3Q==",
+ "dependencies": {
+ "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": "4.3.0"
+ }
+ },
+ "runtime.native.System.Security.Cryptography.OpenSsl": {
+ "type": "Transitive",
+ "resolved": "4.3.2",
+ "contentHash": "QR1OwtwehHxSeQvZKXe+iSd+d3XZNkEcuWMFYa2i0aG1l+lR739HPicKMlTbJst3spmeekDVBUS7SeS26s4U/g==",
+ "dependencies": {
+ "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
+ "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
+ "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
+ "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
+ "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
+ "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
+ "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
+ "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
+ "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
+ "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2"
+ }
+ },
+ "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
+ "type": "Transitive",
+ "resolved": "4.3.2",
+ "contentHash": "I+GNKGg2xCHueRd1m9PzeEW7WLbNNLznmTuEi8/vZX71HudUbx1UTwlGkiwMri7JLl8hGaIAWnA/GONhu+LOyQ=="
+ },
+ "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
+ "type": "Transitive",
+ "resolved": "4.3.2",
+ "contentHash": "1Z3TAq1ytS1IBRtPXJvEUZdVsfWfeNEhBkbiOCGEl9wwAfsjP2lz3ZFDx5tq8p60/EqbS0HItG5piHuB71RjoA=="
+ },
+ "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "kVXCuMTrTlxq4XOOMAysuNwsXWpYeboGddNGpIgNSZmv1b6r/s/DPk0fYMB7Q5Qo4bY68o48jt4T4y5BVecbCQ=="
+ },
+ "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
+ "type": "Transitive",
+ "resolved": "4.3.2",
+ "contentHash": "6mU/cVmmHtQiDXhnzUImxIcDL48GbTk+TsptXyJA+MIOG9LRjPoAQC/qBFB7X+UNyK86bmvGwC8t+M66wsYC8w=="
+ },
+ "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
+ "type": "Transitive",
+ "resolved": "4.3.2",
+ "contentHash": "vjwG0GGcTW/PPg6KVud8F9GLWYuAV1rrw1BKAqY0oh4jcUqg15oYF1+qkGR2x2ZHM4DQnWKQ7cJgYbfncz/lYg=="
+ },
+ "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
+ "type": "Transitive",
+ "resolved": "4.3.2",
+ "contentHash": "7KMFpTkHC/zoExs+PwP8jDCWcrK9H6L7soowT80CUx3e+nxP/AFnq0AQAW5W76z2WYbLAYCRyPfwYFG6zkvQRw=="
+ },
+ "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
+ "type": "Transitive",
+ "resolved": "4.3.2",
+ "contentHash": "xrlmRCnKZJLHxyyLIqkZjNXqgxnKdZxfItrPkjI+6pkRo5lHX8YvSZlWrSI5AVwLMi4HbNWP7064hcAWeZKp5w=="
+ },
+ "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
+ "type": "Transitive",
+ "resolved": "4.3.2",
+ "contentHash": "leXiwfiIkW7Gmn7cgnNcdtNAU70SjmKW3jxGj1iKHOvdn0zRWsgv/l2OJUO5zdGdiv2VRFnAsxxhDgMzofPdWg=="
+ },
+ "SemanticVersioning": {
+ "type": "Transitive",
+ "resolved": "2.0.2",
+ "contentHash": "4EQgYdNZ92SyaO7YFk6olVnebF5V+jrHyMUjvPq89tLeMo8NSfgDF+6Zwq/lgh9j/0yfQp9Lkm0ZA0rUATCZFA=="
+ },
+ "StreamJsonRpc": {
+ "type": "Transitive",
+ "resolved": "2.8.28",
+ "contentHash": "i2hKUXJSLEoWpPqQNyISqLDqmFHMiyasjTC/PrrHNWhQyauFeVoebSct3E4OTUzRC1DYjVJ9AMiVbp/uVYLnjQ==",
+ "dependencies": {
+ "MessagePack": "2.2.85",
+ "Microsoft.Bcl.AsyncInterfaces": "5.0.0",
+ "Microsoft.VisualStudio.Threading": "16.9.60",
+ "Nerdbank.Streams": "2.6.81",
+ "Newtonsoft.Json": "12.0.2",
+ "System.Collections.Immutable": "5.0.0",
+ "System.Diagnostics.DiagnosticSource": "5.0.1",
+ "System.IO.Pipelines": "5.0.1",
+ "System.Memory": "4.5.4",
+ "System.Net.Http": "4.3.4",
+ "System.Net.WebSockets": "4.3.0",
+ "System.Reflection.Emit": "4.7.0",
+ "System.Threading.Tasks.Dataflow": "5.0.0",
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ }
+ },
+ "System.Collections": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Collections.Concurrent": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "ztl69Xp0Y/UXCL+3v3tEU+lIy+bvjKNUmopn1wep/a291pVPK7dxBd6T7WnlQqRog+d1a/hSsgRsmFnIBKTPLQ==",
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Diagnostics.Tracing": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Threading": "4.3.0",
+ "System.Threading.Tasks": "4.3.0"
+ }
+ },
+ "System.Collections.Immutable": {
+ "type": "Transitive",
+ "resolved": "5.0.0",
+ "contentHash": "FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g=="
+ },
+ "System.Diagnostics.Debug": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "ZUhUOdqmaG5Jk3Xdb8xi5kIyQYAA4PnTNlHx1mu9ZY3qv4ELIdKbnL/akbGaKi2RnNUWaZsAs31rvzFdewTj2g==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Diagnostics.DiagnosticSource": {
+ "type": "Transitive",
+ "resolved": "5.0.1",
+ "contentHash": "uXQEYqav2V3zP6OwkOKtLv+qIi6z3m1hsGyKwXX7ZA7htT4shoVccGxnJ9kVRFPNAsi1ArZTq2oh7WOto6GbkQ=="
+ },
+ "System.Diagnostics.Tracing": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "rswfv0f/Cqkh78rA5S8eN8Neocz234+emGCtTF3lxPY96F+mmmUen6tbn0glN6PMvlKQb9bPAY5e9u7fgPTkKw==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Globalization": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Globalization.Calendars": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "GUlBtdOWT4LTV3I+9/PJW+56AnnChTaOqqTLFtdmype/L500M2LIyXgmtd9X2P2VOkmJd5c67H5SaC2QcL1bFA==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Globalization": "4.3.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Globalization.Extensions": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "FhKmdR6MPG+pxow6wGtNAWdZh7noIOpdD5TwQ3CprzgIE1bBBoim0vbR1+AWsWjQmU7zXHgQo4TWSP6lCeiWcQ==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "System.Globalization": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Runtime.InteropServices": "4.3.0"
+ }
+ },
+ "System.IO": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Runtime": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "System.Threading.Tasks": "4.3.0"
+ }
+ },
+ "System.IO.FileSystem": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "3wEMARTnuio+ulnvi+hkRNROYwa1kylvYahhcLk4HSoVdl+xxTFVeVlYOfLwrDPImGls0mDqbMhrza8qnWPTdA==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.IO": "4.3.0",
+ "System.IO.FileSystem.Primitives": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Handles": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "System.Threading.Tasks": "4.3.0"
+ }
+ },
+ "System.IO.FileSystem.Primitives": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "6QOb2XFLch7bEc4lIcJH49nJN2HV+OC3fHDgsLVsBVBk3Y4hFAnOBGzJ2lUu7CyDDFo9IBWkSsnbkT6IBwwiMw==",
+ "dependencies": {
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.IO.Pipelines": {
+ "type": "Transitive",
+ "resolved": "5.0.1",
+ "contentHash": "qEePWsaq9LoEEIqhbGe6D5J8c9IqQOUuTzzV6wn1POlfdLkJliZY3OlB0j0f17uMWlqZYjH7txj+2YbyrIA8Yg=="
+ },
+ "System.Linq": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "5DbqIUpsDp0dFftytzuMmc0oeMdQwjcP/EWxsksIz/w1TcFRkZ3yKKz0PqiYFMmEwPSWw+qNVqD7PJ889JzHbw==",
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0"
+ }
+ },
+ "System.Memory": {
+ "type": "Transitive",
+ "resolved": "4.5.4",
+ "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw=="
+ },
+ "System.Net.Http": {
+ "type": "Transitive",
+ "resolved": "4.3.4",
+ "contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.1",
+ "System.Collections": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Diagnostics.DiagnosticSource": "4.3.0",
+ "System.Diagnostics.Tracing": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.Globalization.Extensions": "4.3.0",
+ "System.IO": "4.3.0",
+ "System.IO.FileSystem": "4.3.0",
+ "System.Net.Primitives": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Runtime.Handles": "4.3.0",
+ "System.Runtime.InteropServices": "4.3.0",
+ "System.Security.Cryptography.Algorithms": "4.3.0",
+ "System.Security.Cryptography.Encoding": "4.3.0",
+ "System.Security.Cryptography.OpenSsl": "4.3.0",
+ "System.Security.Cryptography.Primitives": "4.3.0",
+ "System.Security.Cryptography.X509Certificates": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "System.Threading": "4.3.0",
+ "System.Threading.Tasks": "4.3.0",
+ "runtime.native.System": "4.3.0",
+ "runtime.native.System.Net.Http": "4.3.0",
+ "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2"
+ }
+ },
+ "System.Net.Primitives": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "qOu+hDwFwoZPbzPvwut2qATe3ygjeQBDQj91xlsaqGFQUI5i4ZnZb8yyQuLGpDGivEPIt8EJkd1BVzVoP31FXA==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Handles": "4.3.0"
+ }
+ },
+ "System.Net.WebSockets": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "u6fFNY5q4T8KerUAVbya7bR6b7muBuSTAersyrihkcmE5QhEOiH3t5rh4il15SexbVlpXFHGuMwr/m8fDrnkQg==",
+ "dependencies": {
+ "Microsoft.Win32.Primitives": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Threading.Tasks": "4.3.0"
+ }
+ },
+ "System.Reflection": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.IO": "4.3.0",
+ "System.Reflection.Primitives": "4.3.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Reflection.Emit": {
+ "type": "Transitive",
+ "resolved": "4.7.0",
+ "contentHash": "VR4kk8XLKebQ4MZuKuIni/7oh+QGFmZW3qORd1GvBq/8026OpW501SzT/oypwiQl4TvT8ErnReh/NzY9u+C6wQ=="
+ },
+ "System.Reflection.Emit.Lightweight": {
+ "type": "Transitive",
+ "resolved": "4.6.0",
+ "contentHash": "j/V5HVvxvBQ7uubYD0PptQW2KGsi1Pc2kZ9yfwLixv3ADdjL/4M78KyC5e+ymW612DY8ZE4PFoZmWpoNmN2mqg=="
+ },
+ "System.Reflection.Metadata": {
+ "type": "Transitive",
+ "resolved": "1.6.0",
+ "contentHash": "COC1aiAJjCoA5GBF+QKL2uLqEBew4JsCkQmoHKbN3TlOZKa2fKLz5CpiRQKDz0RsAOEGsVKqOD5bomsXq/4STQ=="
+ },
+ "System.Reflection.Primitives": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Resources.ResourceManager": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Globalization": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Runtime": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0"
+ }
+ },
+ "System.Runtime.CompilerServices.Unsafe": {
+ "type": "Transitive",
+ "resolved": "4.7.1",
+ "contentHash": "zOHkQmzPCn5zm/BH+cxC1XbUS3P4Yoi3xzW7eRgVpDR2tPGSzyMZ17Ig1iRkfJuY0nhxkQQde8pgePNiA7z7TQ=="
+ },
+ "System.Runtime.Extensions": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Runtime.Handles": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "OKiSUN7DmTWeYb3l51A7EYaeNMnvxwE249YtZz7yooT4gOZhmTjIn48KgSsw2k2lYdLgTKNJw/ZIfSElwDRVgg==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Runtime.InteropServices": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "uv1ynXqiMK8mp1GM3jDqPCFN66eJ5w5XNomaK2XD+TuCroNTLFGeZ+WCmBMcBDyTFKou3P6cR6J/QsaqDp7fGQ==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Reflection": "4.3.0",
+ "System.Reflection.Primitives": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Handles": "4.3.0"
+ }
+ },
+ "System.Runtime.Numerics": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "yMH+MfdzHjy17l2KESnPiF2dwq7T+xLnSJar7slyimAkUh/gTrS9/UQOtv7xarskJ2/XDSNvfLGOBQPjL7PaHQ==",
+ "dependencies": {
+ "System.Globalization": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0"
+ }
+ },
+ "System.Security.AccessControl": {
+ "type": "Transitive",
+ "resolved": "5.0.0",
+ "contentHash": "dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "5.0.0",
+ "System.Security.Principal.Windows": "5.0.0"
+ }
+ },
+ "System.Security.Cryptography.Algorithms": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "System.Collections": "4.3.0",
+ "System.IO": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Runtime.Handles": "4.3.0",
+ "System.Runtime.InteropServices": "4.3.0",
+ "System.Runtime.Numerics": "4.3.0",
+ "System.Security.Cryptography.Encoding": "4.3.0",
+ "System.Security.Cryptography.Primitives": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "runtime.native.System.Security.Cryptography.Apple": "4.3.0",
+ "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
+ }
+ },
+ "System.Security.Cryptography.Cng": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "03idZOqFlsKRL4W+LuCpJ6dBYDUWReug6lZjBa3uJWnk5sPCUXckocevTaUA8iT/MFSrY/2HXkOt753xQ/cf8g==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "System.IO": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Runtime.Handles": "4.3.0",
+ "System.Runtime.InteropServices": "4.3.0",
+ "System.Security.Cryptography.Algorithms": "4.3.0",
+ "System.Security.Cryptography.Encoding": "4.3.0",
+ "System.Security.Cryptography.Primitives": "4.3.0",
+ "System.Text.Encoding": "4.3.0"
+ }
+ },
+ "System.Security.Cryptography.Csp": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "X4s/FCkEUnRGnwR3aSfVIkldBmtURMhmexALNTwpjklzxWU7yjMk7GHLKOZTNkgnWnE0q7+BCf9N2LVRWxewaA==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "System.IO": "4.3.0",
+ "System.Reflection": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Runtime.Handles": "4.3.0",
+ "System.Runtime.InteropServices": "4.3.0",
+ "System.Security.Cryptography.Algorithms": "4.3.0",
+ "System.Security.Cryptography.Encoding": "4.3.0",
+ "System.Security.Cryptography.Primitives": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "System.Threading": "4.3.0"
+ }
+ },
+ "System.Security.Cryptography.Encoding": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "System.Collections": "4.3.0",
+ "System.Collections.Concurrent": "4.3.0",
+ "System.Linq": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Runtime.Handles": "4.3.0",
+ "System.Runtime.InteropServices": "4.3.0",
+ "System.Security.Cryptography.Primitives": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
+ }
+ },
+ "System.Security.Cryptography.OpenSsl": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "h4CEgOgv5PKVF/HwaHzJRiVboL2THYCou97zpmhjghx5frc7fIvlkY1jL+lnIQyChrJDMNEXS6r7byGif8Cy4w==",
+ "dependencies": {
+ "System.Collections": "4.3.0",
+ "System.IO": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Runtime.Handles": "4.3.0",
+ "System.Runtime.InteropServices": "4.3.0",
+ "System.Runtime.Numerics": "4.3.0",
+ "System.Security.Cryptography.Algorithms": "4.3.0",
+ "System.Security.Cryptography.Encoding": "4.3.0",
+ "System.Security.Cryptography.Primitives": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
+ }
+ },
+ "System.Security.Cryptography.Primitives": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==",
+ "dependencies": {
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.IO": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Threading": "4.3.0",
+ "System.Threading.Tasks": "4.3.0"
+ }
+ },
+ "System.Security.Cryptography.X509Certificates": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "System.Collections": "4.3.0",
+ "System.Diagnostics.Debug": "4.3.0",
+ "System.Globalization": "4.3.0",
+ "System.Globalization.Calendars": "4.3.0",
+ "System.IO": "4.3.0",
+ "System.IO.FileSystem": "4.3.0",
+ "System.IO.FileSystem.Primitives": "4.3.0",
+ "System.Resources.ResourceManager": "4.3.0",
+ "System.Runtime": "4.3.0",
+ "System.Runtime.Extensions": "4.3.0",
+ "System.Runtime.Handles": "4.3.0",
+ "System.Runtime.InteropServices": "4.3.0",
+ "System.Runtime.Numerics": "4.3.0",
+ "System.Security.Cryptography.Algorithms": "4.3.0",
+ "System.Security.Cryptography.Cng": "4.3.0",
+ "System.Security.Cryptography.Csp": "4.3.0",
+ "System.Security.Cryptography.Encoding": "4.3.0",
+ "System.Security.Cryptography.OpenSsl": "4.3.0",
+ "System.Security.Cryptography.Primitives": "4.3.0",
+ "System.Text.Encoding": "4.3.0",
+ "System.Threading": "4.3.0",
+ "runtime.native.System": "4.3.0",
+ "runtime.native.System.Net.Http": "4.3.0",
+ "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
+ }
+ },
+ "System.Security.Principal.Windows": {
+ "type": "Transitive",
+ "resolved": "5.0.0",
+ "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA=="
+ },
+ "System.Text.Encoding": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Threading": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "VkUS0kOBcUf3Wwm0TSbrevDDZ6BlM+b/HRiapRFWjM5O0NS0LviG0glKmFK+hhPDd1XFeSdU1GmlLhb2CoVpIw==",
+ "dependencies": {
+ "System.Runtime": "4.3.0",
+ "System.Threading.Tasks": "4.3.0"
+ }
+ },
+ "System.Threading.Tasks": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.NETCore.Targets": "1.1.0",
+ "System.Runtime": "4.3.0"
+ }
+ },
+ "System.Threading.Tasks.Dataflow": {
+ "type": "Transitive",
+ "resolved": "5.0.0",
+ "contentHash": "NBp0zSAMZp4muDje6XmbDfmkqw9+qsDCHp+YMEtnVgHEjQZ3Q7MzFTTp3eHqpExn4BwMrS7JkUVOTcVchig4Sw=="
+ },
+ "System.Threading.Tasks.Extensions": {
+ "type": "Transitive",
+ "resolved": "4.5.4",
+ "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg=="
+ },
+ "fantomas.client": {
+ "type": "Project",
+ "dependencies": {
+ "FSharp.Core": "[5.0.1, )",
+ "SemanticVersioning": "[2.0.2, )",
+ "StreamJsonRpc": "[2.8.28, )"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Fantomas.Client/CHANGELOG.md b/src/Fantomas.Client/CHANGELOG.md
index fcd5f26be0..142bc3a776 100644
--- a/src/Fantomas.Client/CHANGELOG.md
+++ b/src/Fantomas.Client/CHANGELOG.md
@@ -2,6 +2,12 @@
This is the changelog for the Fantomas.Client package specifically. It's distinct from that of the overall libraries and command-line tool.
+## 0.9.0 - 2023-02-24
+* Fix JSON serialization of new cursor API. [#2778](https://github.com/fsprojects/fantomas/issues/2778)
+
+## 0.8.0 - 2023-01-24
+* Initial cursor API. [#2739](https://github.com/fsprojects/fantomas/pull/2739)
+
## 0.7.0 - 2022-11-09
### Changed
diff --git a/src/Fantomas.Client/Contracts.fs b/src/Fantomas.Client/Contracts.fs
index 17016b9bd4..9de7f8a1c1 100644
--- a/src/Fantomas.Client/Contracts.fs
+++ b/src/Fantomas.Client/Contracts.fs
@@ -20,17 +20,21 @@ module Methods =
let Configuration = "fantomas/configuration"
type FormatDocumentRequest =
- {
- SourceCode: string
- /// File path will be used to identify the .editorconfig options
- /// Unless the configuration is passed
- FilePath: string
- /// Overrides the found .editorconfig.
- Config: IReadOnlyDictionary option
- }
+ { SourceCode: string
+ FilePath: string
+ Config: IReadOnlyDictionary option
+ Cursor: FormatCursorPosition option }
member this.IsSignatureFile = this.FilePath.EndsWith(".fsi")
+and FormatCursorPosition =
+ class
+ val Line: int
+ val Column: int
+
+ new(line: int, column: int) = { Line = line; Column = column }
+ end
+
type FormatSelectionRequest =
{
SourceCode: string
@@ -60,14 +64,11 @@ and FormatSelectionRange =
end
type FantomasResponse =
- {
- Code: int
- FilePath: string
- Content: string option
- /// The actual range that was used to format a selection.
- /// This can differ from the input selection range if the selection had leading or trailing whitespace.
- SelectedRange: FormatSelectionRange option
- }
+ { Code: int
+ FilePath: string
+ Content: string option
+ SelectedRange: FormatSelectionRange option
+ Cursor: FormatCursorPosition option }
type FantomasService =
interface
diff --git a/src/Fantomas.Client/Contracts.fsi b/src/Fantomas.Client/Contracts.fsi
index a0afbbde0a..c94e5a73dc 100644
--- a/src/Fantomas.Client/Contracts.fsi
+++ b/src/Fantomas.Client/Contracts.fsi
@@ -28,10 +28,21 @@ type FormatDocumentRequest =
/// Overrides the found .editorconfig.
Config: IReadOnlyDictionary option
+
+ /// The current position of the cursor.
+ /// Zero-based
+ Cursor: FormatCursorPosition option
}
member IsSignatureFile: bool
+and FormatCursorPosition =
+ class
+ new: line: int * column: int -> FormatCursorPosition
+ val Line: int
+ val Column: int
+ end
+
type FormatSelectionRequest =
{
SourceCode: string
@@ -67,6 +78,10 @@ type FantomasResponse =
/// The actual range that was used to format a selection.
/// This can differ from the input selection range if the selection had leading or trailing whitespace.
SelectedRange: FormatSelectionRange option
+
+ /// Cursor position after formatting.
+ /// Zero-based.
+ Cursor: FormatCursorPosition option
}
type FantomasService =
diff --git a/src/Fantomas.Client/LSPFantomasService.fs b/src/Fantomas.Client/LSPFantomasService.fs
index 575c62428f..b99dbf3e1b 100644
--- a/src/Fantomas.Client/LSPFantomasService.fs
+++ b/src/Fantomas.Client/LSPFantomasService.fs
@@ -4,6 +4,7 @@ open System
open System.IO
open System.Threading
open System.Threading.Tasks
+open Newtonsoft.Json.Linq
open StreamJsonRpc
open Fantomas.Client.Contracts
open Fantomas.Client.LSPFantomasServiceTypes
@@ -167,14 +168,16 @@ let private fileNotFoundResponse filePath : Task =
{ Code = int FantomasResponseCode.FileNotFound
FilePath = filePath
Content = Some $"File \"%s{filePath}\" does not exist."
- SelectedRange = None }
+ SelectedRange = None
+ Cursor = None }
|> Task.FromResult
let private fileNotAbsoluteResponse filePath : Task =
{ Code = int FantomasResponseCode.FilePathIsNotAbsolute
FilePath = filePath
Content = Some $"\"%s{filePath}\" is not an absolute file path. Relative paths are not supported."
- SelectedRange = None }
+ SelectedRange = None
+ Cursor = None }
|> Task.FromResult
let private daemonNotFoundResponse filePath (error: GetDaemonError) : Task =
@@ -214,14 +217,16 @@ let private daemonNotFoundResponse filePath (error: GetDaemonError) : Task Task.FromResult
let private cancellationWasRequestedResponse filePath : Task =
{ Code = int FantomasResponseCode.CancellationWasRequested
FilePath = filePath
Content = Some "FantomasService is being or has been disposed."
- SelectedRange = None }
+ SelectedRange = None
+ Cursor = None }
|> Task.FromResult
let mapResultToResponse (filePath: string) (result: Result, FantomasServiceError>) =
@@ -232,6 +237,102 @@ let mapResultToResponse (filePath: string) (result: Result daemonNotFoundResponse filePath e
| Error FantomasServiceError.CancellationWasRequested -> cancellationWasRequestedResponse filePath
+///
+///
+/// The Fantomas daemon currently sends a Fantomas.Client.LSPFantomasServiceTypes.FormatDocumentResponse back to Fantomas.Client.
+/// This was a poor choice as the serialization of a DU case breaks when you add a new field to it. Even though that field is optional.
+/// To overcome this, we deserialize the FormatDocumentResponse ourselves to construct the matching FantomasResponse.
+///
+///
+/// In v6.0 we introduced an additional option field to FormatDocumentResponse.Formatted being the cursor position.
+/// That is why we currently have two match cases that try to deserialize "Formatted".
+///
+///
+/// When serialization fails, we re-use the input file path from the request information.
+/// The raw JObject that send sent over the wire.
+let decodeFormatResult (inputFilePath: string) (json: JObject) : FantomasResponse =
+ let mkError msg =
+ { Code = int FantomasResponseCode.Error
+ FilePath = inputFilePath
+ Content = Some msg
+ SelectedRange = None
+ Cursor = None }
+
+ try
+ if not (json.ContainsKey("Case")) || not (json.ContainsKey("Fields")) then
+ mkError "Expected \"Case\" and \"Fields\" to be present in the response json"
+ else
+ let caseName = json.["Case"].Value()
+ let fields = json.["Fields"].Value()
+
+ match caseName with
+ | "Formatted" when fields.Count = 2 ->
+ let fileName = fields.[0].Value()
+ let formattedContent = fields.[1].Value()
+
+ { Code = int FantomasResponseCode.Formatted
+ FilePath = fileName
+ Content = Some formattedContent
+ SelectedRange = None
+ Cursor = None }
+ | "Formatted" when fields.Count = 3 ->
+ let fileName = fields.[0].Value()
+ let formattedContent = fields.[1].Value()
+
+ let cursor =
+ if fields.[2].Type = JTokenType.Null then
+ None
+ else
+ // This is wrapped as an option, the Case is "Some" here.
+ // We need to extract the Line and Column from the first item in Fields
+ let cursorObject = fields.[2].Value()
+ let cursorObject = cursorObject.["Fields"].[0].Value()
+
+ Some(
+ FormatCursorPosition(
+ cursorObject.["Line"].Value(),
+ cursorObject.["Column"].Value()
+ )
+ )
+
+ { Code = int FantomasResponseCode.Formatted
+ FilePath = fileName
+ Content = Some formattedContent
+ SelectedRange = None
+ Cursor = cursor }
+
+ | "Unchanged" when fields.Count = 1 ->
+ let fileName = fields.[0].Value()
+
+ { Code = int FantomasResponseCode.UnChanged
+ FilePath = fileName
+ Content = None
+ SelectedRange = None
+ Cursor = None }
+ | "Error" when fields.Count = 2 ->
+ let fileName = fields.[0].Value()
+ let formattingError = fields.[1].Value()
+
+ { Code = int FantomasResponseCode.Error
+ FilePath = fileName
+ Content = Some formattingError
+ SelectedRange = None
+ Cursor = None }
+ | "IgnoredFile" when fields.Count = 1 ->
+ let fileName = fields.[0].Value()
+
+ { Code = int FantomasResponseCode.Ignored
+ FilePath = fileName
+ Content = None
+ SelectedRange = None
+ Cursor = None }
+ | _ ->
+ mkError
+ $"Could not deserialize the message from the daemon, got unexpected case name %s{caseName} with %i{fields.Count} fields."
+
+ with ex ->
+ mkError $"Could not deserialize the message from the daemon, %s{ex.Message}"
+
type LSPFantomasService() =
let cts = new CancellationTokenSource()
let agent = createAgent cts.Token
@@ -239,7 +340,7 @@ type LSPFantomasService() =
interface FantomasService with
member this.Dispose() =
if not cts.IsCancellationRequested then
- agent.PostAndReply Reset
+ let _ = agent.PostAndReply Reset
cts.Cancel()
member _.VersionAsync(filePath, ?cancellationToken: CancellationToken) : Task =
@@ -256,7 +357,8 @@ type LSPFantomasService() =
{ Code = int FantomasResponseCode.Version
Content = Some t.Result
FilePath = filePath
- SelectedRange = None }))
+ SelectedRange = None
+ Cursor = None }))
|> mapResultToResponse filePath
member _.FormatDocumentAsync
@@ -269,12 +371,12 @@ type LSPFantomasService() =
|> Result.bind (getDaemon agent)
|> Result.map (fun client ->
client
- .InvokeWithParameterObjectAsync(
+ .InvokeWithParameterObjectAsync(
Methods.FormatDocument,
argument = formatDocumentOptions,
cancellationToken = Option.defaultValue cts.Token cancellationToken
)
- .ContinueWith(fun (t: Task) -> t.Result.AsFormatResponse()))
+ .ContinueWith(fun (t: Task) -> decodeFormatResult formatDocumentOptions.FilePath t.Result))
|> mapResultToResponse formatDocumentOptions.FilePath
member _.FormatSelectionAsync
@@ -310,7 +412,8 @@ type LSPFantomasService() =
{ Code = int FantomasResponseCode.Configuration
FilePath = filePath
Content = Some t.Result
- SelectedRange = None }))
+ SelectedRange = None
+ Cursor = None }))
|> mapResultToResponse filePath
member _.ClearCache() = agent.PostAndReply Reset
diff --git a/src/Fantomas.Client/LSPFantomasServiceTypes.fs b/src/Fantomas.Client/LSPFantomasServiceTypes.fs
index a0f3376acb..7505e3b22d 100644
--- a/src/Fantomas.Client/LSPFantomasServiceTypes.fs
+++ b/src/Fantomas.Client/LSPFantomasServiceTypes.fs
@@ -29,43 +29,22 @@ type FormatSelectionResponse =
{ Code = int FantomasResponseCode.Formatted
FilePath = name
Content = Some content
- SelectedRange = Some formattedRange }
+ SelectedRange = Some formattedRange
+ Cursor = None }
| FormatSelectionResponse.Error(name, ex) ->
{ Code = int FantomasResponseCode.Error
FilePath = name
Content = Some ex
- SelectedRange = None }
+ SelectedRange = None
+ Cursor = None }
[]
type FormatDocumentResponse =
- | Formatted of filename: string * formattedContent: string
+ | Formatted of filename: string * formattedContent: string * cursor: FormatCursorPosition option
| Unchanged of filename: string
| Error of filename: string * formattingError: string
| IgnoredFile of filename: string
- member this.AsFormatResponse() =
- match this with
- | FormatDocumentResponse.Formatted(name, content) ->
- { Code = int FantomasResponseCode.Formatted
- FilePath = name
- Content = Some content
- SelectedRange = None }
- | FormatDocumentResponse.Unchanged name ->
- { Code = int FantomasResponseCode.UnChanged
- FilePath = name
- Content = None
- SelectedRange = None }
- | FormatDocumentResponse.Error(name, err) ->
- { Code = int FantomasResponseCode.Error
- FilePath = name
- Content = Some(err)
- SelectedRange = None }
- | FormatDocumentResponse.IgnoredFile name ->
- { Code = int FantomasResponseCode.Ignored
- FilePath = name
- Content = None
- SelectedRange = None }
-
type FantomasVersion = FantomasVersion of string
type FantomasExecutableFile = FantomasExecutableFile of string
type Folder = Folder of path: string
diff --git a/src/Fantomas.Client/LSPFantomasServiceTypes.fsi b/src/Fantomas.Client/LSPFantomasServiceTypes.fsi
index 075430f02e..8dedde8b4e 100644
--- a/src/Fantomas.Client/LSPFantomasServiceTypes.fsi
+++ b/src/Fantomas.Client/LSPFantomasServiceTypes.fsi
@@ -24,13 +24,11 @@ type FormatSelectionResponse =
[]
type FormatDocumentResponse =
- | Formatted of filename: string * formattedContent: string
+ | Formatted of filename: string * formattedContent: string * cursor: FormatCursorPosition option
| Unchanged of filename: string
| Error of filename: string * formattingError: string
| IgnoredFile of filename: string
- member AsFormatResponse: unit -> FantomasResponse
-
type FantomasVersion = FantomasVersion of string
type FantomasExecutableFile = FantomasExecutableFile of string
diff --git a/src/Fantomas.Core.Tests/ASTTransformerTests.fs b/src/Fantomas.Core.Tests/ASTTransformerTests.fs
index 4ba6ec85af..1afdff97a3 100644
--- a/src/Fantomas.Core.Tests/ASTTransformerTests.fs
+++ b/src/Fantomas.Core.Tests/ASTTransformerTests.fs
@@ -6,7 +6,6 @@ open FSharp.Compiler.Xml
open FSharp.Compiler.Syntax
open FSharp.Compiler.SyntaxTrivia
open Fantomas.Core
-open Fantomas.Core.FormatConfig
[]
let ``avoid stack-overflow in long array/list, 2485`` () =
diff --git a/src/Fantomas.Core.Tests/MultilineBlockBracketsOnSameColumnArrayOrListTests.fs b/src/Fantomas.Core.Tests/AlignedMultilineBracketStyleArrayOrListTests.fs
similarity index 98%
rename from src/Fantomas.Core.Tests/MultilineBlockBracketsOnSameColumnArrayOrListTests.fs
rename to src/Fantomas.Core.Tests/AlignedMultilineBracketStyleArrayOrListTests.fs
index 64bc6f0bc3..56f215d4e0 100644
--- a/src/Fantomas.Core.Tests/MultilineBlockBracketsOnSameColumnArrayOrListTests.fs
+++ b/src/Fantomas.Core.Tests/AlignedMultilineBracketStyleArrayOrListTests.fs
@@ -1,9 +1,9 @@
-module Fantomas.Core.Tests.MultilineBlockBracketsOnSameColumnArrayOrListTests
+module Fantomas.Core.Tests.AlignedMultilineBracketStyleArrayOrListTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
diff --git a/src/Fantomas.Core.Tests/MultilineBlockBracketsOnSameColumnRecordTests.fs b/src/Fantomas.Core.Tests/AlignedMultilineBracketStyleTests.fs
similarity index 90%
rename from src/Fantomas.Core.Tests/MultilineBlockBracketsOnSameColumnRecordTests.fs
rename to src/Fantomas.Core.Tests/AlignedMultilineBracketStyleTests.fs
index 8d89f76448..8752786b19 100644
--- a/src/Fantomas.Core.Tests/MultilineBlockBracketsOnSameColumnRecordTests.fs
+++ b/src/Fantomas.Core.Tests/AlignedMultilineBracketStyleTests.fs
@@ -1,9 +1,9 @@
-module Fantomas.Core.Tests.MultilineBlockBracketsOnSameColumnRecordTests
+module Fantomas.Core.Tests.AlignedMultilineBracketStyleTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
@@ -1182,6 +1182,29 @@ type Foo =
static member Baz : int
"""
+[]
+let ``record type definition with members and trivia`` () =
+ formatSourceString
+ false
+ """
+type X = {
+ Y : int
+} with // foo
+ member x.Z = ()
+"""
+ { config with
+ NewlineBetweenTypeDefinitionAndMembers = false }
+ |> prepend newline
+ |> should
+ equal
+ """
+type X =
+ {
+ Y : int
+ } // foo
+ member x.Z = ()
+"""
+
[]
let ``anonymous records with comments on record fields`` () =
formatSourceString
@@ -1456,3 +1479,117 @@ let a =
// test2
|}
"""
+
+[]
+let ``equality comparison with a `with` expression should format correctly with Allman alignment, 2507`` () =
+ formatSourceString
+ false
+ """
+let compareThings (first: Thing) (second: Thing) =
+ first = { second with
+ Foo = first.Foo
+ Bar = first.Bar
+ }
+"""
+ { config with
+ MultilineBracketStyle = Aligned }
+ |> prepend newline
+ |> should
+ equal
+ """
+let compareThings (first : Thing) (second : Thing) =
+ first = { second with
+ Foo = first.Foo
+ Bar = first.Bar
+ }
+"""
+
+// `Aligned` copy-and-update expression keeps label on first line to match G-Research style guide.
+// See https://github.com/G-Research/fsharp-formatting-conventions#formatting-copy-and-update-record-expressions
+[]
+let ``update record in aligned style`` () =
+ formatSourceString
+ false
+ """
+// standalone
+{ rainbow with Boss = "Jeffrey" ; Lackeys = [ "Zippy"; "George"; "Bungle" ] }
+
+// binding expression
+let v = { rainbow with Boss = "Jeffrey" ; Lackeys = [ "Zippy"; "George"; "Bungle" ] }
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+// standalone
+{ rainbow with
+ Boss = "Jeffrey"
+ Lackeys = [ "Zippy" ; "George" ; "Bungle" ]
+}
+
+// binding expression
+let v =
+ { rainbow with
+ Boss = "Jeffrey"
+ Lackeys = [ "Zippy" ; "George" ; "Bungle" ]
+ }
+"""
+
+// In contrast, Stroustrup will indent the entire record body when the record is placed standalone.
+[]
+let ``update record in stroustrup style`` () =
+ formatSourceString
+ false
+ """
+// standalone
+{ rainbow with Boss = "Jeffrey" ; Lackeys = [ "Zippy"; "George"; "Bungle" ] }
+
+// binding expression
+let v = { rainbow with Boss = "Jeffrey" ; Lackeys = [ "Zippy"; "George"; "Bungle" ] }
+"""
+ { config with
+ MultilineBracketStyle = Stroustrup }
+ |> prepend newline
+ |> should
+ equal
+ """
+// standalone
+{
+ rainbow with
+ Boss = "Jeffrey"
+ Lackeys = [ "Zippy" ; "George" ; "Bungle" ]
+}
+
+// binding expression
+let v = {
+ rainbow with
+ Boss = "Jeffrey"
+ Lackeys = [ "Zippy" ; "George" ; "Bungle" ]
+}
+"""
+
+[]
+let ``anonymous struct record with trivia`` () =
+ formatSourceString
+ false
+ """
+struct // 1
+ {| // 2
+ // 3
+ X = 4
+ // 5
+ |} // 6
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+struct // 1
+ {| // 2
+ // 3
+ X = 4
+ // 5
+ |} // 6
+"""
diff --git a/src/Fantomas.Core.Tests/CodePrinterHelperFunctionsTests.fs b/src/Fantomas.Core.Tests/CodePrinterHelperFunctionsTests.fs
index 3e127072ac..464a6e64a0 100644
--- a/src/Fantomas.Core.Tests/CodePrinterHelperFunctionsTests.fs
+++ b/src/Fantomas.Core.Tests/CodePrinterHelperFunctionsTests.fs
@@ -3,7 +3,6 @@ module Fantomas.Core.Tests.CodePrinterHelperFunctionsTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Context
-open Fantomas.Core.FormatConfig
open Fantomas.Core
open Fantomas.Core.SyntaxOak
@@ -12,7 +11,7 @@ open Fantomas.Core.SyntaxOak
// It might help for some things to "click".
/// Transform the WriterEvents in a Context to a string
-let private dump (context: Context) : string = dump false context
+let private dump (context: Context) : string = (dump false context).Code
[]
let ``!- add a single WriterEvent.Write`` () =
diff --git a/src/Fantomas.Core.Tests/ColMultilineItemTests.fs b/src/Fantomas.Core.Tests/ColMultilineItemTests.fs
index 1c5a97b2d5..adfcd6cc42 100644
--- a/src/Fantomas.Core.Tests/ColMultilineItemTests.fs
+++ b/src/Fantomas.Core.Tests/ColMultilineItemTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.ColMultilineItemTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
[]
let ``two short let binding should not have extra newline`` () =
diff --git a/src/Fantomas.Core.Tests/CommentTests.fs b/src/Fantomas.Core.Tests/CommentTests.fs
index eeb5e5cbc3..d79bc43650 100644
--- a/src/Fantomas.Core.Tests/CommentTests.fs
+++ b/src/Fantomas.Core.Tests/CommentTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.CommentTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
[]
let ``should keep sticky-to-the-left comments after nowarn directives`` () =
diff --git a/src/Fantomas.Core.Tests/ComputationExpressionTests.fs b/src/Fantomas.Core.Tests/ComputationExpressionTests.fs
index f8c799bd1c..a0a2b8ed2f 100644
--- a/src/Fantomas.Core.Tests/ComputationExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/ComputationExpressionTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.ComputationExpressionTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
[]
let ``async workflows`` () =
diff --git a/src/Fantomas.Core.Tests/ContextTests.fs b/src/Fantomas.Core.Tests/ContextTests.fs
index b1e15f07ae..8091953711 100644
--- a/src/Fantomas.Core.Tests/ContextTests.fs
+++ b/src/Fantomas.Core.Tests/ContextTests.fs
@@ -4,10 +4,9 @@ open NUnit.Framework
open FsUnit
open Fantomas.Core.Context
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
open Fantomas.Core
-let private dump = dump false
+let private dump ctx = (dump false ctx).Code
[]
let ``sepSpace should not add an additional space if the line ends with a space`` () =
diff --git a/src/Fantomas.Core.Tests/ControlStructureTests.fs b/src/Fantomas.Core.Tests/ControlStructureTests.fs
index 6f2cd2ff05..8b4556fe47 100644
--- a/src/Fantomas.Core.Tests/ControlStructureTests.fs
+++ b/src/Fantomas.Core.Tests/ControlStructureTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.ControlStructureTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
[]
let ``if/then/else block`` () =
diff --git a/src/Fantomas.Core.Tests/RecordTests.fs b/src/Fantomas.Core.Tests/CrampedMultilineBracketStyleTests.fs
similarity index 98%
rename from src/Fantomas.Core.Tests/RecordTests.fs
rename to src/Fantomas.Core.Tests/CrampedMultilineBracketStyleTests.fs
index 675fcbf368..4d22cff4e6 100644
--- a/src/Fantomas.Core.Tests/RecordTests.fs
+++ b/src/Fantomas.Core.Tests/CrampedMultilineBracketStyleTests.fs
@@ -1,9 +1,9 @@
-module Fantomas.Core.Tests.RecordTests
+module Fantomas.Core.Tests.CrampedMultilineBracketStyleTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
[]
let ``record declaration`` () =
@@ -656,6 +656,41 @@ let person =
()
"
+[]
+let ``multiline string before closing brace with anonymous record`` () =
+ formatSourceString
+ false
+ "
+let person =
+ let y =
+ let x =
+ {| Story = \"\"\"
+ foo
+ bar
+\"\"\"
+ |}
+ ()
+ ()
+"
+ config
+ |> prepend newline
+ |> should
+ equal
+ "
+let person =
+ let y =
+ let x =
+ {| Story =
+ \"\"\"
+ foo
+ bar
+\"\"\" |}
+
+ ()
+
+ ()
+"
+
[]
let ``issue 457`` () =
formatSourceString
@@ -1041,6 +1076,27 @@ type Foo =
member this.Foo() = ()
"""
+[]
+let ``record type definition with members and trivia`` () =
+ formatSourceString
+ false
+ """
+type X = {
+ Y: int
+} with // foo
+ member x.Z = ()
+"""
+ { config with
+ NewlineBetweenTypeDefinitionAndMembers = false }
+ |> prepend newline
+ |> should
+ equal
+ """
+type X =
+ { Y: int } // foo
+ member x.Z = ()
+"""
+
[]
let ``short anonymous record with two members`` () =
formatSourceString
@@ -1686,8 +1742,8 @@ let ``record with comments above field, indent 2`` () =
equal
"""
{ Foo =
- // bar
- someValue }
+ // bar
+ someValue }
"""
[]
@@ -1743,8 +1799,8 @@ let ``anonymous record with multiline field, indent 2`` () =
equal
"""
{| Foo =
- // meh
- someValue |}
+ // meh
+ someValue |}
"""
[]
@@ -2124,30 +2180,6 @@ let compareThings (first: Thing) (second: Thing) =
Bar = first.Bar }
"""
-[]
-let ``equality comparison with a `with` expression should format correctly with Allman alignment, 2507`` () =
- formatSourceString
- false
- """
-let compareThings (first: Thing) (second: Thing) =
- first = { second with
- Foo = first.Foo
- Bar = first.Bar
- }
-"""
- { config with
- MultilineBracketStyle = Aligned }
- |> prepend newline
- |> should
- equal
- """
-let compareThings (first: Thing) (second: Thing) =
- first = { second with
- Foo = first.Foo
- Bar = first.Bar
- }
-"""
-
[]
let ``multiline record field type annotation`` () =
formatSourceString
diff --git a/src/Fantomas.Core.Tests/CursorTests.fs b/src/Fantomas.Core.Tests/CursorTests.fs
new file mode 100644
index 0000000000..08d645e1e0
--- /dev/null
+++ b/src/Fantomas.Core.Tests/CursorTests.fs
@@ -0,0 +1,46 @@
+module Fantomas.Core.Tests.CursorTests
+
+open FSharp.Compiler.Text
+open NUnit.Framework
+open FsUnit
+open Fantomas.Core
+
+let formatWithCursor source (line, column) =
+ CodeFormatter.FormatDocumentAsync(false, source, FormatConfig.Default, CodeFormatter.MakePosition(line, column))
+ |> Async.RunSynchronously
+
+let assertCursor (expectedLine: int, expectedColumn: int) (result: FormatResult) : unit =
+ match result.Cursor with
+ | None -> Assert.Fail "Expected a cursor"
+ | Some cursor -> Assert.AreEqual(Position.mkPos expectedLine expectedColumn, cursor)
+
+[]
+let ``cursor inside of a node`` () =
+ formatWithCursor
+ """
+let a =
+ "foobar"
+"""
+ (3, 8)
+ |> assertCursor (1, 12)
+
+[]
+let ``cursor outside of a node`` () =
+ formatWithCursor
+ """
+let a =
+ ()
+"""
+ (3, 7)
+ |> assertCursor (1, 11)
+
+[]
+let ``cursor inside a node between defines`` () =
+ formatWithCursor
+ """
+#if FOO
+ ()
+#endif
+"""
+ (3, 4)
+ |> assertCursor (2, 0)
diff --git a/src/Fantomas.Core.Tests/DallasTests.fs b/src/Fantomas.Core.Tests/DallasTests.fs
index ed5e27e7a7..2ecbbc8ddd 100644
--- a/src/Fantomas.Core.Tests/DallasTests.fs
+++ b/src/Fantomas.Core.Tests/DallasTests.fs
@@ -3,7 +3,7 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
[]
let ``proof of concept`` () =
@@ -1857,7 +1857,7 @@ let someTest input1 input2 =
}
"""
{ config with
- MultilineBracketStyle = ExperimentalStroustrup }
+ MultilineBracketStyle = Stroustrup }
|> prepend newline
|> should
equal
diff --git a/src/Fantomas.Core.Tests/DefinesTests.fs b/src/Fantomas.Core.Tests/DefinesTests.fs
index 622f441c59..a79c97bba3 100644
--- a/src/Fantomas.Core.Tests/DefinesTests.fs
+++ b/src/Fantomas.Core.Tests/DefinesTests.fs
@@ -17,7 +17,7 @@ let private getDefines (v: string) =
| ParsedInput.SigFile(ParsedSigFileInput(trivia = { ConditionalDirectives = directives })) -> directives
getDefineCombination hashDirectives
- |> List.collect id
+ |> List.collect (fun (DefineCombination(defines)) -> defines)
|> List.distinct
|> List.sort
diff --git a/src/Fantomas.Core.Tests/DotGetTests.fs b/src/Fantomas.Core.Tests/DotGetTests.fs
index 4b7545d2d5..227c2eb507 100644
--- a/src/Fantomas.Core.Tests/DotGetTests.fs
+++ b/src/Fantomas.Core.Tests/DotGetTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.DotGetTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
[]
let ``a TypeApp inside a DotGet should stay on the same line, 994`` () =
diff --git a/src/Fantomas.Core.Tests/DotIndexedGetTests.fs b/src/Fantomas.Core.Tests/DotIndexedGetTests.fs
index d4a61345b6..67375ac7a2 100644
--- a/src/Fantomas.Core.Tests/DotIndexedGetTests.fs
+++ b/src/Fantomas.Core.Tests/DotIndexedGetTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.DotIndexedGetTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
[]
let ``multiline function application inside DotIndexedGet`` () =
diff --git a/src/Fantomas.Core.Tests/ExternTests.fs b/src/Fantomas.Core.Tests/ExternTests.fs
index cb7f8d00d8..8d618d18fe 100644
--- a/src/Fantomas.Core.Tests/ExternTests.fs
+++ b/src/Fantomas.Core.Tests/ExternTests.fs
@@ -6,14 +6,14 @@ open Fantomas.Core.Tests.TestHelper
[]
let ``attribute above extern keyword, 562`` () =
- formatSourceString
+ formatAST
false
"""
module C =
[]
extern IntPtr f()
"""
- { config with StrictMode = true }
+ config
|> prepend newline
|> should
equal
diff --git a/src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj b/src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj
index cf34cd5094..b0cb713268 100644
--- a/src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj
+++ b/src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj
@@ -21,7 +21,7 @@
-
+
@@ -35,6 +35,7 @@
+
@@ -57,8 +58,8 @@
-
-
+
+
@@ -104,9 +105,11 @@
-
+
+
+
@@ -121,6 +124,8 @@
+
+
diff --git a/src/Fantomas.Core.Tests/FormattingSelectionOnlyTests.fs b/src/Fantomas.Core.Tests/FormattingSelectionOnlyTests.fs
index 2144cd579d..17ec4e6cf0 100644
--- a/src/Fantomas.Core.Tests/FormattingSelectionOnlyTests.fs
+++ b/src/Fantomas.Core.Tests/FormattingSelectionOnlyTests.fs
@@ -6,7 +6,7 @@ open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-let private config = FormatConfig.FormatConfig.Default
+let private config = FormatConfig.Default
let private formatSelectionOnly isFsiFile selection (source: string) config =
let formattedSelection, _ =
diff --git a/src/Fantomas.Core.Tests/InterpolatedStringTests.fs b/src/Fantomas.Core.Tests/InterpolatedStringTests.fs
index 468e4fcef2..e3b20c67b1 100644
--- a/src/Fantomas.Core.Tests/InterpolatedStringTests.fs
+++ b/src/Fantomas.Core.Tests/InterpolatedStringTests.fs
@@ -1,6 +1,5 @@
module Fantomas.Core.Tests.InterpolatedStringTests
-open FSharp.Compiler.Text
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
@@ -64,13 +63,13 @@ let s = $\"\"\"%s{text} bar\"\"\"
[]
let ``interpolation in strict mode`` () =
- formatSourceString
+ formatAST
false
"""
let text = "foo"
let s = $"%s{text} bar"
"""
- { config with StrictMode = true }
+ config
|> prepend newline
|> should
equal
diff --git a/src/Fantomas.Core.Tests/KeepIndentInBranchTests.fs b/src/Fantomas.Core.Tests/KeepIndentInBranchTests.fs
index e16bbedd44..a1234ba95d 100644
--- a/src/Fantomas.Core.Tests/KeepIndentInBranchTests.fs
+++ b/src/Fantomas.Core.Tests/KeepIndentInBranchTests.fs
@@ -3,7 +3,7 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
diff --git a/src/Fantomas.Core.Tests/KeepMaxEmptyLinesTests.fs b/src/Fantomas.Core.Tests/KeepMaxEmptyLinesTests.fs
index 7bbf472736..22aa8e2184 100644
--- a/src/Fantomas.Core.Tests/KeepMaxEmptyLinesTests.fs
+++ b/src/Fantomas.Core.Tests/KeepMaxEmptyLinesTests.fs
@@ -3,7 +3,7 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let checkFormat config source expected =
formatSourceString false source config
diff --git a/src/Fantomas.Core.Tests/LambdaTests.fs b/src/Fantomas.Core.Tests/LambdaTests.fs
index 2b667a0ce7..96d2ee5ac2 100644
--- a/src/Fantomas.Core.Tests/LambdaTests.fs
+++ b/src/Fantomas.Core.Tests/LambdaTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.LambdaTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
[]
let ``keep comment after arrow`` () =
diff --git a/src/Fantomas.Core.Tests/LetBindingTests.fs b/src/Fantomas.Core.Tests/LetBindingTests.fs
index eb2813c9b3..cf7262cabb 100644
--- a/src/Fantomas.Core.Tests/LetBindingTests.fs
+++ b/src/Fantomas.Core.Tests/LetBindingTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.LetBindingTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
[]
let ``let in should be preserved`` () =
diff --git a/src/Fantomas.Core.Tests/ListTests.fs b/src/Fantomas.Core.Tests/ListTests.fs
index 7b7c4bb2b9..73d21d804b 100644
--- a/src/Fantomas.Core.Tests/ListTests.fs
+++ b/src/Fantomas.Core.Tests/ListTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.ListTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
[]
let ``array indices`` () =
diff --git a/src/Fantomas.Core.Tests/ModuleTests.fs b/src/Fantomas.Core.Tests/ModuleTests.fs
index 5f2098ee4f..64217fcb98 100644
--- a/src/Fantomas.Core.Tests/ModuleTests.fs
+++ b/src/Fantomas.Core.Tests/ModuleTests.fs
@@ -393,7 +393,7 @@ type T() =
CodeFormatter.FormatDocumentAsync(false, sourceCode, config)
|> Async.RunSynchronously
- |> fun s -> s.Replace("\r\n", "\n")
+ |> fun s -> s.Code.Replace("\r\n", "\n")
|> should
equal
"""open System
diff --git a/src/Fantomas.Core.Tests/MultiLineLambdaClosingNewlineTests.fs b/src/Fantomas.Core.Tests/MultiLineLambdaClosingNewlineTests.fs
index 99d23671d1..7e236f9f6d 100644
--- a/src/Fantomas.Core.Tests/MultiLineLambdaClosingNewlineTests.fs
+++ b/src/Fantomas.Core.Tests/MultiLineLambdaClosingNewlineTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.MultiLineLambdaClosingNewlineTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let defaultConfig = config
diff --git a/src/Fantomas.Core.Tests/MultipleDefineCombinationsTests.fs b/src/Fantomas.Core.Tests/MultipleDefineCombinationsTests.fs
new file mode 100644
index 0000000000..13f8febc01
--- /dev/null
+++ b/src/Fantomas.Core.Tests/MultipleDefineCombinationsTests.fs
@@ -0,0 +1,194 @@
+module Fantomas.Core.Tests.MultipleDefineCombinationsTests
+
+open NUnit.Framework
+open Fantomas.Core
+open Fantomas.Core.Tests.TestHelper
+
+let private mergeAndCompare (aDefines, aCode) (bDefines, bCode) expected =
+ let result =
+ MultipleDefineCombinations.mergeMultipleFormatResults
+ { config with
+ EndOfLine = EndOfLineStyle.LF }
+ [ DefineCombination(aDefines),
+ { Code = String.normalizeNewLine aCode
+ Cursor = None }
+ DefineCombination(bDefines),
+ { Code = String.normalizeNewLine bCode
+ Cursor = None } ]
+
+ let normalizedExpected = String.normalizeNewLine expected
+ normalizedExpected == result.Code
+
+[]
+let ``merging of source code that starts with a hash`` () =
+ let a =
+ """#if NOT_DEFINED
+ printfn \"meh\"
+#else
+
+#endif
+"""
+
+ let b =
+ """#if NOT_DEFINED
+
+#else
+ printfn \"foo\"
+#endif
+"""
+
+ """#if NOT_DEFINED
+ printfn \"meh\"
+#else
+ printfn \"foo\"
+#endif
+"""
+ |> mergeAndCompare ([], a) ([ "NOT_DEFINED" ], b)
+
+[]
+let ``merging of defines content work when source code starts with a newline`` () =
+ let a =
+ """
+[]
+let private assemblyConfig() =
+ #if TRACE
+
+ #else
+ let x = "x"
+ #endif
+ x
+"""
+
+ let b =
+ """
+[]
+let private assemblyConfig() =
+ #if TRACE
+ let x = ""
+ #else
+
+ #endif
+ x
+"""
+
+ """
+[]
+let private assemblyConfig() =
+#if TRACE
+ let x = ""
+#else
+ let x = "x"
+#endif
+ x
+"""
+ |> mergeAndCompare ([], a) ([ "TRACE" ], b)
+
+[]
+let ``only split on control structure keyword`` () =
+ let a =
+ """
+#if INTERACTIVE
+#else
+#load "../FSharpx.TypeProviders/SetupTesting.fsx"
+
+SetupTesting.generateSetupScript __SOURCE_DIRECTORY__
+
+#load "__setup__.fsx"
+#endif
+"""
+
+ let b =
+ """
+#if INTERACTIVE
+#else
+
+
+
+#endif
+ """
+
+ """
+#if INTERACTIVE
+#else
+#load "../FSharpx.TypeProviders/SetupTesting.fsx"
+
+SetupTesting.generateSetupScript __SOURCE_DIRECTORY__
+
+#load "__setup__.fsx"
+#endif
+"""
+ |> mergeAndCompare ([], a) ([ "INTERACTIVE" ], b)
+
+// This test illustrates the goal of MultipleDefineCombinations
+// All three results will be merged in one go.
+[]
+let ``triple merge`` () =
+ let result =
+ MultipleDefineCombinations.mergeMultipleFormatResults
+ { config with
+ EndOfLine = EndOfLineStyle.LF }
+ [ DefineCombination([]),
+ { Code =
+ String.normalizeNewLine
+ """
+let v =
+ #if A
+
+ #else
+ #if B
+
+ #else
+ 'C'
+ #endif
+ #endif
+"""
+ Cursor = None }
+ DefineCombination([ "A" ]),
+ { Code =
+ String.normalizeNewLine
+ """
+let v =
+ #if A
+ 'A'
+ #else
+ #if B
+
+ #else
+
+ #endif
+ #endif
+"""
+ Cursor = None }
+ DefineCombination([ "B" ]),
+ { Code =
+ String.normalizeNewLine
+ """
+let v =
+ #if A
+
+ #else
+ #if B
+ 'B'
+ #else
+
+ #endif
+ #endif
+"""
+ Cursor = None } ]
+
+ let expected =
+ String.normalizeNewLine
+ """
+let v =
+#if A
+ 'A'
+#else
+#if B
+ 'B'
+#else
+ 'C'
+#endif
+#endif
+"""
+
+ expected == result.Code
diff --git a/src/Fantomas.Core.Tests/NewlineBeforeMultilineComputationExpressionTests.fs b/src/Fantomas.Core.Tests/NewlineBeforeMultilineComputationExpressionTests.fs
new file mode 100644
index 0000000000..1d72f52339
--- /dev/null
+++ b/src/Fantomas.Core.Tests/NewlineBeforeMultilineComputationExpressionTests.fs
@@ -0,0 +1,724 @@
+module Fantomas.Core.Tests.NewlineBeforeMultilineComputationExpressionTests
+
+open NUnit.Framework
+open FsUnit
+open Fantomas.Core.Tests.TestHelper
+open Fantomas.Core
+
+let config =
+ { config with
+ NewlineBeforeMultilineComputationExpression = false
+ MaxArrayOrListWidth = 40 }
+
+[]
+let ``prefer computation expression name on same line`` () =
+ formatSourceString
+ false
+ """
+let t =
+ task {
+ let! thing = otherThing ()
+ return 5
+ }
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+let t = task {
+ let! thing = otherThing ()
+ return 5
+}
+"""
+
+[]
+let ``prefer computation expression name on same line handling short expression`` () =
+ formatSourceString
+ false
+ """
+let t =
+ task {
+ return ()
+ }
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+let t = task { return () }
+"""
+
+[]
+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 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 ``dotIndexedSet with computation expression`` () =
+ formatSourceString
+ false
+ """
+myMutable.[x] <-
+ task {
+ // some computation here
+ ()
+ }
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+myMutable.[x] <- task {
+ // some computation here
+ ()
+}
+"""
+
+[]
+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 ``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 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 ``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 ``lambda with computation expression`` () =
+ formatSourceString
+ false
+ """
+fun x ->
+ task {
+ // some computation here
+ ()
+ }
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+fun x -> task {
+ // some computation here
+ ()
+}
+"""
+
+[]
+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 ``longIdentSet with computation expression`` () =
+ formatSourceString
+ false
+ """
+myMutable <-
+ task {
+ // some computation here
+ ()
+ }
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+myMutable <- task {
+ // some computation here
+ ()
+}
+"""
+
+[]
+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 ``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 ``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 ``set with computation expression`` () =
+ formatSourceString
+ false
+ """
+myMutable[x] <-
+ task {
+ // some computation here
+ ()
+ }
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+myMutable[x] <- task {
+ // some computation here
+ ()
+}
+"""
+
+[]
+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 computation expression with return type`` () =
+ formatSourceString
+ false
+ """
+let x y: Task =
+ task {
+ // some computation here
+ ()
+ }
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+let x y : Task = task {
+ // some computation here
+ ()
+}
+"""
+
+[]
+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 computation expression with return type`` () =
+ 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 ``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 ``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 ``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 ``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 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 ``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 ``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 ``prefer computation expression name on same line, with trivia`` () =
+ formatSourceString
+ false
+ """
+let t =
+ //
+ task {
+ let! thing = otherThing ()
+ return 5
+ }
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+let t =
+ //
+ task {
+ let! thing = otherThing ()
+ return 5
+ }
+"""
+
+[]
+let ``fsharp_multiline_bracket_style = stroustrup has not influence`` () =
+ formatSourceString
+ false
+ """
+fun _ -> task { // foo
+ () }
+"""
+ { FormatConfig.Default with
+ MultilineBracketStyle = Stroustrup }
+ |> prepend newline
+ |> should
+ equal
+ """
+fun _ ->
+ task { // foo
+ ()
+ }
+"""
diff --git a/src/Fantomas.Core.Tests/NumberOfItemsListOrArrayTests.fs b/src/Fantomas.Core.Tests/NumberOfItemsListOrArrayTests.fs
index 628abb822e..a0d3fefdda 100644
--- a/src/Fantomas.Core.Tests/NumberOfItemsListOrArrayTests.fs
+++ b/src/Fantomas.Core.Tests/NumberOfItemsListOrArrayTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.NumberOfItemsListOrArrayTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
[]
let ``number of items sized lists are formatted properly`` () =
@@ -88,7 +88,7 @@ h [ longValueThatIsALotOfCharactersSoooooLong; longValueThatIsALotOfCharactersSo
"""
{ config with
ArrayOrListMultilineFormatter = NumberOfItems
- MultilineBracketStyle = ExperimentalStroustrup }
+ ExperimentalElmish = true }
|> prepend newline
|> should
equal
@@ -206,7 +206,7 @@ h [ longValueThatIsALotOfCharactersSoooooLong; longValueThatIsALotOfCharactersSo
"""
{ config with
ArrayOrListMultilineFormatter = NumberOfItems
- MultilineBracketStyle = ExperimentalStroustrup }
+ ExperimentalElmish = true }
|> prepend newline
|> should
equal
@@ -240,7 +240,7 @@ h [ longValueThatIsALotOfCharactersSoooooLong; longValueThatIsALotOfCharactersSo
"""
{ config with
ArrayOrListMultilineFormatter = NumberOfItems
- MultilineBracketStyle = ExperimentalStroustrup }
+ ExperimentalElmish = true }
|> prepend newline
|> should
equal
@@ -272,7 +272,7 @@ h [ longValueThatIsALotOfCharactersSoooooLong; longValueThatIsALotOfCharactersSo
"""
{ config with
ArrayOrListMultilineFormatter = NumberOfItems
- MultilineBracketStyle = ExperimentalStroustrup }
+ ExperimentalElmish = true }
|> prepend newline
|> should
equal
diff --git a/src/Fantomas.Core.Tests/NumberOfItemsRecordTests.fs b/src/Fantomas.Core.Tests/NumberOfItemsRecordTests.fs
index b882e1f54c..c03f892f58 100644
--- a/src/Fantomas.Core.Tests/NumberOfItemsRecordTests.fs
+++ b/src/Fantomas.Core.Tests/NumberOfItemsRecordTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.NumberOfItemsRecordTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
@@ -697,8 +697,8 @@ let ``indent update anonymous record fields far enough`` () =
"""
let expected =
{| ThisIsAThing.Empty with
- TheNewValue = 1
- ThatValue = 2 |}
+ TheNewValue = 1
+ ThatValue = 2 |}
"""
[]
diff --git a/src/Fantomas.Core.Tests/OpenTypeTests.fs b/src/Fantomas.Core.Tests/OpenTypeTests.fs
index c530c0f6fa..073d08fab4 100644
--- a/src/Fantomas.Core.Tests/OpenTypeTests.fs
+++ b/src/Fantomas.Core.Tests/OpenTypeTests.fs
@@ -1,6 +1,5 @@
module Fantomas.Core.Tests.OpenTypeTests
-open Fantomas
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
diff --git a/src/Fantomas.Core.Tests/OperatorTests.fs b/src/Fantomas.Core.Tests/OperatorTests.fs
index a22ab7011d..c2614a41c6 100644
--- a/src/Fantomas.Core.Tests/OperatorTests.fs
+++ b/src/Fantomas.Core.Tests/OperatorTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.OperatorTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
[]
let ``should format prefix operators`` () =
diff --git a/src/Fantomas.Core.Tests/SignatureTests.fs b/src/Fantomas.Core.Tests/SignatureTests.fs
index fa66d252ba..e182ba1829 100644
--- a/src/Fantomas.Core.Tests/SignatureTests.fs
+++ b/src/Fantomas.Core.Tests/SignatureTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.SignatureTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
// the current behavior results in a compile error since "(string * string) list" is converted to "string * string list"
[]
diff --git a/src/Fantomas.Core.Tests/SpaceBeforeClassConstructorTests.fs b/src/Fantomas.Core.Tests/SpaceBeforeClassConstructorTests.fs
index 1c744fec13..0b6e608be1 100644
--- a/src/Fantomas.Core.Tests/SpaceBeforeClassConstructorTests.fs
+++ b/src/Fantomas.Core.Tests/SpaceBeforeClassConstructorTests.fs
@@ -3,7 +3,7 @@ module Fantomas.Core.Tests.SpaceBeforeClassConstructorTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let spaceBeforeConfig =
{ config with
diff --git a/src/Fantomas.Core.Tests/StringTests.fs b/src/Fantomas.Core.Tests/StringTests.fs
index 38733e2569..f3297036fb 100644
--- a/src/Fantomas.Core.Tests/StringTests.fs
+++ b/src/Fantomas.Core.Tests/StringTests.fs
@@ -113,7 +113,7 @@ let g = '\n'
[]
let ``uncommon literals strict mode`` () =
- formatSourceString
+ formatAST
false
"""
let a = 0xFFy
@@ -123,7 +123,7 @@ let e = 1.40e10f
let f = 23.4M
let g = '\n'
"""
- { config with StrictMode = true }
+ config
|> prepend newline
|> should
equal
@@ -219,14 +219,14 @@ let ``chars should be properly escaped`` () =
[]
let ``quotes should be escaped in strict mode`` () =
- formatSourceString
+ formatAST
false
"""
let formatter =
// escape commas left in invalid entries
sprintf "%i,\"%s\""
"""
- { config with StrictMode = true }
+ config
|> should
equal
"""let formatter = sprintf "%i,\"%s\""
diff --git a/src/Fantomas.Core.Tests/Stroustrup/DotIndexedSetExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/DotIndexedSetExpressionTests.fs
index 88d69a4e49..8f881af18e 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/DotIndexedSetExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/DotIndexedSetExpressionTests.fs
@@ -3,11 +3,11 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -45,10 +45,10 @@ myMutable.[x] <-
|> should
equal
"""
-myMutable.[x] <-
- { astContext with
+myMutable.[x] <- {
+ astContext with
IsInsideMatchClausePattern = true
- }
+}
"""
[]
@@ -96,28 +96,6 @@ myMutable.[x] <- struct {|
|}
"""
-[]
-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
@@ -205,10 +183,10 @@ app().[x] <-
|> should
equal
"""
-app().[x] <-
- { astContext with
+app().[x] <- {
+ astContext with
IsInsideMatchClausePattern = true
- }
+}
"""
[]
@@ -256,28 +234,6 @@ app().[x] <- struct {|
|}
"""
-[]
-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
@@ -371,10 +327,10 @@ app(meh).[x] <-
"""
app(
meh
-).[x] <-
- { astContext with
+).[x] <- {
+ astContext with
IsInsideMatchClausePattern = true
- }
+}
"""
[]
@@ -426,30 +382,6 @@ app(
|}
"""
-[]
-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
diff --git a/src/Fantomas.Core.Tests/Stroustrup/DotSetExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/DotSetExpressionTests.fs
index e345eb9a6e..db191b34db 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/DotSetExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/DotSetExpressionTests.fs
@@ -3,11 +3,11 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -68,10 +68,10 @@ App().foo <-
|> should
equal
"""
-App().foo <-
- { astContext with
+App().foo <- {
+ astContext with
IsInsideMatchClausePattern = true
- }
+}
"""
[]
@@ -119,28 +119,6 @@ App().foo <- struct {|
|}
"""
-[]
-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
diff --git a/src/Fantomas.Core.Tests/Stroustrup/ElmishTests.fs b/src/Fantomas.Core.Tests/Stroustrup/ExperimentalElmishTests.fs
similarity index 84%
rename from src/Fantomas.Core.Tests/Stroustrup/ElmishTests.fs
rename to src/Fantomas.Core.Tests/Stroustrup/ExperimentalElmishTests.fs
index 22d60553c3..5e7d871f49 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/ElmishTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/ExperimentalElmishTests.fs
@@ -1,158 +1,13 @@
-module Fantomas.Core.Tests.ElmishTests
+module Fantomas.Core.Tests.Stroustrup.ExperimentalElmishTests
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup }
-
-[]
-let ``long named arguments should go on newline`` () =
- formatSourceString
- false
- """let view (model: Model) dispatch =
- View.ContentPage(
- appearing=(fun () -> dispatch PageAppearing),
- title=model.Planet.Info.Name,
- backgroundColor=Color.Black,
- content=["....long line....................................................................................................."]
- )
-"""
- config
- |> prepend newline
- |> should
- equal
- """
-let view (model: Model) dispatch =
- View.ContentPage(
- appearing = (fun () -> dispatch PageAppearing),
- title = model.Planet.Info.Name,
- backgroundColor = Color.Black,
- content = [
- "....long line....................................................................................................."
- ]
- )
-"""
-
-[]
-let ``single view entry`` () =
- formatSourceString
- false
- """
-let a =
- View.Entry(
- placeholder = "User name",
- isEnabled = (not model.IsSigningIn),
- textChanged = (fun args -> (dispatch (UserNameChanged args.NewTextValue))))
-"""
- config
- |> prepend newline
- |> should
- equal
- """
-let a =
- View.Entry(
- placeholder = "User name",
- isEnabled = (not model.IsSigningIn),
- textChanged = (fun args -> (dispatch (UserNameChanged args.NewTextValue)))
- )
-"""
-
-[]
-let ``fabulous view`` () =
- formatSourceString
- false
- """
- let loginPage =
- View.ContentPage(
- title = "Fabulous Demo",
- content = View.ScrollView(
- content = View.StackLayout(
- padding = 30.0,
- children = [
- View.Frame(
- verticalOptions = LayoutOptions.CenterAndExpand,
- content = View.StackLayout(children = [
- View.Entry(
- placeholder = "User name",
- isEnabled = (not model.IsSigningIn),
- textChanged = (fun args -> (dispatch (UserNameChanged args.NewTextValue))))
- View.Entry(
- placeholder = "Password",
- isPassword = true,
- isEnabled = (not model.IsSigningIn),
- textChanged = (fun args -> (dispatch (PasswordChanged args.NewTextValue))))
- View.Button(
- text = "Sign in",
- heightRequest = 30.0,
- isVisible = (not model.IsSigningIn),
- command = (fun () -> dispatch SignIn),
- canExecute = model.IsCredentialsProvided)
- View.ActivityIndicator(
- isRunning = true,
- heightRequest = 30.0,
- isVisible = model.IsSigningIn)])
- )
- ]
- )
- )
- )
-"""
- config
- |> prepend newline
- |> should
- equal
- """
-let loginPage =
- View.ContentPage(
- title = "Fabulous Demo",
- content =
- View.ScrollView(
- content =
- View.StackLayout(
- padding = 30.0,
- children = [
- View.Frame(
- verticalOptions = LayoutOptions.CenterAndExpand,
- content =
- View.StackLayout(
- children = [
- View.Entry(
- placeholder = "User name",
- isEnabled = (not model.IsSigningIn),
- textChanged =
- (fun args -> (dispatch (UserNameChanged args.NewTextValue)))
- )
- View.Entry(
- placeholder = "Password",
- isPassword = true,
- isEnabled = (not model.IsSigningIn),
- textChanged =
- (fun args -> (dispatch (PasswordChanged args.NewTextValue)))
- )
- View.Button(
- text = "Sign in",
- heightRequest = 30.0,
- isVisible = (not model.IsSigningIn),
- command = (fun () -> dispatch SignIn),
- canExecute = model.IsCredentialsProvided
- )
- View.ActivityIndicator(
- isRunning = true,
- heightRequest = 30.0,
- isVisible = model.IsSigningIn
- )
- ]
- )
- )
- ]
- )
- )
- )
-"""
+ ExperimentalElmish = true }
[]
let ``input without attributes`` () =
@@ -1048,10 +903,8 @@ let private useLocationDetail (auth0 : Auth0Hook) (roles : RolesHook) id =
match usersResult with
| Ok name -> setCreatorName (Some name)
| Error err -> JS.console.log err)),
- [|
- box roles.Roles
- box location.Creator
- |]
+ [| box roles.Roles
+ box location.Creator |]
)
location, creatorName
@@ -1355,7 +1208,7 @@ let Dashboard () =
]
"""
{ config with
- RecordMultilineFormatter = Fantomas.Core.FormatConfig.MultilineFormatterType.NumberOfItems
+ RecordMultilineFormatter = MultilineFormatterType.NumberOfItems
MaxArrayOrListWidth = 20
// MaxElmishWidth = 10
MultiLineLambdaClosingNewline = true }
@@ -1528,3 +1381,137 @@ ReactDom.render (
root
)
"""
+
+[]
+let ``record type definition and elmish dsl are controlled separately`` () =
+ formatSourceString
+ false
+ """
+type Point =
+ {
+ /// Great comment
+ X: int
+ Y: int
+ }
+
+type Model = {
+ Points: Point list
+}
+
+let view dispatch model =
+ div
+ []
+ [
+ h1 [] [ str "Some title" ]
+ ul
+ []
+ [
+ for p in model.Points do
+ li [] [ str $"%i{p.X}, %i{p.Y}" ]
+ ]
+ hr []
+ ]
+
+let stillCramped = [
+ // yow
+ x ; y ; z
+]
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+type Point =
+ {
+ /// Great comment
+ X: int
+ Y: int
+ }
+
+type Model = { Points: Point list }
+
+let view dispatch model =
+ div [] [
+ h1 [] [ str "Some title" ]
+ ul [] [
+ for p in model.Points do
+ li [] [ str $"%i{p.X}, %i{p.Y}" ]
+ ]
+ hr []
+ ]
+
+let stillCramped =
+ [
+ // yow
+ x
+ y
+ z ]
+"""
+
+[]
+let ``fsharp_multiline_bracket_style = stroustrup also applies for applications that ends with list arguments`` () =
+ formatSourceString
+ false
+ """
+type Point =
+ {
+ /// Great comment
+ X: int
+ Y: int
+ }
+
+type Model = {
+ Points: Point list
+}
+
+let view dispatch model =
+ div
+ []
+ [
+ h1 [] [ str "Some title" ]
+ ul
+ []
+ [
+ for p in model.Points do
+ li [] [ str $"%i{p.X}, %i{p.Y}" ]
+ ]
+ hr []
+ ]
+
+let alsoStroup = [
+ // yow
+ x ; y ; z
+]
+"""
+ { FormatConfig.Default with
+ MultilineBracketStyle = Stroustrup }
+ |> prepend newline
+ |> should
+ equal
+ """
+type Point = {
+ /// Great comment
+ X: int
+ Y: int
+}
+
+type Model = { Points: Point list }
+
+let view dispatch model =
+ div [] [
+ h1 [] [ str "Some title" ]
+ ul [] [
+ for p in model.Points do
+ li [] [ str $"%i{p.X}, %i{p.Y}" ]
+ ]
+ hr []
+ ]
+
+let alsoStroup = [
+ // yow
+ x
+ y
+ z
+]
+"""
diff --git a/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationDualListTests.fs b/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationDualListTests.fs
index 5bc637a864..86e6578a99 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationDualListTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationDualListTests.fs
@@ -3,11 +3,11 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup }
+ ExperimentalElmish = true }
[]
let ``two short lists`` () =
diff --git a/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationSingleListTests.fs b/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationSingleListTests.fs
index a100c73de5..9b54989810 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationSingleListTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationSingleListTests.fs
@@ -3,11 +3,11 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup }
+ ExperimentalElmish = true }
[]
let ``short function application`` () =
diff --git a/src/Fantomas.Core.Tests/Stroustrup/KeepIndentInBranchExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/KeepIndentInBranchExpressionTests.fs
index 986252a46e..55054b5833 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/KeepIndentInBranchExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/KeepIndentInBranchExpressionTests.fs
@@ -3,14 +3,14 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
// ExperimentalKeepIndentInBranch has precedence over ExperimentalStroustrupStyle
let config =
{ config with
ExperimentalKeepIndentInBranch = true
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
// There currently is no conflict with this setting, but I'm guessing the case was never brought up.
@@ -57,8 +57,9 @@ match x with
"""
match x with
| _ ->
- { astContext with
- IsInsideMatchClausePattern = true
+ {
+ astContext with
+ IsInsideMatchClausePattern = true
}
"""
diff --git a/src/Fantomas.Core.Tests/Stroustrup/LambdaExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/LambdaExpressionTests.fs
index 74b944bd77..d1c80fd6b3 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/LambdaExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/LambdaExpressionTests.fs
@@ -3,11 +3,11 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -45,10 +45,10 @@ fun x ->
|> should
equal
"""
-fun x ->
- { astContext with
+fun x -> {
+ astContext with
IsInsideMatchClausePattern = true
- }
+}
"""
[]
@@ -96,28 +96,6 @@ fun x -> struct {|
|}
"""
-[]
-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
@@ -205,10 +183,10 @@ let ``paren lambda with update record`` () =
|> should
equal
"""
-(fun x ->
- { astContext with
+(fun x -> {
+ astContext with
IsInsideMatchClausePattern = true
- })
+})
"""
[]
@@ -256,28 +234,6 @@ let ``paren lambda with anonymous record instance struct`` () =
|})
"""
-[]
-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
@@ -365,10 +321,10 @@ List.map (fun x ->
|> should
equal
"""
-List.map (fun x ->
- { astContext with
+List.map (fun x -> {
+ astContext with
IsInsideMatchClausePattern = true
- })
+})
"""
[]
@@ -416,28 +372,6 @@ List.map (fun x -> struct {|
|})
"""
-[]
-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
@@ -529,10 +463,10 @@ List.map (fun x ->
equal
"""
List.map
- (fun x ->
- { astContext with
+ (fun x -> {
+ astContext with
IsInsideMatchClausePattern = true
- })
+ })
b
c
"""
@@ -588,31 +522,6 @@ List.map
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
@@ -713,13 +622,13 @@ Bar.Foo(fun x -> { other with
equal
"""
Bar
- .Foo(fun x ->
- { other with
+ .Foo(fun x -> {
+ other with
A = longTypeName
B = someOtherVariable
C = ziggyBarX
D = evenMoreZigBarry
- })
+ })
.Bar()
"""
@@ -773,31 +682,6 @@ Bar
.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
diff --git a/src/Fantomas.Core.Tests/Stroustrup/LetOrUseBangExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/LetOrUseBangExpressionTests.fs
index e04c7b04ac..6c2eee6a1b 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/LetOrUseBangExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/LetOrUseBangExpressionTests.fs
@@ -2,12 +2,12 @@
open NUnit.Framework
open FsUnit
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
open Fantomas.Core.Tests.TestHelper
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -60,12 +60,12 @@ opt {
equal
"""
opt {
- let! foo =
- { bar with
+ let! foo = {
+ bar with
X = xFieldValueOne
Y = yFieldValueTwo
Z = zFieldValueThree
- }
+ }
()
}
@@ -131,35 +131,6 @@ opt {
}
"""
-[]
-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
diff --git a/src/Fantomas.Core.Tests/Stroustrup/LongIdentSetExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/LongIdentSetExpressionTests.fs
index f230f6db86..f4b7386886 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/LongIdentSetExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/LongIdentSetExpressionTests.fs
@@ -2,12 +2,12 @@
open NUnit.Framework
open FsUnit
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
open Fantomas.Core.Tests.TestHelper
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -45,10 +45,10 @@ myMutable <-
|> should
equal
"""
-myMutable <-
- { astContext with
+myMutable <- {
+ astContext with
IsInsideMatchClausePattern = true
- }
+}
"""
[]
@@ -96,28 +96,6 @@ myMutable <- struct {|
|}
"""
-[]
-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
diff --git a/src/Fantomas.Core.Tests/Stroustrup/MultiLineLambdaClosingNewlineExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/MultiLineLambdaClosingNewlineExpressionTests.fs
index 8540d0ca21..6cd4f24c8d 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/MultiLineLambdaClosingNewlineExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/MultiLineLambdaClosingNewlineExpressionTests.fs
@@ -3,12 +3,12 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
MultiLineLambdaClosingNewline = true
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -46,11 +46,10 @@ let ``paren lambda with update record`` () =
|> should
equal
"""
-(fun x ->
- { astContext with
+(fun x -> {
+ astContext with
IsInsideMatchClausePattern = true
- }
-)
+})
"""
[]
@@ -98,28 +97,6 @@ let ``paren lambda with anonymous record instance struct`` () =
|})
"""
-[]
-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
@@ -207,11 +184,10 @@ List.map (fun x ->
|> should
equal
"""
-List.map (fun x ->
- { astContext with
+List.map (fun x -> {
+ astContext with
IsInsideMatchClausePattern = true
- }
-)
+})
"""
[]
@@ -259,28 +235,6 @@ List.map (fun x -> struct {|
|})
"""
-[]
-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
@@ -372,11 +326,10 @@ List.map (fun x ->
equal
"""
List.map
- (fun x ->
- { astContext with
+ (fun x -> {
+ astContext with
IsInsideMatchClausePattern = true
- }
- )
+ })
b
c
"""
@@ -432,31 +385,6 @@ List.map
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
@@ -557,14 +485,13 @@ Bar.Foo(fun x -> { other with
equal
"""
Bar
- .Foo(fun x ->
- { other with
+ .Foo(fun x -> {
+ other with
A = longTypeName
B = someOtherVariable
C = ziggyBarX
D = evenMoreZigBarry
- }
- )
+ })
.Bar()
"""
@@ -618,31 +545,6 @@ Bar
.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
diff --git a/src/Fantomas.Core.Tests/Stroustrup/NamedArgumentExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/NamedArgumentExpressionTests.fs
index 716a642543..e071d88ba6 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/NamedArgumentExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/NamedArgumentExpressionTests.fs
@@ -3,11 +3,11 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -59,13 +59,13 @@ let v =
"""
let v =
SomeConstructor(
- v =
- { astContext with
+ v = {
+ astContext with
IsInsideMatchClausePattern = true
A = longTypeName
B = someOtherVariable
C = ziggyBarX
- }
+ }
)
"""
@@ -125,34 +125,6 @@ let v =
)
"""
-[]
-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
@@ -313,13 +285,13 @@ let v =
"""
let v =
new FooBar(
- v =
- { astContext with
+ v = {
+ astContext with
IsInsideMatchClausePattern = true
A = longTypeName
B = someOtherVariable
C = ziggyBarX
- }
+ }
)
"""
@@ -379,34 +351,6 @@ let v =
)
"""
-[]
-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
diff --git a/src/Fantomas.Core.Tests/Stroustrup/NamedParameterTests.fs b/src/Fantomas.Core.Tests/Stroustrup/NamedParameterTests.fs
new file mode 100644
index 0000000000..562621ac2b
--- /dev/null
+++ b/src/Fantomas.Core.Tests/Stroustrup/NamedParameterTests.fs
@@ -0,0 +1,155 @@
+module Fantomas.Core.Tests.NamedParameterTests
+
+open NUnit.Framework
+open FsUnit
+open Fantomas.Core.Tests.TestHelper
+open Fantomas.Core
+
+let config =
+ { config with
+ MultilineBracketStyle = Stroustrup }
+
+[]
+let ``long named arguments should go on newline`` () =
+ formatSourceString
+ false
+ """let view (model: Model) dispatch =
+ View.ContentPage(
+ appearing=(fun () -> dispatch PageAppearing),
+ title=model.Planet.Info.Name,
+ backgroundColor=Color.Black,
+ content=["....long line....................................................................................................."]
+ )
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+let view (model: Model) dispatch =
+ View.ContentPage(
+ appearing = (fun () -> dispatch PageAppearing),
+ title = model.Planet.Info.Name,
+ backgroundColor = Color.Black,
+ content = [
+ "....long line....................................................................................................."
+ ]
+ )
+"""
+
+[]
+let ``single view entry`` () =
+ formatSourceString
+ false
+ """
+let a =
+ View.Entry(
+ placeholder = "User name",
+ isEnabled = (not model.IsSigningIn),
+ textChanged = (fun args -> (dispatch (UserNameChanged args.NewTextValue))))
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+let a =
+ View.Entry(
+ placeholder = "User name",
+ isEnabled = (not model.IsSigningIn),
+ textChanged = (fun args -> (dispatch (UserNameChanged args.NewTextValue)))
+ )
+"""
+
+[]
+let ``fabulous view`` () =
+ formatSourceString
+ false
+ """
+ let loginPage =
+ View.ContentPage(
+ title = "Fabulous Demo",
+ content = View.ScrollView(
+ content = View.StackLayout(
+ padding = 30.0,
+ children = [
+ View.Frame(
+ verticalOptions = LayoutOptions.CenterAndExpand,
+ content = View.StackLayout(children = [
+ View.Entry(
+ placeholder = "User name",
+ isEnabled = (not model.IsSigningIn),
+ textChanged = (fun args -> (dispatch (UserNameChanged args.NewTextValue))))
+ View.Entry(
+ placeholder = "Password",
+ isPassword = true,
+ isEnabled = (not model.IsSigningIn),
+ textChanged = (fun args -> (dispatch (PasswordChanged args.NewTextValue))))
+ View.Button(
+ text = "Sign in",
+ heightRequest = 30.0,
+ isVisible = (not model.IsSigningIn),
+ command = (fun () -> dispatch SignIn),
+ canExecute = model.IsCredentialsProvided)
+ View.ActivityIndicator(
+ isRunning = true,
+ heightRequest = 30.0,
+ isVisible = model.IsSigningIn)])
+ )
+ ]
+ )
+ )
+ )
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+let loginPage =
+ View.ContentPage(
+ title = "Fabulous Demo",
+ content =
+ View.ScrollView(
+ content =
+ View.StackLayout(
+ padding = 30.0,
+ children = [
+ View.Frame(
+ verticalOptions = LayoutOptions.CenterAndExpand,
+ content =
+ View.StackLayout(
+ children = [
+ View.Entry(
+ placeholder = "User name",
+ isEnabled = (not model.IsSigningIn),
+ textChanged =
+ (fun args -> (dispatch (UserNameChanged args.NewTextValue)))
+ )
+ View.Entry(
+ placeholder = "Password",
+ isPassword = true,
+ isEnabled = (not model.IsSigningIn),
+ textChanged =
+ (fun args -> (dispatch (PasswordChanged args.NewTextValue)))
+ )
+ View.Button(
+ text = "Sign in",
+ heightRequest = 30.0,
+ isVisible = (not model.IsSigningIn),
+ command = (fun () -> dispatch SignIn),
+ canExecute = model.IsCredentialsProvided
+ )
+ View.ActivityIndicator(
+ isRunning = true,
+ heightRequest = 30.0,
+ isVisible = model.IsSigningIn
+ )
+ ]
+ )
+ )
+ ]
+ )
+ )
+ )
+"""
diff --git a/src/Fantomas.Core.Tests/Stroustrup/SetExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/SetExpressionTests.fs
index 6ad063f916..bfc83edf8d 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/SetExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/SetExpressionTests.fs
@@ -3,11 +3,11 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -45,10 +45,10 @@ myMutable[x] <-
|> should
equal
"""
-myMutable[x] <-
- { astContext with
+myMutable[x] <- {
+ astContext with
IsInsideMatchClausePattern = true
- }
+}
"""
[]
@@ -96,28 +96,6 @@ myMutable[x] <- struct {|
|}
"""
-[]
-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
diff --git a/src/Fantomas.Core.Tests/Stroustrup/SynBindingFunctionExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/SynBindingFunctionExpressionTests.fs
index f48d866057..219ec5e8d6 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/SynBindingFunctionExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/SynBindingFunctionExpressionTests.fs
@@ -2,12 +2,12 @@
open NUnit.Framework
open FsUnit
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
open Fantomas.Core.Tests.TestHelper
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -45,10 +45,10 @@ let x y =
|> should
equal
"""
-let x y =
- { astContext with
+let x y = {
+ astContext with
IsInsideMatchClausePattern = true
- }
+}
"""
[]
@@ -73,28 +73,6 @@ let x y = {|
|}
"""
-[]
-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
@@ -185,10 +163,10 @@ type Foo() =
equal
"""
type Foo() =
- member this.Bar x =
- { astContext with
+ member this.Bar x = {
+ astContext with
IsInsideMatchClausePattern = true
- }
+ }
"""
[]
@@ -240,30 +218,6 @@ type Foo() =
|}
"""
-[]
-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
diff --git a/src/Fantomas.Core.Tests/Stroustrup/SynBindingFunctionLongPatternExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/SynBindingFunctionLongPatternExpressionTests.fs
index b47c444e4a..3c990d3c51 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/SynBindingFunctionLongPatternExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/SynBindingFunctionLongPatternExpressionTests.fs
@@ -2,13 +2,13 @@
open NUnit.Framework
open FsUnit
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
open Fantomas.Core.Tests.TestHelper
let config =
{ config with
MaxLineLength = 80
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
// TODO: conclude on what should happen here
@@ -78,8 +78,9 @@ let private addTaskToScheduler
(task: unit -> unit)
groupName
=
- { astContext with
- IsInsideMatchClausePattern = true
+ {
+ astContext with
+ IsInsideMatchClausePattern = true
}
"""
@@ -307,8 +308,9 @@ type Foo() =
(task: unit -> unit)
groupName
=
- { astContext with
- IsInsideMatchClausePattern = true
+ {
+ astContext with
+ IsInsideMatchClausePattern = true
}
"""
diff --git a/src/Fantomas.Core.Tests/Stroustrup/SynBindingFunctionWithReturnTypeExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/SynBindingFunctionWithReturnTypeExpressionTests.fs
index 9b2f224d53..19ff09f198 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/SynBindingFunctionWithReturnTypeExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/SynBindingFunctionWithReturnTypeExpressionTests.fs
@@ -2,12 +2,12 @@
open NUnit.Framework
open FsUnit
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
open Fantomas.Core.Tests.TestHelper
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -45,10 +45,10 @@ let x y : MyRecord =
|> should
equal
"""
-let x y : MyRecord =
- { astContext with
+let x y : MyRecord = {
+ astContext with
IsInsideMatchClausePattern = true
- }
+}
"""
[]
@@ -73,28 +73,6 @@ let x y : {| A: int; B: int; C: int |} = {|
|}
"""
-[]
-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
@@ -185,10 +163,10 @@ type Foo() =
equal
"""
type Foo() =
- member this.Bar x : MyRecord =
- { astContext with
+ member this.Bar x : MyRecord = {
+ astContext with
IsInsideMatchClausePattern = true
- }
+ }
"""
[]
@@ -240,30 +218,6 @@ type Foo() =
|}
"""
-[]
-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
diff --git a/src/Fantomas.Core.Tests/Stroustrup/SynBindingValueExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/SynBindingValueExpressionTests.fs
index 84e4040459..0ca525fdaa 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/SynBindingValueExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/SynBindingValueExpressionTests.fs
@@ -3,11 +3,11 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -38,17 +38,40 @@ let ``synbinding value with update record`` () =
false
"""
let astCtx =
- { astContext with IsInsideMatchClausePattern = true }
+ { astContext with IsInsideMatchClausePattern = true; OtherThing = "YOLO" }
"""
- config
+ { config with
+ RecordMultilineFormatter = NumberOfItems }
|> prepend newline
|> should
equal
"""
+let astCtx = {
+ astContext with
+ IsInsideMatchClausePattern = true
+ OtherThing = "YOLO"
+}
+"""
+
+[]
+let ``synbinding value with update anonymous record`` () =
+ formatSourceString
+ false
+ """
let astCtx =
- { astContext with
+ {| astContext with IsInsideMatchClausePattern = true; OtherThing = "YOLO" |}
+"""
+ { config with
+ RecordMultilineFormatter = NumberOfItems }
+ |> prepend newline
+ |> should
+ equal
+ """
+let astCtx = {|
+ astContext with
IsInsideMatchClausePattern = true
- }
+ OtherThing = "YOLO"
+|}
"""
[]
@@ -96,28 +119,6 @@ let x = struct {|
|}
"""
-[]
-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
@@ -235,10 +236,10 @@ type Foo() =
equal
"""
type Foo() =
- member this.Bar =
- { astContext with
+ member this.Bar = {
+ astContext with
IsInsideMatchClausePattern = true
- }
+ }
"""
[]
@@ -290,30 +291,6 @@ type Foo() =
|}
"""
-[]
-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
@@ -371,7 +348,7 @@ type Foo() =
"""
[]
-let ``let binding for anonymous record with expression, 2508`` () =
+let ``let binding for anonymous record with copy expression, 2508`` () =
formatSourceString
false
"""
@@ -389,14 +366,14 @@ let fooDto =
|> should
equal
"""
-let fooDto =
- {| otherDto with
+let fooDto = {|
+ otherDto with
TextFilters =
criteria.Meta.TextFilter
|> Option.map (fun f -> f.Filters)
|> Option.map (List.map (sprintf "~%s~"))
|> Option.toObj
- |}
+|}
"""
[]
@@ -592,3 +569,153 @@ let myRecord = {
}
}
"""
+
+[]
+let ``app node with single record member`` () =
+ formatSourceString
+ false
+ """
+let newState = {
+ Foo =
+ Some
+ {
+ F1 = 0
+ F2 = ""
+ }
+}
+"""
+ { config with
+ RecordMultilineFormatter = NumberOfItems }
+ |> prepend newline
+ |> should
+ equal
+ """
+let newState = {
+ Foo =
+ Some {
+ F1 = 0
+ F2 = ""
+ }
+}
+"""
+
+[]
+let ``app node with single anonymous record member`` () =
+ formatSourceString
+ false
+ """
+let newState = {|
+ Foo =
+ Some
+ {|
+ F1 = 0
+ F2 = ""
+ |}
+|}
+"""
+ { config with
+ RecordMultilineFormatter = NumberOfItems }
+ |> prepend newline
+ |> should
+ equal
+ """
+let newState = {|
+ Foo =
+ Some {|
+ F1 = 0
+ F2 = ""
+ |}
+|}
+"""
+
+[]
+let ``app node with single record arg`` () =
+ formatSourceString
+ false
+ """
+let newState =
+ Some
+ {
+ F1 = 0
+ F2 = ""
+ }
+"""
+ { config with
+ RecordMultilineFormatter = NumberOfItems }
+ |> prepend newline
+ |> should
+ equal
+ """
+let newState =
+ Some {
+ F1 = 0
+ F2 = ""
+ }
+"""
+
+[]
+let ``lowercase app node with single record arg`` () =
+ formatSourceString
+ false
+ """
+let newState =
+ someFunc
+ {
+ F1 = 0
+ F2 = ""
+ }
+"""
+ { config with
+ RecordMultilineFormatter = NumberOfItems }
+ |> prepend newline
+ |> should
+ equal
+ """
+let newState =
+ someFunc {
+ F1 = 0
+ F2 = ""
+ }
+"""
+
+[]
+let ``lowercase app node with multiple args ending in a single record arg`` () =
+ formatSourceString
+ false
+ """
+let newState =
+ myFn a b c { D = d; E = e }
+"""
+ { config with
+ RecordMultilineFormatter = NumberOfItems }
+ |> prepend newline
+ |> should
+ equal
+ """
+let newState =
+ myFn a b c {
+ D = d
+ E = e
+ }
+"""
+
+[]
+let ``lowercase app node with multiple args ending in a single anonymous record arg`` () =
+ formatSourceString
+ false
+ """
+let newState =
+ myFn a b c {| D = d; E = e |}
+"""
+ { config with
+ RecordMultilineFormatter = NumberOfItems }
+ |> prepend newline
+ |> should
+ equal
+ """
+let newState =
+ myFn a b c {|
+ D = d
+ E = e
+ |}
+"""
diff --git a/src/Fantomas.Core.Tests/Stroustrup/SynExprAndBangExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/SynExprAndBangExpressionTests.fs
index b330cf93b5..c3d0e79b21 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/SynExprAndBangExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/SynExprAndBangExpressionTests.fs
@@ -2,12 +2,12 @@
open NUnit.Framework
open FsUnit
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
open Fantomas.Core.Tests.TestHelper
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -66,12 +66,12 @@ opt {
opt {
let! abc = def ()
- and! foo =
- { bar with
+ and! foo = {
+ bar with
X = xFieldValueOne
Y = yFieldValueTwo
Z = zFieldValueThree
- }
+ }
()
}
@@ -143,38 +143,6 @@ opt {
}
"""
-[]
-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
diff --git a/src/Fantomas.Core.Tests/Stroustrup/SynExprAnonRecdStructTests.fs b/src/Fantomas.Core.Tests/Stroustrup/SynExprAnonRecdStructTests.fs
new file mode 100644
index 0000000000..2f50fdf8df
--- /dev/null
+++ b/src/Fantomas.Core.Tests/Stroustrup/SynExprAnonRecdStructTests.fs
@@ -0,0 +1,35 @@
+module Fantomas.Core.Tests.Stroustrup.SynExprAnonRecdStructTests
+
+open NUnit.Framework
+open FsUnit
+open Fantomas.Core.Tests.TestHelper
+open Fantomas.Core
+
+let config =
+ { config with
+ MultilineBracketStyle = Stroustrup }
+
+[]
+let ``anonymous struct record with trivia`` () =
+ formatSourceString
+ false
+ """
+struct // 1
+ {| // 2
+ // 3
+ X = 4
+ // 5
+ |} // 6
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+struct // 1
+ {| // 2
+ // 3
+ X = 4
+ // 5
+ |} // 6
+"""
diff --git a/src/Fantomas.Core.Tests/Stroustrup/SynMatchClauseExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/SynMatchClauseExpressionTests.fs
index 153490a445..959701005b 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/SynMatchClauseExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/SynMatchClauseExpressionTests.fs
@@ -3,11 +3,11 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -49,10 +49,10 @@ match x with
equal
"""
match x with
-| _ ->
- { astContext with
+| _ -> {
+ astContext with
IsInsideMatchClausePattern = true
- }
+ }
"""
[]
@@ -104,30 +104,6 @@ match x with
|}
"""
-[]
-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
@@ -265,10 +241,10 @@ with ex ->
"""
try
foo ()
-with ex ->
- { astContext with
+with ex -> {
+ astContext with
IsInsideMatchClausePattern = true
- }
+}
"""
[]
@@ -324,33 +300,6 @@ with ex -> struct {|
|}
"""
-[]
-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
diff --git a/src/Fantomas.Core.Tests/Stroustrup/SynTypeDefnSigReprSimpleTests.fs b/src/Fantomas.Core.Tests/Stroustrup/SynTypeDefnSigReprSimpleTests.fs
index 12058bbaa9..5edcc57e36 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/SynTypeDefnSigReprSimpleTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/SynTypeDefnSigReprSimpleTests.fs
@@ -3,11 +3,11 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup }
+ MultilineBracketStyle = Stroustrup }
[]
let ``record type definition`` () =
@@ -63,9 +63,6 @@ type V = // comment
}
"""
-// TODO: I feel like stroustrup 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
@@ -87,11 +84,10 @@ type V =
"""
namespace Foo
-type V =
- {
- X: SomeFieldType
- Y: OhSomethingElse
- Z: ALongTypeName
- }
+type V = {
+ X: SomeFieldType
+ Y: OhSomethingElse
+ Z: ALongTypeName
+} with
member Coordinate: SomeFieldType * OhSomethingElse * ALongTypeName
"""
diff --git a/src/Fantomas.Core.Tests/Stroustrup/SynTypeDefnSimpleReprRecordTests.fs b/src/Fantomas.Core.Tests/Stroustrup/SynTypeDefnSimpleReprRecordTests.fs
index 11e531eab4..a3b9e8e528 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/SynTypeDefnSimpleReprRecordTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/SynTypeDefnSimpleReprRecordTests.fs
@@ -3,11 +3,11 @@
open NUnit.Framework
open FsUnit
open Fantomas.Core.Tests.TestHelper
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup }
+ MultilineBracketStyle = Stroustrup }
[]
let ``record type definition`` () =
@@ -77,9 +77,6 @@ type V = // comment
}
"""
-// TODO: I feel like stroustrup 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
@@ -97,15 +94,36 @@ type V =
|> should
equal
"""
-type V =
- {
- X: SomeFieldType
- Y: OhSomethingElse
- Z: ALongTypeName
- }
+type V = {
+ X: SomeFieldType
+ Y: OhSomethingElse
+ Z: ALongTypeName
+} with
member this.Coordinate = (this.X, this.Y, this.Z)
"""
+[]
+let ``record type definition with members and trivia`` () =
+ formatSourceString
+ false
+ """
+type X = {
+ Y: int
+} with // foo
+ member x.Z = ()
+"""
+ { config with
+ NewlineBetweenTypeDefinitionAndMembers = false }
+ |> prepend newline
+ |> should
+ equal
+ """
+type X = {
+ Y: int
+} with // foo
+ member x.Z = ()
+"""
+
[]
let ``record definition with private accessibility modifier, 2481`` () =
formatSourceString
@@ -188,17 +206,36 @@ type NonEmptyList<'T> =
|> should
equal
"""
-type NonEmptyList<'T> =
- private
- {
- List: 'T list
- }
+type NonEmptyList<'T> = private {
+ List: 'T list
+} with
member this.Head = this.List.Head
member this.Tail = this.List.Tail
member this.Length = this.List.Length
"""
+[]
+let ``record definition with accessibility modifier without members`` () =
+ formatSourceString
+ false
+ """
+type NonEmptyList<'T> =
+ private
+ { List: 'T list; Value: 'T; Third: string}
+"""
+ config
+ |> prepend newline
+ |> should
+ equal
+ """
+type NonEmptyList<'T> = private {
+ List: 'T list
+ Value: 'T
+ Third: string
+}
+"""
+
[]
let ``outdenting problem when specifying record with accessibility modifier, 2597`` () =
formatSourceString
@@ -257,3 +294,63 @@ type MangaDexAtHomeResponse = {
|}
}
"""
+
+[]
+let ``record interface declarations can break with Stroustrup enabled, 2787 `` () =
+ formatSourceString
+ false
+ """
+type IEvent = interface end
+
+type SomeEvent =
+ { Id: string
+ Name: string }
+ interface IEvent
+
+type UpdatedName = { PreviousName: string }
+"""
+ { config with
+ NewlineBetweenTypeDefinitionAndMembers = false }
+ |> prepend newline
+ |> should
+ equal
+ """
+type IEvent =
+ interface
+ end
+
+type SomeEvent = {
+ Id: string
+ Name: string
+} with
+ interface IEvent
+
+type UpdatedName = { PreviousName: string }
+"""
+
+[]
+let ``record member declarations can break with Stroustrup enabled, 2787 `` () =
+ formatSourceString
+ false
+ """
+type SomeEvent =
+ { Id: string
+ Name: string }
+ member x.BreakWithOtherStuffAs well = ()
+
+type UpdatedName = { PreviousName: string }
+"""
+ { config with
+ NewlineBetweenTypeDefinitionAndMembers = false }
+ |> prepend newline
+ |> should
+ equal
+ """
+type SomeEvent = {
+ Id: string
+ Name: string
+} with
+ member x.BreakWithOtherStuffAs well = ()
+
+type UpdatedName = { PreviousName: string }
+"""
diff --git a/src/Fantomas.Core.Tests/Stroustrup/YieldOrReturnBangExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/YieldOrReturnBangExpressionTests.fs
index e23c3b8df8..9c0c9f6cdc 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/YieldOrReturnBangExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/YieldOrReturnBangExpressionTests.fs
@@ -2,12 +2,12 @@
open NUnit.Framework
open FsUnit
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
open Fantomas.Core.Tests.TestHelper
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -68,19 +68,19 @@ myComp {
equal
"""
myComp {
- yield!
- { bar with
+ yield! {
+ bar with
X = xFieldValueOne
Y = yFieldValueTwo
Z = zFieldValueThree
- }
+ }
- return!
- { bar with
+ return! {
+ bar with
X = xFieldValueOne
Y = yFieldValueTwo
Z = zFieldValueThree
- }
+ }
}
"""
@@ -157,42 +157,6 @@ myComp {
}
"""
-[]
-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
diff --git a/src/Fantomas.Core.Tests/Stroustrup/YieldOrReturnExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/YieldOrReturnExpressionTests.fs
index 6828057ab7..114d7151ae 100644
--- a/src/Fantomas.Core.Tests/Stroustrup/YieldOrReturnExpressionTests.fs
+++ b/src/Fantomas.Core.Tests/Stroustrup/YieldOrReturnExpressionTests.fs
@@ -2,12 +2,12 @@
open NUnit.Framework
open FsUnit
-open Fantomas.Core.FormatConfig
+open Fantomas.Core
open Fantomas.Core.Tests.TestHelper
let config =
{ config with
- MultilineBracketStyle = ExperimentalStroustrup
+ MultilineBracketStyle = Stroustrup
MaxArrayOrListWidth = 40 }
[]
@@ -68,19 +68,19 @@ myComp {
equal
"""
myComp {
- yield
- { bar with
+ yield {
+ bar with
X = xFieldValueOne
Y = yFieldValueTwo
Z = zFieldValueThree
- }
+ }
- return
- { bar with
+ return {
+ bar with
X = xFieldValueOne
Y = yFieldValueTwo
Z = zFieldValueThree
- }
+ }
}
"""
@@ -157,42 +157,6 @@ myComp {
}
"""
-[]
-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
diff --git a/src/Fantomas.Core.Tests/StructTests.fs b/src/Fantomas.Core.Tests/StructTests.fs
index 88f53a7821..6420b0d6e2 100644
--- a/src/Fantomas.Core.Tests/StructTests.fs
+++ b/src/Fantomas.Core.Tests/StructTests.fs
@@ -164,3 +164,28 @@ type NameStruct() =
struct
end
"""
+
+[