package org.rubypeople.rdt.internal.core.parser.warnings; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.jruby.ast.ClassNode; import org.jruby.ast.ConstDeclNode; import org.jruby.ast.ModuleNode; import org.rubypeople.rdt.core.RubyCore; import org.rubypeople.rdt.core.parser.warnings.RubyLintVisitor; import org.rubypeople.rdt.internal.core.util.ASTUtil; public class ConstantReassignmentVisitor extends RubyLintVisitor { private Set<String> assignedConstants; private List<String> namespace; public ConstantReassignmentVisitor(String contents) { super(contents); assignedConstants = new HashSet<String>(); namespace = new ArrayList<String>(); } @Override protected String getOptionKey() { return RubyCore.COMPILER_PB_CONSTANT_REASSIGNMENT; } public Object visitConstDeclNode(ConstDeclNode iVisited) { String name; if (iVisited.getConstNode() != null) { name = ASTUtil.getFullyQualifiedName(iVisited.getConstNode()); } else { name = getNamespace() + iVisited.getName(); } if (assignedConstants.contains(name)) createProblem(iVisited.getPosition(), "Reassignment of a constant"); else assignedConstants.add(name); return super.visitConstDeclNode(iVisited); } @Override public Object visitClassNode(ClassNode visited) { namespace.add(ASTUtil.getFullyQualifiedName(visited.getCPath())); Object ret = super.visitClassNode(visited); namespace.remove(namespace.size() - 1); return ret; } @Override public Object visitModuleNode(ModuleNode visited) { namespace.add(ASTUtil.getFullyQualifiedName(visited.getCPath())); Object ret = super.visitModuleNode(visited); namespace.remove(namespace.size() - 1); return ret; } private String getNamespace() { StringBuilder builder = new StringBuilder(); for (String portion : namespace) { builder.append(portion).append("::"); } return builder.toString(); } }