Skip to content

Commit c6ae676

Browse files
committed
Change style of base constructor calls. (#2555)
* Change style of base constructor calls. * Add changelog entry for 5.1.0-alpha-005.
1 parent 3e4d15c commit c6ae676

File tree

7 files changed

+174
-58
lines changed

7 files changed

+174
-58
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
# Changelog
22

3-
## [Unreleased]
3+
## [5.1.0-alpha-005] - 2022-10-07
44

55
### Changed
66
* Control space in pattern by `fsharp_space_before_lowercase_invocation` and `fsharp_space_before_uppercase_invocation`. [fslang-design/issues/712](https://github.com/fsharp/fslang-design/issues/712)
7+
* Style of base constructor calls. [fsharp/fslang-design#693](https://github.com/fsharp/fslang-design/issues/693)
8+
* Style of multiline type annotations/ [fsharp/fslang-design#708](https://github.com/fsharp/fslang-design/issues/708)
79

810
### Fixed
911
* Comments in SynArgPats.NamePatPairs are lost. [#2541](https://github.com/fsprojects/fantomas/issues/2541)
12+
* Vanity alignment used inside base ctor call. [#2111](https://github.com/fsprojects/fantomas/issues/2111)
13+
* Add line break before start of argument list. [#2335](https://github.com/fsprojects/fantomas/issues/2335)
1014

1115
## [5.1.0-alpha-004] - 2022-10-07
1216

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
module Fantomas.Core.Tests.BaseConstructorTests
2+
3+
open NUnit.Framework
4+
open FsUnit
5+
open Fantomas.Core.Tests.TestHelper
6+
7+
[<Test>]
8+
let ``multiple base constructors in record, 2111`` () =
9+
formatSourceString
10+
false
11+
"""
12+
type UnhandledWebException =
13+
inherit Exception
14+
15+
new(status: WebExceptionStatus, innerException: Exception) =
16+
{ inherit Exception(SPrintF1
17+
"Backend not prepared for this WebException with Status[%i]"
18+
(int status),
19+
innerException) }
20+
21+
new(info: SerializationInfo, context: StreamingContext) =
22+
{ inherit Exception(info, context) }
23+
"""
24+
{ config with MaxLineLength = 100 }
25+
|> prepend newline
26+
|> should
27+
equal
28+
"""
29+
type UnhandledWebException =
30+
inherit Exception
31+
32+
new(status: WebExceptionStatus, innerException: Exception) =
33+
{ inherit
34+
Exception(
35+
SPrintF1 "Backend not prepared for this WebException with Status[%i]" (int status),
36+
innerException
37+
) }
38+
39+
new(info: SerializationInfo, context: StreamingContext) = { inherit Exception(info, context) }
40+
"""
41+
42+
[<Test>]
43+
let ``single multiline base constructor, 2335`` () =
44+
formatSourceString
45+
false
46+
"""
47+
type FieldNotFoundException<'T>(obj:'T, field:string, specLink:string) =
48+
inherit SwaggerSchemaParseException(
49+
sprintf "Object MUST contain field `%s` (See %s for more details).\nObject:%A"
50+
field specLink obj)
51+
"""
52+
{ config with
53+
SpaceBeforeClassConstructor = true
54+
MaxLineLength = 90 }
55+
|> prepend newline
56+
|> should
57+
equal
58+
"""
59+
type FieldNotFoundException<'T> (obj: 'T, field: string, specLink: string) =
60+
inherit
61+
SwaggerSchemaParseException (
62+
sprintf
63+
"Object MUST contain field `%s` (See %s for more details).\nObject:%A"
64+
field
65+
specLink
66+
obj
67+
)
68+
"""

src/Fantomas.Core.Tests/ClassTests.fs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -954,8 +954,8 @@ type public DerivedExceptionWithLongNaaaaaaaaameException
954954
originalRequest: string,
955955
originalResponse: string
956956
) =
957-
inherit BaseExceptionWithLongNaaaameException
958-
(
957+
inherit
958+
BaseExceptionWithLongNaaaameException(
959959
message,
960960
code,
961961
originalRequest,
@@ -991,8 +991,8 @@ type public DerivedExceptionWithLongNaaaaaaaaameException
991991
originalRequest: string,
992992
originalResponse: string
993993
) =
994-
inherit BaseExceptionWithLongNaaaameException
995-
(
994+
inherit
995+
BaseExceptionWithLongNaaaameException(
996996
message,
997997
code,
998998
originalRequest,

src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
<Compile Include="InterfaceStaticMethodTests.fs" />
120120
<Compile Include="ExternTests.fs" />
121121
<Compile Include="TypeAnnotationTests.fs" />
122+
<Compile Include="BaseConstructorTests.fs" />
122123
</ItemGroup>
123124
<ItemGroup>
124125
<ProjectReference Include="..\Fantomas.Core\Fantomas.Core.fsproj" />

src/Fantomas.Core.Tests/MultilineBlockBracketsOnSameColumnRecordTests.fs

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,21 @@ let ``record instance with inherit keyword and no fields`` () =
151151
"""let a =
152152
{ inherit ProjectPropertiesBase<_>(projectTypeGuids, factoryGuid, targetFrameworkIds, dotNetCoreSDK) }
153153
"""
154-
config
154+
{ config with MaxLineLength = 80 }
155155
|> prepend newline
156156
|> should
157157
equal
158158
"""
159159
let a =
160-
{ inherit ProjectPropertiesBase<_>(projectTypeGuids, factoryGuid, targetFrameworkIds, dotNetCoreSDK) }
160+
{
161+
inherit
162+
ProjectPropertiesBase<_>(
163+
projectTypeGuids,
164+
factoryGuid,
165+
targetFrameworkIds,
166+
dotNetCoreSDK
167+
)
168+
}
161169
"""
162170

163171
[<Test>]
@@ -177,7 +185,10 @@ let ``type with record instance with inherit keyword`` () =
177185
type ServerCannotBeResolvedException =
178186
inherit CommunicationUnsuccessfulException
179187
180-
new(message) = { inherit CommunicationUnsuccessfulException(message) }
188+
new(message) =
189+
{
190+
inherit CommunicationUnsuccessfulException(message)
191+
}
181192
"""
182193

183194
[<Test>]
@@ -1270,3 +1281,42 @@ let ``comment after equals in anonymous record field`` () =
12701281
B
12711282
|}
12721283
"""
1284+
1285+
[<Test>]
1286+
let ``multiple base constructors in record`` () =
1287+
formatSourceString
1288+
false
1289+
"""
1290+
type UnhandledWebException =
1291+
inherit Exception
1292+
1293+
new(status: WebExceptionStatus, innerException: Exception) =
1294+
{ inherit Exception(SPrintF1
1295+
"Backend not prepared for this WebException with Status[%i]"
1296+
(int status),
1297+
innerException) }
1298+
1299+
new(info: SerializationInfo, context: StreamingContext) =
1300+
{ inherit Exception(info, context) }
1301+
"""
1302+
{ config with MaxLineLength = 100 }
1303+
|> prepend newline
1304+
|> should
1305+
equal
1306+
"""
1307+
type UnhandledWebException =
1308+
inherit Exception
1309+
1310+
new(status : WebExceptionStatus, innerException : Exception) =
1311+
{
1312+
inherit
1313+
Exception(
1314+
SPrintF1
1315+
"Backend not prepared for this WebException with Status[%i]"
1316+
(int status),
1317+
innerException
1318+
)
1319+
}
1320+
1321+
new(info : SerializationInfo, context : StreamingContext) = { inherit Exception(info, context) }
1322+
"""

src/Fantomas.Core/CodePrinter.fs

Lines changed: 27 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,11 +1086,9 @@ and genExpr astContext synExpr ctx =
10861086
let smallRecordExpr =
10871087
genTriviaFor SynExpr_Record_OpeningBrace openingBrace sepOpenS
10881088
+> optSingle
1089-
(fun (inheritType, inheritExpr) ->
1089+
(fun inheritCtor ->
10901090
!- "inherit "
1091-
+> genType astContext inheritType
1092-
+> addSpaceBeforeClassConstructor inheritExpr
1093-
+> genExpr astContext inheritExpr
1091+
+> genInheritConstructor astContext inheritCtor
10941092
+> onlyIf (List.isNotEmpty xs) sepSemi)
10951093
inheritOpt
10961094
+> optSingle (fun e -> genExpr astContext e +> !- " with ") eo
@@ -2503,13 +2501,11 @@ and genMultilineRecordInstance
25032501

25042502
let expr =
25052503
match inheritOpt with
2506-
| Some (t, e) ->
2504+
| Some inheritCtor ->
25072505
genTriviaFor SynExpr_Record_OpeningBrace openingBrace sepOpenS
25082506
+> atCurrentColumn (
25092507
!- "inherit "
2510-
+> genType astContext t
2511-
+> addSpaceBeforeClassConstructor e
2512-
+> genExpr astContext e
2508+
+> autoIndentAndNlnIfExpressionExceedsPageWidth (genInheritConstructor astContext inheritCtor)
25132509
+> onlyIf (List.isNotEmpty xs) sepNln
25142510
+> fieldsExpr
25152511
+> genTriviaFor SynExpr_Record_ClosingBrace closingBrace sepCloseS
@@ -2568,22 +2564,16 @@ and genMultilineRecordInstanceAlignBrackets
25682564
let hasFields = List.isNotEmpty xs
25692565

25702566
match inheritOpt, eo with
2571-
| Some (inheritType, inheritExpr), None ->
2572-
genTriviaFor SynExpr_Record_OpeningBrace openingBrace sepOpenS
2573-
+> ifElse hasFields (indent +> sepNln) sepNone
2574-
+> !- "inherit "
2575-
+> genType astContext inheritType
2576-
+> addSpaceBeforeClassConstructor inheritExpr
2577-
+> genExpr astContext inheritExpr
2578-
+> ifElse
2579-
hasFields
2580-
(sepNln
2581-
+> fieldsExpr
2582-
+> unindent
2583-
+> sepNln
2584-
+> genTriviaFor SynExpr_Record_ClosingBrace closingBrace sepCloseSFixed)
2585-
(sepSpace +> genTriviaFor SynExpr_Record_ClosingBrace closingBrace sepCloseSFixed)
2586-
2567+
| Some inheritCtor, None ->
2568+
genTriviaFor SynExpr_Record_OpeningBrace openingBrace sepOpenSFixed
2569+
+> indentSepNlnUnindent (
2570+
!- "inherit "
2571+
+> autoIndentAndNlnIfExpressionExceedsPageWidth (genInheritConstructor astContext inheritCtor)
2572+
+> onlyIf hasFields sepNln
2573+
+> fieldsExpr
2574+
)
2575+
+> sepNln
2576+
+> genTriviaFor SynExpr_Record_ClosingBrace closingBrace sepCloseSFixed
25872577
| None, Some e ->
25882578
genTriviaFor SynExpr_Record_OpeningBrace openingBrace sepOpenS
25892579
+> atCurrentColumnIndent (genExpr astContext e)
@@ -2603,6 +2593,18 @@ and genMultilineRecordInstanceAlignBrackets
26032593
+> ifElseCtx lastWriteEventIsNewline sepNone sepNln
26042594
+> genTriviaFor SynExpr_Record_ClosingBrace closingBrace sepCloseSFixed)
26052595

2596+
and genInheritConstructor (astContext: ASTContext) (inheritCtor: SynType * SynExpr) =
2597+
match inheritCtor with
2598+
| TypeOnlyInheritConstructor t -> genType astContext t
2599+
| UnitInheritConstructor t -> genType astContext t +> sepSpaceBeforeClassConstructor +> sepOpenT +> sepCloseT
2600+
| ParenInheritConstructor (t, px) ->
2601+
genType astContext t
2602+
+> sepSpaceBeforeClassConstructor
2603+
+> expressionFitsOnRestOfLine (genExpr astContext px) (genMultilineFunctionApplicationArguments astContext px)
2604+
| OtherInheritConstructor (t, e) ->
2605+
genType astContext t
2606+
+> sepSpaceOrIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e)
2607+
26062608
and genMultilineAnonRecord (isStruct: bool) fields copyInfo (astContext: ASTContext) =
26072609
let recordExpr =
26082610
match copyInfo with
@@ -4222,32 +4224,8 @@ and genMemberDefn astContext node =
42224224
| MDOpen lid -> !- "open " +> genSynLongIdent false lid
42234225
// What is the role of so
42244226
| MDImplicitInherit (t, e, _) ->
4225-
let genBasecall =
4226-
let shortExpr = genExpr astContext e
4227-
4228-
let longExpr =
4229-
match e with
4230-
| Paren (lpr, Tuple (es, tr), rpr, pr) ->
4231-
indent
4232-
+> sepNln
4233-
+> indent
4234-
+> sepOpenTFor lpr
4235-
+> sepNln
4236-
+> (col (sepComma +> sepNln) es (genExpr astContext)
4237-
|> genTriviaFor SynExpr_Tuple tr)
4238-
+> unindent
4239-
+> sepNln
4240-
+> unindent
4241-
+> sepCloseTFor rpr
4242-
|> genTriviaFor SynExpr_Paren pr
4243-
| _ -> genExpr astContext e
4244-
4245-
expressionFitsOnRestOfLine shortExpr longExpr
4246-
42474227
!- "inherit "
4248-
+> genType astContext t
4249-
+> addSpaceBeforeClassConstructor e
4250-
+> genBasecall
4228+
+> autoIndentAndNlnIfExpressionExceedsPageWidth (genInheritConstructor astContext (t, e))
42514229

42524230
| MDInherit (t, _) -> !- "inherit " +> genType astContext t
42534231
| MDValField f -> genField astContext "val " f

src/Fantomas.Core/SourceParser.fs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1042,10 +1042,25 @@ let rec (|ElIf|_|) =
10421042
Some([ (None, trivia.IfKeyword, trivia.IsElif, e1, trivia.ThenKeyword, e2) ], elseInfo, range)
10431043
| _ -> None
10441044

1045+
let (|TypeOnlyInheritConstructor|UnitInheritConstructor|ParenInheritConstructor|OtherInheritConstructor|)
1046+
(
1047+
t: SynType,
1048+
e: SynExpr
1049+
) =
1050+
match e with
1051+
| SynExpr.Const (constant = SynConst.Unit; range = unitRange) ->
1052+
// The unit expression could have been added artificially.
1053+
if unitRange.StartColumn + 2 = unitRange.EndColumn then
1054+
UnitInheritConstructor(t)
1055+
else
1056+
TypeOnlyInheritConstructor t
1057+
| SynExpr.Paren _ as px -> ParenInheritConstructor(t, px)
1058+
| _ -> OtherInheritConstructor(t, e)
1059+
10451060
let (|Record|_|) =
10461061
function
10471062
| SynExpr.Record (inheritOpt, eo, xs, StartEndRange 1 (openingBrace, _, closingBrace)) ->
1048-
let inheritOpt = inheritOpt |> Option.map (fun (typ, expr, _, _, _) -> (typ, expr))
1063+
let inheritOpt = inheritOpt |> Option.map (fun (t, e, _, _, _) -> t, e)
10491064

10501065
Some(openingBrace, inheritOpt, xs, Option.map fst eo, closingBrace)
10511066
| _ -> None

0 commit comments

Comments
 (0)