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; }
@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; } }
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); }