package ee.edio.garmin; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.search.FileTypeIndex; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.XmlFile; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.indexing.FileBasedIndex; import com.intellij.util.xml.DomElement; import com.intellij.util.xml.DomFileElement; import com.intellij.util.xml.DomManager; import ee.edio.garmin.psi.MonkeyFile; import ee.edio.garmin.psi.MonkeyNamedElement; import ee.edio.garmin.psi.MonkeyReference; import ee.edio.garmin.psi.MonkeyReferenceExpression; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.*; public class MonkeyUtil { public static List<MonkeyNamedElement> findReferences(Project project, MonkeyReference monkeyReference) { final MonkeyReferenceExpression referenceExpression = (MonkeyReferenceExpression) monkeyReference; final String name = referenceExpression.getComponentName().getName(); if (name == null) { return new ArrayList<>(); } List<MonkeyNamedElement> result = new ArrayList<>(); Collection<VirtualFile> virtualFiles = FileBasedIndex.getInstance().getContainingFiles(FileTypeIndex.NAME, MonkeyFileType.INSTANCE, GlobalSearchScope.allScope(project)); for (VirtualFile virtualFile : virtualFiles) { MonkeyFile monkeyFile = (MonkeyFile) PsiManager.getInstance(project).findFile(virtualFile); if (monkeyFile != null) { MonkeyNamedElement[] references = PsiTreeUtil.getChildrenOfType(monkeyFile.getFirstChild(), MonkeyNamedElement.class); if (references != null) { for (MonkeyNamedElement reference : references) { if (name.equals(reference.getName())) { result.add(reference); } } //Collections.addAll(result, references); } } } return result; } private static final Set<String> keywords = ContainerUtil.immutableSet( "and", "as", "class", "const", "do", "else", "enum", "extends", "false", "for", "function", "has", "hidden", "if", "instanceof", "module", "native", "new", "null", "or", "return", "static", "true", "using", "var", "while"); public static Set<String> getKeywords() { return keywords; } public static boolean isRealDevice(String deviceId) { return !deviceId.equalsIgnoreCase("round_watch") && !deviceId.equalsIgnoreCase("square_watch") && !deviceId.equalsIgnoreCase("semi_round_watch"); } public static String generateProjectId() { UUID id = UUID.randomUUID(); return String.format("%016X%016X", id.getMostSignificantBits(), id.getLeastSignificantBits()); } public static VirtualFile createChildDirectoryIfNotExist(Project project, VirtualFile parent, String name) throws IOException { final VirtualFile child = parent.findChild(name); return child == null ? parent.createChildDirectory(project, name) : child; } @Nullable public static <T extends DomElement> T loadDomElement(@NotNull final Project project, @NotNull final VirtualFile file, @NotNull final Class<T> aClass) { return ApplicationManager.getApplication().runReadAction(new Computable<T>() { @Override @Nullable public T compute() { if (project.isDisposed()) return null; PsiFile psiFile = PsiManager.getInstance(project).findFile(file); if (psiFile instanceof XmlFile) { return loadDomElementWithReadPermission(project, (XmlFile) psiFile, aClass); } else { return null; } } }); } /** * This method should be called under a read action. */ @Nullable public static <T extends DomElement> T loadDomElementWithReadPermission(@NotNull Project project, @NotNull XmlFile xmlFile, @NotNull Class<T> aClass) { ApplicationManager.getApplication().assertReadAccessAllowed(); DomManager domManager = DomManager.getDomManager(project); DomFileElement<T> element = domManager.getFileElement(xmlFile, aClass); if (element == null) return null; return element.getRootElement(); } }