Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a8c967a
temporary stash
T-Gro Apr 5, 2023
8571a4d
Merge remote-tracking branch 'upstream/main' into 14967-bulk-codefixe…
T-Gro Apr 5, 2023
d6122a0
Merge remote-tracking branch 'upstream/main' into 14967-bulk-codefixe…
T-Gro Apr 5, 2023
5f32fda
Merge remote-tracking branch 'upstream/main' into 14967-bulk-codefixe…
T-Gro Apr 6, 2023
bfae9d1
pick which codefixes should be turned into having bulk support
T-Gro Apr 6, 2023
c400bae
format
T-Gro Apr 7, 2023
7b3a4b2
bulk codefix refactor
T-Gro Apr 13, 2023
2eb6008
Merge remote-tracking branch 'upstream/main' into 14967-bulk-codefixe…
T-Gro Apr 13, 2023
62a79b1
cleanup telemetry reporting
T-Gro Apr 13, 2023
2135305
Merge remote-tracking branch 'upstream/main' into 14967-bulk-codefixe…
T-Gro Apr 13, 2023
e91d8df
remove stupid copy paste bug
T-Gro Apr 13, 2023
dd2d23a
Automated command ran: fantomas
github-actions[bot] Apr 13, 2023
029eedd
Merge branch 'main' into 14967-bulk-codefixes-are-broken
T-Gro Apr 17, 2023
200eed8
Merge branch 'main' into 14967-bulk-codefixes-are-broken
T-Gro Apr 18, 2023
3710495
codefix refactorings
T-Gro Apr 18, 2023
f12e5a4
codefix registration - for now the ones using CodeFixHelpers
T-Gro Apr 18, 2023
81e4a1b
fantomas'd
T-Gro Apr 18, 2023
b43ede0
typo fix
T-Gro Apr 18, 2023
59851a8
codefix simplification
T-Gro Apr 18, 2023
8eb9063
fix
T-Gro Apr 18, 2023
363da95
Merge branch 'main' into codefixes-cleanup
T-Gro Apr 18, 2023
0227efd
FSharpWrapExpressionInParenthesesFixProvider simplified
T-Gro Apr 18, 2023
d3e6760
Merge branch 'codefixes-cleanup' of https://github.com/T-Gro/fsharp i…
T-Gro Apr 18, 2023
ece3b76
fantomas'd
T-Gro Apr 18, 2023
af7af1f
removing unused value
T-Gro Apr 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace Microsoft.VisualStudio.FSharp.Editor

open System.Composition
open System.Threading.Tasks
open System.Collections.Immutable

open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.CodeFixes
Expand All @@ -12,10 +13,9 @@ open Microsoft.CodeAnalysis.CodeFixes
type internal FSharpAddInstanceMemberParameterCodeFixProvider() =
inherit CodeFixProvider()

let fixableDiagnosticIds = set [ "FS0673" ]
static let title = SR.AddMissingInstanceMemberParameter()

override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds
override _.FixableDiagnosticIds = ImmutableArray.Create("FS0673")

override _.RegisterCodeFixesAsync context : Task =
asyncMaybe {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace Microsoft.VisualStudio.FSharp.Editor
open System
open System.Composition
open System.Threading.Tasks
open System.Collections.Immutable

open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.CodeFixes
Expand All @@ -13,9 +14,8 @@ open Microsoft.CodeAnalysis.CodeFixes
type internal FSharpAddMissingEqualsToTypeDefinitionCodeFixProvider() =
inherit CodeFixProvider()

let fixableDiagnosticIds = set [ "FS3360" ]
static let title = SR.AddMissingEqualsToTypeDefinition()
override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds
override _.FixableDiagnosticIds = ImmutableArray.Create("FS3360")

override _.RegisterCodeFixesAsync context : Task =
asyncMaybe {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace Microsoft.VisualStudio.FSharp.Editor

open System
open System.Composition
open System.Collections.Immutable

open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.CodeFixes
Expand All @@ -16,9 +17,7 @@ type internal FSharpAddMissingFunKeywordCodeFixProvider [<ImportingConstructor>]
inherit CodeFixProvider()
static let title = SR.AddMissingFunKeyword()

let fixableDiagnosticIds = set [ "FS0010" ]

override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds
override _.FixableDiagnosticIds = ImmutableArray.Create("FS0010")

override _.RegisterCodeFixesAsync context =
asyncMaybe {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,13 @@ open FSharp.Compiler.CodeAnalysis
open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.CodeActions

[<ExportCodeFixProvider(FSharpConstants.FSharpLanguageName, Name = "AddMissingRecToMutuallyRecFunctions"); Shared>]
[<ExportCodeFixProvider(FSharpConstants.FSharpLanguageName, Name = CodeFix.AddMissingRecToMutuallyRecFunctions); Shared>]
type internal FSharpAddMissingRecToMutuallyRecFunctionsCodeFixProvider [<ImportingConstructor>] () =
inherit CodeFixProvider()

let fixableDiagnosticIds = set [ "FS0576" ]
static let titleFormat = SR.MakeOuterBindingRecursive()

let createCodeFix
(
context: CodeFixContext,
symbolName: string,
titleFormat: string,
textChange: TextChange,
diagnostics: ImmutableArray<Diagnostic>
) =
let title = String.Format(titleFormat, symbolName)

let codeAction =
CodeAction.Create(
title,
(fun (cancellationToken: CancellationToken) ->
async {
let cancellationToken = context.CancellationToken
let! sourceText = context.Document.GetTextAsync(cancellationToken) |> Async.AwaitTask
return context.Document.WithText(sourceText.WithChanges(textChange))
}
|> RoslynHelpers.StartAsyncAsTask(cancellationToken)),
title
)

context.RegisterCodeFix(codeAction, diagnostics)

override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds
override _.FixableDiagnosticIds = ImmutableArray.Create("FS0576")

override _.RegisterCodeFixesAsync context =
asyncMaybe {
Expand Down Expand Up @@ -82,18 +57,12 @@ type internal FSharpAddMissingRecToMutuallyRecFunctionsCodeFixProvider [<Importi
let! funcNameSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, funcLexerSymbol.Range)
let funcName = sourceText.GetSubText(funcNameSpan).ToString()

let diagnostics =
context.Diagnostics
|> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id)
|> Seq.toImmutableArray

createCodeFix (
context,
funcName,
SR.MakeOuterBindingRecursive(),
TextChange(TextSpan(context.Span.End, 0), " rec"),
diagnostics
)
do
context.RegisterFsharpFix(
CodeFix.AddMissingRecToMutuallyRecFunctions,
String.Format(titleFormat, funcName),
[| TextChange(TextSpan(context.Span.End, 0), " rec") |]
)
}
|> Async.Ignore
|> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)
51 changes: 18 additions & 33 deletions vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ open System
open System.Composition
open System.Threading
open System.Threading.Tasks
open System.Collections.Immutable

open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Text
Expand All @@ -21,35 +22,24 @@ open FSharp.Compiler.Text
type internal FSharpAddOpenCodeFixProvider [<ImportingConstructor>] (assemblyContentProvider: AssemblyContentProvider) =
inherit CodeFixProvider()

let fixableDiagnosticIds = [ "FS0039"; "FS0043" ]

let fixUnderscoresInMenuText (text: string) = text.Replace("_", "__")

let qualifySymbolFix (context: CodeFixContext) (fullName, qualifier) =
CodeFixHelpers.createTextChangeCodeFix (
CodeFix.AddOpen,
fixUnderscoresInMenuText fullName,
context,
[| TextChange(context.Span, qualifier) |]
)

let openNamespaceFix (context: CodeFixContext) ctx name ns multipleNames =
context.RegisterFsharpFix(CodeFix.AddOpen, fixUnderscoresInMenuText fullName, [| TextChange(context.Span, qualifier) |])

let openNamespaceFix (context: CodeFixContext) ctx name ns multipleNames sourceText =
let displayText = "open " + ns + (if multipleNames then " (" + name + ")" else "")
let newText, _ = OpenDeclarationHelper.insertOpenDeclaration sourceText ctx ns
let changes = newText.GetTextChanges(sourceText)

CodeAction.Create(
fixUnderscoresInMenuText displayText,
(fun (cancellationToken: CancellationToken) ->
async {
let! sourceText = context.Document.GetTextAsync(cancellationToken) |> Async.AwaitTask
let changedText, _ = OpenDeclarationHelper.insertOpenDeclaration sourceText ctx ns
return context.Document.WithText(changedText)
}
|> RoslynHelpers.StartAsyncAsTask(cancellationToken)),
displayText
)
context.RegisterFsharpFix(CodeFix.AddOpen, fixUnderscoresInMenuText displayText, changes)

let addSuggestionsAsCodeFixes (context: CodeFixContext) (candidates: (InsertionContextEntity * InsertionContext) list) =
let openNamespaceFixes =
let addSuggestionsAsCodeFixes
(context: CodeFixContext)
(sourceText: SourceText)
(candidates: (InsertionContextEntity * InsertionContext) list)
=
do
candidates
|> Seq.choose (fun (entity, ctx) -> entity.Namespace |> Option.map (fun ns -> ns, entity.FullDisplayName, ctx))
|> Seq.groupBy (fun (ns, _, _) -> ns)
Expand All @@ -64,22 +54,17 @@ type internal FSharpAddOpenCodeFixProvider [<ImportingConstructor>] (assemblyCon
let multipleNames = names |> Array.length > 1
names |> Seq.map (fun (name, ctx) -> ns, name, ctx, multipleNames))
|> Seq.concat
|> Seq.map (fun (ns, name, ctx, multipleNames) -> openNamespaceFix context ctx name ns multipleNames)
|> Seq.toList
|> Seq.iter (fun (ns, name, ctx, multipleNames) -> openNamespaceFix context ctx name ns multipleNames sourceText)

let qualifiedSymbolFixes =
do
candidates
|> Seq.filter (fun (entity, _) -> not (entity.LastIdent.StartsWith "op_")) // Don't include qualified operator names. The resultant codefix won't compile because it won't be an infix operator anymore.
|> Seq.map (fun (entity, _) -> entity.FullRelativeName, entity.Qualifier)
|> Seq.distinct
|> Seq.sort
|> Seq.map (qualifySymbolFix context)
|> Seq.toList

for codeFix in openNamespaceFixes @ qualifiedSymbolFixes do
context.RegisterCodeFix(codeFix, context.Diagnostics)
|> Seq.iter (qualifySymbolFix context)

override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds
override _.FixableDiagnosticIds = ImmutableArray.Create("FS0039", "FS0043")

override _.RegisterCodeFixesAsync context : Task =
asyncMaybe {
Expand Down Expand Up @@ -186,7 +171,7 @@ type internal FSharpAddOpenCodeFixProvider [<ImportingConstructor>] (assemblyCon
|> Seq.map createEntity
|> Seq.concat
|> Seq.toList
|> addSuggestionsAsCodeFixes context
|> addSuggestionsAsCodeFixes context sourceText
}
|> Async.Ignore
|> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ open System
open System.Composition
open System.Threading
open System.Threading.Tasks
open System.Collections.Immutable

open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.CodeFixes
Expand All @@ -16,20 +17,16 @@ open FSharp.Compiler.Text
open FSharp.Compiler.Symbols
open Microsoft.CodeAnalysis.CodeActions

[<ExportCodeFixProvider(FSharpConstants.FSharpLanguageName, Name = "AddTypeAnnotationToObjectOfIndeterminateType"); Shared>]
[<ExportCodeFixProvider(FSharpConstants.FSharpLanguageName, Name = CodeFix.AddTypeAnnotationToObjectOfIndeterminateType); Shared>]
type internal FSharpAddTypeAnnotationToObjectOfIndeterminateTypeFixProvider [<ImportingConstructor>] () =
inherit CodeFixProvider()

let fixableDiagnosticIds = set [ "FS0072"; "FS3245" ]
static let title = SR.AddTypeAnnotation()

override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds
override _.FixableDiagnosticIds = ImmutableArray.Create("FS0072", "FS3245")

override _.RegisterCodeFixesAsync context : Task =
asyncMaybe {
let diagnostics =
context.Diagnostics
|> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id)
|> Seq.toImmutableArray

let document = context.Document
let position = context.Span.Start
Expand Down Expand Up @@ -95,29 +92,17 @@ type internal FSharpAddTypeAnnotationToObjectOfIndeterminateTypeFixProvider [<Im
let hasRightParen = rightLoop sourceText.[declSpan.End] declSpan.End
hasLeftParen && hasRightParen

let getChangedText (sourceText: SourceText) =
if alreadyWrappedInParens then
sourceText.WithChanges(TextChange(TextSpan(declSpan.End, 0), ": " + typeString))
else
sourceText
.WithChanges(TextChange(TextSpan(declSpan.Start, 0), "("))
.WithChanges(TextChange(TextSpan(declSpan.End + 1, 0), ": " + typeString + ")"))

let title = SR.AddTypeAnnotation()

let codeAction =
CodeAction.Create(
title,
(fun (cancellationToken: CancellationToken) ->
async {
let! sourceText = context.Document.GetTextAsync(cancellationToken) |> Async.AwaitTask
return context.Document.WithText(getChangedText sourceText)
}
|> RoslynHelpers.StartAsyncAsTask(cancellationToken)),
title
)

context.RegisterCodeFix(codeAction, diagnostics)
let changes =
[
if alreadyWrappedInParens then
TextChange(TextSpan(declSpan.End, 0), ": " + typeString)
else
TextChange(TextSpan(declSpan.Start, 0), "(")
TextChange(TextSpan(declSpan.End + 1, 0), ": " + typeString + ")")
]

context.RegisterFsharpFix(CodeFix.AddTypeAnnotationToObjectOfIndeterminateType, title, changes)

| _ -> ()
| _ -> ()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace Microsoft.VisualStudio.FSharp.Editor
open System
open System.Composition
open System.Threading.Tasks
open System.Collections.Immutable

open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.CodeFixes
Expand All @@ -13,10 +14,9 @@ open Microsoft.CodeAnalysis.CodeFixes
type internal FSharpChangePrefixNegationToInfixSubtractionodeFixProvider() =
inherit CodeFixProvider()

let fixableDiagnosticIds = set [ "FS0003" ]
static let title = SR.ChangePrefixNegationToInfixSubtraction()

override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds
override _.FixableDiagnosticIds = ImmutableArray.Create("FS0003")

override _.RegisterCodeFixesAsync context : Task =
asyncMaybe {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace Microsoft.VisualStudio.FSharp.Editor

open System.Composition
open System.Threading.Tasks
open System.Collections.Immutable

open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.CodeFixes
Expand All @@ -12,10 +13,9 @@ open Microsoft.CodeAnalysis.CodeFixes
type internal FSharpChangeRefCellDerefToNotExpressionCodeFixProvider [<ImportingConstructor>] () =
inherit CodeFixProvider()

let fixableDiagnosticIds = set [ "FS0001" ]
static let title = SR.UseNotForNegation()

override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds
override _.FixableDiagnosticIds = ImmutableArray.Create("FS0001")

override this.RegisterCodeFixesAsync context : Task =
asyncMaybe {
Expand Down
5 changes: 2 additions & 3 deletions vsintegration/src/FSharp.Editor/CodeFix/ChangeToUpcast.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace Microsoft.VisualStudio.FSharp.Editor

open System.Composition
open System.Threading.Tasks
open System.Collections.Immutable

open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.CodeFixes
Expand All @@ -12,9 +13,7 @@ open Microsoft.CodeAnalysis.CodeFixes
type internal FSharpChangeToUpcastCodeFixProvider() =
inherit CodeFixProvider()

let fixableDiagnosticIds = set [ "FS3198" ]

override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds
override _.FixableDiagnosticIds = ImmutableArray.Create("FS3198")

override this.RegisterCodeFixesAsync context : Task =
asyncMaybe {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Microsoft.VisualStudio.FSharp.Editor

open System.Composition
open System.Collections.Immutable

open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.CodeFixes
Expand All @@ -11,9 +12,9 @@ open Microsoft.CodeAnalysis.CodeFixes
type internal FSharpConvertCSharpLambdaToFSharpLambdaCodeFixProvider [<ImportingConstructor>] () =
inherit CodeFixProvider()

let fixableDiagnosticIds = set [ "FS0039"; "FS0043" ]
static let title = SR.UseFSharpLambda()
override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds

override _.FixableDiagnosticIds = ImmutableArray.Create("FS0039", "FS0043")

override _.RegisterCodeFixesAsync context =
asyncMaybe {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ open Microsoft.CodeAnalysis.CodeFixes
type internal FSharpConvertCSharpUsingToFSharpOpen [<ImportingConstructor>] () =
inherit CodeFixProvider()

let fixableDiagnosticIds = set [ "FS0039"; "FS0201" ]
static let title = SR.ConvertCSharpUsingToFSharpOpen()
let usingLength = "using".Length

Expand Down Expand Up @@ -47,7 +46,7 @@ type internal FSharpConvertCSharpUsingToFSharpOpen [<ImportingConstructor>] () =

do context.RegisterFsharpFix(CodeFix.ConvertCSharpUsingToFSharpOpen, title, [| replacement |])

override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds
override _.FixableDiagnosticIds = ImmutableArray.Create("FS0039", "FS0201")

override _.RegisterCodeFixesAsync context =
asyncMaybe {
Expand Down
Loading