boolean (@NotNull PsiSwitchStatement switchStatement, @Nullable PsiMethod method) { if (statementIsBreakTarget(switchStatement)) { return true; } final PsiExpression selectorExpression = switchStatement.getExpression(); if (selectorExpression == null) { return true; } final PsiType selectorType = selectorExpression.getType(); if (selectorType == null) { return true; } final PsiCodeBlock body = switchStatement.getBody(); if (body == null) { return true; } final PsiStatement[] statements = body.getStatements(); if (statements.length == 0) { return true; } int numCases = 0; boolean hasDefaultCase = false, hasUnconditionalPattern = false; for (PsiStatement statement : statements) { if (statement instanceof PsiSwitchLabelStatementBase switchLabelStatement) { if (statement instanceof PsiSwitchLabelStatement) { numCases++; } if (hasDefaultCase || hasUnconditionalPattern) { continue; } if (switchLabelStatement.isDefaultCase()) { hasDefaultCase = true; continue; } // this information doesn't exist in spec draft (14.22) for pattern in switch as expected // but for now javac considers the switch statement containing at least either case default label element or an unconditional pattern "incomplete normally" PsiCaseLabelElementList labelElementList = switchLabelStatement.getCaseLabelElementList(); if (labelElementList == null) { continue; } for (PsiCaseLabelElement labelElement : labelElementList.getElements()) { if (labelElement instanceof PsiDefaultCaseLabelElement) { hasDefaultCase = true; } else if (labelElement instanceof PsiPattern) { hasUnconditionalPattern = JavaPsiPatternUtil.isUnconditionalForType(labelElement, selectorType); } } } else if (statement instanceof final PsiBreakStatement breakStatement && breakStatement.getLabelIdentifier() == null) { return true; } } // todo actually there is no information about an impact of enum constants on switch statements being complete normally in spec (Unreachable statements) // todo comparing to javac that produces some false-negative highlighting in enum switch statements containing all possible constants final boolean isEnum = isEnumSwitch(switchStatement); if (!hasDefaultCase && !hasUnconditionalPattern && !isEnum) { return true; } if (!hasDefaultCase && !hasUnconditionalPattern) { final PsiClass aClass = ((PsiClassType)selectorType).resolve(); if (aClass == null) { return true; } if (!hasChildrenOfTypeCount(aClass, numCases, PsiEnumConstant.class)) { return true; } } // todo replace the code and comments below with the method that helps to understand whether // todo we need to check every statement or only the last statement in the code block // 14.22. Unreachable Statements // We need to check every rule's body not just the last one if the switch block includes the switch rules boolean isLabeledRuleSwitch = statements[0] instanceof PsiSwitchLabeledRuleStatement; if (isLabeledRuleSwitch) { for (PsiStatement statement : statements) { if (statementMayCompleteNormally(statement, method)) { return true; } } return false; } return statementMayCompleteNormally(statements[statements.length - 1], method); }