package fr.adrienbrault.idea.symfony2plugin.stubs.indexes; import com.intellij.ide.highlighter.XmlFileType; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.XmlFile; import com.intellij.util.indexing.*; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent; import fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper; import fr.adrienbrault.idea.symfony2plugin.stubs.dict.StubIndexedRoute; import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.externalizer.ObjectStreamDataExternalizer; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.yaml.YAMLFileType; import org.jetbrains.yaml.psi.YAMLDocument; import org.jetbrains.yaml.psi.YAMLFile; import java.util.Map; /** * @author Daniel Espendiller <daniel@espendiller.net> */ public class RoutesStubIndex extends FileBasedIndexExtension<String, StubIndexedRoute> { public static final ID<String, StubIndexedRoute> KEY = ID.create("fr.adrienbrault.idea.symfony2plugin.routes_object"); private final KeyDescriptor<String> myKeyDescriptor = new EnumeratorStringDescriptor(); private static ObjectStreamDataExternalizer<StubIndexedRoute> EXTERNALIZER = new ObjectStreamDataExternalizer<>(); @NotNull @Override public ID<String, StubIndexedRoute> getName() { return KEY; } @NotNull @Override public DataIndexer<String, StubIndexedRoute, FileContent> getIndexer() { return inputData -> { Map<String, StubIndexedRoute> map = new THashMap<>(); PsiFile psiFile = inputData.getPsiFile(); if(!Symfony2ProjectComponent.isEnabledForIndex(psiFile.getProject())) { return map; } if(psiFile instanceof YAMLFile) { if(!isValidForIndex(inputData, psiFile)) { return map; } YAMLDocument yamlDocument = PsiTreeUtil.getChildOfType(psiFile, YAMLDocument.class); if(yamlDocument == null) { return map; } for(StubIndexedRoute indexedRoutes: RouteHelper.getYamlRouteDefinitions(yamlDocument)) { map.put(indexedRoutes.getName(), indexedRoutes); } return map; } if(psiFile instanceof XmlFile) { for(StubIndexedRoute indexedRoutes: RouteHelper.getXmlRouteDefinitions((XmlFile) psiFile)) { map.put(indexedRoutes.getName(), indexedRoutes); } } return map; }; } @NotNull @Override public KeyDescriptor<String> getKeyDescriptor() { return this.myKeyDescriptor; } @NotNull @Override public DataExternalizer<StubIndexedRoute> getValueExternalizer() { return EXTERNALIZER; } @NotNull @Override public FileBasedIndex.InputFilter getInputFilter() { return file -> file.getFileType() == YAMLFileType.YML || file.getFileType() == XmlFileType.INSTANCE; } @Override public boolean dependsOnFileContent() { return true; } @Override public int getVersion() { return 3; } public static boolean isValidForIndex(FileContent inputData, PsiFile psiFile) { String fileName = psiFile.getName(); if(fileName.startsWith(".") || fileName.endsWith("Test")) { return false; } VirtualFile baseDir = inputData.getProject().getBaseDir(); if(baseDir == null) { return false; } // is Test file in path name String relativePath = VfsUtil.getRelativePath(inputData.getFile(), baseDir, '/'); if(relativePath != null && (relativePath.contains("/Test/") || relativePath.contains("/Fixtures/"))) { return false; } return true; } }