package com.aptana.rdt.internal.parser.warnings;
import org.jruby.ast.ArrayNode;
import org.jruby.ast.ClassNode;
import org.jruby.ast.ConstNode;
import org.jruby.ast.DefnNode;
import org.jruby.ast.FCallNode;
import org.jruby.ast.Node;
import org.jruby.lexer.yacc.ISourcePosition;
import org.rubypeople.rdt.core.parser.warnings.RubyLintVisitor;
import com.aptana.rdt.AptanaRDTPlugin;
import com.aptana.rdt.IProblem;
public class EnumerableInclusionVisitor extends RubyLintVisitor {
private static final String INCLUDE = "include";
private static final String ENUMERABLE_METHOD = "each";
private static final String ENUMERABLE = "Enumerable";
private boolean includedEnumerable = false;
private boolean definedEnumerableMethod;
private ISourcePosition pos;
public EnumerableInclusionVisitor(String code) {
super(AptanaRDTPlugin.getDefault().getOptions(), code);
}
@Override
protected String getOptionKey() {
return AptanaRDTPlugin.COMPILER_PB_ENUMERABLE_MISSING_METHOD;
}
@Override
public Object visitFCallNode(FCallNode iVisited) {
if (includedEnumerable) return null;
String callName = iVisited.getName();
if (!callName.equals(INCLUDE))
return null;
Node args = iVisited.getArgsNode();
if (args instanceof ArrayNode) {
ArrayNode array = (ArrayNode) args;
for (Object arg : array.childNodes()) {
if (!(arg instanceof ConstNode))
continue;
ConstNode constNode = (ConstNode) arg;
if (!(constNode.getName().equals(ENUMERABLE)))
continue;
pos = constNode.getPosition();
includedEnumerable = true;
return null;
}
}
return null;
}
@Override
public Object visitDefnNode(DefnNode iVisited) {
String methodName = iVisited.getName();
if (methodName.equals(ENUMERABLE_METHOD)) {
definedEnumerableMethod = true;
}
return super.visitDefnNode(iVisited);
}
@Override
public void exitClassNode(ClassNode iVisited) {
if (includedEnumerable && !definedEnumerableMethod) {
createProblem(pos, "Included Enumerable but did not define an each method");
}
includedEnumerable = false;
pos = null;
definedEnumerableMethod = false;
}
@Override
protected int getProblemID() {
return IProblem.EnumerableInclusionMissingEachMethod;
}
}