package fr.adrienbrault.idea.symfony2plugin.routing; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.ide.highlighter.XmlFileType; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiRecursiveElementWalkingVisitor; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.indexing.FileBasedIndex; import com.jetbrains.php.lang.PhpFileType; import com.jetbrains.php.lang.psi.elements.StringLiteralExpression; import fr.adrienbrault.idea.symfony2plugin.Settings; import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent; import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.AnnotationRoutesStubIndex; import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.RoutesStubIndex; import fr.adrienbrault.idea.symfony2plugin.util.MethodMatcher; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.yaml.YAMLFileType; import java.util.Collection; import java.util.Map; /** * @author Daniel Espendiller <daniel@espendiller.net> */ public class PhpRouteInspection extends LocalInspectionTool { @NotNull @Override public PsiElementVisitor buildVisitor(final @NotNull ProblemsHolder holder, boolean isOnTheFly) { PsiFile psiFile = holder.getFile(); if(!Symfony2ProjectComponent.isEnabled(psiFile.getProject()) || !Settings.getInstance(psiFile.getProject()).phpAnnotateRoute) { return super.buildVisitor(holder, isOnTheFly); } psiFile.acceptChildren(new PsiRecursiveElementWalkingVisitor() { @Override public void visitElement(PsiElement element) { if(element instanceof StringLiteralExpression) { annotate((StringLiteralExpression) element, holder); } super.visitElement(element); } }); return super.buildVisitor(holder, isOnTheFly); } public void annotate(@NotNull final StringLiteralExpression element, @NotNull ProblemsHolder holder) { String routeName = element.getContents(); if(StringUtils.isBlank(routeName)) { return; } MethodMatcher.MethodMatchParameter methodMatchParameter = new MethodMatcher.StringParameterMatcher(element, 0) .withSignature(PhpRouteReferenceContributor.GENERATOR_SIGNATURES) .match(); if(methodMatchParameter == null) { return; } annotateRouteName(element, holder, routeName); } public static void annotateRouteName(PsiElement target, @NotNull ProblemsHolder holder, final String routeName) { Map<String, Route> routes = RouteHelper.getCompiledRoutes(target.getProject()); if(routes.containsKey(routeName)) { return; } Collection fileCollection = FileBasedIndex.getInstance().getContainingFiles(RoutesStubIndex.KEY, routeName, GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(target.getProject()), YAMLFileType.YML, XmlFileType.INSTANCE)); if(fileCollection.size() > 0) { return; } fileCollection = FileBasedIndex.getInstance().getContainingFiles(AnnotationRoutesStubIndex.KEY, routeName, GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(target.getProject()), PhpFileType.INSTANCE)); if(fileCollection.size() > 0) { return; } holder.registerProblem(target, "Missing Route", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } }