Skip to content

Commit adfb5c9

Browse files
committed
Make ConvertToProcedureQuickFix convert Exit statements as well
1 parent 79b1cba commit adfb5c9

File tree

2 files changed

+113
-15
lines changed

2 files changed

+113
-15
lines changed

Rubberduck.CodeAnalysis/QuickFixes/ConvertToProcedureQuickFix.cs

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,48 +33,88 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio
3333
}
3434

3535
private void ConvertFunction(IInspectionResult result, VBAParser.FunctionStmtContext functionContext, IModuleRewriter rewriter)
36+
{
37+
RemoveAsTypeDeclaration(functionContext, rewriter);
38+
RemoveTypeHint(result, functionContext, rewriter);
39+
40+
ConvertFunctionDeclaration(functionContext, rewriter);
41+
ConvertExitFunctionStatements(functionContext, rewriter);
42+
43+
RemoveReturnStatements(result, rewriter);
44+
}
45+
46+
private static void RemoveAsTypeDeclaration(ParserRuleContext functionContext, IModuleRewriter rewriter)
3647
{
3748
var asTypeContext = functionContext.GetChild<VBAParser.AsTypeClauseContext>();
3849
if (asTypeContext != null)
3950
{
4051
rewriter.Remove(asTypeContext);
41-
rewriter.Remove(functionContext.children.ElementAt(functionContext.children.IndexOf(asTypeContext) - 1) as ParserRuleContext);
52+
rewriter.Remove(
53+
functionContext.children.ElementAt(functionContext.children.IndexOf(asTypeContext) -
54+
1) as ParserRuleContext);
4255
}
56+
}
4357

58+
private static void RemoveTypeHint(IInspectionResult result, ParserRuleContext functionContext, IModuleRewriter rewriter)
59+
{
4460
if (result.Target.TypeHint != null)
4561
{
4662
rewriter.Remove(functionContext.GetDescendent<VBAParser.TypeHintContext>());
4763
}
64+
}
4865

49-
rewriter.Replace(functionContext.FUNCTION(), Tokens.Sub);
50-
rewriter.Replace(functionContext.END_FUNCTION(), "End Sub");
51-
66+
private void RemoveReturnStatements(IInspectionResult result, IModuleRewriter rewriter)
67+
{
5268
foreach (var returnStatement in GetReturnStatements(result.Target))
5369
{
5470
rewriter.Remove(returnStatement);
5571
}
5672
}
5773

58-
private void ConvertPropertyGet(IInspectionResult result, VBAParser.PropertyGetStmtContext propertyGetContext, IModuleRewriter rewriter)
74+
private static void ConvertFunctionDeclaration(VBAParser.FunctionStmtContext functionContext, IModuleRewriter rewriter)
5975
{
60-
var asTypeContext = propertyGetContext.GetChild<VBAParser.AsTypeClauseContext>();
61-
if (asTypeContext != null)
62-
{
63-
rewriter.Remove(asTypeContext);
64-
rewriter.Remove(propertyGetContext.children.ElementAt(propertyGetContext.children.IndexOf(asTypeContext) - 1) as ParserRuleContext);
65-
}
76+
rewriter.Replace(functionContext.FUNCTION(), Tokens.Sub);
77+
rewriter.Replace(functionContext.END_FUNCTION(), "End Sub");
78+
}
6679

67-
if (result.Target.TypeHint != null)
80+
private static void ConvertExitFunctionStatements(VBAParser.FunctionStmtContext context, IModuleRewriter rewriter)
81+
{
82+
var exitStatements = context.GetDescendents<VBAParser.ExitStmtContext>();
83+
foreach (var exitStatement in exitStatements)
6884
{
69-
rewriter.Remove(propertyGetContext.GetDescendent<VBAParser.TypeHintContext>());
85+
if (exitStatement.EXIT_FUNCTION() != null)
86+
{
87+
rewriter.Replace(exitStatement, $"{Tokens.Exit} {Tokens.Sub}");
88+
}
7089
}
90+
}
91+
92+
private void ConvertPropertyGet(IInspectionResult result, VBAParser.PropertyGetStmtContext propertyGetContext, IModuleRewriter rewriter)
93+
{
94+
RemoveAsTypeDeclaration(propertyGetContext, rewriter);
95+
RemoveTypeHint(result, propertyGetContext, rewriter);
7196

97+
ConvertPropertyGetDeclaration(propertyGetContext, rewriter);
98+
ConvertExitPropertyStatements(propertyGetContext, rewriter);
99+
100+
RemoveReturnStatements(result, rewriter);
101+
}
102+
103+
private static void ConvertPropertyGetDeclaration(VBAParser.PropertyGetStmtContext propertyGetContext, IModuleRewriter rewriter)
104+
{
72105
rewriter.Replace(propertyGetContext.PROPERTY_GET(), Tokens.Sub);
73106
rewriter.Replace(propertyGetContext.END_PROPERTY(), "End Sub");
107+
}
74108

75-
foreach (var returnStatement in GetReturnStatements(result.Target))
109+
private static void ConvertExitPropertyStatements(VBAParser.PropertyGetStmtContext context, IModuleRewriter rewriter)
110+
{
111+
var exitStatements = context.GetDescendents<VBAParser.ExitStmtContext>();
112+
foreach (var exitStatement in exitStatements)
76113
{
77-
rewriter.Remove(returnStatement);
114+
if (exitStatement.EXIT_PROPERTY() != null)
115+
{
116+
rewriter.Replace(exitStatement, $"{Tokens.Exit} {Tokens.Sub}");
117+
}
78118
}
79119
}
80120

RubberduckTests/QuickFixes/ConvertToProcedureQuickFixTests.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,35 @@ public void NonReturningFunction_QuickFixWorks_Function()
162162
Assert.AreEqual(expectedCode, actualCode);
163163
}
164164

165+
[Test]
166+
[Category("QuickFixes")]
167+
//See issue #5298 at https://github.com/rubberduck-vba/Rubberduck/issues/5298
168+
public void NonReturningFunction_ConvertsExitFunction()
169+
{
170+
const string inputCode =
171+
@"Function Foo() As Boolean
172+
If False Then Exit Function
173+
if True Then
174+
Exit Function
175+
Else
176+
Exit Function
177+
End If
178+
End Function";
179+
180+
const string expectedCode =
181+
@"Sub Foo()
182+
If False Then Exit Sub
183+
if True Then
184+
Exit Sub
185+
Else
186+
Exit Sub
187+
End If
188+
End Sub";
189+
190+
var actualCode = ApplyQuickFixToFirstInspectionResult(inputCode, state => new NonReturningFunctionInspection(state));
191+
Assert.AreEqual(expectedCode, actualCode);
192+
}
193+
165194
[Test]
166195
[Category("QuickFixes")]
167196
public void GivenFunctionNameWithTypeHint_SubNameHasNoTypeHint()
@@ -226,6 +255,35 @@ public void GivenNonReturningPropertyGetter_QuickFixConvertsToSub()
226255
Assert.AreEqual(expectedCode, actualCode);
227256
}
228257

258+
[Test]
259+
[Category("QuickFixes")]
260+
//See issue #5298 at https://github.com/rubberduck-vba/Rubberduck/issues/5298
261+
public void GivenNonReturningPropertyGetter_ConvertsExitProperty()
262+
{
263+
const string inputCode =
264+
@"Property Get Foo() As Boolean
265+
If False Then Exit Property
266+
if True Then
267+
Exit Property
268+
Else
269+
Exit Property
270+
End If
271+
End Property";
272+
273+
const string expectedCode =
274+
@"Sub Foo()
275+
If False Then Exit Sub
276+
if True Then
277+
Exit Sub
278+
Else
279+
Exit Sub
280+
End If
281+
End Sub";
282+
283+
var actualCode = ApplyQuickFixToFirstInspectionResult(inputCode, state => new NonReturningFunctionInspection(state));
284+
Assert.AreEqual(expectedCode, actualCode);
285+
}
286+
229287
[Test]
230288
[Category("QuickFixes")]
231289
public void GivenNonReturningPropertyGetWithTypeHint_QuickFixDropsTypeHint()

0 commit comments

Comments
 (0)