package org.radrails.rails.internal.parser.warnings;
import org.jruby.ast.CallNode;
import org.jruby.ast.ClassNode;
import org.jruby.ast.ConstNode;
import org.jruby.ast.FCallNode;
import org.jruby.ast.Node;
import org.jruby.ast.RootNode;
import org.jruby.ast.VCallNode;
import org.jruby.ast.types.INameNode;
import org.radrails.rails.core.IDeprecationProblems;
import org.radrails.rails.internal.core.RailsPlugin;
import org.rubypeople.rdt.core.parser.warnings.RubyLintVisitor;
import org.rubypeople.rdt.internal.core.util.ASTUtil;
public class DeprecatedActiveRecordFindMethods extends RubyLintVisitor {
private static final String ACTIVE_RECORD_BASE = "ActiveRecord::Base";
private static final String[] DEPRECATED = new String[] { "find_first",
"find_all" };
private static final String[] SOLUTIONS = new String[] { "find(:first)",
"find(:all)" };
private boolean inActiveRecord;
public DeprecatedActiveRecordFindMethods() {
super(RailsPlugin.getInstance().getOptions(), "");
}
@Override
protected int getProblemID() {
return IDeprecationProblems.DeprecatedARFindCalls;
}
@Override
protected String getOptionKey() {
return RailsPlugin.RAILS_DEPRECATION_ACTIVE_RECORD_FIND_METHODS;
}
@Override
public Object visitRootNode(RootNode visited)
{
inActiveRecord = false;
return super.visitRootNode(visited);
}
@Override
public Object visitCallNode(CallNode iVisited) {
String name = iVisited.getName();
for (int i = 0; i < DEPRECATED.length; i++) {
if (!name.equals(DEPRECATED[i]))
continue;
Node receiver = iVisited.getReceiverNode();
if (receiver instanceof ConstNode) {
createProblem(iVisited.getPosition(), "Deprecated method, use "
+ SOLUTIONS[i] + " instead");
break;
}
}
return super.visitCallNode(iVisited);
}
@Override
public Object visitClassNode(ClassNode iVisited) {
Node superNode = iVisited.getSuperNode();
String superName = ASTUtil.getSuperClassName(superNode);
if (superName != null && superName.equals(ACTIVE_RECORD_BASE)) {
inActiveRecord = true;
}
return super.visitClassNode(iVisited);
}
@Override
public void exitClassNode(ClassNode iVisited) {
inActiveRecord = false;
super.exitClassNode(iVisited);
}
@Override
public Object visitVCallNode(VCallNode iVisited) {
checkForDeprecatedCalls(iVisited);
return super.visitVCallNode(iVisited);
}
@Override
public Object visitFCallNode(FCallNode iVisited) {
checkForDeprecatedCalls(iVisited);
return super.visitFCallNode(iVisited);
}
private void checkForDeprecatedCalls(INameNode iVisited) {
if (!inActiveRecord) return;
if (iVisited == null) return;
String name = iVisited.getName();
if (name == null || name.trim().length() == 0) return;
for (int i = 0; i < DEPRECATED.length; i++) {
if (!name.equals(DEPRECATED[i]))
continue;
createProblem(((Node)iVisited).getPosition(), "Deprecated method, use " + SOLUTIONS[i] + " instead");
break;
}
}
}