Skip to content
This repository was archived by the owner on Dec 23, 2024. It is now read-only.

Commit 1df766e

Browse files
authored
Add refactoring to replace ! with .Value (dotnet#11227)
1 parent edd951b commit 1df766e

16 files changed

+133
-0
lines changed

FSharp.Editor.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
<Compile Include="Commands\FsiCommandService.fs" />
9191
<Compile Include="Commands\XmlDocCommandService.fs" />
9292
<Compile Include="Refactor\AddExplicitTypeToParameter.fs" />
93+
<Compile Include="Refactor\ChangeDerefToValueRefactoring.fs" />
9394
<Compile Include="CodeFix\CodeFixHelpers.fs" />
9495
<Compile Include="CodeFix\AddTypeAnnotationToObjectOfIndeterminateType.fs" />
9596
<Compile Include="CodeFix\AddMissingRecToMutuallyRecFunctions.fs" />

FSharp.Editor.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,9 @@
273273
<data name="ConvertToNotEqualsEqualityExpression" xml:space="preserve">
274274
<value>Use '&lt;&gt;' for inequality check</value>
275275
</data>
276+
<data name="UseValueInsteadOfDeref" xml:space="preserve">
277+
<value>Use '.Value' to dereference expression</value>
278+
</data>
276279
<data name="AddTypeAnnotation" xml:space="preserve">
277280
<value>Add type annotation</value>
278281
</data>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+
namespace Microsoft.VisualStudio.FSharp.Editor
4+
5+
open System
6+
open System.Composition
7+
open System.Threading
8+
9+
open FSharp.Compiler
10+
open FSharp.Compiler.CodeAnalysis
11+
open FSharp.Compiler.Symbols
12+
open FSharp.Compiler.Text
13+
open FSharp.Compiler.Syntax
14+
15+
open Microsoft.CodeAnalysis.Text
16+
open Microsoft.CodeAnalysis.CodeRefactorings
17+
open Microsoft.CodeAnalysis.CodeActions
18+
19+
[<ExportCodeRefactoringProvider(FSharpConstants.FSharpLanguageName, Name = "ChangeDerefToValue"); Shared>]
20+
type internal FSharpChangeDerefToValueRefactoring
21+
[<ImportingConstructor>]
22+
(
23+
checkerProvider: FSharpCheckerProvider,
24+
projectInfoManager: FSharpProjectOptionsManager
25+
) =
26+
inherit CodeRefactoringProvider()
27+
28+
static let userOpName = "ChangeDerefToValue"
29+
30+
override _.ComputeRefactoringsAsync context =
31+
asyncMaybe {
32+
let document = context.Document
33+
let! parsingOptions, _ = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken, userOpName)
34+
let! sourceText = context.Document.GetTextAsync(context.CancellationToken)
35+
let! parseResults = checkerProvider.Checker.ParseFile(document.FilePath, sourceText.ToFSharpSourceText(), parsingOptions, userOpName=userOpName) |> liftAsync
36+
37+
let selectionRange = RoslynHelpers.TextSpanToFSharpRange(document.FilePath, context.Span, sourceText)
38+
let! derefRange = parseResults.TryRangeOfRefCellDereferenceContainingPos selectionRange.Start
39+
let! exprRange = parseResults.TryRangeOfExpressionBeingDereferencedContainingPos selectionRange.Start
40+
41+
let combinedRange = Range.unionRanges derefRange exprRange
42+
let! combinedSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, combinedRange)
43+
let replacementString =
44+
// Trim off the `!`
45+
sourceText.GetSubText(combinedSpan).ToString().[1..] + ".Value"
46+
47+
let title = SR.UseValueInsteadOfDeref()
48+
49+
let getChangedText (sourceText: SourceText) =
50+
sourceText.WithChanges(TextChange(combinedSpan, replacementString))
51+
52+
let codeAction =
53+
CodeAction.Create(
54+
title,
55+
(fun (cancellationToken: CancellationToken) ->
56+
async {
57+
let! sourceText = context.Document.GetTextAsync(cancellationToken) |> Async.AwaitTask
58+
return context.Document.WithText(getChangedText sourceText)
59+
} |> RoslynHelpers.StartAsyncAsTask(cancellationToken)),
60+
title)
61+
context.RegisterRefactoring(codeAction)
62+
}
63+
|> Async.Ignore
64+
|> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)

xlf/FSharp.Editor.cs.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@
262262
<target state="translated">Negovat výraz pomocí not</target>
263263
<note />
264264
</trans-unit>
265+
<trans-unit id="UseValueInsteadOfDeref">
266+
<source>Use '.Value' to dereference expression</source>
267+
<target state="new">Use '.Value' to dereference expression</target>
268+
<note />
269+
</trans-unit>
265270
<trans-unit id="WrapExpressionInParentheses">
266271
<source>Wrap expression in parentheses</source>
267272
<target state="translated">Uzavřít výraz do závorek</target>

xlf/FSharp.Editor.de.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@
262262
<target state="translated">"not" zum Negieren eines Ausdruck verwenden</target>
263263
<note />
264264
</trans-unit>
265+
<trans-unit id="UseValueInsteadOfDeref">
266+
<source>Use '.Value' to dereference expression</source>
267+
<target state="new">Use '.Value' to dereference expression</target>
268+
<note />
269+
</trans-unit>
265270
<trans-unit id="WrapExpressionInParentheses">
266271
<source>Wrap expression in parentheses</source>
267272
<target state="translated">Ausdruck in Klammern einschließen</target>

xlf/FSharp.Editor.es.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@
262262
<target state="translated">Usar "not" para negar la expresión</target>
263263
<note />
264264
</trans-unit>
265+
<trans-unit id="UseValueInsteadOfDeref">
266+
<source>Use '.Value' to dereference expression</source>
267+
<target state="new">Use '.Value' to dereference expression</target>
268+
<note />
269+
</trans-unit>
265270
<trans-unit id="WrapExpressionInParentheses">
266271
<source>Wrap expression in parentheses</source>
267272
<target state="translated">Encapsular la expresión entre paréntesis</target>

xlf/FSharp.Editor.fr.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@
262262
<target state="translated">Utiliser 'not' pour annuler l'expression</target>
263263
<note />
264264
</trans-unit>
265+
<trans-unit id="UseValueInsteadOfDeref">
266+
<source>Use '.Value' to dereference expression</source>
267+
<target state="new">Use '.Value' to dereference expression</target>
268+
<note />
269+
</trans-unit>
265270
<trans-unit id="WrapExpressionInParentheses">
266271
<source>Wrap expression in parentheses</source>
267272
<target state="translated">Mettre l'expression entre parenthèses</target>

xlf/FSharp.Editor.it.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@
262262
<target state="translated">Usare 'not' per negare l'espressione</target>
263263
<note />
264264
</trans-unit>
265+
<trans-unit id="UseValueInsteadOfDeref">
266+
<source>Use '.Value' to dereference expression</source>
267+
<target state="new">Use '.Value' to dereference expression</target>
268+
<note />
269+
</trans-unit>
265270
<trans-unit id="WrapExpressionInParentheses">
266271
<source>Wrap expression in parentheses</source>
267272
<target state="translated">Racchiudere l'espressione tra parentesi</target>

xlf/FSharp.Editor.ja.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@
262262
<target state="translated">式を否定するには 'not' を使用する</target>
263263
<note />
264264
</trans-unit>
265+
<trans-unit id="UseValueInsteadOfDeref">
266+
<source>Use '.Value' to dereference expression</source>
267+
<target state="new">Use '.Value' to dereference expression</target>
268+
<note />
269+
</trans-unit>
265270
<trans-unit id="WrapExpressionInParentheses">
266271
<source>Wrap expression in parentheses</source>
267272
<target state="translated">式をかっこで囲む</target>

xlf/FSharp.Editor.ko.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@
262262
<target state="translated">식을 부정하려면 'not' 사용</target>
263263
<note />
264264
</trans-unit>
265+
<trans-unit id="UseValueInsteadOfDeref">
266+
<source>Use '.Value' to dereference expression</source>
267+
<target state="new">Use '.Value' to dereference expression</target>
268+
<note />
269+
</trans-unit>
265270
<trans-unit id="WrapExpressionInParentheses">
266271
<source>Wrap expression in parentheses</source>
267272
<target state="translated">식을 괄호로 래핑</target>

0 commit comments

Comments
 (0)