PsiElementVisitor (@NotNull final ProblemsHolder holder, boolean isOnTheFly, @NotNull LocalInspectionToolSession session) { return new JavaElementVisitor() { @Override public void visitJavaFile(@NotNull PsiJavaFile file) { if (!InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file)) { Runnable fix = getAttachAnnotationsJarFix(file.getProject()); if (fix != null) { fix.run(); // try to attach automatically } } } @Override public void visitEnumConstant(@NotNull PsiEnumConstant enumConstant) { checkCall(enumConstant, holder); } @Override public void visitCallExpression(@NotNull PsiCallExpression callExpression) { checkCall(callExpression, holder); } @Override public void visitAssignmentExpression(@NotNull PsiAssignmentExpression expression) { PsiExpression r = expression.getRExpression(); if (r != null && expression.getLExpression() instanceof PsiReferenceExpression ref && ref.resolve() instanceof PsiModifierListOwner owner) { PsiType type = expression.getType(); checkExpression(r, owner, type, holder); } } @Override public void visitVariable(@NotNull PsiVariable variable) { PsiExpression initializer = variable.getInitializer(); if (initializer != null) { checkExpression(initializer, variable, variable.getType(), holder); } } @Override public void visitReturnStatement(@NotNull PsiReturnStatement statement) { PsiExpression value = statement.getReturnValue(); if (value == null) return; PsiElement element = PsiTreeUtil.getParentOfType(statement, PsiMethod.class, PsiLambdaExpression.class); PsiMethod method = element instanceof PsiMethod ? (PsiMethod)element : LambdaUtil.getFunctionalInterfaceMethod(element); if (method == null) return; checkExpression(value, method, value.getType(), holder); } @Override public void visitNameValuePair(@NotNull PsiNameValuePair pair) { PsiAnnotationMemberValue value = pair.getValue(); if (!(value instanceof PsiExpression expression)) return; PsiReference ref = pair.getReference(); if (ref == null) return; PsiMethod method = (PsiMethod)ref.resolve(); if (method == null) return; checkExpression(expression, method, method.getReturnType(), holder); } @Override public void visitBinaryExpression(@NotNull PsiBinaryExpression expression) { IElementType tokenType = expression.getOperationTokenType(); if (tokenType != JavaTokenType.EQEQ && tokenType != JavaTokenType.NE) return; PsiExpression l = expression.getLOperand(); PsiExpression r = expression.getROperand(); if (r == null) return; checkBinary(l, r); checkBinary(r, l); } @Override public void visitCaseLabelElementList(@NotNull PsiCaseLabelElementList list) { PsiSwitchBlock switchBlock = PsiTreeUtil.getParentOfType(list, PsiSwitchBlock.class); if (switchBlock == null) return; PsiExpression selector = switchBlock.getExpression(); PsiModifierListOwner owner = null; if (selector instanceof PsiReference ref) { owner = ObjectUtils.tryCast(ref.resolve(), PsiModifierListOwner.class); } else if (selector instanceof PsiMethodCallExpression call) { owner = call.resolveMethod(); } if (owner == null) return; for (PsiCaseLabelElement element : list.getElements()) { if (element instanceof PsiExpression expression) { checkExpression(expression, owner, PsiUtil.getTypeByPsiElement(owner), holder); } } } private void checkBinary(@NotNull PsiExpression l, @NotNull PsiExpression r) { if (l instanceof PsiReference ref && ref.resolve() instanceof PsiModifierListOwner owner) { checkExpression(r, owner, PsiUtil.getTypeByPsiElement(owner), holder); } else if (l instanceof PsiMethodCallExpression call) { PsiMethod method = call.resolveMethod(); if (method != null) { checkExpression(r, method, method.getReturnType(), holder); checkExpression(r, holder, SPECIAL_CASES.mapFirst(call)); } } } }; }