rubberduck-vba / Rubberduck

Every programmer needs a rubberduck. COM add-in for the VBA & VB6 IDE (VBE).
https://rubberduckvba.com
GNU General Public License v3.0
1.88k stars 299 forks source link

Run Rubberduck parser at the command line #803

Open dfinke opened 8 years ago

dfinke commented 8 years ago

I'd like to wire up Rubberduck in PowerShell so I can pass in a .bas file and parse it.

I only did a quick scan of the code and it look like it will only run in Excel. Is this true?

Would it be easy to refactor the code to pass in a string of VBA and have it return the parsed results?

retailcoder commented 8 years ago

It will indeed only run within a VBE environment. The RubberduckParser has a (IIRC) private method that returns the raw ANTLR parse tree off a string, I guess you could tweak it a bit and work off that... although I don't think it's particularly useful on its own...

dfinke commented 8 years ago

Thanks, I'm looking to get a collection of tokens from the parser, preferably in the context of the VBA. I'll take a look.

rubberduck203 commented 8 years ago

@retailcoder, couldn't we get the same parse tree through AntlrWorks? IIRC the RubberduckParser itself is just to simplify hooking into the IDE to get the code. Or is it doing more work than I realize?

retailcoder commented 8 years ago

@ckuhn203 The IRubberduckParser interface is designed to work off a VBProject COM object, and return a VBProjectParseResult object which translates specific tokens into Declaration objects, with their references resolved, including references to built-in / standard library declarations.

Indeed, @dfinke is probably better off just grabbing the VBA.g4 grammar file and working with that, although the raw ANTLR parse tree is a royal PITA to work with; without things like tree walkers and listeners, you would be constantly reinventing the wheel and writing very convoluted code just to get basic things like the names of the procedures in a module.

Depends on exactly what you're trying to achieve.

retailcoder commented 8 years ago

Ah, here's the method in question - turns out it's public, but not exposed by the IRubberduckParser interface:

    public IParseTree Parse(string code, out ITokenStream outStream)
    {
        var input = new AntlrInputStream(code);
        var lexer = new VBALexer(input);
        var tokens = new CommonTokenStream(lexer);
        var parser = new VBAParser(tokens);
        parser.AddErrorListener(new ExceptionErrorListener());
        outStream = tokens;

        var result = parser.startRule();
        return result;
    }

The out parameter is used for creating a TokenStreamRewriter which we use in the rename refactoring; classes VBALexer and VBAParser are generated by ANTLR when we process the VBA.g4 grammar file.

The ExceptionErrorListener is a little class that we use to throw a specific exception to better log and report parsing exceptions thrown when giving the parser invalid syntax:

public class ExceptionErrorListener : BaseErrorListener
{
    public override void SyntaxError(IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
    {
        // adding 1 to line, because line is 0-based, but it's 1-based in the VBE
        throw new SyntaxErrorException(msg, e, offendingSymbol, line, charPositionInLine + 1);
    }
}

And I have misleading comments to update :wink:

retailcoder commented 7 years ago

Food for thought: Seeing how http://rubberduckvba.com is now able to run a RD build and inspect code online, I'm pretty sure at this point it would be possible and relatively easy to create a console application that references a RD build and inspect code from the file system; the "client" application has access to the ParserState and all the Declaration instances, as well as the IParseTree's - I'm pretty sure it's possible to implement this, against the 2.0.10 build.

rubberduck203 commented 7 years ago

If there's still interest in this, I wouldn't mind reopening it with an "up-for-grabs" label. I can see how it may be a useful feature, I just question how much demand there is for it.

retailcoder commented 7 years ago

@ckuhn203 I'm considering creating a RD-Console repo just for the heck of it.

PeterMTaylor commented 7 years ago

I was thinking could it be possible to have this command prompt evaluated via appveyor when loading in VBA code triggered by GitHub that uses the latest RD inspections with a test section enabled. This feature is the same way as proof of concept by inspections heading of the webpage.

rubberduck203 commented 7 years ago

I have to admit that'd be pretty cool @PeterMTaylor.