package com.aptana.rdt.internal.parser.warnings;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.jruby.ast.Node;
import org.rubypeople.rdt.core.IRubyModelMarker;
import org.rubypeople.rdt.core.IRubyProject;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.core.compiler.BuildContext;
import org.rubypeople.rdt.core.compiler.CategorizedProblem;
import org.rubypeople.rdt.core.compiler.CompilationParticipant;
import org.rubypeople.rdt.core.compiler.ReconcileContext;
import org.rubypeople.rdt.core.parser.warnings.RubyLintVisitor;
import com.aptana.rdt.AptanaRDTPlugin;
public class RubyRedLint extends CompilationParticipant
{
@Override
public void reconcile(ReconcileContext context)
{
try
{
List<CategorizedProblem> problems = handleFile(context.getWorkingCopy().getElementName(), context
.getWorkingCopy().getSource(), context.getAST());
addProblems(context, IRubyModelMarker.RUBY_MODEL_PROBLEM_MARKER, problems);
}
catch (RubyModelException e)
{
AptanaRDTPlugin.log(e);
}
}
private List<CategorizedProblem> handleFile(String name, String contents, Node ast)
{
if (ast == null)
return Collections.emptyList();
List<RubyLintVisitor> visitors = createLintVisitors(contents);
List<CategorizedProblem> problems = new ArrayList<CategorizedProblem>();
for (RubyLintVisitor visitor : visitors)
{
ast.accept(visitor);
problems.addAll(visitor.getProblems());
}
return problems;
}
@Override
public void buildStarting(BuildContext[] files, boolean isBatch, IProgressMonitor monitor)
{
SubMonitor sub = SubMonitor.convert(monitor, files.length);
for (BuildContext context : files)
{
sub.subTask("Parsing and analyzing " + context.getFile().getLocation().toPortableString());
String contents = new String(context.getContents());
List<CategorizedProblem> problems = handleFile(context.getFile().getName(), contents, context.getAST());
context.recordNewProblems(problems.toArray(new CategorizedProblem[problems.size()]));
sub.worked(1);
}
sub.done();
}
@Override
public boolean isActive(IRubyProject project)
{
return true;
}
private List<RubyLintVisitor> createLintVisitors(String contents)
{
List<RubyLintVisitor> visitors = new ArrayList<RubyLintVisitor>();
visitors.add(new AccidentalBooleanAssignmentVisitor(contents));
visitors.add(new UnusedPrivateMethodVisitor(contents));
visitors.add(new MisspelledConstructorVisitor(contents));
visitors.add(new LocalsMaskingMethodsVisitor(contents));
visitors.add(new UnusedParameterVisitor(contents));
visitors.add(new UnecessaryElseVisitor(contents));
visitors.add(new TooManyLocalsVisitor(contents));
visitors.add(new TooManyLinesVisitor(contents));
visitors.add(new TooManyBranchesVisitor(contents));
visitors.add(new TooManyArgumentsVisitor(contents));
visitors.add(new TooManyReturnsVisitor(contents));
visitors.add(new SimilarVariableNameVisitor(contents));
visitors.add(new SubclassCallsSuper(contents));
visitors.add(new ComparableInclusionVisitor(contents));
visitors.add(new EnumerableInclusionVisitor(contents));
visitors.add(new AndOrUsedOnRighthandAssignment(contents));
visitors.add(new ConstantNamingConvention(contents));
visitors.add(new MethodMissingWithoutRespondTo(contents));
visitors.add(new DynamicVariableAliasesLocal(contents));
visitors.add(new LocalVariablePossibleAttributeAccess(contents));
visitors.add(new LocalAndMethodNamingConvention(contents));
visitors.add(new UnusedLocalVariable(contents));
visitors.add(new RequireGemChecker(contents));
visitors.add(new RetryOutsideRescueBodyChecker(contents));
visitors.add(new DuplicateHashKeyVisitor(contents));
visitors.add(new ControlCouple(contents));
visitors.add(new FeatureEnvy(contents));
List<RubyLintVisitor> filtered = new ArrayList<RubyLintVisitor>();
for (RubyLintVisitor visitor : visitors)
{
if (visitor.isIgnored())
continue;
filtered.add(visitor);
}
return filtered;
}
}