Skip to content

Commit

Permalink
Implement labelDetails for CompletionItem
Browse files Browse the repository at this point in the history
Signed-off-by: Jessica He <[email protected]>
  • Loading branch information
JessicaJHee committed Apr 11, 2023
1 parent c5e3114 commit 96b220e
Show file tree
Hide file tree
Showing 13 changed files with 249 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.eclipse.jdt.ls.core.internal.handlers.JsonRpcHelpers;
import org.eclipse.jface.text.IDocument;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionItemLabelDetails;

/**
* Provides string labels for completionProposals.
Expand Down Expand Up @@ -93,15 +94,20 @@ public StringBuilder createMethodProposalDescription(CompletionProposal proposal

// return type
if (!proposal.isConstructor()) {
// TODO remove SignatureUtil.fix83600 call when bugs are fixed
char[] returnType = createTypeDisplayName(SignatureUtil.getUpperBound(Signature.getReturnType(SignatureUtil.fix83600(proposal.getSignature()))));
description.append(RETURN_TYPE_SEPARATOR);
description.append(returnType);
appendReturnType(description, proposal);
}
}
return description; // dummy
}

private StringBuilder appendReturnType(StringBuilder description, CompletionProposal proposal){
// TODO remove SignatureUtil.fix83600 call when bugs are fixed
char[] returnType = createTypeDisplayName(SignatureUtil.getUpperBound(Signature.getReturnType(SignatureUtil.fix83600(proposal.getSignature()))));
description.append(returnType);
return description;
}

/**
* Creates and returns a parameter list of the given method or type proposal suitable for
* display. The list does not include parentheses. The lower bound of parameter types is
Expand Down Expand Up @@ -313,7 +319,21 @@ private final StringBuilder appendParameterSignature(StringBuilder buffer, char[
*/
private void createMethodProposalLabel(CompletionProposal methodProposal, CompletionItem item) {
StringBuilder description = this.createMethodProposalDescription(methodProposal);
item.setLabel(description.toString());
if (isCompletionItemLabelDetailsSupport()){
StringBuilder methodParams = new StringBuilder();
methodParams.append('(');
appendUnboundedParameterList(methodParams, methodProposal);
methodParams.append(')');
if (methodProposal.getKind() != CompletionProposal.CONSTRUCTOR_INVOCATION) {
StringBuilder returnType = new StringBuilder();
appendReturnType(returnType, methodProposal);
setLabelDetails(item, String.valueOf(methodProposal.getName()), methodParams.toString(), returnType.toString());
} else {
setLabelDetails(item, String.valueOf(methodProposal.getName()), methodParams.toString(), null);
}
} else {
item.setLabel(description.toString());
}
item.setInsertText(String.valueOf(methodProposal.getName()));

// declaring type
Expand Down Expand Up @@ -375,27 +395,37 @@ private void createJavadocMethodProposalLabel(CompletionProposal methodProposal,
String declaringType= extractDeclaringTypeFQN(methodProposal);
declaringType= Signature.getSimpleName(declaringType);
item.setDetail(declaringType);
// don't set completion item description in the case of constructor
if (isCompletionItemLabelDetailsSupport() && methodProposal.getKind() != CompletionProposal.CONSTRUCTOR_INVOCATION){
StringBuilder returnType = new StringBuilder();
appendReturnType(returnType, methodProposal);
setLabelDetails(item, null, null, returnType.toString());
}
}

private void createOverrideMethodProposalLabel(CompletionProposal methodProposal, CompletionItem item) {
StringBuilder nameBuffer= new StringBuilder();

// method name
String name = new String(methodProposal.getName());
item.setInsertText(name);
nameBuffer.append(name);
// parameters
nameBuffer.append('(');
appendUnboundedParameterList(nameBuffer, methodProposal);
nameBuffer.append(')');

nameBuffer.append(RETURN_TYPE_SEPARATOR);

StringBuilder parameters = new StringBuilder();
parameters.append('(');
appendUnboundedParameterList(parameters, methodProposal);
parameters.append(')');
// return type
// TODO remove SignatureUtil.fix83600 call when bugs are fixed
char[] returnType= createTypeDisplayName(SignatureUtil.getUpperBound(Signature.getReturnType(SignatureUtil.fix83600(methodProposal.getSignature()))));
nameBuffer.append(returnType);
item.setLabel(nameBuffer.toString());
char[] returnType = createTypeDisplayName(SignatureUtil.getUpperBound(Signature.getReturnType(SignatureUtil.fix83600(methodProposal.getSignature()))));

if (isCompletionItemLabelDetailsSupport()) {
setLabelDetails(item, String.valueOf(methodProposal.getName()), parameters.toString(), String.valueOf(returnType));
} else {
StringBuilder nameBuffer = new StringBuilder();
nameBuffer.append(name);
nameBuffer.append(parameters);
nameBuffer.append(RETURN_TYPE_SEPARATOR);
nameBuffer.append(returnType);
item.setLabel(nameBuffer.toString());
}
item.setFilterText(name);

// declaring type
Expand Down Expand Up @@ -471,16 +501,23 @@ void createTypeProposalLabel(char[] fullName, CompletionItem item) {
int qIndex= findSimpleNameStart(fullName);

String name = new String(fullName, qIndex, fullName.length - qIndex);
StringBuilder nameBuffer= new StringBuilder();
nameBuffer.append(name);
if (qIndex > 0) {
nameBuffer.append(PACKAGE_NAME_SEPARATOR);
nameBuffer.append(new String(fullName,0,qIndex-1));
}
item.setFilterText(name);
item.setInsertText(name);
item.setLabel(nameBuffer.toString());
item.setDetail(new String(fullName));

String packageName = qIndex > 0 ? new String(fullName, 0, qIndex - 1) : null;

if (isCompletionItemLabelDetailsSupport()) {
setLabelDetails(item, name, null, packageName);
} else {
StringBuilder nameBuffer = new StringBuilder();
nameBuffer.append(name);
if (packageName != null) {
nameBuffer.append(PACKAGE_NAME_SEPARATOR);
nameBuffer.append(packageName);
}
item.setLabel(nameBuffer.toString());
}
}

private void createJavadocTypeProposalLabel(char[] fullName, CompletionItem item) {
Expand All @@ -496,8 +533,9 @@ private void createJavadocTypeProposalLabel(char[] fullName, CompletionItem item
nameBuffer.append('}');
item.setLabel(nameBuffer.toString());
item.setFilterText(name);
if (qIndex > 0) {
item.setDetail(new String(fullName, 0, qIndex - 1));
String packageName = qIndex > 0 ? new String(fullName, 0, qIndex - 1) : null;
if (packageName != null) {
item.setDetail(packageName);
}
}

Expand All @@ -515,15 +553,21 @@ private int findSimpleNameStart(char[] array) {
}

private void createSimpleLabelWithType(CompletionProposal proposal, CompletionItem item) {
StringBuilder nameBuffer= new StringBuilder();
nameBuffer.append(proposal.getCompletion());
item.setInsertText(nameBuffer.toString());
char[] typeName= Signature.getSignatureSimpleName(proposal.getSignature());
if (typeName.length > 0) {
nameBuffer.append(VAR_TYPE_SEPARATOR);
nameBuffer.append(typeName);
char[] typeName = Signature.getSignatureSimpleName(proposal.getSignature());
String name = String.valueOf(proposal.getCompletion());
item.setInsertText(name);

if (isCompletionItemLabelDetailsSupport()) {
setLabelDetails(item, name, null, String.valueOf(typeName));
} else {
StringBuilder nameBuffer = new StringBuilder();
nameBuffer.append(name);
if (typeName.length > 0) {
nameBuffer.append(VAR_TYPE_SEPARATOR);
nameBuffer.append(typeName);
}
item.setLabel(nameBuffer.toString());
}
item.setLabel(nameBuffer.toString());
}

/**
Expand All @@ -544,16 +588,20 @@ private void createLabelWithTypeAndDeclaration(CompletionProposal proposal, Comp
if (!isThisPrefix(name)) {
name= proposal.getName();
}
StringBuilder buf= new StringBuilder();
char[] typeName= Signature.getSignatureSimpleName(proposal.getSignature());

StringBuilder buf = new StringBuilder();
buf.append(name);
item.setInsertText(buf.toString());
char[] typeName= Signature.getSignatureSimpleName(proposal.getSignature());
if (typeName.length > 0) {
buf.append(VAR_TYPE_SEPARATOR);
buf.append(typeName);
}
item.setLabel(buf.toString());
if (isCompletionItemLabelDetailsSupport()){
setLabelDetails(item, String.valueOf(name), null, String.valueOf(typeName));
} else {
item.setLabel(buf.toString());
}

char[] declaration= proposal.getDeclarationSignature();
StringBuilder detailBuf = new StringBuilder();
Expand Down Expand Up @@ -587,6 +635,9 @@ private void createPackageProposalLabel(CompletionProposal proposal, CompletionI
detail.append(proposal.getKind() == CompletionProposal.PACKAGE_REF ? "(package) " : "(module) ");
detail.append(String.valueOf(proposal.getDeclarationSignature()));
item.setDetail(detail.toString());
if (isCompletionItemLabelDetailsSupport()){
setLabelDetails(item, null, null, proposal.getKind() == CompletionProposal.PACKAGE_REF ? "(package)" : "(module)");
}
}

StringBuilder createSimpleLabel(CompletionProposal proposal) {
Expand All @@ -600,15 +651,24 @@ private void createAnonymousTypeLabel(CompletionProposal proposal, CompletionIte
declaringTypeSignature= Signature.getTypeErasure(declaringTypeSignature);
String name = new String(Signature.getSignatureSimpleName(declaringTypeSignature));
item.setInsertText(name);
StringBuilder buf= new StringBuilder();
buf.append(name);
buf.append('(');
appendUnboundedParameterList(buf, proposal);
buf.append(')');
buf.append(" "); //$NON-NLS-1$
buf.append("Anonymous Inner Type"); //TODO: consider externalization
item.setLabel(buf.toString());

StringBuilder methodParams = new StringBuilder();
methodParams.append('(');
appendUnboundedParameterList(methodParams, proposal);
methodParams.append(')');

if (isCompletionItemLabelDetailsSupport()){
StringBuilder returnType = new StringBuilder();
appendReturnType(returnType, proposal);
setLabelDetails(item, name, methodParams.toString(), "Anonymous Inner Type");
} else {
StringBuilder buf= new StringBuilder();
buf.append(name);
buf.append(methodParams);
buf.append(" "); //$NON-NLS-1$
buf.append("Anonymous Inner Type"); //TODO: consider externalization
item.setLabel(buf.toString());
}
if (proposal.getRequiredProposals() != null) {
char[] signatureQualifier= Signature.getSignatureQualifier(declaringTypeSignature);
if (signatureQualifier.length > 0) {
Expand All @@ -619,16 +679,19 @@ private void createAnonymousTypeLabel(CompletionProposal proposal, CompletionIte
}

private void createLabelWithLambdaExpression(CompletionProposal proposal, CompletionItem item) {
StringBuilder buffer = new StringBuilder();
buffer.append('(');
appendUnboundedParameterList(buffer, proposal);
buffer.append(')');
buffer.append(" ->");
StringBuilder label = new StringBuilder();
label.append('(');
appendUnboundedParameterList(label, proposal);
label.append(')');
label.append(" ->");
char[] returnType = createTypeDisplayName(SignatureUtil.getUpperBound(Signature.getReturnType(SignatureUtil.fix83600(proposal.getSignature()))));
buffer.append(RETURN_TYPE_SEPARATOR);
buffer.append(returnType);
String label = buffer.toString();
item.setLabel(label);
if (isCompletionItemLabelDetailsSupport()) {
setLabelDetails(item, label.toString(), null, String.valueOf(returnType));
} else {
label.append(RETURN_TYPE_SEPARATOR);
label.append(returnType);
item.setLabel(label.toString());
}
}

/**
Expand Down Expand Up @@ -740,4 +803,32 @@ private String getProposal(CompletionProposal proposal) {
}
return "unknown";
}

/**
*
* Sets the Completion Item Label Details
*
* @param item the completion item
* @param label the label of the completion item
* @param detail the detail of the completion item
* @param description the description of the completion item showing the return type
*
*/
private void setLabelDetails(CompletionItem item, String label, String detail, String description) {
CompletionItemLabelDetails itemLabelDetails = new CompletionItemLabelDetails();
if (label != null) {
item.setLabel(label);
}
if (detail != null) {
itemLabelDetails.setDetail(detail);
}
if (description != null) {
itemLabelDetails.setDescription(description);
}
item.setLabelDetails(itemLabelDetails);
}

private boolean isCompletionItemLabelDetailsSupport() {
return JavaLanguageServerPlugin.getPreferencesManager() != null && JavaLanguageServerPlugin.getPreferencesManager().getClientPreferences().isCompletionItemLabelDetailsSupport();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionItemDefaults;
import org.eclipse.lsp4j.CompletionItemKind;
import org.eclipse.lsp4j.CompletionItemLabelDetails;
import org.eclipse.lsp4j.InsertTextFormat;

public class SnippetCompletionProposal extends CompletionProposal {
Expand Down Expand Up @@ -318,6 +319,11 @@ private static List<CompletionItem> getGenericSnippets(SnippetCompletionContext
item.setTextEditText(SnippetUtils.templateToSnippet(template.getPattern()));
}
item.setDetail(template.getDescription());
if (isCompletionItemLabelDetailsSupport()){
CompletionItemLabelDetails itemLabelDetails = new CompletionItemLabelDetails();
itemLabelDetails.setDescription(template.getDescription());
item.setLabelDetails(itemLabelDetails);
}

Map<String, String> data = new HashMap<>(3);
data.put(CompletionResolveHandler.DATA_FIELD_URI, uri);
Expand All @@ -335,6 +341,10 @@ private static List<CompletionItem> getGenericSnippets(SnippetCompletionContext
return res;
}

private static boolean isCompletionItemLabelDetailsSupport() {
return JavaLanguageServerPlugin.getPreferencesManager() != null && JavaLanguageServerPlugin.getPreferencesManager().getClientPreferences().isCompletionItemLabelDetailsSupport();
}

public static String evaluateGenericTemplate(ICompilationUnit cu, CompletionContext completionContext, Template template) {
JavaContextType contextType = (JavaContextType) JavaLanguageServerPlugin.getInstance().getTemplateContextRegistry().getContextType(JavaContextType.ID_STATEMENTS);
char[] completionToken = completionContext.getToken();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionItemDefaults;
import org.eclipse.lsp4j.CompletionItemKind;
import org.eclipse.lsp4j.CompletionItemLabelDetails;
import org.eclipse.lsp4j.InsertTextFormat;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextEdit;
Expand Down Expand Up @@ -108,6 +109,11 @@ public List<CompletionItem> complete(IDocument document, int offset, ICompilatio
item.setInsertTextFormat(null);
}
item.setDetail(template.getDescription());
if (isCompletionItemLabelDetailsSupport()) {
CompletionItemLabelDetails itemLabelDetails = new CompletionItemLabelDetails();
itemLabelDetails.setDescription(template.getDescription());
item.setLabelDetails(itemLabelDetails);
}
item.setDocumentation(SnippetUtils.beautifyDocument(content));
// we hope postfix shows at the bottom of the completion list.
item.setSortText(SortTextHelper.convertRelevance(0));
Expand All @@ -125,6 +131,10 @@ public List<CompletionItem> complete(IDocument document, int offset, ICompilatio
return res;
}

private boolean isCompletionItemLabelDetailsSupport() {
return JavaLanguageServerPlugin.getPreferencesManager() != null && JavaLanguageServerPlugin.getPreferencesManager().getClientPreferences().isCompletionItemLabelDetailsSupport();
}

/**
* see
* org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateEngine.isTemplateAllowed(Template,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.eclipse.jdt.ls.core.internal.syntaxserver.ModelBasedCompletionEngine;
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionItemOptions;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.CompletionOptions;
import org.eclipse.lsp4j.CompletionParams;
Expand All @@ -60,7 +61,16 @@

public class CompletionHandler{

public final static CompletionOptions DEFAULT_COMPLETION_OPTIONS = new CompletionOptions(Boolean.TRUE, Arrays.asList(".", "@", "#", "*", " "));
public final static CompletionOptions getDefaultCompletionOptions(PreferenceManager preferenceManager) {
CompletionOptions completionOptions = new CompletionOptions(Boolean.TRUE, Arrays.asList(".", "@", "#", "*", " "));
if (preferenceManager.getClientPreferences().isCompletionItemLabelDetailsSupport()) {
CompletionItemOptions completionItemOptions = new CompletionItemOptions();
completionItemOptions.setLabelDetailsSupport(Boolean.TRUE);
completionOptions.setCompletionItem(completionItemOptions);
}
return completionOptions;
}

private static final Set<String> UNSUPPORTED_RESOURCES = Sets.newHashSet("module-info.java", "package-info.java");

static final Comparator<CompletionItem> PROPOSAL_COMPARATOR = new Comparator<>() {
Expand Down
Loading

0 comments on commit 96b220e

Please sign in to comment.