diff --git a/java/java-analysis-impl/resources/messages/InspectionGadgetsBundle.properties b/java/java-analysis-impl/resources/messages/InspectionGadgetsBundle.properties index e18f3acbc04d..0a2f283028ba 100644 --- a/java/java-analysis-impl/resources/messages/InspectionGadgetsBundle.properties +++ b/java/java-analysis-impl/resources/messages/InspectionGadgetsBundle.properties @@ -2391,6 +2391,7 @@ markdown.documentation.comments.migration.display.name=Javadoc comment can be Ma markdown.documentation.comments.migration.fix=Convert to Markdown documentation comment inspection.clamp.migration.display.name=Clamp function can be used +comparator.min.max.can.be.used.display.name='Comparator.min()' or 'Comparator.max()' can be used array.hash.code.fix.family.name=Replace with 'Arrays.hashCode()' call objects.hash.fix.family.name=Wrap with 'Arrays.hashCode()' diff --git a/java/java-analysis-impl/src/com/siyeh/ig/migration/ComparatorMinMaxCanBeUsedInspection.java b/java/java-analysis-impl/src/com/siyeh/ig/migration/ComparatorMinMaxCanBeUsedInspection.java new file mode 100644 index 000000000000..6a3a2e65cd43 --- /dev/null +++ b/java/java-analysis-impl/src/com/siyeh/ig/migration/ComparatorMinMaxCanBeUsedInspection.java @@ -0,0 +1,264 @@ +// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.siyeh.ig.migration; + +import com.intellij.codeInspection.CommonQuickFixBundle; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.dataFlow.DfaPsiUtil; +import com.intellij.codeInspection.dataFlow.value.RelationType; +import com.intellij.modcommand.ModPsiUpdater; +import com.intellij.modcommand.PsiUpdateModCommandQuickFix; +import com.intellij.openapi.project.Project; +import com.intellij.pom.java.JavaFeature; +import com.intellij.psi.PsiAssignmentExpression; +import com.intellij.psi.PsiBinaryExpression; +import com.intellij.psi.PsiConditionalExpression; +import com.intellij.psi.PsiDeclarationStatement; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiExpressionStatement; +import com.intellij.psi.PsiIfStatement; +import com.intellij.psi.PsiLocalVariable; +import com.intellij.psi.PsiMethodCallExpression; +import com.intellij.psi.PsiReturnStatement; +import com.intellij.psi.PsiStatement; +import com.intellij.psi.PsiYieldStatement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.siyeh.ig.BaseInspection; +import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.callMatcher.CallMatcher; +import com.siyeh.ig.psiutils.CommentTracker; +import com.siyeh.ig.psiutils.EquivalenceChecker; +import com.siyeh.ig.psiutils.ExpressionUtils; +import com.siyeh.ig.psiutils.SideEffectChecker; +import com.siyeh.ig.style.ConditionalModel; +import com.siyeh.ig.style.IfConditionalModel; +import com.siyeh.ig.style.SimplifiableIfStatementInspection; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Set; + +/** + * Inspection that detects ternary expressions and if statements using {@code Comparator.compare()} that can be + * replaced with {@code Comparator.max()} or {@code Comparator.min()} methods available since Java 26. + *

+ * Detected ternary patterns (where {@code comp} is a {@code Comparator} instance): + *

+ * Detected if-statement patterns: + * + * All comparison operators ({@code >}, {@code <}, {@code >=}, {@code <=}) are supported, as well as + * reversed comparisons (e.g. {@code 0 < comp.compare(a, b)}). + */ +public final class ComparatorMinMaxCanBeUsedInspection extends BaseInspection { + + private static final CallMatcher COMPARATOR_COMPARE = + CallMatcher.instanceCall("java.util.Comparator", "compare").parameterCount(2); + + @Override + public @NotNull Set requiredFeatures() { + return Set.of(JavaFeature.COMPARATOR_MIN_MAX); + } + + @Override + protected @NotNull String buildErrorString(Object... infos) { + String methodName = (String)infos[0]; + return CommonQuickFixBundle.message("fix.can.replace.with.x", "Comparator." + methodName + "()"); + } + + @Override + protected LocalQuickFix buildFix(Object... infos) { + String methodName = (String)infos[0]; + return new ReplaceWithComparatorMinMaxFix(methodName); + } + + @Override + public @NotNull BaseInspectionVisitor buildVisitor() { + return new ComparatorMinMaxVisitor(); + } + + private record MinMaxInfo( + @NotNull PsiExpression comparatorQualifier, + @NotNull PsiExpression firstArg, + @NotNull PsiExpression secondArg, + @NotNull String methodName + ) {} + + private static @Nullable MinMaxInfo extractMinMaxInfo(@NotNull ConditionalModel conditional) { + PsiExpression condition = PsiUtil.skipParenthesizedExprDown(conditional.getCondition()); + if (!(condition instanceof PsiBinaryExpression binExpr)) return null; + + PsiExpression lhs = PsiUtil.skipParenthesizedExprDown(binExpr.getLOperand()); + PsiExpression rhs = PsiUtil.skipParenthesizedExprDown(binExpr.getROperand()); + IElementType tokenType = binExpr.getOperationTokenType(); + + PsiMethodCallExpression compareCall; + RelationType relationType = DfaPsiUtil.getRelationByToken(tokenType); + if (relationType == null) return null; + if (lhs instanceof PsiMethodCallExpression lhsCall && COMPARATOR_COMPARE.test(lhsCall) && ExpressionUtils.isZero(rhs)) { + compareCall = lhsCall; + } + else if (rhs instanceof PsiMethodCallExpression rhsCall && COMPARATOR_COMPARE.test(rhsCall) && ExpressionUtils.isZero(lhs)) { + compareCall = rhsCall; + relationType = relationType.getFlipped(); + } + else { + return null; + } + + if (relationType == null || relationType == RelationType.NE || !relationType.isInequality()) { + return null; + } + + PsiExpression qualifier = compareCall.getMethodExpression().getQualifierExpression(); + if (qualifier == null) return null; + + PsiExpression[] args = compareCall.getArgumentList().getExpressions(); + if (args.length != 2) return null; + + if (SideEffectChecker.mayHaveSideEffects(args[0]) || SideEffectChecker.mayHaveSideEffects(args[1])) { + return null; + } + + PsiExpression thenExpr = PsiUtil.skipParenthesizedExprDown(conditional.getThenExpression()); + PsiExpression elseExpr = PsiUtil.skipParenthesizedExprDown(conditional.getElseExpression()); + if (thenExpr == null || elseExpr == null) return null; + + PsiExpression compareFirst = PsiUtil.skipParenthesizedExprDown(args[0]); + PsiExpression compareSecond = PsiUtil.skipParenthesizedExprDown(args[1]); + if (compareFirst == null || compareSecond == null) return null; + + EquivalenceChecker checker = EquivalenceChecker.getCanonicalPsiEquivalence(); + boolean thenIsFirst = checker.expressionsAreEquivalent(thenExpr, compareFirst) && + checker.expressionsAreEquivalent(elseExpr, compareSecond); + boolean thenIsSecond = !thenIsFirst && + checker.expressionsAreEquivalent(thenExpr, compareSecond) && + checker.expressionsAreEquivalent(elseExpr, compareFirst); + + if (!thenIsFirst && !thenIsSecond) return null; + + String methodName = RelationType.GE.isSubRelation(relationType) == thenIsFirst ? "max" : "min"; + + return new MinMaxInfo(qualifier, args[0], args[1], methodName); + } + + private static class ComparatorMinMaxVisitor extends BaseInspectionVisitor { + @Override + public void visitConditionalExpression(@NotNull PsiConditionalExpression expression) { + ConditionalModel model = ConditionalModel.from(expression); + if (model == null) return; + MinMaxInfo info = extractMinMaxInfo(model); + if (info == null) return; + registerError(expression, info.methodName()); + } + + @Override + public void visitIfStatement(@NotNull PsiIfStatement statement) { + ConditionalModel model = IfConditionalModel.from(statement, false); + if (model != null) { + MinMaxInfo info = extractMinMaxInfo(model); + if (info == null) return; + registerError(statement.getFirstChild(), info.methodName()); + } + } + } + + private static class ReplaceWithComparatorMinMaxFix extends PsiUpdateModCommandQuickFix { + private final String myMethodName; + + ReplaceWithComparatorMinMaxFix(@NotNull String methodName) { + myMethodName = methodName; + } + + @Override + public @NotNull String getFamilyName() { + return CommonQuickFixBundle.message("fix.replace.with.x", "Comparator." + myMethodName + "()"); + } + + @Override + protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) { + PsiElement parent = PsiTreeUtil.getParentOfType(element, false, PsiConditionalExpression.class, PsiIfStatement.class); + ConditionalModel model = switch (parent) { + case PsiConditionalExpression conditional -> ConditionalModel.from(conditional); + case PsiIfStatement statement -> IfConditionalModel.from(statement, false); + case null, default -> null; + }; + if (model == null) return; + MinMaxInfo info = extractMinMaxInfo(model); + if (info == null) return; + + CommentTracker ct = new CommentTracker(); + String callText = ct.text(info.comparatorQualifier()) + + "." + info.methodName() + "(" + + ct.text(info.firstArg()) + ", " + + ct.text(info.secondArg()) + ")"; + + if (parent instanceof PsiIfStatement ifStatement && model instanceof IfConditionalModel ifModel) { + replaceIfStatement(ct, ifStatement, ifModel, callText); + } + else { + ct.replaceAndRestoreComments(parent, callText); + } + } + + private static void replaceIfStatement(@NotNull CommentTracker ct, + @NotNull PsiIfStatement ifStatement, + @NotNull IfConditionalModel model, + @NotNull String callText) { + PsiStatement thenBranch = model.getThenBranch(); + PsiStatement elseBranch = model.getElseBranch(); + boolean elseIsOutside = !PsiTreeUtil.isAncestor(ifStatement, elseBranch, true); + + if (elseIsOutside && elseBranch instanceof PsiDeclarationStatement statement) { + PsiLocalVariable var = (PsiLocalVariable)statement.getDeclaredElements()[0]; + PsiExpression initializer = var.getInitializer(); + if (initializer != null) { + ct.replace(initializer, callText); + } + ct.deleteAndRestoreComments(ifStatement); + } + else { + if (elseIsOutside) { + ct.delete(elseBranch); + } + String statementText = buildStatementText(ct, thenBranch, model.getThenExpression(), callText); + PsiElement result = ct.replaceAndRestoreComments(ifStatement, statementText); + SimplifiableIfStatementInspection.tryJoinDeclaration(result); + } + } + + private static @NotNull String buildStatementText(@NotNull CommentTracker ct, + @NotNull PsiStatement thenBranch, + @NotNull PsiExpression thenExpression, + @NotNull String callText) { + if (thenBranch instanceof PsiReturnStatement) { + return "return " + callText + ";"; + } + if (thenBranch instanceof PsiYieldStatement) { + return "yield " + callText + ";"; + } + if (thenBranch instanceof PsiExpressionStatement exprStmt && + exprStmt.getExpression() instanceof PsiAssignmentExpression assignment) { + return ct.text(assignment.getLExpression()) + " = " + callText + ";"; + } + // Fallback for method call pattern or other cases + ct.replace(thenExpression, callText); + return thenBranch.getText(); + } + } +} diff --git a/java/java-backend/resources/META-INF/InspectionGadgets.xml b/java/java-backend/resources/META-INF/InspectionGadgets.xml index 06d4dc8205aa..1c0d256b204b 100644 --- a/java/java-backend/resources/META-INF/InspectionGadgets.xml +++ b/java/java-backend/resources/META-INF/InspectionGadgets.xml @@ -1347,6 +1347,11 @@ key="inspection.clamp.migration.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.language.level.specific.issues.and.migration.aids21" enabledByDefault="true" level="WARNING" implementationClass="com.siyeh.ig.migration.MathClampMigrationInspection"/> + + +Reports ternary expressions using Comparator.compare() that can be replaced +with Comparator.max() or Comparator.min() methods available since Java 26. + +

Example:

+

+Comparator<String> comp = Comparator.naturalOrder();
+/*before*/ String result = comp.compare(a, b) > 0 ? a : b;
+/*after*/  String result = comp.max(a, b);
+
+ + +

New in 2026.2

+ + diff --git a/java/java-syntax/gen/com/intellij/java/syntax/DefaultJavaSyntaxResources.kt b/java/java-syntax/gen/com/intellij/java/syntax/DefaultJavaSyntaxResources.kt index c6f9a81b1f27..3ee9bad22267 100644 --- a/java/java-syntax/gen/com/intellij/java/syntax/DefaultJavaSyntaxResources.kt +++ b/java/java-syntax/gen/com/intellij/java/syntax/DefaultJavaSyntaxResources.kt @@ -62,6 +62,7 @@ internal object DefaultJavaSyntaxResources { "feature.binary.literals" to "Binary literals", "feature.classfile.api" to "ClassFile API", "feature.collection.factories" to "Collection factory methods", + "feature.comparator.min.max" to "Comparator min/max methods", "feature.diamond.types" to "Diamond types", "feature.effectively.final" to "Effectively final variables", "feature.enhanced.switch" to "Enhanced 'switch' blocks", diff --git a/java/java-syntax/resources/messages/JavaSyntaxBundle.properties b/java/java-syntax/resources/messages/JavaSyntaxBundle.properties index 9661ea4beb6b..3dbbb7511283 100644 --- a/java/java-syntax/resources/messages/JavaSyntaxBundle.properties +++ b/java/java-syntax/resources/messages/JavaSyntaxBundle.properties @@ -87,6 +87,7 @@ feature.markdown.comment=Markdown Documentation Comments feature.java.lang.io=java.lang.IO utility class feature.lazy.constants=Lazy constants feature.patterns.with.tightened.dominance=Patterns with tightened dominance +feature.comparator.min.max=Comparator min/max methods else.without.if='else' without 'if' expected.array.initializer=Array initializer expected diff --git a/java/java-syntax/src/com/intellij/pom/java/JavaFeature.kt b/java/java-syntax/src/com/intellij/pom/java/JavaFeature.kt index a529ec436761..58780ad60944 100644 --- a/java/java-syntax/src/com/intellij/pom/java/JavaFeature.kt +++ b/java/java-syntax/src/com/intellij/pom/java/JavaFeature.kt @@ -305,6 +305,8 @@ enum class JavaFeature { PATTERNS_WITH_TIGHTENED_DOMINANCE(LanguageLevel.JDK_26_PREVIEW, "feature.patterns.with.tightened.dominance"), + COMPARATOR_MIN_MAX(LanguageLevel.JDK_26, "feature.comparator.min.max"), + VALHALLA_VALUE_CLASSES(LanguageLevel.JDK_X, "feature.valhalla.value.classes"), ; diff --git a/java/java-tests/testData/ig/com/siyeh/igtest/migration/comparator_min_max_can_be_used/ComparatorMinMaxCanBeUsed.after.java b/java/java-tests/testData/ig/com/siyeh/igtest/migration/comparator_min_max_can_be_used/ComparatorMinMaxCanBeUsed.after.java new file mode 100644 index 000000000000..80ace89fa5e7 --- /dev/null +++ b/java/java-tests/testData/ig/com/siyeh/igtest/migration/comparator_min_max_can_be_used/ComparatorMinMaxCanBeUsed.after.java @@ -0,0 +1,105 @@ +package com.siyeh.igtest.migration.comparator_min_max_can_be_used; + +import java.util.Comparator; + +class ComparatorMinMaxCanBeUsed { + void testGreaterThan(Comparator comp, String a, String b) { + String r1 = comp.max(a, b); + String r2 = comp.min(a, b); + } + + void testLessThan(Comparator comp, String a, String b) { + String r1 = comp.min(a, b); + String r2 = comp.max(a, b); + } + + void testGreaterThanOrEqual(Comparator comp, String a, String b) { + String r1 = comp.max(a, b); + String r2 = comp.min(a, b); + } + + void testLessThanOrEqual(Comparator comp, String a, String b) { + String r1 = comp.min(a, b); + String r2 = comp.max(a, b); + } + + void testReversedComparison(Comparator comp, String a, String b) { + // 0 < compare(a, b) is equivalent to compare(a, b) > 0 + String r1 = comp.max(a, b); + // 0 >= compare(a, b) is equivalent to compare(a, b) <= 0 + String r2 = comp.max(a, b); + } + + void testParenthesized(Comparator comp, String a, String b) { + String r1 = comp.max(a, b); + String r2 = comp.min(a, b); + } + + // If-statement patterns + String testIfReturnGreaterThan(Comparator comp, String a, String b) { + return comp.max(a, b); + } + + String testIfReturnLessThan(Comparator comp, String a, String b) { + return comp.min(a, b); + } + + String testIfReturnReversedBranches(Comparator comp, String a, String b) { + return comp.min(a, b); + } + + String testIfReturnWithBlocks(Comparator comp, String a, String b) { + return comp.max(a, b); + } + + String testIfImplicitReturn(Comparator comp, String a, String b) { + return comp.max(a, b); + } + + void testIfAssignment(Comparator comp, String a, String b) { + String r = comp.max(a, b); + System.out.println(r); + } + + void testIfOverwrittenDeclaration(Comparator comp, String a, String b) { + String r = comp.max(a, b); + System.out.println(r); + } + + void testIfGreaterOrEqual(Comparator comp, String a, String b) { + String r = comp.max(a, b); + System.out.println(r); + } + + void testIfReversedComparison(Comparator comp, String a, String b) { + String r = comp.max(a, b); + System.out.println(r); + } + + void testIfNoWarning(Comparator comp, String a, String b) { + // Non-matching branches + String r; + if (comp.compare(a, b) > 0) r = a; else r = "default"; + // Comparison to non-zero + if (comp.compare(a, b) > 1) r = a; else r = b; + // Equality comparison + if (comp.compare(a, b) == 0) r = a; else r = b; + System.out.println(r); + } + + void testNoWarning(Comparator comp, String a, String b) { + // Side effects in compare arguments + String r1 = comp.max(a.trim(), b.trim()); + // Non-matching branches + String r2 = comp.compare(a, b) > 0 ? a : "default"; + // Comparison to non-zero + String r3 = comp.compare(a, b) > 1 ? a : b; + // Equality comparison + String r4 = comp.compare(a, b) == 0 ? a : b; + // Not a Comparator.compare call + int cmp = comp.compare(a, b); + String r5 = cmp > 0 ? a : b; + // Branches swapped with unrelated expressions + String r6 = comp.compare(a, b) > 0 ? b : b; + } +} diff --git a/java/java-tests/testData/ig/com/siyeh/igtest/migration/comparator_min_max_can_be_used/ComparatorMinMaxCanBeUsed.java b/java/java-tests/testData/ig/com/siyeh/igtest/migration/comparator_min_max_can_be_used/ComparatorMinMaxCanBeUsed.java new file mode 100644 index 000000000000..f82b9cb01991 --- /dev/null +++ b/java/java-tests/testData/ig/com/siyeh/igtest/migration/comparator_min_max_can_be_used/ComparatorMinMaxCanBeUsed.java @@ -0,0 +1,114 @@ +package com.siyeh.igtest.migration.comparator_min_max_can_be_used; + +import java.util.Comparator; + +class ComparatorMinMaxCanBeUsed { + void testGreaterThan(Comparator comp, String a, String b) { + String r1 = comp.compare(a, b) > 0 ? a : b; + String r2 = comp.compare(a, b) > 0 ? b : a; + } + + void testLessThan(Comparator comp, String a, String b) { + String r1 = comp.compare(a, b) < 0 ? a : b; + String r2 = comp.compare(a, b) < 0 ? b : a; + } + + void testGreaterThanOrEqual(Comparator comp, String a, String b) { + String r1 = comp.compare(a, b) >= 0 ? a : b; + String r2 = comp.compare(a, b) >= 0 ? b : a; + } + + void testLessThanOrEqual(Comparator comp, String a, String b) { + String r1 = comp.compare(a, b) <= 0 ? a : b; + String r2 = comp.compare(a, b) <= 0 ? b : a; + } + + void testReversedComparison(Comparator comp, String a, String b) { + // 0 < compare(a, b) is equivalent to compare(a, b) > 0 + String r1 = 0 < comp.compare(a, b) ? a : b; + // 0 >= compare(a, b) is equivalent to compare(a, b) <= 0 + String r2 = 0 >= comp.compare(a, b) ? b : a; + } + + void testParenthesized(Comparator comp, String a, String b) { + String r1 = (comp.compare(a, b)) > 0 ? a : b; + String r2 = comp.compare(a, b) > 0 ? (b) : (a); + } + + // If-statement patterns + String testIfReturnGreaterThan(Comparator comp, String a, String b) { + if (comp.compare(a, b) > 0) return a; else return b; + } + + String testIfReturnLessThan(Comparator comp, String a, String b) { + if (comp.compare(a, b) < 0) return a; else return b; + } + + String testIfReturnReversedBranches(Comparator comp, String a, String b) { + if (comp.compare(a, b) > 0) return b; else return a; + } + + String testIfReturnWithBlocks(Comparator comp, String a, String b) { + if (comp.compare(a, b) > 0) { + return a; + } else { + return b; + } + } + + String testIfImplicitReturn(Comparator comp, String a, String b) { + if (comp.compare(a, b) > 0) return a; + return b; + } + + void testIfAssignment(Comparator comp, String a, String b) { + String r; + if (comp.compare(a, b) > 0) r = a; else r = b; + System.out.println(r); + } + + void testIfOverwrittenDeclaration(Comparator comp, String a, String b) { + String r = b; + if (comp.compare(a, b) > 0) r = a; + System.out.println(r); + } + + void testIfGreaterOrEqual(Comparator comp, String a, String b) { + String r; + if (comp.compare(a, b) >= 0) r = a; else r = b; + System.out.println(r); + } + + void testIfReversedComparison(Comparator comp, String a, String b) { + String r; + if (0 < comp.compare(a, b)) r = a; else r = b; + System.out.println(r); + } + + void testIfNoWarning(Comparator comp, String a, String b) { + // Non-matching branches + String r; + if (comp.compare(a, b) > 0) r = a; else r = "default"; + // Comparison to non-zero + if (comp.compare(a, b) > 1) r = a; else r = b; + // Equality comparison + if (comp.compare(a, b) == 0) r = a; else r = b; + System.out.println(r); + } + + void testNoWarning(Comparator comp, String a, String b) { + // Side effects in compare arguments + String r1 = comp.compare(a.trim(), b.trim()) > 0 ? a.trim() : b.trim(); + // Non-matching branches + String r2 = comp.compare(a, b) > 0 ? a : "default"; + // Comparison to non-zero + String r3 = comp.compare(a, b) > 1 ? a : b; + // Equality comparison + String r4 = comp.compare(a, b) == 0 ? a : b; + // Not a Comparator.compare call + int cmp = comp.compare(a, b); + String r5 = cmp > 0 ? a : b; + // Branches swapped with unrelated expressions + String r6 = comp.compare(a, b) > 0 ? b : b; + } +} diff --git a/java/java-tests/testSrc/com/siyeh/ig/migration/ComparatorMinMaxCanBeUsedInspectionTest.java b/java/java-tests/testSrc/com/siyeh/ig/migration/ComparatorMinMaxCanBeUsedInspectionTest.java new file mode 100644 index 000000000000..ae18be7081a1 --- /dev/null +++ b/java/java-tests/testSrc/com/siyeh/ig/migration/ComparatorMinMaxCanBeUsedInspectionTest.java @@ -0,0 +1,18 @@ +// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.siyeh.ig.migration; + +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightJavaInspectionTestCase; + +public final class ComparatorMinMaxCanBeUsedInspectionTest extends LightJavaInspectionTestCase { + + public void testComparatorMinMaxCanBeUsed() { + doTest(); + checkQuickFixAll(); + } + + @Override + protected InspectionProfileEntry getInspection() { + return new ComparatorMinMaxCanBeUsedInspection(); + } +} diff --git a/platform/analysis-api/resources/messages/InspectionsBundle.properties b/platform/analysis-api/resources/messages/InspectionsBundle.properties index 000735ee2210..f0a02af6a982 100644 --- a/platform/analysis-api/resources/messages/InspectionsBundle.properties +++ b/platform/analysis-api/resources/messages/InspectionsBundle.properties @@ -212,6 +212,7 @@ group.names.language.level.specific.issues.and.migration.aids16=Java 16 group.names.language.level.specific.issues.and.migration.aids21=Java 21 group.names.language.level.specific.issues.and.migration.aids23=Java 23 group.names.language.level.specific.issues.and.migration.aids25=Java 25 +group.names.language.level.specific.issues.and.migration.aids26=Java 26 group.names.javabeans.issues=JavaBeans issues group.names.inheritance.issues=Inheritance issues group.names.data.flow.issues=Data flow