diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightFixUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightFixUtil.java index 415a01565151..591341898026 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightFixUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightFixUtil.java @@ -16,7 +16,10 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.openapi.projectRoots.JavaSdkVersionUtil; import com.intellij.openapi.projectRoots.JavaVersionService; +import com.intellij.pom.java.JavaFeature; +import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.controlFlow.*; import com.intellij.psi.infos.CandidateInfo; @@ -865,6 +868,36 @@ public final class HighlightFixUtil { registerChangeParameterClassFix(lType, rType, sink); } + private static @NotNull LanguageLevel getApplicableLevel(@NotNull PsiFile file, @NotNull JavaFeature feature) { + LanguageLevel standardLevel = feature.getStandardLevel(); + LanguageLevel featureLevel = feature.getMinimumLevel(); + if (featureLevel.isPreview()) { + JavaSdkVersion sdkVersion = JavaSdkVersionUtil.getJavaSdkVersion(file); + if (sdkVersion != null) { + if (standardLevel != null && sdkVersion.isAtLeast(JavaSdkVersion.fromLanguageLevel(standardLevel))) { + return standardLevel; + } + LanguageLevel previewLevel = sdkVersion.getMaxLanguageLevel().getPreviewLevel(); + if (previewLevel != null && previewLevel.isAtLeast(featureLevel)) { + return previewLevel; + } + } + } + return featureLevel; + } + + public static @NotNull List getIncreaseLanguageLevelFixes( + @NotNull PsiElement element, @NotNull JavaFeature feature) { + if (PsiUtil.isAvailable(feature, element)) return List.of(); + if (feature.isLimited()) return List.of(); //no reason for applying it because it can be outdated + LanguageLevel applicableLevel = getApplicableLevel(element.getContainingFile(), feature); + if (applicableLevel == LanguageLevel.JDK_X) return List.of(); // do not suggest to use experimental level + QuickFixFactory factory = QuickFixFactory.getInstance(); + return List.of(factory.createIncreaseLanguageLevelFix(applicableLevel), + factory.createUpgradeSdkFor(applicableLevel), + factory.createShowModulePropertiesFix(element)); + } + private static final class ReturnModel { final PsiReturnStatement myStatement; final PsiType myType; diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 2f7fa172b280..dc6324d5577b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -19,7 +19,6 @@ import com.intellij.openapi.module.LanguageLevelUtil; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.JavaSdkVersionUtil; import com.intellij.openapi.roots.impl.FilePropertyPusher; import com.intellij.openapi.roots.impl.JavaLanguageLevelPusher; import com.intellij.openapi.util.*; @@ -539,26 +538,15 @@ public final class HighlightUtil { return null; } - public static void registerIncreaseLanguageLevelFixes(@NotNull PsiElement element, - @NotNull JavaFeature feature, - HighlightInfo.Builder info) { + static void registerIncreaseLanguageLevelFixes(@NotNull PsiElement element, + @NotNull JavaFeature feature, + HighlightInfo.Builder info) { if (info == null) return; - for (CommonIntentionAction action : getIncreaseLanguageLevelFixes(element, feature)) { + for (CommonIntentionAction action : HighlightFixUtil.getIncreaseLanguageLevelFixes(element, feature)) { info.registerFix(action.asIntention(), null, null, null, null); } } - public static @NotNull List getIncreaseLanguageLevelFixes( - @NotNull PsiElement element, @NotNull JavaFeature feature) { - if (PsiUtil.isAvailable(feature, element)) return List.of(); - if (feature.isLimited()) return List.of(); //no reason for applying it because it can be outdated - LanguageLevel applicableLevel = getApplicableLevel(element.getContainingFile(), feature); - if (applicableLevel == LanguageLevel.JDK_X) return List.of(); // do not suggest to use experimental level - return List.of(getFixFactory().createIncreaseLanguageLevelFix(applicableLevel), - getFixFactory().createUpgradeSdkFor(applicableLevel), - getFixFactory().createShowModulePropertiesFix(element)); - } - private static @NotNull @NlsContexts.DetailedDescription String getUnsupportedFeatureMessage(@NotNull JavaFeature feature, @NotNull LanguageLevel level, @NotNull PsiFile file) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaErrorFixProvider.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaErrorFixProvider.java index 7c549e4aaf5e..65edf3249513 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaErrorFixProvider.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaErrorFixProvider.java @@ -97,8 +97,8 @@ final class JavaErrorFixProvider { } JavaErrorFixProvider() { - multi(UNSUPPORTED_FEATURE, error -> HighlightUtil.getIncreaseLanguageLevelFixes(error.psi(), error.context())); - multi(PREVIEW_API_USAGE, error -> HighlightUtil.getIncreaseLanguageLevelFixes(error.psi(), error.context().feature())); + multi(UNSUPPORTED_FEATURE, error -> HighlightFixUtil.getIncreaseLanguageLevelFixes(error.psi(), error.context())); + multi(PREVIEW_API_USAGE, error -> HighlightFixUtil.getIncreaseLanguageLevelFixes(error.psi(), error.context().feature())); JavaFixProvider genericRemover = error -> myFactory.createDeleteFix(error.psi()); for (JavaErrorKind kind : List.of(ANNOTATION_MEMBER_THROWS_NOT_ALLOWED, ANNOTATION_ATTRIBUTE_DUPLICATE, ANNOTATION_NOT_ALLOWED_EXTENDS, ANNOTATION_NOT_ALLOWED_IN_PERMIT_LIST, @@ -595,7 +595,7 @@ final class JavaErrorFixProvider { String text = QuickFixBundle.message("remove.modifier.fix", name, VisibilityUtil.toPresentableText(PsiModifier.ABSTRACT)); return myFactory.createAddMethodBodyFix(method, text); }); - multi(CALL_CONSTRUCTOR_MUST_BE_FIRST_STATEMENT, error -> HighlightUtil.getIncreaseLanguageLevelFixes( + multi(CALL_CONSTRUCTOR_MUST_BE_FIRST_STATEMENT, error -> HighlightFixUtil.getIncreaseLanguageLevelFixes( error.psi(), JavaFeature.STATEMENTS_BEFORE_SUPER)); fix(STRING_TEMPLATE_PROCESSOR_MISSING, error -> new MissingStrProcessorFix(error.psi())); fixes(UNARY_OPERATOR_NOT_APPLICABLE, (error, sink) -> { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaFutureKeywordUseFixProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaFutureKeywordUseFixProvider.java index f2dcad5d7d69..273603a8c1b4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaFutureKeywordUseFixProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaFutureKeywordUseFixProvider.java @@ -48,7 +48,7 @@ public final class JavaFutureKeywordUseFixProvider extends UnresolvedReferenceQu private static void registerIncreaseLevelFixes(@NotNull PsiJavaCodeReferenceElement ref, @NotNull JavaFeature feature, @NotNull QuickFixActionRegistrar registrar) { - for (CommonIntentionAction fix : HighlightUtil.getIncreaseLanguageLevelFixes(ref, feature)) { + for (CommonIntentionAction fix : HighlightFixUtil.getIncreaseLanguageLevelFixes(ref, feature)) { registrar.register(fix.asIntention()); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/SealedClassUnresolvedReferenceFixProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/SealedClassUnresolvedReferenceFixProvider.java index b5ffbbfd5493..f6a4c4dce86f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/SealedClassUnresolvedReferenceFixProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/SealedClassUnresolvedReferenceFixProvider.java @@ -17,7 +17,7 @@ public final class SealedClassUnresolvedReferenceFixProvider extends UnresolvedR @Override public void registerFixes(@NotNull PsiJavaCodeReferenceElement ref, @NotNull QuickFixActionRegistrar registrar) { if (!PsiUtil.isAvailable(JavaFeature.SEALED_CLASSES, ref) && ref.textMatches(PsiKeyword.SEALED)) { - for (CommonIntentionAction intention : HighlightUtil.getIncreaseLanguageLevelFixes(ref, JavaFeature.SEALED_CLASSES)) { + for (CommonIntentionAction intention : HighlightFixUtil.getIncreaseLanguageLevelFixes(ref, JavaFeature.SEALED_CLASSES)) { registrar.register(intention.asIntention()); } }