package org.elixir_lang.psi.scope.module_attribute.implemetation;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementResolveResult;
import com.intellij.psi.ResolveResult;
import com.intellij.psi.ResolveState;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.util.PsiTreeUtil;
import org.elixir_lang.psi.QualifiableAlias;
import org.elixir_lang.psi.call.Call;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import static org.elixir_lang.psi.impl.ElixirPsiImplUtil.ENTRANCE;
public class Protocol implements PsiScopeProcessor {
/*
*
* Static Methods
*
*/
@Nullable
public static List<ResolveResult> resolveResultList(boolean validResult, @NotNull PsiElement entrance) {
Protocol protocol = new Protocol(validResult);
PsiTreeUtil.treeWalkUp(
protocol,
entrance,
entrance.getContainingFile(),
ResolveState.initial().put(ENTRANCE, entrance)
);
return protocol.getResolveResultList();
}
/*
* Fields
*/
private final boolean validResult;
@Nullable
private List<ResolveResult> resolveResultList = null;
/*
* Constructors
*/
public Protocol(boolean validResult) {
this.validResult = !validResult;
}
/*
*
* Instance Methods
*
*/
/*
* Public Instance Methods
*/
@Override
public boolean execute(@NotNull PsiElement element, @NotNull ResolveState state) {
boolean keepProcessing = true;
if (element instanceof Call) {
keepProcessing = execute((Call) element, state);
}
return keepProcessing;
}
@Nullable
@Override
public <T> T getHint(@NotNull Key<T> hintKey) {
return null;
}
@Nullable
public List<ResolveResult> getResolveResultList() {
return resolveResultList;
}
@Override
public void handleEvent(@NotNull Event event, @Nullable Object associated) {
}
/*
* Private Instance Methods
*/
private boolean execute(@NotNull Call call, @NotNull @SuppressWarnings("unused") ResolveState state) {
boolean keepProcessing = true;
if (org.elixir_lang.structure_view.element.modular.Implementation.is(call)) {
QualifiableAlias protocolNameElement = org.elixir_lang.structure_view.element.modular.Implementation.protocolNameElement(call);
PsiElement element;
boolean validResult;
if (protocolNameElement != null) {
element = protocolNameElement;
validResult = this.validResult;
} else {
element = call;
validResult = false;
}
resolveResultList = Collections.<ResolveResult>singletonList(new PsiElementResolveResult(element, validResult));
keepProcessing = false;
}
return keepProcessing;
}
}