From 52db54b2c8fcba431aab728b27bba18a3ce115dc Mon Sep 17 00:00:00 2001 From: nojaf Date: Tue, 13 Sep 2022 15:01:53 +0200 Subject: [PATCH 1/3] Add failing test --- .../FSharp.Compiler.ComponentTests.fsproj | 1 + .../Signatures/TypeTests.fs | 80 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 4acda7d0cd7..d1d821777fe 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -201,6 +201,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs b/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs new file mode 100644 index 00000000000..89424e989b6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs @@ -0,0 +1,80 @@ +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 +""" From 0cf1aa35af17966370251913e12e27a9a6b72cd3 Mon Sep 17 00:00:00 2001 From: nojaf Date: Tue, 13 Sep 2022 15:51:03 +0200 Subject: [PATCH 2/3] Attempt to print attributes after and keyword. --- src/Compiler/Checking/NicePrint.fs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index dbbe333b9cd..485d94aa386 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -1757,7 +1757,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 (---) @@ -1787,6 +1787,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 @@ -2138,7 +2144,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 @@ -2168,8 +2174,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 = @@ -2281,7 +2287,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 //-------------------------------------------------------------------------- @@ -2575,7 +2581,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 From d5aff32f2d4d4f48ee2e81fd4c3053c5e3a12c80 Mon Sep 17 00:00:00 2001 From: nojaf Date: Tue, 13 Sep 2022 16:11:51 +0200 Subject: [PATCH 3/3] Update indentation in unit test. --- .../Signatures/TypeTests.fs | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs b/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs index 89424e989b6..d7f81a04f50 100644 --- a/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Signatures/TypeTests.fs @@ -47,34 +47,31 @@ and FormatSelectionRange = """ namespace Foo.Types - type FormatSelectionRequest = - { - SourceCode: string + type FormatSelectionRequest = + { + SourceCode: string - /// File path will be used to identify the .editorconfig options - /// Unless the configuration is passed - FilePath: 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 + /// Overrides the found .editorconfig. + Config: System.Collections.Generic.IReadOnlyDictionary option - /// Range follows the same semantics of the FSharp Compiler Range type. - Range: FormatSelectionRange - } + /// Range follows the same semantics of the FSharp Compiler Range type. + Range: FormatSelectionRange + } - member IsSignatureFile: bool + member IsSignatureFile: bool - and [] FormatSelectionRange = + and [] FormatSelectionRange = - new: startLine: int * startColumn: int * endLine: int * endColumn: int -> - FormatSelectionRange + new: startLine: int * startColumn: int * endLine: int * endColumn: int -> FormatSelectionRange - val StartLine: int + val StartLine: int - val StartColumn: int + val StartColumn: int - val EndLine: int + val EndLine: int - val EndColumn: int -""" + val EndColumn: int"""