Skip to content

Commit

Permalink
Update long secondary constructor parameters.
Browse files Browse the repository at this point in the history
  • Loading branch information
nojaf committed Jan 11, 2024
1 parent d8f44db commit 68ae554
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 96 deletions.
66 changes: 0 additions & 66 deletions src/Fantomas.Core.Tests/BaseConstructorTests.fs

This file was deleted.

168 changes: 168 additions & 0 deletions src/Fantomas.Core.Tests/ConstructorTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
module Fantomas.Core.Tests.ConstructorTests

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

[<Test>]
let ``multiple base constructors in record, 2111`` () =
formatSourceString
"""
type UnhandledWebException =
inherit Exception
new(status: WebExceptionStatus, innerException: Exception) =
{ inherit Exception(SPrintF1
"Backend not prepared for this WebException with Status[%i]"
(int status),
innerException) }
new(info: SerializationInfo, context: StreamingContext) =
{ inherit Exception(info, context) }
"""
{ config with MaxLineLength = 100 }
|> prepend newline
|> should
equal
"""
type UnhandledWebException =
inherit Exception
new(status: WebExceptionStatus, innerException: Exception) =
{ inherit
Exception(
SPrintF1 "Backend not prepared for this WebException with Status[%i]" (int status),
innerException
) }
new(info: SerializationInfo, context: StreamingContext) = { inherit Exception(info, context) }
"""

[<Test>]
let ``single multiline base constructor, 2335`` () =
formatSourceString
"""
type FieldNotFoundException<'T>(obj:'T, field:string, specLink:string) =
inherit SwaggerSchemaParseException(
sprintf "Object MUST contain field `%s` (See %s for more details).\nObject:%A"
field specLink obj)
"""
{ config with
SpaceBeforeClassConstructor = true
MaxLineLength = 90 }
|> prepend newline
|> should
equal
"""
type FieldNotFoundException<'T> (obj: 'T, field: string, specLink: string) =
inherit
SwaggerSchemaParseException (
sprintf
"Object MUST contain field `%s` (See %s for more details).\nObject:%A"
field
specLink
obj
)
"""

[<Test>]
let ``multiline secondary constructor, 3037`` () =
formatSourceString
"""
type IntersectionOptions
private
(
primary: bool,
?root: Element,
?rootMargin: string,
?threshold: ResizeArray<float>,
?triggerOnce: bool
)
=
new(?root: Element,
?rootMargin: string,
?threshold: ResizeArray<float>,
?triggerOnce: bool) =
IntersectionOptions(true)
"""
{ config with MaxLineLength = 80 }
|> prepend newline
|> should
equal
"""
type IntersectionOptions
private
(
primary: bool,
?root: Element,
?rootMargin: string,
?threshold: ResizeArray<float>,
?triggerOnce: bool
) =
new
(
?root: Element,
?rootMargin: string,
?threshold: ResizeArray<float>,
?triggerOnce: bool
) =
IntersectionOptions(true)
"""

[<Test>]
let ``secondary constructor with xml doc`` () =
formatSourceString
"""
type IntersectionOptions
(
primary: bool
) =
/// Good stuff
new (secondary: int) = IntersectionOptions(secondary = 0)
"""
config
|> prepend newline
|> should
equal
"""
type IntersectionOptions(primary: bool) =
/// Good stuff
new(secondary: int) = IntersectionOptions(secondary = 0)
"""

[<Test>]
let ``setting AlternativeLongMemberDefinitions should be respected in long secondary constructor`` () =
formatSourceString
"""
type StateMachine(
// meh
) =
new(
// also meh but with an int
x:int) as secondCtor = StateMachine()
"""
{ config with
AlternativeLongMemberDefinitions = true }
|> prepend newline
|> should
equal
"""
type StateMachine
(
// meh
)
=
new
(
// also meh but with an int
x: int
) as secondCtor
=
StateMachine()
"""
2 changes: 1 addition & 1 deletion src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
<Compile Include="InterfaceStaticMethodTests.fs" />
<Compile Include="ExternTests.fs" />
<Compile Include="TypeAnnotationTests.fs" />
<Compile Include="BaseConstructorTests.fs" />
<Compile Include="ConstructorTests.fs" />
<Compile Include="DallasTests.fs" />
<Compile Include="InlineTests.fs" />
<Compile Include="ChainTests.fs" />
Expand Down
84 changes: 55 additions & 29 deletions src/Fantomas.Core/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3260,6 +3260,17 @@ let sepNlnBetweenTypeAndMembers (node: ITypeDefn) (ctx: Context) : Context =
else
ctx

let genLongPatternInConstructor (pat: Pattern) =
match pat with
| Pattern.Paren patParen ->
genSingleTextNode patParen.OpeningParen
+> expressionFitsOnRestOfLine
(genPat patParen.Pattern)
(indentSepNlnUnindent (genPat patParen.Pattern) +> sepNln)
+> genSingleTextNode patParen.ClosingParen
|> genNode patParen
| _ -> genPat pat

let genImplicitConstructor (node: ImplicitConstructorNode) =
let short =
genXml node.XmlDoc
Expand All @@ -3270,26 +3281,15 @@ let genImplicitConstructor (node: ImplicitConstructorNode) =
+> genPat node.Pattern

let long =
let genPats =
match node.Pattern with
| Pattern.Paren patParen ->
genSingleTextNode patParen.OpeningParen
+> expressionFitsOnRestOfLine
(genPat patParen.Pattern)
(indentSepNlnUnindent (genPat patParen.Pattern) +> sepNln)
+> genSingleTextNode patParen.ClosingParen
|> genNode patParen
| _ -> genPat node.Pattern

indentSepNlnUnindent (
genXml node.XmlDoc
+> genOnelinerAttributes node.Attributes
+> onlyIf node.Attributes.IsSome sepNln
+> expressionFitsOnRestOfLine
(genAccessOpt node.Accessibility +> genPats)
(genAccessOpt node.Accessibility +> genLongPatternInConstructor node.Pattern)
(genAccessOpt node.Accessibility
+> optSingle (fun _ -> sepNln) node.Accessibility
+> genPats)
+> genLongPatternInConstructor node.Pattern)
+> (fun ctx -> onlyIf ctx.Config.AlternativeLongMemberDefinitions sepNln ctx)
)

Expand Down Expand Up @@ -3709,24 +3709,50 @@ let genMemberDefn (md: MemberDefn) =
| MemberDefn.ExternBinding node -> genExternBinding node
| MemberDefn.DoExpr node -> genExpr (Expr.Single node)
| MemberDefn.ExplicitCtor node ->
let short =
genAccessOpt node.Accessibility
+> genSingleTextNode node.New
+> sepSpaceBeforeClassConstructor
+> genPat node.Pattern
+> optSingle (fun alias -> sepSpace +> !- "as" +> sepSpace +> genSingleTextNode alias) node.Alias
+> sepSpace
+> genSingleTextNode node.Equals
+> sepSpace
+> genExpr node.Expr

let long =
leadingExpressionIsMultiline
(genAccessOpt node.Accessibility
+> genSingleTextNode node.New
+> sepSpaceBeforeClassConstructor
+> autoIndentAndNlnIfExpressionExceedsPageWidth (genLongPatternInConstructor node.Pattern)
+> optSingle (fun alias -> sepSpace +> !- "as" +> sepSpace +> genSingleTextNode alias) node.Alias)
(fun isMultiline ctx ->
let genExpr =
genExpr node.Expr
+> optSingle
(fun thenExpr ->
sepNln
+> !- "then"
+> sepSpaceOrIndentAndNlnIfExpressionExceedsPageWidth (genExpr thenExpr))
node.ThenExpr

let short = genSingleTextNode node.Equals +> sepSpace +> genExpr

let long ctx =
if ctx.Config.AlternativeLongMemberDefinitions then
indentSepNlnUnindent (genSingleTextNode node.Equals +> sepNln +> genExpr) ctx
else
(sepSpace +> genSingleTextNode node.Equals +> indentSepNlnUnindent genExpr) ctx

if isMultiline then
long ctx
else
expressionFitsOnRestOfLine short long ctx)

genXml node.XmlDoc
+> genAttributes node.Attributes
+> genAccessOpt node.Accessibility
+> genSingleTextNode node.New
+> sepSpaceBeforeClassConstructor
+> genPat node.Pattern
+> optSingle (fun alias -> sepSpace +> !- "as" +> sepSpace +> genSingleTextNode alias) node.Alias
+> sepSpace
+> genSingleTextNode node.Equals
+> sepSpaceOrIndentAndNlnIfExpressionExceedsPageWidth (
genExpr node.Expr
+> optSingle
(fun thenExpr ->
sepNln
+> !- "then"
+> sepSpaceOrIndentAndNlnIfExpressionExceedsPageWidth (genExpr thenExpr))
node.ThenExpr
)
+> ifElse node.ThenExpr.IsSome long (expressionFitsOnRestOfLine short long)
|> genNode (MemberDefn.Node md)
| MemberDefn.LetBinding node -> genBindings true node.Bindings |> genNode (MemberDefn.Node md)
| MemberDefn.Interface node ->
Expand Down
2 changes: 2 additions & 0 deletions src/Fantomas.Core/SyntaxOak.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2389,6 +2389,8 @@ type MemberDefnInheritNode(inheritKeyword: SingleTextNode, baseType: Type, range
member val Inherit = inheritKeyword
member val BaseType = baseType

/// Secondary constructor
/// new (pat: type) = expr
type MemberDefnExplicitCtorNode
(
xmlDoc: XmlDocNode option,
Expand Down

0 comments on commit 68ae554

Please sign in to comment.