From 24557b83380b32f7741c9de2ae9841b61e2d33f3 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 20 Dec 2024 15:58:23 +0100 Subject: [PATCH] Java: fix inappropriate quick-fix for bodyless methods in record (IDEA-299166) fixes error message as well GitOrigin-RevId: 2b9d54fa48b282dc003753645237ebfdb50c0d01 --- .../daemon/impl/analysis/HighlightMethodUtil.java | 8 +++++--- .../resources/messages/JavaErrorBundle.properties | 3 ++- .../advHighlighting/AbstractMethods.java | 11 ++++++++--- .../advHighlightingRecords/RecordBasics.java | 3 +++ .../testData/inspection/optionalGet/OptionalGet.java | 2 +- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index 06541ca42ec5..fbd5303b917d 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -1300,12 +1300,14 @@ public final class HighlightMethodUtil { int start = method.getModifierList().getTextRange().getStartOffset(); int end = Math.max(start, method.getTextRange().getEndOffset()); - String description = JavaErrorBundle.message("missing.method.body"); + boolean abstractAllowed = !aClass.isRecord() && !method.isConstructor() && !(aClass instanceof PsiAnonymousClass); + String description = abstractAllowed + ? JavaErrorBundle.message("missing.method.body.or.declare.abstract") + : JavaErrorBundle.message("missing.method.body"); errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(start, end).descriptionAndTooltip(description); IntentionAction action = QuickFixFactory.getInstance().createAddMethodBodyFix(method); errorResult.registerFix(action, null, null, null, null); - if (HighlightUtil.getIncompatibleModifier(PsiModifier.ABSTRACT, method.getModifierList()) == null && - !(aClass instanceof PsiAnonymousClass)) { + if (abstractAllowed && HighlightUtil.getIncompatibleModifier(PsiModifier.ABSTRACT, method.getModifierList()) == null) { final List actions = JvmElementActionFactories.createModifierActions(method, MemberRequestsKt.modifierRequest(JvmModifier.ABSTRACT, true)); QuickFixAction.registerQuickFixActions(errorResult, null, actions); diff --git a/java/java-psi-impl/resources/messages/JavaErrorBundle.properties b/java/java-psi-impl/resources/messages/JavaErrorBundle.properties index 5f066ac8f09c..a0b1bba51409 100644 --- a/java/java-psi-impl/resources/messages/JavaErrorBundle.properties +++ b/java/java-psi-impl/resources/messages/JavaErrorBundle.properties @@ -158,7 +158,8 @@ ambiguous.method.call=Ambiguous method call: both ''{0}'' and ''{1}'' match ambiguous.reference=Reference to ''{0}'' is ambiguous, both ''{1}'' and ''{2}'' match cannot.resolve.method=Cannot resolve method ''{0}'' ambiguous.method.call.no.match=Cannot resolve method ''{0}'' in ''{1}'' -missing.method.body=Missing method body, or declare abstract +missing.method.body.or.declare.abstract=Method body or 'abstract' modifier expected +missing.method.body=Method body expected abstract.method.in.non.abstract.class=Abstract method in non-abstract class missing.return.type=Invalid method declaration; return type required duplicate.method=''{0}'' is already defined in ''{1}'' diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/AbstractMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/AbstractMethods.java index f05274772299..ebdcea255886 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/AbstractMethods.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/AbstractMethods.java @@ -1,11 +1,11 @@ // abstract methods class a { - void f(); + void f(); } abstract class c1 { abstract void f1(); - int f2(); + int f2(); } interface ff { @@ -80,7 +80,11 @@ abstract class cc2 extends cc1 { abstract protected void f(int i); } class cc3 extends cc2 { - public void f(int i) {} + public void f(int i) { + new Object() { + void x(); + }; + } } /////////////// interface MyComparator { @@ -89,6 +93,7 @@ interface MyComparator { boolean equals(java.lang.Object object); } class MyComparatorImpl implements MyComparator { + MyComparatorImpl(); public int compare(Object o, Object o1) { new MyComparator() { public int compare(Object o, Object o1) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingRecords/RecordBasics.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingRecords/RecordBasics.java index ac867931adbb..995d599a89cf 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingRecords/RecordBasics.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingRecords/RecordBasics.java @@ -80,4 +80,7 @@ record ExtendsRecordExplicitly() record AbstractMethod() { abstract void f(); +} +record MethodWithoutBody() { + void x(); } \ No newline at end of file diff --git a/java/java-tests/testData/inspection/optionalGet/OptionalGet.java b/java/java-tests/testData/inspection/optionalGet/OptionalGet.java index 633a4749d226..a80c597a63df 100644 --- a/java/java-tests/testData/inspection/optionalGet/OptionalGet.java +++ b/java/java-tests/testData/inspection/optionalGet/OptionalGet.java @@ -370,7 +370,7 @@ class CtorTest { System.out.println(test.get()); } - CtorTest(String noBody); + CtorTest(String noBody); void something() { test = Optional.empty();