From 35204f17fc2c7903a2b932a3e5ee924599d340b9 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 12 Feb 2025 17:00:18 +0100 Subject: [PATCH] Refactorings/introduce var: don't suggest 'use' for top-level bindings --- .../src/Refactorings/IntroduceVariable.fs | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Refactorings/IntroduceVariable.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Refactorings/IntroduceVariable.fs index 9935b7df98..610b4df809 100644 --- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Refactorings/IntroduceVariable.fs +++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Refactorings/IntroduceVariable.fs @@ -51,6 +51,7 @@ type FSharpIntroduceVariableData(sourceExpr, usages) = member val FirstUsageExpr: IFSharpExpression = null with get, set member val ContextExpr: IFSharpExpression = null with get, set + member val ContextDecl: IModuleMember = null with get, set member val Keywords = [FSharpTokenType.LET] with get, set member val BindComputation = false with get, set @@ -144,6 +145,16 @@ module FSharpIntroduceVariable = getOutermostLambda parent | _ -> parent + let getContextDeclaration (contextExpr: IFSharpExpression): IModuleMember = + let binding = BindingNavigator.GetByExpression(contextExpr) + if isNotNull binding && binding.HasParameters then null else + + let letBindings = LetBindingsDeclarationNavigator.GetByBinding(binding) + if isNotNull letBindings then letBindings :> _ else + + let exprStmt = ExpressionStatementNavigator.GetByExpression(contextExpr) + if isNotNull exprStmt then exprStmt :> _ else null + let getOccurrenceText (displayContext: FSharpDisplayContext) (fcsType: FSharpType) (text: string) = let richText = RichText("Bind '") richText.Append(fcsType.Format(displayContext), TextStyle(JetFontStyles.Bold)) |> ignore @@ -218,16 +229,6 @@ type FSharpIntroduceVariable(workflow: IntroduceLocalWorkflowBase, solution, dri let range = TreeRange(contextExpr) {| ReplaceRange = range; InRange = range; AddNewLine = true |} - let getContextDeclaration (contextExpr: IFSharpExpression): IModuleMember = - let binding = BindingNavigator.GetByExpression(contextExpr) - if isNotNull binding && binding.HasParameters then null else - - let letBindings = LetBindingsDeclarationNavigator.GetByBinding(binding) - if isNotNull letBindings then letBindings :> _ else - - let exprStmt = ExpressionStatementNavigator.GetByExpression(contextExpr) - if isNotNull exprStmt then exprStmt :> _ else null - let createBinding (context: IFSharpExpression) (contextDecl: IModuleMember) name: ILetBindings = let elementFactory = context.CreateElementFactory() if isNotNull contextDecl then @@ -308,9 +309,7 @@ type FSharpIntroduceVariable(workflow: IntroduceLocalWorkflowBase, solution, dri let data = data :?> FSharpIntroduceVariableData let sourceExpr = data.FirstUsageExpr let contextExpr = data.ContextExpr - - // `contextDecl` is not null when expression is bound to a module/type let binding. - let contextDecl = getContextDeclaration contextExpr + let contextDecl = data.ContextDecl let contextIsSourceExpr = sourceExpr == contextExpr && isNull contextDecl let contextIsImplicitDo = sourceExpr == contextExpr && contextDecl :? IDoLikeStatement @@ -681,7 +680,7 @@ type FSharpIntroduceVarHelper() = override this.AdditionalInitialization(workflow, expression, context) = let data = workflow.DataModel :?> FSharpIntroduceVariableData - // Replace the actual source expression with the outer-most expression among usages, + // Replace the actual source expression with the outermost expression among usages, // since it's needed for calculating a common node to replace. let sourceExpr = data.Usages |> Seq.minBy (fun u -> u.GetTreeStartOffset().Offset) :?> IFSharpExpression @@ -689,8 +688,12 @@ type FSharpIntroduceVarHelper() = let safeParentToInsertBefore = FSharpIntroduceVariable.getSafeParentExprToInsertBefore workflow commonParent let contextExpr = FSharpIntroduceVariable.getExprToInsertBefore safeParentToInsertBefore + // `contextDecl` is not null when expression is bound to a module/type let binding. + let contextDecl = FSharpIntroduceVariable.getContextDeclaration contextExpr + data.FirstUsageExpr <- sourceExpr data.ContextExpr <- contextExpr + data.ContextDecl <- contextDecl let fcsType = sourceExpr.TryGetFcsType() let displayContext = sourceExpr.TryGetFcsDisplayContext() @@ -752,6 +755,8 @@ type FSharpIntroduceVarHelper() = let isDisposable = mappedBoundType.IsSubtypeOf(disposableType) let supportsUse = + isNull contextDecl && + match isDisposable, computationType with | false, _ -> false | _, None -> true