Package org.jetbrains.plugins.clojure.psi.impl.ns

Source Code of org.jetbrains.plugins.clojure.psi.impl.ns.ClNsImpl

package org.jetbrains.plugins.clojure.psi.impl.ns;

import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.*;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.clojure.psi.api.ClList;
import org.jetbrains.plugins.clojure.psi.api.ClListLike;
import org.jetbrains.plugins.clojure.psi.api.ns.ClNs;
import org.jetbrains.plugins.clojure.psi.api.symbols.ClSymbol;
import org.jetbrains.plugins.clojure.psi.impl.ImportOwner;
import org.jetbrains.plugins.clojure.psi.impl.list.ClListBaseImpl;
import org.jetbrains.plugins.clojure.psi.stubs.api.ClNsStub;
import org.jetbrains.plugins.clojure.psi.util.ClojureKeywords;
import org.jetbrains.plugins.clojure.psi.util.ClojurePsiFactory;
import org.jetbrains.plugins.clojure.psi.util.ClojurePsiUtil;

/**
* @author ilyas
*/
public class ClNsImpl extends ClListBaseImpl<ClNsStub> implements ClNs, StubBasedPsiElement<ClNsStub> {

  public ClNsImpl(ClNsStub stub, @NotNull IStubElementType nodeType) {
    super(stub, nodeType);
  }

  public ClNsImpl(ASTNode node) {
    super(node);
  }

  @Override
  public String toString() {
    return "ClNs";
  }

  @Override
  @Nullable
  public String getName() {
    ClNsStub stub = getStub();
    if (stub != null) {
      return stub.getName();
    }

    return getDefinedName();
  }

  /**
   * @return Name of string symbol defined
   */
  @Nullable
  public ClSymbol getNameSymbol() {
    PsiElement element = getSecondNonLeafElement();
    while (element != null && !(element instanceof ClSymbol)) {
      element = element.getNextSibling();
    }
    if (element != null) {
      return (ClSymbol) element;
    }
    return null;
  }

  public String getDefinedName() {
    ClSymbol sym = getNameSymbol();
    if (sym != null) {
      String name = sym.getText();
      assert name != null;
      return name;
    }
    return "";
  }

  public PsiElement setName(@NonNls String name) throws IncorrectOperationException {
    //todo implement me
    return this;
  }

  @Override
  public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place) {
    return ImportOwner.processDeclarations(this, processor, place);
  }

  @Override
  public int getTextOffset() {
    ClNsStub stub = getStub();
    if (stub != null) {
      return stub.getTextOffset();
    }

    final ClSymbol symbol = getNameSymbol();
    if (symbol != null) {
      return symbol.getTextRange().getStartOffset();
    }
    return super.getTextOffset();
  }

  public ClList findImportClause(@Nullable final PsiElement place) {
    final PsiElement element = ContainerUtil.find(getChildren(), new Condition<PsiElement>() {
      public boolean value(PsiElement psiElement) {
        return psiElement instanceof ClList &&
            (place == null || ClojurePsiUtil.isStrictlyBefore(psiElement, place)) &&
            ClojureKeywords.IMPORT.equals(((ClList) psiElement).getHeadText());
      }
    });
    return (ClList) element;
  }

  @NotNull
  public ClList findOrCreateImportClause(@Nullable PsiElement place) {
    final ClList imports = findImportClause(place);
    if (imports != null) return imports;
    return addFreshImportClause();
  }

  public ClList findImportClause() {
    return findImportClause(null);
  }

  @NotNull
  public ClList findOrCreateImportClause() {
    return findOrCreateImportClause(null);
  }

  public ClListLike addImportForClass(PsiElement place, PsiClass clazz) {
    commitDocument();
    final ClojurePsiFactory factory = ClojurePsiFactory.getInstance(getProject());
    final ClList importClause = findOrCreateImportClause(place);
    return factory.findOrCreateJavaImportForClass(clazz, importClause);
  }

  @NotNull
  protected ClList addFreshImportClause() {
    commitDocument();
    final ClSymbol first = getFirstSymbol();
    final ClSymbol nsSymbol = getNameSymbol();
    final PsiElement preamble = findGenClassPreamble();

    final PsiElement anchor = (preamble != null ? preamble :
        nsSymbol != null ? nsSymbol : first);
    assert first != null;

    final ClojurePsiFactory factory = ClojurePsiFactory.getInstance(getProject());
    final ClList list = factory.createListFromText(":import ");
    return (ClList) addAfter(list, anchor);
  }

  protected PsiElement findGenClassPreamble() {
    return ContainerUtil.find(getChildren(), new Condition<PsiElement>() {
      public boolean value(PsiElement psiElement) {
        return (psiElement instanceof ClList) &&
            (ClojureKeywords.GEN_CLASS.equals(((ClList) psiElement).getHeadText()));
      }
    });
  }

}
TOP

Related Classes of org.jetbrains.plugins.clojure.psi.impl.ns.ClNsImpl

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.