Package ideah.psi.impl

Source Code of ideah.psi.impl.HaskellAbstractIdentImpl

package ideah.psi.impl;

import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
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.PsiReference;
import com.intellij.util.IncorrectOperationException;
import ideah.lexer.HaskellTokenTypes;
import ideah.lexer.LexedIdentifier;
import ideah.parser.HaskellElementTypes;
import ideah.psi.api.util.HaskellPsiElementFactory;
import ideah.util.DeclarationPosition;
import ideah.util.LineCol;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public abstract class HaskellAbstractIdentImpl extends HaskellBaseElementImpl implements PsiReference {

    private static final Logger LOG = Logger.getInstance("ideah.psi.impl.HaskellAbstractIdentImpl");

    protected HaskellAbstractIdentImpl(@NotNull ASTNode node) {
        super(node);
    }

    @Override
    public PsiReference getReference() {
        return this;
    }

    @Nullable
    public PsiElement setName(@NotNull @NonNls String name) throws IncorrectOperationException {
        LexedIdentifier parsedNewName = LexedIdentifier.parse(name);
        LexedIdentifier parsedOldName = LexedIdentifier.parseMaybeInfixPrefix(getText());
        LOG.assertTrue(!(parsedNewName == null || parsedOldName == null));
        boolean newNameOperator = HaskellTokenTypes.OPERATORS.contains(parsedNewName.type);
        String createdNewName;

        String module = parsedOldName.module;
        String nameWithModule = module == null ? name : module + "." + name;

        boolean prefixInfixIdent = isPrefixInfixIdent();
        boolean oldOrNewOperatorAndOneOfThemNot = !newNameOperator == HaskellTokenTypes.OPERATORS.contains(parsedOldName.type);

        if (oldOrNewOperatorAndOneOfThemNot != prefixInfixIdent) {
            if (newNameOperator) {
                createdNewName = "(" + nameWithModule + ")";
            } else {
                createdNewName = "`" + nameWithModule + "`";
            }
        } else {
            createdNewName = nameWithModule;
        }

        HaskellPsiElementFactory factory = HaskellPsiElementFactory.getInstance(getProject());
        ASTNode newIdentNode = factory.createIdentNodeFromText(createdNewName);
        if (newIdentNode == null)
            return this;
        ASTNode nodeToBeInsertedTo = getNodeToBeInsertedTo();
        ASTNode nodeToBeReplaced = getNodeToBeReplaced();
        nodeToBeInsertedTo.replaceChild(nodeToBeReplaced, newIdentNode);
        return newIdentNode.getPsi();
    }

    protected abstract ASTNode getNodeToBeReplaced();

    protected abstract ASTNode getNodeToBeInsertedTo();

    protected abstract boolean isPrefixInfixIdent();

    public PsiElement getElement() {
        return this;
    }

    public TextRange getRangeInElement() {
        return new TextRange(0, getTextLength());
    }

    public PsiElement resolve() {
        PsiFile psiFile = getContainingFile();
        LineCol coord = LineCol.fromOffset(psiFile, getTextOffset());
        try {
            DeclarationPosition declaration = DeclarationPosition.get(psiFile, coord);
            return getElementAt(getProject(), declaration);
        } catch (ProcessCanceledException ex) {
            return null;
        } catch (Exception e) {
            LOG.error(e);
            return null;
        }
    }

    public static PsiElement getElementAt(Project project, DeclarationPosition declaration) {
        if (declaration == null)
            return null;
        VirtualFile baseDir = project.getBaseDir();
        if (baseDir == null)
            return null;
        VirtualFile declarationModuleVirtualFile = baseDir.getFileSystem().findFileByPath(declaration.module);
        if (declarationModuleVirtualFile == null)
            return null;
        PsiFile declarationModulePsiFile = PsiManager.getInstance(project).findFile(declarationModuleVirtualFile);
        if (declarationModulePsiFile == null)
            return null;
        int declarationStart = declaration.coord.getOffset(declarationModulePsiFile);
        PsiElement elementAt = declarationModulePsiFile.findElementAt(declarationStart);
        if (elementAt == null)
            return null;
        ASTNode parentNode = elementAt.getParent().getNode();
        if (parentNode.getElementType() == HaskellElementTypes.INFIX_PREFIX_IDENT) {
            return new HPInfixPrefixIdentImpl(parentNode);
        }
        return new HPIdentImpl(elementAt.getNode());
    }

    @NotNull
    public String getCanonicalText() {
        return getText(); // todo: resolve full module name?
    }

    public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
        return setName(newElementName);
    }

    public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
        return null; // todo
    }

    public boolean isReferenceTo(PsiElement element) {
        return false; // todo
    }

    @NotNull
    public Object[] getVariants() {
        return new Object[0]; // todo
    }

    public boolean isSoft() {
        return false;
    }
}
TOP

Related Classes of ideah.psi.impl.HaskellAbstractIdentImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.