From 2229506980c9cdb348d9f284b5e51ae72cfbfe31 Mon Sep 17 00:00:00 2001 From: nojaf Date: Thu, 6 Jul 2023 10:44:30 +0200 Subject: [PATCH 1/5] Add empty quickfix for ValueNotContainedMutabilityCompiledNamesDifferError. --- .../src/Stages/FcsErrorsStageProcessBase.fs | 2 ++ .../FSharp.Psi.Intentions.fsproj | 1 + .../QuickFixes/UpdateCompiledNameInSignatureFix.fs | 12 ++++++++++++ .../src/Daemon/Highlightings/FcsErrors.xml | 11 +++++++++++ 4 files changed, 26 insertions(+) create mode 100644 ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateCompiledNameInSignatureFix.fs diff --git a/ReSharper.FSharp/src/FSharp.Psi.Daemon/src/Stages/FcsErrorsStageProcessBase.fs b/ReSharper.FSharp/src/FSharp.Psi.Daemon/src/Stages/FcsErrorsStageProcessBase.fs index a73cea2a62..8e983061b2 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Daemon/src/Stages/FcsErrorsStageProcessBase.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Daemon/src/Stages/FcsErrorsStageProcessBase.fs @@ -319,6 +319,8 @@ type FcsErrorsStageProcessBase(fsFile, daemonProcess) = | ValueNotContainedMutability -> if error.Message.EndsWith("The mutability attributes differ") then createHighlightingFromNodeWithMessage ValueNotContainedMutabilityAttributesDifferError range error + elif error.Message.EndsWith("The compiled names differ") then + createHighlightingFromNodeWithMessage ValueNotContainedMutabilityCompiledNamesDifferError range error else createGenericHighlighting error range diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj b/ReSharper.FSharp/src/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj index 5c9e7bc265..ccb1bb1920 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj @@ -101,6 +101,7 @@ + QUICKFIX JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateCompiledNameInSignatureFix.fs b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateCompiledNameInSignatureFix.fs new file mode 100644 index 0000000000..bfc919da67 --- /dev/null +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateCompiledNameInSignatureFix.fs @@ -0,0 +1,12 @@ +namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes + +open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree +open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings +open JetBrains.ReSharper.Resources.Shell +open JetBrains.ReSharper.Plugins.FSharp.Psi + +type UpdateCompiledNameInSignatureFix(error: ValueNotContainedMutabilityCompiledNamesDifferError) = + inherit FSharpQuickFixBase() + + override this.IsAvailable(cache) = failwith "todo" + override this.Text = failwith "todo" diff --git a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Daemon/Highlightings/FcsErrors.xml b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Daemon/Highlightings/FcsErrors.xml index 891563e5b0..08a6717b64 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Services/src/Daemon/Highlightings/FcsErrors.xml +++ b/ReSharper.FSharp/src/FSharp.Psi.Services/src/Daemon/Highlightings/FcsErrors.xml @@ -218,6 +218,17 @@ UpdateMutabilityInSignatureFix + + + + pat.GetNavigationRange() + + fcsMessage + + + UpdateCompiledNameInSignatureFix + + From 6d36b13621addb56930f67fbe0c749b53837233b Mon Sep 17 00:00:00 2001 From: nojaf Date: Thu, 6 Jul 2023 10:44:51 +0200 Subject: [PATCH 2/5] Extract tryFindBindingPairFromTopReferencePat to SignatureFixUtil.fs --- .../src/QuickFixes/SignatureFixUtil.fs | 15 +++++++++ .../UpdateMutabilityInSignatureFix.fs | 33 +++---------------- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/SignatureFixUtil.fs b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/SignatureFixUtil.fs index ace35ecac4..4b7a023318 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/SignatureFixUtil.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/SignatureFixUtil.fs @@ -123,3 +123,18 @@ let updateSignatureFieldDecls (implementationRecordRepr: IRecordRepresentation) if signatureFieldCount > implementationRecordRepr.FieldDeclarations.Count then [ implementationRecordRepr.FieldDeclarations.Count .. (signatureFieldCount - 1) ] |> List.iter (fun idx -> signatureRecordRepr.FieldDeclarations.Item idx |> deleteChild) + +/// ImplementationBinding * SignatureBinding +/// Implementation top reference pattern. +let tryFindBindingPairFromTopReferencePat (pat: ITopReferencePat) = + match pat.Binding, pat.DeclaredElement.As() with + | null, _ | _, null -> None + | implBinding, fsMember -> + + fsMember.GetDeclarations() + |> Seq.tryPick (function + | :? IReferencePat as pat when pat.IsFSharpSigFile() -> + Option.ofObj pat.Binding + |> Option.map (fun sigBinding -> implBinding, sigBinding) + | _ -> None + ) diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateMutabilityInSignatureFix.fs b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateMutabilityInSignatureFix.fs index 2e9bcb5560..9c6d7db7b4 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateMutabilityInSignatureFix.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateMutabilityInSignatureFix.fs @@ -1,45 +1,22 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes -open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings open JetBrains.ReSharper.Resources.Shell -open JetBrains.ReSharper.Plugins.FSharp.Psi +open JetBrains.ReSharper.Plugins.FSharp.Psi.Intentions.QuickFixes type UpdateMutabilityInSignatureFix(error: ValueNotContainedMutabilityAttributesDifferError) = inherit FSharpQuickFixBase() - let tryFindBindingSignature (declaredElement: IFSharpMember) = - declaredElement.GetDeclarations() - |> Seq.tryPick (function - | :? IReferencePat as pat when pat.IsFSharpSigFile() -> Option.ofObj pat.Binding - | _ -> None - ) - - let tryFindImplementationBindingInfo (pat: ITopReferencePat) = - if isNull pat then None else - - match pat.Binding, pat.DeclaredElement.As() with - | null, _ | _, null -> None - | binding, fsMember -> - - let mfv = fsMember.Mfv - if isNull mfv then None else - - Some(binding, fsMember) - let mutable bindingSignature = null override x.Text = $"Update mutability for {error.Pat.Identifier.Name} in signature" override x.IsAvailable _ = - match tryFindImplementationBindingInfo error.Pat with + match SignatureFixUtil.tryFindBindingPairFromTopReferencePat error.Pat with | None -> false - | Some (topLevelBinding, declaredElement) -> - match tryFindBindingSignature declaredElement with - | None -> false - | Some signature -> - bindingSignature <- signature - topLevelBinding.IsMutable <> signature.IsMutable + | Some (topLevelBinding, signature) -> + bindingSignature <- signature + topLevelBinding.IsMutable <> signature.IsMutable override x.ExecutePsiTransaction _ = use writeCookie = WriteLockCookie.Create(error.Pat.IsPhysical()) From 76297795a423cf66ab01e7c9370e95a0dd85b648 Mon Sep 17 00:00:00 2001 From: nojaf Date: Thu, 6 Jul 2023 14:33:45 +0200 Subject: [PATCH 3/5] Add CompiledName to signature file. --- .../src/Util/FSharpPredefinedType.fs | 3 ++ .../src/QuickFixes/SignatureFixUtil.fs | 54 +++++++++++++++---- .../UpdateCompiledNameInSignatureFix.fs | 50 +++++++++++++++-- .../UpdateMutabilityInSignatureFix.fs | 6 +-- .../Attribute in implementation - 01.fs | 4 ++ .../Attribute in implementation - 01.fs.gold | 4 ++ .../Attribute in implementation - 01.fsi | 3 ++ .../Attribute in implementation - 01.fsi.gold | 4 ++ .../FSharp.Intentions.Tests.fsproj | 1 + .../UpdateCompiledNameInSignatureFixTest.fs | 11 ++++ 10 files changed, 123 insertions(+), 17 deletions(-) create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fs create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fs.gold create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fsi create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fsi.gold create mode 100644 ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/UpdateCompiledNameInSignatureFixTest.fs diff --git a/ReSharper.FSharp/src/FSharp.Common/src/Util/FSharpPredefinedType.fs b/ReSharper.FSharp/src/FSharp.Common/src/Util/FSharpPredefinedType.fs index 3ac9e7b67b..d3608c58bd 100644 --- a/ReSharper.FSharp/src/FSharp.Common/src/Util/FSharpPredefinedType.fs +++ b/ReSharper.FSharp/src/FSharp.Common/src/Util/FSharpPredefinedType.fs @@ -34,6 +34,9 @@ let cliEventAttrTypeName = clrTypeName "Microsoft.FSharp.Core.CLIEventAttribute" [] let structAttrTypeName = clrTypeName "Microsoft.FSharp.Core.StructAttribute" +[] +let compiledNameAttrTypeName = clrTypeName "Microsoft.FSharp.Core.CompiledNameAttribute" + [] let fsListTypeName = clrTypeName "Microsoft.FSharp.Collections.FSharpList`1" diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/SignatureFixUtil.fs b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/SignatureFixUtil.fs index 4b7a023318..cce0b8c9a3 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/SignatureFixUtil.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/SignatureFixUtil.fs @@ -124,17 +124,49 @@ let updateSignatureFieldDecls (implementationRecordRepr: IRecordRepresentation) [ implementationRecordRepr.FieldDeclarations.Count .. (signatureFieldCount - 1) ] |> List.iter (fun idx -> signatureRecordRepr.FieldDeclarations.Item idx |> deleteChild) -/// ImplementationBinding * SignatureBinding -/// Implementation top reference pattern. -let tryFindBindingPairFromTopReferencePat (pat: ITopReferencePat) = - match pat.Binding, pat.DeclaredElement.As() with +type BindingPair = + | BindingPair of + implBinding: IBindingLikeDeclaration * + implMember: IFSharpMember * + sigBinding: IBindingLikeDeclaration * + sigMember: IFSharpMember + +let tryFindBindingPairFromTopReferencePat (implTopRefPat: ITopReferencePat) = + match implTopRefPat.Binding, implTopRefPat.DeclaredElement.As() with | null, _ | _, null -> None - | implBinding, fsMember -> + | implBinding, implMember -> - fsMember.GetDeclarations() - |> Seq.tryPick (function - | :? IReferencePat as pat when pat.IsFSharpSigFile() -> - Option.ofObj pat.Binding - |> Option.map (fun sigBinding -> implBinding, sigBinding) + let tryPickFromDeclaration (condition: IReferencePat -> bool) (declaration: IDeclaration) = + match declaration with + | :? IReferencePat as pat when pat.IsFSharpSigFile() && condition pat -> + Option.both (Option.ofObj pat.Binding) (Option.ofObj (pat.DeclaredElement.As())) + |> Option.map (fun (sigBinding, sigMember) -> BindingPair(implBinding, implMember, sigBinding, sigMember)) | _ -> None - ) + + implMember.GetDeclarations() + |> Seq.tryPick (tryPickFromDeclaration (fun _ -> true)) + |> Option.orElseWith (fun () -> + let parentDeclarations = implMember.ContainingType.GetDeclarations() + + // Find the parent signature counter part + let parentSignatureDeclaration = + parentDeclarations + |> Seq.tryPick (fun d -> + match d with + | :? INamedModuleDeclaration as signatureModule when signatureModule.IsFSharpSigFile() -> + Some signatureModule + | _ -> None) + + parentSignatureDeclaration + |> Option.bind (fun signatureModule -> + signatureModule.MemberDeclarations + |> Seq.tryPick ( + tryPickFromDeclaration (fun (sigRefPat: IReferencePat) -> + match implBinding.HeadPattern with + | :? IReferencePat as implPat -> + implPat.DeclaredName = sigRefPat.DeclaredName + || implPat.Identifier.Name = sigRefPat.Identifier.Name + | _ -> false) + ) + ) + ) \ No newline at end of file diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateCompiledNameInSignatureFix.fs b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateCompiledNameInSignatureFix.fs index bfc919da67..636b145027 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateCompiledNameInSignatureFix.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateCompiledNameInSignatureFix.fs @@ -1,12 +1,56 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes -open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings +open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util +open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree +open JetBrains.ReSharper.Plugins.FSharp.Util +open JetBrains.ReSharper.Psi.ExtensionsAPI open JetBrains.ReSharper.Resources.Shell +open type JetBrains.ReSharper.Plugins.FSharp.Psi.FSharpTreeNodeExtensions +open JetBrains.ReSharper.Plugins.FSharp.Psi.PsiUtil.PsiModificationUtil +open JetBrains.ReSharper.Plugins.FSharp.Psi.Intentions.QuickFixes.SignatureFixUtil open JetBrains.ReSharper.Plugins.FSharp.Psi +open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl.Tree type UpdateCompiledNameInSignatureFix(error: ValueNotContainedMutabilityCompiledNamesDifferError) = inherit FSharpQuickFixBase() - override this.IsAvailable(cache) = failwith "todo" - override this.Text = failwith "todo" + let mutable bindingImplementation = null + let mutable bindingSignature = null + + let tryFindCompiledNameAttribute (binding: IBindingLikeDeclaration) = + binding.Attributes + |> Seq.tryFind (FSharpAttributesUtil.resolvesToType FSharpPredefinedType.compiledNameAttrTypeName) + + override this.Text = $"Update CompiledName for {error.Pat.Identifier.Name} in signature" + + override x.IsAvailable _ = + match tryFindBindingPairFromTopReferencePat error.Pat with + | None -> false + | Some (BindingPair(implementation, implMember, signature, sigMember)) -> + bindingImplementation <- implementation + bindingSignature <- signature + implMember.Mfv.CompiledName <> sigMember.Mfv.CompiledName + + override x.ExecutePsiTransaction _ = + use writeCookie = WriteLockCookie.Create(error.Pat.IsPhysical()) + use disableFormatter = new DisableCodeFormatter() + + let signatureCompiledNameAttribute = tryFindCompiledNameAttribute bindingSignature + let implementationCompiledNamedAttribute = tryFindCompiledNameAttribute bindingImplementation + match implementationCompiledNamedAttribute, signatureCompiledNameAttribute with + | None, None -> failwith "both don't have the attribute, add the attribute to the signature" // weird situation though + | Some value, None -> + if bindingSignature.Attributes.IsEmpty then + // We create an elementFactory with the implementation file because the CreateEmptyAttributeList is tied to implementation files only. + let elementFactory = bindingImplementation.CreateElementFactory() + let attributeList = elementFactory.CreateEmptyAttributeList() + FSharpAttributesUtil.addAttribute attributeList value |> ignore + addNodesBefore bindingSignature [ + attributeList + NewLine(bindingSignature.GetLineEnding()) + ] |> ignore + else + FSharpAttributesUtil.addAttributeAfter (Seq.last bindingSignature.Attributes) value + | None, Some value -> failwith "add the attribute to the signature" + | Some value, Some value1 -> failwith "update the value of the signature" diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateMutabilityInSignatureFix.fs b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateMutabilityInSignatureFix.fs index 9c6d7db7b4..2e30b0ddab 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateMutabilityInSignatureFix.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateMutabilityInSignatureFix.fs @@ -2,7 +2,7 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings open JetBrains.ReSharper.Resources.Shell -open JetBrains.ReSharper.Plugins.FSharp.Psi.Intentions.QuickFixes +open JetBrains.ReSharper.Plugins.FSharp.Psi.Intentions.QuickFixes.SignatureFixUtil type UpdateMutabilityInSignatureFix(error: ValueNotContainedMutabilityAttributesDifferError) = inherit FSharpQuickFixBase() @@ -12,9 +12,9 @@ type UpdateMutabilityInSignatureFix(error: ValueNotContainedMutabilityAttributes override x.Text = $"Update mutability for {error.Pat.Identifier.Name} in signature" override x.IsAvailable _ = - match SignatureFixUtil.tryFindBindingPairFromTopReferencePat error.Pat with + match tryFindBindingPairFromTopReferencePat error.Pat with | None -> false - | Some (topLevelBinding, signature) -> + | Some (BindingPair(implBinding = topLevelBinding; sigBinding = signature)) -> bindingSignature <- signature topLevelBinding.IsMutable <> signature.IsMutable diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fs b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fs new file mode 100644 index 0000000000..d167cbc9e0 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fs @@ -0,0 +1,4 @@ +module A + +[] +let x{caret} (a:int) (b:int) = a + 1 diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fs.gold b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fs.gold new file mode 100644 index 0000000000..6e67b0d6af --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fs.gold @@ -0,0 +1,4 @@ +module A + +[] +let x{caret} (a:int) (b:int) = a + 1 diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fsi b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fsi new file mode 100644 index 0000000000..16afb5025b --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fsi @@ -0,0 +1,3 @@ +module A + +val x: a:int -> b:int -> int diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fsi.gold b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fsi.gold new file mode 100644 index 0000000000..9261da7595 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 01.fsi.gold @@ -0,0 +1,4 @@ +module A + +[] +val x: a:int -> b:int -> int diff --git a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/FSharp.Intentions.Tests.fsproj b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/FSharp.Intentions.Tests.fsproj index 851df9608e..86c47ff1ea 100644 --- a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/FSharp.Intentions.Tests.fsproj +++ b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/FSharp.Intentions.Tests.fsproj @@ -118,6 +118,7 @@ + diff --git a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/UpdateCompiledNameInSignatureFixTest.fs b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/UpdateCompiledNameInSignatureFixTest.fs new file mode 100644 index 0000000000..6413289250 --- /dev/null +++ b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/UpdateCompiledNameInSignatureFixTest.fs @@ -0,0 +1,11 @@ +namespace JetBrains.ReSharper.Plugins.FSharp.Tests.Intentions.QuickFixes + +open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes +open NUnit.Framework + +type UpdateCompiledNameInSignatureFixTest() = + inherit FSharpQuickFixTestBase() + + override x.RelativeTestDataPath = "features/quickFixes/updateCompiledNameInSignatureFix" + + [] member x.``Attribute in implementation - 01`` () = x.DoNamedTestWithSignature() From 578f5d7404adce333af883f805c30436148454a4 Mon Sep 17 00:00:00 2001 From: nojaf Date: Mon, 10 Jul 2023 15:03:34 +0200 Subject: [PATCH 4/5] Implement other pattern matches. --- .../UpdateCompiledNameInSignatureFix.fs | 20 ++++++++++++++----- .../Attribute in implementation - 02.fs | 4 ++++ .../Attribute in implementation - 02.fs.gold | 4 ++++ .../Attribute in implementation - 02.fsi | 4 ++++ .../Attribute in implementation - 02.fsi.gold | 4 ++++ .../No attribute in implementation - 01.fs | 3 +++ ...o attribute in implementation - 01.fs.gold | 3 +++ .../No attribute in implementation - 01.fsi | 4 ++++ ... attribute in implementation - 01.fsi.gold | 4 ++++ .../No attribute in implementation - 02.fs | 4 ++++ ...o attribute in implementation - 02.fs.gold | 4 ++++ .../No attribute in implementation - 02.fsi | 5 +++++ ... attribute in implementation - 02.fsi.gold | 5 +++++ .../UpdateCompiledNameInSignatureFixTest.fs | 3 +++ 14 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fs create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fs.gold create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fsi create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fsi.gold create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fs create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fs.gold create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fsi create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fsi.gold create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fs create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fs.gold create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fsi create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fsi.gold diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateCompiledNameInSignatureFix.fs b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateCompiledNameInSignatureFix.fs index 636b145027..ce22103453 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateCompiledNameInSignatureFix.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/UpdateCompiledNameInSignatureFix.fs @@ -17,6 +17,8 @@ type UpdateCompiledNameInSignatureFix(error: ValueNotContainedMutabilityCompiled let mutable bindingImplementation = null let mutable bindingSignature = null + let mutable signatureCompiledNameAttribute = None + let mutable implementationCompiledNamedAttribute = None let tryFindCompiledNameAttribute (binding: IBindingLikeDeclaration) = binding.Attributes @@ -30,16 +32,17 @@ type UpdateCompiledNameInSignatureFix(error: ValueNotContainedMutabilityCompiled | Some (BindingPair(implementation, implMember, signature, sigMember)) -> bindingImplementation <- implementation bindingSignature <- signature + signatureCompiledNameAttribute <-tryFindCompiledNameAttribute signature + implementationCompiledNamedAttribute <- tryFindCompiledNameAttribute implementation implMember.Mfv.CompiledName <> sigMember.Mfv.CompiledName + && (implementationCompiledNamedAttribute.IsSome || signatureCompiledNameAttribute.IsSome) override x.ExecutePsiTransaction _ = use writeCookie = WriteLockCookie.Create(error.Pat.IsPhysical()) use disableFormatter = new DisableCodeFormatter() - let signatureCompiledNameAttribute = tryFindCompiledNameAttribute bindingSignature - let implementationCompiledNamedAttribute = tryFindCompiledNameAttribute bindingImplementation match implementationCompiledNamedAttribute, signatureCompiledNameAttribute with - | None, None -> failwith "both don't have the attribute, add the attribute to the signature" // weird situation though + | None, None -> () // This error will not be raised unless one side has a CompiledNameAttribute. | Some value, None -> if bindingSignature.Attributes.IsEmpty then // We create an elementFactory with the implementation file because the CreateEmptyAttributeList is tied to implementation files only. @@ -52,5 +55,12 @@ type UpdateCompiledNameInSignatureFix(error: ValueNotContainedMutabilityCompiled ] |> ignore else FSharpAttributesUtil.addAttributeAfter (Seq.last bindingSignature.Attributes) value - | None, Some value -> failwith "add the attribute to the signature" - | Some value, Some value1 -> failwith "update the value of the signature" + | None, Some sigAttr -> + let parentAttributeList = AttributeListNavigator.GetByAttribute(sigAttr) + if parentAttributeList.Attributes.Count = 1 then + deleteChild parentAttributeList + else + deleteChild sigAttr + | Some implAttr, Some sigAttr -> + sigAttr.SetArgExpression(implAttr.ArgExpression) + |> ignore diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fs b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fs new file mode 100644 index 0000000000..d167cbc9e0 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fs @@ -0,0 +1,4 @@ +module A + +[] +let x{caret} (a:int) (b:int) = a + 1 diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fs.gold b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fs.gold new file mode 100644 index 0000000000..d167cbc9e0 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fs.gold @@ -0,0 +1,4 @@ +module A + +[] +let x{caret} (a:int) (b:int) = a + 1 diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fsi b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fsi new file mode 100644 index 0000000000..9f6d23ccc0 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fsi @@ -0,0 +1,4 @@ +module A + +[] +val x: a:int -> b:int -> int diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fsi.gold b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fsi.gold new file mode 100644 index 0000000000..9261da7595 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 02.fsi.gold @@ -0,0 +1,4 @@ +module A + +[] +val x: a:int -> b:int -> int diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fs b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fs new file mode 100644 index 0000000000..585748482e --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fs @@ -0,0 +1,3 @@ +module A + +let x{caret} (a:int) (b:int) = a + 1 diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fs.gold b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fs.gold new file mode 100644 index 0000000000..585748482e --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fs.gold @@ -0,0 +1,3 @@ +module A + +let x{caret} (a:int) (b:int) = a + 1 diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fsi b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fsi new file mode 100644 index 0000000000..9f6d23ccc0 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fsi @@ -0,0 +1,4 @@ +module A + +[] +val x: a:int -> b:int -> int diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fsi.gold b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fsi.gold new file mode 100644 index 0000000000..1d5b776b76 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 01.fsi.gold @@ -0,0 +1,4 @@ +module A + + +val x: a:int -> b:int -> int diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fs b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fs new file mode 100644 index 0000000000..1204ed029a --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fs @@ -0,0 +1,4 @@ +module A + +[] +let x{caret} (a:int) (b:int) = a + 1 diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fs.gold b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fs.gold new file mode 100644 index 0000000000..1204ed029a --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fs.gold @@ -0,0 +1,4 @@ +module A + +[] +let x{caret} (a:int) (b:int) = a + 1 diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fsi b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fsi new file mode 100644 index 0000000000..2227b156fe --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fsi @@ -0,0 +1,5 @@ +module A + +[] +[] +val x: a:int -> b:int -> int diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fsi.gold b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fsi.gold new file mode 100644 index 0000000000..0b68503297 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/No attribute in implementation - 02.fsi.gold @@ -0,0 +1,5 @@ +module A + + +[] +val x: a:int -> b:int -> int diff --git a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/UpdateCompiledNameInSignatureFixTest.fs b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/UpdateCompiledNameInSignatureFixTest.fs index 6413289250..0e3d7a17bc 100644 --- a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/UpdateCompiledNameInSignatureFixTest.fs +++ b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/UpdateCompiledNameInSignatureFixTest.fs @@ -9,3 +9,6 @@ type UpdateCompiledNameInSignatureFixTest() = override x.RelativeTestDataPath = "features/quickFixes/updateCompiledNameInSignatureFix" [] member x.``Attribute in implementation - 01`` () = x.DoNamedTestWithSignature() + [] member x.``Attribute in implementation - 02`` () = x.DoNamedTestWithSignature() + [] member x.``No attribute in implementation - 01`` () = x.DoNamedTestWithSignature() + [] member x.``No attribute in implementation - 02`` () = x.DoNamedTestWithSignature() From f04f7326b3888b778238d0a1e0e6283a39f6d532 Mon Sep 17 00:00:00 2001 From: nojaf Date: Wed, 19 Jul 2023 11:41:22 +0200 Subject: [PATCH 5/5] Support Nested modules --- .../src/QuickFixes/SignatureFixUtil.fs | 2 +- .../Attribute in implementation - 03.fs | 6 ++++++ .../Attribute in implementation - 03.fs.gold | 6 ++++++ .../Attribute in implementation - 03.fsi | 5 +++++ .../Attribute in implementation - 03.fsi.gold | 6 ++++++ .../src/QuickFixes/UpdateCompiledNameInSignatureFixTest.fs | 1 + 6 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fs create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fs.gold create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fsi create mode 100644 ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fsi.gold diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/SignatureFixUtil.fs b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/SignatureFixUtil.fs index cce0b8c9a3..3eea9282d5 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/SignatureFixUtil.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/QuickFixes/SignatureFixUtil.fs @@ -153,7 +153,7 @@ let tryFindBindingPairFromTopReferencePat (implTopRefPat: ITopReferencePat) = parentDeclarations |> Seq.tryPick (fun d -> match d with - | :? INamedModuleDeclaration as signatureModule when signatureModule.IsFSharpSigFile() -> + | :? ITypeDeclaration as signatureModule when signatureModule.IsFSharpSigFile() -> Some signatureModule | _ -> None) diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fs b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fs new file mode 100644 index 0000000000..03d27e7ab5 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fs @@ -0,0 +1,6 @@ +namespace A + +module B = + + [] + let x{caret} (a:int) (b:int) = a + 1 diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fs.gold b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fs.gold new file mode 100644 index 0000000000..03d27e7ab5 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fs.gold @@ -0,0 +1,6 @@ +namespace A + +module B = + + [] + let x{caret} (a:int) (b:int) = a + 1 diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fsi b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fsi new file mode 100644 index 0000000000..a5f36e8e30 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fsi @@ -0,0 +1,5 @@ +namespace A + +module B = + + val x: a:int -> b:int -> int diff --git a/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fsi.gold b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fsi.gold new file mode 100644 index 0000000000..47eddf5027 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/quickFixes/updateCompiledNameInSignatureFix/Attribute in implementation - 03.fsi.gold @@ -0,0 +1,6 @@ +namespace A + +module B = + + [] +val x: a:int -> b:int -> int diff --git a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/UpdateCompiledNameInSignatureFixTest.fs b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/UpdateCompiledNameInSignatureFixTest.fs index 0e3d7a17bc..99c7d90b5f 100644 --- a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/UpdateCompiledNameInSignatureFixTest.fs +++ b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/UpdateCompiledNameInSignatureFixTest.fs @@ -10,5 +10,6 @@ type UpdateCompiledNameInSignatureFixTest() = [] member x.``Attribute in implementation - 01`` () = x.DoNamedTestWithSignature() [] member x.``Attribute in implementation - 02`` () = x.DoNamedTestWithSignature() + [] member x.``Attribute in implementation - 03`` () = x.DoNamedTestWithSignature() [] member x.``No attribute in implementation - 01`` () = x.DoNamedTestWithSignature() [] member x.``No attribute in implementation - 02`` () = x.DoNamedTestWithSignature()