List<PsiSwitchLabelStatementBase> (@NotNull PsiSwitchBlock switchBlock, @NotNull List<String> allNames, @NotNull Collection<String> missingNames, @NotNull Function<? super PsiSwitchLabelStatementBase, ? extends List<String>> caseExtractor) { final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(switchBlock.getProject()); boolean isRuleBasedFormat = SwitchUtils.isRuleFormatSwitch(switchBlock); final PsiCodeBlock body = switchBlock.getBody(); final PsiExpression switchExpression = switchBlock.getExpression(); PsiClass selectorClass = PsiUtil.resolveClassInClassTypeOnly(switchExpression != null ? switchExpression.getType() : null); boolean hasSealedClass = selectorClass != null && (selectorClass.hasModifierProperty(PsiModifier.SEALED) || (selectorClass instanceof PsiTypeParameter typeParameter && ContainerUtil.exists(typeParameter.getExtendsListTypes(), extType -> { PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(extType); return psiClass != null && psiClass.hasModifierProperty(PsiModifier.SEALED); }))); boolean isPatternsGenerated = selectorClass != null && !selectorClass.isEnum() && hasSealedClass; if (body == null) { // replace entire switch statement if no code block is present @NonNls final StringBuilder newStatementText = new StringBuilder(); CommentTracker commentTracker = new CommentTracker(); newStatementText.append("switch(").append(switchExpression == null ? "" : commentTracker.text(switchExpression)).append("){"); for (String missingName : missingNames) { newStatementText.append(String.join("", generateStatements(missingName, switchBlock, isRuleBasedFormat, isPatternsGenerated))); } newStatementText.append('}'); PsiSwitchBlock block = (PsiSwitchBlock)commentTracker.replaceAndRestoreComments(switchBlock, newStatementText.toString()); javaCodeStyleManager.shortenClassReferences(block); return PsiTreeUtil.getChildrenOfTypeAsList(block.getBody(), PsiSwitchLabelStatementBase.class); } Map<String, String> prevToNext = StreamEx.of(allNames).pairMap(Couple::of).toMap(c -> c.getFirst(), c -> c.getSecond()); List<String> missingLabels = ContainerUtil.filter(allNames, missingNames::contains); String nextLabel = getNextLabel(prevToNext, missingLabels); PsiElement bodyElement = body.getFirstBodyElement(); List<PsiSwitchLabelStatementBase> addedLabels = new ArrayList<>(); if (bodyElement instanceof PsiWhiteSpace && bodyElement == body.getLastBodyElement()) { bodyElement.delete(); bodyElement = null; } while (bodyElement != null) { PsiSwitchLabelStatementBase label = ObjectUtils.tryCast(bodyElement, PsiSwitchLabelStatementBase.class); if (label != null) { List<String> caseLabelNames = caseExtractor.apply(label); while (nextLabel != null && caseLabelNames.contains(nextLabel)) { addedLabels.add(addSwitchLabelStatementBefore(missingLabels.get(0), bodyElement, switchBlock, isRuleBasedFormat, isPatternsGenerated)); missingLabels = missingLabels.subList(1, missingLabels.size()); if (missingLabels.isEmpty()) { break; } nextLabel = getNextLabel(prevToNext, missingLabels); } if (SwitchUtils.isDefaultLabel(label)) { for (String missingElement : missingLabels) { addedLabels.add(addSwitchLabelStatementBefore(missingElement, bodyElement, switchBlock, isRuleBasedFormat, isPatternsGenerated)); } missingLabels = Collections.emptyList(); break; } } bodyElement = bodyElement.getNextSibling(); } if (!missingLabels.isEmpty()) { final PsiElement lastChild = body.getLastChild(); for (String missingElement : missingLabels) { addedLabels.add(addSwitchLabelStatementBefore(missingElement, lastChild, switchBlock, isRuleBasedFormat, isPatternsGenerated)); } } addedLabels.forEach(label -> javaCodeStyleManager.shortenClassReferences(label)); return addedLabels; }