question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

API changes: extend visitor with return values

See original GitHub issue

If you try to build a CopyVisitor of some kind of object hierarchy, one has to build some kind of Stack structure, to give the actual visitor a hint, where it should write its copied data.

I suggest to extend all visitor methods with a return value:

MyType visitor(MyType param);

The standard implementation should return the actual object inserted.

public interface StatementVisitor {
    Comment visit(Comment comment);
    Commit visit(Commit commit);
    Delete visit(Delete delete);
    Update visit(Update update);

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:2
  • Comments:19 (17 by maintainers)

github_iconTop GitHub Comments

3reactions
SerialVelocitycommented, Feb 10, 2020

I agree with @sivaraam but would go one step further and make the extra visitor generic:

public <T> T accept(Generic*Visitor<T> visitor);

This would:

  • Allow CopyVisitor to be written. Each visitor would be allowed to have its own type so you can have implements GenericStatementVisitor<Statement>, GenericExpressionVisitor<Expression>, etc.
  • Allow custom types to be returned too. e.g. the TableVisitor could have T set to List<TableName> (this has the added benefit of easily making the class thread-safe because you no longer have a field lying around).
1reaction
lalithsureshcommented, Nov 25, 2020

To add to what @SerialVelocity suggested:

I really like the Presto parser API. For example, I have some code where I am converting from SQL to a datalog dialect, and this is one example of how I use the Presto API to do so.


    /*
     * Translates literals into corresponding DDlogRecord instances
     */
    private static class ParseLiterals extends AstVisitor<DDlogRecord, Boolean> {

        @Override
        protected DDlogRecord visitStringLiteral(final StringLiteral node, final Boolean isNullable) {
            try {
                return maybeOption(isNullable, new DDlogRecord(node.getValue()));
            } catch (final DDlogException e) {
                throw new RuntimeException(e);
            }
        }

        @Override
        protected DDlogRecord visitLongLiteral(final LongLiteral node, final Boolean isNullable) {
            return maybeOption(isNullable, new DDlogRecord(node.getValue()));
        }

        @Override
        protected DDlogRecord visitBooleanLiteral(final BooleanLiteral node, final Boolean isNullable) {
            return maybeOption(isNullable, new DDlogRecord(node.getValue()));
        }
    }

And elsewhere, I can do this:

// later, in some method
DDLogRecord record = parseLiterals.process(literal, isNullable);

Note that the visit methods can receive a context and a return value, both of which are generic types parameterized by AstVisitor<X, Y>. And in the above case, the ParseLiterals class is purely stateless (so I can re-use a single instance for the lifetime of my program).

I’ve been trying out the JSQLParser API simply because Presto is an odd SQL dialect and doesn’t support some statements I need. But writing something like the above becomes cumbersome. The return values and the context I pass through the visitors (generic parameters X and Y) now become fields.

Here’s the AstVisitor implementation in Presto: https://github.com/prestodb/presto/blob/master/presto-parser/src/main/java/com/facebook/presto/sql/tree/AstVisitor.java

Read more comments on GitHub >

github_iconTop Results From Across the Web

java - Return a value from Visitor - Stack Overflow
Suppose we have following classes which we can't change: interface Base { ...
Read more >
Visitor Design Pattern in C# - Code Maze
The Visitor pattern allows decoupling algorithms from the objects on which they operate. It allows adding and changing functionalities in a ...
Read more >
Interface AnnotationValueVisitor<R,P> - Oracle Help Center
Classes implementing this interface are used to operate on a value when the type of that value is unknown at compile time. When...
Read more >
Visitor Design Pattern in Java - DigitalOcean
Visitor pattern is used when we have to perform an operation on a group of similar kind of Objects. With the help of...
Read more >
Extending the REST API (REST Application Developer's Guide)
Your extension can return JavaScript objects and XML, JSON, text, or binary document nodes. A JavaScript object is serialized as JSON before returning...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found