package sk.stuba.fiit.perconik.core.java.dom; import javax.annotation.Nullable; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.Multimap; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTVisitor; import sk.stuba.fiit.perconik.eclipse.jdt.core.dom.NodeType; import sk.stuba.fiit.perconik.utilities.function.MultimapCollector; public final class NodeTypeDivider<N extends ASTNode> implements MultimapCollector<N, NodeType, ASTNode> { private static final NodeTypeDivider<ASTNode> instance = new NodeTypeDivider<>(); NodeTypeDivider() {} public static <N extends ASTNode> NodeTypeDivider<N> create() { // stateless internal singleton is shared across all types @SuppressWarnings("unchecked") NodeTypeDivider<N> casted = (NodeTypeDivider<N>) instance; return casted; } public Multimap<NodeType, ASTNode> apply(final N node) { return new Processor().perform(node); } private final class Processor extends ASTVisitor { final Multimap<NodeType, ASTNode> result; Processor() { super(true); this.result = LinkedListMultimap.create(NodeType.count()); } Multimap<NodeType, ASTNode> perform(@Nullable final N node) { if (node == null) { return ImmutableMultimap.of(); } node.accept(this); return this.result; } @Override public void preVisit(final ASTNode node) { this.result.put(NodeType.valueOf(node), node); } } @Override public boolean equals(@Nullable final Object o) { return o == this; } @Override public int hashCode() { return super.hashCode(); } @Override public String toString() { return "divider"; } }