package org.angularjs.index;
import com.intellij.psi.PsiFile;
import com.intellij.psi.XmlRecursiveElementWalkingVisitor;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.Processor;
import com.intellij.util.indexing.*;
import com.intellij.util.io.EnumeratorStringDescriptor;
import com.intellij.util.io.KeyDescriptor;
import com.intellij.xml.util.HtmlUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
/**
* @author Dennis.Ushakov
*/
public class AngularTemplateCacheIndex extends ScalarIndexExtension<String> {
public static final ID<String, Void> TEMPLATE_CACHE_INDEX = ID.create("angularjs.template.cache");
private final DataIndexer<String, Void, FileContent> myDataIndexer = new MyDataIndexer();
@NotNull
@Override
public ID<String, Void> getName() {
return TEMPLATE_CACHE_INDEX;
}
@NotNull
@Override
public DataIndexer<String, Void, FileContent> getIndexer() {
return myDataIndexer;
}
@NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return EnumeratorStringDescriptor.INSTANCE;
}
@NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return AngularTemplateIndexInputFilter.INSTANCE;
}
@Override
public boolean dependsOnFileContent() {
return true;
}
@Override
public int getVersion() {
return AngularIndexUtil.BASE_VERSION;
}
private static class MyDataIndexer implements DataIndexer<String, Void, FileContent> {
@NotNull
@Override
public Map<String, Void> map(@NotNull FileContent inputData) {
final Map<String, Void> result = new THashMap<>();
PsiFile psiFile = inputData.getPsiFile();
processTemplates(psiFile, attribute -> {
result.put(attribute.getValue(), null);
return true;
});
return result;
}
}
public static void processTemplates(final PsiFile psiFile, final Processor<XmlAttribute> processor) {
if (psiFile instanceof XmlFile) {
psiFile.accept(new XmlRecursiveElementWalkingVisitor() {
@Override
public void visitXmlTag(XmlTag tag) {
if (HtmlUtil.isScriptTag(tag) && "text/ng-template".equals(tag.getAttributeValue("type"))) {
final XmlAttribute id = tag.getAttribute("id");
if (id != null) {
processor.process(id);
return;
}
}
super.visitXmlTag(tag);
}
});
}
}
}