private static AllowedValues getAllowedValuesFromMagic(
      @NotNull PsiModifierListOwner element, @NotNull PsiType type, PsiAnnotation magic) {
    if (magic == null) return null;
    PsiAnnotationMemberValue[] allowedValues;
    final boolean canBeOred;
    if (TypeConversionUtil.getTypeRank(type) <= TypeConversionUtil.LONG_RANK) {
      PsiAnnotationMemberValue intValues = magic.findAttributeValue("intValues");
      allowedValues =
          intValues instanceof PsiArrayInitializerMemberValue
              ? ((PsiArrayInitializerMemberValue) intValues).getInitializers()
              : PsiAnnotationMemberValue.EMPTY_ARRAY;
      if (allowedValues.length == 0) {
        PsiAnnotationMemberValue orValue = magic.findAttributeValue("flags");
        allowedValues =
            orValue instanceof PsiArrayInitializerMemberValue
                ? ((PsiArrayInitializerMemberValue) orValue).getInitializers()
                : PsiAnnotationMemberValue.EMPTY_ARRAY;
        canBeOred = true;
      } else {
        canBeOred = false;
      }
    } else if (type.equals(
        PsiType.getJavaLangString(
            element.getManager(), GlobalSearchScope.allScope(element.getProject())))) {
      PsiAnnotationMemberValue strValuesAttr = magic.findAttributeValue("stringValues");
      allowedValues =
          strValuesAttr instanceof PsiArrayInitializerMemberValue
              ? ((PsiArrayInitializerMemberValue) strValuesAttr).getInitializers()
              : PsiAnnotationMemberValue.EMPTY_ARRAY;
      canBeOred = false;
    } else {
      return null; // other types not supported
    }

    if (allowedValues.length != 0) {
      return new AllowedValues(allowedValues, canBeOred);
    }

    // last resort: try valuesFromClass
    PsiAnnotationMemberValue[] values = readFromClass("valuesFromClass", magic, type);
    boolean ored = false;
    if (values == null) {
      values = readFromClass("flagsFromClass", magic, type);
      ored = true;
    }
    if (values == null) return null;
    return new AllowedValues(values, ored);
  }
Beispiel #2
0
 private static void annotate(
     final PsiElementFactory factory,
     final PsiModifierListOwner listOwner,
     final String annotationQName)
     throws IncorrectOperationException {
   final PsiModifierList modifierList = listOwner.getModifierList();
   LOG.assertTrue(modifierList != null);
   modifierList.addAfter(factory.createAnnotationFromText("@" + annotationQName, listOwner), null);
 }
  public void setCorrectVisibility(final HashSet<PsiMember> movedMembers, GrMemberInfo info) {
    PsiModifierListOwner modifierListOwner = info.getMember();
    if (myTargetSuperClass.isInterface()) {
      PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PUBLIC, true);
    } else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) {
      if (info.isToAbstract()
          || willBeUsedInSubclass(
              modifierListOwner, movedMembers, myTargetSuperClass, mySourceClass)) {
        PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PROTECTED, true);
      }

      if (modifierListOwner instanceof GrTypeDefinition) {
        ((GrTypeDefinition) modifierListOwner)
            .accept(
                new GroovyRecursiveElementVisitor() {
                  @Override
                  public void visitMethod(GrMethod method) {
                    check(method);
                  }

                  @Override
                  public void visitField(GrField field) {
                    check(field);
                  }

                  @Override
                  public void visitTypeDefinition(GrTypeDefinition typeDefinition) {
                    check(typeDefinition);
                    super.visitTypeDefinition(typeDefinition);
                  }

                  private void check(PsiMember member) {
                    if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
                      if (willBeUsedInSubclass(
                          member, movedMembers, myTargetSuperClass, mySourceClass)) {
                        PsiUtil.setModifierProperty(member, PsiModifier.PROTECTED, true);
                      }
                    }
                  }
                });
      }
    }
  }
  @Override
  public void setCorrectVisibility(MemberInfo info) {
    PsiModifierListOwner modifierListOwner = info.getMember();
    if (myIsTargetInterface) {
      PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PUBLIC, true);
    } else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) {
      if (info.isToAbstract()
          || willBeUsedInSubclass(modifierListOwner, myTargetSuperClass, mySourceClass)) {
        PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PROTECTED, true);
      }
      if (modifierListOwner instanceof PsiClass) {
        modifierListOwner.accept(
            new JavaRecursiveElementWalkingVisitor() {
              @Override
              public void visitMethod(PsiMethod method) {
                check(method);
              }

              @Override
              public void visitField(PsiField field) {
                check(field);
              }

              @Override
              public void visitClass(PsiClass aClass) {
                check(aClass);
                super.visitClass(aClass);
              }

              private void check(PsiMember member) {
                if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
                  if (willBeUsedInSubclass(member, myTargetSuperClass, mySourceClass)) {
                    PsiUtil.setModifierProperty(member, PsiModifier.PROTECTED, true);
                  }
                }
              }
            });
      }
    }
  }
  public boolean execute(PsiElement element, ResolveState state) {
    //noinspection SuspiciousMethodCalls
    if (myNonInitializedFields.contains(element)) {
      return true;
    }

    if (!(element instanceof PsiClass) && element instanceof PsiModifierListOwner) {
      PsiModifierListOwner modifierListOwner = (PsiModifierListOwner) element;
      if (myStatic) {
        if (!modifierListOwner.hasModifierProperty(PsiModifier.STATIC)) {
          // we don't need non static method in static context.
          return true;
        }
      } else {
        if (!mySettings.SHOW_STATIC_AFTER_INSTANCE
            && modifierListOwner.hasModifierProperty(PsiModifier.STATIC)
            && !myMembersFlag) {
          // according settings we don't need to process such fields/methods
          return true;
        }
      }
    }
    final PsiElement elementParent = myElement.getParent();
    if (element instanceof PsiPackage && myScope instanceof PsiClass) {
      if (!(elementParent instanceof PsiQualifiedReference
          && ((PsiQualifiedReference) elementParent).getQualifier() != null)) {
        return true;
      }
    }

    if (satisfies(element, state) && isAccessible(element)) {
      CompletionElement element1 =
          new CompletionElement(
              myQualifierType, element, state.get(PsiSubstitutor.KEY), myQualifierClass);
      if (myResultNames.add(element1.getUniqueId())) {
        myResults.add(element1);
      }
    }
    return true;
  }
 private static boolean hasAnnotation(
     PsiModifierListOwner modifierListOwner, String qualifiedName) {
   PsiModifierList modifierList = modifierListOwner.getModifierList();
   if (modifierList != null) {
     for (PsiAnnotation annotation : modifierList.getAnnotations()) {
       if (annotation instanceof ClsAnnotationImpl) {
         if (qualifiedName.equals(annotation.getQualifiedName())) {
           return true;
         }
       }
     }
   }
   return false;
 }
  @Nullable
  private static PsiAnnotation findContainerAnnotation(
      PsiModifierListOwner owner, String annotationFQN) {
    PsiElement element = owner.getParent();
    while (element != null) {
      if (element instanceof PsiModifierListOwner) {
        PsiAnnotation annotation =
            AnnotationUtil.findAnnotation((PsiModifierListOwner) element, annotationFQN);
        if (annotation != null) {
          return annotation;
        }
      }

      if (element instanceof PsiClassOwner) {
        String packageName = ((PsiClassOwner) element).getPackageName();
        PsiPackage psiPackage =
            JavaPsiFacade.getInstance(element.getProject()).findPackage(packageName);
        return AnnotationUtil.findAnnotation(psiPackage, annotationFQN);
      }

      element = element.getContext();
    }
    return null;
  }
  private static AllowedValues parseBeanInfo(@NotNull PsiModifierListOwner owner) {
    PsiMethod method = null;
    if (owner instanceof PsiParameter) {
      PsiParameter parameter = (PsiParameter) owner;
      PsiElement scope = parameter.getDeclarationScope();
      if (!(scope instanceof PsiMethod)) return null;
      PsiElement nav = scope.getNavigationElement();
      if (!(nav instanceof PsiMethod)) return null;
      method = (PsiMethod) nav;
      if (method.isConstructor()) {
        // not a property, try the @ConstructorProperties({"prop"})
        PsiAnnotation annotation =
            AnnotationUtil.findAnnotation(method, "java.beans.ConstructorProperties");
        if (annotation == null) return null;
        PsiAnnotationMemberValue value = annotation.findAttributeValue("value");
        if (!(value instanceof PsiArrayInitializerMemberValue)) return null;
        PsiAnnotationMemberValue[] initializers =
            ((PsiArrayInitializerMemberValue) value).getInitializers();
        PsiElement parent = parameter.getParent();
        if (!(parent instanceof PsiParameterList)) return null;
        int index = ((PsiParameterList) parent).getParameterIndex(parameter);
        if (index >= initializers.length) return null;
        PsiAnnotationMemberValue initializer = initializers[index];
        if (!(initializer instanceof PsiLiteralExpression)) return null;
        Object val = ((PsiLiteralExpression) initializer).getValue();
        if (!(val instanceof String)) return null;
        PsiMethod setter =
            PropertyUtil.findPropertySetter(
                method.getContainingClass(), (String) val, false, false);
        if (setter == null) return null;
        // try the @beaninfo of the corresponding setter
        method = (PsiMethod) setter.getNavigationElement();
      }
    } else if (owner instanceof PsiMethod) {
      PsiElement nav = owner.getNavigationElement();
      if (!(nav instanceof PsiMethod)) return null;
      method = (PsiMethod) nav;
    }
    if (method == null) return null;

    PsiClass aClass = method.getContainingClass();
    if (aClass == null) return null;
    if (PropertyUtil.isSimplePropertyGetter(method)) {
      List<PsiMethod> setters =
          PropertyUtil.getSetters(aClass, PropertyUtil.getPropertyNameByGetter(method));
      if (setters.size() != 1) return null;
      method = setters.get(0);
    }
    if (!PropertyUtil.isSimplePropertySetter(method)) return null;
    PsiDocComment doc = method.getDocComment();
    if (doc == null) return null;
    PsiDocTag beaninfo = doc.findTagByName("beaninfo");
    if (beaninfo == null) return null;
    String data =
        StringUtil.join(
            beaninfo.getDataElements(),
            new Function<PsiElement, String>() {
              @Override
              public String fun(PsiElement element) {
                return element.getText();
              }
            },
            "\n");
    int enumIndex = StringUtil.indexOfSubstringEnd(data, "enum:");
    if (enumIndex == -1) return null;
    data = data.substring(enumIndex);
    int colon = data.indexOf(":");
    int last = colon == -1 ? data.length() : data.substring(0, colon).lastIndexOf("\n");
    data = data.substring(0, last);

    List<PsiAnnotationMemberValue> values = new ArrayList<PsiAnnotationMemberValue>();
    for (String line : StringUtil.splitByLines(data)) {
      List<String> words = StringUtil.split(line, " ", true, true);
      if (words.size() != 2) continue;
      String ref = words.get(1);
      PsiExpression constRef =
          JavaPsiFacade.getElementFactory(aClass.getProject())
              .createExpressionFromText(ref, aClass);
      if (!(constRef instanceof PsiReferenceExpression)) continue;
      PsiReferenceExpression expr = (PsiReferenceExpression) constRef;
      values.add(expr);
    }
    if (values.isEmpty()) return null;
    PsiAnnotationMemberValue[] array = values.toArray(new PsiAnnotationMemberValue[values.size()]);
    return new AllowedValues(array, false);
  }
  @Override
  @Nullable
  public List<PsiFile> findExternalAnnotationsFiles(@NotNull PsiModifierListOwner listOwner) {
    final PsiFile containingFile = listOwner.getContainingFile();
    if (!(containingFile instanceof PsiJavaFile)) {
      return null;
    }
    final PsiJavaFile javaFile = (PsiJavaFile) containingFile;
    final String packageName = javaFile.getPackageName();
    final VirtualFile virtualFile = containingFile.getVirtualFile();
    if (virtualFile == null) return null;

    final List<PsiFile> files = myExternalAnnotations.get(virtualFile);
    if (files == NULL_LIST) return null;
    if (files != null) {
      boolean allValid = true;
      for (PsiFile file : files) {
        allValid &= file.isValid();
      }
      if (allValid) {
        return files;
      }
    }

    if (virtualFile == null) {
      return null;
    }

    Set<PsiFile> possibleAnnotationsXmls = new THashSet<PsiFile>();
    for (VirtualFile root : getExternalAnnotationsRoots(virtualFile)) {
      final VirtualFile ext =
          root.findFileByRelativePath(packageName.replace('.', '/') + "/" + ANNOTATIONS_XML);
      if (ext == null) continue;
      final PsiFile psiFile = myPsiManager.findFile(ext);
      if (psiFile == null) continue;
      possibleAnnotationsXmls.add(psiFile);
    }
    List<PsiFile> result;
    if (possibleAnnotationsXmls.isEmpty()) {
      myExternalAnnotations.put(virtualFile, NULL_LIST);
      result = null;
    } else {
      result = new SmartList<PsiFile>(possibleAnnotationsXmls);
      // sorting by writability: writable go first
      Collections.sort(
          result,
          new Comparator<PsiFile>() {
            @Override
            public int compare(PsiFile f1, PsiFile f2) {
              boolean w1 = f1.isWritable();
              boolean w2 = f2.isWritable();
              if (w1 == w2) {
                return 0;
              }
              return w1 ? -1 : 1;
            }
          });

      myExternalAnnotations.put(virtualFile, result);
    }
    return result;
  }
 public static boolean isNotNull(@NotNull PsiModifierListOwner owner) {
   return getInstance(owner.getProject()).isNotNull(owner, true);
 }
  public static boolean hasTest(
      PsiModifierListOwner element,
      boolean checkHierarchy,
      boolean checkDisabled,
      boolean checkJavadoc) {
    // LanguageLevel effectiveLanguageLevel = element.getManager().getEffectiveLanguageLevel();
    // boolean is15 = effectiveLanguageLevel != LanguageLevel.JDK_1_4 && effectiveLanguageLevel !=
    // LanguageLevel.JDK_1_3;
    boolean hasAnnotation =
        AnnotationUtil.isAnnotated(element, TEST_ANNOTATION_FQN, checkHierarchy, true);
    if (hasAnnotation) {
      if (checkDisabled) {
        PsiAnnotation annotation =
            AnnotationUtil.findAnnotation(element, true, TEST_ANNOTATION_FQN);
        if (annotation != null) {
          if (isDisabled(annotation)) return false;
        }
      }
      return true;
    }
    if (element instanceof PsiDocCommentOwner
        && checkJavadoc
        && getTextJavaDoc((PsiDocCommentOwner) element) != null) return true;
    // now we check all methods for the test annotation
    if (element instanceof PsiClass) {
      PsiClass psiClass = (PsiClass) element;
      for (PsiMethod method : psiClass.getAllMethods()) {
        PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, true, TEST_ANNOTATION_FQN);
        if (annotation != null) {
          if (checkDisabled) {
            if (isDisabled(annotation)) continue;
          }
          return true;
        }
        if (AnnotationUtil.isAnnotated(method, FACTORY_ANNOTATION_FQN, false, true)) return true;
        if (checkJavadoc && getTextJavaDoc(method) != null) return true;
      }
      return false;
    } else if (element instanceof PsiMethod) {
      // even if it has a global test, we ignore private and static methods
      if (element.hasModifierProperty(PsiModifier.PRIVATE)
          || element.hasModifierProperty(PsiModifier.STATIC)) {
        return false;
      }

      // if it's a method, we check if the class it's in has a global @Test annotation
      PsiClass psiClass = ((PsiMethod) element).getContainingClass();
      if (psiClass != null) {
        final PsiAnnotation annotation =
            checkHierarchy
                ? AnnotationUtil.findAnnotationInHierarchy(
                    psiClass, Collections.singleton(TEST_ANNOTATION_FQN))
                : AnnotationUtil.findAnnotation(psiClass, true, TEST_ANNOTATION_FQN);
        if (annotation != null) {
          if (checkDisabled && isDisabled(annotation)) return false;
          return !hasConfig(element);
        } else if (checkJavadoc && getTextJavaDoc(psiClass) != null) return true;
      }
    }
    return false;
  }