From 585108db36bb5216dd29b081f4bc265495f9094f Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Fri, 22 Jan 2021 15:04:46 +0800 Subject: [PATCH 1/2] Sort completion by relevance & respect completion filters registered by JLS --- .../java/debug/core/protocol/Types.java | 4 + .../internal/CompletionProposalRequestor.java | 84 ++++++++++++++++++- .../plugin/internal/CompletionsProvider.java | 5 ++ 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Types.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Types.java index 017814a30..3ce41869c 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Types.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Types.java @@ -278,6 +278,10 @@ public static class CompletionItem { public String label; public String text; public String type; + /** + * A string that should be used when comparing this item with other items. + */ + public String sortText; public int start; public int number; diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java index 2b32ae3f6..6ef2aa4ca 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java @@ -22,6 +22,7 @@ import java.util.logging.Logger; import org.apache.commons.lang3.StringUtils; +import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.CompletionContext; @@ -34,6 +35,7 @@ import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeRoot; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin; import org.eclipse.jdt.ls.core.internal.contentassist.CompletionProposalDescriptionProvider; import org.eclipse.jdt.ls.core.internal.contentassist.GetterSetterCompletionProposal; @@ -109,6 +111,10 @@ private boolean isTestSource(IJavaProject project, ITypeRoot cu) { @Override public void accept(CompletionProposal proposal) { + if (isFiltered(proposal)) { + return; + } + if (!isIgnored(proposal.getKind())) { if (proposal.getKind() == CompletionProposal.POTENTIAL_METHOD_DECLARATION) { acceptPotentialMethodDeclaration(proposal); @@ -265,4 +271,80 @@ public CompletionContext getContext() { return context; } -} \ No newline at end of file + /** + * copied from + * org.eclipse.jdt.ui.text.java.CompletionProposalCollector.isFiltered(CompletionProposal) + */ + private boolean isFiltered(CompletionProposal proposal) { + if (isIgnored(proposal.getKind())) { + return true; + } + + try { + // Only filter types and constructors from completion. + // Methods from already imported types and packages can still be proposed. + // See https://github.com/eclipse/eclipse.jdt.ls/issues/1212 + switch (proposal.getKind()) { + case CompletionProposal.CONSTRUCTOR_INVOCATION: + case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION: + case CompletionProposal.JAVADOC_TYPE_REF: + case CompletionProposal.TYPE_REF: { + char[] declaringType = getDeclaringType(proposal); + return declaringType != null && org.eclipse.jdt.ls.core.internal.contentassist.TypeFilter.isFiltered(declaringType); + } + } + } catch (Exception e) { + // do nothing + } + + return false; + } + + /** + * copied from + * org.eclipse.jdt.ui.text.java.CompletionProposalCollector.getDeclaringType(CompletionProposal) + */ + private final char[] getDeclaringType(CompletionProposal proposal) { + switch (proposal.getKind()) { + case CompletionProposal.METHOD_DECLARATION: + case CompletionProposal.METHOD_NAME_REFERENCE: + case CompletionProposal.JAVADOC_METHOD_REF: + case CompletionProposal.METHOD_REF: + case CompletionProposal.CONSTRUCTOR_INVOCATION: + case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION: + case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER: + case CompletionProposal.ANNOTATION_ATTRIBUTE_REF: + case CompletionProposal.POTENTIAL_METHOD_DECLARATION: + case CompletionProposal.ANONYMOUS_CLASS_DECLARATION: + case CompletionProposal.FIELD_REF: + case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER: + case CompletionProposal.JAVADOC_FIELD_REF: + case CompletionProposal.JAVADOC_VALUE_REF: + char[] declaration = proposal.getDeclarationSignature(); + // special methods may not have a declaring type: methods defined on arrays etc. + // Currently known: class literals don't have a declaring type - use Object + if (declaration == null) { + return "java.lang.Object".toCharArray(); //$NON-NLS-1$ + } + return Signature.toCharArray(declaration); + case CompletionProposal.PACKAGE_REF: + case CompletionProposal.MODULE_REF: + case CompletionProposal.MODULE_DECLARATION: + return proposal.getDeclarationSignature(); + case CompletionProposal.JAVADOC_TYPE_REF: + case CompletionProposal.TYPE_REF: + return Signature.toCharArray(proposal.getSignature()); + case CompletionProposal.LOCAL_VARIABLE_REF: + case CompletionProposal.VARIABLE_DECLARATION: + case CompletionProposal.KEYWORD: + case CompletionProposal.LABEL_REF: + case CompletionProposal.JAVADOC_BLOCK_TAG: + case CompletionProposal.JAVADOC_INLINE_TAG: + case CompletionProposal.JAVADOC_PARAM_REF: + return null; + default: + Assert.isTrue(false); + return null; + } + } +} diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionsProvider.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionsProvider.java index 3b9680017..19b808161 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionsProvider.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionsProvider.java @@ -115,6 +115,11 @@ private CompletionItem convertFromLsp(org.eclipse.lsp4j.CompletionItem lspItem) if (lspItem.getKind() != null) { item.type = lspItem.getKind().name().toLowerCase(); } + + if (lspItem.getSortText() != null) { + item.sortText = lspItem.getSortText(); + } + return item; } } From 0ce272413903c8563a4e3d366b3843ce7526bea8 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Fri, 22 Jan 2021 15:41:55 +0800 Subject: [PATCH 2/2] Make checkstyle happy --- .../java/debug/plugin/internal/CompletionProposalRequestor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java index 6ef2aa4ca..be7932992 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java @@ -292,6 +292,7 @@ private boolean isFiltered(CompletionProposal proposal) { char[] declaringType = getDeclaringType(proposal); return declaringType != null && org.eclipse.jdt.ls.core.internal.contentassist.TypeFilter.isFiltered(declaringType); } + default: // do nothing } } catch (Exception e) { // do nothing