Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 578815 - [content assist] Provide concrete types when expecting an interface on new object completion
Summary: [content assist] Provide concrete types when expecting an interface on new ob...
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.22   Edit
Hardware: PC All
: P3 normal with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-02-17 22:07 EST by Sheng Chen CLA
Modified: 2023-03-19 21:39 EDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sheng Chen CLA 2022-02-17 22:07:42 EST
Given the following Java code:

  java.util.List<String> list = new |

The completion list will show the constructors of the expected type. This feature is very handy when the expected type is an object. But when it comes to an interface (like the above example), it’s not useful anymore. Since most commonly people will new an implementation of the List interface like ‘ArrayList’ or ‘LinkedList’ instead of having an anonymous class creation.

I have an idea to add more completion candidates for this case.

For example, when the expected type is java.util.List, then we search all the constructors under the package java.util, and then only accept those which are compatible with java.util.List.

A fake code of this proposal could look like this:

In org.eclipse.jdt.internal.codeassist.CompletionEngine#findTypesAndPackages()@line 11624,

if (isEmptyPrefix && !this.assistNodeIsAnnotation) {
    if (!proposeConstructor) {
        findTypesFromExpectedTypes(token, scope, typesFound, proposeType, proposeConstructor);
    } else {
        /* 1. Get qualified package name of the expected type */

        /* 2. Find constructor declarations which start with the qualified package name */

        /* 3. Filter out the constructors which are not compatible with the expected type */
    }
}

By doing such changes, users are more likely to find the right completion candidate. And since we limit the search scope into a specific package, the performance should not be a big problem (We can even only do such search when the qualified package name has more than 2 components).
Comment 1 Sheng Chen CLA 2022-02-22 00:18:55 EST
Hi team,

Do you have any ideas or concerns about this proposal? I'm willing to make a pull request if you think this proposal makes sense :)
Comment 2 Sheng Chen CLA 2022-02-25 03:08:42 EST
Another idea: Maybe we can try to find subtypes of the expected type. This should be better than searching all the constructors under a package.

To make sure the performance is acceptable, maybe we can try to only search for the directed subtypes (search for only one level). I checked the APIs of the SearchEngine, looks like it can only search for all the subtypes, is this true?
Comment 3 Dirk Steinkamp CLA 2022-02-26 05:38:55 EST
(In reply to Sheng Chen from comment #2)
> Another idea: Maybe we can try to find subtypes of the expected type. This
> should be better than searching all the constructors under a package.
> 
> To make sure the performance is acceptable, maybe we can try to only search
> for the directed subtypes (search for only one level). I checked the APIs of
> the SearchEngine, looks like it can only search for all the subtypes, is
> this true?

Why would you limit it to direct subtypes if you get more out of the box? Depending on how the search index is internally organized looking for subtypes might be not such an expensive operation.

Your idea could be extended to support static factory methods, that create desired objects, e.g.:

    List<String> l = |

could propose

    Collections.emptyList()

and the likes.

But maybe all this is something the code recommenders project was about, which is unfortunately archived, as it doesn't have active contributors:

    https://projects.eclipse.org/projects/technology.recommenders
Comment 4 Sheng Chen CLA 2022-02-28 03:41:57 EST
Thank you Dirk for replying.

I made a mistake about the statement: 'the SearchEngine can only search for all the subtypes'. In fact, the truth is that it can find the direct subtype (but not all, see org.eclipse.jdt.internal.core.search.matching.SuperTypeReferencePattern).

That's exactly what I need. I think we can consider do a search for the direct implementers when the expected type is an interface.

I did a rough experiment that triggering completion at 'java.util.List<String> list = new |' in the project spring-petclinic, which contains 106 index files. For the first time, it takes ~600 ms to resolve the proposals. Start from the second time, it reduced to ~200ms. I think the time is acceptable.

// My machine is i7-10700 + 32G mem + Windows.
Comment 5 Eclipse Genie CLA 2022-03-01 21:14:53 EST
New Gerrit change created: https://git.eclipse.org/r/c/jdt/eclipse.jdt.core/+/191337
Comment 6 Simeon Andreev CLA 2023-03-17 15:45:01 EDT
Is this bug done? The commit is in GitHub: https://github.com/eclipse-jdt/eclipse.jdt.core/commit/a15d9e04a750aba2960ff12853200cba4bfcc197

Please close this ticket if so. I didn't find an issue or PR on GitHub, so I can't close this as moved.