From 4f618b7dd2f202f692e2910cebeae7afebe72f7a Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Wed, 18 Nov 2020 14:00:16 -0800 Subject: [PATCH] Add MakeDeclarationMutable code fix (#10480) --- CodeFix/MakeDeclarationMutable.fs | 73 +++++++++++++++++++++++++++++++ FSharp.Editor.fsproj | 1 + FSharp.Editor.resx | 3 ++ xlf/FSharp.Editor.cs.xlf | 5 +++ xlf/FSharp.Editor.de.xlf | 5 +++ xlf/FSharp.Editor.es.xlf | 5 +++ xlf/FSharp.Editor.fr.xlf | 5 +++ xlf/FSharp.Editor.it.xlf | 5 +++ xlf/FSharp.Editor.ja.xlf | 5 +++ xlf/FSharp.Editor.ko.xlf | 5 +++ xlf/FSharp.Editor.pl.xlf | 5 +++ xlf/FSharp.Editor.pt-BR.xlf | 5 +++ xlf/FSharp.Editor.ru.xlf | 5 +++ xlf/FSharp.Editor.tr.xlf | 5 +++ xlf/FSharp.Editor.zh-Hans.xlf | 5 +++ xlf/FSharp.Editor.zh-Hant.xlf | 5 +++ 16 files changed, 142 insertions(+) create mode 100644 CodeFix/MakeDeclarationMutable.fs diff --git a/CodeFix/MakeDeclarationMutable.fs b/CodeFix/MakeDeclarationMutable.fs new file mode 100644 index 00000000000..52287c96298 --- /dev/null +++ b/CodeFix/MakeDeclarationMutable.fs @@ -0,0 +1,73 @@ +// 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.Range +open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.AbstractIL.Internal.Library + +[] +type internal FSharpMakeDeclarationMutableFixProvider + [] + ( + checkerProvider: FSharpCheckerProvider, + projectInfoManager: FSharpProjectOptionsManager + ) = + inherit CodeFixProvider() + + static let userOpName = "MakeDeclarationMutable" + + let fixableDiagnosticIds = set ["FS0027"] + + 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! parseFileResults, _, 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 decl = checkFileResults.GetDeclarationLocation (fcsTextLineNumber, lexerSymbol.Ident.idRange.EndColumn, textLine.ToString(), lexerSymbol.FullIsland, false) + + match decl with + // Only do this for symbols in the same file. That covers almost all cases anyways. + // We really shouldn't encourage making values mutable outside of local scopes anyways. + | FSharpFindDeclResult.DeclFound declRange when declRange.FileName = document.FilePath -> + let! span = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, declRange) + + // Bail if it's a parameter, because like, that ain't allowed + do! Option.guard (not (parseFileResults.IsPositionContainedInACurriedParameter declRange.Start)) + + let title = SR.MakeDeclarationMutable() + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| TextChange(TextSpan(span.Start, 0), "mutable ") |])) + + context.RegisterCodeFix(codeFix, diagnostics) + | _ -> + () + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) \ No newline at end of file diff --git a/FSharp.Editor.fsproj b/FSharp.Editor.fsproj index 4d8542a4495..7ee5ebb362e 100644 --- a/FSharp.Editor.fsproj +++ b/FSharp.Editor.fsproj @@ -184,6 +184,7 @@ + diff --git a/FSharp.Editor.resx b/FSharp.Editor.resx index fbfd462a09e..b84fec2d255 100644 --- a/FSharp.Editor.resx +++ b/FSharp.Editor.resx @@ -219,6 +219,9 @@ F# Dispostable Values (top-level) + + Make declaration 'mutable' + Use 'upcast' diff --git a/xlf/FSharp.Editor.cs.xlf b/xlf/FSharp.Editor.cs.xlf index cfc92dc856e..21c7283d96f 100644 --- a/xlf/FSharp.Editor.cs.xlf +++ b/xlf/FSharp.Editor.cs.xlf @@ -52,6 +52,11 @@ Implementujte rozhraní bez anotace typu. + + Make declaration 'mutable' + Make declaration 'mutable' + + Prefix '{0}' with underscore Před {0} vložte podtržítko. diff --git a/xlf/FSharp.Editor.de.xlf b/xlf/FSharp.Editor.de.xlf index 18b949208c7..53a83d33922 100644 --- a/xlf/FSharp.Editor.de.xlf +++ b/xlf/FSharp.Editor.de.xlf @@ -52,6 +52,11 @@ Schnittstelle ohne Typanmerkung implementieren + + Make declaration 'mutable' + Make declaration 'mutable' + + Prefix '{0}' with underscore "{0}" einen Unterstrich voranstellen diff --git a/xlf/FSharp.Editor.es.xlf b/xlf/FSharp.Editor.es.xlf index 78f2b99a234..dc6c9c40f63 100644 --- a/xlf/FSharp.Editor.es.xlf +++ b/xlf/FSharp.Editor.es.xlf @@ -52,6 +52,11 @@ Implementar interfaz sin anotación de tipos + + Make declaration 'mutable' + Make declaration 'mutable' + + Prefix '{0}' with underscore Colocar un carácter de subrayado delante de "{0}" diff --git a/xlf/FSharp.Editor.fr.xlf b/xlf/FSharp.Editor.fr.xlf index 9c18b60164b..934e8d5c697 100644 --- a/xlf/FSharp.Editor.fr.xlf +++ b/xlf/FSharp.Editor.fr.xlf @@ -52,6 +52,11 @@ Implémenter l'interface sans annotation de type + + Make declaration 'mutable' + Make declaration 'mutable' + + Prefix '{0}' with underscore Faire précéder '{0}' d'un trait de soulignement diff --git a/xlf/FSharp.Editor.it.xlf b/xlf/FSharp.Editor.it.xlf index 560bb871c5c..aee12fbb58f 100644 --- a/xlf/FSharp.Editor.it.xlf +++ b/xlf/FSharp.Editor.it.xlf @@ -52,6 +52,11 @@ Implementa l'interfaccia senza annotazione di tipo + + Make declaration 'mutable' + Make declaration 'mutable' + + Prefix '{0}' with underscore Anteponi a '{0}' un carattere di sottolineatura diff --git a/xlf/FSharp.Editor.ja.xlf b/xlf/FSharp.Editor.ja.xlf index 0a6e6dc43c5..191ff6c3dfe 100644 --- a/xlf/FSharp.Editor.ja.xlf +++ b/xlf/FSharp.Editor.ja.xlf @@ -52,6 +52,11 @@ 型の注釈を指定しないでインターフェイスを実装する + + Make declaration 'mutable' + Make declaration 'mutable' + + Prefix '{0}' with underscore アンダースコアが含まれているプレフィックス '{0}' diff --git a/xlf/FSharp.Editor.ko.xlf b/xlf/FSharp.Editor.ko.xlf index 1951db13fab..60bb0063367 100644 --- a/xlf/FSharp.Editor.ko.xlf +++ b/xlf/FSharp.Editor.ko.xlf @@ -52,6 +52,11 @@ 형식 주석 없이 인터페이스 구현 + + Make declaration 'mutable' + Make declaration 'mutable' + + Prefix '{0}' with underscore 밑줄이 있는 '{0}' 접두사 diff --git a/xlf/FSharp.Editor.pl.xlf b/xlf/FSharp.Editor.pl.xlf index 7b903f93fa3..152937264c9 100644 --- a/xlf/FSharp.Editor.pl.xlf +++ b/xlf/FSharp.Editor.pl.xlf @@ -52,6 +52,11 @@ Zaimplementuj interfejs bez adnotacji typu + + Make declaration 'mutable' + Make declaration 'mutable' + + Prefix '{0}' with underscore Prefiks „{0}” ze znakiem podkreślenia diff --git a/xlf/FSharp.Editor.pt-BR.xlf b/xlf/FSharp.Editor.pt-BR.xlf index 30a5191c9d9..3e18128e93f 100644 --- a/xlf/FSharp.Editor.pt-BR.xlf +++ b/xlf/FSharp.Editor.pt-BR.xlf @@ -52,6 +52,11 @@ Implementar a interface sem a anotação de tipo + + Make declaration 'mutable' + Make declaration 'mutable' + + Prefix '{0}' with underscore Prefixo '{0}' sem sublinhado diff --git a/xlf/FSharp.Editor.ru.xlf b/xlf/FSharp.Editor.ru.xlf index 29fb73ca1bd..db8fbd7b78f 100644 --- a/xlf/FSharp.Editor.ru.xlf +++ b/xlf/FSharp.Editor.ru.xlf @@ -52,6 +52,11 @@ Реализовать интерфейс без заметки с типом + + Make declaration 'mutable' + Make declaration 'mutable' + + Prefix '{0}' with underscore Добавить символ подчеркивания как префикс "{0}" diff --git a/xlf/FSharp.Editor.tr.xlf b/xlf/FSharp.Editor.tr.xlf index 10b88fe3681..abf4e3c70e5 100644 --- a/xlf/FSharp.Editor.tr.xlf +++ b/xlf/FSharp.Editor.tr.xlf @@ -52,6 +52,11 @@ Tür ek açıklaması olmadan arabirim uygulama + + Make declaration 'mutable' + Make declaration 'mutable' + + Prefix '{0}' with underscore '{0}' öğesinin önüne alt çizgi ekleme diff --git a/xlf/FSharp.Editor.zh-Hans.xlf b/xlf/FSharp.Editor.zh-Hans.xlf index c17436ace25..0ef2dc2e91d 100644 --- a/xlf/FSharp.Editor.zh-Hans.xlf +++ b/xlf/FSharp.Editor.zh-Hans.xlf @@ -52,6 +52,11 @@ 无类型批注的实现接口 + + Make declaration 'mutable' + Make declaration 'mutable' + + Prefix '{0}' with underscore 带下划线的前缀“{0}” diff --git a/xlf/FSharp.Editor.zh-Hant.xlf b/xlf/FSharp.Editor.zh-Hant.xlf index 29a418e0050..254adcaa42a 100644 --- a/xlf/FSharp.Editor.zh-Hant.xlf +++ b/xlf/FSharp.Editor.zh-Hant.xlf @@ -52,6 +52,11 @@ 實作沒有類型註釋的介面 + + Make declaration 'mutable' + Make declaration 'mutable' + + Prefix '{0}' with underscore 有底線的前置詞 '{0}'