package com.sylvanaar.idea.Lua.lang.psi.impl.symbols; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; import com.sylvanaar.idea.Lua.lang.psi.LuaPsiManager; import com.sylvanaar.idea.Lua.lang.psi.LuaReferenceElement; import com.sylvanaar.idea.Lua.lang.psi.expressions.LuaExpression; import com.sylvanaar.idea.Lua.lang.psi.resolve.LuaResolveResult; import com.sylvanaar.idea.Lua.lang.psi.resolve.LuaResolver; import com.sylvanaar.idea.Lua.lang.psi.resolve.ResolveUtil; import com.sylvanaar.idea.Lua.lang.psi.resolve.completion.CompletionProcessor; import com.sylvanaar.idea.Lua.lang.psi.symbols.LuaIdentifier; import com.sylvanaar.idea.Lua.lang.psi.util.LuaPsiUtils; import com.sylvanaar.idea.Lua.lang.psi.visitor.LuaElementVisitor; import com.sylvanaar.idea.Lua.options.LuaApplicationSettings; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; /** * TODO: implement all reference stuff... */ public abstract class LuaReferenceElementImpl extends LuaSymbolImpl implements LuaReferenceElement { public LuaReferenceElementImpl(ASTNode node) { super(node); } @Override public void accept(LuaElementVisitor visitor) { visitor.visitReferenceElement(this); } @Override public void accept(@NotNull PsiElementVisitor visitor) { if (visitor instanceof LuaElementVisitor) { ((LuaElementVisitor) visitor).visitReferenceElement(this); } else { visitor.visitElement(this); } } public PsiElement getElement() { return this; } public PsiReference getReference() { return this; } public PsiElement getResolvedElement() { return resolve(); } public TextRange getRangeInElement() { final PsiElement nameElement = getElement(); return new TextRange(getTextOffset() - nameElement.getTextOffset(), nameElement.getTextLength()); } @Nullable public PsiElement resolve() { ResolveResult[] results = getManager().getResolveCache().resolveWithCaching(this, RESOLVER, true, false); return results.length == 1 ? results[0].getElement() : null; } @NotNull public ResolveResult[] multiResolve(final boolean incompleteCode) { return getManager().getResolveCache().resolveWithCaching(this, RESOLVER, true, incompleteCode); } private static final LuaResolver RESOLVER = new LuaResolver(); @NotNull public String getCanonicalText() { return getName(); } public PsiElement setName(@NotNull String s) { ((PsiNamedElement)getElement()).setName(s); resolve(); return this; } public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { ((PsiNamedElement)getElement()).setName(newElementName); resolve(); return this; } public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { findChildByClass(LuaIdentifier.class).replace(element); return this; } public boolean isReferenceTo(PsiElement element) { if (LuaApplicationSettings.getInstance().RESOLVE_ALIASED_IDENTIFIERS) { return resolve() == element; } else { // return ((PsiNamedElement)getElement()).getName().equals(((PsiNamedElement)element).getName()); return getElement().getManager().areElementsEquivalent(element, resolve()); } //return false; } @NotNull public Object[] getVariants() { CompletionProcessor variantsProcessor = new CompletionProcessor(this); ResolveUtil.treeWalkUp(this, variantsProcessor); Collection<String> names = LuaPsiManager.getInstance(getProject()).getFilteredGlobalsCache(); if (names == null) return variantsProcessor.getResultElements(); for (PsiElement e : variantsProcessor.getResultElements()) { final String name = ((PsiNamedElement) e).getName(); if (name != null) names.add(name); } return names.toArray(); } public boolean isSoft() { return false; } public boolean isAssignedTo() { return false; } public PsiElement replaceWithExpression(LuaExpression newCall, boolean b) { return LuaPsiUtils.replaceElement(this, newCall); } @Override public String getName() { return ((PsiNamedElement)getElement()).getName(); } @Override public PsiElement resolveWithoutCaching(boolean ingnoreAlias) { boolean save = RESOLVER.getIgnoreAliasing(); RESOLVER.setIgnoreAliasing(ingnoreAlias); LuaResolveResult[] results = RESOLVER.resolve(this, false); RESOLVER.setIgnoreAliasing(save); if (results != null && results.length > 0) return results[0].getElement(); return null; } }