예제 #1
0
 public static MultiMap<PsiElement, UsageInfo> classifyUsages(
     Collection<? extends PsiElement> elements, UsageInfo[] usages) {
   final MultiMap<PsiElement, UsageInfo> result = new MultiMap<PsiElement, UsageInfo>();
   for (UsageInfo usage : usages) {
     LOG.assertTrue(usage instanceof MoveRenameUsageInfo);
     if (usage.getReference() instanceof LightElement) {
       continue; // filter out implicit references (e.g. from derived class to super class' default
                 // constructor)
     }
     MoveRenameUsageInfo usageInfo = (MoveRenameUsageInfo) usage;
     if (usage instanceof RelatedUsageInfo) {
       final PsiElement relatedElement = ((RelatedUsageInfo) usage).getRelatedElement();
       if (elements.contains(relatedElement)) {
         result.putValue(relatedElement, usage);
       }
     } else {
       PsiElement referenced = usageInfo.getReferencedElement();
       if (elements.contains(referenced)) {
         result.putValue(referenced, usage);
       } else if (referenced != null) {
         PsiElement indirect = referenced.getNavigationElement();
         if (elements.contains(indirect)) {
           result.putValue(indirect, usage);
         }
       }
     }
   }
   return result;
 }
예제 #2
0
  @NotNull
  private static Nullness checkNullness(final PsiElement element) {
    // null
    PsiElement value = element;
    if (value instanceof PsiExpression) {
      value = PsiUtil.deparenthesizeExpression((PsiExpression) value);
    }
    if (value instanceof PsiLiteralExpression) {
      return ((PsiLiteralExpression) value).getValue() == null
          ? Nullness.NULLABLE
          : Nullness.NOT_NULL;
    }

    // not null
    if (value instanceof PsiNewExpression) return Nullness.NOT_NULL;
    if (value instanceof PsiThisExpression) return Nullness.NOT_NULL;
    if (value instanceof PsiMethodCallExpression) {
      PsiMethod method = ((PsiMethodCallExpression) value).resolveMethod();
      if (method != null && NullableNotNullManager.isNotNull(method)) return Nullness.NOT_NULL;
      if (method != null && NullableNotNullManager.isNullable(method)) return Nullness.NULLABLE;
    }
    if (value instanceof PsiPolyadicExpression
        && ((PsiPolyadicExpression) value).getOperationTokenType() == JavaTokenType.PLUS) {
      return Nullness.NOT_NULL; // "xxx" + var
    }

    // unfortunately have to resolve here, since there can be no subnodes
    PsiElement context = value;
    if (value instanceof PsiReference) {
      PsiElement resolved = ((PsiReference) value).resolve();
      if (resolved instanceof PsiCompiledElement) {
        resolved = resolved.getNavigationElement();
      }
      value = resolved;
    }
    if (value instanceof PsiParameter
        && ((PsiParameter) value).getDeclarationScope() instanceof PsiCatchSection) {
      // exception thrown is always not null
      return Nullness.NOT_NULL;
    }

    if (value instanceof PsiLocalVariable || value instanceof PsiParameter) {
      Nullness result = DfaUtil.checkNullness((PsiVariable) value, context);
      if (result != Nullness.UNKNOWN) {
        return result;
      }
    }

    if (value instanceof PsiModifierListOwner) {
      if (NullableNotNullManager.isNotNull((PsiModifierListOwner) value)) return Nullness.NOT_NULL;
      if (NullableNotNullManager.isNullable((PsiModifierListOwner) value)) return Nullness.NULLABLE;
    }

    if (value instanceof PsiEnumConstant) return Nullness.NOT_NULL;
    return Nullness.UNKNOWN;
  }
 @Nullable
 private static Map<PsiFile, PsiClass[]> convertToTopLevelClasses(
     final PsiElement[] elements,
     final boolean fromUpdate,
     String relativePath,
     Map<PsiFile, String> relativeMap) {
   final Map<PsiFile, PsiClass[]> result = new HashMap<PsiFile, PsiClass[]>();
   for (PsiElement element : elements) {
     final PsiElement navigationElement = element.getNavigationElement();
     LOG.assertTrue(navigationElement != null, element);
     final PsiFile containingFile = navigationElement.getContainingFile();
     if (!(containingFile instanceof PsiClassOwner
         && ProjectRootsUtil.isOutsideSourceRoot(containingFile))) {
       PsiClass[] topLevelClasses = getTopLevelClasses(element);
       if (topLevelClasses == null) {
         if (element instanceof PsiDirectory) {
           if (!fromUpdate) {
             final String name = ((PsiDirectory) element).getName();
             final String path =
                 relativePath != null
                     ? (relativePath.length() > 0 ? (relativePath + "/") : "") + name
                     : null;
             final Map<PsiFile, PsiClass[]> map =
                 convertToTopLevelClasses(element.getChildren(), fromUpdate, path, relativeMap);
             if (map == null) return null;
             for (Map.Entry<PsiFile, PsiClass[]> entry : map.entrySet()) {
               fillResultsMap(result, entry.getKey(), entry.getValue());
             }
           }
           continue;
         }
         if (!(element instanceof PsiFileSystemItem)) return null;
       }
       fillResultsMap(result, containingFile, topLevelClasses);
       if (relativeMap != null) {
         relativeMap.put(containingFile, relativePath);
       }
     }
   }
   if (result.isEmpty()) {
     return null;
   } else {
     boolean hasClasses = false;
     for (PsiClass[] classes : result.values()) {
       if (classes != null) {
         hasClasses = true;
         break;
       }
     }
     return hasClasses ? result : null;
   }
 }
예제 #4
0
  public void registerReference(
      @NotNull PsiJavaReference ref, @NotNull JavaResolveResult resolveResult) {
    PsiElement refElement = resolveResult.getElement();
    PsiFile psiFile = refElement == null ? null : refElement.getContainingFile();
    if (psiFile != null)
      psiFile =
          (PsiFile)
              psiFile
                  .getNavigationElement(); // look at navigation elements because all references
                                           // resolve into Cls elements when highlighting library
                                           // source
    if (refElement != null
        && psiFile != null
        && myFile.getViewProvider().equals(psiFile.getViewProvider())) {
      registerLocalRef(ref, refElement.getNavigationElement());
    }

    PsiElement resolveScope = resolveResult.getCurrentFileResolveScope();
    if (resolveScope instanceof PsiImportStatementBase) {
      registerImportStatement(ref, (PsiImportStatementBase) resolveScope);
    }
  }
  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);
  }