From 08c50dbffae52fbbc0fcf9f091058c75be206e9a Mon Sep 17 00:00:00 2001 From: dawe Date: Wed, 24 May 2023 18:08:23 +0200 Subject: [PATCH 1/6] "naked" single case unions like "type U = C" are interpreted as ITypeAbbreviationRepresentation Add the needed code to add a bar and fix their indentation --- .../src/Generate/GenerateProvider.fs | 15 ++++++++++++++- .../Repr - Union - No bar - Single 03.fs | 4 ++++ .../Repr - Union - No bar - Single 03.fs.gold | 13 +++++++++++++ .../Generate/FSharpGenerateOverridesTest.fs | 1 + 4 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 03.fs create mode 100644 ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 03.fs.gold diff --git a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs index 88040accfc..e6d2e943f2 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs @@ -11,12 +11,14 @@ open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Generate open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl.Cache2 open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl.Tree +open JetBrains.ReSharper.Plugins.FSharp.Psi.Parsing open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.ReSharper.Plugins.FSharp.Psi.Util open JetBrains.ReSharper.Plugins.FSharp.Util open JetBrains.ReSharper.Psi open JetBrains.ReSharper.Psi.DataContext open JetBrains.ReSharper.Psi.ExtensionsAPI +open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree open JetBrains.ReSharper.Psi.Impl open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Psi.Util @@ -293,6 +295,11 @@ type FSharpOverridingMembersBuilder() = if diff > 0 then shiftWithWhitespaceBefore -diff unionRepr null, null + | :? ITypeAbbreviationRepresentation as abbrRepr -> + let diff = origTypeReprIndent - desiredIndent + if diff > 0 then shiftWithWhitespaceBefore -diff abbrRepr + null, null + | _ -> null, null let reindentRange additionalIndent (range: TreeRange) = @@ -323,7 +330,13 @@ type FSharpOverridingMembersBuilder() = | :? IUnionRepresentation as unionRepr -> unionRepr.UnionCasesEnumerable |> Seq.tryHead - |> Option.iter EnumCaseLikeDeclarationUtil.addBarIfNeeded + |> Option.iter EnumCaseLikeDeclarationUtil.addBarIfNeeded + | :? ITypeAbbreviationRepresentation as abbrRepr -> + if isNotNull abbrRepr.FirstChild then + addNodesBefore abbrRepr.FirstChild [ + FSharpTokenType.BAR.CreateLeafElement() + Whitespace() + ] |> ignore | _ -> () addNewLineBeforeReprIfNeeded typeDecl typeRepr diff --git a/ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 03.fs b/ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 03.fs new file mode 100644 index 0000000000..af28b079a3 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 03.fs @@ -0,0 +1,4 @@ +// ${KIND:Overrides} +// ${SELECT0:ToString():System.String} + +type SingleCaseUnion = Case{caret} diff --git a/ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 03.fs.gold b/ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 03.fs.gold new file mode 100644 index 0000000000..2b396fb852 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 03.fs.gold @@ -0,0 +1,13 @@ +Provided elements: + 0: ToString():System.String + 1: Equals(System.Object):System.Boolean + 2: GetHashCode():System.Int32 + 3: Finalize():System.Void + +// ${KIND:Overrides} +// ${SELECT0:ToString():System.String} + +type SingleCaseUnion = + | Case + + override this.ToString() = {selstart}failwith "todo"{selend} diff --git a/ReSharper.FSharp/test/src/FSharp.Tests/Generate/FSharpGenerateOverridesTest.fs b/ReSharper.FSharp/test/src/FSharp.Tests/Generate/FSharpGenerateOverridesTest.fs index abc1958a84..d94af1fc9e 100644 --- a/ReSharper.FSharp/test/src/FSharp.Tests/Generate/FSharpGenerateOverridesTest.fs +++ b/ReSharper.FSharp/test/src/FSharp.Tests/Generate/FSharpGenerateOverridesTest.fs @@ -104,6 +104,7 @@ type FSharpGenerateOverridesTest() = [] member x.``Repr - Union - No bar - Multiple 03``() = x.DoNamedTest() [] member x.``Repr - Union - No bar - Single 01``() = x.DoNamedTest() [] member x.``Repr - Union - No bar - Single 02``() = x.DoNamedTest() + [] member x.``Repr - Union - No bar - Single 03``() = x.DoNamedTest() [] member x.``Repr - Union 01``() = x.DoNamedTest() [] member x.``Repr - Union 02``() = x.DoNamedTest() From 864f59544e9c5b2c7a4d52be13fcaa4350a09ee5 Mon Sep 17 00:00:00 2001 From: dawe Date: Fri, 26 May 2023 18:05:55 +0200 Subject: [PATCH 2/6] Replace the ITypeAbbreviationRepresentation node with a newly created IUnionRepresentation node. Use a Navigator.Set* method and mutate the context.Anchor if needed. --- .../src/Generate/GenerateProvider.fs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs index e6d2e943f2..30a602c878 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs @@ -324,21 +324,23 @@ type FSharpOverridingMembersBuilder() = use disableFormatter = new DisableCodeFormatter() let typeDecl = context.Root :?> IFSharpTypeDeclaration - let typeRepr = typeDecl.TypeRepresentation - match typeRepr with + match typeDecl.TypeRepresentation with | :? IUnionRepresentation as unionRepr -> unionRepr.UnionCasesEnumerable |> Seq.tryHead |> Option.iter EnumCaseLikeDeclarationUtil.addBarIfNeeded - | :? ITypeAbbreviationRepresentation as abbrRepr -> - if isNotNull abbrRepr.FirstChild then - addNodesBefore abbrRepr.FirstChild [ - FSharpTokenType.BAR.CreateLeafElement() - Whitespace() - ] |> ignore + | :? ITypeAbbreviationRepresentation as abbrRepr when abbrRepr.CanBeUnionCase -> + let factory = typeDecl.CreateElementFactory() + let declGroup = factory.CreateModuleMember($"type U = | {abbrRepr.AbbreviatedTypeOrUnionCase.DeclaredName}") + let typeDeclaration = declGroup.FirstChild.As() + let repr = typeDeclaration.TypeRepresentation.As() + let nav = FSharpTypeDeclarationNavigator.GetByTypeRepresentation(abbrRepr) + let newRepr = nav.SetTypeRepresentation(repr) + if context.Anchor == abbrRepr then context.Anchor <- newRepr | _ -> () + let typeRepr = typeDecl.TypeRepresentation addNewLineBeforeReprIfNeeded typeDecl typeRepr let anchor: ITreeNode = From bee1a4f7628d5edf0ac7c4483083843892239add Mon Sep 17 00:00:00 2001 From: dawe Date: Fri, 26 May 2023 19:04:25 +0200 Subject: [PATCH 3/6] - use mangleNameIfNecessary and SourceName instead of DeclaredName - remove cast to IUnionRepresentation - add test case for type U = ``A B`` --- .../src/Generate/GenerateProvider.fs | 5 +++-- .../overrides/Repr - Union - No bar - Single 04.fs | 4 ++++ .../Repr - Union - No bar - Single 04.fs.gold | 13 +++++++++++++ .../Generate/FSharpGenerateOverridesTest.fs | 1 + 4 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 04.fs create mode 100644 ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 04.fs.gold diff --git a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs index 30a602c878..9a52be7eb8 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs @@ -332,9 +332,10 @@ type FSharpOverridingMembersBuilder() = |> Option.iter EnumCaseLikeDeclarationUtil.addBarIfNeeded | :? ITypeAbbreviationRepresentation as abbrRepr when abbrRepr.CanBeUnionCase -> let factory = typeDecl.CreateElementFactory() - let declGroup = factory.CreateModuleMember($"type U = | {abbrRepr.AbbreviatedTypeOrUnionCase.DeclaredName}") + let caseName = FSharpNamingService.mangleNameIfNecessary abbrRepr.AbbreviatedTypeOrUnionCase.SourceName + let declGroup = factory.CreateModuleMember($"type U = | {caseName}") let typeDeclaration = declGroup.FirstChild.As() - let repr = typeDeclaration.TypeRepresentation.As() + let repr = typeDeclaration.TypeRepresentation let nav = FSharpTypeDeclarationNavigator.GetByTypeRepresentation(abbrRepr) let newRepr = nav.SetTypeRepresentation(repr) if context.Anchor == abbrRepr then context.Anchor <- newRepr diff --git a/ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 04.fs b/ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 04.fs new file mode 100644 index 0000000000..1396d5ce0f --- /dev/null +++ b/ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 04.fs @@ -0,0 +1,4 @@ +// ${KIND:Overrides} +// ${SELECT0:ToString():System.String} + +type U = ``A{caret} B`` diff --git a/ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 04.fs.gold b/ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 04.fs.gold new file mode 100644 index 0000000000..62578b09b4 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/generate/overrides/Repr - Union - No bar - Single 04.fs.gold @@ -0,0 +1,13 @@ +Provided elements: + 0: ToString():System.String + 1: Equals(System.Object):System.Boolean + 2: GetHashCode():System.Int32 + 3: Finalize():System.Void + +// ${KIND:Overrides} +// ${SELECT0:ToString():System.String} + +type U = + | ``A B`` + + override this.ToString() = {selstart}failwith "todo"{selend} diff --git a/ReSharper.FSharp/test/src/FSharp.Tests/Generate/FSharpGenerateOverridesTest.fs b/ReSharper.FSharp/test/src/FSharp.Tests/Generate/FSharpGenerateOverridesTest.fs index d94af1fc9e..6d6927d360 100644 --- a/ReSharper.FSharp/test/src/FSharp.Tests/Generate/FSharpGenerateOverridesTest.fs +++ b/ReSharper.FSharp/test/src/FSharp.Tests/Generate/FSharpGenerateOverridesTest.fs @@ -105,6 +105,7 @@ type FSharpGenerateOverridesTest() = [] member x.``Repr - Union - No bar - Single 01``() = x.DoNamedTest() [] member x.``Repr - Union - No bar - Single 02``() = x.DoNamedTest() [] member x.``Repr - Union - No bar - Single 03``() = x.DoNamedTest() + [] member x.``Repr - Union - No bar - Single 04``() = x.DoNamedTest() [] member x.``Repr - Union 01``() = x.DoNamedTest() [] member x.``Repr - Union 02``() = x.DoNamedTest() From 0df938f44a2d611e32e9a1946fbba458e41522e3 Mon Sep 17 00:00:00 2001 From: dawe Date: Fri, 26 May 2023 19:45:21 +0200 Subject: [PATCH 4/6] Update ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs Co-authored-by: Eugene Auduchinok --- .../src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs index 9a52be7eb8..4a52918da7 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs @@ -334,7 +334,7 @@ type FSharpOverridingMembersBuilder() = let factory = typeDecl.CreateElementFactory() let caseName = FSharpNamingService.mangleNameIfNecessary abbrRepr.AbbreviatedTypeOrUnionCase.SourceName let declGroup = factory.CreateModuleMember($"type U = | {caseName}") - let typeDeclaration = declGroup.FirstChild.As() + let typeDeclaration = declGroup.TypeDeclarations[0] :?> IFSharpTypeDeclaration let repr = typeDeclaration.TypeRepresentation let nav = FSharpTypeDeclarationNavigator.GetByTypeRepresentation(abbrRepr) let newRepr = nav.SetTypeRepresentation(repr) From fb8f4be533e1aee63ac66b2757468c5e381a6218 Mon Sep 17 00:00:00 2001 From: dawe Date: Fri, 26 May 2023 19:50:53 +0200 Subject: [PATCH 5/6] call SetTypeRepresentation() on typeDecl directly --- .../src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs index 4a52918da7..f109c72d90 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs @@ -333,11 +333,10 @@ type FSharpOverridingMembersBuilder() = | :? ITypeAbbreviationRepresentation as abbrRepr when abbrRepr.CanBeUnionCase -> let factory = typeDecl.CreateElementFactory() let caseName = FSharpNamingService.mangleNameIfNecessary abbrRepr.AbbreviatedTypeOrUnionCase.SourceName - let declGroup = factory.CreateModuleMember($"type U = | {caseName}") + let declGroup = factory.CreateModuleMember($"type U = | {caseName}") :?> ITypeDeclarationGroup let typeDeclaration = declGroup.TypeDeclarations[0] :?> IFSharpTypeDeclaration let repr = typeDeclaration.TypeRepresentation - let nav = FSharpTypeDeclarationNavigator.GetByTypeRepresentation(abbrRepr) - let newRepr = nav.SetTypeRepresentation(repr) + let newRepr = typeDecl.SetTypeRepresentation(repr) if context.Anchor == abbrRepr then context.Anchor <- newRepr | _ -> () From 61a307d1a89efb97dcf09449db339b8b4ae14c15 Mon Sep 17 00:00:00 2001 From: dawe Date: Mon, 29 May 2023 17:57:33 +0200 Subject: [PATCH 6/6] combine branches for IUnionRepresentation and ITypeAbbreviationRepresentation --- .../src/Generate/GenerateProvider.fs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs index f109c72d90..7bb171f273 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Generate/GenerateProvider.fs @@ -290,14 +290,10 @@ type FSharpOverridingMembersBuilder() = normalizeReprEnd recordRepr.LeftBrace recordRepr.RightBrace recordRepr.LeftBrace, recordRepr.RightBrace - | :? IUnionRepresentation as unionRepr -> + | :? IUnionRepresentation + | :? ITypeAbbreviationRepresentation as typeRepr -> let diff = origTypeReprIndent - desiredIndent - if diff > 0 then shiftWithWhitespaceBefore -diff unionRepr - null, null - - | :? ITypeAbbreviationRepresentation as abbrRepr -> - let diff = origTypeReprIndent - desiredIndent - if diff > 0 then shiftWithWhitespaceBefore -diff abbrRepr + if diff > 0 then shiftWithWhitespaceBefore -diff typeRepr null, null | _ -> null, null