-
Notifications
You must be signed in to change notification settings - Fork 789
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a codefix that suggests replacements for unknown identifiers #2106
Changes from all commits
3015b15
4ea67e7
f72331d
2c3557f
b3f2fd1
0de2322
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,4 @@ | ||
|
||
usesfsi.fsx(2,1): error FS0039: The namespace or module 'fsi' is not defined. | ||
|
||
Maybe you want one of the following: | ||
usesfsi.fsx(2,1): error FS0039: The namespace or module 'fsi' is not defined. Maybe you want one of the following: | ||
|
||
FSharp |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
namespace rec Microsoft.VisualStudio.FSharp.Editor | ||
|
||
open System | ||
open System.Composition | ||
open System.Collections.Immutable | ||
open System.Threading | ||
open System.Threading.Tasks | ||
|
||
open Microsoft.CodeAnalysis | ||
open Microsoft.CodeAnalysis.Text | ||
open Microsoft.CodeAnalysis.CodeFixes | ||
open Microsoft.CodeAnalysis.CodeActions | ||
|
||
[<ExportCodeFixProvider(FSharpCommonConstants.FSharpLanguageName, Name = "ReplaceWithSuggestion"); Shared>] | ||
type internal FSharpReplaceWithSuggestionCodeFixProvider() = | ||
inherit CodeFixProvider() | ||
let fixableDiagnosticIds = ["FS0039"; "FS1129"; "FS0495"] |> Set.ofList | ||
let maybeString = FSComp.SR.undefinedNameSuggestionsIntro() | ||
|
||
let createCodeFix (title: string, context: CodeFixContext, textChange: TextChange) = | ||
CodeAction.Create( | ||
title, | ||
(fun (cancellationToken: CancellationToken) -> | ||
async { | ||
let! sourceText = context.Document.GetTextAsync() | ||
return context.Document.WithText(sourceText.WithChanges(textChange)) | ||
} |> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken)), | ||
title) | ||
|
||
override __.FixableDiagnosticIds = fixableDiagnosticIds.ToImmutableArray() | ||
|
||
override __.RegisterCodeFixesAsync context : Task = | ||
async { | ||
context.Diagnostics | ||
|> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) | ||
|> Seq.iter (fun diagnostic -> | ||
let message = diagnostic.GetMessage() | ||
let splitted = message.Split([|maybeString|], StringSplitOptions.None) | ||
if splitted.Length > 1 then | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This feels somewhat icky ... we should consider adding to the compiler service an improved method of transmitting error information to the IDE. For example:
Obviously that's not specific to this PR ... but we should consider an improvement. Kevin There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Absolutely. Parsing error messages is definitely the wrong way to do it (I think this specific case could also work in Arabic - because we concatenate the error message from left to right). That said: it is an easy way to do it. And it works in practice. We already love to use it in ionide |
||
let suggestions = | ||
splitted.[1].Split([|' '; '\r'; '\n'|], StringSplitOptions.RemoveEmptyEntries) | ||
|> Array.map (fun s -> s.Trim()) | ||
|
||
let diagnostics = [| diagnostic |].ToImmutableArray() | ||
|
||
for suggestion in suggestions do | ||
let codefix = | ||
createCodeFix( | ||
FSComp.SR.replaceWithSuggestion suggestion, | ||
context, | ||
TextChange(context.Span, suggestion)) | ||
context.RegisterCodeFix(codefix, diagnostics)) | ||
} |> CommonRoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
splitted is not really a word :-)
The past tense of split is .... split.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lol.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://en.m.wiktionary.org/wiki/splitted it says I'm nonstandard or archaic. Guess I can live with that.
Anyways, will fix tomorrow.