From c8abbb0286a1019738bba6f0b132f44595e32650 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 21 May 2026 16:00:02 +0200 Subject: [PATCH 1/4] RIDER-138918 Commands: allow selecting menu item via test sources GitOrigin-RevId: d349ab58bf59d9cf590a256edff0d5b2f75a5c81 --- .../New line - Match - Deindent - Single clause 01.fs | 2 ++ ...ew line - Match - Deindent - Single clause 01.fs.gold | 4 +++- .../addIgnore/New line - Match - Deindent 02.fs | 2 ++ .../addIgnore/New line - Match - Deindent 02.fs.gold | 4 +++- .../features/quickFixes/addIgnore/New line - Match 01.fs | 2 ++ .../quickFixes/addIgnore/New line - Match 01.fs.gold | 4 +++- .../features/quickFixes/addIgnore/New line - Match 02.fs | 2 ++ .../quickFixes/addIgnore/New line - Match 02.fs.gold | 4 +++- .../addIgnore/New line - Match 03 - Single line.fs | 2 ++ .../addIgnore/New line - Match 03 - Single line.fs.gold | 4 +++- .../addIgnore/Single line - Multiple clauses 01.fs | 2 ++ .../addIgnore/Single line - Multiple clauses 01.fs.gold | 4 +++- .../addIgnore/Single line - Single clause 01.fs | 2 ++ .../addIgnore/Single line - Single clause 01.fs.gold | 4 +++- .../src/QuickFixes/AddIgnoreTest.fs | 9 --------- .../test/src/FSharp.Tests.Common/src/Common.fs | 7 +++++++ 16 files changed, 42 insertions(+), 16 deletions(-) diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent - Single clause 01.fs b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent - Single clause 01.fs index dd43fcada0..6d68d80d82 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent - Single clause 01.fs +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent - Single clause 01.fs @@ -1,3 +1,5 @@ +//${OCCURRENCE:Whole expression} + while true do match () with | _ -> [ diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent - Single clause 01.fs.gold b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent - Single clause 01.fs.gold index 6327433ac7..ed2f10df61 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent - Single clause 01.fs.gold +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent - Single clause 01.fs.gold @@ -1,4 +1,6 @@ -while true do +//${OCCURRENCE:Whole expression} + +while true do match () with | _ -> [ ] diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent 02.fs b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent 02.fs index 35f8eed2b6..ba4afee255 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent 02.fs +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent 02.fs @@ -1,3 +1,5 @@ +//${OCCURRENCE:Whole expression} + while true do match () with | _ -> [] diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent 02.fs.gold b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent 02.fs.gold index 2023835539..15d3e4d2ae 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent 02.fs.gold +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match - Deindent 02.fs.gold @@ -1,4 +1,6 @@ -while true do +//${OCCURRENCE:Whole expression} + +while true do match () with | _ -> [] | _ -> [ diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 01.fs b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 01.fs index 9484bfd953..3412412790 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 01.fs +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 01.fs @@ -1,3 +1,5 @@ +//${OCCURRENCE:Whole expression} + let x = match () with | _ -> 1 diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 01.fs.gold b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 01.fs.gold index 5b3f2cebee..22b672748a 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 01.fs.gold +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 01.fs.gold @@ -1,4 +1,6 @@ -let x = +//${OCCURRENCE:Whole expression} + +let x = match () with | _ -> 1 | _ -> 1 diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 02.fs b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 02.fs index 6788dabfa9..0829c17f36 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 02.fs +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 02.fs @@ -1,3 +1,5 @@ +//${OCCURRENCE:Whole expression} + let x = match () with | _ -> diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 02.fs.gold b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 02.fs.gold index 9dc0349100..56ea5ac667 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 02.fs.gold +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 02.fs.gold @@ -1,4 +1,6 @@ -let x = +//${OCCURRENCE:Whole expression} + +let x = match () with | _ -> 1 diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 03 - Single line.fs b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 03 - Single line.fs index b0ef0357dd..d1e442518b 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 03 - Single line.fs +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 03 - Single line.fs @@ -1,3 +1,5 @@ +//${OCCURRENCE:Whole expression} + let x = match () with | _ -> 1 | _ -> 1{caret} () diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 03 - Single line.fs.gold b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 03 - Single line.fs.gold index 926de24500..62d4cf6bbc 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 03 - Single line.fs.gold +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/New line - Match 03 - Single line.fs.gold @@ -1,3 +1,5 @@ -let x = +//${OCCURRENCE:Whole expression} + +let x = (match () with | _ -> 1 | _ -> 1) |> ignore{caret} () diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Multiple clauses 01.fs b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Multiple clauses 01.fs index 7e4c9b98d0..6aad93d086 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Multiple clauses 01.fs +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Multiple clauses 01.fs @@ -1,2 +1,4 @@ +//${OCCURRENCE:Whole expression} + do match () with | _ -> 1 | _ -> 1{caret} diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Multiple clauses 01.fs.gold b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Multiple clauses 01.fs.gold index 4efd0ccf69..a8db5c3f98 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Multiple clauses 01.fs.gold +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Multiple clauses 01.fs.gold @@ -1,2 +1,4 @@ -do +//${OCCURRENCE:Whole expression} + +do (match () with | _ -> 1 | _ -> 1) |> ignore{caret} diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Single clause 01.fs b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Single clause 01.fs index fa332741c6..f076f6f442 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Single clause 01.fs +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Single clause 01.fs @@ -1,2 +1,4 @@ +//${OCCURRENCE:Whole expression} + do match () with | _ -> 1{caret} diff --git a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Single clause 01.fs.gold b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Single clause 01.fs.gold index e9e9c5eb11..59675f5000 100644 --- a/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Single clause 01.fs.gold +++ b/ReSharper.FSharp/test/data/features/quickFixes/addIgnore/Single line - Single clause 01.fs.gold @@ -1,2 +1,4 @@ -do +//${OCCURRENCE:Whole expression} + +do (match () with | _ -> 1) |> ignore{caret} diff --git a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/AddIgnoreTest.fs b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/AddIgnoreTest.fs index b3451dacd4..0231ac0068 100644 --- a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/AddIgnoreTest.fs +++ b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/AddIgnoreTest.fs @@ -3,7 +3,6 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Tests.Intentions.QuickFixes open JetBrains.ReSharper.FeaturesTestFramework.Intentions open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes open JetBrains.ReSharper.Plugins.FSharp.Tests -open JetBrains.ReSharper.TestFramework open NUnit.Framework [] @@ -28,29 +27,21 @@ type AddIgnoreTest() = [] member x.``New line - Lazy 01``() = x.DoNamedTest() - [] [] member x.``New line - Match - Deindent - Single clause 01``() = x.DoNamedTest() [] member x.``New line - Match - Deindent - Single clause 02``() = x.DoNamedTest() // todo: formatter: wrong indent - [] [] member x.``New line - Match - Deindent 01``() = x.DoNamedTest() // todo: formatter: wrong indent - [] [] member x.``New line - Match - Deindent 02``() = x.DoNamedTest() [] member x.``New line - Match - Deindent 03``() = x.DoNamedTest() - [] [] member x.``New line - Match 01``() = x.DoNamedTest() - [] [] member x.``New line - Match 02``() = x.DoNamedTest() - [] [] member x.``New line - Match 03 - Single line``() = x.DoNamedTest() [] member x.``Parens 01``() = x.DoNamedTest() [] member x.``Parens 02``() = x.DoNamedTest() - [] [] member x.``Single line - Multiple clauses 01``() = x.DoNamedTest() [] member x.``Single line - Multiple clauses 02``() = x.DoNamedTest() - [] [] member x.``Single line - Single clause 01``() = x.DoNamedTest() [] member x.``Single line - Single clause 02``() = x.DoNamedTest() diff --git a/ReSharper.FSharp/test/src/FSharp.Tests.Common/src/Common.fs b/ReSharper.FSharp/test/src/FSharp.Tests.Common/src/Common.fs index 964fb63a30..57a88f7334 100644 --- a/ReSharper.FSharp/test/src/FSharp.Tests.Common/src/Common.fs +++ b/ReSharper.FSharp/test/src/FSharp.Tests.Common/src/Common.fs @@ -16,6 +16,7 @@ open JetBrains.Lifetimes open JetBrains.ProjectModel open JetBrains.ProjectModel.Properties open JetBrains.ProjectModel.Properties.Managed +open JetBrains.ReSharper.Feature.Services.BulbActions.Commands open JetBrains.ReSharper.FeaturesTestFramework.Refactorings open JetBrains.ReSharper.Plugins.FSharp open JetBrains.ReSharper.Plugins.FSharp.Checker @@ -509,3 +510,9 @@ module FSharpTestPopup = |> Option.defaultValue null ) ) + + BulbActionExecutorTestUtil.RegisterContextConfigurer(lifetime, solution, + _.add_OnSessionStarted( + _.UserData.PutData(BulbActionExecutorTestUtil.BulbMenuItemOccurrenceTextKey, occurrenceName) + ) + ) From 1d3a04d9a8b9e9e936acae3f2cc68735130247d4 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 21 May 2026 16:42:50 +0200 Subject: [PATCH 2/4] RIDER-138918 Intentions: implement quick fix previews in F# * Translate highlightings to forks * Cleanup highlighting declarations * Convert the most of the quick fixes and context actions to modern bulb actions GitOrigin-RevId: 3f3382b91e60b8235db437d54c41e007d70f333f --- .../InterpolatedStringCandidateAnalyzer.fs | 12 +- .../src/Analyzers/RecordExprAnalyzer.fs | 2 +- .../PostfixTemplates/MatchPostfixTemplate.fs | 9 +- .../PostfixTemplates/NewObjPostfixTemplate.fs | 5 +- .../src/PostfixTemplates/PostfixTemplates.fs | 5 +- .../PostfixTemplates/WithPostfixTemplate.fs | 10 +- .../ConvertDotLambdaToLambdaExprAction.fs | 10 +- ...tPartiallyAppliedFunctionToLambdaAction.fs | 10 +- .../src/Intentions/DataProviders.fs | 10 + .../src/Intentions/FSharpContextActionBase.fs | 13 +- .../src/Intentions/IfToElifAction.fs | 6 +- .../MatchLambdaExprToParameterAction.fs | 9 +- .../RenameFileToMatchTypeNameAction.fs | 2 +- .../src/Intentions/SetNameAction.fs | 14 +- .../ToPositionalFieldPatternsAction.fs | 10 +- .../src/QuickFixes/AddIgnoreFix.fs | 4 +- .../src/QuickFixes/AddMatchAllClauseFix.fs | 10 +- .../QuickFixes/AddMissingInnerPatternsFix.fs | 20 +- .../QuickFixes/AddParensToApplicationFix.fs | 67 ++-- .../src/QuickFixes/ChangeTypeFix.fs | 6 +- .../src/QuickFixes/DeconstructPatternFix.fs | 10 +- .../src/QuickFixes/FSharpQuickFixBase.fs | 31 +- .../QuickFixes/GenerateInterfaceMembersFix.fs | 12 +- .../QuickFixes/GenerateMissingOverridesFix.fs | 2 +- .../GenerateMissingRecordFieldsFix.fs | 27 +- .../src/QuickFixes/IntroduceVarFix.fs | 2 +- .../QuickFixes/RemoveUnusedLocalBindingFix.fs | 12 +- .../src/QuickFixes/ReplaceReturnTypeFix.fs | 13 +- .../src/QuickFixes/ReplaceUseWithLetFix.fs | 1 - .../ReplaceWithInterpolatedStringFix.fs | 20 +- .../QuickFixes/SpecifyParameterBaseTypeFix.fs | 36 +- .../src/QuickFixes/ToObjectExpressionFix.fs | 5 +- .../src/QuickFixes/ToRecursiveFunctionFix.fs | 28 +- .../UseNestedRecordFieldSyntaxFix.fs | 4 +- .../src/Daemon/Highlightings/Errors.xml | 170 +++++----- .../src/Daemon/Highlightings/FcsErrors.xml | 313 +++++------------- .../src/Generate/GenerateOverrides.fs | 32 +- .../src/Generate/GenerateProvider.fs | 4 +- .../src/Util/FSharpTypeUsageUtil.fs | 3 +- .../src/Resolve/FcsCachedDiagnosticInfo.cs | 10 + .../QuickFixes/AddParensToApplicationTest.fs | 24 -- 41 files changed, 387 insertions(+), 606 deletions(-) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Analyzers/InterpolatedStringCandidateAnalyzer.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Analyzers/InterpolatedStringCandidateAnalyzer.fs index 254ced9442..21b0d1c1a4 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Analyzers/InterpolatedStringCandidateAnalyzer.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Analyzers/InterpolatedStringCandidateAnalyzer.fs @@ -110,12 +110,10 @@ type InterpolatedStringCandidateAnalyzer() = if anyDisallowedExprs then () else - let formatSpecsAndExprs = - appliedExprs - |> Seq.rev - |> Seq.zip matchingFormatSpecsAndArity - |> Seq.map (fun ((r, _), expr) -> r, expr) - |> List.ofSeq + let exprs = appliedExprs |> Seq.rev |> Array.ofSeq + let formatSpecs = matchingFormatSpecsAndArity |> Seq.map fst + let offsets = formatSpecs |> Seq.map (fun range -> range.EndOffset.Offset - literalExpr.GetDocumentStartOffset().Offset) |> Array.ofSeq + let formatSpecs = formatSpecs |> Seq.map _.GetText() |> Array.ofSeq - InterpolatedStringCandidateWarning(literalExpr, prefixAppExpr, outerPrefixAppExpr, formatSpecsAndExprs) + InterpolatedStringCandidateWarning(literalExpr, prefixAppExpr, outerPrefixAppExpr, formatSpecs, offsets, exprs) |> consumer.AddHighlighting diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Analyzers/RecordExprAnalyzer.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Analyzers/RecordExprAnalyzer.fs index efb6035fc2..5b37fd529c 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Analyzers/RecordExprAnalyzer.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Analyzers/RecordExprAnalyzer.fs @@ -25,7 +25,7 @@ type RecordExprAnalyzer() = if isNull innerFieldBinding.Expression then () elif not (innerFieldBinding.ReferenceName.Reference.GetFcsSymbol() :? FSharpField) then () else - let qualifiedFieldName = qualifiedFieldNameReversed |> List.rev + let qualifiedFieldName = qualifiedFieldNameReversed |> Array.ofList |> Array.rev consumer.AddHighlighting(NestedRecordUpdateCanBeSimplifiedWarning(outerFieldBinding, innerFieldBinding, qualifiedFieldName)) let rec compareReferenceExprs (x: IReferenceExpr) (y: IReferenceExpr) = diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/MatchPostfixTemplate.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/MatchPostfixTemplate.fs index 122cf9feb1..ff6d0c3651 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/MatchPostfixTemplate.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/MatchPostfixTemplate.fs @@ -1,5 +1,7 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.PostfixTemplates +open JetBrains.ReSharper.Feature.Services.BulbActions +open JetBrains.ReSharper.Feature.Services.CodeCompletion.Settings open JetBrains.ReSharper.Feature.Services.PostfixTemplates open JetBrains.ReSharper.Feature.Services.PostfixTemplates.Contexts open JetBrains.ReSharper.Plugins.FSharp.Psi @@ -64,6 +66,7 @@ and MatchPostfixTemplateBehavior(info) = matchExpr :> ITreeNode ) - override x.AfterComplete(textControl, node, _) = - textControl.Caret.MoveTo(node.GetDocumentEndOffset() + 1, CaretVisualPlacement.DontScrollIfVisible) - textControl.RescheduleCompletion(node.GetSolution()) + override this.AfterComplete(textControl, node, _) = + let offset = node.GetDocumentEndOffset() + 1 + let command = BulbActionCommands.ShowCodeCompletionPopup(offset, FSharpLanguage.Instance, AutopopupType.SoftAutopopup) + this.RunAndForget(command, textControl) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/NewObjPostfixTemplate.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/NewObjPostfixTemplate.fs index d6fdd325cf..687bb7d30a 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/NewObjPostfixTemplate.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/NewObjPostfixTemplate.fs @@ -6,7 +6,6 @@ open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Generate open JetBrains.ReSharper.Plugins.FSharp.Psi.Services.Util.ObjExprUtil open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree -open JetBrains.ReSharper.Psi.ExtensionsAPI open JetBrains.ReSharper.Psi.Transactions open JetBrains.ReSharper.Resources.Shell @@ -47,5 +46,5 @@ and NewObjPostfixTemplateBehavior(info) = ) override this.AfterComplete(textControl, node, _) = - let objExpr = node :?> IObjExpr - GenerateOverrides.selectObjExprMemberOrCallCompletion objExpr textControl + let command = GenerateOverrides.selectObjExprMemberOrCallCompletion (downcast node) + this.RunAndForget(command, textControl) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/PostfixTemplates.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/PostfixTemplates.fs index 9f56b55e9d..c66c9fe182 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/PostfixTemplates.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/PostfixTemplates.fs @@ -1,10 +1,10 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.PostfixTemplates open JetBrains.Application.Parts -open JetBrains.Application.Settings open JetBrains.Diagnostics open JetBrains.DocumentModel open JetBrains.ProjectModel +open JetBrains.ReSharper.Feature.Services.BulbActions open JetBrains.ReSharper.Feature.Services.CodeCompletion.PostfixTemplates open JetBrains.ReSharper.Feature.Services.LiveTemplates.Hotspots open JetBrains.ReSharper.Feature.Services.LiveTemplates.LiveTemplates @@ -291,6 +291,9 @@ type FSharpPostfixTemplateBehaviorBase(info) = let node = context.Expression :?> IFSharpTreeNode FSharpPostfixTemplates.removeTemplateAndGetParentExpression node + member this.RunAndForget(command: IBulbActionCommand, textControl) = + command.RunAndForget(info.ExecutionContext.Solution, textControl, info.Text) + [] type FSharpPostfixTemplateBase() = diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/WithPostfixTemplate.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/WithPostfixTemplate.fs index 6fb525c4e2..446aae2f8b 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/WithPostfixTemplate.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/PostfixTemplates/WithPostfixTemplate.fs @@ -2,12 +2,13 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.PostfixTemplates open JetBrains.Application.Threading open JetBrains.ProjectModel +open JetBrains.ReSharper.Feature.Services.BulbActions +open JetBrains.ReSharper.Feature.Services.CodeCompletion.Settings open JetBrains.ReSharper.Feature.Services.Navigation.CustomHighlighting open JetBrains.ReSharper.Feature.Services.PostfixTemplates open JetBrains.ReSharper.Feature.Services.PostfixTemplates.Contexts open JetBrains.ReSharper.Feature.Services.Refactorings.WorkflowOccurrences open JetBrains.ReSharper.Plugins.FSharp.Psi -open JetBrains.ReSharper.Plugins.FSharp.Psi.Services.Util.FSharpCompletionUtil open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.ReSharper.Plugins.FSharp.Psi.Util open JetBrains.ReSharper.Plugins.FSharp.Util @@ -16,7 +17,6 @@ open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree open JetBrains.ReSharper.Psi.Transactions open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Resources.Shell -open JetBrains.TextControl open JetBrains.UI.RichText module WithPostfixTemplate = @@ -152,6 +152,8 @@ and WithPostfixTemplateBehavior(info) = let innermostExpr = WithPostfixTemplate.getInnermostRecordExpr recordExpr let range = innermostExpr.GetDocumentRange() - textControl.Caret.MoveTo(range.EndOffset - 2, CaretVisualPlacement.DontScrollIfVisible) - textControl.RescheduleCompletion(solution) + + let offset = range.EndOffset - 2 + let command = BulbActionCommands.ShowCodeCompletionPopup(offset, FSharpLanguage.Instance, AutopopupType.SoftAutopopup) + x.RunAndForget(command, textControl) ) |> ignore diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/ConvertDotLambdaToLambdaExprAction.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/ConvertDotLambdaToLambdaExprAction.fs index 7b10e52dc8..91c219d0f1 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/ConvertDotLambdaToLambdaExprAction.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/ConvertDotLambdaToLambdaExprAction.fs @@ -1,7 +1,6 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions -open System -open JetBrains.ReSharper.Feature.Services.Bulbs +open JetBrains.ReSharper.Feature.Services.BulbActions open JetBrains.ReSharper.Feature.Services.ContextActions open JetBrains.ReSharper.Feature.Services.LiveTemplates.Hotspots open JetBrains.ReSharper.Plugins.FSharp.Psi @@ -9,7 +8,6 @@ open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util open JetBrains.ReSharper.Plugins.FSharp.Psi.Parsing open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.ReSharper.Plugins.FSharp.Psi.Util -open JetBrains.ReSharper.Psi.ExtensionsAPI open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Psi.Util @@ -89,7 +87,5 @@ type ConvertDotLambdaToLambdaExprAction(dataProvider: FSharpContextActionDataPro let nodes = [pattern :> ITreeNode; qualifierExpr] hotspotsRegistry.Register(nodes, NameSuggestionsExpression(names)) - Action<_>(fun texControl -> - let offset = bodyExpr.GetDocumentStartOffset() - BulbActionUtils.ExecuteHotspotSession(hotspotsRegistry, offset).Invoke(texControl) - ) + let endCaretPosition = bodyExpr.GetDocumentStartOffset() + BulbActionCommands.ShowHotspotSession(hotspotsRegistry, endCaretPosition) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/ConvertPartiallyAppliedFunctionToLambdaAction.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/ConvertPartiallyAppliedFunctionToLambdaAction.fs index 5cb67fffbe..d795a3015a 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/ConvertPartiallyAppliedFunctionToLambdaAction.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/ConvertPartiallyAppliedFunctionToLambdaAction.fs @@ -1,8 +1,7 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions -open System open JetBrains.Diagnostics -open JetBrains.ReSharper.Feature.Services.Bulbs +open JetBrains.ReSharper.Feature.Services.BulbActions open JetBrains.ReSharper.Feature.Services.ContextActions open JetBrains.ReSharper.Feature.Services.LiveTemplates.Hotspots open JetBrains.ReSharper.Plugins.FSharp.Psi @@ -11,7 +10,6 @@ open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.ReSharper.Plugins.FSharp.Psi.Util open JetBrains.ReSharper.Plugins.FSharp.Util -open JetBrains.ReSharper.Psi.ExtensionsAPI open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Resources.Shell @@ -175,7 +173,5 @@ type ConvertPartiallyAppliedFunctionToLambdaAction(dataProvider: FSharpContextAc hotspotsRegistry.Register(nodes, nameExpression) ) - Action<_>(fun textControl -> - let endOffset = bodyExpr.GetDocumentStartOffset() - BulbActionUtils.ExecuteHotspotSession(hotspotsRegistry, endOffset).Invoke(textControl) - ) + let endCaretPosition = bodyExpr.GetDocumentStartOffset() + BulbActionCommands.ShowHotspotSession(hotspotsRegistry, endCaretPosition) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/DataProviders.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/DataProviders.fs index a0e768accf..34617911e7 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/DataProviders.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/DataProviders.fs @@ -5,11 +5,21 @@ open JetBrains.ReSharper.Feature.Services.ContextActions open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree +open JetBrains.ReSharper.Psi.ContentModel open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Psi.Util type FSharpContextActionDataProvider(solution, textControl, fsFile) = inherit CachedContextActionDataProviderBase(solution, textControl, fsFile) + + interface ISupportsContentModelForkTranslation with + member this.TryTranslateToCurrentFork(translator) = + match translator.TryTranslateNodeToCurrentFork(this.PsiFile) with + | null -> null + | fileInFork -> + + let textControlInFork = translator.TranslateTextControl(this.TextControl) + FSharpContextActionDataProvider(this.Solution, textControlInFork, fileInFork) [)>] diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/FSharpContextActionBase.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/FSharpContextActionBase.fs index 1b076f0052..7183dc0f9f 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/FSharpContextActionBase.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/FSharpContextActionBase.fs @@ -6,7 +6,7 @@ open JetBrains.ReSharper.Psi.Tree [] type FSharpContextActionBase(dataProvider: FSharpContextActionDataProvider) = - inherit ContextActionBase() + inherit ModernContextActionBase() abstract ExecutePsiTransaction: ISolution -> unit default x.ExecutePsiTransaction _ = () @@ -17,3 +17,14 @@ type FSharpContextActionBase(dataProvider: FSharpContextActionDataProvider) = member x.IsAtTreeNode(node: ITreeNode) = isAtTreeNode dataProvider node + +[] +type FSharpLegacyContextActionBase() = + inherit ContextActionBase() + + abstract ExecutePsiTransaction: ISolution -> unit + default x.ExecutePsiTransaction _ = () + + override x.ExecutePsiTransaction(solution, _) = + x.ExecutePsiTransaction(solution) + null diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/IfToElifAction.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/IfToElifAction.fs index 9bc212501b..70b16a9509 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/IfToElifAction.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/IfToElifAction.fs @@ -1,6 +1,6 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions -open System +open JetBrains.ReSharper.Feature.Services.BulbActions open JetBrains.ReSharper.Feature.Services.ContextActions open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl.Tree @@ -10,7 +10,6 @@ open JetBrains.ReSharper.Psi.ExtensionsAPI open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Resources.Shell -open JetBrains.TextControl open JetBrains.Util [, Description = "Converts `if` expression to 'elif'")>] @@ -47,5 +46,4 @@ type IfToElifAction(dataProvider: FSharpContextActionDataProvider) = let elifExpr = ModificationUtil.ReplaceChild(ifExpr, ElementType.ELIF_EXPR.Create()) LowLevelModificationUtil.AddChild(elifExpr, ifExpr.Children().AsArray()) - Action<_>(fun textControl -> - textControl.Caret.MoveTo(elifExpr.GetDocumentStartOffset(), CaretVisualPlacement.DontScrollIfVisible)) + BulbActionCommands.SetCaretBefore(elifExpr) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/MatchLambdaExprToParameterAction.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/MatchLambdaExprToParameterAction.fs index 49d17c1db4..7d76ce5d91 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/MatchLambdaExprToParameterAction.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/MatchLambdaExprToParameterAction.fs @@ -1,8 +1,7 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions -open System open FSharp.Compiler.Symbols -open JetBrains.ReSharper.Feature.Services.Bulbs +open JetBrains.ReSharper.Feature.Services.BulbActions open JetBrains.ReSharper.Feature.Services.ContextActions open JetBrains.ReSharper.Feature.Services.LiveTemplates.Hotspots open JetBrains.ReSharper.Plugins.FSharp.Psi @@ -85,7 +84,5 @@ type MatchLambdaExprToParameterAction(dataProvider) = let nodes: ITreeNode list = [parameterDecl; matchExpr.Expression] hotspotsRegistry.Register(nodes, NameSuggestionsExpression(names)) - Action<_>(fun texControl -> - let offset = parameterDecl.GetDocumentEndOffset() - BulbActionUtils.ExecuteHotspotSession(hotspotsRegistry, offset).Invoke(texControl) - ) + let endCaretPosition = parameterDecl.GetDocumentEndOffset() + BulbActionCommands.ShowHotspotSession(hotspotsRegistry, endCaretPosition) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/RenameFileToMatchTypeNameAction.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/RenameFileToMatchTypeNameAction.fs index 13f88462ee..2f4c29eeb5 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/RenameFileToMatchTypeNameAction.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/RenameFileToMatchTypeNameAction.fs @@ -14,7 +14,7 @@ open JetBrains.Util [, Name = "Match file name with type name", Priority = 1s, Description = "Renames current file to match the name of the single type or a top-level module.")>] type RenameFileToMatchTypeNameAction(dataProvider: FSharpContextActionDataProvider) = - inherit FSharpContextActionBase(dataProvider) + inherit FSharpLegacyContextActionBase() let isApplicable (typeElement: ITypeElement) = let types = HashSet() diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/SetNameAction.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/SetNameAction.fs index cd5102773c..842e9377be 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/SetNameAction.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/SetNameAction.fs @@ -1,13 +1,11 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions -open System +open JetBrains.ReSharper.Feature.Services.BulbActions open JetBrains.ReSharper.Feature.Services.LiveTemplates.Hotspots -open JetBrains.ReSharper.Feature.Services.LiveTemplates.LiveTemplates open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util.FSharpNamingService open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl.Tree open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree -open JetBrains.ReSharper.Psi.ExtensionsAPI open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Resources.Shell @@ -29,7 +27,6 @@ type SetNameAction(dataProvider: FSharpContextActionDataProvider) = override x.ExecutePsiTransaction(_, _) = let wildPat = dataProvider.GetSelectedElement() - let solution = wildPat.GetSolution() let psiServices = wildPat.GetPsiServices() let factory = wildPat.CreateElementFactory() @@ -55,10 +52,5 @@ type SetNameAction(dataProvider: FSharpContextActionDataProvider) = hotspotsRegistry.Register([| refPat :> ITreeNode |], nameExpression) let hotspots = hotspotsRegistry.CreateHotspots() - Action<_>(fun textControl -> - let endCaretPosition = refPat.GetDocumentEndOffset() - let escapeAction = LiveTemplatesManager.EscapeAction.LeaveTextAndCaret - LiveTemplatesManager.Instance - .CreateHotspotSessionAtopExistingText(solution, endCaretPosition, textControl, escapeAction, hotspots) - .ExecuteAndForget() - ) + let endCaretPosition = refPat.GetDocumentEndOffset() + BulbActionCommands.ShowHotspotSession(hotspots, endCaretPosition) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/ToPositionalFieldPatternsAction.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/ToPositionalFieldPatternsAction.fs index 1b7714d30a..0f3ac57d33 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/ToPositionalFieldPatternsAction.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/ToPositionalFieldPatternsAction.fs @@ -1,20 +1,17 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions -open System open System.Collections.Generic open FSharp.Compiler.Symbols open JetBrains.DocumentModel -open JetBrains.ReSharper.Feature.Services.Bulbs +open JetBrains.ReSharper.Feature.Services.BulbActions open JetBrains.ReSharper.Feature.Services.ContextActions open JetBrains.ReSharper.Feature.Services.LiveTemplates.Hotspots -open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions.Deconstruction open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.ReSharper.Plugins.FSharp.Util -open JetBrains.ReSharper.Psi.ExtensionsAPI open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Resources.Shell @@ -87,6 +84,5 @@ type ToPositionalFieldPatternsAction(dataProvider: FSharpContextActionDataProvid let rangeMarker = itemPat.GetDocumentRange().CreateRangeMarker() hotspotsRegistry.Register(rangeMarker, nameSuggestionsExpression) - Action<_>(fun textControl -> - BulbActionUtils.ExecuteHotspotSession(hotspotsRegistry, replacedPat.GetDocumentEndOffset()).Invoke(textControl) - ) + let endCaretPosition = replacedPat.GetDocumentEndOffset() + BulbActionCommands.ShowHotspotSession(hotspotsRegistry, endCaretPosition) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddIgnoreFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddIgnoreFix.fs index f01f43c095..75016cbf2a 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddIgnoreFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddIgnoreFix.fs @@ -9,7 +9,7 @@ open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree open JetBrains.ReSharper.Resources.Shell type AddIgnoreFix(node: IFSharpTypeOwnerNode) = - inherit FSharpModernQuickFixBase() + inherit FSharpQuickFixBase() let expr = node.As() @@ -65,7 +65,7 @@ type AddIgnoreFix(node: IFSharpTypeOwnerNode) = let occurrences = [| innerExpression, text expr, "Whole expression" |] - x.SelectExpression(occurrences, addIgnore) + x.ShowMenuAndExecute(occurrences, addIgnore) | _ -> base.GetCommandSequence() diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddMatchAllClauseFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddMatchAllClauseFix.fs index 7870aabf33..748809157c 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddMatchAllClauseFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddMatchAllClauseFix.fs @@ -1,16 +1,13 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes -open System +open JetBrains.ReSharper.Feature.Services.BulbActions open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes open JetBrains.ReSharper.Plugins.FSharp.Psi.Services.Util open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.ReSharper.Psi -open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Resources.Shell -open JetBrains.TextControl - open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree [] @@ -50,7 +47,4 @@ type AddMatchAllClauseFix(expr: IMatchLikeExpr, generatedExpr: GeneratedClauseEx let refExpr = ctorExpr.FunctionExpression :?> IReferenceExpr FSharpBindUtil.bindDeclaredElementToReference expr refExpr.Reference exnTypeElement "" - Action<_>(fun textControl -> - let range = clause.Expression.GetDocumentRange() - textControl.Caret.MoveTo(range.EndOffset, CaretVisualPlacement.DontScrollIfVisible) - textControl.Selection.SetRange(range)) + BulbActionCommands.SetSelection(clause.Expression) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddMissingInnerPatternsFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddMissingInnerPatternsFix.fs index 9a0ace3f5c..94ec8a56d0 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddMissingInnerPatternsFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddMissingInnerPatternsFix.fs @@ -1,19 +1,17 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes -open System open System.Collections.Generic open JetBrains.Application.Environment open JetBrains.Application.Environment.Helpers +open JetBrains.ReSharper.Feature.Services.BulbActions open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util.MatchTree open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree -open JetBrains.ReSharper.Psi.ExtensionsAPI open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Resources.Shell -open JetBrains.TextControl open JetBrains.Util [] @@ -51,16 +49,14 @@ type AddMissingMatchClausesFixBase(warning: MatchIncompleteWarning) = let deconstructions = this.GetGenerationDeconstructions(value, deconstructions) MatchTree.generateClauses matchExpr value nodes deconstructions - Action<_>(fun textControl -> - lastClause - |> Option.iter (fun (clause: IMatchClause) -> - let newClause = clause.GetNextMeaningfulSibling().As() - if isNotNull newClause then - let range = newClause.Expression.GetDocumentRange() - textControl.Caret.MoveTo(range.EndOffset, CaretVisualPlacement.DontScrollIfVisible) - textControl.Selection.SetRange(range) - ) + lastClause + |> Option.map (fun (clause: IMatchClause) -> + match clause.GetNextMeaningfulSibling() with + | :? IMatchClause as newClause -> + BulbActionCommands.SetSelection(newClause.Expression.GetDocumentRange()) + | _ -> null ) + |> Option.defaultValue null type AddMissingPatternsFix(warning: MatchIncompleteWarning) = diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddParensToApplicationFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddParensToApplicationFix.fs index db1a13d731..3e5bfc6504 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddParensToApplicationFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/AddParensToApplicationFix.fs @@ -3,8 +3,8 @@ open System open System.Text.RegularExpressions open FSharp.Compiler.Symbols -open JetBrains.ReSharper.Feature.Services.Navigation.CustomHighlighting -open JetBrains.ReSharper.Feature.Services.Refactorings.WorkflowOccurrences +open JetBrains.ReSharper.Feature.Services.BulbActions.Commands +open JetBrains.ReSharper.Feature.Services.BulbActions.Commands.Menu open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util @@ -16,31 +16,24 @@ open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Resources.Shell open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl -open JetBrains.ProjectModel open JetBrains.UI.RichText -module AddParensToApplicationFix = - let [] AppPopupName = "AppPopup" - let [] ArgsPopupName = "ArgsPopup" - type AddParensToApplicationFix(error: NotAFunctionError) = inherit FSharpQuickFixBase() let [] popupItemMaxLength = 80 let errorPrefixApp = error.PrefixApp - let mutable appToApply = null - let mutable argsToApply = [] - let toDisplay (text: string) = - if text.Length <= popupItemMaxLength then text else + let trim (text: string) = + if text.Length <= popupItemMaxLength then RichText(text) else let text = Regex("\n\s*", RegexOptions.Compiled).Replace(text, " ↩ ") let diff = text.Length - popupItemMaxLength let center = text.Length / 2 let textBefore = text.Substring(0, center - diff / 2) let textAfter = text.Substring(center + diff / 2) - String.Concat(textBefore, " ... ", textAfter) + RichText($"{textBefore} ... {textAfter}") let getParentPrefixApp expr nestingLevel = let rec getParentPrefixAppRec expr i = @@ -117,45 +110,32 @@ type AddParensToApplicationFix(error: NotAFunctionError) = | [] -> false | list -> list |> List.forall (fun appData -> isValid appData.App) - override x.Execute(solution, textControl) = - let popupMenu = solution.GetComponent() - - let showPopup occurrences id = - popupMenu.ShowPopup(textControl.Lifetime, occurrences, CustomHighlightingKind.Other, textControl, null, id) - + override x.GetCommandSequence() = let appOccurrences = appCandidates |> Seq.rev - |> Seq.map (fun x -> - WorkflowPopupMenuOccurrence( - RichText(toDisplay (x.App.GetText())), RichText.Empty, x, - (fun appData -> [| appData.App.GetDocumentRange() |]))) + |> Seq.map (fun (x: {| App: IFSharpExpression; ArgCandidates: IFSharpExpression list; MaxArgsCount: int |}) -> + let text = trim (x.App.GetText()) + BulbActionCommandMenuItem<_>(Text = text, Data = x, Range = x.App.GetDocumentRange())) |> Array.ofSeq - let appOccurrence = showPopup appOccurrences AddParensToApplicationFix.AppPopupName - if isNull appOccurrence then () else - - let appData = Seq.head appOccurrence.Entities - - let argOccurrences = - [ 1 .. Math.Min(appData.MaxArgsCount, appData.ArgCandidates.Length) ] - |> Seq.rev - |> Seq.map (fun i -> - let args = appData.ArgCandidates |> List.take i - let argsTexts = args |> List.map (fun x -> x.GetText()) |> String.concat " " - WorkflowPopupMenuOccurrence( - RichText(toDisplay(String.Join(" ", appData.App.GetText(), argsTexts))), RichText.Empty, args, - (fun args -> [| getTreeNodesDocumentRange appData.App (args |> List.last) |]))) - |> Array.ofSeq + let argCommands (appData: {| App: IFSharpExpression; ArgCandidates: IFSharpExpression list; MaxArgsCount: int |}) = + let argOccurrences = + [ 1 .. Math.Min(appData.MaxArgsCount, appData.ArgCandidates.Length) ] + |> Seq.rev + |> Seq.map (fun i -> + let args = appData.ArgCandidates |> List.take i + let argTexts = args |> List.map _.GetText() |> String.concat " " + let text = trim($"{appData.App.GetText()} {argTexts}") + let range = getTreeNodesDocumentRange appData.App (args |> List.last) + BulbActionCommandMenuItem<_>(Text = text, Data = args, Range = range)) + |> Array.ofSeq - let argsOccurrence = showPopup argOccurrences AddParensToApplicationFix.ArgsPopupName - if isNull argsOccurrence then () else + x.ShowMenuAndExecute(argOccurrences, fun argsToApply -> x.Execute(appData.App, argsToApply)) - appToApply <- appData.App - argsToApply <- Seq.head argsOccurrence.Entities - base.Execute(solution, textControl) + BulbActionCommandSequence.From(x.ShowMenuAndExecute(appOccurrences, argCommands)) - override x.ExecutePsiTransaction _ = + member x.Execute(appToApply, argsToApply) = use writeCookie = WriteLockCookie.Create(errorPrefixApp.IsPhysical()) let factory = errorPrefixApp.CreateElementFactory() @@ -166,3 +146,4 @@ type AddParensToApplicationFix(error: NotAFunctionError) = let parentApp = PrefixAppExprNavigator.GetByArgumentExpression(parenExpr) ModificationUtil.ReplaceChild(getParentPrefixApp parentApp argsToApply.Length, parentApp) |> ignore + null diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ChangeTypeFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ChangeTypeFix.fs index 2f6b688324..4d805cfa4a 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ChangeTypeFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ChangeTypeFix.fs @@ -228,8 +228,9 @@ type ChangeReturnTypeFromInvocationFix(node: IFSharpTypeOwnerNode, fcsDiagnostic reference.Resolve().DeclaredElement - override this.SetType(decl, _, fcsType) = + override this.SetType(decl, fcsSymbol, fcsType) = let decl = FSharpParameterOwnerDeclarationNavigator.Unwrap(decl) + let mfv = fcsSymbol.As() let lambdaParamsCount = let bindingParamDeclCount = @@ -237,12 +238,11 @@ type ChangeReturnTypeFromInvocationFix(node: IFSharpTypeOwnerNode, fcsDiagnostic | :? IParameterOwnerMemberDeclaration as paramOwnerDecl -> paramOwnerDecl.ParametersDeclarations.Count | _ -> 0 - let mfv = decl.GetFcsSymbol().As() mfv.CurriedParameterGroups.Count - bindingParamDeclCount let decl = decl.As() if isNull decl.TypeUsage then - FSharpTypeUsageUtil.setFcsParametersOwnerReturnType decl + FSharpTypeUsageUtil.setFcsParametersOwnerReturnType mfv decl decl.TypeUsage |> FSharpTypeUsageUtil.skipParameters lambdaParamsCount diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/DeconstructPatternFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/DeconstructPatternFix.fs index fd4f78d1c3..adab3025d0 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/DeconstructPatternFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/DeconstructPatternFix.fs @@ -1,5 +1,7 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes +open JetBrains.DocumentModel +open JetBrains.ReSharper.Feature.Services.BulbActions open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions.Deconstruction @@ -15,6 +17,7 @@ type DeconstructPatternFix(error: UnionCaseExpectsTupledArgumentsError) = match DeconstructionFromUnionCaseFields.TryCreate(pattern, false) with | null -> None | d -> Some(pattern, d) + isNotNull deconstruction override this.IsAvailable _ = @@ -34,5 +37,8 @@ type DeconstructPatternFix(error: UnionCaseExpectsTupledArgumentsError) = override x.ExecutePsiTransaction(_, _) = match deconstruction with | Some(pattern, deconstruction) -> - FSharpDeconstruction.deconstruct true null deconstruction pattern - | _ -> failwithf "" + match FSharpDeconstructionImpl.deconstructImpl true deconstruction pattern with + | Some(hotspotsRegistry, _) -> + BulbActionCommands.ShowHotspotSession(hotspotsRegistry, DocumentOffset.InvalidOffset) + | _ -> null + | _ -> null diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/FSharpQuickFixBase.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/FSharpQuickFixBase.fs index 45880db9c4..b7ecad4a32 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/FSharpQuickFixBase.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/FSharpQuickFixBase.fs @@ -21,7 +21,7 @@ open JetBrains.TextControl open JetBrains.UI.RichText [] -type FSharpQuickFixBase() = +type FSharpLegacyQuickFixBase() = inherit QuickFixBase() abstract ExecutePsiTransaction: solution: ISolution -> unit @@ -50,18 +50,22 @@ type FSharpQuickFixBase() = [] -type FSharpModernQuickFixBase() = +type FSharpQuickFixBase() = inherit ModernQuickFixBase() - member x.SelectExpression(expressions: (IFSharpExpression * string) array, action) = - let menuItems = - expressions - |> Array.map (fun (expr, text) -> - let range = expr.GetDocumentRange() - BulbActionCommandMenuItem(Text = text, Data = expr, Range = range) - ) + member this.ShowMenuAndExecute(occurrences: BulbActionCommandMenuItem<_>[], action) = + BulbActionCommands.ShowMenu(occurrences, fun _ _ occurrence -> + BulbActionCommands.ExecutePsiTransaction(fun _ _ -> action occurrence) + ) + member x.ShowMenuAndExecute<'Node when 'Node :> ITreeNode>(occurrences: ('Node * string) array, action, rangeSelector) = BulbActionCommandSequence.From( + let menuItems = + occurrences + |> Array.map (fun (node, text) -> + BulbActionCommandMenuItem<'Node>(Text = text, Data = node, Range = rangeSelector node) + ) + BulbActionCommands.ShowMenu(menuItems, fun _ _ selectedExpr -> BulbActionCommands.ExecutePsiTransaction(fun _ _ -> action selectedExpr @@ -70,6 +74,15 @@ type FSharpModernQuickFixBase() = ) ) + member x.ShowMenuAndExecute(occurrences, action) = + x.ShowMenuAndExecute(occurrences, action, _.GetDocumentRange()) + + abstract ExecutePsiTransaction: solution: ISolution -> unit + default x.ExecutePsiTransaction _ = () + + override x.ExecutePsiTransaction(solution, _) = + x.ExecutePsiTransaction(solution) + null [] type FSharpScopedQuickFixBase(contextNode: ITreeNode) = diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/GenerateInterfaceMembersFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/GenerateInterfaceMembersFix.fs index b14e7ac492..97a51ccdc8 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/GenerateInterfaceMembersFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/GenerateInterfaceMembersFix.fs @@ -1,8 +1,8 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes -open System open System.Collections.Generic open FSharp.Compiler.Symbols +open JetBrains.ReSharper.Feature.Services.BulbActions open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Generate @@ -16,7 +16,6 @@ open JetBrains.ReSharper.Psi.Impl open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Psi.Util open JetBrains.ReSharper.Resources.Shell -open JetBrains.TextControl type FSharpGeneratorMfvElement(mfv, displayContext, substitution, addTypes) = new (mfvInstance: FcsMfvInstance, addTypes) = @@ -171,10 +170,5 @@ type GenerateInterfaceMembersFix(impl: IInterfaceImplementation) = impl.WithKeyword let addedMembers = GenerateOverrides.addMembers membersToGenerate typeDeclaration anchor - - Action<_>(fun textControl -> - let treeTextRange = GenerateOverrides.getGeneratedSelectionTreeRange addedMembers - if treeTextRange.IsValid() then - let documentRange = anchor.GetContainingFile().GetDocumentRange(treeTextRange) - textControl.Caret.MoveTo(documentRange.StartOffset, CaretVisualPlacement.DontScrollIfVisible) - textControl.Selection.SetRange(documentRange)) + let expr = GenerateOverrides.getGeneratedBodyToSelect addedMembers + BulbActionCommands.SetSelection(expr) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/GenerateMissingOverridesFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/GenerateMissingOverridesFix.fs index 88b8246e6c..e7bf66ff03 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/GenerateMissingOverridesFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/GenerateMissingOverridesFix.fs @@ -8,7 +8,7 @@ open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.Util type GenerateMissingOverridesFix(typeDecl: IFSharpTypeElementDeclaration) = - inherit FSharpQuickFixBase() + inherit FSharpLegacyQuickFixBase() let configureContext (context: IGeneratorContext) = context.InputElements.Clear() diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/GenerateMissingRecordFieldsFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/GenerateMissingRecordFieldsFix.fs index 06b1060a37..04e4d0debc 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/GenerateMissingRecordFieldsFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/GenerateMissingRecordFieldsFix.fs @@ -1,9 +1,8 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes -open System open System.Linq open JetBrains.Diagnostics -open JetBrains.ReSharper.Feature.Services.LiveTemplates.LiveTemplates +open JetBrains.ReSharper.Feature.Services.BulbActions open JetBrains.ReSharper.Feature.Services.LiveTemplates.Hotspots open JetBrains.ReSharper.Feature.Services.LiveTemplates.Templates open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings @@ -35,25 +34,17 @@ type GenerateMissingRecordFieldsFix(recordExpr: IRecordExpr) = let declaredElement = reference.Resolve().DeclaredElement isNotNull declaredElement - override x.ExecutePsiTransaction(solution, _) = + override x.ExecutePsiTransaction(_, _) = let typeElement = recordExpr.Reference.Resolve().DeclaredElement :?> ITypeElement Assertion.Assert(typeElement.IsRecord(), "Expecting record type") let generatedBindings = RecordExprUtil.generateBindings typeElement recordExpr - Action<_>(fun textControl -> - let templatesManager = LiveTemplatesManager.Instance - let endCaretPosition = recordExpr.RightBrace.GetDocumentEndOffset() + let hotspotInfos = + generatedBindings.ToArray() + |> Array.map (fun binding -> + let templateField = TemplateField(binding.ReferenceName.ShortName, SimpleHotspotExpression(null), 0) + HotspotInfo(templateField, binding.Expression.GetDocumentRange(), KeepExistingText = true)) - let hotspotInfos = - generatedBindings.ToArray() - |> Array.map (fun binding -> - let templateField = TemplateField(binding.ReferenceName.ShortName, SimpleHotspotExpression(null), 0) - HotspotInfo(templateField, binding.Expression.GetDocumentRange(), KeepExistingText = true)) - - let hotspotSession = - templatesManager.CreateHotspotSessionAtopExistingText( - solution, endCaretPosition, textControl, - LiveTemplatesManager.EscapeAction.LeaveTextAndCaret, hotspotInfos) - - hotspotSession.ExecuteAndForget()) + let endCaretPosition = recordExpr.RightBrace.GetDocumentEndOffset() + BulbActionCommands.ShowHotspotSession(hotspotInfos, endCaretPosition) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/IntroduceVarFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/IntroduceVarFix.fs index 6797fb9b3a..1faab255db 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/IntroduceVarFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/IntroduceVarFix.fs @@ -11,7 +11,7 @@ module IntroduceVarFix = let [] introduceVarOutsideLambdaText = "Introduce 'let' binding outside lambda" type IntroduceVarFix(node: IFSharpTypeOwnerNode, removeExpr, escapeLambdas, addMutable, text) = - inherit FSharpQuickFixBase() + inherit FSharpLegacyQuickFixBase() let mutable expr = node.As() diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/RemoveUnusedLocalBindingFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/RemoveUnusedLocalBindingFix.fs index 7df169b0a1..d7af670ba5 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/RemoveUnusedLocalBindingFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/RemoveUnusedLocalBindingFix.fs @@ -1,17 +1,14 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes -open System open JetBrains.Diagnostics +open JetBrains.ReSharper.Feature.Services.BulbActions open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree -open JetBrains.ReSharper.Psi.ExtensionsAPI open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree -open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Psi.Util open JetBrains.ReSharper.Resources.Shell -open JetBrains.TextControl type RemoveUnusedLocalBindingFix(warning: UnusedValueWarning) = inherit FSharpQuickFixBase() @@ -119,7 +116,6 @@ type RemoveUnusedLocalBindingFix(warning: UnusedValueWarning) = ModificationUtil.DeleteChildRange(rangeToDelete) - Action<_>(fun textControl -> - let anchorIndex = if bindingIndex > 0 then bindingIndex - 1 else 0 - let offset = letBindings.Bindings[anchorIndex].GetDocumentRange().EndOffset - textControl.Caret.MoveTo(offset, CaretVisualPlacement.DontScrollIfVisible)) + let anchorIndex = if bindingIndex > 0 then bindingIndex - 1 else 0 + let binding = letBindings.Bindings[anchorIndex] + BulbActionCommands.SetCaretAfter(binding) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ReplaceReturnTypeFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ReplaceReturnTypeFix.fs index 81423a4ea1..961c01d4f8 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ReplaceReturnTypeFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ReplaceReturnTypeFix.fs @@ -1,5 +1,6 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes +open FSharp.Compiler.Symbols open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Resolve open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util.FcsTypeUtil @@ -83,6 +84,14 @@ type ReplaceReturnTypeFix(node: IFSharpTypeOwnerNode, diagnosticInfo: FcsCachedD isNull returnTypeUsage || canUpdateReturnType returnTypeUsage override this.ExecutePsiTransaction _ = + let decls = + decl.DeclaredElement.GetDeclarations() + |> Seq.map (fun decl -> + let fsDecl = decl :?> IFSharpDeclaration + let mfv = fsDecl.GetFcsSymbol().As() + fsDecl, mfv + ) + use writeCookie = WriteLockCookie.Create(decl.IsPhysical()) let paramCount = @@ -90,7 +99,7 @@ type ReplaceReturnTypeFix(node: IFSharpTypeOwnerNode, diagnosticInfo: FcsCachedD | :? IParameterOwnerMemberDeclaration as paramOwnerDecl -> paramOwnerDecl.ParametersDeclarations.Count | _ -> 0 - for originalDecl in decl.DeclaredElement.GetDeclarations() do + for originalDecl, fcsSymbol in decls do let decl = unwrapDecl originalDecl if isNull decl then () else @@ -101,7 +110,7 @@ type ReplaceReturnTypeFix(node: IFSharpTypeOwnerNode, diagnosticInfo: FcsCachedD lambdaParametersCount if isNull decl.TypeUsage then - FSharpTypeUsageUtil.setFcsParametersOwnerReturnType decl + FSharpTypeUsageUtil.setFcsParametersOwnerReturnType fcsSymbol decl let typeUsage = let pat = originalDecl.As() diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ReplaceUseWithLetFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ReplaceUseWithLetFix.fs index c99d7196f8..373216985f 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ReplaceUseWithLetFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ReplaceUseWithLetFix.fs @@ -5,7 +5,6 @@ open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings open JetBrains.ReSharper.Plugins.FSharp.Psi.Parsing open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree -open JetBrains.ReSharper.Psi.ExtensionsAPI open JetBrains.ReSharper.Resources.Shell type ReplaceUseWithLetFix(letNode: ILetBindings) = diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ReplaceWithInterpolatedStringFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ReplaceWithInterpolatedStringFix.fs index 747fc0ffbb..8304fb22f5 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ReplaceWithInterpolatedStringFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ReplaceWithInterpolatedStringFix.fs @@ -2,13 +2,13 @@ open System.Text open JetBrains.Metadata.Reader.API +open JetBrains.ReSharper.Plugins.FSharp open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl.Tree open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.ReSharper.Psi -open JetBrains.ReSharper.Psi.ExtensionsAPI open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Resources.Shell @@ -45,11 +45,12 @@ module ReplaceWithInterpolatedStringFix = | _ -> false type ReplaceWithInterpolatedStringFix(warning: InterpolatedStringCandidateWarning) = - inherit FSharpScopedQuickFixBase(warning.FormatStringExpr) + inherit FSharpScopedNonIncrementalQuickFixBase(warning.FormatStringExpr) let outerPrefixAppExpr = warning.OuterPrefixAppExpr let prefixAppExpr = warning.PrefixAppExpr let formatStringExpr = warning.FormatStringExpr + let isSprintf = isPredefinedFunctionRef "sprintf" prefixAppExpr.FunctionExpression override this.Text = "To interpolated string" @@ -57,15 +58,14 @@ type ReplaceWithInterpolatedStringFix(warning: InterpolatedStringCandidateWarnin isValid formatStringExpr override this.ExecutePsiTransaction _ = + use prohibitTypeCheckCookie = ProhibitTypeCheckCookie.Create() use writeCookie = WriteLockCookie.Create(formatStringExpr.IsPhysical()) let appliedExprFormatSpecs = - let startOffset = formatStringExpr.GetDocumentRange().StartOffset.Offset - - warning.FormatSpecsAndExprs - |> Seq.map (fun (specifierRange, expr) -> - let index = specifierRange.EndOffset.Offset - startOffset - index, InsertInterpolation(specifierRange.GetText(), expr)) + (warning.SpecOffsets, warning.FormatSpecs, warning.Expressions) + |||> Seq.zip3 + |> Seq.map (fun (index, specifier, expr) -> + index, InsertInterpolation(specifier, expr)) let formatString = formatStringExpr.GetText() @@ -116,10 +116,12 @@ type ReplaceWithInterpolatedStringFix(warning: InterpolatedStringCandidateWarnin interpolatedSb.Insert(0, '$') |> ignore let interpolatedStringExpr = factory.CreateExpr(interpolatedSb.ToString()) - if isPredefinedFunctionRef "sprintf" prefixAppExpr.FunctionExpression then + if isSprintf then let newChild = ModificationUtil.ReplaceChild(outerPrefixAppExpr, interpolatedStringExpr) if not (isWhitespace (newChild.GetPreviousToken())) then ModificationUtil.AddChildBefore(newChild, Whitespace()) |> ignore else ModificationUtil.ReplaceChild(formatStringExpr, interpolatedStringExpr) |> ignore ModificationUtil.ReplaceChild(outerPrefixAppExpr, prefixAppExpr) |> ignore + + override this.IsReanalysisRequired = false diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/SpecifyParameterBaseTypeFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/SpecifyParameterBaseTypeFix.fs index 68c759e93d..1e6033bcdb 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/SpecifyParameterBaseTypeFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/SpecifyParameterBaseTypeFix.fs @@ -2,8 +2,8 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes open FSharp.Compiler.Symbols open JetBrains.ProjectModel -open JetBrains.ReSharper.Feature.Services.Navigation.CustomHighlighting -open JetBrains.ReSharper.Feature.Services.Refactorings.WorkflowOccurrences +open JetBrains.ReSharper.Feature.Services.BulbActions.Commands +open JetBrains.ReSharper.Feature.Services.BulbActions.Commands.Menu open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util @@ -11,8 +11,8 @@ open JetBrains.ReSharper.Plugins.FSharp.Psi.Services.Util open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.ReSharper.Plugins.FSharp.Psi.Util open JetBrains.ReSharper.Psi +open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Resources.Shell -open JetBrains.TextControl open JetBrains.UI.RichText module SpecifyParameterBaseTypeFix = @@ -30,9 +30,9 @@ type SpecifyParameterBaseTypeFix(refExpr: IReferenceExpr, typeUsage: ITypeUsage) let pat = if not refExpr.IsSimpleName then null else - refExpr.Reference.Resolve().DeclaredElement.As() + refExpr.Reference.Resolve().DeclaredElement.As() - let mutable baseType: FSharpType option = None + let solution = refExpr.GetSolution() let getFcsEntity (typeUsage: ITypeUsage) = let namedTypeUsage = typeUsage.As() @@ -119,21 +119,16 @@ type SpecifyParameterBaseTypeFix(refExpr: IReferenceExpr, typeUsage: ITypeUsage) ) |> Option.defaultValue false - override this.ExecutePsiTransaction _ = + member this.Execute fcsType = use writeCookie = WriteLockCookie.Create(pat.IsPhysical()) - TypeAnnotationUtil.specifyPatternType baseType.Value pat + TypeAnnotationUtil.specifyPatternType fcsType pat + null - override this.Execute(solution, textControl) = + override x.GetCommandSequence() = let fcsEntity, displayContext = getFcsEntity typeUsage |> Option.get - let superTypes = getSuperTypes fcsEntity - baseType <- this.SelectType(superTypes, displayContext, solution, textControl) + let typeNames = getSuperTypes fcsEntity - if baseType.IsSome then - base.Execute(solution, textControl) - - member x.SelectType(typeNames: (FSharpType * bool) list, displayContext: FSharpDisplayContext, solution: ISolution, - textControl: ITextControl) = let occurrences = typeNames |> List.map (fun (fcsType, isImmediateSuperType) -> @@ -150,13 +145,8 @@ type SpecifyParameterBaseTypeFix(refExpr: IReferenceExpr, typeUsage: ITypeUsage) let richText = RichText(fcsType.Format(displayContext)) if isImmediateSuperType then richText.SetStyle(JetFontStyles.Bold, 0, richText.Length) |> ignore - WorkflowPopupMenuOccurrence(richText, RichText.Empty, fcsType, icon)) + BulbActionCommandMenuItem<_>(Text = richText, Data = fcsType, Icon = icon) + ) |> List.toArray - let occurrence = - let popupMenu = solution.GetComponent() - popupMenu.ShowPopup(textControl.Lifetime, occurrences, CustomHighlightingKind.Other, textControl, null) - - occurrence - |> Option.ofObj - |> Option.bind (fun occurrence -> occurrence.Entities |> Seq.tryHead) + BulbActionCommandSequence.From(x.ShowMenuAndExecute(occurrences, x.Execute)) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ToObjectExpressionFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ToObjectExpressionFix.fs index b7399ddb7a..69523c6c71 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ToObjectExpressionFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ToObjectExpressionFix.fs @@ -6,7 +6,6 @@ open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Generate open JetBrains.ReSharper.Plugins.FSharp.Psi.Services.Util.ObjExprUtil open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree -open JetBrains.ReSharper.Psi.ExtensionsAPI open JetBrains.ReSharper.Resources.Shell type ToObjectExpressionFix(error: AbstractTypeCannotBeInstantiatedError) = @@ -16,7 +15,7 @@ type ToObjectExpressionFix(error: AbstractTypeCannotBeInstantiatedError) = override this.Text = "Convert to object expression" - override this.IsAvailable(cache) = + override this.IsAvailable _ = let appExpr = expr.As() isNotNull appExpr && @@ -25,7 +24,7 @@ type ToObjectExpressionFix(error: AbstractTypeCannotBeInstantiatedError) = NewObjPostfixTemplate.isApplicableExpr refExpr - override this.ExecutePsiTransaction(solution, var0) = + override this.ExecutePsiTransaction(_, _) = let factory = expr.CreateElementFactory() use writeCookie = WriteLockCookie.Create(expr.IsPhysical()) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ToRecursiveFunctionFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ToRecursiveFunctionFix.fs index 851270ad4d..a58c0a3d00 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ToRecursiveFunctionFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/ToRecursiveFunctionFix.fs @@ -1,13 +1,10 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes -open JetBrains.ProjectModel -open JetBrains.ReSharper.Feature.Services.Navigation.CustomHighlighting -open JetBrains.ReSharper.Feature.Services.Refactorings.WorkflowOccurrences +open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.ReSharper.Psi.Tree -open JetBrains.UI.RichText type ToRecursiveFunctionFix(warning: UndefinedNameError) = inherit FSharpQuickFixBase() @@ -22,7 +19,7 @@ type ToRecursiveFunctionFix(warning: UndefinedNameError) = | node -> loop node (node :: result) loop refExpr [] - let isSuitable (letBindings: ILetBindings) = + let isApplicable (letBindings: ILetBindings) = if isNull referenceExpr then false else if letBindings.IsRecursive then false else @@ -35,7 +32,7 @@ type ToRecursiveFunctionFix(warning: UndefinedNameError) = |> Option.defaultValue false let getNameRange (letBindings: ILetBindings) = - [| letBindings.Bindings[0].HeadPattern.GetDocumentRange() |] + letBindings.Bindings[0].HeadPattern.GetDocumentRange() override x.Text = $"Make '{referenceExpr.ShortName}' recursive" @@ -43,27 +40,20 @@ type ToRecursiveFunctionFix(warning: UndefinedNameError) = if not (isValid referenceExpr && not referenceExpr.IsQualified) then false else getContainingBindings referenceExpr - |> List.filter isSuitable + |> List.filter isApplicable |> List.isEmpty |> not - override x.Execute(solution, textControl) = - let letBindings = getContainingBindings referenceExpr |> List.filter isSuitable - let name = RichText(referenceExpr.ShortName) + override x.GetCommandSequence() = + let letBindings = getContainingBindings referenceExpr |> List.filter isApplicable + let name = referenceExpr.ShortName let occurrences = letBindings - |> List.map (fun bindings -> WorkflowPopupMenuOccurrence(name, RichText.Empty, bindings, getNameRange)) + |> List.map (fun bindings -> bindings, $"{name} (line {bindings.Bindings[0].HeadPattern.StartLine})") |> Array.ofSeq - let occurrence = - let popupMenu = solution.GetComponent() - popupMenu.ShowPopup(textControl.Lifetime, occurrences, CustomHighlightingKind.Other, textControl, null) - - if isNull occurrence then () else - - chosenLetBindings <- Seq.head occurrence.Entities - base.Execute(solution, textControl) + x.ShowMenuAndExecute(occurrences, ToRecursiveLetBindingsAction.Execute, getNameRange) override x.ExecutePsiTransaction _ = ToRecursiveLetBindingsAction.Execute(chosenLetBindings) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/UseNestedRecordFieldSyntaxFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/UseNestedRecordFieldSyntaxFix.fs index cbde6f5c1a..a987d10afd 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/UseNestedRecordFieldSyntaxFix.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/UseNestedRecordFieldSyntaxFix.fs @@ -4,7 +4,6 @@ open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util.FSharpResolveUtil open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl -open JetBrains.ReSharper.Psi.ExtensionsAPI open JetBrains.ReSharper.Resources.Shell type UseNestedRecordFieldSyntaxFix(warning: NestedRecordUpdateCanBeSimplifiedWarning) = @@ -37,6 +36,7 @@ type UseNestedRecordFieldSyntaxFix(warning: NestedRecordUpdateCanBeSimplifiedWar | [] -> [] | _ -> findRequiredQualifierForRecordField outerBinding |> Option.defaultValue [] - let newBinding = factory.CreateRecordFieldBinding(fieldQualifier @ fieldName, isNotNull outerBinding.Semicolon) + let qualifiedName = fieldQualifier @ List.ofArray fieldName + let newBinding = factory.CreateRecordFieldBinding(qualifiedName, isNotNull outerBinding.Semicolon) replace newBinding.Expression (innerBinding.Expression.IgnoreInnerParens()) replace outerBinding newBinding diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Daemon/Highlightings/Errors.xml b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Daemon/Highlightings/Errors.xml index 47943c8294..8fb7ec3f17 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Daemon/Highlightings/Errors.xml +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Daemon/Highlightings/Errors.xml @@ -1,5 +1,8 @@  - + JetBrains.ReSharper.Intentions.QuickFixes; JetBrains.ReSharper.Plugins.FSharp.Psi; @@ -14,92 +17,92 @@ - - <Description resourceName="ParenthesesCanBeSafelyRemovedWithoutChangingCodeSemantics" resourceType="Strings"/> + <Title resourceName="RemoveRedundantParentheses"/> + <Description resourceName="ParenthesesCanBeSafelyRemovedWithoutChangingCodeSemantics"/> </Tag> <Tag name="FSharpRedundantOpen" default="WARNING"> - <Title resourceName="RedundantOpenDirective" resourceType="Strings"/> - <Description resourceName="OpenDirectiveIsNotRequiredByTheCodeAndCanBeSafelyRemoved" resourceType="Strings"/> + <Title resourceName="RedundantOpenDirective"/> + <Description resourceName="OpenDirectiveIsNotRequiredByTheCodeAndCanBeSafelyRemoved"/> </Tag> <Tag name="FSharpRedundantBackticks" default="WARNING"> - <Title resourceName="RedundantIdentifierEscaping" resourceType="Strings"/> - <Description resourceName="RedundantUseOfEscapingSequences" resourceType="Strings"/> + <Title resourceName="RedundantIdentifierEscaping"/> + <Description resourceName="RedundantUseOfEscapingSequences"/> </Tag> <Tag name="FSharpRedundantNameQualifier" default="WARNING"> - <Title resourceName="RedundantNameQualifier" resourceType="Strings"/> - <Description resourceName="RedundantUseOfQualifierForName" resourceType="Strings"/> + <Title resourceName="RedundantNameQualifier"/> + <Description resourceName="RedundantUseOfQualifierForName"/> </Tag> <Tag name="FSharpRedundantNew" default="WARNING"> - <Title resourceName="RedundantNewKeyword" resourceType="Strings"/> - <Description resourceName="NewKeywordIsNotRequiredAndCanBeSafelyRemoved" resourceType="Strings"/> + <Title resourceName="RedundantNewKeyword"/> + <Description resourceName="NewKeywordIsNotRequiredAndCanBeSafelyRemoved"/> </Tag> <Tag name="FSharpRedundantAttributeParens" default="WARNING"> - <Title resourceName="RedundantAttributeParenthesesArgument" resourceType="Strings"/> - <Description resourceName="ParenthesesAreRedundantIfAttributeHasNoArguments" resourceType="Strings"/> + <Title resourceName="RedundantAttributeParenthesesArgument"/> + <Description resourceName="ParenthesesAreRedundantIfAttributeHasNoArguments"/> </Tag> <Tag name="FSharpRedundantAttributeSuffix" default="WARNING"> - <Title resourceName="RedundantAttributeSuffix" resourceType="Strings"/> - <Description resourceName="RedundantAttributeSuffix1" resourceType="Strings"/> + <Title resourceName="RedundantAttributeSuffix"/> + <Description resourceName="RedundantAttributeSuffix1"/> </Tag> <Tag name="FSharpRedundantUnionCaseFieldPatterns" default="WARNING"> - <Title resourceName="RedundantUnionCaseFieldsMatching" resourceType="Strings"/> - <Description resourceName="ExplicitFieldsMatchingIsRedundantAndCanBeReplacedWith" resourceType="Strings"/> + <Title resourceName="RedundantUnionCaseFieldsMatching"/> + <Description resourceName="ExplicitFieldsMatchingIsRedundantAndCanBeReplacedWith"/> </Tag> <Tag name="FSharpConsWithEmptyListPat" default="SUGGESTION"> - <Title resourceName="RedundantConcatenationWithEmptyList" resourceType="Strings"/> - <Description resourceName="RedundantConcatenationWithEmptyList2" resourceType="Strings"/> + <Title resourceName="RedundantConcatenationWithEmptyList"/> + <Description resourceName="RedundantConcatenationWithEmptyList2"/> </Tag> <Tag name="FSharpRedundantApplication" default="WARNING"> - <Title resourceName="RedundantApplication" resourceType="Strings"/> - <Description resourceName="ApplicationIsRedundantAndCanBeReplacedWithItsArgument" resourceType="Strings"/> + <Title resourceName="RedundantApplication"/> + <Description resourceName="ApplicationIsRedundantAndCanBeReplacedWithItsArgument"/> </Tag> <Tag name="FSharpRedundantRequireQualifiedAccessAttribute" default="WARNING"> - <Title resourceName="RedundantRequireQualifiedAccessAttribute" resourceType="Strings"/> - <Description resourceName="EnumTypeAlwaysRequiresQualifiedAccess" resourceType="Strings"/> + <Title resourceName="RedundantRequireQualifiedAccessAttribute"/> + <Description resourceName="EnumTypeAlwaysRequiresQualifiedAccess"/> </Tag> <Tag name="FSharpLambdaCanBeSimplified" default="HINT"> - <Title resourceName="LambdaExpressionCanBeSimplified" resourceType="Strings"/> - <Description resourceName="LambdaExpressionCanBeSimplified3" resourceType="Strings"/> + <Title resourceName="LambdaExpressionCanBeSimplified"/> + <Description resourceName="LambdaExpressionCanBeSimplified3"/> </Tag> <Tag name="FSharpLambdaCanBeReplacedWithInnerExpression" default="HINT"> - <Title resourceName="LambdaExpressionCanBeReplacedWithInnerExpression" resourceType="Strings"/> - <Description resourceName="LambdaExpressionCanBeReplacedWithInnerExpression4" resourceType="Strings"/> + <Title resourceName="LambdaExpressionCanBeReplacedWithInnerExpression"/> + <Description resourceName="LambdaExpressionCanBeReplacedWithInnerExpression4"/> </Tag> <Tag name="FSharpBuiltinFunctionReimplementation" default="HINT"> - <Title resourceName="LambdaExpressionCanBeReplacedWithBuiltInFunction" resourceType="Strings"/> - <Description resourceName="LambdaExpressionCanBeReplacedWithBuiltInFunction5" resourceType="Strings"/> + <Title resourceName="LambdaExpressionCanBeReplacedWithBuiltInFunction"/> + <Description resourceName="LambdaExpressionCanBeReplacedWithBuiltInFunction5"/> </Tag> <Tag name="FSharpUseWildSelfId" default="SUGGESTION"> - <Title resourceName="UseSelfId" resourceType="Strings"/> - <Description resourceName="UseSelfId6" resourceType="Strings"/> + <Title resourceName="UseSelfId"/> + <Description resourceName="UseSelfId6"/> </Tag> <Tag name="FSharpRedundantStringInterpolation" default="SUGGESTION"> - <Title resourceName="RedundantStringInterpolation" resourceType="Strings"/> - <Description resourceName="StringInterpolationExpressionWithoutArgumentsIsRedundant" resourceType="Strings"/> + <Title resourceName="RedundantStringInterpolation"/> + <Description resourceName="StringInterpolationExpressionWithoutArgumentsIsRedundant"/> </Tag> <Tag name="FSharpInterpolatedString" default="SUGGESTION"> - <Title resourceName="FormatStringCanBeReplacedWithAnInterpolatedString" resourceType="Strings"/> - <Description resourceName="FormatStringCanBeReplacedWithAnInterpolatedString7" resourceType="Strings"/> + <Title resourceName="FormatStringCanBeReplacedWithAnInterpolatedString"/> + <Description resourceName="FormatStringCanBeReplacedWithAnInterpolatedString7"/> </Tag> <Tag name="FSharpExpressionCanBeReplacedWithCondition" default="HINT"> - <Title resourceName="IfExpressionCanBeReplacedWithItsCondition" resourceType="Strings"/> - <Description resourceName="IfExpressionCanBeReplacedWithItsCondition8" resourceType="Strings"/> + <Title resourceName="IfExpressionCanBeReplacedWithItsCondition"/> + <Description resourceName="IfExpressionCanBeReplacedWithItsCondition8"/> </Tag> <Tag name="FSharpRedundantAsPattern" default="WARNING"> - <Title resourceName="RedundantAsPattern" resourceType="Strings"/> - <Description resourceName="AsPatternCanBeReplacedWithItsName" resourceType="Strings"/> + <Title resourceName="RedundantAsPattern"/> + <Description resourceName="AsPatternCanBeReplacedWithItsName"/> </Tag> <Tag name="FSharpRedundantDotInIndexer" default="WARNING"> - <Title resourceName="RedundantInIndexer" resourceType="Strings"/> - <Description resourceName="CanBeRemovedInIndexers" resourceType="Strings"/> + <Title resourceName="RedundantInIndexer"/> + <Description resourceName="CanBeRemovedInIndexers"/> </Tag> <Tag name="NestedRecordUpdateCanBeSimplified" default="SUGGESTION"> - <Title resourceName="NestedRecordUpdateCanBeSimplifiedMessage" resourceType="Strings"/> - <Description resourceName="NestedRecordUpdateCanBeSimplifiedMessage" resourceType="Strings"/> + <Title resourceName="NestedRecordUpdateCanBeSimplifiedMessage"/> + <Description resourceName="NestedRecordUpdateCanBeSimplifiedMessage"/> </Tag> <Tag name="FSharpDotLambdaCanBeUsed" default="HINT"> - <Title resourceName="DotLambdaCanBeUsedStringMessage" resourceType="Strings"/> - <Description resourceName="DotLambdaCanBeUsedStringMessage" resourceType="Strings"/> + <Title resourceName="DotLambdaCanBeUsedStringMessage"/> + <Description resourceName="DotLambdaCanBeUsedStringMessage"/> </Tag> </Group> </SeverityConfiguration> @@ -110,7 +113,7 @@ <Warning name="UnusedOpen" configurableSeverity="FSharpRedundantOpen"> <Parameter type="IOpenStatement" name="openStatement"/> - <Message resourceName="OpenDirectiveIsNotRequiredByTheCodeAndCanBeSafelyRemovedMessage" resourceType="Strings"/> + <Message resourceName="OpenDirectiveIsNotRequiredByTheCodeAndCanBeSafelyRemovedMessage"/> <Range>openStatement.GetHighlightingRange()</Range> <Behavour attributeID="DEADCODE"/> <QuickFix>RemoveUnusedOpensFix</QuickFix> @@ -120,7 +123,7 @@ <Parameter type="IAttribute" name="attr"/> <Range>attr.GetHighlightingRange()</Range> <Behavour overlapResolvePolicy="NONE"/> - <Message resourceName="ExtensionMemberInNonExtensionTypeLooksSuspiciousMessage" resourceType="Strings"/> + <Message resourceName="ExtensionMemberInNonExtensionTypeLooksSuspiciousMessage"/> <QuickFix>AddExtensionAttributeFix</QuickFix> </Warning> @@ -128,14 +131,14 @@ <Parameter type="IAttribute" name="attr"/> <Range>attr.GetHighlightingRange()</Range> <Behavour attributeID="DEADCODE" overlapResolvePolicy="NONE"/> - <Message resourceName="ExtensionTypeDoesnTHaveAnyExtensionMembersMessage" resourceType="Strings"/> + <Message resourceName="ExtensionTypeDoesnTHaveAnyExtensionMembersMessage"/> </Warning> <Warning staticGroup="FSharpErrors" name="ExtensionAttributeIsRedundant"> <Parameter type="IAttribute" name="attribute"/> <Range>attribute.GetHighlightingRange()</Range> <Behavour attributeID="DEADCODE" overlapResolvePolicy="NONE"/> - <Message resourceName="ExtensionAttributeIsRedundantMessage" resourceType="Strings"/> + <Message resourceName="ExtensionAttributeIsRedundantMessage"/> <QuickFix>RemoveRedundantAttributeFix</QuickFix> </Warning> @@ -143,21 +146,21 @@ <Parameter type="IAttribute" name="attr"/> <Range>attr.GetHighlightingRange()</Range> <Behavour overlapResolvePolicy="NONE"/> - <Message resourceName="ExtensionMemberShouldBeStaticMessage" resourceType="Strings"/> + <Message resourceName="ExtensionMemberShouldBeStaticMessage"/> </Warning> <Warning name="RedundantRequireQualifiedAccessAttribute" configurableSeverity="FSharpRedundantRequireQualifiedAccessAttribute"> <Parameter type="IAttribute" name="attr"/> <Range>attr.GetHighlightingRange()</Range> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> - <Message resourceName="RedundantRequireQualifiedAccessAttributeMessage" resourceType="Strings"/> + <Message resourceName="RedundantRequireQualifiedAccessAttributeMessage"/> <QuickFix>RemoveRedundantAttributeFix</QuickFix> </Warning> <Warning name="RedundantBackticks" configurableSeverity="FSharpRedundantBackticks"> <Parameter type="FSharpIdentifierToken" name="identifier"/> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> - <Message resourceName="RedundantIdentifierEscapingMessage" resourceType="Strings"/> + <Message resourceName="RedundantIdentifierEscapingMessage"/> <Range>identifier.GetHighlightingRange().StartOffsetRange().ExtendRight(2)</Range> <SecondaryRanges>[| identifier.GetHighlightingRange().EndOffsetRange().ExtendLeft(2) |] :> _</SecondaryRanges> <QuickFix>RemoveRedundantBackticksFix</QuickFix> @@ -167,7 +170,7 @@ <Parameter type="INewExpr" name="newExpr"/> <Range>newExpr.NewKeyword.GetHighlightingRange()</Range> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> - <Message resourceName="NewKeywordIsRedundantMessage" resourceType="Strings"/> + <Message resourceName="NewKeywordIsRedundantMessage"/> <QuickFix>RemoveRedundantNewFix</QuickFix> </Warning> @@ -175,14 +178,14 @@ <Parameter type="ILetOrUseExpr" name="letExpr"/> <Range>letExpr.BindingKeyword.GetHighlightingRange()</Range> <Behavour overlapResolvePolicy="NONE"/> - <Message resourceName="ConvertToUseBindingMessage" resourceType="Strings"/> + <Message resourceName="ConvertToUseBindingMessage"/> <QuickFix>ConvertToUseFix</QuickFix> </Warning> <Warning staticGroup="FSharpErrors" name="RedundantParenExpr" configurableSeverity="FSharpRedundantParens" isSuppressedInTests="true"> <Parameter type="IParenExpr" name="parenExpr"/> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> - <Message resourceName="RedundantParenthesesMessage" resourceType="Strings"/> + <Message resourceName="RedundantParenthesesMessage"/> <Range>parenExpr.LeftParen.GetHighlightingRange()</Range> <SecondaryRanges>secondaryRangesFromNode parenExpr.RightParen</SecondaryRanges> <QuickFix>RemoveRedundantParenExprFix</QuickFix> @@ -191,7 +194,7 @@ <Warning staticGroup="FSharpErrors" name="RedundantParenPat" configurableSeverity="FSharpRedundantParens"> <Parameter type="IParenPat" name="parenPat"/> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> - <Message resourceName="RedundantParenthesesMessage" resourceType="Strings"/> + <Message resourceName="RedundantParenthesesMessage"/> <Range>parenPat.LeftParen.GetHighlightingRange()</Range> <SecondaryRanges>secondaryRangesFromNode parenPat.RightParen</SecondaryRanges> <QuickFix>RemoveRedundantParenPatFix</QuickFix> @@ -200,7 +203,7 @@ <Warning staticGroup="FSharpErrors" name="RedundantParenTypeUsage" configurableSeverity="FSharpRedundantParens"> <Parameter type="IParenTypeUsage" name="parenTypeUsage"/> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> - <Message resourceName="RedundantParenthesesMessage" resourceType="Strings"/> + <Message resourceName="RedundantParenthesesMessage"/> <Range>parenTypeUsage.LeftParen.GetHighlightingRange()</Range> <SecondaryRanges>secondaryRangesFromNode parenTypeUsage.RightParen</SecondaryRanges> <QuickFix>RemoveRedundantParenTypeUsageFix</QuickFix> @@ -210,7 +213,7 @@ <Parameter type="IAttribute" name="attribute"/> <Range>attribute.ArgExpression.GetHighlightingRange()</Range> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> - <Message resourceName="ParenthesesAreRedundantIfAttributeHasNoArgumentsMessage" resourceType="Strings"/> + <Message resourceName="ParenthesesAreRedundantIfAttributeHasNoArgumentsMessage"/> <QuickFix>RemoveRedundantAttributeParensFix</QuickFix> </Warning> @@ -218,7 +221,7 @@ <Parameter type="IAttribute" name="attribute"/> <Range>getAttributeSuffixRange attribute</Range> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> - <Message resourceName="AttributeSuffixIsRedundantMessage" resourceType="Strings"/> + <Message resourceName="AttributeSuffixIsRedundantMessage"/> <QuickFix>RemoveRedundantAttributeSuffixFix</QuickFix> </Warning> @@ -226,21 +229,21 @@ <Parameter type="ITreeNode" name="treeNode"/> <Range>getQualifierRange treeNode</Range> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> - <Message resourceName="QualifierIsRedundantMessage" resourceType="Strings"/> + <Message resourceName="QualifierIsRedundantMessage"/> <QuickFix>RemoveRedundantQualifierFix</QuickFix> </Warning> <Warning name="RedundantUnionCaseFieldPatterns" configurableSeverity="FSharpRedundantUnionCaseFieldPatterns"> <Parameter type="IParenPat" name="parenPat"/> <Range>parenPat.GetHighlightingRange()</Range> - <Message resourceName="RedundantUnionCaseFieldsMatchingMessage" resourceType="Strings"/> + <Message resourceName="RedundantUnionCaseFieldsMatchingMessage"/> <QuickFix>ReplaceWithWildPatScopedFix</QuickFix> </Warning> <Warning name="ConsWithEmptyListPat" configurableSeverity="FSharpConsWithEmptyListPat"> <Parameter type="IListConsPat" name="listConsPat"/> <Range>listConsPat.GetHighlightingRange()</Range> - <Message resourceName="PatternCanBeSimplifiedMessage" resourceType="Strings"/> + <Message resourceName="PatternCanBeSimplifiedMessage"/> <QuickFix>SimplifyListConsPatFix</QuickFix> </Warning> @@ -249,7 +252,7 @@ <Parameter type="IFSharpExpression" name="argExpr"/> <Range>getFunctionApplicationRange appExpr</Range> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> - <Message resourceName="RedundantApplicationMessage" resourceType="Strings"/> + <Message resourceName="RedundantApplicationMessage"/> <QuickFix>ReplaceAppExprWithArgFix</QuickFix> </Warning> @@ -257,7 +260,7 @@ <Parameter type="ILambdaExpr" name="lambdaExpr"/> <Parameter type="IFSharpExpression" name="replaceCandidate"/> <Range>lambdaExpr.GetHighlightingRange()</Range> - <Message resourceName="LambdaCanBeSimplifiedMessage" resourceType="Strings"/> + <Message resourceName="LambdaCanBeSimplifiedMessage"/> <QuickFix>SimplifyLambdaFix</QuickFix> </Warning> @@ -265,9 +268,7 @@ <Parameter type="ILambdaExpr" name="lambdaExpr"/> <Parameter type="IFSharpExpression" name="replaceCandidate"/> <Range>lambdaExpr.GetHighlightingRange()</Range> - <Message resourceName="Message" resourceType="Strings"> - <Argument>getLambdaCanBeReplacedWarningText replaceCandidate</Argument> - </Message> + <Message>getLambdaCanBeReplacedWarningText replaceCandidate</Message> <QuickFix>ReplaceLambdaWithInnerExpressionFix</QuickFix> </Warning> @@ -275,24 +276,22 @@ <Parameter type="ILambdaExpr" name="lambda"/> <Parameter type="string" name="funName"/> <Range>lambda.GetHighlightingRange()</Range> - <Message resourceName="Message" resourceType="Strings"> - <Argument>sprintf "Lambda can be replaced with '%s'" funName</Argument> - </Message> + <Message>sprintf "Lambda can be replaced with '%s'" funName</Message> <QuickFix>ReplaceLambdaWithBuiltinFunctionFix</QuickFix> </Warning> - <Warning name="DotLambdaCanBeUsed" configurableSeverity="FSharpDotLambdaCanBeUsed"> + <Warning name="DotLambdaCanBeUsed" configurableSeverity="FSharpDotLambdaCanBeUsed" forkTranslation="false"> <Parameter type="ILambdaExpr" name="lambda"/> <Parameter type="IReferenceExpr" name="rootRefExpr"/> <Range>getTreeNodesDocumentRange lambda lambda.RArrow</Range> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> - <Message resourceName="DotLambdaCanBeUsedStringMessage" resourceType="Strings"/> + <Message resourceName="DotLambdaCanBeUsedStringMessage"/> <QuickFix>ReplaceLambdaWithDotLambdaFix</QuickFix> </Warning> <Warning name="UseWildSelfId" configurableSeverity="FSharpUseWildSelfId"> <Parameter type="INamedSelfId" name="selfId"/> - <Message resourceName="UseMessage" resourceType="Strings"/> + <Message resourceName="UseMessage"/> <Range>selfId.GetDocumentRange()</Range> <QuickFix>UseWildSelfIdFix</QuickFix> </Warning> @@ -301,15 +300,17 @@ <Parameter type="ILiteralExpr" name="formatStringExpr"/> <Parameter type="IPrefixAppExpr" name="prefixAppExpr"/> <Parameter type="IFSharpExpression" name="outerPrefixAppExpr"/> - <Parameter type="(DocumentRange * IFSharpExpression) list" name="formatSpecsAndExprs" isValid="skip"/> + <Parameter type="string[]" name="formatSpecs" isCollection="true"/> + <Parameter type="int[]" name="specOffsets" isCollection="true"/> + <Parameter type="IFSharpExpression[]" name="expressions" isCollection="true"/> <Range>formatStringExpr.GetHighlightingRange()</Range> - <Message resourceName="FormatStringCanBeReplacedWithAnInterpolatedStringMessage" resourceType="Strings"/> + <Message resourceName="FormatStringCanBeReplacedWithAnInterpolatedStringMessage"/> <QuickFix>ReplaceWithInterpolatedStringFix</QuickFix> </Warning> <Warning name="RedundantStringInterpolation" configurableSeverity="FSharpRedundantStringInterpolation"> <Parameter type="IInterpolatedStringExpr" name="expr"/> - <Message resourceName="RedundantStringInterpolationMessage" resourceType="Strings"/> + <Message resourceName="RedundantStringInterpolationMessage"/> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> <Range>expr.GetDollarSignRange()</Range> <QuickFix>ReplaceWithRegularStringFix</QuickFix> @@ -318,19 +319,14 @@ <Warning name="ExpressionCanBeReplacedWithCondition" configurableSeverity="FSharpExpressionCanBeReplacedWithCondition"> <Parameter type="IIfThenElseExpr" name="expr"/> <Parameter type="bool" name="needsNegation"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument> - if needsNegation then "Expression can be replaced with condition negation" - else "Expression can be replaced with condition" - </Argument> - </Message> + <Message>if needsNegation then "Expression can be replaced with condition negation" else "Expression can be replaced with condition"</Message> <Range>expr.GetDocumentRange()</Range> <QuickFix>ReplaceWithConditionFix</QuickFix> </Warning> <Warning name="RedundantAsPattern" configurableSeverity="FSharpRedundantAsPattern"> <Parameter type="IAsPat" name="asPat"/> - <Message resourceName="RedundantAsPatternMessage" resourceType="Strings"/> + <Message resourceName="RedundantAsPatternMessage"/> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> <Range>getAsPatternRange asPat</Range> <QuickFix>RemoveRedundantAsPatFix</QuickFix> @@ -338,17 +334,17 @@ <Warning name="RedundantIndexerDot" configurableSeverity="FSharpRedundantDotInIndexer"> <Parameter type="IItemIndexerExpr" name="indexerExpr"/> - <Message resourceName="RedundantMessage" resourceType="Strings"/> + <Message resourceName="RedundantMessage"/> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> <Range>getIndexerDotRange indexerExpr</Range> <QuickFix>RemoveIndexerDotFix</QuickFix> </Warning> - <Warning name="NestedRecordUpdateCanBeSimplified" configurableSeverity="NestedRecordUpdateCanBeSimplified"> + <Warning name="NestedRecordUpdateCanBeSimplified" configurableSeverity="NestedRecordUpdateCanBeSimplified" forkTranslation="false"> <Parameter type="IRecordFieldBinding" name="outerBinding"/> <Parameter type="IRecordFieldBinding" name="innerBinding"/> - <Parameter type="string list" name="fieldQualifiedName" isValid="skip"/> - <Message resourceName="NestedRecordUpdateCanBeSimplifiedMessage" resourceType="Strings"/> + <Parameter type="string[]" name="fieldQualifiedName" isValid="skip" isCollection="true"/> + <Message resourceName="NestedRecordUpdateCanBeSimplifiedMessage"/> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> <Range>getNestedRecordUpdateRange outerBinding innerBinding</Range> <QuickFix>UseNestedRecordFieldSyntaxFix</QuickFix> diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Daemon/Highlightings/FcsErrors.xml b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Daemon/Highlightings/FcsErrors.xml index d9e1c3fc03..acb2dc38ad 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Daemon/Highlightings/FcsErrors.xml +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Daemon/Highlightings/FcsErrors.xml @@ -1,5 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> -<Errors language="F#" implementationLanguage="FSHARP"> +<Errors language="F#" + implementationLanguage="F#" + defaultResourceType="Strings" + defaultOverlapResolvePolicy="NONE" + forkTranslationForAllHighlightings="true"> <Usings> FSharp.Compiler.Symbols; JetBrains.ReSharper.Intentions.QuickFixes; @@ -22,11 +26,8 @@ <Parameter type="FcsCachedDiagnosticInfo" name="diagnosticInfo" isValid="skip"/> <Parameter type="IFSharpTypeOwnerNode" name="node"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>node.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ConvertTupleToArrayOrListElementsFix</QuickFix> <QuickFix>ReplaceReturnTypeFix</QuickFix> <QuickFix>ChangeParameterTypeFromArgumentFix</QuickFix> @@ -39,11 +40,8 @@ <Error staticGroup="FSharpErrors" name="UnitTypeExpected" ID="FS0001: 'unit' type expected"> <Parameter type="IFSharpTypeOwnerNode" name="node"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>node.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ReplaceWithAssignmentExpressionFix</QuickFix> <QuickFix>AddIgnoreFix</QuickFix> <QuickFix>IntroduceVarFix</QuickFix> @@ -53,79 +51,57 @@ <Parameter type="FcsCachedDiagnosticInfo" name="diagnosticInfo" isValid="skip"/> <Parameter type="IFSharpExpression" name="expr"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>expr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ReplaceReturnTypeFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="NotAFunction" ID="FS0003: Value is not a function"> <Parameter type="IFSharpExpression" name="expr"/> <Parameter type="IPrefixAppExpr" name="prefixApp"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>if prefixApp.FunctionExpression == expr then "Unexpected argument" else "Unexpected arguments" - </Argument> - </Message> + <Message>if prefixApp.FunctionExpression == expr then "Unexpected argument" else "Unexpected arguments"</Message> <Range>PrefixAppExprNavigator.GetByFunctionExpression(expr).ArgumentExpression.GetHighlightingRange()</Range> <SecondaryRanges>getPrefixAppExprArgs expr |> Seq.tail |> getNodeRanges</SecondaryRanges> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>AddParensToApplicationFix</QuickFix> <QuickFix>RemoveUnexpectedArgumentsFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="FieldNotMutable" ID="FS0005: Field is not mutable"> <Parameter type="IReferenceExpr" name="refExpr"/> - <Message resourceName="IsNotMutableMessage" resourceType="Strings"> - <Argument>refExpr.Identifier.GetSourceName()</Argument> - </Message> + <Message resourceName="IsNotMutableMessage">refExpr.Identifier.GetSourceName()</Message> <Range>getRefExprNameRange refExpr</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ToMutableFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="IndeterminateTypeRuntimeCoercionPattern" ID="FS0008: Runtime coercion or type test involves an indeterminate type"> <Parameter type="IIsInstPat" name="isInstPat"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>isInstPat.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>SpecifyParameterBaseTypeFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="IndeterminateTypeRuntimeCoercionExpression" ID="FS0008: Runtime coercion or type test involves an indeterminate type"> <Parameter type="ITypeTestExpr" name="typeTestExpr"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>typeTestExpr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>SpecifyParameterBaseTypeFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="RuntimeCoercionSourceSealed" ID="FS0016: Can't coerce sealed type"> <Parameter type="ITypedLikeExpr" name="expr"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>expr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>AddParensToTypedLikeExprFix</QuickFix> </Error> <Warning compilerGroup="FSharpErrors" name="UnitTypeExpected" ID="FS0020: 'unit' type expected"> <Parameter type="IFSharpTypeOwnerNode" name="node"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>node.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>IntroduceVarFix</QuickFix> <QuickFix>AddIgnoreFix</QuickFix> <QuickFix>RemoveSubsequentFix</QuickFix> @@ -135,11 +111,8 @@ <Warning compilerGroup="FSharpErrors" name="MatchIncomplete" ID="FS0025: Match incomplete"> <Parameter type="IMatchLikeExpr" name="expr"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>getMatchLikeExprIncompleteRange expr</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>AddMissingPatternsFix</QuickFix> <QuickFix>AddMissingInnerPatternsFix</QuickFix> <QuickFix>AddMatchAllClauseFix</QuickFix> @@ -147,7 +120,7 @@ <Warning compilerGroup="FSharpErrors" name="RuleNeverMatched" ID="FS0026: Rule never matched"> <Parameter type="IMatchClause" name="matchClause"/> - <Message resourceName="ThisRuleWillNeverBeMatchedMessage" resourceType="Strings"/> + <Message resourceName="ThisRuleWillNeverBeMatchedMessage"/> <Range>matchClause.GetHighlightingRange()</Range> <Behavour attributeID="DEADCODE" overlapResolvePolicy="NONE"/> <QuickFix>RemoveNeverMatchingRuleFix</QuickFix> @@ -155,11 +128,8 @@ <Error staticGroup="FSharpErrors" name="ValueNotMutable" ID="FS0027: Value is not mutable"> <Parameter type="IReferenceExpr" name="refExpr"/> - <Message resourceName="IsNotMutableMessage" resourceType="Strings"> - <Argument>refExpr.Identifier.GetSourceName()</Argument> - </Message> + <Message resourceName="IsNotMutableMessage">refExpr.Identifier.GetSourceName()</Message> <Range>getRefExprNameRange refExpr</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ToMutableFix</QuickFix> </Error> @@ -167,20 +137,14 @@ <Parameter type="ITopReferencePat" name="pat"/> <Parameter type="string" name="fcsMessage"/> <Range>pat.GetNavigationRange()</Range> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> - <Behavour overlapResolvePolicy="NONE"/> + <Message>fcsMessage</Message> <QuickFix>UpdateMutabilityInSignatureFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="VarBoundTwice" ID="FS0038: Pattern bound twice"> <Parameter type="IReferencePat" name="pat"/> - <Message resourceName="IsBoundMultipleTimesMessage" resourceType="Strings"> - <Argument>pat.SourceName</Argument> - </Message> + <Message resourceName="IsBoundMultipleTimesMessage">pat.SourceName</Message> <Range>pat.GetNavigationRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ReplaceWithWildPatFix</QuickFix> </Error> @@ -188,9 +152,7 @@ <Parameter type="FSharpSymbolReference" name="reference"/> <!-- todo: change to IReference? --> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <!--todo: identifier null check--> <Range>reference.GetElement().NameIdentifier.GetHighlightingRange()</Range> <Behavour attributeID="UNRESOLVED_ERROR" overlapResolvePolicy="NONE"/> @@ -205,31 +167,22 @@ <Error staticGroup="FSharpErrors" name="UndefinedIndexer" ID="FS0039: Undefined indexer"> <Parameter type="IItemIndexerExpr" name="indexerExpr"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>indexerExpr.IndexerArgList.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> </Error> <Error staticGroup="FSharpErrors" name="UndefinedIndexerLikeExpr" ID="FS0039: Undefined indexer"> <Parameter type="IPrefixAppExpr" name="prefixAppExpr"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>prefixAppExpr.ArgumentExpression.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> </Error> <Error staticGroup="FSharpErrors" name="AddingConstraint" ID="FS0043: Error from adding type constraint"> <Parameter type="IFSharpExpression" name="expr"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>expr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ReplaceWithPredefinedOperatorFix</QuickFix> </Error> @@ -237,12 +190,9 @@ <Parameter type="FSharpSymbolReference" name="reference"/> <!-- todo: change to IReference? --> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <!--todo: identifier null check--> <Range>reference.GetElement().NameIdentifier.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix arguments="h.Reference">FSharpImportModuleMemberFix</QuickFix> </Warning> @@ -250,26 +200,22 @@ <Parameter type="IUpcastExpr" name="upcastExpr"/> <Behavour attributeID="DEADCODE" overlapResolvePolicy="DEADCODE"/> <Range>getUpcastRange upcastExpr</Range> - <Message resourceName="UpcastIsUnnecessaryMessage" resourceType="Strings"/> + <Message resourceName="UpcastIsUnnecessaryMessage"/> <QuickFix>RemoveUnnecessaryUpcastFix</QuickFix> </Warning> <Warning compilerGroup="FSharpErrors" name="TypeTestUnnecessary" ID="FS0067: Type test is unnecessary"> <Parameter type="IDowncastExpr" name="expr"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>expr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ToUpcastFix</QuickFix> </Warning> <Error staticGroup="FSharpErrors" name="IndeterminateType" ID="FS0072: Lookup on indeterminate type object"> <Parameter type="IReferenceExpr" name="refExpr"/> - <Message resourceName="LookupOnObjectOfIndeterminateTypeBasedOnInformationPriorToThisProgramPointATypeAnnotationMayBeNeededConstrainTheTypeOfTheObjectMessage" resourceType="Strings"/> + <Message resourceName="LookupOnObjectOfIndeterminateTypeBasedOnInformationPriorToThisProgramPointATypeAnnotationMayBeNeededConstrainTheTypeOfTheObjectMessage"/> <Range>refExpr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>SpecifyParameterTypeFix</QuickFix> <QuickFix>SpecifyPropertyTypeFix</QuickFix> </Error> @@ -277,22 +223,16 @@ <Warning compilerGroup="FSharpErrors" name="EnumMatchIncomplete" ID="FS0104: Match incomplete for enum"> <Parameter type="IMatchLikeExpr" name="expr"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>getMatchLikeExprIncompleteRange expr</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>AddMatchAllClauseFix</QuickFix> </Warning> <Warning compilerGroup="FSharpErrors" name="FunctionValueUnexpected" ID="FS0193: Function type expected"> <Parameter type="IFSharpTypeOwnerNode" name="node"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>node.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>IntroduceVarFix</QuickFix> <QuickFix>AddIgnoreFix</QuickFix> <QuickFix>RemoveSubsequentFix</QuickFix> @@ -302,11 +242,8 @@ <Parameter type="FcsCachedDiagnosticInfo" name="diagnosticInfo" isValid="skip"/> <Parameter type="IFSharpTypeOwnerNode" name="node"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>node.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>AddParensToTypedLikeExprFix</QuickFix> <QuickFix>ReplaceReturnTypeFix</QuickFix> <QuickFix>ChangeParameterTypeFromArgumentFix</QuickFix> @@ -319,79 +256,61 @@ <Error staticGroup="FSharpErrors" name="FieldNotContainedTypesDiffer" ID="FS0193: The module contains the field but its signature specifies The types differ"> <Parameter type="IRecordFieldDeclaration" name="recordFieldDeclaration"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>recordFieldDeclaration.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>UpdateRecordFieldTypeInSignatureFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="NamespaceCannotContainBindings" ID="FS0201: Namespaces can't contain values"> <Parameter type="IBindingLikeDeclaration" name="binding"/> - <Message resourceName="NamespacesCannotContainBindingsMessage" resourceType="Strings"/> + <Message resourceName="NamespacesCannotContainBindingsMessage"/> <Range>binding.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>NamespaceToModuleFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="NamespaceCannotContainExpressions" ID="FS0201: Namespaces can't contain values"> <Parameter type="IDoLikeStatement" name="expr"/> - <Message resourceName="NamespacesCannotContainExpressionsMessage" resourceType="Strings"/> + <Message resourceName="NamespacesCannotContainExpressionsMessage"/> <Range>expr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>NamespaceToModuleFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="ValueMustBeMutable" ID="FS0256: A value must be mutable in order to mutate the contents or take the address of a value type"> <Parameter type="IReferenceExpr" name="refExpr"/> - <Message resourceName="ValueMustBeMutableMessage" resourceType="Strings"/> + <Message resourceName="ValueMustBeMutableMessage"/> <Range>getQualifierExprOrThisRange refExpr</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ToMutableFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="DefinitionsInSigAndImplNotCompatibleFieldWasPresent" ID="FS0311: The type definitions for type in the signature and implementation are not compatible because the field was present in the implementation but not in the signature"> <Parameter type="IFSharpTypeDeclaration" name="typeDeclaration"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>typeDeclaration.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>UpdateRecordFieldsInSignatureFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="DefinitionsInSigAndImplNotCompatibleFieldOrderDiffer" ID="FS0312: The type definitions for type in the signature and implementation are not compatible because the order of the fields is different in the signature and implementation"> <Parameter type="IFSharpTypeDeclaration" name="typeDeclaration"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>typeDeclaration.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>UpdateRecordFieldsInSignatureFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="DefinitionsInSigAndImplNotCompatibleFieldRequiredButNotSpecified" ID="FS0313: The type definitions for type in the signature and implementation are not compatible because the field Field2 was required by the signature but was not specified by the implementation"> <Parameter type="IFSharpTypeDeclaration" name="typeDeclaration"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>typeDeclaration.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>UpdateRecordFieldsInSignatureFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="NoImplementationGivenInType" ID="FS0365: No implementation given"> <Parameter type="IFSharpTypeDeclaration" name="typeDecl"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>typeDecl.GetNameDocumentRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>GenerateMissingOverridesFix</QuickFix> <QuickFix>ToAbstractFix</QuickFix> </Error> @@ -399,22 +318,16 @@ <Error staticGroup="FSharpErrors" name="NoImplementationGivenInInterface" ID="FS0365: No implementation given"> <Parameter type="IInterfaceImplementation" name="impl"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>getInterfaceImplHeaderRange impl</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>GenerateInterfaceMembersFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="NoImplementationGivenInTypeWithSuggestion" ID="FS0366: No implementation given"> <Parameter type="IFSharpTypeElementDeclaration" name="typeDecl"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>typeDecl.GetNameDocumentRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>GenerateMissingOverridesFix</QuickFix> <QuickFix>ToAbstractFix</QuickFix> </Error> @@ -422,149 +335,122 @@ <Error staticGroup="FSharpErrors" name="NoImplementationGivenInInterfaceWithSuggestion" ID="FS0366: No implementation given"> <Parameter type="IInterfaceImplementation" name="impl"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>getInterfaceImplHeaderRange impl</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>GenerateInterfaceMembersFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="MemberIsNotAccessible" ID="FS0491: Member is inaccessible"> <Parameter type="IReferenceExpr" name="refExpr"/> - <Message resourceName="ProtectedMembersCannotBeAccessedFromClosuresMessage" resourceType="Strings"/> + <Message resourceName="ProtectedMembersCannotBeAccessedFromClosuresMessage"/> <Range>refExpr.Identifier.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>IntroduceVarFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="FieldIsStatic" ID="FS0493: Static field used on instance"> <Parameter type="IReferenceExpr" name="refExpr"/> - <Message resourceName="IsStaticMessage" resourceType="Strings"> - <Argument>refExpr.ShortName</Argument> - </Message> + <Message resourceName="IsStaticMessage">refExpr.ShortName</Message> <Range>refExpr.Identifier.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ReplaceWithTypeRefExprFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="MethodIsStatic" ID="FS0493: Static method used on instance"> <Parameter type="IReferenceExpr" name="refExpr"/> - <Message resourceName="IsStaticMessage" resourceType="Strings"> - <Argument>refExpr.ShortName</Argument> - </Message> + <Message resourceName="IsStaticMessage">refExpr.ShortName</Message> <Range>refExpr.Identifier.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ReplaceWithTypeRefExprFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="UseKeywordIllegalInPrimaryCtor" ID="FS0523: 'use' bindings illegal in implicit constructors"> <Parameter type="ILetBindingsDeclaration" name="letBindings"/> - <Message resourceName="UseBindingsAreNotPermittedInPrimaryConstructorsMessage" resourceType="Strings"/> + <Message resourceName="UseBindingsAreNotPermittedInPrimaryConstructorsMessage"/> <Range>letBindings.BindingKeyword.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ReplaceUseWithLetFix</QuickFix> </Error> <Warning compilerGroup="FSharpErrors" name="UseBindingsIllegalInModules" ID="FS0524: 'use' bindings illegal in modules"> <Parameter type="ILetBindingsDeclaration" name="letBindings"/> - <Message resourceName="UseBindingsAreTreatedAsLetBindingsInModulesMessage" resourceType="Strings"/> + <Message resourceName="UseBindingsAreTreatedAsLetBindingsInModulesMessage"/> <Range>letBindings.BindingKeyword.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ReplaceUseWithLetFix</QuickFix> </Warning> <Error staticGroup="FSharpErrors" name="OnlyClassCanTakeValueArguments" ID="FS0552: Only class and struct types may have constructors"> <Parameter type="IPrimaryConstructorDeclaration" name="ctorDecl"/> - <Message resourceName="OnlyClassAndStructTypesMayHaveConstructorsMessage" resourceType="Strings"/> + <Message resourceName="OnlyClassAndStructTypesMayHaveConstructorsMessage"/> <Range>ctorDecl.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>RemoveConstructorFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="LetAndForNonRecBindings" ID="FS0576: 'and' is used in non-recursive bindings"> <Parameter type="ILetBindings" name="letBindings"/> <Range>getSecondBindingKeyword letBindings</Range> - <Behavour overlapResolvePolicy="NONE"/> - <Message resourceName="TheDeclarationFormLetAndIsOnlyAllowedForRecursiveBindingsConsiderUsingASequenceOfLetBindingsMessage" resourceType="Strings"/> + <Message resourceName="TheDeclarationFormLetAndIsOnlyAllowedForRecursiveBindingsConsiderUsingASequenceOfLetBindingsMessage"/> <QuickFix>ToRecursiveLetBindingsFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="ExpectedExpressionAfterLet" ID="FS0588: Missing 'in' expression"> <Parameter type="ILetOrUseExpr" name="letExpr"/> <Range>letExpr.BindingKeyword.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> - <Message resourceName="IsMissingExpressionMessage" resourceType="Strings"> - <Argument>getLetTokenText letExpr.BindingKeyword</Argument> - </Message> + <Message resourceName="IsMissingExpressionMessage">getLetTokenText letExpr.BindingKeyword</Message> <QuickFix>ReplaceLetWithExpressionFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="SuccessiveArgsShouldBeSpacedOrTupled" ID="FS0597: Successive args should be separated with spaces or have parens"> <Parameter type="IFSharpExpression" name="expr"/> <Range>expr.GetHighlightingRange()</Range> - <Message resourceName="SuccessiveArgumentsShouldBeSeparatedBySpacesTupledOrParenthesizedMessage" resourceType="Strings"/> - <Behavour overlapResolvePolicy="NONE"/> + <Message resourceName="SuccessiveArgumentsShouldBeSeparatedBySpacesTupledOrParenthesizedMessage"/> <QuickFix>AddParensFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="InstanceMemberRequiresTarget" ID="FS0673: Missing 'this' identifier"> <Parameter type="IMemberDeclaration" name="memberDecl"/> - <Message resourceName="InstanceMemberRequiresAParameterToRepresentTheObjectMessage" resourceType="Strings"/> + <Message resourceName="InstanceMemberRequiresAParameterToRepresentTheObjectMessage"/> <Range>memberDecl.Identifier.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>AddInstanceMemberSelfIdFix</QuickFix> <QuickFix>ToStaticMemberFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="UnionCaseDoesNotTakeArguments" ID="FS0725: This union case does not take arguments"> <Parameter type="IParametersOwnerPat" name="pattern"/> - <Message resourceName="ThisUnionCaseDoesNotTakeArgumentsMessage" resourceType="Strings"/> + <Message resourceName="ThisUnionCaseDoesNotTakeArgumentsMessage"/> <Range>pattern.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>RemovePatternArgumentFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="UnionCaseExpectsTupledArguments" ID="FS0727: Union case expects tupled arguments"> <Parameter type="IParametersOwnerPat" name="pat"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>getParameterOwnerPatParametersRange pat</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>DeconstructPatternFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="InvalidRecordSequenceOrComputationExpression" ID="FS740: Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq { ... }'"> <Parameter type="IComputationExpr" name="computationExpr"/> - <Message resourceName="InvalidRecordSequenceOrComputationExpressionMessage" resourceType="Strings"/> + <Message resourceName="InvalidRecordSequenceOrComputationExpressionMessage"/> <Range>computationExpr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>AddMissingSeqFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="YieldRequiresSeqExpression" ID="FS0747: 'yield' is not allowed"> <Parameter type="IYieldOrReturnExpr" name="yieldExpr"/> - <Message resourceName="YieldMayOnlyBeUsedWithinListArrayAndSequenceExpressionsMessage" resourceType="Strings"/> + <Message resourceName="YieldMayOnlyBeUsedWithinListArrayAndSequenceExpressionsMessage"/> <Range>yieldExpr.YieldKeyword.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>RemoveYieldFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="ReturnRequiresComputationExpression" ID="FS0748: 'return' is not allowed"> <Parameter type="IYieldOrReturnExpr" name="yieldExpr"/> - <Message resourceName="ReturnMayOnlyBeUsedWithinComputationExpressionsMessage" resourceType="Strings"/> + <Message resourceName="ReturnMayOnlyBeUsedWithinComputationExpressionsMessage"/> <Range>yieldExpr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>RemoveYieldFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="IndexerIndeterminateType" ID="FS0752: Use of indexer on indeterminate type object"> <Parameter type="IItemIndexerExpr" name="indexerExpr"/> - <Message resourceName="TheOperatorExprIdxHasBeenUsedOnAnObjectOfIndeterminateTypeBasedOnInformationPriorToThisProgramPointMessage" resourceType="Strings"/> + <Message resourceName="TheOperatorExprIdxHasBeenUsedOnAnObjectOfIndeterminateTypeBasedOnInformationPriorToThisProgramPointMessage"/> <Range>indexerExpr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>SpecifyParameterTypeFix</QuickFix> <QuickFix>SpecifyPropertyTypeFix</QuickFix> </Error> @@ -572,33 +458,24 @@ <Error staticGroup="FSharpErrors" name="AbstractTypeCannotBeInstantiated" ID="FS0759: Abstract type cannot be instantiated"> <Parameter type="IFSharpExpression" name="expr"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>expr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ToObjectExpressionFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="FieldRequiresAssignment" ID="FS0764: Field requires assignment"> <Parameter type="IRecordExpr" name="expr"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>expr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>GenerateMissingRecordFieldsFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="EmptyRecordInvalid" ID="FS0789: '{}' is not a valid expression"> <Parameter type="IRecordExpr" name="expr"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>expr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>GenerateMissingRecordFieldsFix</QuickFix> </Error> @@ -606,67 +483,51 @@ <Parameter type="FSharpSymbolReference" name="reference"/> <!-- todo: change to IReference? --> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <!--todo: identifier null check--> <Range>reference.GetElement().NameIdentifier.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix arguments="h.Reference">FSharpImportTypeFix</QuickFix> <QuickFix arguments="h.Reference">FSharpReferenceModuleAndTypeFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="PropertyIsStatic" ID="FS0809: Static propery used on instance"> <Parameter type="IReferenceExpr" name="refExpr"/> - <Message resourceName="IsStaticMessage" resourceType="Strings"> - <Argument>refExpr.ShortName</Argument> - </Message> + <Message resourceName="IsStaticMessage">refExpr.ShortName</Message> <Range>refExpr.Identifier.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ReplaceWithTypeRefExprFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="PropertyCannotBeSet" ID="FS0810: Property cannot be set"> <Parameter type="IReferenceExpr" name="refExpr"/> - <Message resourceName="PropertyCannotBeSetMessage" resourceType="Strings"> - <Argument>refExpr.ShortName</Argument> - </Message> + <Message resourceName="PropertyCannotBeSetMessage">refExpr.ShortName</Message> <Range>refExpr.Identifier.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>AddSetterFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="AttributeIsNotValidOnThisElement" ID="FS0842: This attribute is not valid for use on this language element"> <Parameter type="IAttribute" name="attribute"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>attribute.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>RemoveRedundantAttributeFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="LocalClassBindingsCannotBeInline" ID="FS0894: Class bindings can't be inline"> <Parameter type="ITopBinding" name="binding"/> <Range>binding.InlineKeyword.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> - <Message resourceName="ClassLocalBindingsCannotBeInlineMessage" resourceType="Strings"/> + <Message resourceName="ClassLocalBindingsCannotBeInlineMessage"/> <QuickFix>RemoveInlineFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="TypeAbbreviationsCannotHaveAugmentations" ID="FS0964: Type abbreviations cannot have augmentations"> <Parameter type="ITypeExtensionDeclaration" name="extensionDecl"/> - <Message resourceName="TypeAbbreviationsCannotHaveAugmentationsMessage" resourceType="Strings"/> + <Message resourceName="TypeAbbreviationsCannotHaveAugmentationsMessage"/> <Range>extensionDecl.Identifier.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ReplaceWithAbbreviatedTypeFix</QuickFix> </Error> <Warning compilerGroup="FSharpErrors" name="UnusedValue" ID="FS1182: Unused value"> <Parameter type="IReferencePat" name="pat"/> - <Message resourceName="TheValueIsUnusedMessage" resourceType="Strings"> - <Argument>pat.SourceName</Argument> - </Message> + <Message resourceName="TheValueIsUnusedMessage">pat.SourceName</Message> <Range>pat.GetNavigationRange()</Range> <SecondaryRanges>pat.GetPartialDeclarations() |> Seq.filter ((!=) pat) |> getNodeRanges</SecondaryRanges> <Behavour attributeID="DEADCODE" overlapResolvePolicy="NONE"/> @@ -678,7 +539,7 @@ <Warning compilerGroup="FSharpErrors" name="UnusedThisVariable" ID="FS1183: Unused 'this' value"> <Parameter type="ICtorSelfId" name="selfId"/> - <Message resourceName="TheSelfReferenceIsUnusedAndAddsRuntimeInitializationChecksToMembersInThisAndDerivedTypesMessage" resourceType="Strings"/> + <Message resourceName="TheSelfReferenceIsUnusedAndAddsRuntimeInitializationChecksToMembersInThisAndDerivedTypesMessage"/> <Range>selfId.Identifier.GetHighlightingRange()</Range> <Behavour attributeID="DEADCODE" overlapResolvePolicy="NONE"/> <QuickFix>RemoveUnusedSelfIdVariableFix</QuickFix> @@ -686,9 +547,8 @@ <Error staticGroup="FSharpErrors" name="LiteralPatternDoesNotTakeArguments" ID="FS3191: This literal pattern does not take arguments"> <Parameter type="IParametersOwnerPat" name="pattern"/> - <Message resourceName="ThisLiteralPatternDoesNotTakeArgumentsMessage" resourceType="Strings"/> + <Message resourceName="ThisLiteralPatternDoesNotTakeArgumentsMessage"/> <Range>pattern.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>RemovePatternArgumentFix</QuickFix> </Error> @@ -697,47 +557,37 @@ <Parameter type="string" name="signatureParameterName"/> <Parameter type="string" name="implementationParameterName"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>pattern.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>UpdateParameterNameInSignatureFix</QuickFix> </Warning> <Error staticGroup="FSharpErrors" name="CantTakeAddressOfExpression" ID="FS3236: Can't take address of expression"> <Parameter type="IAddressOfExpr" name="expr"/> - <Message resourceName="CanTTakeAddressOfExpressionMessage" resourceType="Strings"/> + <Message resourceName="CanTTakeAddressOfExpressionMessage"/> <Range>expr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>IntroduceVarFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="SingleQuoteInSingleQuote" ID="FS3373: Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal."> <Parameter type="IFSharpExpression" name="expr"/> <Parameter type="string" name="fcsMessage"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>fcsMessage</Argument> - </Message> + <Message>fcsMessage</Message> <Range>expr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ReplaceWithTripleQuotedInterpolatedStringFix</QuickFix> </Error> <Error staticGroup="FSharpErrors" name="ConstructDeprecatedSequenceExpressionsInvalidForm" ID="FS3873: This construct is deprecated. Sequence expressions should be of the form 'seq {{ ... }}'"> <Parameter type="IComputationExpr" name="computationExpr"/> - <Message resourceName="ConstructDeprecatedSequenceExpressionInvalidFormMessage" resourceType="Strings"/> + <Message resourceName="ConstructDeprecatedSequenceExpressionInvalidFormMessage"/> <Range>computationExpr.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>AddMissingSeqFix</QuickFix> </Error> <Warning compilerGroup="FSharpErrors" name="XmlDocCommentSyntax" ID="FS3390: This XML comment is invalid"> <Parameter type="IHighlighting" name="baseHighlighting"/> <Parameter type="DocumentRange" name="documentRange"/> - <Message resourceName="Message" resourceType="Strings"> - <Argument>baseHighlighting.ToolTip</Argument> - </Message> + <Message resourceName="Message">baseHighlighting.ToolTip</Message> <Range>documentRange</Range> <IsValid>baseHighlighting.IsValid()</IsValid> <Behavour overlapResolvePolicy="WARNING"/> @@ -745,37 +595,32 @@ <Warning compilerGroup="FSharpErrors" name="XmlDocMissingParameter" ID="FS3390: This XML comment is incomplete: no documentation for parameter"> <Parameter type="ITreeNode" name="parameter"/> - <Message resourceName="NoDocumentationForParameterMessage" resourceType="Strings"/> + <Message resourceName="NoDocumentationForParameterMessage"/> <Range>parameter.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> </Warning> <Warning compilerGroup="FSharpErrors" name="XmlDocDuplicateParameter" ID="FS3390: This XML comment is invalid: multiple documentation entries for parameter"> <Parameter type="ITreeNode" name="paramEntry"/> - <Message resourceName="MultipleDocumentationEntriesForParameterMessage" resourceType="Strings"/> + <Message resourceName="MultipleDocumentationEntriesForParameterMessage"/> <Range>paramEntry.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> </Warning> <Warning compilerGroup="FSharpErrors" name="XmlDocUnresolvedParameter" ID="FS3390: This XML comment is invalid: unknown parameter"> <Parameter type="ITreeNode" name="paramEntry"/> - <Message resourceName="UnknownParameterNameMessage" resourceType="Strings"/> + <Message resourceName="UnknownParameterNameMessage"/> <Range>paramEntry.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> </Warning> <Warning compilerGroup="FSharpErrors" name="XmlDocMissingParameterName" ID="FS3390: This XML comment is invalid: missing 'name' attribute for parameter or parameter reference"> <Parameter type="ITreeNode" name="paramTag"/> - <Message resourceName="MissingNameAttributeForParameterOrParameterReferenceMessage" resourceType="Strings"/> + <Message resourceName="MissingNameAttributeForParameterOrParameterReferenceMessage"/> <Range>paramTag.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> </Warning> <Warning compilerGroup="FSharpErrors" name="InvalidXmlDocPosition" ID="FS3520: XML comment is not placed on a valid language element"> <Parameter type="DocComment" name="comment"/> - <Message resourceName="XMLCommentIsNotPlacedOnAValidLanguageElementMessage" resourceType="Strings"/> + <Message resourceName="XMLCommentIsNotPlacedOnAValidLanguageElementMessage"/> <Range>comment.GetHighlightingRange()</Range> - <Behavour overlapResolvePolicy="NONE"/> <QuickFix>ReplaceXmlDocWithLineCommentFix</QuickFix> <QuickFix>RemoveXmlDocFix</QuickFix> </Warning> diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Generate/GenerateOverrides.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Generate/GenerateOverrides.fs index f508566a6c..ccb5baf0ec 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Generate/GenerateOverrides.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Generate/GenerateOverrides.fs @@ -5,6 +5,8 @@ open System.Collections.Generic open FSharp.Compiler.CodeAnalysis open FSharp.Compiler.Symbols open JetBrains.Diagnostics +open JetBrains.ReSharper.Feature.Services.BulbActions +open JetBrains.ReSharper.Feature.Services.CodeCompletion.Settings open JetBrains.ReSharper.Feature.Services.Generate open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util @@ -12,7 +14,6 @@ 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.Services.Util -open JetBrains.ReSharper.Plugins.FSharp.Psi.Services.Util.FSharpCompletionUtil open JetBrains.ReSharper.Plugins.FSharp.Psi.Services.Util.ObjExprUtil open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree open JetBrains.ReSharper.Plugins.FSharp.Psi.Util @@ -27,7 +28,6 @@ open JetBrains.ReSharper.Psi.Impl open JetBrains.ReSharper.Psi.Modules open JetBrains.ReSharper.Psi.Tree open JetBrains.ReSharper.Psi.Util -open JetBrains.TextControl let getMembersNeedingTypeAnnotations (mfvInstances: FcsMfvInstance list) = let sameParamNumberMembersGroups = @@ -177,14 +177,14 @@ let noEmptyLineAnchors = let getThisOrPreviousMeaningfulSibling (node: ITreeNode) = if isNotNull node && node.IsFiltered() then node.GetPreviousMeaningfulSibling() else node -let getGeneratedSelectionTreeRange (addedMembers: IMemberDeclaration seq) = +let getGeneratedBodyToSelect (addedMembers: IMemberDeclaration seq) = match Seq.tryHead addedMembers with - | None -> TreeTextRange.InvalidRange + | None -> null | Some memberDecl -> match Seq.tryHead memberDecl.AccessorDeclarationsEnumerable with - | Some accessorDecl -> accessorDecl.Expression.GetTreeTextRange() - | _ -> memberDecl.Expression.GetTreeTextRange() + | Some accessorDecl -> accessorDecl.Expression + | _ -> memberDecl.Expression let private getObjectTypeReprAnchor (objectTypeRepr: IObjectModelTypeRepresentation) (psiView: IPsiView) = let node = psiView.GetSelectedTreeNode() @@ -505,17 +505,11 @@ let convertToObjectExpression (factory: IFSharpElementFactory) (psiModule: IPsiM objExpr -let selectObjExprMemberOrCallCompletion (objExpr: IObjExpr) (textControl: ITextControl) = +let selectObjExprMemberOrCallCompletion (objExpr: IObjExpr) : IBulbActionCommand = match objExpr.MemberDeclarationsEnumerable |> Seq.tryHead with - | Some decl -> - let memberDecl = decl.As<IMemberDeclaration>() - if isNull memberDecl then () else - - let expr = memberDecl.Expression - textControl.Caret.MoveTo(expr.GetDocumentEndOffset(), CaretVisualPlacement.DontScrollIfVisible) - textControl.Selection.SetRange(expr.GetDocumentRange()) - - | None -> - let rBraceOffset = objExpr.RightBrace.GetDocumentStartOffset() - textControl.Caret.MoveTo(rBraceOffset - 1, CaretVisualPlacement.DontScrollIfVisible) - textControl.RescheduleCompletion(objExpr.GetSolution()) + | Some(:? IMemberDeclaration as decl) -> + BulbActionCommands.SetSelection(decl.Expression) + + | _ -> + let offset = objExpr.RightBrace.GetDocumentStartOffset() - 1 + BulbActionCommands.ShowCodeCompletionPopup(offset, FSharpLanguage.Instance, AutopopupType.SoftAutopopup) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Generate/GenerateProvider.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Generate/GenerateProvider.fs index e03e334121..8eb639475e 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Generate/GenerateProvider.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Generate/GenerateProvider.fs @@ -233,8 +233,8 @@ type FSharpOverridingMembersBuilder() = |> GenerateOverrides.sanitizeMembers let addedMembers = GenerateOverrides.addMembers inputElements typeDecl anchor - let selectedRange = GenerateOverrides.getGeneratedSelectionTreeRange addedMembers - context.SetSelectedRange(selectedRange) + let expr = GenerateOverrides.getGeneratedBodyToSelect addedMembers + context.SetSelectedRange(expr.GetTreeTextRange()) [<Language(typeof<FSharpLanguage>)>] diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FSharpTypeUsageUtil.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FSharpTypeUsageUtil.fs index a5aa400020..56e24da540 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FSharpTypeUsageUtil.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FSharpTypeUsageUtil.fs @@ -44,8 +44,7 @@ let setFcsParametersOwnerReturnTypeNoBind (decl: IFSharpTypeOwnerDeclaration) (m setParametersOwnerReturnTypeNoBind decl fcsReturnType -let setFcsParametersOwnerReturnType (decl: IFSharpTypeOwnerDeclaration) = - let mfv = decl.GetFcsSymbolUse().Symbol.As<FSharpMemberOrFunctionOrValue>() +let setFcsParametersOwnerReturnType (mfv: FSharpMemberOrFunctionOrValue) (decl: IFSharpTypeOwnerDeclaration) = let fcsReturnType, returnTypeUsage = setFcsParametersOwnerReturnTypeNoBind decl mfv TypeAnnotationUtil.bindAnnotations [ fcsReturnType, returnTypeUsage ] diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Resolve/FcsCachedDiagnosticInfo.cs b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Resolve/FcsCachedDiagnosticInfo.cs index 286cd1672a..7d939be788 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Resolve/FcsCachedDiagnosticInfo.cs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Resolve/FcsCachedDiagnosticInfo.cs @@ -3,10 +3,12 @@ using FSharp.Compiler.Text; using JetBrains.Diagnostics; using JetBrains.ReSharper.Plugins.FSharp.Psi.Tree; +using JetBrains.ReSharper.Psi.ContentModel; namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Resolve; public class FcsCachedDiagnosticInfo(FSharpDiagnostic diagnostic, IFSharpFile fsFile, Position pos) + : ISupportsContentModelForkTranslation { private WeakReference<FSharpDiagnostic> myReference = new(diagnostic); @@ -25,4 +27,12 @@ public FSharpDiagnostic GetDiagnostic() public static bool CanBeCached(FSharpDiagnostic diagnostic) => diagnostic.ErrorNumber is 1 or 193; + + object ISupportsContentModelForkTranslation.TryTranslateToCurrentFork(IContentModelForkTranslator translator) + { + if (translator.TryTranslateAnythingToCurrentFork(fsFile) is IFSharpFile fsFileInFork) + return new FcsCachedDiagnosticInfo(diagnostic, fsFileInFork, pos); + + return null; + } } diff --git a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/AddParensToApplicationTest.fs b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/AddParensToApplicationTest.fs index c75a1bcf31..e60e85b01a 100644 --- a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/AddParensToApplicationTest.fs +++ b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/QuickFixes/AddParensToApplicationTest.fs @@ -1,10 +1,7 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Tests.Intentions.QuickFixes -open JetBrains.ProjectModel open JetBrains.ReSharper.FeaturesTestFramework.Intentions -open JetBrains.ReSharper.FeaturesTestFramework.Refactorings open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes -open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.QuickFixes.AddParensToApplicationFix open JetBrains.ReSharper.Plugins.FSharp.Tests open NUnit.Framework @@ -12,9 +9,6 @@ open NUnit.Framework type AddParensToApplicationTest() = inherit FSharpQuickFixTestBase<AddParensToApplicationFix>() - let [<Literal>] AppOccurrenceName = "APP_OCCURRENCE" - let [<Literal>] ArgsOccurrenceName = "ARGS_OCCURRENCE" - override x.RelativeTestDataPath = "features/quickFixes/addParensToApplication" [<Test>] member x.``Single application``() = x.DoNamedTest() @@ -31,24 +25,6 @@ type AddParensToApplicationTest() = [<Test>] member x.``Type constructor 02 - Exception``() = x.DoNamedTest() [<Test>] member x.``Type constructor 03 - With lambda application``() = x.DoNamedTest() - override x.DoTestOnTextControlAndExecuteWithGold(project, textControl, projectFile) = - let appOccurrenceName = QuickFixTestBase.GetSetting(textControl, AppOccurrenceName) - let argsOccurrenceName = QuickFixTestBase.GetSetting(textControl, ArgsOccurrenceName) - - let workflowPopupMenu = x.Solution.GetComponent<TestWorkflowPopupMenu>() - workflowPopupMenu.SetTestData(x.TestLifetime, fun _ occurrences _ _ id -> - let occurrenceName = - match id with - | AppPopupName when isNotNull appOccurrenceName -> appOccurrenceName - | ArgsPopupName when isNotNull argsOccurrenceName -> argsOccurrenceName - | _ -> occurrences[0].Name.Text - - occurrences - |> Seq.tryFind (fun occurrence -> occurrence.Name.Text = occurrenceName) - |> Option.defaultWith (fun _ -> failwithf $"Could not find {occurrenceName} occurrence")) - - base.DoTestOnTextControlAndExecuteWithGold(project, textControl, projectFile) - [<FSharpTest>] type AddParensToApplicationAvailabilityTest() = From 408218ceceb30c524cd156d68d3bebd23367a29b Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok <eugene.auduchinok@jetbrains.com> Date: Thu, 14 May 2026 14:35:24 +0200 Subject: [PATCH 3/4] RIDER-138916 Reformat code: use ReSharper formatter for selection, allow using it on file GitOrigin-RevId: 7f21658c0bb21718a6cd5737d85dfeea04103f5d --- .../src/Settings/FSharpOptions.fs | 13 +- .../src/Util/FSharpExperimentalFeatures.fs | 2 - .../src/CodeCleanup/FSharpReformatCode.fs | 143 ++++++++++-------- .../service/codeCleanup/Expr - CompExpr 01.fs | 6 + .../codeCleanup/Expr - CompExpr 01.fs.gold | 6 + .../{Record 01.fs => Expr - Record 01.fs} | 0 .../codeCleanup/Expr - Record 01.fs.gold | 4 + .../service/codeCleanup/Expr - Record 02.fs | 8 + .../codeCleanup/Expr - Record 02.fs.gold | 8 + .../service/codeCleanup/Record 01.fs.jcnf | 1 - .../Service/FSharpCodeFormatterTest.fs | 4 +- 11 files changed, 120 insertions(+), 75 deletions(-) create mode 100644 ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - CompExpr 01.fs create mode 100644 ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - CompExpr 01.fs.gold rename ReSharper.FSharp/test/data/features/service/codeCleanup/{Record 01.fs => Expr - Record 01.fs} (100%) create mode 100644 ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 01.fs.gold create mode 100644 ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 02.fs create mode 100644 ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 02.fs.gold delete mode 100644 ReSharper.FSharp/test/data/features/service/codeCleanup/Record 01.fs.jcnf diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Common/src/Settings/FSharpOptions.fs b/ReSharper.FSharp/src/FSharp/FSharp.Common/src/Settings/FSharpOptions.fs index c87591f4de..bebe8c1cfe 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Common/src/Settings/FSharpOptions.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Common/src/Settings/FSharpOptions.fs @@ -84,11 +84,10 @@ type FSharpScriptOptions = module FSharpExperimentalFeatures = let [<Literal>] postfixTemplates = "Enable postfix templates" let [<Literal>] redundantParenAnalysis = "Enable redundant paren analysis" - let [<Literal>] formatter = "Enable F# code formatter" + let [<Literal>] formatter = "Prefer ReSharper code formatter" let [<Literal>] fsiInteractiveEditor = "Enable analysis of F# Interactive editor" let [<Literal>] outOfProcessTypeProviders = "Host type providers out-of-process" let [<Literal>] generativeTypeProvidersInMemoryAnalysis = "Enable generative type providers analysis in C#/VB.NET projects" - let [<Literal>] tryRecoverFcsProjects = "Try to reuse FCS results on project changes" [<SettingsKey(typeof<FSharpOptions>, "F# experimental features")>] @@ -109,10 +108,7 @@ type FSharpExperimentalFeatures = mutable OutOfProcessTypeProviders: bool [<SettingsEntry(true, FSharpExperimentalFeatures.generativeTypeProvidersInMemoryAnalysis); DefaultValue>] - mutable GenerativeTypeProvidersInMemoryAnalysis: bool - - [<SettingsEntry(false, FSharpExperimentalFeatures.tryRecoverFcsProjects); DefaultValue>] - mutable TryRecoverFcsProjects: bool } + mutable GenerativeTypeProvidersInMemoryAnalysis: bool } [<AllowNullLiteral>] @@ -148,7 +144,6 @@ type FSharpExperimentalFeaturesProvider(lifetime, solution: ISolution, settings, member val Formatter = base.GetValueProperty<bool>("Formatter") member val OutOfProcessTypeProviders = base.GetValueProperty<bool>("OutOfProcessTypeProviders") member val GenerativeTypeProvidersInMemoryAnalysis = base.GetValueProperty<bool>("GenerativeTypeProvidersInMemoryAnalysis") - member val TryRecoverFcsProjects = base.GetValueProperty<bool>("TryRecoverFcsProjects") [<SolutionInstanceComponent(Instantiation.DemandAnyThreadSafe)>] @@ -227,11 +222,11 @@ type FSharpOptionsPage(lifetime: Lifetime, optionsPageContext, settings, this.AddBoolOptionWithComment((fun key -> key.NonFSharpProjectInMemoryReferences), nonFSharpProjectInMemoryReferences, "Requires restart") |> ignore + this.AddHeader("Experimental features") + this.AddBoolOption((fun key -> key.Formatter), RichText(FSharpExperimentalFeatures.formatter), null) |> ignore if configurations.IsInternalMode() then - this.AddHeader("Experimental features") this.AddBoolOption((fun key -> key.PostfixTemplates), RichText(FSharpExperimentalFeatures.postfixTemplates), null) |> ignore this.AddBoolOption((fun key -> key.RedundantParensAnalysis), RichText(FSharpExperimentalFeatures.redundantParenAnalysis), null) |> ignore - this.AddBoolOption((fun key -> key.Formatter), RichText(FSharpExperimentalFeatures.formatter), null) |> ignore [<ShellComponent>] diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Common/src/Util/FSharpExperimentalFeatures.fs b/ReSharper.FSharp/src/FSharp/FSharp.Common/src/Util/FSharpExperimentalFeatures.fs index 82c233ab77..36cb4e6a81 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Common/src/Util/FSharpExperimentalFeatures.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Common/src/Util/FSharpExperimentalFeatures.fs @@ -12,7 +12,6 @@ type ExperimentalFeature = | PostfixTemplates = 2 | RedundantParenAnalysis = 3 | AssemblyReaderShim = 4 - | TryRecoverFcsProjects = 5 type FSharpExperimentalFeatureCookie(feature: ExperimentalFeature) = static let cookies = OneToListMap<ExperimentalFeature, IDisposable>() @@ -51,7 +50,6 @@ type FSharpExperimentalFeatures() = | ExperimentalFeature.Formatter -> experimentalFeatures.RedundantParensAnalysis.Value | ExperimentalFeature.PostfixTemplates -> experimentalFeatures.EnablePostfixTemplates.Value | ExperimentalFeature.RedundantParenAnalysis -> experimentalFeatures.RedundantParensAnalysis.Value - | ExperimentalFeature.TryRecoverFcsProjects -> experimentalFeatures.TryRecoverFcsProjects.Value | _ -> failwith $"Unexpected feature: {feature}" [<Extension>] diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/CodeCleanup/FSharpReformatCode.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/CodeCleanup/FSharpReformatCode.fs index 88cdd87103..c58c476c5d 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/CodeCleanup/FSharpReformatCode.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/CodeCleanup/FSharpReformatCode.fs @@ -2,6 +2,7 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Services.Formatter open JetBrains.Application.Infra open JetBrains.Application.Parts +open JetBrains.Application.Progress open JetBrains.Diagnostics open JetBrains.DocumentModel open JetBrains.DocumentModel.Impl @@ -10,6 +11,7 @@ open JetBrains.ProjectModel open JetBrains.ReSharper.Feature.Services.CodeCleanup open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Resources +open JetBrains.ReSharper.Plugins.FSharp.Settings open JetBrains.ReSharper.Plugins.FSharp.Util open JetBrains.ReSharper.Psi open JetBrains.ReSharper.Psi.CodeStyle @@ -25,10 +27,79 @@ type FSharpReformatCode(textControlManager: ITextControlManager) = "FSharpReformatCode", CodeCleanupLanguage("F#", 2), CodeCleanupOptionDescriptor.ReformatGroup, - typeof<Strings>) + typeof<Strings>, displayName = "F#") let language = FSharpLanguage.Instance + let reformatWithReSharper (sourceFile: IPsiSourceFile) (rangeMarker: IRangeMarker) (profile: CodeCleanupProfile) + (progressIndicator: IProgressIndicator) = + let solution = sourceFile.GetSolution() + let codeFormatProfile = profile.GetSetting(ReformatOptions.CODE_FORMATER_PROFILE_DESCRIPTOR) + let formatter = language.Formatter().NotNull() + + sourceFile.GetPsiServices().Transactions.Execute("F# Reformat code", fun () -> + if isNotNull rangeMarker then + CodeFormatterHelper.Format(language, solution, rangeMarker.DocumentRange, codeFormatProfile, true, + false, progressIndicator) + else + formatter.FormatFile(sourceFile.FSharpFile, codeFormatProfile, progressIndicator) + ) |> ignore + + let reformatWithFantomas (sourceFile: IPsiSourceFile) (rangeMarker: IRangeMarker) = + let fsFile = sourceFile.FSharpFile + if isNull fsFile then () else + + match fsFile.ParseTree with + | None -> () + | Some _ -> + + let filePath = sourceFile.GetLocation().FullPath + let document = sourceFile.Document :?> DocumentBase + let text = document.GetText() + + let solution = fsFile.GetSolution() + let settingsStore = sourceFile.GetSettingsStoreWithEditorConfig() + let formatter = fsFile.Language.LanguageServiceNotNull().CodeFormatter + let settings = formatter.GetFormatterSettings(solution, sourceFile, settingsStore, false) :?> _ + let fantomasHost = solution.GetComponent<FantomasHost>() + + let stamp = document.LastModificationStamp + let modificationSide = TextModificationSide.NotSpecified + let newLineText = sourceFile.DetectLineEnding().GetPresentation() + let parsingOptions = fsFile.CheckerService.FcsProjectProvider.GetParsingOptions(sourceFile) + + try + if isNotNull rangeMarker then + let range = ofDocumentRange rangeMarker.DocumentRange + let formatted = fantomasHost.FormatSelection(filePath, range, text, settings, parsingOptions, newLineText, settingsStore) + let offset = rangeMarker.DocumentRange.StartOffset.Offset + let oldLength = rangeMarker.DocumentRange.Length + let documentChange = DocumentChange(document, offset, oldLength, formatted, stamp, modificationSide) + use _ = WriteLockCookie.Create() + document.ChangeDocument(documentChange, TimeStamp.NextValue) + sourceFile.GetPsiServices().Files.CommitAllDocuments() + else + let textControl = textControlManager.VisibleTextControls + |> Seq.tryFind (fun c -> c.Document == document && c.Window.IsFocused.Value) + let cursorPosition = textControl |> Option.map (fun c -> c.Caret.Position.Value.ToDocLineColumn()) + let formatResult = fantomasHost.FormatDocument(filePath, text, settings, parsingOptions, newLineText, cursorPosition, settingsStore) + let newCursorPosition = formatResult.CursorPosition + + document.ReplaceText(document.DocumentRange, formatResult.Code) + sourceFile.GetPsiServices().Files.CommitAllDocuments() + + if isNull textControl || isNull newCursorPosition then () else + + // move cursor after current document transaction + let moveCursorLifetime = new LifetimeDefinition() + let codeCleanupService = solution.GetComponent<CodeCleanupService>() + codeCleanupService.WholeFileCleanupCompletedAfterSave.Advise(moveCursorLifetime.Lifetime, fun _ -> + moveCursorLifetime.Terminate() + textControl.Value.Caret.MoveTo(docLine newCursorPosition.Row, + docColumn newCursorPosition.Column, + CaretVisualPlacement.Generic)) + with _ -> () + interface IReformatCodeCleanupModule with member x.Name = Strings.FSharpReformatCode_Name_Reformat_FSharp member x.LanguageType = language @@ -50,64 +121,12 @@ type FSharpReformatCode(textControlManager: ITextControlManager) = profile.GetSetting(REFORMAT_CODE_DESCRIPTOR) member x.Process(sourceFile, rangeMarker, profile, progressIndicator, _) = - // let solution = sourceFile.GetSolution() - // let codeFormatProfile = profile.GetSetting(ReformatOptions.CODE_FORMATER_PROFILE_DESCRIPTOR) - // - // sourceFile.GetPsiServices().Transactions.Execute("F# Reformat code", fun () -> - // CodeFormatterHelper.Format(language, solution, rangeMarker.DocumentRange, codeFormatProfile, true, - // false, progressIndicator) - // ) |> ignore - - let fsFile = sourceFile.FSharpFile - if isNull fsFile then () else - - match fsFile.ParseTree with - | None -> () - | Some _ -> - - let filePath = sourceFile.GetLocation().FullPath - let document = sourceFile.Document :?> DocumentBase - let text = document.GetText() - - let solution = fsFile.GetSolution() - let settingsStore = sourceFile.GetSettingsStoreWithEditorConfig() - let formatter = fsFile.Language.LanguageServiceNotNull().CodeFormatter - let settings = formatter.GetFormatterSettings(solution, sourceFile, settingsStore, false) :?> _ - let fantomasHost = solution.GetComponent<FantomasHost>() - - let stamp = document.LastModificationStamp - let modificationSide = TextModificationSide.NotSpecified - let newLineText = sourceFile.DetectLineEnding().GetPresentation() - let parsingOptions = fsFile.CheckerService.FcsProjectProvider.GetParsingOptions(sourceFile) - - try - if isNotNull rangeMarker then - let range = ofDocumentRange rangeMarker.DocumentRange - let formatted = fantomasHost.FormatSelection(filePath, range, text, settings, parsingOptions, newLineText, settingsStore) - let offset = rangeMarker.DocumentRange.StartOffset.Offset - let oldLength = rangeMarker.DocumentRange.Length - let documentChange = DocumentChange(document, offset, oldLength, formatted, stamp, modificationSide) - use _ = WriteLockCookie.Create() - document.ChangeDocument(documentChange, TimeStamp.NextValue) - sourceFile.GetPsiServices().Files.CommitAllDocuments() - else - let textControl = textControlManager.VisibleTextControls - |> Seq.tryFind (fun c -> c.Document == document && c.Window.IsFocused.Value) - let cursorPosition = textControl |> Option.map (fun c -> c.Caret.Position.Value.ToDocLineColumn()) - let formatResult = fantomasHost.FormatDocument(filePath, text, settings, parsingOptions, newLineText, cursorPosition, settingsStore) - let newCursorPosition = formatResult.CursorPosition - - document.ReplaceText(document.DocumentRange, formatResult.Code) - sourceFile.GetPsiServices().Files.CommitAllDocuments() - - if isNull textControl || isNull newCursorPosition then () else - - // move cursor after current document transaction - let moveCursorLifetime = new LifetimeDefinition() - let codeCleanupService = solution.GetComponent<CodeCleanupService>() - codeCleanupService.WholeFileCleanupCompletedAfterSave.Advise(moveCursorLifetime.Lifetime, fun _ -> - moveCursorLifetime.Terminate() - textControl.Value.Caret.MoveTo(docLine newCursorPosition.Row, - docColumn newCursorPosition.Column, - CaretVisualPlacement.Generic)) - with _ -> () + let useReSharperFormatter () = + sourceFile + .GetSolution() + .GetSolutionInstanceComponent<FSharpExperimentalFeaturesProvider>().Formatter.Value + + if isNotNull rangeMarker || useReSharperFormatter () then + reformatWithReSharper sourceFile rangeMarker profile progressIndicator + else + reformatWithFantomas sourceFile rangeMarker diff --git a/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - CompExpr 01.fs b/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - CompExpr 01.fs new file mode 100644 index 0000000000..eef5f49d2a --- /dev/null +++ b/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - CompExpr 01.fs @@ -0,0 +1,6 @@ +module Module + +async { + let! i, s = async { return 1, "" } + {selstart}return 1{selend} +} diff --git a/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - CompExpr 01.fs.gold b/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - CompExpr 01.fs.gold new file mode 100644 index 0000000000..603b19873a --- /dev/null +++ b/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - CompExpr 01.fs.gold @@ -0,0 +1,6 @@ +module Module + +async { + let! i, s = async { return 1, "" } + return 1 +} diff --git a/ReSharper.FSharp/test/data/features/service/codeCleanup/Record 01.fs b/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 01.fs similarity index 100% rename from ReSharper.FSharp/test/data/features/service/codeCleanup/Record 01.fs rename to ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 01.fs diff --git a/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 01.fs.gold b/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 01.fs.gold new file mode 100644 index 0000000000..878532ce52 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 01.fs.gold @@ -0,0 +1,4 @@ +module Module + +let r = + { A = 1; B = 2 } diff --git a/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 02.fs b/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 02.fs new file mode 100644 index 0000000000..9ee7e08bf6 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 02.fs @@ -0,0 +1,8 @@ +module Module + +do + {selstart}{ F1 = 1 + F2 = 2 + F3 = 3 + F4 = 4 + F5 = 6 }{selend} \ No newline at end of file diff --git a/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 02.fs.gold b/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 02.fs.gold new file mode 100644 index 0000000000..06740a9046 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/service/codeCleanup/Expr - Record 02.fs.gold @@ -0,0 +1,8 @@ +module Module + +do + { F1 = 1 + F2 = 2 + F3 = 3 + F4 = 4 + F5 = 6 } \ No newline at end of file diff --git a/ReSharper.FSharp/test/data/features/service/codeCleanup/Record 01.fs.jcnf b/ReSharper.FSharp/test/data/features/service/codeCleanup/Record 01.fs.jcnf deleted file mode 100644 index 098892da92..0000000000 --- a/ReSharper.FSharp/test/data/features/service/codeCleanup/Record 01.fs.jcnf +++ /dev/null @@ -1 +0,0 @@ -{MakeLog: true} \ No newline at end of file diff --git a/ReSharper.FSharp/test/src/FSharp.Tests/Service/FSharpCodeFormatterTest.fs b/ReSharper.FSharp/test/src/FSharp.Tests/Service/FSharpCodeFormatterTest.fs index 1075397c83..a5afa9089f 100644 --- a/ReSharper.FSharp/test/src/FSharp.Tests/Service/FSharpCodeFormatterTest.fs +++ b/ReSharper.FSharp/test/src/FSharp.Tests/Service/FSharpCodeFormatterTest.fs @@ -206,4 +206,6 @@ type FSharpCodeCleanupTest() = override x.RelativeTestDataPath = "features/service/codeCleanup" - [<Test; Explicit>] member x.``Record 01``() = x.DoNamedTest() + [<Test>] member x.``Expr - CompExpr 01``() = x.DoNamedTest() + [<Test>] member x.``Expr - Record 01``() = x.DoNamedTest() + [<Test>] member x.``Expr - Record 02``() = x.DoNamedTest() From 9caf0a874f5208199ea86e2f568c4dde597fe4a4 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok <eugene.auduchinok@jetbrains.com> Date: Fri, 22 May 2026 16:26:24 +0200 Subject: [PATCH 4/4] RIDER-139200 Generate/overrides: fix missing byref passing in base calls GitOrigin-RevId: 01017ae4ceaa37dc7cdffeb53fc144ea8a76f6a8 --- .../src/Generate/GenerateOverrides.fs | 14 ++++++++++---- .../FSharp.Psi.Services/src/Util/FcsTypeUtil.fs | 4 ++++ .../generate/overrides/Parameter - Ref - Out 01.cs | 6 ++++++ .../generate/overrides/Parameter - Ref - Out 01.fs | 4 ++++ .../overrides/Parameter - Ref - Out 01.fs.gold | 13 +++++++++++++ .../Generate/FSharpGenerateOverridesTest.fs | 5 +++++ 6 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 ReSharper.FSharp/test/data/features/generate/overrides/Parameter - Ref - Out 01.cs create mode 100644 ReSharper.FSharp/test/data/features/generate/overrides/Parameter - Ref - Out 01.fs create mode 100644 ReSharper.FSharp/test/data/features/generate/overrides/Parameter - Ref - Out 01.fs.gold diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Generate/GenerateOverrides.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Generate/GenerateOverrides.fs index ccb5baf0ec..51e528d3e1 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Generate/GenerateOverrides.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Generate/GenerateOverrides.fs @@ -10,6 +10,7 @@ open JetBrains.ReSharper.Feature.Services.CodeCompletion.Settings open JetBrains.ReSharper.Feature.Services.Generate open JetBrains.ReSharper.Plugins.FSharp.Psi open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util +open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util.FcsTypeUtil open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl.Cache2 open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl.Tree open JetBrains.ReSharper.Plugins.FSharp.Psi.Parsing @@ -66,7 +67,8 @@ let generateMember (context: ITreeNode) (mayHaveBaseCalls: bool) (element: IFSha let getParamNameAndType defaultName (param: FSharpParameter) = let name = param.Name |> Option.defaultWith defaultName |> FSharpNamingService.mangleNameIfNecessary - name, getParamType param + let paramType = getParamType param + name, paramType let getValueParamNameAndType (param: FSharpParameter) = getParamNameAndType (fun _ -> "value") param @@ -131,6 +133,10 @@ let generateMember (context: ITreeNode) (mayHaveBaseCalls: bool) (element: IFSha (not (overridableMember :? IAccessor) || not generateParameters) if mayHaveBaseCalls && shouldCallBase element then + let paramNameTypeGroups = + paramNameTypeGroups + |> List.map (List.map (fun (name, fcsType) -> if isRef fcsType then $"&{name}" else name)) + let args = if paramNameTypeGroups.IsEmpty || not generateParameters then "" else @@ -139,10 +145,10 @@ let generateMember (context: ITreeNode) (mayHaveBaseCalls: bool) (element: IFSha paramNameTypeGroups |> List.mapi (fun i paramNames -> match paramNames, i with - | [head, _], 0 when groupCount > 1 -> $" {head}" - | [head, _], _ when groupCount > 1 -> head + | [head], 0 when groupCount > 1 -> $" {head}" + | [head], _ when groupCount > 1 -> head | _ -> - let names = paramNames |> List.map fst |> String.concat ", " + let names = paramNames |> String.concat ", " $"({names})" ) |> String.concat " " diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FcsTypeUtil.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FcsTypeUtil.fs index d77fb00447..65916617a8 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FcsTypeUtil.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FcsTypeUtil.fs @@ -58,3 +58,7 @@ let rec isFcsTypeAccessible (context: ITreeNode) (fcsType: FSharpType) = else true + +let isRef (fcsType: FSharpType) = + let fcsType = fcsType.ErasedType + fcsType.HasTypeDefinition && fcsType.TypeDefinition.IsByRef diff --git a/ReSharper.FSharp/test/data/features/generate/overrides/Parameter - Ref - Out 01.cs b/ReSharper.FSharp/test/data/features/generate/overrides/Parameter - Ref - Out 01.cs new file mode 100644 index 0000000000..505e1cdb85 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/generate/overrides/Parameter - Ref - Out 01.cs @@ -0,0 +1,6 @@ +public class Class +{ + public virtual void M(out string s) + { + } +} diff --git a/ReSharper.FSharp/test/data/features/generate/overrides/Parameter - Ref - Out 01.fs b/ReSharper.FSharp/test/data/features/generate/overrides/Parameter - Ref - Out 01.fs new file mode 100644 index 0000000000..f1e224f133 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/generate/overrides/Parameter - Ref - Out 01.fs @@ -0,0 +1,4 @@ +// ${KIND:Overrides} +// ${SELECT0:M(System.String):System.Void} +type T() = + inherit Class(){caret} diff --git a/ReSharper.FSharp/test/data/features/generate/overrides/Parameter - Ref - Out 01.fs.gold b/ReSharper.FSharp/test/data/features/generate/overrides/Parameter - Ref - Out 01.fs.gold new file mode 100644 index 0000000000..a50fc69f12 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/generate/overrides/Parameter - Ref - Out 01.fs.gold @@ -0,0 +1,13 @@ +Provided elements: + 0: M(System.String):System.Void + 1: Equals(System.Object?):System.Boolean + 2: Finalize():System.Void + 3: GetHashCode():System.Int32 + 4: ToString():System.String? + +// ${KIND:Overrides} +// ${SELECT0:M(System.String):System.Void} +type T() = + inherit Class() + + override this.M(s) = {selstart}base.M(&s){selend} diff --git a/ReSharper.FSharp/test/src/FSharp.Tests/Generate/FSharpGenerateOverridesTest.fs b/ReSharper.FSharp/test/src/FSharp.Tests/Generate/FSharpGenerateOverridesTest.fs index 5b9359346b..542298b628 100644 --- a/ReSharper.FSharp/test/src/FSharp.Tests/Generate/FSharpGenerateOverridesTest.fs +++ b/ReSharper.FSharp/test/src/FSharp.Tests/Generate/FSharpGenerateOverridesTest.fs @@ -10,6 +10,9 @@ type FSharpGenerateOverridesTest() = override x.RelativeTestDataPath = "features/generate/overrides" + member x.DoNamedTestFsCs() = + x.DoTestSolution(FSharpTestUtil.referenceCSharpProject x) + [<Test>] member x.``Anchor - Ctor - Primary 01``() = x.DoNamedTest() [<Test>] member x.``Anchor - Inherit 01``() = x.DoNamedTest() [<Test>] member x.``Anchor - Inherit 02``() = x.DoNamedTest() @@ -117,6 +120,8 @@ type FSharpGenerateOverridesTest() = [<Test>] member x.``Input elements - Overriden 01``() = x.DoNamedTest() + [<Test; Explicit "Fails on the buildserver">] member x.``Parameter - Ref - Out 01``() = x.DoNamedTestFsCs() + [<Test>] member x.``Repr - Empty - Class 01``() = x.DoNamedTest() [<Test>] member x.``Repr - Empty - Class 02 - Same line``() = x.DoNamedTest() [<Test>] member x.``Repr - Empty - Class 03 - Comment``() = x.DoNamedTest()