From 05a5f6223d4869c2e51435d00c2ed0d21518628b Mon Sep 17 00:00:00 2001 From: cartermp Date: Fri, 29 Jan 2021 17:21:42 -0800 Subject: [PATCH] Account for properties and qualified items in the 'Use <- to mutate' codefix --- .../CodeFix/UseMutationWhenValueIsMutable.fs | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs b/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs index 3a3ea50cb5d..a0d423ca149 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs @@ -2,6 +2,7 @@ namespace Microsoft.VisualStudio.FSharp.Editor +open System open System.Composition open System.Threading open System.Threading.Tasks @@ -36,20 +37,29 @@ type internal FSharpUseMutationWhenValueIsMutableFixProvider 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 adjustedPosition = + let rec loop ch pos = + if Char.IsWhiteSpace(ch) then + pos + else + loop sourceText.[pos + 1] (pos + 1) + + loop sourceText.[context.Span.Start] context.Span.Start + + let textLine = sourceText.Lines.GetLineFromPosition adjustedPosition + let textLinePos = sourceText.Lines.GetLinePosition adjustedPosition 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! lexerSymbol = Tokenizer.getSymbolAtPosition (document.Id, sourceText, adjustedPosition, 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 -> + | :? FSharpMemberOrFunctionOrValue as mfv when mfv.IsMutable || mfv.HasSetterMethod -> let title = SR.UseMutationWhenValueIsMutable() let! symbolSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate) let mutable pos = symbolSpan.End