package com.aptana.rdt.internal.rake; import java.util.ArrayList; import java.util.List; import org.jruby.ast.ArrayNode; import org.jruby.ast.CallNode; import org.jruby.ast.FCallNode; import org.jruby.ast.HashNode; import org.jruby.ast.IArgumentNode; import org.jruby.ast.Node; import org.jruby.ast.RootNode; import org.jruby.ast.StrNode; import org.rubypeople.rdt.internal.core.parser.InOrderVisitor; import org.rubypeople.rdt.internal.core.util.ASTUtil; public class RakeStructureCreator extends InOrderVisitor { private static final String TASK = "task"; private static final String NAMESPACE = "namespace"; private List<Namespace> namespaces = new ArrayList<Namespace>(); public Object visitFCallNode(FCallNode visited) { if (visited.getName().equals(TASK)) { // start of a task String name = getFirstArgument(visited); Task task = new Task(name, getStart(visited), getLength(visited)); Namespace curNamespace = namespaces.get(namespaces.size() - 1); curNamespace.addChild(task); } else if (visited.getName().equals(NAMESPACE)) { String namespaceName = getFirstArgument(visited); Namespace namespace = new Namespace(namespaceName, getStart(visited), getLength(visited)); Namespace curNamespace = namespaces.get(namespaces.size() - 1); curNamespace.addChild(namespace); namespaces.add(namespace); Object ins = super.visitFCallNode(visited); namespaces.remove(namespaces.size() - 1); return ins; } return super.visitFCallNode(visited); } public Object visitCallNode(CallNode visited) { if (visited.getName().equals("new")) { String receiver = ASTUtil.stringRepresentation(visited .getReceiverNode()); if (receiver.equals("TestTask") || receiver.equals("RDocTask")) { String name = getFirstArgument(visited); Task task = new Task(name, getStart(visited), getLength(visited)); Namespace curNamespace = namespaces.get(namespaces.size() - 1); curNamespace.addChild(task); } } return super.visitCallNode(visited); } private String getFirstArgument(IArgumentNode visited) { List<String> args = ASTUtil.getArgumentsFromFunctionCall(visited); Node arguments = visited.getArgsNode(); String name = args.get(0); if (arguments instanceof ArrayNode) { ArrayNode array = (ArrayNode) arguments; Node firstArg = array.get(0); if (firstArg instanceof HashNode) { HashNode hash = (HashNode) firstArg; Node firstHashMember = hash.getListNode().get(0); name = ASTUtil.getNameReflectively(firstHashMember); } if (firstArg instanceof StrNode) { name = ((StrNode)firstArg).getValue().toString(); } else { String newName = ASTUtil.getNameReflectively(firstArg); if (newName != null) { name = newName; } } } return name; } public Object visitRootNode(RootNode visited) { namespaces.add(new Namespace("ROOT", getStart(visited), getLength(visited))); return super.visitRootNode(visited); } private int getLength(Node visited) { return getEnd(visited) - getStart(visited) + 1; } private int getEnd(Node visited) { return visited.getPosition().getEndOffset(); } private int getStart(Node visited) { return visited.getPosition().getStartOffset(); } public Object[] getTasks() { return namespaces.get(namespaces.size() - 1).getChildren(); } }