package com.chrisfolger.needsmoredojo.intellij.inspections;
import com.chrisfolger.needsmoredojo.core.amd.define.DefineResolver;
import com.chrisfolger.needsmoredojo.core.amd.filesystem.DojoModuleFileResolver;
import com.chrisfolger.needsmoredojo.core.amd.filesystem.SourcesLocator;
import com.chrisfolger.needsmoredojo.core.amd.naming.NameResolver;
import com.chrisfolger.needsmoredojo.core.amd.objectmodel.cycledetection.CyclicDependencyDetector;
import com.chrisfolger.needsmoredojo.core.amd.objectmodel.cycledetection.DependencyNode;
import com.chrisfolger.needsmoredojo.core.amd.objectmodel.cycledetection.DetectionResult;
import com.intellij.codeInspection.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
public class CyclicDependencyInspection extends DojoInspection
{
private CyclicDependencyDetector detector;
@Override
public String getDisplayName()
{
return "Check for cyclic dependencies in AMD modules";
}
@Override
public boolean isEnabledByDefault()
{
return false;
}
@Override
public String getShortName()
{
return "CyclicDependencyInspection";
}
@Nullable @Override
public String getStaticDescription() {
return "Detects potential cycles on the current file. Cyclic dependencies in dojo can cause obscure bugs if not accounted for. This inspection is "
+ "disabled by default.";
}
@Nls
@NotNull
@Override
public String getGroupDisplayName()
{
return "Needs More Dojo";
}
@Override
public String[] getGroupPath()
{
return new String[] { "JavaScript", "Needs More Dojo "};
}
@Override
public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull final InspectionManager manager, boolean isOnTheFly)
{
if(!isEnabled(file.getProject()))
{
return new ProblemDescriptor[0];
}
if(detector == null || isOnTheFly)
{
detector = new CyclicDependencyDetector();
}
final List<ProblemDescriptor> descriptors = new ArrayList<ProblemDescriptor>();
DependencyNode cycle = detector.addDependenciesOfFile(file, file.getProject(), file, null, null, false);
if(cycle != null)
{
DetectionResult cycleDetectionResult = detector.getCycleDetectionResult(cycle);
DefineResolver resolver = new DefineResolver();
final List<PsiElement> parameters = new ArrayList<PsiElement>();
final List<PsiElement> defines = new ArrayList<PsiElement>();
resolver.gatherDefineAndParameters(file, defines, parameters);
for(PsiElement define : defines)
{
if(cycleDetectionResult.getLastDependency() != null && define.getText().equals(cycleDetectionResult.getLastDependency().getModulePath()))
{
LocalQuickFix fix = null;
descriptors.add(manager.createProblemDescriptor(define, "A cyclic dependency exists with the path: \n" + cycleDetectionResult.getCyclePath(), fix, ProblemHighlightType.GENERIC_ERROR, true));
}
}
}
return descriptors.toArray(new ProblemDescriptor[0]);
}
}