Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No completion for FQN constructors #2152

Merged
merged 1 commit into from
Jul 18, 2022
Merged

Conversation

snjeza
Copy link
Contributor

@snjeza snjeza commented Jul 6, 2022

Fixes #2147

Signed-off-by: Snjezana Peco [email protected]

@rgrunber
Copy link
Contributor

rgrunber commented Jul 7, 2022

It definitely works. I'm just not sure if we should be accepting this without also fixing the duplicate constructor issue in JDT Core.

@rgrunber
Copy link
Contributor

rgrunber commented Jul 8, 2022

Ok, so this is basically the same principle as redhat-developer/vscode-java#2538 ? The language server is doing the right thing and returning all the constructor invocations that match java.util.Arr from the context of List<String> list = new java.util.Arr|, but the client ignores them because (I'm assuming) java.util.Arr can never match a completion item label like ArrayList(int initialCapacity). So this PR modifies the label to ArrayList(int capacity) - java.util.ArrayList to ensure the match can happen in the client.

  • Is it safe to say we have no control over this "filtering logic" that happens after we return the set of constructors ?
  • Do other clients even suffer from this ?
  • I assume it would be possible to do this change on the client side (eg. vscode-java) by using completion provider ? Maybe adding to the completion item data to contain the package name ?

Update : I noticed the constructors don't define a filterText in their completion items. Can this workaround be simplified just by supplying a proper filterText ?

/**
* A string that should be used when filtering a set of
* completion items. When `falsy` the label is used as the
* filter text for this item.
*/
filterText?: string;

Update 2 : item.setFilterText(typeInfo.toString()); seems to be working for me.

@snjeza
Copy link
Contributor Author

snjeza commented Jul 8, 2022

Update 2 : item.setFilterText(typeInfo.toString()); seems to be working for me.

@rgrunber I have updated the PR. Please review it.

@rgrunber
Copy link
Contributor

rgrunber commented Jul 8, 2022

Awesome. Is there any downside to adding the typeInfo as filterText to all constructor invocations (not just when they're qualified with package name) ? It should simplify the logic quite a bit.

@snjeza
Copy link
Contributor Author

snjeza commented Jul 8, 2022

Awesome. Is there any downside to adding the typeInfo as filterText to all constructor invocations (not just when they're qualified with package name) ? It should simplify the logic quite a bit.

checking...
It works fine.

@snjeza
Copy link
Contributor Author

snjeza commented Jul 8, 2022

@rgrunber I have updated the PR.

@rgrunber
Copy link
Contributor

rgrunber commented Jul 9, 2022

@testforstephen , let me know if you're ok with with merging this. The only downside is it would expose eclipse-jdt/eclipse.jdt.core#195 until it gets fixed.

@testforstephen
Copy link
Contributor

I see some side effects with current change.

  • The filter text has impact on ranking. Since we use FQN as the filter text for the constructor proposal, it will result in the filter matching less efficient for non-FQN constructors. See the case below, the expected proposal new ArrayList<>() is displayed after anonymous proposal, that's not good. It might be better to restrict the new approach to the FQN constructor only.
    image
  • Typing () after the method name, the completion list disappeared.
    Current:
    image
    Expected:
    image
    We had discussion on how to use filterText for method proposal before, see Why is java.signatureHelp disabled by default? redhat-developer/vscode-java#2063 (comment). If we only put the method name in the filter text, then it's better to enable signature help by default to assist the parameter names.

@rgrunber
Copy link
Contributor

@snjeza initially had a change to only do the filterText for the FQN-constuctor case, but I asked to have it removed for ease of maintenance. It could be restored to do as you wanted.

Do we need to abandon the filterText entirely since it breaks completing within the parameter names ? Do we have to restore the label hack ?

Copy link
Contributor

@rgrunber rgrunber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fixed to me. @testforstephen , can you confirm ? The duplicate issue would be fixed after we update the target platform.

@snjeza
Copy link
Contributor Author

snjeza commented Jul 14, 2022

The duplicate issue would be fixed after we update the target platform.

A related PR - #2158

Comment on lines 347 to 351
ICompilationUnit unit = JDTUtils.resolveCompilationUnit(uri);
if (unit != null) {
IDocument document = JsonRpcHelpers.toDocument(unit.getBuffer());
String prefix = document.get(requiredProposal.getReplaceStart(), requiredProposal.getReplaceEnd() - requiredProposal.getReplaceStart());
if (prefix != null && prefix.indexOf(".") > -1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new commit works well for the two cases I mentioned previously. One additional concern is performance.

image

The profiling shows the operation JDTUtils.resolveCompliationUnit is not cheap. For all constructor completion proposals, the completion context prefix should be the same, can we calculate it only once and reuse it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@snjeza
Copy link
Contributor Author

snjeza commented Jul 14, 2022

@rgrunber @testforstephen I have updated the PR.

Comment on lines 344 to 346
Object data = item.getData();
if (data instanceof Map) {
String uri = ((Map<String, String>) data).get(CompletionResolveHandler.DATA_FIELD_URI);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest commit works better.

A minor comment is to remove the unnecessary lines 344 ~ Line 346.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@snjeza
Copy link
Contributor Author

snjeza commented Jul 15, 2022

@rgrunber @testforstephen I have updated the PR.

Copy link
Contributor

@testforstephen testforstephen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

No completion for FQN constructors
3 participants