package sk.stuba.fiit.perconik.core.java.dom; import java.nio.file.Path; import java.nio.file.Paths; import com.google.common.base.Function; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; import sk.stuba.fiit.perconik.eclipse.jdt.core.dom.NodeType; public class NodePaths { static final String unknownPathName = "_"; static final String variableSeparator = ","; static final Path singleUnknownPath = Paths.get(unknownPathName); private static final NodePathExtractor<?> namePathExtractor = NodePathExtractor.using(PathNameStrategy.NAME); private static final NodePathExtractor<?> typePathExtractor = NodePathExtractor.using(PathNameStrategy.TYPE); private NodePaths() {} public static String unknownPathName() { return unknownPathName; } public static String variableSeparator() { return variableSeparator; } private enum PathNameStrategy implements Function<ASTNode, String> { NAME { public String apply(final ASTNode node) { if (node == null) { return unknownPathName; } for (StructuralPropertyDescriptor descriptor: Nodes.structuralProperties(node)) { if (descriptor.getId().equals("name")) { return node.getStructuralProperty(descriptor).toString(); } } return unknownPathName; } @Override public String toString() { return "name"; } }, TYPE { public String apply(final ASTNode node) { return node != null ? NodeType.valueOf(node).getName() : unknownPathName; } @Override public String toString() { return "type"; } }; } private static <N extends ASTNode> NodePathExtractor<N> cast(final NodePathExtractor<?> extractor) { // only for stateless internal singletons shared across all types @SuppressWarnings("unchecked") NodePathExtractor<N> result = (NodePathExtractor<N>) extractor; return result; } public static <N extends ASTNode> NodePathExtractor<N> namePathExtractor() { return cast(namePathExtractor); } public static <N extends ASTNode> NodePathExtractor<N> typePathExtractor() { return cast(typePathExtractor); } }