コード例 #1
0
  /**
   * Allows to check if static import may be performed for the given element.
   *
   * @param element element to check
   * @return target class that may be statically imported if any; <code>null</code> otherwise
   */
  @Nullable
  public static PsiClass getClassToPerformStaticImport(@NotNull PsiElement element) {
    if (!PsiUtil.isLanguageLevel5OrHigher(element)) return null;
    if (!(element instanceof PsiIdentifier)
        || !(element.getParent() instanceof PsiJavaCodeReferenceElement)) {
      return null;
    }
    PsiJavaCodeReferenceElement refExpr = (PsiJavaCodeReferenceElement) element.getParent();
    if (refExpr instanceof PsiMethodReferenceExpression) return null;
    final PsiElement gParent = refExpr.getParent();
    if (gParent instanceof PsiMethodReferenceExpression) return null;
    if (!(gParent instanceof PsiJavaCodeReferenceElement)
        || isParameterizedReference((PsiJavaCodeReferenceElement) gParent)) return null;

    PsiElement resolved = refExpr.resolve();
    if (!(resolved instanceof PsiClass)) {
      return null;
    }
    PsiClass psiClass = (PsiClass) resolved;
    if (PsiUtil.isFromDefaultPackage(psiClass)
        || psiClass.hasModifierProperty(PsiModifier.PRIVATE)
        || psiClass.getQualifiedName() == null) return null;

    final PsiElement ggParent = gParent.getParent();
    if (ggParent instanceof PsiMethodCallExpression) {
      final PsiMethodCallExpression call = (PsiMethodCallExpression) ggParent.copy();
      final PsiElement qualifier = call.getMethodExpression().getQualifier();
      if (qualifier == null) return null;
      qualifier.delete();
      final PsiMethod method = call.resolveMethod();
      if (method != null && method.getContainingClass() != psiClass) return null;
    } else {
      final PsiJavaCodeReferenceElement copy = (PsiJavaCodeReferenceElement) gParent.copy();
      final PsiElement qualifier = copy.getQualifier();
      if (qualifier == null) return null;
      qualifier.delete();
      final PsiElement target = copy.resolve();
      if (target != null && PsiTreeUtil.getParentOfType(target, PsiClass.class) != psiClass)
        return null;
    }

    PsiFile file = refExpr.getContainingFile();
    if (!(file instanceof PsiJavaFile)) return null;
    PsiImportList importList = ((PsiJavaFile) file).getImportList();
    if (importList == null) return null;

    return psiClass;
  }
コード例 #2
0
  @Nullable
  static Pair<PsiClass, Integer> getTypeParameterInfo(PsiElement context) {
    final PsiReferenceParameterList parameterList =
        PsiTreeUtil.getContextOfType(context, PsiReferenceParameterList.class, true);
    if (parameterList == null) return null;

    PsiElement parent = parameterList.getParent();
    if (!(parent instanceof PsiJavaCodeReferenceElement)) return null;

    final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement) parent;
    final int parameterIndex;

    int index = 0;
    final PsiTypeElement typeElement =
        PsiTreeUtil.getContextOfType(context, PsiTypeElement.class, true);
    if (typeElement != null) {
      final PsiTypeElement[] elements =
          referenceElement.getParameterList().getTypeParameterElements();
      while (index < elements.length) {
        final PsiTypeElement element = elements[index++];
        if (element == typeElement) break;
      }
    }
    parameterIndex = index - 1;

    if (parameterIndex < 0) return null;
    final PsiElement target = referenceElement.resolve();
    if (!(target instanceof PsiClass)) return null;

    final PsiClass referencedClass = (PsiClass) target;
    final PsiTypeParameter[] typeParameters = referencedClass.getTypeParameters();
    if (typeParameters.length <= parameterIndex) return null;

    return Pair.create(referencedClass, parameterIndex);
  }
 @Override
 public void visitAnonymousClass(@NotNull PsiAnonymousClass anonymousClass) {
   if (anonymousClass instanceof PsiEnumConstantInitializer) {
     return;
   }
   final PsiMember containingMember =
       PsiTreeUtil.getParentOfType(anonymousClass, PsiMember.class);
   if (containingMember == null || containingMember.hasModifierProperty(PsiModifier.STATIC)) {
     return;
   }
   final PsiJavaCodeReferenceElement reference = anonymousClass.getBaseClassReference();
   if (reference.resolve() == null) {
     // don't warn on broken code
     return;
   }
   final PsiClass containingClass = PsiTreeUtil.getParentOfType(anonymousClass, PsiClass.class);
   if (containingClass == null) {
     return;
   }
   if (containingClass.getContainingClass() != null
       && !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
     // strictly speaking can be named static inner class but not when part of the current
     // containing class
     return;
   }
   final InnerClassReferenceVisitor visitor = new InnerClassReferenceVisitor(anonymousClass);
   anonymousClass.accept(visitor);
   if (!visitor.canInnerClassBeStatic()) {
     return;
   }
   if (hasReferenceToLocalClass(anonymousClass)) {
     return;
   }
   registerClassError(anonymousClass);
 }
コード例 #4
0
 /**
  * The parameter <code>allowIndirect</code> determines if the method should look for indirect
  * annotations, i.e. annotations which have themselves been annotated by the supplied annotation
  * name. Currently, this only allows one level of indirection and returns an array of
  * [base-annotation, indirect annotation]
  *
  * <p>The <code>annotationName</code> parameter is a pair of the target annotation class' fully
  * qualified name as a String and as a Set. This is done for performance reasons because the Set
  * is required by the {@link com.intellij.codeInsight.AnnotationUtil} utility class and allows to
  * avoid unnecessary object constructions.
  */
 public static PsiAnnotation[] getAnnotationsFromImpl(
     PsiModifierListOwner owner,
     Pair<String, ? extends Set<String>> annotationName,
     boolean allowIndirect,
     boolean inHierarchy) {
   final PsiAnnotation directAnnotation =
       inHierarchy
           ? AnnotationUtil.findAnnotationInHierarchy(owner, annotationName.second)
           : AnnotationUtil.findAnnotation(owner, annotationName.second);
   if (directAnnotation != null) {
     return new PsiAnnotation[] {directAnnotation};
   }
   if (allowIndirect) {
     final PsiAnnotation[] annotations = getAnnotations(owner, inHierarchy);
     for (PsiAnnotation annotation : annotations) {
       PsiJavaCodeReferenceElement nameReference = annotation.getNameReferenceElement();
       if (nameReference == null) continue;
       PsiElement resolved = nameReference.resolve();
       if (resolved instanceof PsiClass) {
         final PsiAnnotation psiAnnotation =
             AnnotationUtil.findAnnotationInHierarchy(
                 (PsiModifierListOwner) resolved, annotationName.second);
         if (psiAnnotation != null) {
           return new PsiAnnotation[] {psiAnnotation, annotation};
         }
       }
     }
   }
   return PsiAnnotation.EMPTY_ARRAY;
 }
コード例 #5
0
 @Override
 public void visitReferenceElement(PsiJavaCodeReferenceElement referenceElement) {
   if (!myIsMovable) return;
   final PsiExpression qualifier;
   if (referenceElement instanceof PsiReferenceExpression) {
     qualifier = ((PsiReferenceExpression) referenceElement).getQualifierExpression();
   } else {
     qualifier = null;
   }
   if (qualifier == null
       || qualifier instanceof PsiThisExpression
       || qualifier instanceof PsiSuperExpression) {
     final PsiElement resolved = referenceElement.resolve();
     if (!(resolved instanceof PsiParameter)) {
       if (resolved instanceof PsiClass
           && (((PsiClass) resolved).hasModifierProperty(PsiModifier.STATIC)
               || ((PsiClass) resolved).getContainingClass() == null)) {
         return;
       }
       PsiClass containingClass = null;
       if (resolved instanceof PsiMember
           && !((PsiMember) resolved).hasModifierProperty(PsiModifier.STATIC)) {
         containingClass = ((PsiMember) resolved).getContainingClass();
       }
       myIsMovable =
           containingClass != null
               && InheritanceUtil.isInheritorOrSelf(myTargetSuperClass, containingClass, true);
     }
   } else {
     qualifier.accept(this);
   }
 }
コード例 #6
0
 @Override
 public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
   super.visitReferenceElement(reference);
   if (referenceFound) {
     return;
   }
   final String text = reference.getText();
   if (text.indexOf((int) '.') >= 0 || !name.equals(text)) {
     return;
   }
   final PsiElement element = reference.resolve();
   if (!(element instanceof PsiClass) || element instanceof PsiTypeParameter) {
     return;
   }
   final PsiClass aClass = (PsiClass) element;
   final String testClassName = aClass.getName();
   final String testClassQualifiedName = aClass.getQualifiedName();
   if (testClassQualifiedName == null
       || testClassName == null
       || testClassQualifiedName.equals(fullyQualifiedName)
       || !testClassName.equals(name)) {
     return;
   }
   referenceFound = true;
 }
コード例 #7
0
 @Override
 public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
   super.visitReferenceElement(reference);
   final PsiElement element = reference.resolve();
   if (element != null) {
     myResult.add(element);
   }
 }
コード例 #8
0
  public JavaCompletionProcessor(
      PsiElement element,
      ElementFilter filter,
      final boolean checkAccess,
      boolean checkInitialized,
      @Nullable Condition<String> nameCondition) {
    myCheckAccess = checkAccess;
    mySettings = CodeInsightSettings.getInstance();
    myResults = new ArrayList<CompletionElement>();
    myElement = element;
    myMatcher = nameCondition;
    myFilter = filter;
    PsiElement scope = element;
    if (JavaResolveUtil.isInJavaDoc(myElement)) myMembersFlag = true;
    while (scope != null && !(scope instanceof PsiFile) && !(scope instanceof PsiClass)) {
      scope = scope.getContext();
    }
    myScope = scope;
    if (!(element.getContainingFile() instanceof PsiJavaFile)) {
      myMembersFlag = true;
    }

    PsiElement elementParent = element.getContext();
    if (elementParent instanceof PsiReferenceExpression) {
      PsiExpression qualifier = ((PsiReferenceExpression) elementParent).getQualifierExpression();
      if (qualifier instanceof PsiSuperExpression) {
        final PsiJavaCodeReferenceElement qSuper = ((PsiSuperExpression) qualifier).getQualifier();
        if (qSuper == null) {
          myQualifierClass = JavaResolveUtil.getContextClass(myElement);
        } else {
          final PsiElement target = qSuper.resolve();
          myQualifierClass = target instanceof PsiClass ? (PsiClass) target : null;
        }
        if (myQualifierClass != null) {
          myQualifierType =
              JavaPsiFacade.getInstance(element.getProject())
                  .getElementFactory()
                  .createType(myQualifierClass);
        }
      } else if (qualifier != null) {
        myQualifierType = qualifier.getType();
        myQualifierClass = PsiUtil.resolveClassInType(myQualifierType);
        if (myQualifierType == null && qualifier instanceof PsiJavaCodeReferenceElement) {
          final PsiElement target = ((PsiJavaCodeReferenceElement) qualifier).resolve();
          if (target instanceof PsiClass) {
            myQualifierClass = (PsiClass) target;
          }
        }
      }
    }

    if (checkInitialized) {
      myNonInitializedFields.addAll(getNonInitializedFields(element));
    }
  }
 @Override
 public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
   super.visitReferenceElement(reference);
   if (reference.getQualifier() != null) {
     return;
   }
   final PsiElement target = reference.resolve();
   if (!(target instanceof PsiClass) || !PsiUtil.isLocalClass((PsiClass) target)) {
     return;
   }
   referenceToLocalClass = true;
 }
コード例 #10
0
 private static void decodeRef(
     final PsiJavaCodeReferenceElement expression,
     final Map<PsiClass, PsiElement> oldToNewMap,
     Set<PsiElement> rebindExpressions) {
   final PsiElement resolved = expression.resolve();
   if (resolved instanceof PsiClass) {
     final PsiClass psiClass = (PsiClass) resolved;
     if (oldToNewMap.containsKey(psiClass)) {
       rebindExpressions.add(expression.bindToElement(oldToNewMap.get(psiClass)));
     }
   }
 }
コード例 #11
0
 @Nullable
 private static PsiReferenceParameterList extractReferenceParameterList(
     final PsiClass superClass, final PsiReferenceList extendsList) {
   for (PsiJavaCodeReferenceElement referenceElement : extendsList.getReferenceElements()) {
     final PsiElement element = referenceElement.resolve();
     if (element instanceof PsiClass
         && InheritanceUtil.isInheritorOrSelf((PsiClass) element, superClass, true)) {
       return referenceElement.getParameterList();
     }
   }
   return null;
 }
    private static boolean containsError(PsiAnnotation annotation) {
      final PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement();
      if (nameRef == null) {
        return true;
      }
      final PsiClass aClass = (PsiClass) nameRef.resolve();
      if (aClass == null || !aClass.isAnnotationType()) {
        return true;
      }
      final Set<String> names = new HashSet<String>();
      final PsiAnnotationParameterList annotationParameterList = annotation.getParameterList();
      if (PsiUtilCore.hasErrorElementChild(annotationParameterList)) {
        return true;
      }
      final PsiNameValuePair[] attributes = annotationParameterList.getAttributes();
      for (PsiNameValuePair attribute : attributes) {
        final PsiReference reference = attribute.getReference();
        if (reference == null) {
          return true;
        }
        final PsiMethod method = (PsiMethod) reference.resolve();
        if (method == null) {
          return true;
        }
        final PsiAnnotationMemberValue value = attribute.getValue();
        if (value == null || PsiUtilCore.hasErrorElementChild(value)) {
          return true;
        }
        if (value instanceof PsiAnnotation && containsError((PsiAnnotation) value)) {
          return true;
        }
        if (!hasCorrectType(value, method.getReturnType())) {
          return true;
        }
        final String name = attribute.getName();
        if (!names.add(name != null ? name : PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME)) {
          return true;
        }
      }

      for (PsiMethod method : aClass.getMethods()) {
        if (!(method instanceof PsiAnnotationMethod)) {
          continue;
        }
        final PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method;
        if (annotationMethod.getDefaultValue() == null
            && !names.contains(annotationMethod.getName())) {
          return true; // missing a required argument
        }
      }
      return false;
    }
コード例 #13
0
  /**
   * @return true if both expressions resolve to the same variable/class or field in the same
   *     instance of the class
   */
  private static boolean sameInstanceReferences(
      @Nullable PsiJavaCodeReferenceElement lRef,
      @Nullable PsiJavaCodeReferenceElement rRef,
      PsiManager manager) {
    if (lRef == null && rRef == null) return true;
    if (lRef == null || rRef == null) return false;
    PsiElement lResolved = lRef.resolve();
    PsiElement rResolved = rRef.resolve();
    if (!manager.areElementsEquivalent(lResolved, rResolved)) return false;
    if (!(lResolved instanceof PsiVariable)) return false;
    final PsiVariable variable = (PsiVariable) lResolved;
    if (variable.hasModifierProperty(PsiModifier.STATIC)) return true;

    final PsiElement lQualifier = lRef.getQualifier();
    final PsiElement rQualifier = rRef.getQualifier();
    if (lQualifier instanceof PsiJavaCodeReferenceElement
        && rQualifier instanceof PsiJavaCodeReferenceElement) {
      return sameInstanceReferences(
          (PsiJavaCodeReferenceElement) lQualifier,
          (PsiJavaCodeReferenceElement) rQualifier,
          manager);
    }

    if (Comparing.equal(lQualifier, rQualifier)) return true;
    boolean lThis =
        lQualifier == null
            || lQualifier instanceof PsiThisExpression
            || lQualifier instanceof PsiSuperExpression;
    boolean rThis =
        rQualifier == null
            || rQualifier instanceof PsiThisExpression
            || rQualifier instanceof PsiSuperExpression;
    if (lThis && rThis) {
      final PsiJavaCodeReferenceElement llQualifier = getQualifier(lQualifier);
      final PsiJavaCodeReferenceElement rrQualifier = getQualifier(rQualifier);
      return sameInstanceReferences(llQualifier, rrQualifier, manager);
    }
    return false;
  }
コード例 #14
0
 private static boolean isAnnotationRepeatedTwice(
     @NotNull PsiAnnotationOwner owner, @NotNull String qualifiedName) {
   int count = 0;
   for (PsiAnnotation annotation : owner.getAnnotations()) {
     PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement();
     if (nameRef == null) continue;
     PsiElement resolved = nameRef.resolve();
     if (!(resolved instanceof PsiClass)
         || !qualifiedName.equals(((PsiClass) resolved).getQualifiedName())) continue;
     count++;
     if (count == 2) return true;
   }
   return false;
 }
コード例 #15
0
  /**
   * From given targets, returns first where the annotation may be applied. Returns {@code null}
   * when the annotation is not applicable at any of the targets, or {@linkplain TargetType#UNKNOWN}
   * if the annotation does not resolve to a valid annotation type.
   */
  @Nullable
  public static TargetType findAnnotationTarget(
      @NotNull PsiAnnotation annotation, @NotNull TargetType... types) {
    if (types.length != 0) {
      PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement();
      if (ref != null) {
        PsiElement annotationType = ref.resolve();
        if (annotationType instanceof PsiClass) {
          return findAnnotationTarget((PsiClass) annotationType, types);
        }
      }
    }

    return TargetType.UNKNOWN;
  }
コード例 #16
0
 @Nullable
 public static HighlightInfo checkAnnotationType(PsiAnnotation annotation) {
   PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();
   if (nameReferenceElement != null) {
     PsiElement resolved = nameReferenceElement.resolve();
     if (!(resolved instanceof PsiClass) || !((PsiClass) resolved).isAnnotationType()) {
       String description = JavaErrorMessages.message("annotation.annotation.type.expected");
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
           .range(nameReferenceElement)
           .descriptionAndTooltip(description)
           .create();
     }
   }
   return null;
 }
コード例 #17
0
  @Override
  public void removeRedundantImports(@NotNull final PsiJavaFile file)
      throws IncorrectOperationException {
    final Collection<PsiImportStatementBase> redundant = findRedundantImports(file);
    if (redundant == null) return;

    for (final PsiImportStatementBase importStatement : redundant) {
      final PsiJavaCodeReferenceElement ref = importStatement.getImportReference();
      // Do not remove non-resolving refs
      if (ref == null || ref.resolve() == null) {
        continue;
      }

      importStatement.delete();
    }
  }
コード例 #18
0
  @Nullable
  public static HighlightInfo checkMissingAttributes(PsiAnnotation annotation) {
    PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement();
    if (nameRef == null) return null;
    PsiClass aClass = (PsiClass) nameRef.resolve();
    if (aClass != null && aClass.isAnnotationType()) {
      Set<String> names = new HashSet<String>();
      PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
      for (PsiNameValuePair attribute : attributes) {
        final String name = attribute.getName();
        if (name != null) {
          names.add(name);
        } else {
          names.add(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME);
        }
      }

      PsiMethod[] annotationMethods = aClass.getMethods();
      List<String> missed = new ArrayList<String>();
      for (PsiMethod method : annotationMethods) {
        if (PsiUtil.isAnnotationMethod(method)) {
          PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method;
          if (annotationMethod.getDefaultValue() == null) {
            if (!names.contains(annotationMethod.getName())) {
              missed.add(annotationMethod.getName());
            }
          }
        }
      }

      if (!missed.isEmpty()) {
        StringBuffer buff = new StringBuffer("'" + missed.get(0) + "'");
        for (int i = 1; i < missed.size(); i++) {
          buff.append(", ");
          buff.append("'").append(missed.get(i)).append("'");
        }

        String description = JavaErrorMessages.message("annotation.missing.attribute", buff);
        return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
            .range(nameRef)
            .descriptionAndTooltip(description)
            .create();
      }
    }

    return null;
  }
コード例 #19
0
 @Override
 public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
   if (referenceFound) {
     return;
   }
   super.visitReferenceElement(reference);
   if (reference.isQualified()) {
     return;
   }
   final PsiElement target = reference.resolve();
   for (PsiMember member : members) {
     if (member.equals(target)) {
       referenceFound = true;
       return;
     }
   }
 }
コード例 #20
0
 private static PsiJavaCodeReferenceElement getQualifier(PsiElement qualifier) {
   if (qualifier instanceof PsiThisExpression) {
     final PsiJavaCodeReferenceElement thisQualifier =
         ((PsiThisExpression) qualifier).getQualifier();
     if (thisQualifier != null) {
       final PsiClass innerMostClass = PsiTreeUtil.getParentOfType(thisQualifier, PsiClass.class);
       if (innerMostClass == thisQualifier.resolve()) {
         return null;
       }
     }
     return thisQualifier;
   }
   if (qualifier != null) {
     return ((PsiSuperExpression) qualifier).getQualifier();
   }
   return null;
 }
コード例 #21
0
 /**
  * @param strict if strict is true this method checks if the conflicting class which is imported
  *     is actually used in the file. If it isn't the on demand import can be overridden with an
  *     exact import for the fqName without breaking stuff.
  */
 private static boolean hasOnDemandImportConflict(
     @NotNull String fqName, @NotNull PsiJavaFile file, boolean strict) {
   final PsiImportList imports = file.getImportList();
   if (imports == null) {
     return false;
   }
   final PsiImportStatement[] importStatements = imports.getImportStatements();
   final String shortName = ClassUtil.extractClassName(fqName);
   final String packageName = ClassUtil.extractPackageName(fqName);
   for (final PsiImportStatement importStatement : importStatements) {
     if (!importStatement.isOnDemand()) {
       continue;
     }
     final PsiJavaCodeReferenceElement importReference = importStatement.getImportReference();
     if (importReference == null) {
       continue;
     }
     final String packageText = importReference.getText();
     if (packageText.equals(packageName)) {
       continue;
     }
     final PsiElement element = importReference.resolve();
     if (element == null || !(element instanceof PsiPackage)) {
       continue;
     }
     final PsiPackage aPackage = (PsiPackage) element;
     final PsiClass[] classes = aPackage.getClasses();
     for (final PsiClass aClass : classes) {
       final String className = aClass.getName();
       if (!shortName.equals(className)) {
         continue;
       }
       if (!strict) {
         return true;
       }
       final String qualifiedClassName = aClass.getQualifiedName();
       if (qualifiedClassName == null || fqName.equals(qualifiedClassName)) {
         continue;
       }
       return containsReferenceToConflictingClass(file, qualifiedClassName);
     }
   }
   return hasJavaLangImportConflict(fqName, file);
 }
コード例 #22
0
  private static PsiFile getTargetFile(PsiElement element) {
    final PsiConstructorCall constructorCall = (PsiConstructorCall) element;

    // Enum constants constructors are file local
    if (constructorCall instanceof PsiEnumConstant) return constructorCall.getContainingFile();

    PsiJavaCodeReferenceElement referenceElement = getReferenceElement(constructorCall);
    if (referenceElement.getQualifier() instanceof PsiJavaCodeReferenceElement) {
      PsiJavaCodeReferenceElement qualifier =
          (PsiJavaCodeReferenceElement) referenceElement.getQualifier();
      PsiElement psiElement = qualifier.resolve();
      if (psiElement instanceof PsiClass) {
        PsiClass psiClass = (PsiClass) psiElement;
        return psiClass.getContainingFile();
      }
    }

    return null;
  }
コード例 #23
0
  @Nullable
  public static PsiAnnotationMemberValue findAttributeValue(
      @NotNull PsiAnnotation annotation, @Nullable @NonNls String attributeName) {
    final PsiAnnotationMemberValue value = findDeclaredAttributeValue(annotation, attributeName);
    if (value != null) return value;

    if (attributeName == null) attributeName = "value";
    final PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement();
    if (referenceElement != null) {
      PsiElement resolved = referenceElement.resolve();
      if (resolved != null) {
        PsiMethod[] methods = ((PsiClass) resolved).findMethodsByName(attributeName, false);
        for (PsiMethod method : methods) {
          if (PsiUtil.isAnnotationMethod(method)) {
            return ((PsiAnnotationMethod) method).getDefaultValue();
          }
        }
      }
    }
    return null;
  }
 @Override
 public void visitNewExpression(PsiNewExpression expression) {
   if (FileTypeUtils.isInServerPageFile(expression)) {
     return;
   }
   super.visitNewExpression(expression);
   final PsiClass containingClass = getContainingContextClass(expression);
   if (containingClass == null) {
     return;
   }
   final PsiMethod constructor = expression.resolveConstructor();
   if (constructor == null) {
     final PsiJavaCodeReferenceElement classReference =
         expression.getClassOrAnonymousClassReference();
     if (classReference == null) {
       return;
     }
     final PsiElement target = classReference.resolve();
     if (!(target instanceof PsiClass)) {
       return;
     }
     final PsiClass aClass = (PsiClass) target;
     if (!aClass.hasModifierProperty(PsiModifier.PRIVATE)) {
       return;
     }
     if (aClass.equals(containingClass)) {
       return;
     }
     registerNewExpressionError(expression, aClass);
   } else {
     if (!constructor.hasModifierProperty(PsiModifier.PRIVATE)) {
       return;
     }
     final PsiClass aClass = constructor.getContainingClass();
     if (containingClass.equals(aClass)) {
       return;
     }
     registerNewExpressionError(expression, aClass);
   }
 }
コード例 #25
0
  @Nullable
  private static HighlightInfo checkReferenceTarget(
      PsiAnnotation annotation, @Nullable PsiJavaCodeReferenceElement ref) {
    if (ref == null) return null;
    PsiElement refTarget = ref.resolve();
    if (refTarget == null) return null;

    String message = null;
    if (!(refTarget instanceof PsiClass)) {
      message = JavaErrorMessages.message("annotation.not.allowed.ref");
    } else {
      PsiElement parent = ref.getParent();
      if (parent instanceof PsiJavaCodeReferenceElement) {
        PsiElement qualified = ((PsiJavaCodeReferenceElement) parent).resolve();
        if (qualified instanceof PsiMember
            && ((PsiMember) qualified).hasModifierProperty(PsiModifier.STATIC)) {
          message = JavaErrorMessages.message("annotation.not.allowed.static");
        }
      }
    }

    return message != null ? annotationError(annotation, message) : null;
  }
 private static void makeConstructorPackageLocal(Project project, PsiElement element) {
   final PsiNewExpression newExpression =
       PsiTreeUtil.getParentOfType(element, PsiNewExpression.class);
   if (newExpression == null) {
     return;
   }
   final PsiMethod constructor = newExpression.resolveConstructor();
   if (constructor != null) {
     final PsiModifierList modifierList = constructor.getModifierList();
     modifierList.setModifierProperty(PsiModifier.PRIVATE, false);
     return;
   }
   final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement) element;
   final PsiElement target = referenceElement.resolve();
   if (!(target instanceof PsiClass)) {
     return;
   }
   final PsiClass aClass = (PsiClass) target;
   final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
   final PsiMethod newConstructor = elementFactory.createConstructor();
   final PsiModifierList modifierList = newConstructor.getModifierList();
   modifierList.setModifierProperty(PsiModifier.PACKAGE_LOCAL, true);
   aClass.add(newConstructor);
 }
コード例 #27
0
  static AllowedValues getAllowedValues(
      @NotNull PsiModifierListOwner element, PsiType type, Set<PsiClass> visited) {
    PsiAnnotation[] annotations = AnnotationUtil.getAllAnnotations(element, true, null);
    for (PsiAnnotation annotation : annotations) {
      AllowedValues values;
      if (type != null && MagicConstant.class.getName().equals(annotation.getQualifiedName())) {
        // PsiAnnotation magic = AnnotationUtil.findAnnotationInHierarchy(element,
        // Collections.singleton(MagicConstant.class.getName()));
        values = getAllowedValuesFromMagic(element, type, annotation);
        if (values != null) return values;
      }

      PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement();
      PsiElement resolved = ref == null ? null : ref.resolve();
      if (!(resolved instanceof PsiClass) || !((PsiClass) resolved).isAnnotationType()) continue;
      PsiClass aClass = (PsiClass) resolved;
      if (visited == null) visited = new THashSet<PsiClass>();
      if (!visited.add(aClass)) continue;
      values = getAllowedValues(aClass, type, visited);
      if (values != null) return values;
    }

    return parseBeanInfo(element);
  }
コード例 #28
0
  static boolean isSideEffectFreeConstructor(PsiNewExpression newExpression) {
    PsiJavaCodeReferenceElement classReference = newExpression.getClassReference();
    PsiClass aClass = classReference == null ? null : (PsiClass) classReference.resolve();
    String qualifiedName = aClass == null ? null : aClass.getQualifiedName();
    if (qualifiedName == null) return false;
    if (ourSideEffectFreeClasses.contains(qualifiedName)) return true;

    PsiFile file = aClass.getContainingFile();
    PsiDirectory directory = file.getContainingDirectory();
    PsiPackage classPackage = JavaDirectoryService.getInstance().getPackage(directory);
    String packageName = classPackage == null ? null : classPackage.getQualifiedName();

    // all Throwable descendants from java.lang are side effects free
    if ("java.lang".equals(packageName) || "java.io".equals(packageName)) {
      PsiClass throwableClass =
          JavaPsiFacade.getInstance(aClass.getProject())
              .findClass("java.lang.Throwable", aClass.getResolveScope());
      if (throwableClass != null
          && InheritanceUtil.isInheritorOrSelf(aClass, throwableClass, true)) {
        return true;
      }
    }
    return false;
  }
コード例 #29
0
  @Nullable
  public static HighlightInfo checkTargetAnnotationDuplicates(PsiAnnotation annotation) {
    PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement();
    if (nameRef == null) return null;

    PsiElement resolved = nameRef.resolve();
    if (!(resolved instanceof PsiClass)
        || !CommonClassNames.JAVA_LANG_ANNOTATION_TARGET.equals(
            ((PsiClass) resolved).getQualifiedName())) {
      return null;
    }

    PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
    if (attributes.length < 1) return null;
    PsiAnnotationMemberValue value = attributes[0].getValue();
    if (!(value instanceof PsiArrayInitializerMemberValue)) return null;
    PsiAnnotationMemberValue[] arrayInitializers =
        ((PsiArrayInitializerMemberValue) value).getInitializers();
    Set<PsiElement> targets = new HashSet<PsiElement>();
    for (PsiAnnotationMemberValue initializer : arrayInitializers) {
      if (initializer instanceof PsiReferenceExpression) {
        PsiElement target = ((PsiReferenceExpression) initializer).resolve();
        if (target != null) {
          if (targets.contains(target)) {
            String description = JavaErrorMessages.message("repeated.annotation.target");
            return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
                .range(initializer)
                .descriptionAndTooltip(description)
                .create();
          }
          targets.add(target);
        }
      }
    }
    return null;
  }
コード例 #30
0
  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;
  }