diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index b7b4cce955f09c06454184ee73701db37ca79128..6f2bcb62f80e9421ba3c547f58d3d45294fb29ee 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -1743,7 +1743,7 @@ module TastDefinitionPrinting = let overallL = modifierAndMember ^^ (nameL |> addColonL) ^^ typL layoutXmlDocOfPropInfo denv infoReader pinfo overallL - let layoutTyconDefn (denv: DisplayEnv) (infoReader: InfoReader) ad m simplified typewordL (tcref: TyconRef) = + let layoutTyconDefn (denv: DisplayEnv) (infoReader: InfoReader) ad m simplified isFirstType (tcref: TyconRef) = let g = denv.g // use 4-indent let (-*) = if denv.printVerboseSignatures then (-----) else (---) @@ -1773,6 +1773,12 @@ module TastDefinitionPrinting = else None, tagUnknownType + let typewordL = + if isFirstType then + WordL.keywordType + else + wordL (tagKeyword "and") ^^ layoutAttribs denv start false tycon.TypeOrMeasureKind tycon.Attribs emptyL + let nameL = ConvertLogicalNameToDisplayLayout (tagger >> mkNav tycon.DefinitionRange >> wordL) tycon.DisplayNameCore let nameL = layoutAccessibility denv tycon.Accessibility nameL @@ -2124,7 +2130,7 @@ module TastDefinitionPrinting = |> addLhs typeDeclL - |> layoutAttribs denv start false tycon.TypeOrMeasureKind tycon.Attribs + |> fun tdl -> if isFirstType then layoutAttribs denv start false tycon.TypeOrMeasureKind tycon.Attribs tdl else tdl |> layoutXmlDocOfEntity denv infoReader tcref // Layout: exception definition @@ -2154,8 +2160,8 @@ module TastDefinitionPrinting = | [] -> emptyL | [h] when h.IsFSharpException -> layoutExnDefn denv infoReader (mkLocalEntityRef h) | h :: t -> - let x = layoutTyconDefn denv infoReader ad m false WordL.keywordType (mkLocalEntityRef h) - let xs = List.map (mkLocalEntityRef >> layoutTyconDefn denv infoReader ad m false (wordL (tagKeyword "and"))) t + let x = layoutTyconDefn denv infoReader ad m false true (mkLocalEntityRef h) + let xs = List.map (mkLocalEntityRef >> layoutTyconDefn denv infoReader ad m false false) t aboveListL (x :: xs) let rec fullPath (mspec: ModuleOrNamespace) acc = @@ -2267,7 +2273,7 @@ module TastDefinitionPrinting = elif eref.IsFSharpException then layoutExnDefn denv infoReader eref else - layoutTyconDefn denv infoReader ad m true WordL.keywordType eref + layoutTyconDefn denv infoReader ad m true true eref //-------------------------------------------------------------------------- @@ -2561,7 +2567,7 @@ let layoutExnDef denv infoReader x = x |> TastDefinitionPrinting.layoutExnDefn d let stringOfTyparConstraints denv x = x |> PrintTypes.layoutConstraintsWithInfo denv SimplifyTypes.typeSimplificationInfo0 |> showL -let layoutTyconDefn denv infoReader ad m (* width *) x = TastDefinitionPrinting.layoutTyconDefn denv infoReader ad m true WordL.keywordType (mkLocalEntityRef x) (* |> Display.squashTo width *) +let layoutTyconDefn denv infoReader ad m (* width *) x = TastDefinitionPrinting.layoutTyconDefn denv infoReader ad m true true (mkLocalEntityRef x) (* |> Display.squashTo width *) let layoutEntityDefn denv infoReader ad m x = TastDefinitionPrinting.layoutEntityDefn denv infoReader ad m x diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 75e0f8a03236f346f485233dbed85ac9767a8ffb..6203b71fd6f3fcb1e9636be6f2a24de5c9c3d964 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -204,6 +204,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs b/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs new file mode 100644 index 0000000000000000000000000000000000000000..d7f81a04f50aa69b04d8c69b15ea4c66a454b698 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs @@ -0,0 +1,77 @@ +module FSharp.Compiler.ComponentTests.Signatures.TypeTests + +open Xunit +open FsUnit +open FSharp.Test.Compiler +open FSharp.Compiler.ComponentTests.Signatures.TestHelpers + +[] +let ``Recursive type with attribute`` () = + FSharp + """ +namespace Foo.Types + +open System.Collections.Generic + +type FormatSelectionRequest = + { + 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 + /// Range follows the same semantics of the FSharp Compiler Range type. + Range: FormatSelectionRange + } + + member this.IsSignatureFile = this.FilePath.EndsWith(".fsi") + +and FormatSelectionRange = + struct + val StartLine: int + val StartColumn: int + val EndLine: int + val EndColumn: int + + new(startLine: int, startColumn: int, endLine: int, endColumn: int) = + { StartLine = startLine + StartColumn = startColumn + EndLine = endLine + EndColumn = endColumn } + end +""" + |> printSignatures + |> prependNewline + |> should equal + """ +namespace Foo.Types + + type FormatSelectionRequest = + { + SourceCode: string + + /// File path will be used to identify the .editorconfig options + /// Unless the configuration is passed + FilePath: string + + /// Overrides the found .editorconfig. + Config: System.Collections.Generic.IReadOnlyDictionary option + + /// Range follows the same semantics of the FSharp Compiler Range type. + Range: FormatSelectionRange + } + + member IsSignatureFile: bool + + and [] FormatSelectionRange = + + new: startLine: int * startColumn: int * endLine: int * endColumn: int -> FormatSelectionRange + + val StartLine: int + + val StartColumn: int + + val EndLine: int + + val EndColumn: int"""