mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
IDEA-239649 Increase language level fix is not suggested for records
GitOrigin-RevId: 19843f9e1f610f7536b7e591012ec3eb64af6c43
This commit is contained in:
committed by
intellij-monorepo-bot
parent
642e4911cd
commit
618696f129
@@ -106,6 +106,7 @@ feature.static.interface.calls=Static interface method calls
|
||||
feature.try.with.resources.refs=Resource references
|
||||
feature.modules=Modules
|
||||
feature.lvti=Local variable type inference
|
||||
feature.var.lambda.parameter='var' in lambda parameters
|
||||
feature.text.blocks=Text block literals
|
||||
feature.enhanced.switch=Enhanced 'switch' blocks
|
||||
feature.switch.expressions='switch' expressions
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.JavaModuleSystemEx;
|
||||
import com.intellij.codeInsight.JavaModuleSystemEx.ErrorWithFixes;
|
||||
import com.intellij.codeInsight.daemon.JavaErrorBundle;
|
||||
import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.*;
|
||||
@@ -3239,14 +3240,21 @@ public class HighlightUtil {
|
||||
if (file.getManager().isInProject(file) && !feature.isSufficient(level)) {
|
||||
String message = getUnsupportedFeatureMessage(element, feature, level, file);
|
||||
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(element).descriptionAndTooltip(message).create();
|
||||
QuickFixAction.registerQuickFixAction(info, getFixFactory().createIncreaseLanguageLevelFix(getApplicableLevel(file, feature)));
|
||||
QuickFixAction.registerQuickFixAction(info, getFixFactory().createShowModulePropertiesFix(element));
|
||||
registerIncreaseLanguageLevelFixes(new QuickFixActionRegistrarImpl(info), element, feature);
|
||||
return info;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void registerIncreaseLanguageLevelFixes(@NotNull QuickFixActionRegistrar registrar,
|
||||
@NotNull PsiElement element,
|
||||
@NotNull HighlightingFeature feature) {
|
||||
if (feature.isAvailable(element)) return;
|
||||
registrar.register(getFixFactory().createIncreaseLanguageLevelFix(getApplicableLevel(element.getContainingFile(), feature)));
|
||||
registrar.register(getFixFactory().createShowModulePropertiesFix(element));
|
||||
}
|
||||
|
||||
private static @NotNull String getUnsupportedFeatureMessage(@NotNull PsiElement element,
|
||||
@NotNull HighlightingFeature feature,
|
||||
@NotNull LanguageLevel level,
|
||||
|
||||
@@ -31,6 +31,7 @@ public enum HighlightingFeature {
|
||||
REFS_AS_RESOURCE(LanguageLevel.JDK_1_9, "feature.try.with.resources.refs"),
|
||||
MODULES(LanguageLevel.JDK_1_9, "feature.modules"),
|
||||
LVTI(LanguageLevel.JDK_10, "feature.lvti"),
|
||||
VAR_LAMBDA_PARAMETER(LanguageLevel.JDK_11, "feature.var.lambda.parameter"),
|
||||
ENHANCED_SWITCH(LanguageLevel.JDK_13_PREVIEW, "feature.enhanced.switch"){
|
||||
@Override
|
||||
boolean isSufficient(@NotNull LanguageLevel useSiteLevel) {
|
||||
|
||||
@@ -5,12 +5,10 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.AddExceptionToCatchFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.AddFinallyFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixActionRegistrarImpl;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.core.JavaPsiBundle;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiErrorElement;
|
||||
import com.intellij.psi.PsiSwitchLabeledRuleStatement;
|
||||
import com.intellij.psi.PsiTryStatement;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class JavaErrorQuickFixProvider implements ErrorQuickFixProvider {
|
||||
@@ -29,5 +27,13 @@ public class JavaErrorQuickFixProvider implements ErrorQuickFixProvider {
|
||||
QuickFixAction.registerQuickFixAction(
|
||||
highlightInfo, QUICK_FIX_FACTORY.createWrapSwitchRuleStatementsIntoBlockFix((PsiSwitchLabeledRuleStatement)parent));
|
||||
}
|
||||
if (parent instanceof PsiJavaFile && errorElement.getErrorDescription().equals(
|
||||
JavaPsiBundle.message("expected.class.or.interface"))) {
|
||||
PsiElement child = errorElement.getFirstChild();
|
||||
if (child instanceof PsiIdentifier && child.textMatches(PsiKeyword.RECORD)) {
|
||||
HighlightUtil.registerIncreaseLanguageLevelFixes(
|
||||
new QuickFixActionRegistrarImpl(highlightInfo), errorElement, HighlightingFeature.RECORDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright 2000-2018 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.codeInsight.daemon.impl.analysis;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
|
||||
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class JavaFutureKeywordUseFixProvider extends UnresolvedReferenceQuickFixProvider<PsiJavaCodeReferenceElement> {
|
||||
@Override
|
||||
public void registerFixes(@NotNull PsiJavaCodeReferenceElement ref, @NotNull QuickFixActionRegistrar registrar) {
|
||||
PsiTypeElement typeElement = ObjectUtils.tryCast(ref.getParent(), PsiTypeElement.class);
|
||||
if (typeElement == null || typeElement.getFirstChild() != typeElement.getLastChild()) return;
|
||||
PsiElement parent = typeElement.getParent();
|
||||
if (PsiKeyword.VAR.equals(ref.getReferenceName())) {
|
||||
registerVarLanguageLevelFix(ref, parent, registrar);
|
||||
}
|
||||
if (PsiKeyword.RECORD.equals(ref.getReferenceName())) {
|
||||
registerRecordLanguageLevelFix(ref, parent, registrar);
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerRecordLanguageLevelFix(@NotNull PsiJavaCodeReferenceElement ref,
|
||||
PsiElement parent,
|
||||
@NotNull QuickFixActionRegistrar registrar) {
|
||||
if ((parent instanceof PsiMethod || parent instanceof PsiField) && parent.getParent() instanceof PsiClass) {
|
||||
// record R() {} is parsed as method if records aren't supported
|
||||
// record R incomplete declaration is also possible
|
||||
HighlightUtil.registerIncreaseLanguageLevelFixes(registrar, ref, HighlightingFeature.RECORDS);
|
||||
}
|
||||
if (parent instanceof PsiLocalVariable && parent.getParent() instanceof PsiDeclarationStatement
|
||||
&& ((PsiDeclarationStatement)parent.getParent()).getDeclaredElements().length == 1) {
|
||||
// record R() declaration inside method
|
||||
HighlightUtil.registerIncreaseLanguageLevelFixes(registrar, ref, HighlightingFeature.RECORDS);
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerVarLanguageLevelFix(@NotNull PsiJavaCodeReferenceElement ref,
|
||||
PsiElement parent,
|
||||
@NotNull QuickFixActionRegistrar registrar) {
|
||||
HighlightingFeature feature;
|
||||
if (parent instanceof PsiParameter && ((PsiParameter)parent).getDeclarationScope() instanceof PsiLambdaExpression) {
|
||||
feature = HighlightingFeature.VAR_LAMBDA_PARAMETER;
|
||||
}
|
||||
else {
|
||||
feature = HighlightingFeature.LVTI;
|
||||
}
|
||||
HighlightUtil.registerIncreaseLanguageLevelFixes(registrar, ref, feature);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Class<PsiJavaCodeReferenceElement> getReferenceClass() {
|
||||
return PsiJavaCodeReferenceElement.class;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
// Copyright 2000-2018 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.codeInsight.daemon.impl.analysis;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
|
||||
import com.intellij.pom.java.AcceptedLanguageLevelsSettings;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class LocalVariableTypeInferenceUnresolvedFixProvider extends UnresolvedReferenceQuickFixProvider<PsiJavaCodeReferenceElement> {
|
||||
@Override
|
||||
public void registerFixes(@NotNull PsiJavaCodeReferenceElement ref, @NotNull QuickFixActionRegistrar registrar) {
|
||||
PsiElement typeElement = ref.getParent();
|
||||
PsiElement parent = typeElement instanceof PsiTypeElement ? typeElement.getParent() : null;
|
||||
boolean increaseLanguageLevel = true;
|
||||
LanguageLevel targetLanguageLevel;
|
||||
if (parent instanceof PsiParameter && ((PsiParameter)parent).getDeclarationScope() instanceof PsiLambdaExpression) {
|
||||
//early-draft specification support to be enabled after release
|
||||
if (LanguageLevel.HIGHEST.isAtLeast(LanguageLevel.JDK_11)) {
|
||||
targetLanguageLevel = LanguageLevel.JDK_11;
|
||||
}
|
||||
else if (AcceptedLanguageLevelsSettings.isLanguageLevelAccepted(LanguageLevel.JDK_11)) {
|
||||
targetLanguageLevel = LanguageLevel.JDK_11;
|
||||
|
||||
//show module options with ability to explicitly agree with legal notice
|
||||
increaseLanguageLevel = false;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
targetLanguageLevel = LanguageLevel.JDK_10;
|
||||
}
|
||||
|
||||
if (PsiUtil.getLanguageLevel(ref).isAtLeast(targetLanguageLevel)) return;
|
||||
if (!PsiKeyword.VAR.equals(ref.getReferenceName())) return;
|
||||
|
||||
if (increaseLanguageLevel) {
|
||||
registrar.register(QuickFixFactory.getInstance().createIncreaseLanguageLevelFix(targetLanguageLevel));
|
||||
}
|
||||
registrar.register(QuickFixFactory.getInstance().createShowModulePropertiesFix(ref));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Class<PsiJavaCodeReferenceElement> getReferenceClass() {
|
||||
return PsiJavaCodeReferenceElement.class;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class X {
|
||||
r<caret>ecord R() {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class X {
|
||||
void test() {
|
||||
r<caret>ecord R() {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
r<caret>ecord R() {}
|
||||
@@ -0,0 +1,9 @@
|
||||
class X {
|
||||
interface Fn {
|
||||
void test(String s);
|
||||
}
|
||||
|
||||
void test() {
|
||||
Fn fn = (v<caret>ar s) -> System.out.println(s);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class X {
|
||||
void test() {
|
||||
v<caret>ar x = 5;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// 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.java.codeInsight.daemon;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.java.JavaBundle;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
|
||||
import com.intellij.util.lang.JavaVersion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class IncreaseLanguageLevelFixTest extends LightDaemonAnalyzerTestCase {
|
||||
@Override
|
||||
protected @NotNull String getTestDataPath() {
|
||||
return JavaTestUtil.getJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/increaseLanguageLevel/";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
return IdeaTestUtil.getMockJdk(JavaVersion.compose(14));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LanguageLevel getLanguageLevel() {
|
||||
return LanguageLevel.JDK_1_8;
|
||||
}
|
||||
|
||||
public void testVarLocal() {
|
||||
doTest(LanguageLevel.JDK_10);
|
||||
}
|
||||
|
||||
public void testVarLambda() {
|
||||
doTest(LanguageLevel.JDK_11);
|
||||
}
|
||||
|
||||
public void testRecordTopLevel() {
|
||||
doTest(LanguageLevel.JDK_14_PREVIEW);
|
||||
}
|
||||
|
||||
public void testRecordInClass() {
|
||||
doTest(LanguageLevel.JDK_14_PREVIEW);
|
||||
}
|
||||
|
||||
public void testRecordInMethod() {
|
||||
doTest(LanguageLevel.JDK_14_PREVIEW);
|
||||
}
|
||||
|
||||
private void doTest(LanguageLevel level) {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
doHighlighting();
|
||||
List<IntentionAction> actions = CodeInsightTestFixtureImpl.getAvailableIntentions(getEditor(), getFile());
|
||||
String message = JavaBundle.message("set.language.level.to.0", level.getPresentableText());
|
||||
boolean found = actions.stream().anyMatch(act -> act.getText().equals(message));
|
||||
if (!found) {
|
||||
LanguageLevel foundLevel = Stream.of(LanguageLevel.values())
|
||||
.filter(l -> actions.stream().anyMatch(
|
||||
act -> act.getText().equals(JavaBundle.message("set.language.level.to.0", l.getPresentableText()))))
|
||||
.findFirst().orElse(null);
|
||||
if (foundLevel != null) {
|
||||
fail("Expected level: "+level+"; actual: "+foundLevel);
|
||||
} else {
|
||||
fail("Action " + message + " not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2808,7 +2808,7 @@
|
||||
bundle="messages.InspectionGadgetsBundle" key="inspection.constant.expression.display.name"
|
||||
groupBundle="messages.InspectionsBundle" groupKey="group.names.code.style.issues"
|
||||
implementationClass="com.siyeh.ig.style.ConstantExpressionInspection"/>
|
||||
<codeInsight.unresolvedReferenceQuickFixProvider implementation="com.intellij.codeInsight.daemon.impl.analysis.LocalVariableTypeInferenceUnresolvedFixProvider"/>
|
||||
<codeInsight.unresolvedReferenceQuickFixProvider implementation="com.intellij.codeInsight.daemon.impl.analysis.JavaFutureKeywordUseFixProvider"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user