@Nullable
  public static PsiQualifiedReference getClassReferenceToShorten(
      @NotNull final PsiClass refClass,
      final boolean addImports,
      @NotNull final PsiQualifiedReference reference) {
    PsiClass parentClass = refClass.getContainingClass();
    if (parentClass != null) {
      JavaPsiFacade facade = JavaPsiFacade.getInstance(parentClass.getProject());
      final PsiResolveHelper resolveHelper = facade.getResolveHelper();
      if (resolveHelper.isAccessible(refClass, reference, null)
          && isSafeToShortenReference(reference.getReferenceName(), reference, refClass)) {
        return reference;
      }

      if (!CodeStyleSettingsManager.getSettings(reference.getProject())
          .INSERT_INNER_CLASS_IMPORTS) {
        final PsiElement qualifier = reference.getQualifier();
        if (qualifier instanceof PsiQualifiedReference) {
          return getClassReferenceToShorten(
              parentClass, addImports, (PsiQualifiedReference) qualifier);
        }
        return null;
      }
    }

    if (addImports && !((PsiImportHolder) reference.getContainingFile()).importClass(refClass))
      return null;
    if (!isSafeToShortenReference(reference, refClass)) return null;
    return reference;
  }
 private static boolean isSafeToShortenReference(
     final String referenceText, final PsiElement psiReference, final PsiClass refClass) {
   final PsiManager manager = refClass.getManager();
   final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
   final PsiResolveHelper helper = facade.getResolveHelper();
   if (manager.areElementsEquivalent(
       refClass, helper.resolveReferencedClass(referenceText, psiReference))) {
     PsiElement parent = psiReference.getParent();
     if (parent instanceof PsiJavaCodeReferenceElement
         && parent.getParent() instanceof PsiNewExpression) return true;
     return helper.resolveReferencedVariable(referenceText, psiReference) == null;
   }
   return false;
 }
 public static PsiElement setName(@NotNull PsiElement element, @NotNull String name)
     throws IncorrectOperationException {
   PsiManager manager = element.getManager();
   PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
   PsiIdentifier newNameIdentifier = factory.createIdentifier(name);
   return element.replace(newNameIdentifier);
 }
  public static PsiType buildTypeFromTypeString(
      @NotNull final String typeName,
      @NotNull final PsiElement context,
      @NotNull final PsiFile psiFile) {
    PsiType resultType;
    final PsiManager psiManager = psiFile.getManager();

    if (typeName.indexOf('<') != -1 || typeName.indexOf('[') != -1 || typeName.indexOf('.') == -1) {
      try {
        return JavaPsiFacade.getInstance(psiManager.getProject())
            .getElementFactory()
            .createTypeFromText(typeName, context);
      } catch (Exception ignored) {
      } // invalid syntax will produce unresolved class type
    }

    PsiClass aClass =
        JavaPsiFacade.getInstance(psiManager.getProject())
            .findClass(typeName, context.getResolveScope());

    if (aClass == null) {
      final LightClassReference ref =
          new LightClassReference(
              psiManager,
              PsiNameHelper.getShortClassName(typeName),
              typeName,
              PsiSubstitutor.EMPTY,
              psiFile);
      resultType = new PsiClassReferenceType(ref, null);
    } else {
      PsiElementFactory factory =
          JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
      PsiSubstitutor substitutor = factory.createRawSubstitutor(aClass);
      resultType = factory.createType(aClass, substitutor);
    }

    return resultType;
  }
  @NotNull
  public static PsiType getType(@NotNull PsiClassObjectAccessExpression classAccessExpression) {
    GlobalSearchScope resolveScope = classAccessExpression.getResolveScope();
    PsiManager manager = classAccessExpression.getManager();
    final PsiClass classClass =
        JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Class", resolveScope);
    if (classClass == null) {
      return new PsiClassReferenceType(
          new LightClassReference(manager, "Class", "java.lang.Class", resolveScope), null);
    }
    if (!PsiUtil.isLanguageLevel5OrHigher(classAccessExpression)) {
      // Raw java.lang.Class
      return JavaPsiFacade.getInstance(manager.getProject())
          .getElementFactory()
          .createType(classClass);
    }

    PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
    PsiType operandType = classAccessExpression.getOperand().getType();
    if (operandType instanceof PsiPrimitiveType && !PsiType.NULL.equals(operandType)) {
      if (PsiType.VOID.equals(operandType)) {
        operandType =
            JavaPsiFacade.getInstance(manager.getProject())
                .getElementFactory()
                .createTypeByFQClassName("java.lang.Void", classAccessExpression.getResolveScope());
      } else {
        operandType = ((PsiPrimitiveType) operandType).getBoxedType(classAccessExpression);
      }
    }
    final PsiTypeParameter[] typeParameters = classClass.getTypeParameters();
    if (typeParameters.length == 1) {
      substitutor = substitutor.put(typeParameters[0], operandType);
    }

    return new PsiImmediateClassType(classClass, substitutor);
  }
  @NotNull
  public static SearchScope getMemberUseScope(@NotNull PsiMember member) {
    PsiFile file = member.getContainingFile();
    PsiElement topElement = file == null ? member : file;
    Project project = topElement.getProject();
    final GlobalSearchScope maximalUseScope =
        ResolveScopeManager.getInstance(project).getUseScope(topElement);
    if (isInServerPage(file)) return maximalUseScope;

    PsiClass aClass = member.getContainingClass();
    if (aClass instanceof PsiAnonymousClass
        && !(aClass instanceof PsiEnumConstantInitializer
            && member instanceof PsiMethod
            && member.hasModifierProperty(PsiModifier.PUBLIC)
            && ((PsiMethod) member).findSuperMethods().length > 0)) {
      // member from anonymous class can be called from outside the class
      PsiElement methodCallExpr =
          PsiUtil.isLanguageLevel8OrHigher(aClass)
              ? PsiTreeUtil.getTopmostParentOfType(aClass, PsiStatement.class)
              : PsiTreeUtil.getParentOfType(aClass, PsiMethodCallExpression.class);
      return new LocalSearchScope(methodCallExpr != null ? methodCallExpr : aClass);
    }

    PsiModifierList modifierList = member.getModifierList();
    int accessLevel =
        modifierList == null ? PsiUtil.ACCESS_LEVEL_PUBLIC : PsiUtil.getAccessLevel(modifierList);
    if (accessLevel == PsiUtil.ACCESS_LEVEL_PUBLIC
        || accessLevel == PsiUtil.ACCESS_LEVEL_PROTECTED) {
      return maximalUseScope; // class use scope doesn't matter, since another very visible class
      // can inherit from aClass
    }
    if (accessLevel == PsiUtil.ACCESS_LEVEL_PRIVATE) {
      PsiClass topClass = PsiUtil.getTopLevelClass(member);
      return topClass != null
          ? new LocalSearchScope(topClass)
          : file == null ? maximalUseScope : new LocalSearchScope(file);
    }
    if (file instanceof PsiJavaFile) {
      PsiPackage aPackage =
          JavaPsiFacade.getInstance(project).findPackage(((PsiJavaFile) file).getPackageName());
      if (aPackage != null) {
        SearchScope scope = PackageScope.packageScope(aPackage, false);
        return scope.intersectWith(maximalUseScope);
      }
    }
    return maximalUseScope;
  }
 @NotNull
 public static PsiJavaCodeReferenceElement[] namesToPackageReferences(
     @NotNull PsiManager manager, @NotNull String[] names) {
   PsiJavaCodeReferenceElement[] refs = new PsiJavaCodeReferenceElement[names.length];
   for (int i = 0; i < names.length; i++) {
     String name = names[i];
     try {
       refs[i] =
           JavaPsiFacade.getInstance(manager.getProject())
               .getElementFactory()
               .createPackageReferenceElement(name);
     } catch (IncorrectOperationException e) {
       LOG.error(e);
     }
   }
   return refs;
 }
  @Override
  public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) {
    if (first.getElementType() == NAME_VALUE_PAIR && last.getElementType() == NAME_VALUE_PAIR) {
      final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this);
      ASTNode lparenth = findChildByRole(ChildRole.LPARENTH);
      if (lparenth == null) {
        LeafElement created =
            Factory.createSingleLeafElement(LPARENTH, "(", 0, 1, treeCharTab, getManager());
        super.addInternal(created, created, getFirstChildNode(), true);
      }
      ASTNode rparenth = findChildByRole(ChildRole.RPARENTH);
      if (rparenth == null) {
        LeafElement created =
            Factory.createSingleLeafElement(RPARENTH, ")", 0, 1, treeCharTab, getManager());
        super.addInternal(created, created, getLastChildNode(), false);
      }

      final ASTNode[] nodes = getChildren(NAME_VALUE_PAIR_BIT_SET);
      if (nodes.length == 1) {
        final ASTNode node = nodes[0];
        if (node instanceof PsiNameValuePair) {
          final PsiNameValuePair pair = (PsiNameValuePair) node;
          if (pair.getName() == null) {
            final String text = pair.getValue().getText();
            try {
              final PsiAnnotation annotation =
                  JavaPsiFacade.getInstance(getProject())
                      .getElementFactory()
                      .createAnnotationFromText("@AAA(value = " + text + ")", null);
              replaceChild(node, annotation.getParameterList().getAttributes()[0].getNode());
            } catch (IncorrectOperationException e) {
              LOG.error(e);
            }
          }
        }
      }

      if (anchor == null && before != null) {
        anchor = findChildByRole(before.booleanValue() ? ChildRole.RPARENTH : ChildRole.LPARENTH);
      }
    }

    return super.addInternal(first, last, anchor, before);
  }
  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;
  }
Example #10
0
  @Override
  public ASTNode process(
      @NotNull ASTNode element,
      boolean addImports,
      boolean incompleteCode,
      boolean useFqInJavadoc,
      boolean useFqInCode) {
    IElementType elementType = element.getElementType();
    if ((elementType == JavaElementType.JAVA_CODE_REFERENCE
            || elementType == JavaElementType.REFERENCE_EXPRESSION)
        && !isAnnotated(element)) {
      IElementType parentType = element.getTreeParent().getElementType();
      if (elementType == JavaElementType.JAVA_CODE_REFERENCE
          || incompleteCode
          || parentType == JavaElementType.REFERENCE_EXPRESSION
          || parentType == JavaElementType.METHOD_REF_EXPRESSION) {
        PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) element.getPsi();

        PsiReferenceParameterList parameterList = ref.getParameterList();
        if (parameterList != null) {
          PsiTypeElement[] typeParameters = parameterList.getTypeParameterElements();
          for (PsiTypeElement typeParameter : typeParameters) {
            process(
                typeParameter.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode);
          }
        }

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

        if (rightKind) {
          // annotations may jump out of reference (see PsiJavaCodeReferenceImpl#setAnnotations())
          // so they should be processed first
          List<PsiAnnotation> annotations =
              PsiTreeUtil.getChildrenOfTypeAsList(ref, PsiAnnotation.class);
          for (PsiAnnotation annotation : annotations) {
            process(annotation.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode);
          }

          boolean isInsideDocComment =
              TreeUtil.findParent(element, JavaDocElementType.DOC_COMMENT) != null;
          boolean isShort = !ref.isQualified();
          if (isInsideDocComment ? !useFqInJavadoc : !useFqInCode) {
            if (isShort) return element; // short name already, no need to change
          }

          PsiElement refElement;
          if (!incompleteCode) {
            refElement = ref.resolve();
          } else {
            PsiResolveHelper helper =
                JavaPsiFacade.getInstance(ref.getManager().getProject()).getResolveHelper();
            final SourceJavaCodeReference reference = (SourceJavaCodeReference) element;
            refElement = helper.resolveReferencedClass(reference.getClassNameText(), ref);
          }

          if (refElement instanceof PsiClass) {
            PsiClass psiClass = (PsiClass) refElement;
            if (isInsideDocComment ? useFqInJavadoc : useFqInCode) {
              String qName = psiClass.getQualifiedName();
              if (qName == null) return element;

              PsiFile file = ref.getContainingFile();
              if (file instanceof PsiJavaFile) {
                if (ImportHelper.isImplicitlyImported(qName, (PsiJavaFile) file)) {
                  if (isShort) return element;
                  return makeShortReference((CompositeElement) element, psiClass, addImports);
                }

                String thisPackageName = ((PsiJavaFile) file).getPackageName();
                if (ImportHelper.hasPackage(qName, thisPackageName)) {
                  if (!isShort) {
                    return makeShortReference((CompositeElement) element, psiClass, addImports);
                  }
                }
              }

              return replaceReferenceWithFQ(element, psiClass);
            } else {
              int oldLength = element.getTextLength();
              ASTNode treeElement =
                  makeShortReference((CompositeElement) element, psiClass, addImports);
              if (treeElement.getTextLength() == oldLength
                  && psiClass.getContainingClass() != null) {
                PsiElement qualifier = ref.getQualifier();
                if (qualifier instanceof PsiJavaCodeReferenceElement
                    && ((PsiJavaCodeReferenceElement) qualifier).resolve() instanceof PsiClass) {
                  process(
                      qualifier.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode);
                }
              }
              return treeElement;
            }
          }
        }
      }
    }

    for (ASTNode child = element.getFirstChildNode(); child != null; child = child.getTreeNext()) {
      //noinspection AssignmentToForLoopParameter
      child = process(child, addImports, incompleteCode, useFqInJavadoc, useFqInCode);
    }

    return element;
  }