Skip to content

Commit ea40d94

Browse files
authored
Record Javadocs not shown in Content Assist suggestions. (eclipse-jdt#4134)
* Completion proposals to be tagged as record component so that clients can fetch the Javadoc contents from the right element. * Method bindings from Object to be picked instead of the synthetic counterparts for toString(), equals() and hashCode() for completion proposals.
1 parent 0054719 commit ea40d94

File tree

7 files changed

+126
-5
lines changed

7 files changed

+126
-5
lines changed

org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests16_2.java

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ public void testCompletionFindConstructor() throws JavaModelException {
491491

492492
assertResults(
493493
"CompletionFindConstructor[METHOD_REF<CONSTRUCTOR>]{, LCompletionFindConstructor;, (I[I)V, CompletionFindConstructor, (i, ia), 39}\n" +
494-
"hashCode[METHOD_REF]{hashCode(), LCompletionFindConstructor;, ()I, hashCode, null, 52}\n" +
494+
"hashCode[METHOD_REF]{hashCode(), Ljava.lang.Object;, ()I, hashCode, null, 52}\n" +
495495
"i[FIELD_REF]{i, LCompletionFindConstructor;, I, i, null, 52}\n" +
496496
"i[METHOD_REF]{i(), LCompletionFindConstructor;, ()I, i, null, 52}\n" +
497497
"x[LOCAL_VARIABLE_REF]{x, null, I, x, null, 52}",
@@ -571,4 +571,75 @@ void foo() {
571571
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner, new NullProgressMonitor());
572572
assertResults("ExplicitCCtorContainingRecord[CONSTRUCTOR_INVOCATION]{(), LExplicitCCtorContainingRecord;, (IIDLjava.lang.Object;)V, ExplicitCCtorContainingRecord, (from, to, length, profile), 59}", requestor.getResults());
573573
}
574+
public void testRecordSyntheticMethods() throws JavaModelException {
575+
this.workingCopies = new ICompilationUnit[2];
576+
this.workingCopies[0] = getWorkingCopy(
577+
"/Completion/src/test/FooBar.java",
578+
"""
579+
package test;
580+
/**
581+
* A foo bar.
582+
* @param foo The foo.
583+
* @param bar The bar.
584+
*/
585+
public record FooBar(String foo, String bar) {}
586+
""");
587+
this.workingCopies[1] = getWorkingCopy(
588+
"/Completion/src/test/X1.java",
589+
"""
590+
package test;
591+
public class X1 {
592+
public static void main(String[] args) {
593+
FooBar fooBar = new FooBar("some foo", "some bar");
594+
fooBar.fo
595+
}
596+
}
597+
""");
598+
CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, false, false, true, true);
599+
requestor.allowAllRequiredProposals();
600+
NullProgressMonitor monitor = new NullProgressMonitor();
601+
String str = this.workingCopies[1].getSource();
602+
String completeBehind = "fooBar.fo";
603+
int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
604+
this.workingCopies[1].codeComplete(cursorLocation, requestor, this.wcOwner, monitor);
605+
606+
assertResults(
607+
"foo[FIELD_REF]{foo, Ltest.FooBar;, Ljava.lang.String;, foo, null, 60}\n"
608+
+ "foo[METHOD_REF]{foo(), Ltest.FooBar;, ()Ljava.lang.String;, foo, null, 60}",
609+
requestor.getResults());
610+
this.workingCopies[1] = getWorkingCopy(
611+
"/Completion/src/test/X1.java",
612+
"""
613+
package test;
614+
public class X1 {
615+
public static void main(String[] args) {
616+
FooBar fooBar = new FooBar("some foo", "some bar");
617+
fooBar.
618+
}
619+
}
620+
""");
621+
requestor = new CompletionTestsRequestor2(true, false, false, true, true);
622+
str = this.workingCopies[1].getSource();
623+
completeBehind = "fooBar.";
624+
cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
625+
this.workingCopies[1].codeComplete(cursorLocation, requestor, this.wcOwner, monitor);
626+
627+
assertResults(
628+
"bar[FIELD_REF]{bar, Ltest.FooBar;, Ljava.lang.String;, bar, null, 60}\n"
629+
+ "bar[METHOD_REF]{bar(), Ltest.FooBar;, ()Ljava.lang.String;, bar, null, 60}\n"
630+
+ "clone[METHOD_REF]{clone(), Ljava.lang.Object;, ()Ljava.lang.Object;, clone, null, 60}\n"
631+
+ "equals[METHOD_REF]{equals(), Ljava.lang.Object;, (Ljava.lang.Object;)Z, equals, (obj), 60}\n"
632+
+ "finalize[METHOD_REF]{finalize(), Ljava.lang.Object;, ()V, finalize, null, 60}\n"
633+
+ "foo[FIELD_REF]{foo, Ltest.FooBar;, Ljava.lang.String;, foo, null, 60}\n"
634+
+ "foo[METHOD_REF]{foo(), Ltest.FooBar;, ()Ljava.lang.String;, foo, null, 60}\n"
635+
+ "getClass[METHOD_REF]{getClass(), Ljava.lang.Object;, ()Ljava.lang.Class<+Ljava.lang.Object;>;, getClass, null, 60}\n"
636+
+ "hashCode[METHOD_REF]{hashCode(), Ljava.lang.Object;, ()I, hashCode, null, 60}\n"
637+
+ "notify[METHOD_REF]{notify(), Ljava.lang.Object;, ()V, notify, null, 60}\n"
638+
+ "notifyAll[METHOD_REF]{notifyAll(), Ljava.lang.Object;, ()V, notifyAll, null, 60}\n"
639+
+ "toString[METHOD_REF]{toString(), Ljava.lang.Object;, ()Ljava.lang.String;, toString, null, 60}\n"
640+
+ "wait[METHOD_REF]{wait(), Ljava.lang.Object;, ()V, wait, null, 60}\n"
641+
+ "wait[METHOD_REF]{wait(), Ljava.lang.Object;, (J)V, wait, (millis), 60}\n"
642+
+ "wait[METHOD_REF]{wait(), Ljava.lang.Object;, (JI)V, wait, (millis, nanos), 60}",
643+
requestor.getResults());
644+
}
574645
}

org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsForRecordPattern.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ public void test006() throws JavaModelException {
258258
String completeBehind = "lr.toStrin";
259259
int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
260260
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
261-
assertResults("toString[METHOD_REF]{toString(), LColoredPoint;, ()Ljava.lang.String;, toString, null, 60}",
261+
assertResults("toString[METHOD_REF]{toString(), Ljava.lang.Object;, ()Ljava.lang.String;, toString, null, 60}",
262262
requestor.getResults());
263263

264264
}

org.eclipse.jdt.core/META-INF/MANIFEST.MF

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.jdt.core; singleton:=true
5-
Bundle-Version: 3.42.100.qualifier
5+
Bundle-Version: 3.43.0.qualifier
66
Bundle-Activator: org.eclipse.jdt.core.JavaCore
77
Bundle-Vendor: %providerName
88
Bundle-Localization: plugin

org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9587,6 +9587,30 @@ else if (this.source != null
95879587
// Standard proposal
95889588
if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
95899589
InternalCompletionProposal proposal = createProposal(completionOnReferenceExpressionName ? CompletionProposal.METHOD_NAME_REFERENCE : CompletionProposal.METHOD_REF, this.actualCompletionPosition);
9590+
9591+
if (method.declaringClass.isRecord() && method instanceof SyntheticMethodBinding smb) {
9592+
MethodBinding[] overridden = null;
9593+
switch(smb.purpose) {
9594+
case SyntheticMethodBinding.RecordOverrideToString:
9595+
overridden = scope.getJavaLangObject().getMethods(TypeConstants.TOSTRING);
9596+
break;
9597+
case SyntheticMethodBinding.RecordOverrideHashCode:
9598+
overridden = scope.getJavaLangObject().getMethods(TypeConstants.HASHCODE);
9599+
break;
9600+
case SyntheticMethodBinding.RecordOverrideEquals:
9601+
overridden = scope.getJavaLangObject().getMethods(TypeConstants.EQUALS);
9602+
break;
9603+
case SyntheticMethodBinding.RecordComponentReadAccess:
9604+
proposal.flagRecordComponentAccessor();
9605+
break;
9606+
default:
9607+
break;
9608+
}
9609+
if (overridden != null && overridden.length > 0) {
9610+
method = overridden[0];
9611+
}
9612+
}
9613+
95909614
proposal.setBinding(method);
95919615
proposal.setDeclarationSignature(getSignature(method.declaringClass));
95929616
proposal.setSignature(getSignature(method));

org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public class InternalCompletionProposal extends CompletionProposal {
5555
protected int accessibility = IAccessRule.K_ACCESSIBLE;
5656

5757
protected boolean isConstructor = false;
58+
protected boolean isComponentAccessor = false;
5859

5960
/**
6061
* Kind of completion request.
@@ -464,6 +465,9 @@ protected void setAccessibility(int kind) {
464465
protected void setIsContructor(boolean isConstructor) {
465466
this.isConstructor = isConstructor;
466467
}
468+
protected void flagRecordComponentAccessor() {
469+
this.isComponentAccessor = true;
470+
}
467471
public void setOriginalSignature(char[] originalSignature) {
468472
this.originalSignature = originalSignature;
469473
}
@@ -1044,6 +1048,10 @@ public int getAccessibility() {
10441048
public boolean isConstructor() {
10451049
return this.isConstructor;
10461050
}
1051+
@Override
1052+
public boolean isRecordComponentAccessor() {
1053+
return this.isComponentAccessor;
1054+
}
10471055

10481056
private int receiverStart;
10491057
private int receiverEnd;

org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1695,7 +1695,7 @@ public int getAccessibility() {
16951695
* <li><code>METHOD_DECLARATION</code> - return <code>true</code>
16961696
* if the declared method is a constructor</li>
16971697
* </ul>
1698-
* For kinds of completion proposals, this method returns
1698+
* For other kinds of completion proposals, this method returns
16991699
* <code>false</code>.
17001700
*
17011701
* @return <code>true</code> if the proposal is a constructor.
@@ -1705,6 +1705,24 @@ public boolean isConstructor() {
17051705
return false; // default overridden by concrete implementation
17061706
}
17071707

1708+
/**
1709+
* Returns whether this proposal is a record component accessor.
1710+
* <p>
1711+
* This field is available for the following kinds of
1712+
* completion proposals:
1713+
* <ul>
1714+
* <li><code>METHOD_REF</code> - return <code>true</code>
1715+
* if the referenced method is a record component accessor</li>
1716+
* </ul>
1717+
* For other kinds of completion proposals, this method returns
1718+
* <code>false</code>.
1719+
*
1720+
* @return <code>true</code> if the proposal is a record component accessor.
1721+
* @since 3.43
1722+
*/
1723+
public boolean isRecordComponentAccessor() {
1724+
return false;
1725+
}
17081726
/**
17091727
* Returns the type signature or package name of the relevant
17101728
* receiver in the context, or <code>null</code> if none.

org.eclipse.jdt.core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<version>4.37.0-SNAPSHOT</version>
1818
</parent>
1919
<artifactId>org.eclipse.jdt.core</artifactId>
20-
<version>3.42.100-SNAPSHOT</version>
20+
<version>3.43.0-SNAPSHOT</version>
2121
<packaging>eclipse-plugin</packaging>
2222

2323
<properties>

0 commit comments

Comments
 (0)