From f6eecaacd94d6d0b943d11a750e57a95c3fda6ce Mon Sep 17 00:00:00 2001 From: nojaf Date: Tue, 5 Jul 2022 14:55:47 +0200 Subject: [PATCH 1/3] Raw outline of feature proposal. --- .../FSharp.Psi.Intentions.fsproj | 1 + .../Intentions/GenerateSignatureFileAction.fs | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/GenerateSignatureFileAction.fs 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 aa4316d46d..709b2a9ba0 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj @@ -25,6 +25,7 @@ + diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/GenerateSignatureFileAction.fs b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/GenerateSignatureFileAction.fs new file mode 100644 index 0000000000..140d8762d0 --- /dev/null +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/GenerateSignatureFileAction.fs @@ -0,0 +1,28 @@ +namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.ContextActions + +open System.IO +open JetBrains.Application.UI.ActionsRevised.Menu +open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions + +type GenerateSignatureFileAction(dataProvider: FSharpContextActionDataProvider) = + interface IExecutableAction with + member this.Update(context, presentation, nextUpdate) = + let sourceFile = dataProvider.SourceFile.Name + let fsiFile = Path.ChangeExtension(sourceFile, ".fsi") + not (File.Exists fsiFile) + + member this.Execute(context, nextExecute) = + let sourceFile = dataProvider.SourceFile.Name + let fsiFile = Path.ChangeExtension(sourceFile, ".fsi") + let currentFSharpFile = dataProvider.PsiFile + let fcsService = currentFSharpFile.FcsCheckerService + let checkResult = fcsService.ParseAndCheckFile(currentFSharpFile.GetSourceFile(), "for signature file", true) + match checkResult with + | None -> () + | Some { CheckResults = checkResult } -> + + match checkResult.GenerateSignature() with + | None -> () + | Some signatureSourceText -> + let content = string signatureSourceText + File.WriteAllText(fsiFile, content) \ No newline at end of file From 19412b92b546becfedc835a777f3596060433c54 Mon Sep 17 00:00:00 2001 From: nojaf Date: Thu, 28 Jul 2022 09:24:50 +0200 Subject: [PATCH 2/3] Inherit from FSharpContextActionBase. --- .../Intentions/GenerateSignatureFileAction.fs | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/GenerateSignatureFileAction.fs b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/GenerateSignatureFileAction.fs index 140d8762d0..b9776e088c 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/GenerateSignatureFileAction.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/GenerateSignatureFileAction.fs @@ -1,22 +1,33 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.ContextActions +open System open System.IO -open JetBrains.Application.UI.ActionsRevised.Menu +open JetBrains.ReSharper.Feature.Services.ContextActions open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions +open type JetBrains.ReSharper.Psi.PsiSourceFileExtensions +[] type GenerateSignatureFileAction(dataProvider: FSharpContextActionDataProvider) = - interface IExecutableAction with - member this.Update(context, presentation, nextUpdate) = - let sourceFile = dataProvider.SourceFile.Name - let fsiFile = Path.ChangeExtension(sourceFile, ".fsi") - not (File.Exists fsiFile) - - member this.Execute(context, nextExecute) = - let sourceFile = dataProvider.SourceFile.Name - let fsiFile = Path.ChangeExtension(sourceFile, ".fsi") - let currentFSharpFile = dataProvider.PsiFile - let fcsService = currentFSharpFile.FcsCheckerService - let checkResult = fcsService.ParseAndCheckFile(currentFSharpFile.GetSourceFile(), "for signature file", true) + inherit FSharpContextActionBase(dataProvider) + + override this.Text = "Generate signature file for current file" + + override this.IsAvailable _ = + let currentFSharpFile = dataProvider.PsiFile + let fcsService = currentFSharpFile.FcsCheckerService + let hasSignature = fcsService.FcsProjectProvider.HasPairFile dataProvider.SourceFile + not hasSignature + + override this.ExecutePsiTransaction(solution, _) = + let project = dataProvider.SourceFile.GetProject() + + let physicalPath = dataProvider.SourceFile.ToProjectFile().Location.FileAccessPath + let fsiFile = Path.ChangeExtension(physicalPath, ".fsi") + let currentFSharpFile = dataProvider.PsiFile + let fcsService = currentFSharpFile.FcsCheckerService + let checkResult = fcsService.ParseAndCheckFile(currentFSharpFile.GetSourceFile(), "for signature file", true) + do match checkResult with | None -> () | Some { CheckResults = checkResult } -> @@ -25,4 +36,6 @@ type GenerateSignatureFileAction(dataProvider: FSharpContextActionDataProvider) | None -> () | Some signatureSourceText -> let content = string signatureSourceText - File.WriteAllText(fsiFile, content) \ No newline at end of file + File.WriteAllText(fsiFile, content) + + Action<_>(ignore) \ No newline at end of file From 9b0b7694bde845a9ebcdec6df5d78e3833f137c3 Mon Sep 17 00:00:00 2001 From: nojaf Date: Thu, 28 Jul 2022 14:46:49 +0200 Subject: [PATCH 3/3] Add signature file to current project. --- .../Intentions/GenerateSignatureFileAction.fs | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/GenerateSignatureFileAction.fs b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/GenerateSignatureFileAction.fs index b9776e088c..1021978d53 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/GenerateSignatureFileAction.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/GenerateSignatureFileAction.fs @@ -1,7 +1,9 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.ContextActions -open System open System.IO +open JetBrains.ProjectModel.ProjectsHost +open JetBrains.RdBackend.Common.Features.ProjectModel +open JetBrains.RdBackend.Common.Features.ProjectModel.View.Ordering open JetBrains.ReSharper.Feature.Services.ContextActions open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions open type JetBrains.ReSharper.Psi.PsiSourceFileExtensions @@ -20,22 +22,32 @@ type GenerateSignatureFileAction(dataProvider: FSharpContextActionDataProvider) not hasSignature override this.ExecutePsiTransaction(solution, _) = - let project = dataProvider.SourceFile.GetProject() - + let projectFile = dataProvider.SourceFile.ToProjectFile() let physicalPath = dataProvider.SourceFile.ToProjectFile().Location.FileAccessPath - let fsiFile = Path.ChangeExtension(physicalPath, ".fsi") - let currentFSharpFile = dataProvider.PsiFile - let fcsService = currentFSharpFile.FcsCheckerService - let checkResult = fcsService.ParseAndCheckFile(currentFSharpFile.GetSourceFile(), "for signature file", true) - do - match checkResult with - | None -> () - | Some { CheckResults = checkResult } -> - - match checkResult.GenerateSignature() with - | None -> () - | Some signatureSourceText -> - let content = string signatureSourceText - File.WriteAllText(fsiFile, content) + let fsiFile = Path.ChangeExtension(physicalPath, ".fsi") + + try + let currentFSharpFile = dataProvider.PsiFile + let fcsService = currentFSharpFile.FcsCheckerService + let checkResult = fcsService.ParseAndCheckFile(currentFSharpFile.GetSourceFile(), "for signature file", true) + do + match checkResult with + | None -> () + | Some { CheckResults = checkResult } -> + + match checkResult.GenerateSignature() with + | None -> () + | Some signatureSourceText -> + let content = string signatureSourceText + File.WriteAllText(fsiFile, content) + with ex -> + // TODO: show some balloon thing? + () + + solution.InvokeUnderTransaction(fun transactionCookie -> + let virtualPath = FileSystemPath.TryParse(fsiFile).ToVirtualFileSystemPath() + let relativeTo = RelativeTo(projectFile, RelativeToType.Before) + transactionCookie.AddFile(projectFile.ParentFolder, virtualPath, context = OrderingContext(relativeTo)) + |> ignore) - Action<_>(ignore) \ No newline at end of file + null \ No newline at end of file