Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[Dltk-dev] Extending AST classes plus ASTNode.traverse template

Our project includes classes which extend your AST classes.

The issue we just discovered is how you handle the visitor pattern.

Here's an example in the class MethodDeclaration:


	public void traverse(ASTVisitor visitor) throws Exception {

		if (visitor.visit(this)) {
			// Deocrators
			if (this.decorators != null) {
				if (this.decorators != null) {
					Iterator it = this.decorators.iterator();
					while (it.hasNext()) {
						Decorator dec = (Decorator) it.next();
						dec.traverse(visitor);
					}
				}
			}

			// Arguments
			if (this.arguments != null) {
				Iterator it = this.arguments.iterator();
				while (it.hasNext()) {
					Argument arg = (Argument) it.next();
					arg.traverse(visitor);
				}
			}

			// Body
			if (this.body != null) {
				this.body.traverse(visitor);
			}

			visitor.endvisit(this);
		}
	}

Our child class adds a few new child ASTNode objects. Here's an example class:

public class MyNode extends ASTNode {
}

public class MyMethodDeclaration extends MethodDeclaration {

private MyNode m_myNode;

	public void traverse(ASTVisitor visitor) throws Exception {

		if (visitor.visit(this)) {

			if (this.m_myNode != null) {
				this.m_myNode.traverse(visitor);
			}

			visitor.endvisit(this);
		}
	}
}

On the surface - this looks fine - except it never traverses the child nodes from the super class object.

How could it do that?

Ideally, you would add a method traverseChildNodes, like this:

	public traverseChildNodes(ASTVisitor visitor) throws Exception {
			// Deocrators
			if (this.decorators != null) {
				if (this.decorators != null) {
					Iterator it = this.decorators.iterator();
					while (it.hasNext()) {
						Decorator dec = (Decorator) it.next();
						dec.traverse(visitor);
					}
				}
			}

			// Arguments
			if (this.arguments != null) {
				Iterator it = this.arguments.iterator();
				while (it.hasNext()) {
					Argument arg = (Argument) it.next();
					arg.traverse(visitor);
				}
			}

			// Body
			if (this.body != null) {
				this.body.traverse(visitor);
			}
}

Then, I could add my own traverseChildNodes method:

	public traverseChildNodes(ASTVisitor visitor) throws Exception {
		super.traverseChildNodes(visitor);
		if (this.m_myNode != null) {
			this.m_myNode.traverse(visitor);
		}
	}

In the absence of this - could you make the data members of each ASTNode protected instead of private?

Thanks,
Chuck


Back to the top