From bacc781ea755d3771e1c8d09e1fbfd873872f750 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 15 Nov 2015 15:31:09 +0000 Subject: Allow descendants of nodes to be traversed --- .../couscous/ast/structure/NodeStructure.java | 138 +++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java (limited to 'src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java') diff --git a/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java b/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java new file mode 100644 index 0000000..5fdd505 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java @@ -0,0 +1,138 @@ +package org.zwobble.couscous.ast.structure; + +import org.zwobble.couscous.ast.*; +import org.zwobble.couscous.ast.visitors.NodeMapper; + +import java.util.stream.Stream; + +import static org.zwobble.couscous.util.ExtraStreams.concatStreams; + +public class NodeStructure { + public static Stream descendantNodesAndSelf(Node node) { + return Stream.concat(Stream.of(node), descendantNodes(node)); + } + + public static Stream descendantNodes(Node node) { + return childNodes(node).flatMap(NodeStructure::descendantNodesAndSelf); + } + + public static Stream childNodes(Node node) { + return node.accept(new NodeMapper>() { + @Override + public Stream visit(LiteralNode literal) { + return Stream.empty(); + } + + @Override + public Stream visit(VariableReferenceNode variableReference) { + return Stream.empty(); + } + + @Override + public Stream visit(ThisReferenceNode reference) { + return Stream.empty(); + } + + @Override + public Stream visit(AssignmentNode assignment) { + return Stream.of(assignment.getValue(), assignment.getTarget()); + } + + @Override + public Stream visit(TernaryConditionalNode ternaryConditional) { + return Stream.of( + ternaryConditional.getCondition(), + ternaryConditional.getIfTrue(), + ternaryConditional.getIfFalse()); + } + + @Override + public Stream visit(MethodCallNode methodCall) { + return Stream.concat( + Stream.of(methodCall.getReceiver()), + methodCall.getArguments().stream()); + } + + @Override + public Stream visit(StaticMethodCallNode staticMethodCall) { + return staticMethodCall.getArguments().stream(); + } + + @Override + public Stream visit(ConstructorCallNode call) { + return call.getArguments().stream(); + } + + @Override + public Stream visit(FieldAccessNode fieldAccess) { + return Stream.of(fieldAccess.getLeft()); + } + + @Override + public Stream visit(ReturnNode returnNode) { + return Stream.of(returnNode.getValue()); + } + + @Override + public Stream visit(ExpressionStatementNode expressionStatement) { + return Stream.of(expressionStatement.getExpression()); + } + + @Override + public Stream visit(LocalVariableDeclarationNode localVariableDeclaration) { + return Stream.of(localVariableDeclaration.getInitialValue()); + } + + @Override + public Stream visit(IfStatementNode ifStatement) { + return concatStreams( + Stream.of(ifStatement.getCondition()), + ifStatement.getTrueBranch().stream(), + ifStatement.getFalseBranch().stream()); + } + + @Override + public Stream visit(WhileNode whileLoop) { + return Stream.concat( + Stream.of(whileLoop.getCondition()), + whileLoop.getBody().stream()); + } + + @Override + public Stream visit(FormalArgumentNode formalArgumentNode) { + return Stream.empty(); + } + + @Override + public Stream visit(AnnotationNode annotation) { + return Stream.empty(); + } + + @Override + public Stream visit(ClassNode classNode) { + return concatStreams( + Stream.of(classNode.getConstructor()), + classNode.getFields().stream(), + classNode.getMethods().stream()); + } + + @Override + public Stream visit(MethodNode methodNode) { + return concatStreams( + methodNode.getAnnotations().stream(), + methodNode.getArguments().stream(), + methodNode.getBody().stream()); + } + + @Override + public Stream visit(ConstructorNode constructorNode) { + return Stream.concat(constructorNode.getArguments().stream(), constructorNode.getBody().stream()); + } + + @Override + public Stream visit(FieldDeclarationNode declaration) { + return Stream.empty(); + } + }); + } +} -- cgit v1.2.3