Skip to content
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

Rename param to match signature code fix #917

Merged
merged 3 commits into from
Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
84 changes: 84 additions & 0 deletions src/FsAutoComplete/CodeFixes/RenameParamToMatchSignature.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
module FsAutoComplete.CodeFix.RenameParamToMatchSignature

open FsToolkit.ErrorHandling
open FsAutoComplete.CodeFix.Types
open Ionide.LanguageServerProtocol.Types
open FsAutoComplete
open FsAutoComplete.LspHelpers
open FSharp.Compiler.Syntax

let title name = $"Replace with '%s{name}'"
/// codefix that renames a parameter to match its signature (specified in fsi file)
let fix
(getParseResultsForFile: GetParseResultsForFile)
: CodeFix
=
Run.ifDiagnosticByCode
(Set.ofList [ "3218" ])
(fun diagnostic codeActionParams -> asyncResult {
let tryGetSigName (msg: string) =
// diag message:
// > The argument names in the signature 'xxx' and implementation 'yyy' do not match. The argument name from the signature file will be used. This may cause problems when debugging or profiling.

/// Match exact message
///
/// Issues:
/// * fails when sig contains `' and implementation '`
/// * only works with english language (-> exact match in english)
/// * exact match of message -> fails when diag message should change
let tryGetByExactMatch (msg: string) =
let head = "The argument names in the signature '"
let mid = "' and implementation '"
if msg.StartsWith head then
match msg.IndexOf mid with
| -1 -> None
| i ->
msg.Substring(head.Length, i - head.Length)
|> Some
else
None
/// Fallback to match between `'`s
///
/// Fails when either sig or impl contains `'` (except at end) (`my'value`)
let tryGetBySimpleRegex (msg: string) =
let parts = System.Text.RegularExpressions.Regex.Match(msg, ".+'(.+)'.+'(.+)'.+")
if parts.Success then
parts.Groups[1].Value
|> Some
else
None
match tryGetByExactMatch msg with
| Some name ->
Some name
| None ->
tryGetBySimpleRegex msg

match tryGetSigName diagnostic.Message with
| None -> return []
| Some sigName ->
let sigName =
sigName
|> PrettyNaming.AddBackticksToIdentifierIfNeeded

// replace usages of parameter with new name
let fileName = codeActionParams.TextDocument.GetFilePath() |> Utils.normalizePath
let fscPos = protocolPosToPos diagnostic.Range.Start
let! (tyRes, line, _) = getParseResultsForFile fileName fscPos

let! (_, usages) = tyRes.TryGetSymbolUseAndUsages fscPos line
let edits =
// usages are inside local function -> all usages in same doc
// `usages` includes parameter position
usages
|> Array.map (fun usage ->
{ Range = fcsRangeToLsp usage.Range; NewText = sigName }
)

return [{
File = codeActionParams.TextDocument
Title = title sigName
Edits = edits
Kind = FixKind.Fix
SourceDiagnostic = Some diagnostic
}]
})
113 changes: 58 additions & 55 deletions src/FsAutoComplete/FsAutoComplete.Lsp.fs
Original file line number Diff line number Diff line change
Expand Up @@ -843,61 +843,64 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS
let getAbstractClassStubReplacements () = abstractClassStubReplacements ()

codeFixes <-
[| Run.ifEnabled
(fun _ -> config.UnusedOpensAnalyzer)
(RemoveUnusedOpens.fix getFileLines)
Run.ifEnabled
(fun _ -> config.ResolveNamespaces)
(ResolveNamespace.fix tryGetParseResultsForFile commands.GetNamespaceSuggestions)
ReplaceWithSuggestion.fix
RemoveRedundantQualifier.fix
Run.ifEnabled (fun _ -> config.UnusedDeclarationsAnalyzer) (RenameUnusedValue.fix getRangeText)
AddNewKeywordToDisposableConstructorInvocation.fix getRangeText
Run.ifEnabled
(fun _ -> config.UnionCaseStubGeneration)
(GenerateUnionCases.fix
getFileLines
tryGetParseResultsForFile
commands.GetUnionPatternMatchCases
getUnionCaseStubReplacements)
ExternalSystemDiagnostics.linter
ExternalSystemDiagnostics.analyzers
Run.ifEnabled
(fun _ -> config.InterfaceStubGeneration)
(GenerateInterfaceStub.fix tryGetParseResultsForFile commands.GetInterfaceStub getInterfaceStubReplacements)
Run.ifEnabled
(fun _ -> config.RecordStubGeneration)
(GenerateRecordStub.fix tryGetParseResultsForFile commands.GetRecordStub getRecordStubReplacements)
Run.ifEnabled
(fun _ -> config.AbstractClassStubGeneration)
(GenerateAbstractClassStub.fix
tryGetParseResultsForFile
commands.GetAbstractClassStub
getAbstractClassStubReplacements)
AddMissingEqualsToTypeDefinition.fix getFileLines
ChangePrefixNegationToInfixSubtraction.fix getFileLines
ConvertDoubleEqualsToSingleEquals.fix getRangeText
ChangeEqualsInFieldTypeToColon.fix
WrapExpressionInParentheses.fix getRangeText
ChangeRefCellDerefToNot.fix tryGetParseResultsForFile
ChangeDowncastToUpcast.fix getRangeText
MakeDeclarationMutable.fix tryGetParseResultsForFile tryGetProjectOptions
UseMutationWhenValueIsMutable.fix tryGetParseResultsForFile
ConvertInvalidRecordToAnonRecord.fix tryGetParseResultsForFile
RemoveUnnecessaryReturnOrYield.fix tryGetParseResultsForFile getLineText
ConvertCSharpLambdaToFSharpLambda.fix tryGetParseResultsForFile getLineText
AddMissingFunKeyword.fix getFileLines getLineText
MakeOuterBindingRecursive.fix tryGetParseResultsForFile getLineText
AddMissingRecKeyword.fix getFileLines getLineText
ConvertBangEqualsToInequality.fix getRangeText
ChangeDerefBangToValue.fix tryGetParseResultsForFile getLineText
RemoveUnusedBinding.fix tryGetParseResultsForFile
AddTypeToIndeterminateValue.fix tryGetParseResultsForFile tryGetProjectOptions
ChangeTypeOfNameToNameOf.fix tryGetParseResultsForFile
AddMissingInstanceMember.fix
AddExplicitTypeToParameter.fix tryGetParseResultsForFile
ConvertPositionalDUToNamed.fix tryGetParseResultsForFile getRangeText
UseTripleQuotedInterpolation.fix tryGetParseResultsForFile getRangeText |]
[|
Run.ifEnabled
(fun _ -> config.UnusedOpensAnalyzer)
(RemoveUnusedOpens.fix getFileLines)
Run.ifEnabled
(fun _ -> config.ResolveNamespaces)
(ResolveNamespace.fix tryGetParseResultsForFile commands.GetNamespaceSuggestions)
ReplaceWithSuggestion.fix
RemoveRedundantQualifier.fix
Run.ifEnabled (fun _ -> config.UnusedDeclarationsAnalyzer) (RenameUnusedValue.fix getRangeText)
AddNewKeywordToDisposableConstructorInvocation.fix getRangeText
Run.ifEnabled
(fun _ -> config.UnionCaseStubGeneration)
(GenerateUnionCases.fix
getFileLines
tryGetParseResultsForFile
commands.GetUnionPatternMatchCases
getUnionCaseStubReplacements)
ExternalSystemDiagnostics.linter
ExternalSystemDiagnostics.analyzers
Run.ifEnabled
(fun _ -> config.InterfaceStubGeneration)
(GenerateInterfaceStub.fix tryGetParseResultsForFile commands.GetInterfaceStub getInterfaceStubReplacements)
Run.ifEnabled
(fun _ -> config.RecordStubGeneration)
(GenerateRecordStub.fix tryGetParseResultsForFile commands.GetRecordStub getRecordStubReplacements)
Run.ifEnabled
(fun _ -> config.AbstractClassStubGeneration)
(GenerateAbstractClassStub.fix
tryGetParseResultsForFile
commands.GetAbstractClassStub
getAbstractClassStubReplacements)
AddMissingEqualsToTypeDefinition.fix getFileLines
ChangePrefixNegationToInfixSubtraction.fix getFileLines
ConvertDoubleEqualsToSingleEquals.fix getRangeText
ChangeEqualsInFieldTypeToColon.fix
WrapExpressionInParentheses.fix getRangeText
ChangeRefCellDerefToNot.fix tryGetParseResultsForFile
ChangeDowncastToUpcast.fix getRangeText
MakeDeclarationMutable.fix tryGetParseResultsForFile tryGetProjectOptions
UseMutationWhenValueIsMutable.fix tryGetParseResultsForFile
ConvertInvalidRecordToAnonRecord.fix tryGetParseResultsForFile
RemoveUnnecessaryReturnOrYield.fix tryGetParseResultsForFile getLineText
ConvertCSharpLambdaToFSharpLambda.fix tryGetParseResultsForFile getLineText
AddMissingFunKeyword.fix getFileLines getLineText
MakeOuterBindingRecursive.fix tryGetParseResultsForFile getLineText
AddMissingRecKeyword.fix getFileLines getLineText
ConvertBangEqualsToInequality.fix getRangeText
ChangeDerefBangToValue.fix tryGetParseResultsForFile getLineText
RemoveUnusedBinding.fix tryGetParseResultsForFile
AddTypeToIndeterminateValue.fix tryGetParseResultsForFile tryGetProjectOptions
ChangeTypeOfNameToNameOf.fix tryGetParseResultsForFile
AddMissingInstanceMember.fix
AddExplicitTypeToParameter.fix tryGetParseResultsForFile
ConvertPositionalDUToNamed.fix tryGetParseResultsForFile getRangeText
UseTripleQuotedInterpolation.fix tryGetParseResultsForFile getRangeText
RenameParamToMatchSignature.fix tryGetParseResultsForFile
|]


match p.RootPath, c.AutomaticWorkspaceInit with
Expand Down