diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java index 51f3269691df..374d6dec410b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java @@ -16,6 +16,7 @@ import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.command.undo.UndoUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.impl.light.LightElement; @@ -160,7 +161,7 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement implements Lo if (modifierListOwner.getParent() instanceof PsiParameterList && modifierListOwner.getParent().getParent() instanceof PsiLambdaExpression lambda) { // Lambda parameter without type cannot be annotated. Check if we can specify types - if (PsiUtil.isLanguageLevel11OrHigher(modifierListOwner)) return true; + if (JavaFeature.VAR_LAMBDA_PARAMETER.isAvailable(modifierListOwner)) return true; return LambdaUtil.createLambdaParameterListWithFormalTypes(lambda.getFunctionalInterfaceType(), lambda, false) != null; } return false; @@ -326,7 +327,7 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement implements Lo PsiParameter[] parameters = list.getParameters(); int index = ArrayUtil.indexOf(parameters, parameter); PsiParameterList newList; - if (PsiUtil.isLanguageLevel11OrHigher(list)) { + if (JavaFeature.VAR_LAMBDA_PARAMETER.isAvailable(list)) { String newListText = StreamEx.of(parameters).map(p -> PsiKeyword.VAR + " " + p.getName()).joining(",", "(", ")"); newList = ((PsiLambdaExpression)JavaPsiFacade.getElementFactory(list.getProject()) .createExpressionFromText(newListText+" -> {}", null)).getParameterList(); diff --git a/java/java-analysis-impl/src/com/siyeh/ig/fixes/AddSerialVersionUIDFix.java b/java/java-analysis-impl/src/com/siyeh/ig/fixes/AddSerialVersionUIDFix.java index 60da51cd0b12..215383c5ced1 100644 --- a/java/java-analysis-impl/src/com/siyeh/ig/fixes/AddSerialVersionUIDFix.java +++ b/java/java-analysis-impl/src/com/siyeh/ig/fixes/AddSerialVersionUIDFix.java @@ -19,9 +19,9 @@ import com.intellij.codeInsight.intention.AddAnnotationPsiFix; 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.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; -import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -41,7 +41,7 @@ public class AddSerialVersionUIDFix extends PsiUpdateModCommandQuickFix { final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(aClass.getProject()); final long serialVersionUID = SerialVersionUIDBuilder.computeDefaultSUID(aClass); final PsiField field = elementFactory.createFieldFromText(generateSerialVersionUIDFieldText(serialVersionUID), aClass); - if (PsiUtil.isLanguageLevel14OrHigher(field)) { + if (JavaFeature.SERIAL_ANNOTATION.isAvailable(field)) { annotateFieldWithSerial(field); } aClass.add(field); diff --git a/java/java-analysis-impl/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java b/java/java-analysis-impl/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java index 6922e64aeadd..bed205b7c4bb 100644 --- a/java/java-analysis-impl/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java +++ b/java/java-analysis-impl/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java @@ -16,9 +16,10 @@ package com.siyeh.ig.j2me; import com.intellij.codeInspection.LocalQuickFix; -import com.intellij.modcommand.PsiUpdateModCommandQuickFix; 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.*; import com.intellij.psi.util.FileTypeUtils; import com.intellij.psi.util.PsiTreeUtil; @@ -171,7 +172,7 @@ public final class PrivateMemberAccessBetweenOuterAndInnerClassInspection extend // disable for jsp files IDEADEV-12957 return false; } - return !PsiUtil.isLanguageLevel11OrHigher(file); + return !JavaFeature.NESTMATES.isAvailable(file); } @Override diff --git a/java/java-analysis-impl/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java b/java/java-analysis-impl/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java index 6fb32978b90d..f5ed0bcf2e42 100644 --- a/java/java-analysis-impl/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java +++ b/java/java-analysis-impl/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java @@ -2,10 +2,11 @@ package com.siyeh.ig.migration; import com.intellij.codeInspection.LocalQuickFix; -import com.intellij.modcommand.PsiUpdateModCommandQuickFix; import com.intellij.modcommand.ModPsiUpdater; +import com.intellij.modcommand.PsiUpdateModCommandQuickFix; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.InheritanceUtil; @@ -259,7 +260,7 @@ public final class TryFinallyCanBeTryWithResourcesInspection extends BaseInspect IntList initializerPositions = new IntArrayList(); for (PsiVariable resourceVariable : collectedVariables) { boolean variableUsedOutsideTry = isVariableUsedOutsideContext(resourceVariable, tryStatement); - if (!PsiUtil.isLanguageLevel9OrHigher(finallyBlock) && variableUsedOutsideTry) return null; + if (!JavaFeature.REFS_AS_RESOURCE.isAvailable(finallyBlock) && variableUsedOutsideTry) return null; if (!variableUsedOutsideTry && resourceVariable instanceof PsiLocalVariable) { PsiExpression initializer = resourceVariable.getInitializer(); boolean hasNonNullInitializer = initializer != null && !PsiTypes.nullType().equals(initializer.getType()); diff --git a/java/java-analysis-impl/src/com/siyeh/ig/performance/ArraysAsListWithZeroOrOneArgumentInspection.java b/java/java-analysis-impl/src/com/siyeh/ig/performance/ArraysAsListWithZeroOrOneArgumentInspection.java index f4dad14fba51..fd2f5eee72d0 100644 --- a/java/java-analysis-impl/src/com/siyeh/ig/performance/ArraysAsListWithZeroOrOneArgumentInspection.java +++ b/java/java-analysis-impl/src/com/siyeh/ig/performance/ArraysAsListWithZeroOrOneArgumentInspection.java @@ -9,8 +9,8 @@ import com.intellij.codeInspection.dataFlow.NullabilityUtil; 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.*; -import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -131,7 +131,7 @@ public final class ArraysAsListWithZeroOrOneArgumentInspection extends BaseInspe final PsiExpression[] arguments = argumentList.getExpressions(); if (arguments.length > 1) return; - boolean suggestListOf = PsiUtil.isLanguageLevel9OrHigher(expression); + boolean suggestListOf = JavaFeature.COLLECTION_FACTORIES.isAvailable(expression); boolean empty = false; if (arguments.length == 0) { empty = true; diff --git a/java/java-analysis-impl/src/com/siyeh/ig/psiutils/SwitchUtils.java b/java/java-analysis-impl/src/com/siyeh/ig/psiutils/SwitchUtils.java index d765422c45c8..8b47dbcc9a77 100644 --- a/java/java-analysis-impl/src/com/siyeh/ig/psiutils/SwitchUtils.java +++ b/java/java-analysis-impl/src/com/siyeh/ig/psiutils/SwitchUtils.java @@ -124,7 +124,7 @@ public final class SwitchUtils { return false; } } - if (languageLevel.isAtLeast(LanguageLevel.JDK_1_7)) { + if (JavaFeature.STRING_SWITCH.isSufficient(languageLevel)) { final PsiExpression stringSwitchExpression = determinePossibleJdk17SwitchExpression(expression, existingCaseValues); if (EquivalenceChecker.getCanonicalPsiEquivalence().expressionsAreEquivalent(switchExpression, stringSwitchExpression)) { return true; @@ -230,7 +230,7 @@ public final class SwitchUtils { if (TypeConversionUtil.isEnumType(type)) { return true; } - if (languageLevel.isAtLeast(LanguageLevel.JDK_1_7) && type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { + if (JavaFeature.STRING_SWITCH.isSufficient(languageLevel) && type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { return true; } return JavaFeature.PATTERNS_IN_SWITCH.isAvailable(expression); @@ -479,7 +479,7 @@ public final class SwitchUtils { } } final PsiType type = expression.getType(); - if ((!languageLevel.isAtLeast(LanguageLevel.JDK_1_7) || !TypeUtils.isJavaLangString(type)) && + if ((!JavaFeature.STRING_SWITCH.isSufficient(languageLevel) || !TypeUtils.isJavaLangString(type)) && !PsiTypes.intType().equals(type) && !PsiTypes.shortType().equals(type) && !PsiTypes.byteType().equals(type) && !PsiTypes.charType().equals(type)) { return false; } diff --git a/java/java-analysis-impl/src/com/siyeh/ig/serialization/MissingSerialAnnotationInspection.java b/java/java-analysis-impl/src/com/siyeh/ig/serialization/MissingSerialAnnotationInspection.java index ef00ec79862f..a6091e04f324 100644 --- a/java/java-analysis-impl/src/com/siyeh/ig/serialization/MissingSerialAnnotationInspection.java +++ b/java/java-analysis-impl/src/com/siyeh/ig/serialization/MissingSerialAnnotationInspection.java @@ -4,9 +4,9 @@ package com.siyeh.ig.serialization; import com.intellij.codeInsight.intention.AddAnnotationFix; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.util.InspectionMessage; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -21,7 +21,7 @@ public final class MissingSerialAnnotationInspection extends BaseInspection { @Override public boolean shouldInspect(@NotNull PsiFile file) { - return PsiUtil.isLanguageLevel14OrHigher(file); + return JavaFeature.SERIAL_ANNOTATION.isAvailable(file); } @Override diff --git a/java/java-analysis-impl/src/com/siyeh/ig/serialization/SerialAnnotationUsedOnWrongMemberInspection.java b/java/java-analysis-impl/src/com/siyeh/ig/serialization/SerialAnnotationUsedOnWrongMemberInspection.java index 2c164e788b18..2bedd6f107ed 100644 --- a/java/java-analysis-impl/src/com/siyeh/ig/serialization/SerialAnnotationUsedOnWrongMemberInspection.java +++ b/java/java-analysis-impl/src/com/siyeh/ig/serialization/SerialAnnotationUsedOnWrongMemberInspection.java @@ -4,9 +4,9 @@ package com.siyeh.ig.serialization; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.RemoveAnnotationQuickFix; import com.intellij.codeInspection.util.InspectionMessage; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -22,7 +22,7 @@ public final class SerialAnnotationUsedOnWrongMemberInspection extends BaseInspe @Override public boolean shouldInspect(@NotNull PsiFile file) { - return PsiUtil.isLanguageLevel14OrHigher(file); + return JavaFeature.SERIAL_ANNOTATION.isAvailable(file); } @Override diff --git a/java/java-analysis-impl/src/com/siyeh/ig/serialization/SerializableRecordContainsIgnoredMembersInspection.java b/java/java-analysis-impl/src/com/siyeh/ig/serialization/SerializableRecordContainsIgnoredMembersInspection.java index a0f594bc7e71..50a9a86f48b4 100644 --- a/java/java-analysis-impl/src/com/siyeh/ig/serialization/SerializableRecordContainsIgnoredMembersInspection.java +++ b/java/java-analysis-impl/src/com/siyeh/ig/serialization/SerializableRecordContainsIgnoredMembersInspection.java @@ -2,8 +2,8 @@ package com.siyeh.ig.serialization; import com.intellij.codeInspection.util.InspectionMessage; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; -import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -14,7 +14,7 @@ public final class SerializableRecordContainsIgnoredMembersInspection extends Ba @Override public boolean shouldInspect(@NotNull PsiFile file) { - return PsiUtil.isLanguageLevel14OrHigher(file); + return JavaFeature.SERIAL_ANNOTATION.isAvailable(file); } @Override diff --git a/java/java-analysis-impl/src/com/siyeh/ig/style/UnnecessaryModifierInspection.java b/java/java-analysis-impl/src/com/siyeh/ig/style/UnnecessaryModifierInspection.java index b6099fb3b660..4a9f5b4bdfdc 100644 --- a/java/java-analysis-impl/src/com/siyeh/ig/style/UnnecessaryModifierInspection.java +++ b/java/java-analysis-impl/src/com/siyeh/ig/style/UnnecessaryModifierInspection.java @@ -3,14 +3,13 @@ package com.siyeh.ig.style; import com.intellij.codeInspection.CleanupLocalInspectionTool; import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.RemoveModifierFix; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -44,7 +43,7 @@ public final class UnnecessaryModifierInspection extends BaseInspection implemen public void visitClass(@NotNull PsiClass aClass) { final PsiElement parent = aClass.getParent(); final boolean interfaceMember = parent instanceof PsiClass && ((PsiClass)parent).isInterface(); - final boolean redundantStrictfp = PsiUtil.isLanguageLevel17OrHigher(aClass) && aClass.hasModifierProperty(PsiModifier.STRICTFP); + final boolean redundantStrictfp = JavaFeature.ALWAYS_STRICTFP.isAvailable(aClass) && aClass.hasModifierProperty(PsiModifier.STRICTFP); if (aClass.isRecord() || aClass.isInterface() || aClass.isEnum() || interfaceMember || redundantStrictfp) { PsiModifierList modifierList = aClass.getModifierList(); if (modifierList == null) { @@ -103,7 +102,7 @@ public final class UnnecessaryModifierInspection extends BaseInspection implemen @Override public void visitMethod(@NotNull PsiMethod method) { - final boolean redundantStrictfp = PsiUtil.isLanguageLevel17OrHigher(method) && method.hasModifierProperty(PsiModifier.STRICTFP); + final boolean redundantStrictfp = JavaFeature.ALWAYS_STRICTFP.isAvailable(method) && method.hasModifierProperty(PsiModifier.STRICTFP); if (redundantStrictfp) { final PsiModifierList modifierList = method.getModifierList(); final List modifiers = PsiTreeUtil.getChildrenOfTypeAsList(modifierList, PsiKeyword.class); diff --git a/java/java-frontback-psi-api/resources/messages/JavaPsiBundle.properties b/java/java-frontback-psi-api/resources/messages/JavaPsiBundle.properties index faf52d47861a..3d9885939c59 100644 --- a/java/java-frontback-psi-api/resources/messages/JavaPsiBundle.properties +++ b/java/java-frontback-psi-api/resources/messages/JavaPsiBundle.properties @@ -63,6 +63,7 @@ feature.multi.catch=Multi-catches feature.try.with.resources=Try-with-resources feature.binary.literals=Binary literals feature.underscores.in.literals=Underscores in literals +feature.string.switch=Strings in 'switch' statements feature.stream.api=Stream API feature.advanced.collection.api=Lambda methods in collections feature.with.initial=ThreadLocal.withInitial() @@ -75,15 +76,20 @@ feature.intersections.in.casts=Intersection types in casts feature.static.interface.calls=Static interface method calls feature.try.with.resources.refs=Resource references feature.modules=Modules +feature.collection.factories=Collection factory methods feature.lvti=Local variable type inference feature.var.lambda.parameter='var' in lambda parameters +feature.nestmates=Nest-based access control feature.text.blocks=Text block literals feature.text.block.escape.sequences='\\s' escape sequences feature.enhanced.switch=Enhanced 'switch' blocks feature.switch.expressions='switch' expressions +feature.serial.annotation=@Serial annotation feature.records=Records feature.patterns.instanceof=Patterns in 'instanceof' feature.sealed.classes=Sealed classes +feature.strictfp=Always-strict floating point semantics +feature.no.this.capture=Inner classes don't capture 'this' feature.local.interfaces=Local interfaces feature.local.enums=Local enums feature.inner.statics=Static declarations in inner classes diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/BulkFileAttributesReadInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/BulkFileAttributesReadInspection.java index 79fe173c79ab..909690d2f3e2 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/BulkFileAttributesReadInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/BulkFileAttributesReadInspection.java @@ -7,6 +7,7 @@ import com.intellij.java.JavaBundle; 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.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.codeStyle.SuggestedNameInfo; @@ -255,7 +256,7 @@ public final class BulkFileAttributesReadInspection extends AbstractBaseJavaLoca if ( initializer != null && parent.getContext() != null - && PsiUtil.isLanguageLevel10OrHigher(parent.getContainingFile()) + && JavaFeature.LVTI.isAvailable(parent) && JavaRefactoringSettings.getInstance().INTRODUCE_LOCAL_CREATE_VAR_TYPE ) { displayType = TypeUtils.getType(PsiKeyword.VAR, parent.getContext()); diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/CapturingCleanerInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/CapturingCleanerInspection.java index ee15bc48b180..fe4603968950 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/CapturingCleanerInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/CapturingCleanerInspection.java @@ -2,7 +2,7 @@ package com.intellij.codeInspection; import com.intellij.java.JavaBundle; -import com.intellij.pom.java.LanguageLevel; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; @@ -95,7 +95,7 @@ public final class CapturingCleanerInspection extends AbstractBaseJavaLocalInspe } if (runnableExpr instanceof PsiNewExpression newExpression) { if (newExpression.getAnonymousClass() != null) { - if (PsiUtil.getDeclaredLanguageLevel(trackedClass).isAtLeast(LanguageLevel.JDK_18)) { + if (JavaFeature.INNER_NOT_CAPTURE_THIS.isAvailable(trackedClass)) { PsiElement elementCapturingThis = getLambdaOrInnerClassElementCapturingThis(newExpression, trackedClass); if (elementCapturingThis != null) { return elementCapturingThis; @@ -110,7 +110,7 @@ public final class CapturingCleanerInspection extends AbstractBaseJavaLocalInspe if (aClass == null) return null; if (aClass.getContainingClass() != trackedClass) return null; if (aClass.hasModifierProperty(PsiModifier.STATIC)) return null; - if (PsiUtil.getDeclaredLanguageLevel(trackedClass).isAtLeast(LanguageLevel.JDK_18) && + if (JavaFeature.INNER_NOT_CAPTURE_THIS.isAvailable(trackedClass) && getLambdaOrInnerClassElementCapturingThis(newExpression, trackedClass) == null) return null; return classReference; } diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/DuplicateBranchesInSwitchInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/DuplicateBranchesInSwitchInspection.java index 8156204525e2..90e8011c0110 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/DuplicateBranchesInSwitchInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/DuplicateBranchesInSwitchInspection.java @@ -477,7 +477,7 @@ public final class DuplicateBranchesInSwitchInspection extends LocalInspectionTo PsiElement prevElement = PsiTreeUtil.skipWhitespacesAndCommentsBackward(myLabelToMergeWith); if (prevElement != null) moveTarget = prevElement; } - if (PsiUtil.isLanguageLevel14OrHigher(moveTarget) && moveTarget instanceof PsiSwitchLabelStatement labelStatement && + if (JavaFeature.SWITCH_EXPRESSION.isAvailable(moveTarget) && moveTarget instanceof PsiSwitchLabelStatement labelStatement && myBranchToDelete.canCopyCaseValues(myBranchToMergeWith) && !SwitchUtils.isCaseNull(labelStatement) && !SwitchUtils.isDefaultLabel(labelStatement)) { for (PsiElement element : myBranchPrefixToMove) { diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java index fb6dd0508a15..60d3b8d6e2e3 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java @@ -16,6 +16,7 @@ import com.intellij.modcommand.PsiUpdateModCommandQuickFix; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; +import com.intellij.pom.java.JavaFeature; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; @@ -1701,7 +1702,7 @@ public final class SimplifyStreamApiCallChainsInspection extends AbstractBaseJav PsiReferenceParameterList typeParameters = qualifierCall.getMethodExpression().getParameterList(); String typeParametersText = typeParameters == null ? "" : ct.text(typeParameters); String factory; - if (PsiUtil.isLanguageLevel9OrHigher(call) && MethodCallUtils.isVarArgCall(qualifierCall) && + if (JavaFeature.COLLECTION_FACTORIES.isAvailable(call) && MethodCallUtils.isVarArgCall(qualifierCall) && ContainerUtil .and(qualifierArgs.getExpressions(), e -> NullabilityUtil.getExpressionNullability(e, true) == Nullability.NOT_NULL)) { factory = JAVA_UTIL_LIST + "." + typeParametersText + "of"; diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/java19api/Java9CollectionFactoryInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/java19api/Java9CollectionFactoryInspection.java index 19fa42bc9e46..98804cc96bad 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/java19api/Java9CollectionFactoryInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/java19api/Java9CollectionFactoryInspection.java @@ -2,7 +2,10 @@ package com.intellij.codeInspection.java19api; import com.intellij.codeInsight.Nullability; -import com.intellij.codeInspection.*; +import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.codeInspection.RemoveRedundantTypeArgumentsUtil; import com.intellij.codeInspection.dataFlow.NullabilityUtil; import com.intellij.codeInspection.options.OptPane; import com.intellij.codeInspection.util.IntentionName; @@ -10,6 +13,7 @@ import com.intellij.java.JavaBundle; 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.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.psi.*; import com.intellij.psi.controlFlow.DefUseUtil; @@ -66,7 +70,7 @@ public final class Java9CollectionFactoryInspection extends AbstractBaseJavaLoca @NotNull @Override public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { - if (!PsiUtil.isLanguageLevel9OrHigher(holder.getFile())) { + if (!JavaFeature.COLLECTION_FACTORIES.isAvailable(holder.getFile())) { return PsiElementVisitor.EMPTY_VISITOR; } return new JavaElementVisitor() { diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/reflectiveAccess/Java9ReflectionClassVisibilityInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/reflectiveAccess/Java9ReflectionClassVisibilityInspection.java index 98d55c6931fa..aaff8932624a 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/reflectiveAccess/Java9ReflectionClassVisibilityInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/reflectiveAccess/Java9ReflectionClassVisibilityInspection.java @@ -9,9 +9,9 @@ import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.java.JavaBundle; import com.intellij.openapi.project.Project; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -25,7 +25,7 @@ public final class Java9ReflectionClassVisibilityInspection extends AbstractBase @Override public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { final PsiFile file = holder.getFile(); - if (PsiUtil.isLanguageLevel9OrHigher(file)) { + if (JavaFeature.MODULES.isAvailable(file)) { final PsiJavaModule javaModule = JavaModuleGraphUtil.findDescriptorByElement(file); if (javaModule != null) { return new JavaElementVisitor() { diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/move/moveClassesOrPackages/ModuleInfoUsageDetector.java b/java/java-impl-refactorings/src/com/intellij/refactoring/move/moveClassesOrPackages/ModuleInfoUsageDetector.java index 9b2e274c393f..3f16a158cc74 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/move/moveClassesOrPackages/ModuleInfoUsageDetector.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/move/moveClassesOrPackages/ModuleInfoUsageDetector.java @@ -3,8 +3,8 @@ package com.intellij.refactoring.move.moveClassesOrPackages; import com.intellij.codeInsight.daemon.impl.analysis.JavaModuleGraphUtil; import com.intellij.openapi.project.Project; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; -import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.MoveDestination; import com.intellij.refactoring.safeDelete.ModuleInfoSafeDeleteUsageDetector; import com.intellij.usageView.UsageInfo; @@ -54,7 +54,7 @@ public abstract class ModuleInfoUsageDetector { @NotNull private static MultiMap groupClassesByDir(PsiElement @NotNull [] elementsToMove) { PsiElement firstElement = ArrayUtil.getFirstElement(elementsToMove); - if (firstElement == null || !PsiUtil.isLanguageLevel9OrHigher(firstElement)) return MultiMap.empty(); + if (firstElement == null || !JavaFeature.MODULES.isAvailable(firstElement)) return MultiMap.empty(); MultiMap result = new MultiMap<>(); for (PsiElement element : elementsToMove) { PsiClass psiClass = ObjectUtils.tryCast(element, PsiClass.class); diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/typeMigration/ui/TypeMigrationDialog.java b/java/java-impl-refactorings/src/com/intellij/refactoring/typeMigration/ui/TypeMigrationDialog.java index cad9f5c8854a..37ff02093e64 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/typeMigration/ui/TypeMigrationDialog.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/typeMigration/ui/TypeMigrationDialog.java @@ -19,11 +19,14 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.NlsContexts; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.pom.java.LanguageLevel; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; -import com.intellij.psi.util.*; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiFormatUtilBase; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.typeMigration.TypeMigrationLabeler; import com.intellij.refactoring.typeMigration.TypeMigrationProcessor; import com.intellij.refactoring.typeMigration.TypeMigrationRules; @@ -140,10 +143,10 @@ public abstract class TypeMigrationDialog extends RefactoringDialog { final String text = rootType != null ? rootType.getCanonicalText(true) : ""; int flags = 0; PsiElement root = roots[0]; - if (PsiUtil.getLanguageLevel(root).isAtLeast(LanguageLevel.JDK_1_5)) { + if (JavaFeature.VARARGS.isAvailable(root)) { flags |= JavaCodeFragmentFactory.ALLOW_ELLIPSIS; } - if (PsiUtil.getLanguageLevel(root).isAtLeast(LanguageLevel.JDK_1_7)) { + if (JavaFeature.MULTI_CATCH.isAvailable(root)) { flags |= JavaCodeFragmentFactory.ALLOW_DISJUNCTION; } flags |= JavaCodeFragmentFactory.ALLOW_VOID; diff --git a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java index 78a961dcc59a..cc2b10d793d9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java @@ -13,6 +13,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.NullableComputable; +import com.intellij.pom.java.JavaFeature; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; @@ -578,7 +579,7 @@ public final class ExpectedTypesProvider { PsiClassType enumType = TypeUtils.getType(CommonClassNames.JAVA_LANG_ENUM, statement); myResult.add(createInfoImpl(enumType, enumType)); - if (level.isAtLeast(LanguageLevel.JDK_1_7)) { + if (JavaFeature.STRING_SWITCH.isSufficient(level)) { PsiClassType stringType = TypeUtils.getStringType(statement); myResult.add(createInfoImpl(stringType, stringType)); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java index ab5912734636..eeaa44857c0b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java @@ -6,7 +6,7 @@ import com.intellij.codeInsight.ExpectedTypeInfo; import com.intellij.codeInsight.daemon.impl.analysis.HighlightClassUtil; import com.intellij.codeInsight.lookup.*; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.pom.java.LanguageLevel; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.filters.getters.ExpectedTypesGetter; import com.intellij.psi.impl.PsiClassImplUtil; @@ -118,7 +118,7 @@ public class JavaInheritorsGetter { PsiType psiType = GenericsUtil.eliminateWildcards(type); if (JavaSmartCompletionContributor.AFTER_NEW.accepts(parameters.getOriginalPosition()) && - PsiUtil.getLanguageLevel(parameters.getOriginalFile()).isAtLeast(LanguageLevel.JDK_1_7)) { + JavaFeature.DIAMOND_TYPES.isAvailable(parameters.getOriginalFile())) { final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiClass.getProject()); PsiClassType classType = (PsiClassType)type; if (psiClass.hasTypeParameters() && !classType.isRaw()) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ModifierChooser.java b/java/java-impl/src/com/intellij/codeInsight/completion/ModifierChooser.java index 5f543e4c3cbd..e2fa75b8747c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ModifierChooser.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ModifierChooser.java @@ -56,13 +56,13 @@ public final class ModifierChooser { {PsiKeyword.SEALED, PsiKeyword.NON_SEALED} }; - private static final String[][] INTERFACE_9_MEMBER_MODIFIERS = { + private static final String[][] INTERFACE_MEMBER_MODIFIERS_WITH_PRIVATE = { {PsiKeyword.PUBLIC, PsiKeyword.PROTECTED, PsiKeyword.PRIVATE}, {PsiKeyword.STATIC, PsiKeyword.DEFAULT}, {PsiKeyword.FINAL, PsiKeyword.ABSTRACT} }; - private static final String[][] INTERFACE_8_MEMBER_MODIFIERS = { + private static final String[][] INTERFACE_MEMBER_MODIFIERS_WITH_DEFAULT = { {PsiKeyword.PUBLIC, PsiKeyword.PROTECTED}, {PsiKeyword.STATIC, PsiKeyword.DEFAULT}, {PsiKeyword.FINAL, PsiKeyword.ABSTRACT} @@ -140,10 +140,10 @@ public final class ModifierChooser { return INTERFACE_MEMBER_MODIFIERS_WITH_SEALED; } if (PsiUtil.isLanguageLevel9OrHigher(list)) { - return INTERFACE_9_MEMBER_MODIFIERS; + return INTERFACE_MEMBER_MODIFIERS_WITH_PRIVATE; } - if (PsiUtil.isLanguageLevel8OrHigher(list)) { - return INTERFACE_8_MEMBER_MODIFIERS; + if (JavaFeature.STATIC_INTERFACE_CALLS.isAvailable(list)) { + return INTERFACE_MEMBER_MODIFIERS_WITH_DEFAULT; } return INTERFACE_MEMBER_MODIFIERS; } diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/RemoveRedundantParameterTypesFix.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/RemoveRedundantParameterTypesFix.java index 99075130bc99..a4a97cd43fa5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/RemoveRedundantParameterTypesFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/RemoveRedundantParameterTypesFix.java @@ -7,8 +7,8 @@ import com.intellij.modcommand.ActionContext; import com.intellij.modcommand.ModPsiUpdater; import com.intellij.modcommand.PsiUpdateModCommandAction; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; -import com.intellij.psi.util.PsiUtil; import com.intellij.util.containers.ContainerUtil; import com.siyeh.ig.psiutils.CommentTracker; import org.jetbrains.annotations.NotNull; @@ -38,7 +38,7 @@ public class RemoveRedundantParameterTypesFix extends PsiUpdateModCommandAction< for (PsiParameter parameter : parameters) { PsiTypeElement typeElement = parameter.getTypeElement(); if (typeElement == null) return false; - if (!PsiUtil.isLanguageLevel11OrHigher(parameterList)) { + if (!JavaFeature.VAR_LAMBDA_PARAMETER.isAvailable(parameterList)) { if (AnonymousCanBeLambdaInspection.mustKeepAnnotations(parameter, Collections.emptySet())) { return false; } @@ -73,7 +73,7 @@ public class RemoveRedundantParameterTypesFix extends PsiUpdateModCommandAction< private static void removeTypes(PsiLambdaExpression lambdaExpression) { if (lambdaExpression != null) { final PsiParameter[] parameters = lambdaExpression.getParameterList().getParameters(); - if (PsiUtil.isLanguageLevel11OrHigher(lambdaExpression) && + if (JavaFeature.VAR_LAMBDA_PARAMETER.isAvailable(lambdaExpression) && ContainerUtil.exists(parameters, parameter -> keepVarType(parameter))) { for (PsiParameter parameter : parameters) { PsiTypeElement element = parameter.getTypeElement(); diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java index 9d998994dec7..a1871e0605e2 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java @@ -11,7 +11,7 @@ import com.intellij.modcommand.*; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; -import com.intellij.pom.java.LanguageLevel; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.VariableKind; @@ -40,8 +40,8 @@ public final class SurroundAutoCloseableAction extends PsiUpdateModCommandAction @Override protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiElement element) { boolean available = element.getLanguage().isKindOf(JavaLanguage.INSTANCE) && - PsiUtil.getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_1_7) && - (findVariable(element) != null || findExpression(element) != null); + JavaFeature.TRY_WITH_RESOURCES.isAvailable(element) && + (findVariable(element) != null || findExpression(element) != null); return available ? Presentation.of(getFamilyName()) : null; } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java index 1d88086431cf..0148c0fc4272 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java @@ -14,7 +14,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.TextRange; import com.intellij.pom.java.JavaFeature; -import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; @@ -45,8 +44,7 @@ public class SwitchStatementPostfixTemplate extends SurroundPostfixTemplateBase } if (type.equalsToText(CommonClassNames.JAVA_LANG_STRING) && expression.getContainingFile() instanceof PsiJavaFile javaFile) { - LanguageLevel level = javaFile.getLanguageLevel(); - if (level.isAtLeast(LanguageLevel.JDK_1_7)) return true; + if (JavaFeature.STRING_SWITCH.isAvailable(javaFile)) return true; } return false; diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantExplicitVariableTypeInspection.java b/java/java-impl/src/com/intellij/codeInspection/RedundantExplicitVariableTypeInspection.java index 609f9b7d388f..092531999a1e 100644 --- a/java/java-impl/src/com/intellij/codeInspection/RedundantExplicitVariableTypeInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/RedundantExplicitVariableTypeInspection.java @@ -5,7 +5,7 @@ import com.intellij.codeInsight.AnnotationTargetUtil; import com.intellij.modcommand.ModPsiUpdater; import com.intellij.modcommand.PsiUpdateModCommandQuickFix; import com.intellij.openapi.project.Project; -import com.intellij.pom.java.LanguageLevel; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.util.JavaPsiPatternUtil; @@ -23,7 +23,7 @@ public final class RedundantExplicitVariableTypeInspection extends AbstractBaseJ @NotNull @Override public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { - if (!PsiUtil.getLanguageLevel(holder.getFile()).isAtLeast(LanguageLevel.JDK_10)) { + if (!JavaFeature.LVTI.isAvailable(holder.getFile())) { return PsiElementVisitor.EMPTY_VISITOR; } return new JavaElementVisitor() { diff --git a/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java b/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java index dd34481fb3d9..2932f2bc0f40 100644 --- a/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java +++ b/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java @@ -15,10 +15,10 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.light.LightJavaModule; -import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.java.JavaSourceRootType; @@ -45,7 +45,7 @@ public class CreateModuleInfoAction extends CreateFromTemplateActionBase { DataContext ctx = e.getDataContext(); IdeView view = LangDataKeys.IDE_VIEW.getData(ctx); PsiDirectory target = view != null && e.getProject() != null ? getTargetDirectory(ctx, view) : null; - if (target == null || !PsiUtil.isLanguageLevel9OrHigher(target)) { + if (target == null || !JavaFeature.MODULES.isAvailable(target)) { e.getPresentation().setEnabledAndVisible(false); } else { diff --git a/java/java-impl/src/com/siyeh/ig/fixes/IntroduceHolderFix.java b/java/java-impl/src/com/siyeh/ig/fixes/IntroduceHolderFix.java index 06096b67b16b..48cfadfa904c 100644 --- a/java/java-impl/src/com/siyeh/ig/fixes/IntroduceHolderFix.java +++ b/java/java-impl/src/com/siyeh/ig/fixes/IntroduceHolderFix.java @@ -1,10 +1,11 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.siyeh.ig.fixes; -import com.intellij.modcommand.PsiUpdateModCommandQuickFix; import com.intellij.modcommand.ModPsiUpdater; +import com.intellij.modcommand.PsiUpdateModCommandQuickFix; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; @@ -112,7 +113,7 @@ public class IntroduceHolderFix extends PsiUpdateModCommandQuickFix { final PsiModifierList modifierList = newField.getModifierList(); assert modifierList != null; modifierList.setModifierProperty(PsiModifier.FINAL, true); - if (!PsiUtil.isLanguageLevel11OrHigher(holderClass)) { + if (!JavaFeature.NESTMATES.isAvailable(holderClass)) { modifierList.setModifierProperty(PsiModifier.PACKAGE_LOCAL, true); } newField.setInitializer(rhs); diff --git a/java/java-impl/src/com/siyeh/ig/memory/AnonymousInnerClassMayBeStaticInspection.java b/java/java-impl/src/com/siyeh/ig/memory/AnonymousInnerClassMayBeStaticInspection.java index 83c5d216f0b4..e6f73f962762 100644 --- a/java/java-impl/src/com/siyeh/ig/memory/AnonymousInnerClassMayBeStaticInspection.java +++ b/java/java-impl/src/com/siyeh/ig/memory/AnonymousInnerClassMayBeStaticInspection.java @@ -16,7 +16,7 @@ package com.siyeh.ig.memory; import com.intellij.codeInspection.LocalQuickFix; -import com.intellij.pom.java.LanguageLevel; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; @@ -57,7 +57,7 @@ public final class AnonymousInnerClassMayBeStaticInspection extends BaseInspecti if (anonymousClass instanceof PsiEnumConstantInitializer) { return; } - if (PsiUtil.getDeclaredLanguageLevel(anonymousClass).isAtLeast(LanguageLevel.JDK_18) && + if (JavaFeature.INNER_NOT_CAPTURE_THIS.isAvailable(anonymousClass) && !InheritanceUtil.isInheritor(anonymousClass, CommonClassNames.JAVA_IO_SERIALIZABLE)) { // Since Java 18, non-serializable anonymous classes don't capture 'this' reference return; diff --git a/java/java-impl/src/com/siyeh/ipp/collections/ReplaceWithArraysAsListIntention.java b/java/java-impl/src/com/siyeh/ipp/collections/ReplaceWithArraysAsListIntention.java index 5d7ed95b99a5..5a1649607144 100644 --- a/java/java-impl/src/com/siyeh/ipp/collections/ReplaceWithArraysAsListIntention.java +++ b/java/java-impl/src/com/siyeh/ipp/collections/ReplaceWithArraysAsListIntention.java @@ -8,8 +8,8 @@ import com.intellij.codeInspection.dataFlow.NullabilityUtil; import com.intellij.codeInspection.util.IntentionName; import com.intellij.modcommand.ActionContext; import com.intellij.modcommand.Presentation; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; -import com.intellij.psi.util.PsiUtil; import com.intellij.util.containers.ContainerUtil; import com.siyeh.IntentionPowerPackBundle; import com.siyeh.ig.PsiReplacementUtil; @@ -83,12 +83,12 @@ public final class ReplaceWithArraysAsListIntention extends MCIntention { private static String getReplacementMethodText(String methodName, PsiMethodCallExpression context) { final PsiExpression[] arguments = context.getArgumentList().getExpressions(); if (methodName.equals("emptyList") && arguments.length == 1 && - !PsiUtil.isLanguageLevel9OrHigher(context) && ClassUtils.findClass("com.google.common.collect.ImmutableList", context) == null) { + !JavaFeature.COLLECTION_FACTORIES.isAvailable(context) && ClassUtils.findClass("com.google.common.collect.ImmutableList", context) == null) { return "java.util.Collections.singletonList"; } if (methodName.equals("emptyList") || methodName.equals("singletonList")) { if (!ContainerUtil.exists(arguments, ReplaceWithArraysAsListIntention::isPossiblyNull)) { - if (PsiUtil.isLanguageLevel9OrHigher(context)) { + if (JavaFeature.COLLECTION_FACTORIES.isAvailable(context)) { return "java.util.List.of"; } else if (ClassUtils.findClass("com.google.common.collect.ImmutableList", context) != null) { @@ -98,7 +98,7 @@ public final class ReplaceWithArraysAsListIntention extends MCIntention { return "java.util.Arrays.asList"; } if (methodName.equals("emptySet") || methodName.equals("singleton")) { - if (PsiUtil.isLanguageLevel9OrHigher(context)) { + if (JavaFeature.COLLECTION_FACTORIES.isAvailable(context)) { return "java.util.Set.of"; } else if (ClassUtils.findClass("com.google.common.collect.ImmutableSet", context) != null) { @@ -106,7 +106,7 @@ public final class ReplaceWithArraysAsListIntention extends MCIntention { } } else if (methodName.equals("emptyMap") || methodName.equals("singletonMap")) { - if (PsiUtil.isLanguageLevel9OrHigher(context)) { + if (JavaFeature.COLLECTION_FACTORIES.isAvailable(context)) { return "java.util.Map.of"; } else if (ClassUtils.findClass("com.google.common.collect.ImmutableMap", context) != null) { diff --git a/java/java-psi-api/src/com/intellij/pom/java/JavaFeature.java b/java/java-psi-api/src/com/intellij/pom/java/JavaFeature.java index 3293f42d2351..8ce72f5d5183 100644 --- a/java/java-psi-api/src/com/intellij/pom/java/JavaFeature.java +++ b/java/java-psi-api/src/com/intellij/pom/java/JavaFeature.java @@ -9,7 +9,7 @@ import com.intellij.util.ThreeState; import org.jetbrains.annotations.*; /** - * Represents Java language and standard library features and provides information + * Represents Java language, JVM, or standard library features and provides information * whether a particular features is available in a given context */ public enum JavaFeature { @@ -24,6 +24,7 @@ public enum JavaFeature { TRY_WITH_RESOURCES(LanguageLevel.JDK_1_7, "feature.try.with.resources"), BIN_LITERALS(LanguageLevel.JDK_1_7, "feature.binary.literals"), UNDERSCORES(LanguageLevel.JDK_1_7, "feature.underscores.in.literals"), + STRING_SWITCH(LanguageLevel.JDK_1_7, "feature.string.switch"), STREAMS(LanguageLevel.JDK_1_8, "feature.stream.api", true), /** * java.util.Arrays.setAll, java.util.Collection#removeIf, java.util.List.sort(Comparator), @@ -43,18 +44,23 @@ public enum JavaFeature { STATIC_INTERFACE_CALLS(LanguageLevel.JDK_1_8, "feature.static.interface.calls"), REFS_AS_RESOURCE(LanguageLevel.JDK_1_9, "feature.try.with.resources.refs"), MODULES(LanguageLevel.JDK_1_9, "feature.modules"), + COLLECTION_FACTORIES(LanguageLevel.JDK_1_9, "feature.collection.factories"), LVTI(LanguageLevel.JDK_10, "feature.lvti"), VAR_LAMBDA_PARAMETER(LanguageLevel.JDK_11, "feature.var.lambda.parameter"), + NESTMATES(LanguageLevel.JDK_11, "feature.nestmates"), ENHANCED_SWITCH(LanguageLevel.JDK_14, "feature.enhanced.switch"), SWITCH_EXPRESSION(LanguageLevel.JDK_14, "feature.switch.expressions"), + SERIAL_ANNOTATION(LanguageLevel.JDK_14, "feature.serial.annotation"), RECORDS(LanguageLevel.JDK_16, "feature.records"), PATTERNS(LanguageLevel.JDK_16, "feature.patterns.instanceof"), TEXT_BLOCK_ESCAPES(LanguageLevel.JDK_15, "feature.text.block.escape.sequences"), TEXT_BLOCKS(LanguageLevel.JDK_15, "feature.text.blocks"), - SEALED_CLASSES(LanguageLevel.JDK_17, "feature.sealed.classes"), LOCAL_INTERFACES(LanguageLevel.JDK_16, "feature.local.interfaces"), LOCAL_ENUMS(LanguageLevel.JDK_16, "feature.local.enums"), INNER_STATICS(LanguageLevel.JDK_16, "feature.inner.statics"), + SEALED_CLASSES(LanguageLevel.JDK_17, "feature.sealed.classes"), + ALWAYS_STRICTFP(LanguageLevel.JDK_17, "feature.strictfp"), + INNER_NOT_CAPTURE_THIS(LanguageLevel.JDK_18, "feature.no.this.capture"), PARENTHESIZED_PATTERNS(LanguageLevel.JDK_20_PREVIEW, "feature.parenthesised.patterns"){ @Override public boolean isSufficient(@NotNull LanguageLevel useSiteLevel) { diff --git a/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java b/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java index 3ebf87af96de..bfc4d02188a8 100644 --- a/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java @@ -1,6 +1,7 @@ // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.psi.impl.source.resolve.graphInference; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.util.PsiTreeUtil; @@ -105,7 +106,7 @@ public final class PsiPolyExpressionUtil { } private static boolean isVarContext(PsiVariable variable) { - if (PsiUtil.isLanguageLevel10OrHigher(variable)) { + if (JavaFeature.LVTI.isAvailable(variable)) { PsiTypeElement typeElement = variable.getTypeElement(); if (typeElement != null && typeElement.isInferredType()) { return true; diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java index 111a5ff7e3d9..558aa0f7cafe 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java @@ -6,6 +6,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; +import com.intellij.pom.java.JavaFeature; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; @@ -145,12 +146,12 @@ public final class PsiTypesUtil { case CommonClassNames.JAVA_LANG_DOUBLE: return "0.0"; case CommonClassNames.JAVA_UTIL_SET: - return PsiUtil.isLanguageLevel9OrHigher(psiClass) ? "java.util.Set.of()" : "java.util.Collections.emptySet()"; + return JavaFeature.COLLECTION_FACTORIES.isAvailable(psiClass) ? "java.util.Set.of()" : "java.util.Collections.emptySet()"; case CommonClassNames.JAVA_UTIL_COLLECTION: case CommonClassNames.JAVA_UTIL_LIST: - return PsiUtil.isLanguageLevel9OrHigher(psiClass) ? "java.util.List.of()" : "java.util.Collections.emptyList()"; + return JavaFeature.COLLECTION_FACTORIES.isAvailable(psiClass) ? "java.util.List.of()" : "java.util.Collections.emptyList()"; case CommonClassNames.JAVA_UTIL_MAP: - return PsiUtil.isLanguageLevel9OrHigher(psiClass) ? "java.util.Map.of()" : "java.util.Collections.emptyMap()"; + return JavaFeature.COLLECTION_FACTORIES.isAvailable(psiClass) ? "java.util.Map.of()" : "java.util.Collections.emptyMap()"; } } } diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java index bdf599ea0cfa..f963d8758522 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java @@ -1063,18 +1063,10 @@ public final class PsiUtil extends PsiUtilCore { return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_11); } - public static boolean isLanguageLevel14OrHigher(@NotNull PsiElement element) { - return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_14); - } - public static boolean isLanguageLevel16OrHigher(@NotNull PsiElement element) { return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_16); } - public static boolean isLanguageLevel17OrHigher(@NotNull PsiElement element) { - return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_17); - } - /** * @param element element to get Java language level for * @return the language level. If {@linkplain LanguageLevel#isUnsupported() unsupported} language level diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java index c3f43e7cbbe6..33ea6b527d6d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java @@ -4,7 +4,7 @@ package com.intellij.psi.impl; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.pom.java.LanguageLevel; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.augment.PsiAugmentProvider; import com.intellij.psi.codeStyle.CodeStyleManager; @@ -17,7 +17,6 @@ import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.Nullable; import java.util.List; -import java.util.Objects; public final class PsiDiamondTypeUtil { private static final Logger LOG = Logger.getInstance(PsiDiamondTypeUtil.class); @@ -40,7 +39,7 @@ public final class PsiDiamondTypeUtil { final PsiNewExpression context, @Nullable final PsiType expectedType, boolean skipDiamonds) { - if (PsiUtil.getLanguageLevel(context).isAtLeast(LanguageLevel.JDK_1_7)) { + if (JavaFeature.DIAMOND_TYPES.isAvailable(context)) { final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference(); if (classReference != null) { final PsiReferenceParameterList parameterList = classReference.getParameterList(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java index bbce5bb18cf3..48bc332a4dc5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java @@ -9,6 +9,7 @@ import com.intellij.lang.java.parser.JavaParserUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.pom.java.JavaFeature; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.impl.source.*; @@ -266,7 +267,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { @Override public PsiJavaCodeReferenceElement createReferenceFromText(@NotNull String text, @Nullable PsiElement context) throws IncorrectOperationException { boolean isStaticImport = context instanceof PsiImportStaticStatement && !((PsiImportStaticStatement)context).isOnDemand(); - boolean mayHaveDiamonds = context instanceof PsiNewExpression && PsiUtil.getLanguageLevel(context).isAtLeast(LanguageLevel.JDK_1_7); + boolean mayHaveDiamonds = context instanceof PsiNewExpression && JavaFeature.DIAMOND_TYPES.isAvailable(context); JavaParserUtil.ParserWrapper wrapper = isStaticImport ? STATIC_IMPORT_REF : mayHaveDiamonds ? DIAMOND_REF : REFERENCE; DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, wrapper, level(context)), context); PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCatchSectionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCatchSectionImpl.java index d63ea2f14f7f..fd67d23631ad 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCatchSectionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCatchSectionImpl.java @@ -4,7 +4,7 @@ package com.intellij.psi.impl.source.tree.java; import com.intellij.codeInsight.ExceptionUtil; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.pom.java.LanguageLevel; +import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.impl.source.Constants; import com.intellij.psi.impl.source.tree.ChildRole; @@ -76,8 +76,7 @@ public class PsiCatchSectionImpl extends CompositePsiElement implements PsiCatch PsiType declaredType = parameter.getType(); // When the thrown expression is an ... exception parameter Ej (parameter) of a catch clause Cj (this) ... - if (PsiUtil.getLanguageLevel(parameter).isAtLeast(LanguageLevel.JDK_1_7) && - isCatchParameterEffectivelyFinal(parameter, getCatchBlock())) { + if (JavaFeature.MULTI_CATCH.isAvailable(parameter) && isCatchParameterEffectivelyFinal(parameter, getCatchBlock())) { PsiTryStatement statement = getTryStatement(); // ... and the try block of the try statement which declares Cj (tryBlock) can throw T ... Collection thrownTypes = getThrownTypes(statement); diff --git a/jvm/jvm-analysis-impl/src/com/intellij/codeInspection/IllegalDependencyOnInternalPackageInspection.kt b/jvm/jvm-analysis-impl/src/com/intellij/codeInspection/IllegalDependencyOnInternalPackageInspection.kt index 7ac8f79c031b..d340dd17183c 100644 --- a/jvm/jvm-analysis-impl/src/com/intellij/codeInspection/IllegalDependencyOnInternalPackageInspection.kt +++ b/jvm/jvm-analysis-impl/src/com/intellij/codeInspection/IllegalDependencyOnInternalPackageInspection.kt @@ -4,12 +4,12 @@ package com.intellij.codeInspection import com.intellij.analysis.JvmAnalysisBundle import com.intellij.codeInsight.daemon.impl.analysis.JavaModuleGraphUtil import com.intellij.packageDependencies.DependenciesBuilder +import com.intellij.pom.java.JavaFeature import com.intellij.psi.PsiClass import com.intellij.psi.PsiClassOwner import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiFile import com.intellij.psi.impl.light.LightJavaModule -import com.intellij.psi.util.PsiUtil class IllegalDependencyOnInternalPackageInspection : LocalInspectionTool() { override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor = IllegalDependencyOnInternalPackage(holder) @@ -17,7 +17,7 @@ class IllegalDependencyOnInternalPackageInspection : LocalInspectionTool() { private class IllegalDependencyOnInternalPackage(private val holder: ProblemsHolder) : PsiElementVisitor() { override fun visitFile(file: PsiFile) { - if (!PsiUtil.isLanguageLevel9OrHigher(file) || JavaModuleGraphUtil.findDescriptorByElement(file) != null) return + if (!JavaFeature.MODULES.isAvailable(file) || JavaModuleGraphUtil.findDescriptorByElement(file) != null) return DependenciesBuilder.analyzeFileDependencies(file) { place, dependency -> if (dependency !is PsiClass) return@analyzeFileDependencies val dependencyFile = dependency.containingFile