Can a walker be stopped?
Asked Answered
J

1

11

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?

Johnathon answered 15/2, 2015 at 17:42 Comment(1)
Well I guess I could throw an exception and that would possibly kill the walker. But I'd like a non-violent way if possible :)Johnathon
P
5

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.
Primo answered 15/2, 2015 at 23:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.