Skip to content

Commit 373d086

Browse files
committed
Change style of base constructor calls.
1 parent 7134389 commit 373d086

File tree

7 files changed

+178
-57
lines changed

7 files changed

+178
-57
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## [Unreleased]
4+
5+
### Changed
6+
* Style of base constructor calls. [fsharp/fslang-design#693](https://github.com/fsharp/fslang-design/issues/693)
7+
8+
### Fixed
9+
* Vanity alignment used inside base ctor call. [#2111](https://github.com/fsprojects/fantomas/issues/2111)
10+
* Add line break before start of argument list. [#2335](https://github.com/fsprojects/fantomas/issues/2335)
11+
312
## [5.1.0-alpha-004] - 2022-10-07
413

514
### Changed
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
@@ -118,6 +118,7 @@
118118
<Compile Include="DotSetTests.fs" />
119119
<Compile Include="InterfaceStaticMethodTests.fs" />
120120
<Compile Include="ExternTests.fs" />
121+
<Compile Include="BaseConstructorTests.fs" />
121122
</ItemGroup>
122123
<ItemGroup>
123124
<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
@@ -1073,11 +1073,9 @@ and genExpr astContext synExpr ctx =
10731073
let smallRecordExpr =
10741074
genTriviaFor SynExpr_Record_OpeningBrace openingBrace sepOpenS
10751075
+> optSingle
1076-
(fun (inheritType, inheritExpr) ->
1076+
(fun inheritCtor ->
10771077
!- "inherit "
1078-
+> genType astContext inheritType
1079-
+> addSpaceBeforeClassConstructor inheritExpr
1080-
+> genExpr astContext inheritExpr
1078+
+> genInheritConstructor astContext inheritCtor
10811079
+> onlyIf (List.isNotEmpty xs) sepSemi)
10821080
inheritOpt
10831081
+> optSingle (fun e -> genExpr astContext e +> !- " with ") eo
@@ -2486,13 +2484,11 @@ and genMultilineRecordInstance
24862484

24872485
let expr =
24882486
match inheritOpt with
2489-
| Some (t, e) ->
2487+
| Some inheritCtor ->
24902488
genTriviaFor SynExpr_Record_OpeningBrace openingBrace sepOpenS
24912489
+> atCurrentColumn (
24922490
!- "inherit "
2493-
+> genType astContext t
2494-
+> addSpaceBeforeClassConstructor e
2495-
+> genExpr astContext e
2491+
+> autoIndentAndNlnIfExpressionExceedsPageWidth (genInheritConstructor astContext inheritCtor)
24962492
+> onlyIf (List.isNotEmpty xs) sepNln
24972493
+> fieldsExpr
24982494
+> genTriviaFor SynExpr_Record_ClosingBrace closingBrace sepCloseS
@@ -2551,22 +2547,16 @@ and genMultilineRecordInstanceAlignBrackets
25512547
let hasFields = List.isNotEmpty xs
25522548

25532549
match inheritOpt, eo with
2554-
| Some (inheritType, inheritExpr), None ->
2555-
genTriviaFor SynExpr_Record_OpeningBrace openingBrace sepOpenS
2556-
+> ifElse hasFields (indent +> sepNln) sepNone
2557-
+> !- "inherit "
2558-
+> genType astContext inheritType
2559-
+> addSpaceBeforeClassConstructor inheritExpr
2560-
+> genExpr astContext inheritExpr
2561-
+> ifElse
2562-
hasFields
2563-
(sepNln
2564-
+> fieldsExpr
2565-
+> unindent
2566-
+> sepNln
2567-
+> genTriviaFor SynExpr_Record_ClosingBrace closingBrace sepCloseSFixed)
2568-
(sepSpace +> genTriviaFor SynExpr_Record_ClosingBrace closingBrace sepCloseSFixed)
2569-
2550+
| Some inheritCtor, None ->
2551+
genTriviaFor SynExpr_Record_OpeningBrace openingBrace sepOpenSFixed
2552+
+> indentSepNlnUnindent (
2553+
!- "inherit "
2554+
+> autoIndentAndNlnIfExpressionExceedsPageWidth (genInheritConstructor astContext inheritCtor)
2555+
+> onlyIf hasFields sepNln
2556+
+> fieldsExpr
2557+
)
2558+
+> sepNln
2559+
+> genTriviaFor SynExpr_Record_ClosingBrace closingBrace sepCloseSFixed
25702560
| None, Some e ->
25712561
genTriviaFor SynExpr_Record_OpeningBrace openingBrace sepOpenS
25722562
+> atCurrentColumnIndent (genExpr astContext e)
@@ -2586,6 +2576,18 @@ and genMultilineRecordInstanceAlignBrackets
25862576
+> ifElseCtx lastWriteEventIsNewline sepNone sepNln
25872577
+> genTriviaFor SynExpr_Record_ClosingBrace closingBrace sepCloseSFixed)
25882578

2579+
and genInheritConstructor (astContext: ASTContext) (inheritCtor: SynType * SynExpr) =
2580+
match inheritCtor with
2581+
| TypeOnlyInheritConstructor t -> genType astContext t
2582+
| UnitInheritConstructor t -> genType astContext t +> sepSpaceBeforeClassConstructor +> sepOpenT +> sepCloseT
2583+
| ParenInheritConstructor (t, px) ->
2584+
genType astContext t
2585+
+> sepSpaceBeforeClassConstructor
2586+
+> expressionFitsOnRestOfLine (genExpr astContext px) (genMultilineFunctionApplicationArguments astContext px)
2587+
| OtherInheritConstructor (t, e) ->
2588+
genType astContext t
2589+
+> sepSpaceOrIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e)
2590+
25892591
and genMultilineAnonRecord (isStruct: bool) fields copyInfo (astContext: ASTContext) =
25902592
let recordExpr =
25912593
match copyInfo with
@@ -4194,32 +4196,8 @@ and genMemberDefn astContext node =
41944196
| MDOpen lid -> !- "open " +> genSynLongIdent false lid
41954197
// What is the role of so
41964198
| MDImplicitInherit (t, e, _) ->
4197-
let genBasecall =
4198-
let shortExpr = genExpr astContext e
4199-
4200-
let longExpr =
4201-
match e with
4202-
| Paren (lpr, Tuple (es, tr), rpr, pr) ->
4203-
indent
4204-
+> sepNln
4205-
+> indent
4206-
+> sepOpenTFor lpr
4207-
+> sepNln
4208-
+> (col (sepComma +> sepNln) es (genExpr astContext)
4209-
|> genTriviaFor SynExpr_Tuple tr)
4210-
+> unindent
4211-
+> sepNln
4212-
+> unindent
4213-
+> sepCloseTFor rpr
4214-
|> genTriviaFor SynExpr_Paren pr
4215-
| _ -> genExpr astContext e
4216-
4217-
expressionFitsOnRestOfLine shortExpr longExpr
4218-
42194199
!- "inherit "
4220-
+> genType astContext t
4221-
+> addSpaceBeforeClassConstructor e
4222-
+> genBasecall
4200+
+> autoIndentAndNlnIfExpressionExceedsPageWidth (genInheritConstructor astContext (t, e))
42234201

42244202
| MDInherit (t, _) -> !- "inherit " +> genType astContext t
42254203
| 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)