From 1a267fa0a211bbc2397824e475dff5ab46673414 Mon Sep 17 00:00:00 2001 From: "nsingh@pivotal.io" Date: Wed, 13 Nov 2019 15:25:03 -0800 Subject: [PATCH] PT 159667257 - Fixed sorting issue with proposals Boot LS proposals sorting fixed by wrapping LSP4E proposals with IJavaCompletionProposal and setting relevance value. --- ...ingBootJavaCompletionProposalComputer.java | 88 ++++++++++++++++++- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/jdt/SpringBootJavaCompletionProposalComputer.java b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/jdt/SpringBootJavaCompletionProposalComputer.java index c3ccb40c9..79a7107d3 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/jdt/SpringBootJavaCompletionProposalComputer.java +++ b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/jdt/SpringBootJavaCompletionProposalComputer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2018 Pivotal, Inc. + * Copyright (c) 2017, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -20,10 +20,14 @@ import java.util.concurrent.TimeoutException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext; +import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; import org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer; +import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.jface.text.contentassist.IContextInformation; import org.eclipse.lsp4e.operations.completion.LSContentAssistProcessor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; /** * @author Martin Lippert @@ -52,13 +56,46 @@ public class SpringBootJavaCompletionProposalComputer implements IJavaCompletion }); try { - return Arrays.asList(future.get(TIMEOUT_LENGTH, TIMEOUT_UNIT)); + return Arrays.asList(asJavaProposals(future)); } catch (InterruptedException | ExecutionException | TimeoutException e) { e.printStackTrace(); return Collections.emptyList(); } } + /** + * PT 159667257 - Strange sorting order + * + * In order for boot LS proposals to appear in the right order by JDT, we need to return IJavaCompletionProposal + * . the LSPCompletionProposal that LSP4E computes is NOT IJavaCompletionProposal, and as a consequence JDT + * will by default sort any non Java proposals by display value, which is why we get strange sorting order, even if our boot LS + * and LSP4E both return a proposal list in the right order. + * + * This method wraps around the LSCompletionProposal with a IJavaCompletionProposal, and it sets the relevance + * number that JDT uses to sort proposals in a desired order. + * @param future + * @return + * @throws InterruptedException + * @throws ExecutionException + * @throws TimeoutException + */ + private ICompletionProposal[] asJavaProposals(CompletableFuture future) + throws InterruptedException, ExecutionException, TimeoutException { + ICompletionProposal[] originalProposals = future.get(TIMEOUT_LENGTH, TIMEOUT_UNIT); + + // We assume that the original proposals are in the correct order, so we set relevance + // based on this existing order. Note that based on IJavaCompletionProposal javadoc, + // relevance values are [0,1000] so we start at 1000 + int relevance = 1000; + ICompletionProposal[] javaProposals = new ICompletionProposal[originalProposals.length]; + + for (int i = 0; i < originalProposals.length; i++) { + javaProposals[i] = new LSJavaProposal(originalProposals[i], relevance--); + } + + return javaProposals; + } + @Override public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) { @@ -74,5 +111,52 @@ public class SpringBootJavaCompletionProposalComputer implements IJavaCompletion @Override public void sessionEnded() { } + + class LSJavaProposal implements IJavaCompletionProposal { + + private ICompletionProposal delegate; + private int relevance; + + public LSJavaProposal(ICompletionProposal delegate, int relevance) { + this.delegate = delegate; + this.relevance = relevance; + } + + @Override + public void apply(IDocument document) { + delegate.apply(document); + } + + @Override + public String getAdditionalProposalInfo() { + return delegate.getAdditionalProposalInfo(); + } + + @Override + public IContextInformation getContextInformation() { + return delegate.getContextInformation(); + } + + @Override + public String getDisplayString() { + return delegate.getDisplayString(); + } + + @Override + public Image getImage() { + return delegate.getImage(); + } + + @Override + public Point getSelection(IDocument document) { + return delegate.getSelection(document); + } + + @Override + public int getRelevance() { + return relevance; + } + + } }