package org.radrails.rails.internal.ui.text;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jruby.ast.ArrayNode;
import org.jruby.ast.FCallNode;
import org.jruby.ast.Node;
import org.jruby.ast.RootNode;
import org.rubypeople.rdt.core.Flags;
import org.rubypeople.rdt.core.IMethod;
import org.rubypeople.rdt.internal.core.parser.InOrderVisitor;
import org.rubypeople.rdt.internal.core.util.ASTUtil;
public class ActiveRecordAssociationsVisitor extends InOrderVisitor {
private List<IMethod> methods = new ArrayList<IMethod>();
/**
* Names of methods which mark associations
*/
private static Set<String> associationMethodNames = new HashSet<String>();
private static Set<String> multiAssociationMethodNames = new HashSet<String>();
private static Set<String> singularAssociationMethodNames = new HashSet<String>();
static {
singularAssociationMethodNames.add("belongs_to");
singularAssociationMethodNames.add("has_one");
multiAssociationMethodNames.add("has_many");
multiAssociationMethodNames.add("has_and_belongs_to_many");
associationMethodNames.addAll(singularAssociationMethodNames);
associationMethodNames.addAll(multiAssociationMethodNames);
}
public List<IMethod> getMethods() {
return methods;
}
@Override
public Object visitRootNode(RootNode iVisited) {
methods.clear();
return super.visitRootNode(iVisited);
}
@Override
public Object visitFCallNode(FCallNode iVisited) {
if (associationMethodNames.contains(iVisited.getName())) {
ArrayNode args = (ArrayNode) iVisited.getArgsNode();
Node firstArg = args.get(0);
String modelName = ASTUtil.stringRepresentation(firstArg);
if (multiAssociationMethodNames.contains(iVisited.getName())) {
methods.add(new PsuedoMethod(modelName, new String[0], Flags.AccPublic));
} else {
// belongs_to and has_one
methods.add(new PsuedoMethod(modelName, new String[0], Flags.AccPublic));
methods.add(new PsuedoMethod(modelName + "=", new String[] {modelName}, Flags.AccPublic));
}
}
return super.visitFCallNode(iVisited);
}
}