From e8c207fd84959f49a71ef6206d9f7421a659cc37 Mon Sep 17 00:00:00 2001 From: cartermp Date: Tue, 17 Nov 2020 11:57:08 -0800 Subject: [PATCH 1/2] Add UseMutationWhenValueIsMutable code fix --- .../CodeFix/UseMutationWhenValueIsMutable.fs | 72 +++++++++++++++++++ .../src/FSharp.Editor/FSharp.Editor.fsproj | 1 + .../src/FSharp.Editor/FSharp.Editor.resx | 3 + .../FSharp.Editor/xlf/FSharp.Editor.cs.xlf | 5 ++ .../FSharp.Editor/xlf/FSharp.Editor.de.xlf | 5 ++ .../FSharp.Editor/xlf/FSharp.Editor.es.xlf | 5 ++ .../FSharp.Editor/xlf/FSharp.Editor.fr.xlf | 5 ++ .../FSharp.Editor/xlf/FSharp.Editor.it.xlf | 5 ++ .../FSharp.Editor/xlf/FSharp.Editor.ja.xlf | 5 ++ .../FSharp.Editor/xlf/FSharp.Editor.ko.xlf | 5 ++ .../FSharp.Editor/xlf/FSharp.Editor.pl.xlf | 5 ++ .../FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf | 5 ++ .../FSharp.Editor/xlf/FSharp.Editor.ru.xlf | 5 ++ .../FSharp.Editor/xlf/FSharp.Editor.tr.xlf | 5 ++ .../xlf/FSharp.Editor.zh-Hans.xlf | 5 ++ .../xlf/FSharp.Editor.zh-Hant.xlf | 5 ++ 16 files changed, 141 insertions(+) create mode 100644 vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs diff --git a/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs b/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs new file mode 100644 index 00000000000..cccdea000ee --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System.Composition +open System.Threading +open System.Threading.Tasks + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +open FSharp.Compiler.SourceCodeServices + +[] +type internal FSharpUseMutationWhenValueIsMutableFixProvider + [] + ( + checkerProvider: FSharpCheckerProvider, + projectInfoManager: FSharpProjectOptionsManager + ) = + inherit CodeFixProvider() + + static let userOpName = "UseMutationWhenValueIsMutable" + + let fixableDiagnosticIds = set ["FS0020"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context : Task = + asyncMaybe { + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let document = context.Document + do! Option.guard (not(isSignatureFile document.FilePath)) + let position = context.Span.Start + let checker = checkerProvider.Checker + let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, CancellationToken.None, userOpName) + let! sourceText = document.GetTextAsync () |> liftTaskAsync + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions + let textLine = sourceText.Lines.GetLineFromPosition position + let textLinePos = sourceText.Lines.GetLinePosition position + let fcsTextLineNumber = Line.fromZ textLinePos.Line + let! _, _, checkFileResults = checker.ParseAndCheckDocument (document, projectOptions, sourceText=sourceText, userOpName=userOpName) + let! lexerSymbol = Tokenizer.getSymbolAtPosition (document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy, false, false) + let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, lexerSymbol.Ident.idRange.EndColumn, textLine.ToString(), lexerSymbol.FullIsland) + + match symbolUse.Symbol with + | :? FSharpMemberOrFunctionOrValue as mfv when mfv.IsValue && mfv.IsMutable -> + let title = SR.UseMutationWhenValueIsMutable() + let! symbolSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate) + let mutable pos = symbolSpan.End + let mutable ch = sourceText.GetSubText(pos).ToString() + + // We're looking for the possibly erroneous '=' + while pos <= context.Span.Length && ch <> "=" do + pos <- pos + 1 + ch <- sourceText.GetSubText(pos).ToString() + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| TextChange(TextSpan(pos + 1, 1), "<-") |])) + + context.RegisterCodeFix(codeFix, diagnostics) + | _ -> () + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj index 1091a3d4baf..e0e73bf14bf 100644 --- a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj +++ b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj @@ -89,6 +89,7 @@ + diff --git a/vsintegration/src/FSharp.Editor/FSharp.Editor.resx b/vsintegration/src/FSharp.Editor/FSharp.Editor.resx index 802675e062e..f45e5672515 100644 --- a/vsintegration/src/FSharp.Editor/FSharp.Editor.resx +++ b/vsintegration/src/FSharp.Editor/FSharp.Editor.resx @@ -225,4 +225,7 @@ Use subtraction instead of negation + + Use '<-' to mutate value + \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf index d5486f6aac4..09ab0db26e0 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf @@ -177,6 +177,11 @@ Formátování + + Use '<-' to mutate value + Use '<-' to mutate value + + Wrap expression in parentheses Wrap expression in parentheses diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf index b66b9951e47..77b9e76b2ac 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf @@ -177,6 +177,11 @@ Formatierung + + Use '<-' to mutate value + Use '<-' to mutate value + + Wrap expression in parentheses Wrap expression in parentheses diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf index ebe2cb49dbd..a32c7312b07 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf @@ -177,6 +177,11 @@ Formato + + Use '<-' to mutate value + Use '<-' to mutate value + + Wrap expression in parentheses Wrap expression in parentheses diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf index 8a24580b08e..4b15c624677 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf @@ -177,6 +177,11 @@ Mise en forme + + Use '<-' to mutate value + Use '<-' to mutate value + + Wrap expression in parentheses Wrap expression in parentheses diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf index b6cadf4482c..b4f81a5071d 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf @@ -177,6 +177,11 @@ Formattazione + + Use '<-' to mutate value + Use '<-' to mutate value + + Wrap expression in parentheses Wrap expression in parentheses diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf index 9029587aabc..c5ba9365d88 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf @@ -177,6 +177,11 @@ 書式設定 + + Use '<-' to mutate value + Use '<-' to mutate value + + Wrap expression in parentheses Wrap expression in parentheses diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf index 6c18283919e..c6629e4d9f4 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf @@ -177,6 +177,11 @@ 서식 + + Use '<-' to mutate value + Use '<-' to mutate value + + Wrap expression in parentheses Wrap expression in parentheses diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf index 94e101a86e6..883b365ffcc 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf @@ -177,6 +177,11 @@ Formatowanie + + Use '<-' to mutate value + Use '<-' to mutate value + + Wrap expression in parentheses Wrap expression in parentheses diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf index dedf532aedc..75054569bcf 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf @@ -177,6 +177,11 @@ Formatação + + Use '<-' to mutate value + Use '<-' to mutate value + + Wrap expression in parentheses Wrap expression in parentheses diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf index 1207c51d09f..ac9457f48e5 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf @@ -177,6 +177,11 @@ Форматирование + + Use '<-' to mutate value + Use '<-' to mutate value + + Wrap expression in parentheses Wrap expression in parentheses diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf index 19c41424348..514082a3cc5 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf @@ -177,6 +177,11 @@ Biçimlendirme + + Use '<-' to mutate value + Use '<-' to mutate value + + Wrap expression in parentheses Wrap expression in parentheses diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf index 14605a7064c..dda4caba34d 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf @@ -177,6 +177,11 @@ 正在格式化 + + Use '<-' to mutate value + Use '<-' to mutate value + + Wrap expression in parentheses Wrap expression in parentheses diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf index 3e89e5c086c..329f6229482 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf @@ -177,6 +177,11 @@ 格式化 + + Use '<-' to mutate value + Use '<-' to mutate value + + Wrap expression in parentheses Wrap expression in parentheses From a649034bb1d6da6a8c39e5c49c44245a42ecaad5 Mon Sep 17 00:00:00 2001 From: cartermp Date: Tue, 17 Nov 2020 13:38:24 -0800 Subject: [PATCH 2/2] Add missing open --- .../src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs | 1 + 1 file changed, 1 insertion(+) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs b/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs index cccdea000ee..67003759d0a 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs @@ -10,6 +10,7 @@ open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.CodeFixes open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Range [] type internal FSharpUseMutationWhenValueIsMutableFixProvider