I'm inspecting VBA code to find obsolete code constructs - namely explicit Call
statements, like this:
Call DoSomething(42)
The "correct" code construct would be to omit the Call
token and drop the parentheses - my code locates the obsolete Call
statements and rewrites them like this:
DoSomething 42
I have an IdentifierReference
class, which I'm using to store the context of various identifier references throughout the VBA code I'm parsing. In order for my code inspection to easily locate method calls that use the obsolete Call
syntax, I have added this method to the IdentifierReference
class:
public bool HasExplicitCallStatement()
{
try
{
var call = ((dynamic)Context.Parent).CALL();
return call != null && call.Symbol.Text == Tokens.Call;
}
catch (Exception)
{
return false;
}
}
But I didn't like having to handle exceptions here, so I rewrote it in a more strongly-typed way, like this:
public bool HasExplicitCallStatement()
{
var memberProcedureCall = Context.Parent as VBAParser.ECS_MemberProcedureCallContext;
var procedureCall = Context.Parent as VBAParser.ECS_ProcedureCallContext;
return HasExplicitCallStatement(memberProcedureCall)
|| HasExplicitCallStatement(procedureCall);
}
private bool HasExplicitCallStatement(VBAParser.ECS_MemberProcedureCallContext context)
{
if (context == null)
{
return false;
}
var statement = context.CALL();
return statement != null && statement.Symbol.Text == Tokens.Call;
}
private bool HasExplicitCallStatement(VBAParser.ECS_ProcedureCallContext context)
{
if (context == null)
{
return false;
}
var statement = context.CALL();
return statement != null && statement.Symbol.Text == Tokens.Call;
}
And now I wonder... is this really an improvement?
Is there any more elegant way of dealing with different types that should be sharing an interface but aren't? ECS_ProcedureCallContext
and ECS_MemberProcedureCallContext
are ANTLR-generated types, nested in the VBAParser
class, generated from the grammar file I'm using.