package com.thoughtworks.gauge.findUsages; 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 com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.indexing.FileBasedIndex; import com.thoughtworks.gauge.annotator.FileManager; import com.thoughtworks.gauge.language.psi.impl.ConceptStepImpl; import com.thoughtworks.gauge.language.psi.impl.SpecStepImpl; import com.thoughtworks.gauge.stub.FileStub; import java.util.*; public class StepCollector { private Project project; private HashMap<String, List<PsiElement>> stepTextToElement; public StepCollector(Project project) { this.project = project; stepTextToElement = new HashMap<>(); } public void collect() { List<VirtualFile> conceptFiles = FileManager.getConceptFiles(project); List<VirtualFile> files = FileManager.getAllSpecFiles(project); files.addAll(conceptFiles); for (VirtualFile file : files) { List<Set<Integer>> values = FileBasedIndex.getInstance().getValues(FileStub.NAME, file.getPath(), GlobalSearchScope.allScope(project)); PsiFile psiFile = PsiManager.getInstance(project).findFile(file); if (values.size() > 0) getSteps(psiFile, new HashSet<>(values.get(0))); } } public List<PsiElement> get(String stepText) { return stepTextToElement.get(stepText) == null ? new ArrayList<>() : stepTextToElement.get(stepText); } private void getSteps(PsiFile psiFile, Set<Integer> offsets) { for (Integer offset : offsets) { PsiElement stepElement = getStepElement(psiFile.findElementAt(offset)); if (stepElement == null) continue; if (stepElement.getClass().equals(SpecStepImpl.class)) addElement(stepElement, cleanText(((SpecStepImpl) stepElement).getStepValue().getStepText())); else addElement(stepElement, cleanText(((ConceptStepImpl) stepElement).getStepValue().getStepText())); } } private String cleanText(String text) { if (text == null || text.equals("")) return ""; return text.charAt(0) == '*' || text.charAt(0) == '#' ? text.substring(1).trim() : text.trim(); } private void addElement(PsiElement stepElement, String stepText) { List<PsiElement> elementsList = stepTextToElement.get(stepText); if (elementsList == null) { List<PsiElement> elements = new ArrayList<>(); elements.add(stepElement); stepTextToElement.put(stepText, elements); return; } elementsList.add(stepElement); } private PsiElement getStepElement(PsiElement selectedElement) { if (selectedElement == null) return null; if (selectedElement.getClass().equals(SpecStepImpl.class) || selectedElement.getClass().equals(ConceptStepImpl.class)) return selectedElement; return getStepElement(selectedElement.getParent()); } }