Skip to content

Commit

Permalink
Make ConvertToProcedureQuickFix convert Exit statements as well
Browse files Browse the repository at this point in the history
  • Loading branch information
MDoerner committed Nov 22, 2019
1 parent 79b1cba commit adfb5c9
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 15 deletions.
70 changes: 55 additions & 15 deletions Rubberduck.CodeAnalysis/QuickFixes/ConvertToProcedureQuickFix.cs
Expand Up @@ -33,48 +33,88 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio
}

private void ConvertFunction(IInspectionResult result, VBAParser.FunctionStmtContext functionContext, IModuleRewriter rewriter)
{
RemoveAsTypeDeclaration(functionContext, rewriter);
RemoveTypeHint(result, functionContext, rewriter);

ConvertFunctionDeclaration(functionContext, rewriter);
ConvertExitFunctionStatements(functionContext, rewriter);

RemoveReturnStatements(result, rewriter);
}

private static void RemoveAsTypeDeclaration(ParserRuleContext functionContext, IModuleRewriter rewriter)
{
var asTypeContext = functionContext.GetChild<VBAParser.AsTypeClauseContext>();
if (asTypeContext != null)
{
rewriter.Remove(asTypeContext);
rewriter.Remove(functionContext.children.ElementAt(functionContext.children.IndexOf(asTypeContext) - 1) as ParserRuleContext);
rewriter.Remove(
functionContext.children.ElementAt(functionContext.children.IndexOf(asTypeContext) -
1) as ParserRuleContext);
}
}

private static void RemoveTypeHint(IInspectionResult result, ParserRuleContext functionContext, IModuleRewriter rewriter)
{
if (result.Target.TypeHint != null)
{
rewriter.Remove(functionContext.GetDescendent<VBAParser.TypeHintContext>());
}
}

rewriter.Replace(functionContext.FUNCTION(), Tokens.Sub);
rewriter.Replace(functionContext.END_FUNCTION(), "End Sub");

private void RemoveReturnStatements(IInspectionResult result, IModuleRewriter rewriter)
{
foreach (var returnStatement in GetReturnStatements(result.Target))
{
rewriter.Remove(returnStatement);
}
}

private void ConvertPropertyGet(IInspectionResult result, VBAParser.PropertyGetStmtContext propertyGetContext, IModuleRewriter rewriter)
private static void ConvertFunctionDeclaration(VBAParser.FunctionStmtContext functionContext, IModuleRewriter rewriter)
{
var asTypeContext = propertyGetContext.GetChild<VBAParser.AsTypeClauseContext>();
if (asTypeContext != null)
{
rewriter.Remove(asTypeContext);
rewriter.Remove(propertyGetContext.children.ElementAt(propertyGetContext.children.IndexOf(asTypeContext) - 1) as ParserRuleContext);
}
rewriter.Replace(functionContext.FUNCTION(), Tokens.Sub);
rewriter.Replace(functionContext.END_FUNCTION(), "End Sub");
}

if (result.Target.TypeHint != null)
private static void ConvertExitFunctionStatements(VBAParser.FunctionStmtContext context, IModuleRewriter rewriter)
{
var exitStatements = context.GetDescendents<VBAParser.ExitStmtContext>();
foreach (var exitStatement in exitStatements)
{
rewriter.Remove(propertyGetContext.GetDescendent<VBAParser.TypeHintContext>());
if (exitStatement.EXIT_FUNCTION() != null)
{
rewriter.Replace(exitStatement, $"{Tokens.Exit} {Tokens.Sub}");
}
}
}

private void ConvertPropertyGet(IInspectionResult result, VBAParser.PropertyGetStmtContext propertyGetContext, IModuleRewriter rewriter)
{
RemoveAsTypeDeclaration(propertyGetContext, rewriter);
RemoveTypeHint(result, propertyGetContext, rewriter);

ConvertPropertyGetDeclaration(propertyGetContext, rewriter);
ConvertExitPropertyStatements(propertyGetContext, rewriter);

RemoveReturnStatements(result, rewriter);
}

private static void ConvertPropertyGetDeclaration(VBAParser.PropertyGetStmtContext propertyGetContext, IModuleRewriter rewriter)
{
rewriter.Replace(propertyGetContext.PROPERTY_GET(), Tokens.Sub);
rewriter.Replace(propertyGetContext.END_PROPERTY(), "End Sub");
}

foreach (var returnStatement in GetReturnStatements(result.Target))
private static void ConvertExitPropertyStatements(VBAParser.PropertyGetStmtContext context, IModuleRewriter rewriter)
{
var exitStatements = context.GetDescendents<VBAParser.ExitStmtContext>();
foreach (var exitStatement in exitStatements)
{
rewriter.Remove(returnStatement);
if (exitStatement.EXIT_PROPERTY() != null)
{
rewriter.Replace(exitStatement, $"{Tokens.Exit} {Tokens.Sub}");
}
}
}

Expand Down
58 changes: 58 additions & 0 deletions RubberduckTests/QuickFixes/ConvertToProcedureQuickFixTests.cs
Expand Up @@ -162,6 +162,35 @@ public void NonReturningFunction_QuickFixWorks_Function()
Assert.AreEqual(expectedCode, actualCode);
}

[Test]
[Category("QuickFixes")]
//See issue #5298 at https://github.com/rubberduck-vba/Rubberduck/issues/5298
public void NonReturningFunction_ConvertsExitFunction()
{
const string inputCode =
@"Function Foo() As Boolean
If False Then Exit Function
if True Then
Exit Function
Else
Exit Function
End If
End Function";

const string expectedCode =
@"Sub Foo()
If False Then Exit Sub
if True Then
Exit Sub
Else
Exit Sub
End If
End Sub";

var actualCode = ApplyQuickFixToFirstInspectionResult(inputCode, state => new NonReturningFunctionInspection(state));
Assert.AreEqual(expectedCode, actualCode);
}

[Test]
[Category("QuickFixes")]
public void GivenFunctionNameWithTypeHint_SubNameHasNoTypeHint()
Expand Down Expand Up @@ -226,6 +255,35 @@ public void GivenNonReturningPropertyGetter_QuickFixConvertsToSub()
Assert.AreEqual(expectedCode, actualCode);
}

[Test]
[Category("QuickFixes")]
//See issue #5298 at https://github.com/rubberduck-vba/Rubberduck/issues/5298
public void GivenNonReturningPropertyGetter_ConvertsExitProperty()
{
const string inputCode =
@"Property Get Foo() As Boolean
If False Then Exit Property
if True Then
Exit Property
Else
Exit Property
End If
End Property";

const string expectedCode =
@"Sub Foo()
If False Then Exit Sub
if True Then
Exit Sub
Else
Exit Sub
End If
End Sub";

var actualCode = ApplyQuickFixToFirstInspectionResult(inputCode, state => new NonReturningFunctionInspection(state));
Assert.AreEqual(expectedCode, actualCode);
}

[Test]
[Category("QuickFixes")]
public void GivenNonReturningPropertyGetWithTypeHint_QuickFixDropsTypeHint()
Expand Down

0 comments on commit adfb5c9

Please sign in to comment.