package org.elixir_lang.psi.scope.variable; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.PsiReference; import com.intellij.psi.ResolveState; import com.intellij.psi.util.PsiTreeUtil; import gnu.trove.THashMap; import org.elixir_lang.psi.scope.Variable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; import static org.elixir_lang.psi.impl.ElixirPsiImplUtil.ENTRANCE; public class Variants extends Variable { /* * Static Methods */ @Nullable public static List<LookupElement> lookupElementList(@NotNull PsiElement entrance) { Variants variants = new Variants(); PsiTreeUtil.treeWalkUp( variants, entrance, entrance.getContainingFile(), ResolveState.initial().put(ENTRANCE, entrance) ); Collection<LookupElement> lookupElementCollection = variants.getLookupElementCollection(); List<LookupElement> lookupElementList; if (lookupElementCollection != null) { lookupElementList = new ArrayList<LookupElement>(lookupElementCollection); } else { lookupElementList = Collections.emptyList(); } return lookupElementList; } /* * Fields */ @Nullable private Map<PsiElement, LookupElement> lookupElementByElement = null; /* * * Instance Methods * */ /* * Protected Instance Methods */ /** * Decides whether {@code match} matches the criteria being searched for. All other {@link #execute} methods * eventually end here. * * @return {@code false}, as all variables should be found. Prefix filtering will be done later by IDEA core. */ @Override protected boolean executeOnVariable(@NotNull PsiNamedElement match, @NotNull ResolveState state) { PsiReference reference = match.getReference(); String name = null; PsiElement declaration = match; if (reference != null) { PsiElement resolved = reference.resolve(); if (resolved != null) { declaration = resolved; if (resolved instanceof PsiNamedElement) { PsiNamedElement namedResolved = (PsiNamedElement) resolved; name = namedResolved.getName(); } } } if (name == null) { name = match.getName(); } if (name != null) { if (lookupElementByElement == null) { lookupElementByElement = new THashMap<PsiElement, LookupElement>(); } if (!lookupElementByElement.containsKey(declaration)) { final String finalName = name; lookupElementByElement.put( declaration, LookupElementBuilder.createWithSmartPointer( name, declaration ).withRenderer(new org.elixir_lang.code_insight.lookup.element_renderer.Variable(finalName)) ); } } return true; } /* * Private Instance Methods */ @Nullable private Collection<LookupElement> getLookupElementCollection() { Collection<LookupElement> lookupElementCollection = null; if (lookupElementByElement != null) { lookupElementCollection = lookupElementByElement.values(); } return lookupElementCollection; } }