[java-codegen] IDEA-246532 Record toString(), equals(), hashCode() not available in Override Methods

GitOrigin-RevId: a4de8e6a3e1fe15037db3d7d2f26793b3d3f4c66
This commit is contained in:
Tagir Valeev
2020-07-24 16:14:39 +07:00
committed by intellij-monorepo-bot
parent 874d090e21
commit def3e9147e
6 changed files with 74 additions and 2 deletions

View File

@@ -79,7 +79,7 @@ public class OverrideImplementExploreUtil {
Map<MethodSignature, PsiMethod> map = hisClass.isInterface() || method.hasModifierProperty(PsiModifier.ABSTRACT) ? abstracts : concretes;
fillMap(signature, method, map);
if (isDefaultMethod(aClass, method)) {
if (shouldAppearInOverrideList(aClass, method)) {
fillMap(signature, method, concretes);
}
}
@@ -144,7 +144,7 @@ public class OverrideImplementExploreUtil {
if (concrete == null
|| PsiUtil.getAccessLevel(concrete.getModifierList()) < PsiUtil.getAccessLevel(abstractOne.getModifierList())
|| !abstractOne.getContainingClass().isInterface() && abstractOne.getContainingClass().isInheritor(concrete.getContainingClass(), true)
|| isDefaultMethod(aClass, abstractOne)) {
|| shouldAppearInOverrideList(aClass, abstractOne)) {
if (finals.get(signature) == null) {
PsiSubstitutor subst = correctSubstitutor(abstractOne, signature.getSubstitutor());
CandidateInfo info = new CandidateInfo(abstractOne, subst);
@@ -165,6 +165,13 @@ public class OverrideImplementExploreUtil {
}
}
private static boolean shouldAppearInOverrideList(@NotNull PsiClass aClass, PsiMethod abstractOne) {
return isDefaultMethod(aClass, abstractOne) ||
// abstract methods from java.lang.Record (equals/hashCode/toString) are implicitly implemented in subclasses
// so it could be reasonable to expect them in 'override' method dialog
CommonClassNames.JAVA_LANG_RECORD.equals(Objects.requireNonNull(abstractOne.getContainingClass()).getQualifiedName());
}
private static boolean preferLeftForImplement(@NotNull PsiMethod left, @NotNull PsiMethod right) {
if (PsiUtil.getAccessLevel(left.getModifierList()) > PsiUtil.getAccessLevel(right.getModifierList())) return true;
if (!left.getContainingClass().isInterface()) return true;

View File

@@ -0,0 +1,16 @@
record R() {
@Override
public boolean equals(Object obj) {
return false;
}
@Override
public int hashCode() {
return 0;
}
@Override
public String toString() {
return null;
}
}

View File

@@ -0,0 +1,26 @@
record R() {
@Override
public boolean equals(Object obj) {
return false;
}
@Override
public int hashCode() {
return 0;
}
@Override
public String toString() {
return null;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
}
}

View File

@@ -0,0 +1,3 @@
record R() {
<caret>
}

View File

@@ -0,0 +1,3 @@
record R() {
<caret>
}

View File

@@ -12,6 +12,7 @@ import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiClass
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.LightProjectDescriptor
import com.intellij.testFramework.ServiceContainerUtil
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
@@ -24,6 +25,22 @@ class OverrideImplementTest extends LightJavaCodeInsightFixtureTestCase {
JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/overrideImplement"
}
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_15
}
private void addRecordClass() {
myFixture.addClass("package java.lang;public abstract class Record {" +
"public abstract boolean equals(Object obj);" +
"public abstract int hashCode();" +
"public abstract String toString();}")
}
void testImplementRecordMethods() { addRecordClass();doTest(true) }
void testOverrideRecordMethods() { addRecordClass();doTest(false) }
void testImplementExtensionMethods() { doTest(true) }
void testOverrideExtensionMethods() { doTest(false) }