ModCommand (@NotNull ActionContext context, @NotNull PsiMethod method) { Project project = context.project(); PsiClassType exception = JavaPsiFacade.getElementFactory(project).createTypeByFQClassName(myThrowsCanonicalText, method.getResolveScope()); ModCommand action = ModCommand.psiUpdate(method, m -> processMethod(project, m)); if (!IntentionPreviewUtils.isIntentionPreviewActive() && !ExceptionUtil.isUncheckedException(exception)) { JavaMethodFindUsagesOptions ops = new JavaMethodFindUsagesOptions(project); ops.isSearchForTextOccurrences = false; ops.isImplicitToString = false; ops.isSkipImportStatements = true; Map<PsiElement, ModShowConflicts.Conflict> conflicts = new HashMap<>(); JavaFindUsagesHelper.processElementUsages( method, ops, usage -> { PsiElement element = usage.getElement(); if (!(element instanceof PsiReferenceExpression)) return true; PsiElement parent = element.getParent(); if (parent instanceof PsiCallExpression) { ExceptionUtil.HandlePlace place = ExceptionUtil.getHandlePlace(parent, exception, null); if (place instanceof ExceptionUtil.HandlePlace.TryCatch tryCatch) { PsiParameter parameter = tryCatch.getParameter(); PsiCodeBlock block = tryCatch.getTryStatement().getTryBlock(); if (block != null) { PsiCallExpression call = (PsiCallExpression)parent; Collection<PsiClassType> types = ExceptionUtil.collectUnhandledExceptions(block, null, call); if (types.contains(exception)) { return true; } List<PsiClassType> thrownCheckedExceptions = new ArrayList<>(ExceptionUtil.getThrownCheckedExceptions(call)); thrownCheckedExceptions.remove(exception); PsiType caughtExceptionType = parameter.getType(); if (Stream.concat(types.stream(), thrownCheckedExceptions.stream()) .noneMatch(ex -> caughtExceptionType.isAssignableFrom(ex))) { conflicts.put(parameter, new ModShowConflicts.Conflict(List.of( JavaAnalysisBundle.message("exception.handler.will.become.unreachable")))); } } } } return true; }); return new ModShowConflicts(conflicts, action); } return action; }