Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a walker be stopped?

I have a ParseTree listener implementation that I'm using to fetch global-scope declarations in standard VBA modules:

public class DeclarationSectionListener : DeclarationListener
{
    private bool _insideProcedure;

    public override void EnterVariableStmt(VisualBasic6Parser.VariableStmtContext context)
    {
        var visibility = context.visibility();
        if (!_insideProcedure && visibility == null 
            || visibility.GetText() == Tokens.Public
            || visibility.GetText() == Tokens.Global)
        {
            base.EnterVariableStmt(context);
        }
    }

    public override void EnterConstStmt(VisualBasic6Parser.ConstStmtContext context)
    {
        var visibility = context.visibility();
        if (!_insideProcedure && visibility == null
            || visibility.GetText() == Tokens.Public
            || visibility.GetText() == Tokens.Global)
        {
            base.EnterConstStmt(context);
        }
    }

    public override void EnterArg(VisualBasic6Parser.ArgContext context)
    {
        return;
    }

    public override void EnterSubStmt(VisualBasic6Parser.SubStmtContext context)
    {
        _insideProcedure = true;
    }

    public override void EnterFunctionStmt(VisualBasic6Parser.FunctionStmtContext context)
    {
        _insideProcedure = true;
    }

    public override void EnterPropertyGetStmt(VisualBasic6Parser.PropertyGetStmtContext context)
    {
        _insideProcedure = true;
    }

    public override void EnterPropertyLetStmt(VisualBasic6Parser.PropertyLetStmtContext context)
    {
        _insideProcedure = true;
    }

    public override void ExitPropertySetStmt(VisualBasic6Parser.PropertySetStmtContext context)
    {
        _insideProcedure = true;
    }
}

Is there a way to tell the tree walker to stop walking? Say I have a VBA module like this:

Public Const foo = 123
Public bar As String

Public Sub DoSomething()
    ' some code
End Sub

' ...
' 10K more lines of code
' ...

Private Function GetSomething() As String
     ' some code 
End Function

I would like the tree walker to stop walking the parse tree as soon as it enters Public Sub DoSomething(), for I'm not interested in anything below that. Currently I'm walking the entire parse tree, just not doing anything with whatever I pick up within a procedure scope.

Is there a way, from within a parse tree listener implementation, to tell the walker to stop walking the tree?

like image 639
Mathieu Guindon Avatar asked Feb 15 '15 17:02

Mathieu Guindon


1 Answers

Yes, you can do either of the following:

  1. Throw an exception, such as a CancellationException
  2. Create a new class which extends ParseTreeWalker, and provide your own implementation of walk which understands the cancellation concept you need. It would make sense to start with the current implementation of walk and modify it to meet your needs.
like image 144
Sam Harwell Avatar answered Nov 07 '22 23:11

Sam Harwell