예제 #1
0
  public final int getStartOffsetInParent() {
    if (myParent == null) return -1;
    int offsetInParent = myStartOffsetInParent;
    if (offsetInParent != -1) return offsetInParent;

    synchronized (START_OFFSET_LOCK) {
      TreeElement cur = this;
      offsetInParent = myStartOffsetInParent;
      if (offsetInParent != -1) return offsetInParent;

      ApplicationManager.getApplication().assertReadAccessAllowed();

      while (true) {
        TreeElement prev = cur.getTreePrev();
        if (prev == null) break;
        cur = prev;
        offsetInParent = cur.myStartOffsetInParent;
        if (offsetInParent != -1) break;
      }

      if (offsetInParent == -1) {
        cur.myStartOffsetInParent = offsetInParent = 0;
      }

      while (cur != this) {
        TreeElement next = cur.getTreeNext();
        offsetInParent += cur.getTextLength();
        next.myStartOffsetInParent = offsetInParent;
        cur = next;
      }
      return offsetInParent;
    }
  }
  private static void addReferencesInRangeForComposite(
      final ArrayList<ASTNode> array,
      final TreeElement parent,
      final int startOffset,
      final int endOffset) {
    int offset = 0;
    for (TreeElement child = parent.getFirstChildNode();
        child != null;
        child = child.getTreeNext()) {
      int length = child.getTextLength();

      if (startOffset <= offset + length && offset <= endOffset) {
        final IElementType type = child.getElementType();

        if (type == JavaElementType.JAVA_CODE_REFERENCE
            || type == JavaElementType.REFERENCE_EXPRESSION) {
          array.add(child);
        } else {
          addReferencesInRangeForComposite(array, child, startOffset - offset, endOffset - offset);
        }
      }
      offset += length;
    }
  }
  public TreeElement process(TreeElement element, boolean addImports, boolean uncompleteCode) {
    IElementType elementType = element.getElementType();
    if (elementType == JavaElementType.JAVA_CODE_REFERENCE
        || elementType == JavaElementType.REFERENCE_EXPRESSION) {
      final IElementType parentElementType = element.getTreeParent().getElementType();
      if (elementType == JavaElementType.JAVA_CODE_REFERENCE
          || parentElementType == JavaElementType.REFERENCE_EXPRESSION
          || parentElementType == JavaElementType.METHOD_REF_EXPRESSION
          || uncompleteCode) {
        final PsiJavaCodeReferenceElement ref =
            (PsiJavaCodeReferenceElement) SourceTreeToPsiMap.treeElementToPsi(element);
        final PsiReferenceParameterList parameterList = ref.getParameterList();
        if (parameterList != null) {
          final PsiTypeElement[] typeParameters = parameterList.getTypeParameterElements();
          for (PsiTypeElement typeParameter : typeParameters) {
            process(
                (TreeElement) SourceTreeToPsiMap.psiElementToTree(typeParameter),
                addImports,
                uncompleteCode);
          }
        }

        boolean rightKind = true;
        if (elementType == JavaElementType.JAVA_CODE_REFERENCE) {
          int kind = ((PsiJavaCodeReferenceElementImpl) element).getKind();
          rightKind =
              kind == PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND
                  || kind == PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND;
        }

        if (rightKind) {
          boolean isInsideDocComment =
              TreeUtil.findParent(element, JavaDocElementType.DOC_COMMENT) != null;
          boolean isShort = !((SourceJavaCodeReference) element).isQualified();
          if (!makeFQ(isInsideDocComment)) {
            if (isShort) return element; // short name already, no need to change
          }
          PsiElement refElement;
          if (!uncompleteCode) {
            refElement = ref.resolve();
          } else {
            PsiResolveHelper helper =
                JavaPsiFacade.getInstance(element.getManager().getProject()).getResolveHelper();
            refElement =
                helper.resolveReferencedClass(
                    ((SourceJavaCodeReference) element).getClassNameText(),
                    SourceTreeToPsiMap.treeElementToPsi(element));
          }
          if (refElement instanceof PsiClass) {
            if (makeFQ(isInsideDocComment)) {
              String qName = ((PsiClass) refElement).getQualifiedName();
              if (qName == null) return element;
              PsiImportHolder file =
                  (PsiImportHolder)
                      SourceTreeToPsiMap.treeElementToPsi(element).getContainingFile();
              if (file instanceof PsiJavaFile
                  && ImportHelper.isImplicitlyImported(qName, (PsiJavaFile) file)) {
                if (isShort) return element;
                return (TreeElement)
                    makeShortReference(
                        (CompositeElement) element, (PsiClass) refElement, addImports);
              }
              if (file instanceof PsiJavaFile) {
                String thisPackageName = ((PsiJavaFile) file).getPackageName();
                if (ImportHelper.hasPackage(qName, thisPackageName)) {
                  if (!isShort) {
                    return (TreeElement)
                        makeShortReference(
                            (CompositeElement) element, (PsiClass) refElement, addImports);
                  }
                }
              }
              return (TreeElement) replaceReferenceWithFQ(element, (PsiClass) refElement);
            } else {
              int oldLength = element.getTextLength();
              TreeElement treeElement =
                  (TreeElement)
                      makeShortReference(
                          (CompositeElement) element, (PsiClass) refElement, addImports);
              if (treeElement.getTextLength() == oldLength
                  && ((PsiClass) refElement).getContainingClass() != null) {
                PsiElement qualifier = ref.getQualifier();
                if (qualifier instanceof PsiJavaCodeReferenceElement
                    && ((PsiJavaCodeReferenceElement) qualifier).resolve() instanceof PsiClass) {
                  process((TreeElement) qualifier.getNode(), addImports, uncompleteCode);
                }
              }
              return treeElement;
            }
          }
        }
      }
    }

    for (TreeElement child = element.getFirstChildNode();
        child != null;
        child = child.getTreeNext()) {
      child = process(child, addImports, uncompleteCode);
    }

    return element;
  }