public static PsiType getLambdaParameterType(PsiParameter param) { final PsiElement paramParent = param.getParent(); if (paramParent instanceof PsiParameterList) { final int parameterIndex = ((PsiParameterList) paramParent).getParameterIndex(param); if (parameterIndex > -1) { final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(param, PsiLambdaExpression.class); if (lambdaExpression != null) { PsiType type = getFunctionalInterfaceType(lambdaExpression, true, parameterIndex); if (type == null) { type = getFunctionalInterfaceType(lambdaExpression, false); } if (type instanceof PsiIntersectionType) { final PsiType[] conjuncts = ((PsiIntersectionType) type).getConjuncts(); for (PsiType conjunct : conjuncts) { final PsiType lambdaParameterFromType = getLambdaParameterFromType(parameterIndex, lambdaExpression, conjunct); if (lambdaParameterFromType != null) return lambdaParameterFromType; } } else { final PsiType lambdaParameterFromType = getLambdaParameterFromType(parameterIndex, lambdaExpression, type); if (lambdaParameterFromType != null) { return lambdaParameterFromType; } } } } } return new PsiLambdaParameterType(param); }
private static PsiAnnotation[] getHierarchyAnnotations( PsiModifierListOwner listOwner, PsiModifierList modifierList) { final Set<PsiAnnotation> all = new HashSet<PsiAnnotation>() { public boolean add(PsiAnnotation o) { // don't overwrite "higher level" annotations return !contains(o) && super.add(o); } }; if (listOwner instanceof PsiMethod) { ContainerUtil.addAll(all, modifierList.getAnnotations()); SuperMethodsSearch.search((PsiMethod) listOwner, null, true, true) .forEach( new Processor<MethodSignatureBackedByPsiMethod>() { public boolean process(final MethodSignatureBackedByPsiMethod superMethod) { ContainerUtil.addAll( all, superMethod.getMethod().getModifierList().getAnnotations()); return true; } }); return all.toArray(new PsiAnnotation[all.size()]); } if (listOwner instanceof PsiParameter) { PsiParameter parameter = (PsiParameter) listOwner; PsiElement declarationScope = parameter.getDeclarationScope(); PsiParameterList parameterList; if (declarationScope instanceof PsiMethod && parameter.getParent() == (parameterList = ((PsiMethod) declarationScope).getParameterList())) { PsiMethod method = (PsiMethod) declarationScope; final int parameterIndex = parameterList.getParameterIndex(parameter); ContainerUtil.addAll(all, modifierList.getAnnotations()); SuperMethodsSearch.search(method, null, true, true) .forEach( new Processor<MethodSignatureBackedByPsiMethod>() { public boolean process(final MethodSignatureBackedByPsiMethod superMethod) { PsiParameter superParameter = superMethod.getMethod().getParameterList().getParameters()[parameterIndex]; PsiModifierList modifierList = superParameter.getModifierList(); if (modifierList != null) { ContainerUtil.addAll(all, modifierList.getAnnotations()); } return true; } }); return all.toArray(new PsiAnnotation[all.size()]); } } return modifierList.getAnnotations(); }
private static void fixExceptions(PsiElement ref, PsiClassType[] newExceptions) throws IncorrectOperationException { // methods' throws lists are already modified, may use ExceptionUtil.collectUnhandledExceptions newExceptions = filterCheckedExceptions(newExceptions); PsiElement context = PsiTreeUtil.getParentOfType(ref, PsiTryStatement.class, PsiMethod.class); if (context instanceof PsiTryStatement) { PsiTryStatement tryStatement = (PsiTryStatement) context; PsiCodeBlock tryBlock = tryStatement.getTryBlock(); // Remove unused catches Collection<PsiClassType> classes = ExceptionUtil.collectUnhandledExceptions(tryBlock, tryBlock); PsiParameter[] catchParameters = tryStatement.getCatchBlockParameters(); for (PsiParameter parameter : catchParameters) { final PsiType caughtType = parameter.getType(); if (!(caughtType instanceof PsiClassType)) continue; if (ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType) caughtType)) continue; if (!isCatchParameterRedundant((PsiClassType) caughtType, classes)) continue; parameter.getParent().delete(); // delete catch section } PsiClassType[] exceptionsToAdd = filterUnhandledExceptions(newExceptions, tryBlock); addExceptions(exceptionsToAdd, tryStatement); adjustPossibleEmptyTryStatement(tryStatement); } else { newExceptions = filterUnhandledExceptions(newExceptions, ref); if (newExceptions.length > 0) { // Add new try statement PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(ref.getProject()); PsiTryStatement tryStatement = (PsiTryStatement) elementFactory.createStatementFromText("try {} catch (Exception e) {}", null); PsiStatement anchor = PsiTreeUtil.getParentOfType(ref, PsiStatement.class); LOG.assertTrue(anchor != null); tryStatement.getTryBlock().add(anchor); tryStatement = (PsiTryStatement) anchor.getParent().addAfter(tryStatement, anchor); addExceptions(newExceptions, tryStatement); anchor.delete(); tryStatement.getCatchSections()[0].delete(); // Delete dummy catch section } } }
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); }